logo-icon
STWUI

FilePicker

FilePicker is a an input field for uploading files.

Basic
cloud-upload

Upload a profile picture

Drag & Drop your file



svelte
<script lang="ts">
   import { FilePicker } from 'stwui';
</script>

<FilePicker onDrop={(files) => console.log(files)}>
	<FilePicker.Icon slot="icon" data={cloud_upload} />
	<FilePicker.Title slot="title">Upload a profile picture</FilePicker.Title>
	<FilePicker.Description slot="description">Drag & Drop your file</FilePicker.Description>
</FilePicker>
Complete
cloud-upload

Upload a profile picture

Drag & Drop your file

or



svelte
<script lang="ts">
	import { FilePicker } from 'stwui';

	function handleButtonClick(event: Event) {
		event.stopPropagation();
		console.log('Inner button clicked');
	}
</script>

<FilePicker onDrop={(files) => console.log(files)}>
	<FilePicker.Icon slot="icon" data={cloud_upload} />
	<FilePicker.Title slot="title">Upload a profile picture</FilePicker.Title>
	<FilePicker.Description slot="description">Drag & Drop your file</FilePicker.Description>
	<FilePicker.Divider slot="divider" class="mx-[20%]">
		<FilePicker.Divider.Label slot="label"><h4>or</h4></FilePicker.Divider.Label>
	</FilePicker.Divider>
	<FilePicker.Action slot="action">
		<Button type="primary" on:click={handleButtonClick}>Select from vault</Button>
	</FilePicker.Action>
</FilePicker>
Multiple
cloud-upload

Upload multiple files



svelte
<script lang="ts">
   import { FilePicker } from 'stwui';
</script>

<FilePicker onDrop={(files) => console.log(files)} multiple>
	<FilePicker.Icon slot="icon" data={cloud_upload} />
	<FilePicker.Title slot="title">Upload multiple files</FilePicker.Title>
</FilePicker>
Disabled
cloud-upload

Cannot upload anything here



svelte
<script lang="ts">
   import { FilePicker } from 'stwui';
</script>

<FilePicker onDrop={(files) => console.log(files)} disabled>
	<FilePicker.Icon slot="icon" data={cloud_upload} class="filter-gray-500" />
	<FilePicker.Title slot="title">Cannot upload anything here</FilePicker.Title>
</FilePicker>
With FilePreview
cloud-upload

Upload multiple images

Drag & Drop an image to preview it



svelte
<script lang="ts">
	import { FilePicker, List, Button, Progress } from 'stwui';
	import { formatFileSize } from 'stwui/utils';
	import type { DropResult } from 'stwui/types';
	import { slide } from 'svelte/transition';
	

	interface ImageFile {
		file: File;
		src: string;
		progress: number | undefined;
	}

	let myFiles: ImageFile[] = [];
	let errors: string[] = [];

	function handleButtonClick(event: Event) {
		event.stopPropagation();
		console.log('Inner button clicked');
	}

	/* Push the files to the array with a preview URL */
	function onDrop(files: DropResult) {
		let newFiles = files.accepted.map((file) => ({
			file,
			src: URL.createObjectURL(file),
			progress: undefined
		}));

		myFiles = [...myFiles, ...newFiles];
		errors = files.rejected.map((file) => file.name);
	}

	/* Remove the file from the array if it exists */
	function removeFile(file: ImageFile) {
		URL.revokeObjectURL(file.src);
		myFiles = [
			...myFiles.slice(0, myFiles.indexOf(file)),
			...myFiles.slice(myFiles.indexOf(file) + 1)
		];
	}

	async function uploadFile(myFile: ImageFile){
		/* Your upload implementation */
	}
</script>

<FilePicker
	{onDrop}
	multiple
	accept="image/*"
	allowedExtensions={['png', 'jpg', 'jpeg', 'gif']}
>
	<FilePicker.Icon slot="icon" data={cloud_upload} />
	<FilePicker.Title slot="title">Upload multiple images</FilePicker.Title>
	<FilePicker.Description slot="description">Drag & Drop an image to preview it</FilePicker.Description>
</FilePicker>

{#if errors.length > 0}
	<span class="text-md text-danger">
		Error uploading the following files: {errors.join(', ')}
	</span>
{/if}

<List>
	{#each myFiles as myFile, index}
		{@const { file, src, progress } = myFile}
		<div transition:slide>
			<List.Item>
				<List.Item.Leading slot="leading">
					{#if file.type.startsWith('image/')}
						<List.Item.Leading.Avatar slot="avatar" {src} alt={file.name} />
					{/if}
				</List.Item.Leading>
				<List.Item.Content slot="content">
					<List.Item.Content.Title slot="title">{file.name}</List.Item.Content.Title>
					<List.Item.Content.Description slot="description" class="w-full">
						{#if progress != null}
							<Progress value={parseFloat(progress.toFixed(0))} displayValue />
						{:else}
							{formatFileSize(file.size)}
						{/if}
					</List.Item.Content.Description>
				</List.Item.Content>
				<List.Item.Extra slot="extra" placement="start">
					{#if progress === 100}
						<Button>
							<Button.Icon slot="icon" class="text-primary" data={check} />
						</Button>
					{:else}
						{#if progress == null}
							<Button on:click={() => uploadFile(myFile)}>
								<Button.Icon slot="icon" data={play} />
							</Button>
						{/if}
						<Button on:click={() => removeFile(myFile)}>
							<Button.Icon slot="icon" data={close} />
						</Button>
					{/if}
				</List.Item.Extra>
			</List.Item>
		</div>
	{/each}
</List>

{#if myFiles.length > 0}
	<div class="flex justify-end">
		<Button
			type="primary"
			loading={uploading}
			disabled={uploading}
			on:click={uploadAllFiles}
		>
			{uploading ? 'uploading ...' : 'Begin upload'}
		</Button>
	</div>
{/if}
Implementation with animation
cloud-upload


svelte
<script lang="ts">
   import { FilePicker, Progress, Button } from 'stwui';

	let minFile: File | undefined;
	let minUploading: boolean = false;
	let minProgress: number | undefined = undefined;

	async function minimalisticDrop(files: DropResult) {
		if (!files.accepted.length) return;

		minUploading = true;
		minFile = files.accepted[0];

		/* TODO: Upload the file to your server*/

		minUploading = false;
	}

</script>


<div class="flex flex-col w-full justify-center items-center">
	{#if minUploading && minProgress != null}
		<span in:fade class="w-full flex justify-center items-center">
			<Progress value={parseFloat(minProgress.toPrecision(2))} radial />
		</span>
	{:else if !minUploading && minFile}
		<div class="flex items-center space-x-2">
			<h4 transition:slide><b>{minFile.name}</b> was uploaded successfully!</h4>
			<Button on:click={resetMinimalistic}>
				<Button.Icon slot="icon" data={close} />
			</Button>
		</div>
	{:else}
		<FilePicker
			class="w-1/4 aspect-square flex flex-col justify-center"
			onDrop={(files) => minimalisticDrop(files)}
		>
			<FilePicker.Icon slot="icon" data={cloud_upload} class="filter-gray-500" />
		</FilePicker>
	{/if}
</div>

FilePicker Props

name string
onDrop function(files: DropResult)
onEnter function | null null
onLeave function | null null
accept string | undefined undefined
allowedExtensions string[] | undefined undefined
maxFileSize number | undefined undefined
multiple boolean false
strict boolean false
border boolean true

FilePicker Slots

icon <FilePicker.Icon slot="icon" />
title <FilePicker.Title slot="title" />
description <FilePicker.Description slot="description" />
divider <FilePicker.Divider slot="divider" />
action <FilePicker.Action slot="action" />

FilePicker.Icon Props

data string (IconData)
viewBox string 0 0 24 24
size string 24px
width string 24px
height string 24px
color string currentColor
stroke string | undefined
fill string currentColor

FilePicker.Title Slots

default

FilePicker.Description Slots

default

FilePicker.Divider Slots

label <FilePicker.Divider.Label slot="label"/>
default

FilePicker.Divider Props

position 'left' | 'center' | 'right' center

FilePicker.Divider.Label Slots

default

FilePicker.Action Slots

default