+
+
+
+ {file.name}
+
+
+ {errorMessage === ""
+ ? getDescription({ totalSize: file.size, currentSize })
+ : errorMessage}
+
+
+
+ {status === "failedConnection" && (
+
+
+
+ )}
+ {status === "paused" && (
+
+
+
+ )}
+ {status === "uploading" && (
+
+
+
+ )}
+ {status !== "uploading" && (
+
+
+
+ )}
+
+ );
+};
+
+export const FileUploadExample = () => {
+ const [files, setFiles] = useState<{ file: File; badConnection?: boolean }[]>(
+ [],
+ );
+
+ const handleFiles = (_: SyntheticEvent, files: File[]) => {
+ setFiles((old) =>
+ old.concat(
+ files.map((file) => ({
+ file,
+ })),
+ ),
+ );
+ };
+
+ const handleDelete = (fileToRemove: File) => {
+ setFiles((old) => old.filter((file) => file.file !== fileToRemove));
+ };
+
+ return (
+
+
+
+
+
+
+
+
+ Upload files
+
+ Please drag and drop file(s) in the below area; or browse files by
+ using the button.
+
+
+
+
+ Drop files here or
+
+ Files must be in .PDF format. 100KB file size limit.
+
+
+ {files.map(({ file, badConnection }, index) => (
+
+
+ {index < files.length - 1 && (
+
+ )}
+
+ ))}
+
+
+ );
+};
diff --git a/site/docs/patterns/contact-details.mdx b/site/docs/patterns/contact-details.mdx
index cf7fbe1f158..927a737b942 100644
--- a/site/docs/patterns/contact-details.mdx
+++ b/site/docs/patterns/contact-details.mdx
@@ -99,7 +99,7 @@ We recommend emails to be interactive links by default, you can also define othe
diff --git a/site/docs/patterns/file-upload.mdx b/site/docs/patterns/file-upload.mdx
new file mode 100644
index 00000000000..38ae91ed5db
--- /dev/null
+++ b/site/docs/patterns/file-upload.mdx
@@ -0,0 +1,160 @@
+---
+title: File upload
+layout: DetailPattern
+tags:
+ - pattern
+aliases:
+ - /salt/patterns/file-upload
+data:
+ resources: []
+ components: ["File Drop Zone", "Static List"]
+---
+
+A file upload allows users to transfer one or multiple files from an external source to the web application. This pattern is commonly embedded in forms or as a standalone element.
+
+
+
+## When to use
+
+Use this pattern to:
+
+- Upload files by dragging and dropping, or by using a button to select a file in a new window or file browser.
+- Upload single or multiple files within modals or full-page experiences.
+- Display file upload progress, file listings, and management options.
+
+
+ - Consider using a full-page layout or a drawer if additional actions need to be performed on the files.
+ - When used in dialogs, ensure that submit actions are disabled until the file upload is complete.
+ - When used in drawers, the upload status (e.g., completed) should remain visible regardless of the drawer's open or close actions.
+
+
+## How to build
+
+### Anatomy
+
+A file upload pattern typically consists of two main functional areas:
+
+1. **Upload area:** This provides a target area for users to drag and drop files. It is implemented using the [`FileDropZone`](/salt/components/file-drop-zone) component.
+2. **File upload list:** This area can display a single item or multiple items stacked vertically. Items in this list are constructed using the [`StaticList`](/salt/components/static-list) component.
+
+These functional areas can be enhanced with text elements, such as headers and descriptions, to assist users in making informed decisions.
+
+
+
+### Layout
+
+- Use the [`StackLayout`](/salt/components/stack-layout) to display the File drop zone, file upload items and text elements that make up file upload in a column.
+- Use the [`StackLayout`](/salt/components/flex-layout) with a gap of 1 to position the text elements.
+
+
+
+## Unrestricted space areas
+
+The file drop zone component enables users to upload files by providing a designated drag-and-drop target area. It supports both single and multiple file uploads in unrestricted space areas.
+
+
+
+
+ - The file drop zone component should support both single and multiple file uploads.
+ - Restrict file selection to allowed file types.
+ - Include text elements to assist users in making informed decisions.
+
+
+## Space-restricted areas
+
+In space-restricted scenarios, single file uploads can be facilitated using a button. This button opens a file browser, allowing the user to select a file.
+
+
+
+
+ - Use a button for single file uploads only
+ - Restrict file selection to allowed file types
+ - Include text elements to help users make informed decisions
+
+
+## Uploading files
+
+Ensure users are aware of the upload progress for each file. Use the progress component and a secondary label to display relevant information, helping users manage their expectations. Use action buttons to assist users in managing files. For example, a pause button can be used to put a file upload on hold.
+
+
+
+Following a pause action, play and delete buttons can be used to resume or remove the upload, respectively, as shown in the example below.
+
+
+
+## Success validation
+
+Inform users when a file upload has been successfully completed. Once the process is finished, provide users with the ability to remove the file or perform other related actions.
+
+
+
+## Error validation
+
+### File error
+
+Error validation can occur independently at the file item level without impacting other files in the group. In such case scenarios, the secondary label should clearly explain the issue and offer a solution. A refresh button can be used to retry the upload after error validation.
+
+Inform users when a file upload has been successfully completed. Once the process is finished, provide users with the ability to remove the file or perform other related actions.
+
+
+
+### Group error
+
+Errors can occur at the group level. In such scenarios, error messages should be displayed within the file drop zone component. For instance, if only 2 files can be uploaded, the error message should clearly communicate this limit and guide the user, as demonstrated below. For more details, see file drop zone validation.
+
+
+
+Alternatively, group error messages can be displayed using a banner component positioned below the file drop zone. In such scenarios, ensure that error messages are displayed exclusively in the banner and not within the file drop zone itself.
+
+
+
+
+ - Clearly communicate the issue and offer a solution
+ - Ensure error messages are simple and concise
+
+
+:fragment{src="./fragments/feedback.mdx"}
diff --git a/site/public/img/patterns/file-upload/file-upload-anatomy.png b/site/public/img/patterns/file-upload/file-upload-anatomy.png
new file mode 100644
index 00000000000..257321e85b7
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-anatomy.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-file-error.png b/site/public/img/patterns/file-upload/file-upload-file-error.png
new file mode 100644
index 00000000000..1ca460d65b2
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-file-error.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-group-error-banner.png b/site/public/img/patterns/file-upload/file-upload-group-error-banner.png
new file mode 100644
index 00000000000..c248ef22e96
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-group-error-banner.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-group-error.png b/site/public/img/patterns/file-upload/file-upload-group-error.png
new file mode 100644
index 00000000000..2d758552de9
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-group-error.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-layout.png b/site/public/img/patterns/file-upload/file-upload-layout.png
new file mode 100644
index 00000000000..3d2f8f1b2fb
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-layout.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-pause-action.png b/site/public/img/patterns/file-upload/file-upload-pause-action.png
new file mode 100644
index 00000000000..706dae92eec
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-pause-action.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-restricted-space-areas.png b/site/public/img/patterns/file-upload/file-upload-restricted-space-areas.png
new file mode 100644
index 00000000000..f635c0b9805
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-restricted-space-areas.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-resume-action.png b/site/public/img/patterns/file-upload/file-upload-resume-action.png
new file mode 100644
index 00000000000..415b530d3b5
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-resume-action.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-success-validation.png b/site/public/img/patterns/file-upload/file-upload-success-validation.png
new file mode 100644
index 00000000000..94f4a9b88d7
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-success-validation.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload-unrestricted-space-areas.png b/site/public/img/patterns/file-upload/file-upload-unrestricted-space-areas.png
new file mode 100644
index 00000000000..22b913461e7
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload-unrestricted-space-areas.png differ
diff --git a/site/public/img/patterns/file-upload/file-upload.png b/site/public/img/patterns/file-upload/file-upload.png
new file mode 100644
index 00000000000..0236e2c200b
Binary files /dev/null and b/site/public/img/patterns/file-upload/file-upload.png differ