Attachment
Installation
npx @mielui/svelte add attachmentyarn dlx @mielui/svelte add attachmentbunx @mielui/svelte add attachmentUsage
Bind selected files on the root and report rejected files from the onReject callback. Selection is local only; your application owns uploading and upload state.
Set accept, maxFiles, and maxSize to limit selection. disabled prevents adding or removing files and clears the drag highlight.
<script lang="ts">
import * as Attachment from '@mielui/svelte/components/attachment';
let files = $state<File[]>([]);
let rejected = $state<Attachment.AttachmentRejection[]>([]);
</script>
<Attachment.Root
bind:files
accept="image/*,.pdf"
maxFiles={3}
maxSize={5 * 1024 * 1024}
onReject={(rejections) => {
rejected = rejections;
}}
>
<Attachment.Trigger>Choose files</Attachment.Trigger>
<Attachment.List />
</Attachment.Root>Selection and upload ownership
Attachment validates local selection and displays files. It does not upload them. Keep upload progress and errors in your application, or use File Upload when you need an upload callback with cancellation and retry. Item clamps progress from 0 to 100; an omitted or non-finite value shows an indeterminate indicator.
Examples
Upload status
Chips
Set variant="chip" on List or Item for a compact pill with a file-type icon or image thumbnail, the name, and a remove button. A spinner replaces the icon while uploading, and errors add a red edge. Progress and status text stay available to assistive technology. In a chat input, place chips above Composer.Root inside the shared Attachment.Root.
Labels
Built-in text is English by default. Pass labels to Root to translate or reword the drop overlay, the trigger, the list, file status, and the remove button. Every key of AttachmentLabels is optional; omitted keys keep their default.
<Attachment.Root
bind:files
labels={{
dropzone: 'Dรฉposez des fichiers',
add: 'Joindre des fichiers',
remove: (name) => `Retirer ${name}`
}}
>
<Attachment.Trigger />
<Attachment.List />
</Attachment.Root>One file at a time
Root lets people choose several files by default. Set multiple={false} so the file chooser takes one file at a time, and add maxFiles={1} to cap the list at a single file.
List takes label, the accessible name of the list of files. Trigger accepts element and onclick, which runs before the file chooser opens. Root and Trigger render their children.
API reference
Attachment.Root
Manages selected files.
labelsAttachmentLabelsOverrides the built-in text and accessible names. Every key is optional and English is the fallback.
filesBindableFile[]Attached files. Bindable.
Default
[]acceptstringAccepted file types, written as for a file input.
multiplebooleanAllows choosing more than one file.
Default
truemaxFilesnumberLargest number of files.
maxSizenumberLargest file size in bytes.
disabledbooleanPrevents interaction and dims the control.
Default
falseonReject((rejections: AttachmentRejection[]) => void)Called with the files that were refused and the reason for each.
classstringClasses added to the element.
childrenSnippet<[]>Content rendered inside.
Attachment.Item
Displays one selected file.
fileRequiredFileThe file this item shows.
variant"card" | "chip"cardshows a thumbnail and details.chipis a compact pill.Default
'card'statusAttachmentStatusUpload state shown on the item.
Default
'ready'progressnumberUpload progress from 0 to 100.
errorstringMessage shown when the upload failed.
onRemove((file: File) => void)Called when the remove button is pressed.
removablebooleanShows the remove button.
Default
trueclassstringClasses added to the element.
Attachment.List
Lists selected files.
labelstringAccessible name of the list.
variant"card" | "chip"cardshows a thumbnail and details.chipis a compact pill.Default
'card'classstringClasses added to the element.
Attachment.Trigger
Opens the file picker.
classstringClasses added to the element.
childrenSnippet<[]>Content rendered inside.
elementBindableHTMLButtonElement | HTMLAnchorElementBindable reference to the DOM element.
onclick((event: MouseEvent) => void)Called when it is clicked or activated.
variantButtonVariantButton style of the attach button.
Default
'ghost'size"icon" | "lg" | "md" | "sm"Control height of the attach button. It defaults to an icon button when there is no label.
Default
children ? 'md' : 'icon'
pnpm dlx @mielui/svelte add attachment