<script lang="ts">
import { FileUpload } from '@skeletonlabs/skeleton-svelte';
</script>
<FileUpload>
<FileUpload.Label>Label</FileUpload.Label>
<FileUpload.Dropzone>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
<FileUpload.Item {file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
{/each}
{/snippet}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
import { FileUpload } from '@skeletonlabs/skeleton-react';
export default function Default() {
return (
<FileUpload>
<FileUpload.Label>Label</FileUpload.Label>
<FileUpload.Dropzone>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{(fileUpload) =>
fileUpload.acceptedFiles.map((file) => (
<FileUpload.Item key={file.name} file={file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
))
}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
);
}
Custom Content
Supply your own text and icons within the dropzone.
Select file or drag here.
<script lang="ts">
import { FileIcon } from '@lucide/svelte';
import { FileUpload } from '@skeletonlabs/skeleton-svelte';
</script>
<FileUpload>
<FileUpload.Dropzone>
<FileIcon class="size-10" />
<span>Select file or drag here.</span>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
<FileUpload.Item {file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
{/each}
{/snippet}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
Select file or drag here.
import { FileUpload } from '@skeletonlabs/skeleton-react';
import { FileIcon } from 'lucide-react';
export default function Default() {
return (
<FileUpload>
<FileUpload.Dropzone>
<FileIcon className="size-10" />
<span>Select file or drag here.</span>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{(fileUpload) =>
fileUpload.acceptedFiles.map((file) => (
<FileUpload.Item key={file.name} file={file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
))
}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
);
}
Disabled
<script lang="ts">
import { FileUpload } from '@skeletonlabs/skeleton-svelte';
</script>
<FileUpload disabled={true}>
<FileUpload.Dropzone>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
<FileUpload.Item {file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
{/each}
{/snippet}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
import { FileUpload } from '@skeletonlabs/skeleton-react';
export default function Disabled() {
return (
<FileUpload disabled>
<FileUpload.Dropzone>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{(fileUpload) =>
fileUpload.acceptedFiles.map((file) => (
<FileUpload.Item key={file.name} file={file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
))
}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
);
}
Button Only
<script lang="ts">
import { FileUpload } from '@skeletonlabs/skeleton-svelte';
</script>
<FileUpload class="w-fit" onFileAccept={console.log}>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload>
import { FileUpload } from '@skeletonlabs/skeleton-react';
export default function Button() {
return (
<FileUpload className="w-fit">
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload>
);
}
Clear Files
- example.png4 bytes
<script lang="ts">
import { FileUpload, useFileUpload } from '@skeletonlabs/skeleton-svelte';
const id = $props.id();
const fileUpload = useFileUpload({
id,
defaultAcceptedFiles: [new File(['file'], 'example.png', { type: 'image/png' })],
});
</script>
<div class="grid gap-4 w-full">
<FileUpload.Provider value={fileUpload}>
<FileUpload.Dropzone>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
<FileUpload.Item {file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
{/each}
{/snippet}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload.Provider>
<button class="btn preset-filled hover:preset-filled-error-500 w-fit" onclick={() => fileUpload().clearFiles()}>Clear Files</button>
</div>
- example.png4 bytes
import { FileUpload, useFileUpload } from '@skeletonlabs/skeleton-react';
export default function ClearFiles() {
const fileUpload = useFileUpload({
defaultAcceptedFiles: [new File(['file'], 'example.png', { type: 'image/png' })],
});
return (
<div className="grid gap-4 w-full">
<FileUpload.Provider value={fileUpload}>
<FileUpload.Dropzone>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{(fileUpload) =>
fileUpload.acceptedFiles.map((file) => (
<FileUpload.Item key={file.name} file={file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
))
}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload.Provider>
<button className="btn preset-filled hover:preset-filled-error-500 w-fit" onClick={() => fileUpload.clearFiles()}>
Clear Files
</button>
</div>
);
}
Direction
<script lang="ts">
import { FileUpload } from '@skeletonlabs/skeleton-svelte';
</script>
<FileUpload dir="rtl">
<FileUpload.Label>Label</FileUpload.Label>
<FileUpload.Dropzone>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{#snippet children(fileUpload)}
{#each fileUpload().acceptedFiles as file (file.name)}
<FileUpload.Item {file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
{/each}
{/snippet}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
import { FileUpload } from '@skeletonlabs/skeleton-react';
export default function Dir() {
return (
<FileUpload dir="rtl">
<FileUpload.Label>Label</FileUpload.Label>
<FileUpload.Dropzone>
<FileUpload.Trigger>Browse Files</FileUpload.Trigger>
<FileUpload.HiddenInput />
</FileUpload.Dropzone>
<FileUpload.ItemGroup>
<FileUpload.Context>
{(fileUpload) =>
fileUpload.acceptedFiles.map((file) => (
<FileUpload.Item key={file.name} file={file}>
<FileUpload.ItemName>{file.name}</FileUpload.ItemName>
<FileUpload.ItemSizeText>{file.size} bytes</FileUpload.ItemSizeText>
<FileUpload.ItemDeleteTrigger />
</FileUpload.Item>
))
}
</FileUpload.Context>
</FileUpload.ItemGroup>
</FileUpload>
);
}
API Reference
Root
| Property | Default | Type |
|---|---|---|
name | - | string | undefinedThe name of the underlying file input |
ids | - | Partial<{ root: string; dropzone: string; hiddenInput: string; trigger: string; label: string; item: (id: string) => string; itemName: (id: string) => string; itemSizeText: (id: string) => string; itemPreview: (id: string) => string; }> | undefined The ids of the elements. Useful for composition. |
translations | - | IntlTranslations | undefinedThe localized messages to use. |
accept | - | Record<string, string[]> | FileMimeType | FileMimeType[] | undefinedThe accept file types |
disabled | - | boolean | undefinedWhether the file input is disabled |
required | - | boolean | undefinedWhether the file input is required |
allowDrop | true | boolean | undefinedWhether to allow drag and drop in the dropzone element |
maxFileSize | Infinity | number | undefinedThe maximum file size in bytes |
minFileSize | 0 | number | undefinedThe minimum file size in bytes |
maxFiles | 1 | number | undefinedThe maximum number of files |
preventDocumentDrop | true | boolean | undefinedWhether to prevent the drop event on the document |
validate | - | ((file: File, details: FileValidateDetails) => FileError[] | null) | undefinedFunction to validate a file |
defaultAcceptedFiles | - | File[] | undefinedThe default accepted files when rendered. Use when you don't need to control the accepted files of the input. |
acceptedFiles | - | File[] | undefinedThe controlled accepted files |
onFileChange | - | ((details: FileChangeDetails) => void) | undefinedFunction called when the value changes, whether accepted or rejected |
onFileAccept | - | ((details: FileAcceptDetails) => void) | undefinedFunction called when the file is accepted |
onFileReject | - | ((details: FileRejectDetails) => void) | undefinedFunction called when the file is rejected |
capture | - | "user" | "environment" | undefinedThe default camera to use when capturing media |
directory | - | boolean | undefinedWhether to accept directories, only works in webkit browsers |
invalid | - | boolean | undefinedWhether the file input is invalid |
transformFiles | - | ((files: File[]) => Promise<File[]>) | undefinedFunction to transform the accepted files to apply transformations |
locale | "en-US" | string | undefinedThe current locale. Based on the BCP 47 definition. |
dir | "ltr" | "ltr" | "rtl" | undefinedThe document's text/writing direction. |
getRootNode | - | (() => ShadowRoot | Node | Document) | undefinedA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
RootProvider
| Property | Default | Type |
|---|---|---|
value | - | FileUploadApi<PropTypes> |
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
RootContext
| Property | Default | Type |
|---|---|---|
children | - | (fileUpload: FileUploadApi<PropTypes>) => ReactNode |
Label
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"label">) => Element) | undefinedRender the element yourself |
Dropzone
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
Trigger
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"button">) => Element) | undefinedRender the element yourself |
HiddenInput
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"input">) => Element) | undefinedRender the element yourself |
ItemGroup
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"ul">) => Element) | undefinedRender the element yourself |
Item
| Property | Default | Type |
|---|---|---|
file | - | File |
type | - | ItemType | undefined |
element | - | ((attributes: HTMLAttributes<"li">) => Element) | undefinedRender the element yourself |
ItemName
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
ItemSizeText
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
ItemDeleteTrigger
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"button">) => Element) | undefinedRender the element yourself |