Skip to content

Input ​

A single line of text: a name, a reference, an email address, a search term or a password.

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

const bedrijf = ref('')
</script>

<template>
  <FsField label="Bedrijfsnaam" class="w-full max-w-sm">
    <FsInput v-model="bedrijf" autocomplete="organization" />
  </FsField>
</template>

Usage ​

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

const naam = ref('')
</script>

<template>
  <FsField label="Bedrijfsnaam">
    <FsInput v-model="naam" />
  </FsField>
</template>

Put the input in a Field, which gives it its label, description and error. Without one, give it an aria-label. For several lines use Textarea; for amounts and quantities use Number input; for a choice from a list use Select.

Examples ​

Types ​

type is text, email, tel, url, search or password. Add autocomplete for fields about the person filling in the form.

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

const email = ref('')
const telefoon = ref('')
</script>

<template>
  <div class="flex w-full max-w-sm flex-col gap-4">
    <FsField label="E-mailadres" description="Hier sturen we de offerte naartoe.">
      <FsInput v-model="email" type="email" autocomplete="email" />
    </FsField>
    <FsField label="Telefoonnummer">
      <FsInput v-model="telefoon" type="tel" autocomplete="tel" />
    </FsField>
  </div>
</template>

A search field takes a placeholder, which no other type does. It has no label of its own, so name it with aria-label.

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

const zoek = ref('')
</script>

<template>
  <FsInput
    v-model="zoek"
    type="search"
    aria-label="Zoek in offertes"
    leading-icon="search"
    placeholder="Zoek op klant of offertenummer"
    class="w-full max-w-sm"
  />
</template>

Password ​

A button inside the field shows or hides the password.

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

const wachtwoord = ref('')
</script>

<template>
  <FsField label="Wachtwoord" class="w-full max-w-sm">
    <FsInput v-model="wachtwoord" type="password" />
  </FsField>
</template>

Character count ​

maxLength is a limit that counts: typing past it is allowed, and the field turns invalid and says by how many characters. Mention the limit beforehand when it matters.

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

const referentie = ref('Renovatie Jansen')
</script>

<template>
  <FsField label="Referentie" class="w-full max-w-sm">
    <FsInput v-model="referentie" :max-length="20" />
  </FsField>
</template>

Invalid ​

Give the field an error; it marks the input invalid and shows the message. Clear it as soon as the value is fixed.

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

const email = ref('info@jansen')
</script>

<template>
  <FsField label="E-mailadres" error="Vul een geldig e-mailadres in, zoals naam@bedrijf.nl." class="w-full max-w-sm">
    <FsInput v-model="email" type="email" />
  </FsField>
</template>

Read-only and disabled ​

A read-only input can be focused, selected and copied, and is submitted. A disabled one is none of these. Say why in the description.

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

<template>
  <div class="flex w-full max-w-sm flex-col gap-4">
    <FsField label="Offertenummer" readonly description="Het nummer wordt automatisch toegekend.">
      <FsInput model-value="2026-041" />
    </FsField>
    <FsField label="Klant" disabled description="Een verstuurde offerte kan niet van klant wisselen.">
      <FsInput model-value="Bouwbedrijf Jansen" />
    </FsField>
  </div>
</template>

Dense ​

For tables, toolbars and other tight places.

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

const projectnaam = ref('')
</script>

<template>
  <FsField label="Projectnaam" size="dense" class="w-full max-w-sm">
    <FsInput v-model="projectnaam" />
  </FsField>
</template>

Keyboard ​

KeyDoes
EscIn a search field, clears the text
Enter, SpaceOn the password's show button, shows or hides the password

API Reference ​

FsInput ​

PropTypeDefaultDescription
type"search" | "text" | "email" | "tel" | "url" | "password""text"The kind of text. Never a number to calculate with: that has a component of its own.
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 value as wrong; the field says why. In a field, the field's. Over `maxLength` it is invalid regardless.
disabledbooleanUnavailable until something else is done: not focusable, not submitted. A value to see but not change is `readonly`. In a field, the field's.
readonlybooleanA value to see and copy, not change: shown as plain text. In a field, the field's.
requiredbooleanIn a field, the field's, which also shows the asterisk.
leadingIcon"info" | "plus" | "pencil" | "trash" | "copy" | "x" | "download" | "upload" | "search" | "funnel" | "check" | "minus" | "external-link" | "eye" | "eye-off" | "settings" | "log-out" | "ellipsis" | "chevron-down" | "chevron-up" | "chevron-left" | "chevron-right" | "arrow-left" | "arrow-right" | "arrow-up" | "arrow-down" | "arrow-up-down" | "layout-dashboard" | "menu" | "circle-check" | "circle-x" | "triangle-alert" | "circle-question-mark" | "loader-circle" | "calculator" | "file-text" | "user" | "building" | "package" | "truck" | "euro" | "percent" | "clock" | "calendar" | "database" | "chart-column"A decorative icon before the value, such as `search`.
maxLengthnumberA limit that counts down below the field and can be exceeded, so a paste is never cut short; over it the field is invalid.
placeholderstringOnly on `type="search"`. A format or an example goes in the field's hint.
revealTexts{ show?: string | undefined; hide?: string | undefined; shown?: string | undefined; hidden?: string | undefined; }Replaces the reveal's names, "Wachtwoord tonen" and "Wachtwoord verbergen", and what it announces, "Je wachtwoord is zichtbaar" and "verborgen".
countTexts{ limit?: ((max: number) => string) | undefined; remaining?: ((n: number) => string) | undefined; over?: ((n: number) => string) | undefined; }Replaces the count's messages, each a function of the number: the hidden limit, the characters left, the characters over.
modelValuestringThe text. Without `v-model` it keeps its own.
EventPayloadDescription
update:modelValue[value: string | undefined]Sent with the new `modelValue`, for `v-model`.