Skip to content

Number input ​

A field for an amount, a quantity or a percentage that people type, read in the format of their language.

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

const prijs = ref<number | null>(1234.56)
</script>

<template>
  <FsField label="Prijs" class="w-full max-w-xs">
    <FsNumberInput v-model="prijs" :format-options="{ style: 'currency', currency: 'EUR' }" />
  </FsField>
</template>

Usage ​

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

const aantal = ref<number | null>(1)
</script>

<template>
  <FsField label="Aantal">
    <FsNumberInput v-model="aantal" :min="1" />
  </FsField>
</template>

The value is a number, or null when the field is empty or its text cannot be read. The text is read when the field loses focus or on Enter, so people may type "1.234,56" or "€ 1234,56". formatOptions takes any Intl.NumberFormat options: a currency shows its symbol and two decimals. Use Input for text such as a postcode or an ordernumber that is not calculated with.

Examples ​

Steppers with a limit ​

steppers adds minus and plus buttons, for quantities. min and max stop the buttons at the limits and report an out-of-range value; unit adds a word the format does not give.

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

const aantal = ref<number | null>(12)
</script>

<template>
  <FsField label="Aantal" class="w-full max-w-xs">
    <FsNumberInput v-model="aantal" unit="stuks" :min="1" :max="99" steppers />
  </FsField>
</template>

Percentage ​

The value is in points: 7.5 is 7,5%. Typed text is read as points too.

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

const korting = ref<number | null>(7.5)
</script>

<template>
  <FsField label="Korting" description="Typ 7,5 voor 7,5%." class="w-full max-w-xs">
    <FsNumberInput v-model="korting" :format-options="{ style: 'percent', maximumFractionDigits: 1 }" :max="100" />
  </FsField>
</template>

Unit ​

The unit is shown after the value and read out as part of the label.

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

const oppervlakte = ref<number | null>(18.5)
</script>

<template>
  <FsField label="Oppervlakte" class="w-full max-w-xs">
    <FsNumberInput v-model="oppervlakte" unit="m²" :format-options="{ maximumFractionDigits: 1 }" />
  </FsField>
</template>

Aligned to the end ​

align="end" lines up the figures in a column of amounts.

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

const bedrag = ref<number | null>(250)
</script>

<template>
  <FsField label="Bedrag per eenheid" class="w-full max-w-xs">
    <FsNumberInput v-model="bedrag" align="end" :format-options="{ style: 'currency', currency: 'EUR' }" />
  </FsField>
</template>

Invalid ​

The field reports text it cannot read or that is out of range by itself. Your own validation goes through the error of the surrounding field.

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

const aantal = ref<number | null>(120)
</script>

<template>
  <FsField label="Aantal" error="Er zijn nog 80 stuks op voorraad." class="w-full max-w-xs">
    <FsNumberInput v-model="aantal" />
  </FsField>
</template>

Read-only ​

readonly on the field shows the value without letting it change; the steppers disappear.

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

const aantal = ref<number | null>(12)
</script>

<template>
  <FsField label="Aantal" readonly class="w-full max-w-xs">
    <FsNumberInput v-model="aantal" unit="stuks" steppers />
  </FsField>
</template>

Keyboard ​

KeyDoes
↑, ↓Raises or lowers the value by one step, within min and max
Page Up, Page DownRaises or lowers it by ten steps
EnterReads the typed text

API Reference ​

FsNumberInput ​

PropTypeDefaultDescription
formatOptionsIntl.NumberFormatOptionsHow the number is shown, in the app's language: `{ style: 'currency', currency: 'EUR' }`, `{ style: 'percent' }`, `{ maximumFractionDigits: 0 }`. Its maximum fraction digits are the most decimals it takes: 2 for euros, 3 for a plain number, 0 for a percentage.
minnumber0The lowest value it takes; below it the field says so. Negatives only when this is below 0.
maxnumberThe highest value it takes; above it the field says so.
stepnumber1How far the arrow keys and the steppers move it. A typed value is never rounded to it.
steppersbooleanfalseA minus and a plus at the end, for a quantity; never for an amount of money.
align"start" | "end""start"`end` lines the value up at the end, for a column of amounts in a table.
unitstringA unit shown after the value and spoken after the label, such as "stuks" or "m²". A currency or a percentage shows its own sign.
namestringSubmits the value with a form, as "1234.56", whatever the language; a percentage as its points, "25".
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. Text it cannot take is invalid regardless, once left.
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, such as a calculated total: shown as plain text. In a field, the field's.
requiredbooleanIn a field, the field's, which also shows the asterisk.
errorTexts{ unreadable?: ((example: string) => string) | undefined; ambiguous?: ((thousands: string, decimal: string) => string) | undefined; tooLow?: ((min: string) => string) | undefined; tooHigh?: ((max: string) => string) | undefined; between?: ((min: string, max: string) => string) | undefined; tooPrecise?: ((digits: number) => string) | undefined; wholeNumber?: (() => string) | undefined; }Replaces its error messages, each a function of the numbers as the field shows them: an example, the two readings of "1.234", the limits, the decimals.
stepperTexts{ decrease?: string | undefined; increase?: string | undefined; }Replaces the words the steppers' names add to the label, "verlagen" and "verhogen".
modelValuenumber | nullThe number; `null` when empty, or when the text cannot be taken. A percentage in points: 25 is 25%. Without `v-model` it keeps its own.
EventPayloadDescription
update:modelValue[value: number | null | undefined]Sent with the new `modelValue`, for `v-model`.