Skip to main content

File Upload

View as Markdown

A file picker with drag and drop support, file lists, and validation hooks.

Drag files here or choose from your device
Images and PDFs up to 5 files.
    No files selected yet.
<primitives:fileUpload.root>
    <primitives:fileUpload.label />
    <primitives:fileUpload.dropzone>
        <primitives:fileUpload.trigger />
    </primitives:fileUpload.dropzone>
    <primitives:fileUpload.hiddenInput />

    <primitives:fileUpload.itemTemplate>
        <primitives:fileUpload.item>
            <primitives:fileUpload.itemPreview match="image/*">
                <primitives:fileUpload.itemPreviewImage />
            </primitives:fileUpload.itemPreview>
            <primitives:fileUpload.itemPreview match=".*">
                <primitives:fileUpload.itemPreviewFallback />
            </primitives:fileUpload.itemPreview>
            <primitives:fileUpload.itemName />
            <primitives:fileUpload.itemSizeText />
            <primitives:fileUpload.itemError />
            <primitives:fileUpload.itemDeleteTrigger />
        </primitives:fileUpload.item>
    </primitives:fileUpload.itemTemplate>

    <f:comment>Optional - falls back to the itemTemplate above when omitted.</f:comment>
    <primitives:fileUpload.itemTemplate
        type="{f:constant(name: 'Jramke\FluidPrimitives\Enum\FileUploadItemType::Rejected')}"
    >
        <primitives:fileUpload.item>
            <primitives:fileUpload.itemName />
            <primitives:fileUpload.itemError />
            <primitives:fileUpload.itemDeleteTrigger />
        </primitives:fileUpload.item>
    </primitives:fileUpload.itemTemplate>

    <primitives:fileUpload.itemGroup>
        <primitives:fileUpload.emptyState />
    </primitives:fileUpload.itemGroup>
    <primitives:fileUpload.clearTrigger />
</primitives:fileUpload.root>
typo3 ui:add file-upload

Read more about installing Components and Primitives.

Use file upload inside Field for form semantics and validation messaging.

Upload your resume
PDF only, one file maximum.
    No files selected yet.
We use this for your application review.

Accepted and rejected files only ever exist as browser File objects, so they can never be part of the server-rendered markup. The item part is instead authored once inside an itemTemplate part inside ui:fileUpload.root, and the primitive clones/populates it for every accepted or rejected file - the same ui:template pattern the Combobox uses for asynchronously loaded results, just wrapped in a part so neither the stencil's internal name nor its context argument are something you need to type yourself. Rejected items use the itemError part to show why they were rejected, and can use an entirely different template (via itemTemplate's type prop, see Custom Item Layout below) when a rejected file shouldn't look like an accepted one at all.

Drop up to two images
Large files will appear in a rejected list below.
Accepted files
    No files selected yet.
Rejected files
    No rejected files.

Declare multiple itemPreview parts inside the item template, each with a match MIME type pattern (e.g. image/*). The primitive shows the first matching variant for a given file and hides the rest, which makes an image preview plus a generic fallback icon possible without a custom render callback.

Drag files here or choose from your device
Images and PDFs up to 5 files.
    No files selected yet.

FileUpload translates three labels: dropzone (the dropzone's aria-label), itemPreview (an accepted item's preview alt text), and deleteFile (an item's delete button aria-label). The last two are functions in zag-js ((file: File) => string), since they interpolate the file's name - but Fluid has no callbacks to hand over, and the File only exists in the browser anyway. So they're translated as plain strings containing a literal %fileName% placeholder, which the primitive substitutes with the real file name client-side:

<ui:fileUpload.root
    translations="{itemPreview: 'Vorschau von %fileName%', deleteFile: 'Datei %fileName% entfernen'}"
></ui:fileUpload.root>

Use %fileName%, not {fileName} - Fluid's own inline array/object syntax already treats a bare {...} inside a string as a nested variable expression, so a curly-brace placeholder would silently get stripped from an override written this way. Omit itemPreview/deleteFile to keep the built-in translation. Per-locale overrides can also live in your own locallang.xlf and be read with f:translate instead.

Enable directory selection in browsers that support webkitdirectory.

Select a directory
Useful for importing grouped assets or media folders.
    No files selected yet.

Nothing about itemTemplate requires reusing the default part layout - author whatever markup you want inside it, drop parts you don't need (here, itemSizeText is left out entirely), and read the client-side API directly for anything that isn't a part at all, like a running "x / 5 files selected" count.

Rejected items can use a second itemTemplate, given type="{f:constant(name: 'Jramke\FluidPrimitives\Enum\FileUploadItemType::Rejected')}", instead of reusing the accepted one - handy when a rejected file should look nothing like an accepted one, e.g. no preview at all. FileUpload falls back to the accepted itemTemplate for rejected items when no dedicated rejected one is given, so this is opt-in.

The counter is plain userland JS: a ui:ref written directly in the root's slot content (context="fileUpload", since it isn't part of the primitive's own template) is read back via the component's this.hydrator.query(), in a small subclass that updates it after every render.

Item-level data with no corresponding part works the same way, but each rendered item first has to be found again. itemModifiedDate is a plain ui:ref inside the item template - context="fileUpload" is required here too: slot content is evaluated against the rendering context of the template that writes it, which does not know which component it ends up in, so a ui:ref there always needs it - only a primitive's own template body resolves the component on its own. The subclass's render() override then re-finds every rendered item via this.hydrator.queryAll('item'), reads each one's own itemModifiedDate child with this.hydrator.query('itemModifiedDate', itemEl) - passing that specific item as the scope is what lets one query() call resolve correctly per file, the same way it already does for any other item-level part - matches its data-value back to a File via the exported fileValue() helper (the exact identity FileUpload itself stamps onto that attribute), and fills in the date. The same pattern works for any other per-item data a template needs.

0 / 5 files selected
Drop photos here or choose from your device
Up to 5 images. File size is intentionally not shown here.
    No photos selected yet.
Rejected
    Nothing was rejected.

itemDeleteTrigger always deletes immediately once clicked - there's no built-in confirmation step, since what "confirm" means (a dialog, an undo toast, nothing) is entirely up to the consumer. This example pairs FileUpload with Dialog to ask before a file is actually removed: both are mounted as independent, hydration-controlled instances (autoMount="{false}" + a fixed rootId, the same pattern Combobox's custom filter example uses), and a capturing-phase click listener on the item group intercepts the delete trigger's own click before it reaches FileUpload's built-in handler - event.stopImmediatePropagation() keeps the immediate delete from ever running. The file itself is recovered from the clicked item's data-value via the exported fileValue() helper (see Custom Item Layout above), and only deleted (via api.deleteFile()) once the dialog is confirmed.

Delegation is needed here because FileUpload re-clones its item markup on every accepted/rejected-files change, so there's no stable per-item element to attach a listener to directly.

Drop documents here or choose from your device
Removing a file asks for confirmation first.
    No documents selected yet.

FileUpload produces a plain, native <input type="file"> under the hood, so it works with Extbase's #[FileUpload] property attribute without any special controller code - it replaces f:form.upload one-to-one.

<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Domain\Model;

use TYPO3\CMS\Extbase\Attribute\FileUpload;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;

class Conference extends AbstractEntity
{
    #[FileUpload(
        validation: [
            'required' => false,
            'maxFiles' => 1,
            'fileSize' => ['minimum' => '10K', 'maximum' => '2M'],
            'mimeType' => ['allowedMimeTypes' => ['image/jpeg', 'image/png']],
            'fileExtension' => ['allowedFileExtensions' => ['jpg', 'jpeg', 'png']],
        ],
        uploadFolder: '1:/user_upload/conference_logos/',
    )]
    protected ?FileReference $logo = null;

    /**
     * @var ObjectStorage<FileReference>
     */
    #[FileUpload(
        validation: [
            'fileSize' => ['minimum' => '10K', 'maximum' => '10M'],
            'mimeType' => ['allowedMimeTypes' => ['image/jpeg', 'image/png']],
            'fileExtension' => ['allowedFileExtensions' => ['jpg', 'jpeg', 'png']],
        ],
        uploadFolder: '1:/user_upload/conference_impressions/',
    )]
    protected ObjectStorage $impressions;

    // constructor, initializeObject(), getters and setters...
}

Use ui:form.root, and set maxFiles on FileUpload to match the property's cardinality - 1 for a single FileReference, greater than 1 for an ObjectStorage<FileReference>. For a multi-file property, write the [] suffix on name yourself, the same way you would for a CheckboxGroup field bound to an array property - the primitive never appends it for you:

<ui:form.root action="update" objectName="conference" object="{conference}">
    <ui:field.root name="logo">
        <ui:fileUpload.root name="logo" accept="image/jpeg,image/png" maxFiles="1">
            <ui:fileUpload.label>Logo</ui:fileUpload.label>
            <ui:fileUpload.dropzone>
                <ui:fileUpload.trigger>Choose logo</ui:fileUpload.trigger>
            </ui:fileUpload.dropzone>
            <ui:fileUpload.itemGroup>
                <ui:fileUpload.emptyState>No logo selected yet.</ui:fileUpload.emptyState>
            </ui:fileUpload.itemGroup>
        </ui:fileUpload.root>
    </ui:field.root>

    <ui:field.root name="impressions">
        <ui:fileUpload.root name="impressions[]" accept="image/jpeg,image/png" maxFiles="10">
            <ui:fileUpload.label>Impressions</ui:fileUpload.label>
            <ui:fileUpload.dropzone>
                <ui:fileUpload.trigger>Choose images</ui:fileUpload.trigger>
            </ui:fileUpload.dropzone>
            <ui:fileUpload.itemGroup>
                <ui:fileUpload.emptyState>No images selected yet.</ui:fileUpload.emptyState>
            </ui:fileUpload.itemGroup>
        </ui:fileUpload.root>
    </ui:field.root>
</ui:form.root>

No enctype is needed on the form: Form never submits natively - it always posts a FormData body via fetch (see the Forms guide), and fetch always sends a FormData body as multipart/form-data regardless of any enctype attribute, since it isn't reading the <form> element at all.

FileUpload's own file list only ever holds files newly picked in the browser - it has no concept of an already-persisted FileReference from a previous request. For an edit form, render existing files as ordinary items directly inside ui:fileUpload.itemGroup, alongside the newly-picked ones, instead of showing them in a second, separate list. Give each one type="existing" and pair its delete trigger with ui:fileUploadDeleteCheckbox, which renders TYPO3's HMAC-signed @delete token so Extbase removes the file reference on submit. Newly-picked files get their ids from the client (it re-stamps every part with the picked file's own value on mount), but a directly-authored existing item never goes through that - pass its own value, e.g. the file reference's uid, so more than one existing item doesn't collide on the same id:

Existing items still sit inside the same itemTemplate-driven itemGroup as newly-picked files (see Accepted and Rejected Files above), so don't drop the item template when adding them - without it, the itemGroup renders the existing files fine, but selecting a new file has nothing to clone and populate, and throws:

<ui:form.root action="update" objectName="conference" object="{conference}">
    <ui:field.root name="impressions[]">
        <ui:fileUpload.root
            accept="image/jpeg,image/png"
            maxFiles="10"
            existingFilesCount="{conference.impressions -> f:count()}"
        >
            <ui:fileUpload.label>Impressions</ui:fileUpload.label>
            <ui:fileUpload.dropzone>
                <ui:fileUpload.trigger>Choose images</ui:fileUpload.trigger>
            </ui:fileUpload.dropzone>

            <primitives:fileUpload.itemTemplate>
                <ui:fileUpload.fileItem>
                    <primitives:fileUpload.itemPreview
                        match="image/*"
                        class="bg-muted flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-md border"
                    >
                        <primitives:fileUpload.itemPreviewImage class="size-full object-cover" />
                    </primitives:fileUpload.itemPreview>
                    <primitives:fileUpload.itemPreview
                        match=".*"
                        class="bg-muted text-muted-foreground flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-md border"
                    >
                        <ui:fileUpload.filePreviewFallback />
                    </primitives:fileUpload.itemPreview>
                    <div class="grid min-w-0 flex-1 gap-0.5">
                        <ui:fileUpload.fileName />
                        <ui:fileUpload.fileMeta />
                        <ui:fileUpload.fileError />
                    </div>
                    <ui:fileUpload.fileDeleteTrigger />
                </ui:fileUpload.fileItem>
            </primitives:fileUpload.itemTemplate>

            <ui:fileUpload.itemGroup>
                <f:for each="{conference.impressions}" as="fileReference">
                    <ui:fileUpload.fileItem type="existing" value="{fileReference.uid}">
                        <f:image
                            image="{fileReference}"
                            width="40"
                            height="40"
                            class="size-10 shrink-0 rounded-md border object-cover"
                        />
                        <div class="grid min-w-0 flex-1 gap-0.5">
                            <ui:fileUpload.fileName
                                >{fileReference.originalResource.name}</ui:fileUpload.fileName
                            >
                        </div>
                        <ui:fileUploadDeleteCheckbox
                            fileReference="{fileReference}"
                            class="hidden"
                        />
                        <ui:fileUpload.fileDeleteTrigger />
                    </ui:fileUpload.fileItem>
                </f:for>
                <ui:fileUpload.emptyState>No images selected yet.</ui:fileUpload.emptyState>
            </ui:fileUpload.itemGroup>
        </ui:fileUpload.root>
    </ui:field.root>
</ui:form.root>

Clicking that delete trigger checks the sibling checkbox and hides the item immediately, exactly like removing a newly-picked file - the actual FileReference is only deleted once the form is submitted. The checkbox must be a sibling of fileDeleteTrigger, never nested inside it: a native <button> isn't allowed to contain interactive descendants like <input>, so class="hidden" (rather than nesting) is how it's kept out of view.

ui:fileUploadDeleteCheckbox requires the enclosing ui:form.root to have an objectName matching the controller action's argument name, and reads property from the surrounding ui:field.root when not given explicitly.

existingFilesCount tells the machine how many slots the existing items above already use, so maxFiles and the rejected-as-TOO_MANY_FILES behavior account for them too. It's deliberately a plain count, not the existing files themselves: whatever the machine holds as an accepted file also ends up in the hidden input's native FileList and gets resubmitted on the next form post - passing the existing FileReferences in as reconstructed File placeholders would silently overwrite each one with garbage content built from just its name and size.

The following tables cover the available props of the Fluid Primitives. For a full list of available client side props and methods, see the Zag.js Machine API.

Contains every part of the file upload. Renders a <div> element.

NameDescriptionRequiredDefault
namestring
The name of the underlying file input. Inherited from a surrounding field when available.
No
-
disabledboolean
Whether the file upload is disabled. Inherited from a surrounding field when available.
No
-
invalidboolean
Whether the file upload is invalid. Inherited from a surrounding field when available.
No
-
requiredboolean
Whether the file upload is required. Inherited from a surrounding field when available.
No
-
readOnlyboolean
Whether the file upload is read-only. Inherited from a surrounding field when available.
No
-
acceptmixed
The accepted file types, e.g. `image/*` or `{ 'image/png': ['.png'] }`.
No
-
allowDropboolean
Whether to allow drag and drop in the dropzone element.
No
true
maxFilesinteger
The maximum number of files that can be selected.
No
1
existingFilesCountinteger
The number of already-persisted files shown outside the machine's own file list (e.g. as `type="existing"` items), so it can be subtracted from `maxFiles` and the remaining-slots count also accounts for them. Deliberately a plain count, not a list of `File` objects: whatever ends up in the machine's own accepted files also ends up in the hidden input's `FileList` and gets resubmitted on the next form post, which would silently overwrite an already-stored file with placeholder content reconstructed from just its name/size.
No
0
maxFileSizeinteger
The maximum file size in bytes.
No
-
minFileSizeinteger
The minimum file size in bytes.
No
-
preventDocumentDropboolean
Whether to prevent a file drop outside of the dropzone from navigating the document.
No
true
captureEnum\FileUploadCapture
The camera to use to capture media on mobile devices.
No
-
directoryboolean
Whether to accept whole directories instead of files. Only works in webkit based browsers.
No
false
translationsarray
Localized file upload labels. Use `f:translate` for per-template localization overrides when needed.
No
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
rootIdstring
The root ID of the component, used for hydration and identification.
No
-
idsarray
The IDs of of the component parts for composition.
No
[]
autoMountboolean
Whether the client initializes the component on its own. Set it to false to mount it yourself with `mount()`
No
true
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-root<uid>
data-disabledPresent when disabled
data-readonlyPresent when read-only
data-draggingPresent when in the dragging state

The label for the file input. Renders a <label> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-label<uid>
data-disabledPresent when disabled
data-invalidPresent when invalid
data-requiredPresent when required

The drag-and-drop target and click-to-open surface. Renders a <div> element with role="button".

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-dropzone<uid>
data-invalidPresent when invalid
data-disabledPresent when disabled
data-readonlyPresent when read-only
data-draggingPresent when in the dragging state

The native file input used for form submission. Renders a visually hidden <input type="file"> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Opens the file picker dialog. Renders a <button> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-trigger<uid>
data-disabledPresent when disabled
data-readonlyPresent when read-only
data-invalidPresent when invalid

Groups accepted or rejected file items, selected via the type prop (Jramke\FluidPrimitives\Enum\FileUploadItemType). Renders a <div> element.

NameDescriptionRequiredDefault
typeEnum\FileUploadItemType
Which file list this group renders, `accepted` or `rejected`.
No
Accepted
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-item-group<uid>
data-disabledPresent when disabled
data-typeThe type of the item

Shown while an itemGroup has no items yet. Renders a <div> element.

NameDescriptionRequiredDefault
typeEnum\FileUploadItemType
Which file list this empty state belongs to - must match the enclosing item group's own `type`, to keep ids unique when both groups render in the same root.
No
Accepted
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Wraps the item markup for accepted files, or rejected files when type is set to Jramke\FluidPrimitives\Enum\FileUploadItemType::Rejected (falls back to the accepted template when no dedicated rejected one is given). Renders a <template> element - never visible itself, cloned per file.

NameDescriptionRequiredDefault
typeEnum\FileUploadItemType
Which files this template is for. `accepted` (the default) also doubles as the fallback rejected items use when no dedicated `rejected` template is given - see FileUpload.ts's resolveItemTemplatePart().
No
Accepted

One file. Accepted/rejected items are only ever rendered from an itemTemplate; an already-persisted file can be authored directly with type="existing". Renders a <div> element.

NameDescriptionRequiredDefault
typestring
The item's kind, e.g. `accepted`, `rejected`, or a custom value such as `existing` for an already-persisted file authored directly rather than populated from a `ui:template` stencil.
No
'accepted'
valuestring
A unique identifier for this item, e.g. a persisted file reference's own `uid`. Not needed for `accepted`/`rejected` items populated from `itemTemplate` - the client re-stamps those with the picked file's own value on mount. Required when authoring more than one `type=" existing"` item directly, so the client can tell their `item`/`itemName`/`itemSizeText`/`itemDeleteTrigger`/`itemError` parts apart.
No
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-item<uid>
data-disabledPresent when disabled
data-typeThe type of the item

Displays the file's name. Renders a <div> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-item-name<uid>
data-disabledPresent when disabled
data-typeThe type of the item

Displays the file's formatted size. Renders a <div> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-item-size-text<uid>
data-disabledPresent when disabled
data-typeThe type of the item

Displays a rejected file's validation errors, hidden by default. Renders a <div> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

A preview variant for an item, shown when its match MIME type pattern matches the file. Renders a <div> element.

NameDescriptionRequiredDefault
matchstring
A file MIME type pattern (e.g. `image/*`) this preview variant should be used for. The first `itemPreview` whose `match` matches the file wins; use `.*` as a catch-all fallback.
No
'.*'
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-item-preview<uid>
data-disabledPresent when disabled
data-typeThe type of the item

Displays an image preview, only rendered for image files. Renders an <img> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-item-preview-image<uid>
data-disabledPresent when disabled
data-typeThe type of the item

Displays a generic fallback (e.g. the file extension) inside a non-image itemPreview variant. Renders a <div> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Removes a single accepted or rejected file. Renders a <button> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-item-delete-trigger<uid>
data-disabledPresent when disabled
data-readonlyPresent when read-only
data-typeThe type of the item

Clears every accepted file. Renders a <button> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-file-upload-clear-trigger<uid>
data-disabledPresent when disabled
data-readonlyPresent when read-only
NameTypeDescription
draggingbooleanWhether the user is dragging something over the root element
focusedbooleanWhether the user is focused on the dropzone element
disabledbooleanWhether the file input is disabled
readOnlybooleanWhether the file input is in read-only mode
transformingbooleanWhether files are currently being transformed via `transformFiles`
maxFilesReachedbooleanWhether the maximum number of files has been reached
remainingFilesnumberThe number of files that can still be added
openFilePickerVoidFunctionFunction to open the file dialog
deleteFile(file: File, type?: ItemType | undefined) => voidFunction to delete the file from the list
acceptedFilesFile[]The accepted files that have been dropped or selected
rejectedFilesFileRejection[]The files that have been rejected
setFiles(files: File[]) => voidSets the accepted files
clearFilesVoidFunctionClears the accepted files
clearRejectedFilesVoidFunctionClears the rejected files
getFileSize(file: File) => stringReturns the formatted file size (e.g. 1.2MB)
createFileUrl(file: File, cb: (url: string) => void) => VoidFunctionReturns the preview url of a file. Returns a function to revoke the url.
setClipboardFiles(dt: DataTransfer | null) => booleanSets the clipboard files Returns `true` if the clipboard data contains files, `false` otherwise.
getRootState() => RootStateReturns the state of the root
getDropzoneState() => DropzoneStateReturns the state of the dropzone
getTriggerState() => TriggerStateReturns the state of the trigger
getItemGroupState(props: ItemGroupProps) => ItemGroupStateReturns the state of the item group
getItemState(props: ItemProps) => ItemStateReturns the state of the item