AI components

Attachment

Select, validate, preview, and remove local files before your application uploads them.

Installation

pnpm dlx @mielui/svelte add attachment

Usage

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.

  • labels
    AttachmentLabels

    Overrides the built-in text and accessible names. Every key is optional and English is the fallback.

  • files Bindable
    File[]

    Attached files. Bindable.

    Default []

  • accept
    string

    Accepted file types, written as for a file input.

  • multiple
    boolean

    Allows choosing more than one file.

    Default true

  • maxFiles
    number

    Largest number of files.

  • maxSize
    number

    Largest file size in bytes.

  • disabled
    boolean

    Prevents interaction and dims the control.

    Default false

  • onReject
    ((rejections: AttachmentRejection[]) => void)

    Called with the files that were refused and the reason for each.

  • class
    string

    Classes added to the element.

  • children
    Snippet<[]>

    Content rendered inside.

Attachment.Item

Displays one selected file.

  • file Required
    File

    The file this item shows.

  • variant
    "card" | "chip"

    card shows a thumbnail and details. chip is a compact pill.

    Default 'card'

  • status
    AttachmentStatus

    Upload state shown on the item.

    Default 'ready'

  • progress
    number

    Upload progress from 0 to 100.

  • error
    string

    Message shown when the upload failed.

  • onRemove
    ((file: File) => void)

    Called when the remove button is pressed.

  • removable
    boolean

    Shows the remove button.

    Default true

  • class
    string

    Classes added to the element.

Attachment.List

Lists selected files.

  • label
    string

    Accessible name of the list.

  • variant
    "card" | "chip"

    card shows a thumbnail and details. chip is a compact pill.

    Default 'card'

  • class
    string

    Classes added to the element.

Attachment.Trigger

Opens the file picker.

  • class
    string

    Classes added to the element.

  • children
    Snippet<[]>

    Content rendered inside.

  • element Bindable
    HTMLButtonElement | HTMLAnchorElement

    Bindable reference to the DOM element.

  • onclick
    ((event: MouseEvent) => void)

    Called when it is clicked or activated.

  • variant
    ButtonVariant

    Button 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'