Appearance
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>Search
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
| Key | Does |
|---|---|
| Esc | In a search field, clears the text |
| Enter, Space | On the password's show button, shows or hides the password |
API Reference
FsInput
| Prop | Type | Default | Description |
|---|---|---|---|
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. | |
id | string | Only outside a field; in one, it takes the field's. | |
invalid | boolean | Marks the value as wrong; the field says why. In a field, the field's. Over `maxLength` it is invalid regardless. | |
disabled | boolean | Unavailable until something else is done: not focusable, not submitted. A value to see but not change is `readonly`. In a field, the field's. | |
readonly | boolean | A value to see and copy, not change: shown as plain text. In a field, the field's. | |
required | boolean | In 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`. | |
maxLength | number | A limit that counts down below the field and can be exceeded, so a paste is never cut short; over it the field is invalid. | |
placeholder | string | Only 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. | |
modelValue | string | The text. Without `v-model` it keeps its own. |
| Event | Payload | Description |
|---|---|---|
update:modelValue | [value: string | undefined] | Sent with the new `modelValue`, for `v-model`. |