Skip to content

File upload ​

Chooses one file, or a few, to go with a form: a signed contract, photos of a job, a CSV to import.

vue
<script setup lang="ts">
import { FsField, FsFileUpload } from '@fivespark/ui'
import { ref } from 'vue'

const contract = ref<File | null>(null)
</script>

<template>
  <FsField label="Getekend contract" description="Een PDF van maximaal 10 MB" class="w-full max-w-md">
    <FsFileUpload v-model="contract" name="contract" accept=".pdf,application/pdf" :max-size="10_000_000" />
  </FsField>
</template>

Usage ​

vue
<script setup lang="ts">
import { FsField, FsFileUpload } from '@fivespark/ui'
import { ref } from 'vue'

const contract = ref<File | null>(null)
</script>

<template>
  <FsField label="Getekend contract" description="Een PDF van maximaal 10 MB">
    <FsFileUpload v-model="contract" name="contract" accept=".pdf,application/pdf" />
  </FsField>
</template>

It never sends a file; your form or your app does, and your server checks every file again. Say the accepted types and the size limit in the field's description, in words people use. Files already saved on the server are not shown here.

Examples ​

Several files ​

With multiple, a new choice adds to the list. maxFiles is the most the list holds; a choice that would pass it is refused whole.

vue
<script setup lang="ts">
import { FsField, FsFileUpload } from '@fivespark/ui'
import { ref } from 'vue'

const photos = ref<File[]>([])
</script>

<template>
  <FsField label="Foto's van het dak" description="Tot 5 foto's, elk maximaal 8 MB" class="w-full max-w-md">
    <FsFileUpload v-model="photos" name="fotos" multiple accept="image/*" :max-size="8_000_000" :max-files="5" />
  </FsField>
</template>

Invalid ​

A refused file (wrong type, too large, empty or too many) becomes the field's error by itself. Give the field an error for what you check yourself.

vue
<script setup lang="ts">
import { FsField, FsFileUpload } from '@fivespark/ui'
import { ref } from 'vue'

const contract = ref<File | null>(null)
</script>

<template>
  <FsField label="Getekend contract" description="Een PDF van maximaal 10 MB" error="Voeg het getekende contract toe" required class="w-full max-w-md">
    <FsFileUpload v-model="contract" name="contract" accept=".pdf,application/pdf" :max-size="10_000_000" />
  </FsField>
</template>

Disabled ​

vue
<script setup lang="ts">
import { FsField, FsFileUpload } from '@fivespark/ui'
import { ref } from 'vue'

const contract = ref<File | null>(null)
</script>

<template>
  <FsField label="Getekend contract" description="Pas mogelijk als de offerte is geaccepteerd" disabled class="w-full max-w-md">
    <FsFileUpload v-model="contract" name="contract" />
  </FsField>
</template>

Read-only ​

readonly on the field lists the files without letting them change.

vue
<script setup lang="ts">
import { FsField, FsFileUpload } from '@fivespark/ui'
import { ref } from 'vue'

const contract = ref<File | null>(new File(['%PDF-1.7'], 'contract.pdf', { type: 'application/pdf' }))
</script>

<template>
  <FsField label="Getekend contract" readonly class="w-full max-w-md">
    <FsFileUpload v-model="contract" name="contract-vast" />
  </FsField>
</template>

Dense ​

vue
<script setup lang="ts">
import { FsField, FsFileUpload } from '@fivespark/ui'
import { ref } from 'vue'

const csv = ref<File | null>(null)
</script>

<template>
  <FsField label="Klantenlijst" description="Een CSV-bestand met een klant per regel" size="dense" class="w-full max-w-md">
    <FsFileUpload v-model="csv" name="klanten" accept=".csv,text/csv" />
  </FsField>
</template>

Files can also be dropped on the picker. Name what the file is in the label ("Getekend contract"), not "Bestand uploaden".

Keyboard ​

KeyDoes
Enter, SpaceOpens the file picker
TabMoves to the remove button of the first chosen file
Enter, SpaceOn a remove button, removes that file and moves focus to the next one

API Reference ​

FsFileUpload ​

PropTypeDefaultDescription
multiplebooleanfalseSeveral files; a new choice adds to the list. Without it, a new choice replaces the file.
acceptstringThe types it takes, as the native attribute writes them: `application/pdf`, `image/*`, `.csv`, comma-separated. Give the extension beside a MIME type: some files arrive without a type. Say them in the field's hint too.
maxSizenumberThe largest file it takes, in bytes.
maxFilesnumberWith `multiple`, the most files it holds; a choice that would go past it is refused whole.
size"default" | "dense"`default` is 36px high; `dense` is 32px, for tables and toolbars. In a field, the field's.
idstringOnly outside a field; in one, it takes the field's.
invalidbooleanMarks the files as wrong; the field says why. In a field, the field's. A file it refused marks it regardless.
disabledbooleanUnavailable until something else is done: the files listed, nothing chosen or submitted. Files to see but not change are `readonly`. In a field, the field's.
readonlybooleanFiles to see, not change: listed, with no button and nothing submitted. In a field, the field's.
requiredbooleanIn a field, the field's, which also shows the asterisk.
modelValueFile | File[] | nullThe chosen file, or `null`; with `multiple`, the chosen files, `[]` when none. Without `v-model` it keeps its own.
EventPayloadDescription
update:modelValue[value: File | File[] | null | undefined]Sent with the new `modelValue`, for `v-model`.
reject[rejections: FileUploadRejection[]]The files a choice or a drop refused, and why: `type`, `size`, `empty` or `count`. The field already shows the first.