diff --git a/docs/change-log/2025-10-15-modal-file-upload.md b/docs/change-log/2025-10-15-modal-file-upload.md new file mode 100644 index 0000000000..91e7a55890 --- /dev/null +++ b/docs/change-log/2025-10-15-modal-file-upload.md @@ -0,0 +1,18 @@ +--- +title: "Adding More Modal Components!" +date: "2025-10-15" +topics: +- "Interactions" +- "Components" +--- + +Have you ever wanted to collect more than text from a user through a modal? With the new [**File Upload**](/docs/components/reference#file-upload) component you can! You can specify a min and max number of files accepted between 0 and 10, and if uploading files within that limit is required before submitting. Any file types are accepted, and the max file size is based on the user's upload limit in that channel. + +#### The New Component: + +- [**File Upload**](/docs/components/reference#file-upload) + +#### Developer Resources + +- [Using Modal Components](/docs/components/using-modal-components) - Dive into creating a modal +- Check out our [Component Reference](/docs/components/reference) for details on all available components. diff --git a/docs/components/reference.mdx b/docs/components/reference.mdx index 513f54472f..9d7d4ae20b 100644 --- a/docs/components/reference.mdx +++ b/docs/components/reference.mdx @@ -55,6 +55,7 @@ The following is a complete table of available components. Details about each co | 14 | [Separator](/docs/components/reference#separator) | Component to add vertical padding between other components | Layout | Message | | 17 | [Container](/docs/components/reference#container) | Container that visually groups a set of components | Layout | Message | | 18 | [Label](/docs/components/reference#label) | Container associating a label and description with a component | Layout | Modal | +| 19 | [File Upload](/docs/components/reference#file-upload) | Component for uploading files | Interactive | Modal | -------------- ## Anatomy of a Component @@ -1998,6 +1999,7 @@ The `description` may display above or below the `component` depending on the pl | [Role Select](/docs/components/reference#role-select) | | [Mentionable Select](/docs/components/reference#mentionable-select) | | [Channel Select](/docs/components/reference#channel-select) | +| [File Upload](/docs/components/reference#file-upload) | ###### Label Interaction Response Structure @@ -2017,6 +2019,7 @@ The `description` may display above or below the `component` depending on the pl | [Role Select](/docs/components/reference#role-select-role-select-interaction-response-structure) | | [Mentionable Select](/docs/components/reference#mentionable-select-mentionable-select-interaction-response-structure) | | [Channel Select](/docs/components/reference#channel-select-channel-select-interaction-response-structure) | +| [File Upload](/docs/components/reference#file-upload-file-upload-interaction-response-structure) | ###### Examples @@ -2053,7 +2056,115 @@ The `description` may display above or below the `component` depending on the pl ``` --------------------------------- +-------------- +## File Upload + +File Upload is an interactive component that allows users to upload files in modals. File Uploads can be configured to have a minimum and maximum number of files between 0 and 10, along with `required` for if the upload is required to submit the modal. The max file size a user can upload is based on the user's upload limit in that channel. + +File Uploads are available on modals. They must be placed inside a [Label](/docs/components/reference#label). + +###### File Upload Structure + +| Field | Type | Description | +|-------------|---------|--------------------------------------------------------------------------------------------------------| +| type | integer | `19` for file upload | +| id? | integer | Optional identifier for component | +| custom_id | string | ID for the file upload; max 100 characters | +| min_values? | integer | Minimum number of items that must be uploaded (defaults to 1); min 0, max 10 | +| max_values? | integer | Maximum number of items that can be uploaded (defaults to 1); max 10 | +| required? | boolean | Whether the file upload requires files to be uploaded before submitting the modal (defaults to `true`) | + +###### File Upload Interaction Response Structure + +| Field | Type | Description | +|-----------|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------| +| type | integer | `19` for a File Upload | +| id | integer | Unique identifier for the component | +| custom_id | string | Developer-defined identifier for the input; max 100 characters | +| values | array of snowflakes | IDs of the uploaded files found in the [resolved data](/docs/interactions/receiving-and-responding#interaction-object-resolved-data-structure) | + +###### Examples + + + + + ![Example of a modal with a File Upload](images/components/file-upload-modal-example.webp) + + + ```json + { + "type": 9, + "data": { + "custom_id": "bug_submit_modal", + "title": "Bug Submission", + "components": [ + { + "type": 18, // ComponentType.LABEL + "label": "File Upload", + "description": "Please upload a screenshot or other image that shows the bug you encountered.", + "component": { + "type": 19, // ComponentType.FILE_UPLOAD + "custom_id": "file_upload", + "min_values": 1, + "max_values": 10, + "required": true + } + } + ] + } + } + ``` + + + + + When a user submits a modal that contains a File Upload, this is the basic form of the interaction data payload you will receive. The full payload + is available in the [interaction](/docs/interactions/receiving-and-responding#interaction-object-interaction-structure) reference. + + ```json + { + "type": 5, // InteractionType.MODAL_SUBMIT + ...additionalInteractionFields, // See the Interaction documentation for all fields + + "data": { + "components": [ + { + "component": { + "custom_id": "file_upload", + "id": 2, + "type": 19, + "values": [ + "111111111111111111111" + ] + }, + "id": 1, + "type": 18 + } + ], + "custom_id": "bug_submit_modal", + "resolved": { + "attachments": { + "111111111111111111111": { + "content_type": "image/png", + "ephemeral": true, + "filename": "bug.png", + "height": 604, + "id": "111111111111111111111", + "placeholder": "/PcBAoBQydvKesabEIoMsdg=", + "placeholder_version": 1, + "proxy_url": "https://media.discordapp.net/ephemeral-attachments/2222222222222222222/111111111111111111111/bug.png?ex=68dc7ce1&is=68db2b61&hm=5954f90117ccf8716ffa6c7f97a778a0d039810c9584045f400d8a9fff590768&", + "size": 241394, + "url": "https://cdn.discordapp.com/ephemeral-attachments/2222222222222222222/111111111111111111111/bug.png?ex=68dc7ce1&is=68db2b61&hm=5954f90117ccf8716ffa6c7f97a778a0d039810c9584045f400d8a9fff590768&", + "width": 2482 + } + } + } + } + } + ``` + + +---------------------- ## Unfurled Media Item An Unfurled Media Item is a piece of media, represented by a URL, that is used within a component. It can be diff --git a/docs/interactions/receiving-and-responding.mdx b/docs/interactions/receiving-and-responding.mdx index 42dab8c8c6..d76d8427a8 100644 --- a/docs/interactions/receiving-and-responding.mdx +++ b/docs/interactions/receiving-and-responding.mdx @@ -145,6 +145,7 @@ Sent in `APPLICATION_COMMAND` and `APPLICATION_COMMAND_AUTOCOMPLETE` interaction | [Channel Select](/docs/components/reference#channel-select-channel-select-interaction-response-structure) | | [Text Display](/docs/components/reference#text-display-text-display-interaction-response-structure) | | [Label](/docs/components/reference#label-label-interaction-response-structure) | +| [File Upload](/docs/components/reference#file-upload-file-upload-interaction-response-structure) | ###### Resolved Data Structure diff --git a/static/images/components/file-upload-modal-example.webp b/static/images/components/file-upload-modal-example.webp new file mode 100644 index 0000000000..cf3643d6f2 Binary files /dev/null and b/static/images/components/file-upload-modal-example.webp differ