Number Field

PohonGitHub
A number field allows a user to enter a number and increment or decrement the value using stepper buttons.
<script setup lang="ts">
import { ANumberFieldDecrement, ANumberFieldIncrement, ANumberFieldInput, ANumberFieldRoot } from 'akar';
</script>

<template>
  <ANumberFieldRoot
    id="age"
    :min="0"
    :default-value="18"
    class="inline-flex items-center relative"
  >
    <div class="ps-1 flex items-center start-0 inset-y-0 absolute">
      <ANumberFieldDecrement class="text-sm color-primary font-medium px-2.5 py-1.5 rounded-md inline-flex gap-1.5 transition-colors-280 items-center active:color-primary/75 aria-disabled:(color-primary opacity-75 cursor-not-allowed) disabled:(color-primary opacity-75 cursor-not-allowed) hover:color-primary/75 focus:outline-none focus-visible:(ring-2 ring-primary ring-inset) akar:p-1.5">
        <i class="i-lucide:minus shrink-0 size-5" />
      </ANumberFieldDecrement>
    </div>
    <ANumberFieldInput class="text-sm color-text-highlighted px-2.5 py-1.5 pe-9 ps-9 text-center border-0 rounded-md bg-background gap-1.5 w-full ring ring-ring-accented ring-inset transition-colors-280 placeholder:color-text-dimmed focus:outline-none disabled:(opacity-75 cursor-not-allowed) focus-visible:(ring-2 ring-primary ring-inset)" />
    <div class="pe-1 flex items-center end-0 inset-y-0 absolute">
      <ANumberFieldIncrement class="text-sm color-primary font-medium px-2.5 py-1.5 rounded-md inline-flex gap-1.5 transition-colors-280 items-center active:color-primary/75 aria-disabled:(color-primary opacity-75 cursor-not-allowed) disabled:(color-primary opacity-75 cursor-not-allowed) hover:color-primary/75 focus:outline-none focus-visible:(ring-2 ring-primary ring-inset) akar:p-1.5">
        <i class="i-lucide:plus shrink-0 size-5" />
      </ANumberFieldIncrement>
    </div>
  </ANumberFieldRoot>
</template>

Features

  • Full keyboard navigation.
  • Can be controlled or uncontrolled.
  • Support button hold and wheel event.
  • Support numbering systems in different locale.
  • Customizable formatting.
pnpm add @internationalized/number

Anatomy

Import all parts and piece them together.

<script setup>
import { ANumberFieldDecrement, ANumberFieldIncrement, ANumberFieldInput, ANumberFieldRoot } from 'akar';
</script>

<template>
  <ANumberFieldRoot>
    <ANumberFieldDecrement />
    <ANumberFieldInput />
    <ANumberFieldIncrement />
  </ANumberFieldRoot>
</template>

Pohon

One benefit of using Akar is its flexibility and low-level control over the components. However, this also means that you may need to manually construct more complex UI elements by combining multiple Akar components together.

If you feel there's a lot of elements that needs to be constructed manually using Akar, consider using Pohon UI instead. It provides a higher-level abstraction over Akar components with pre-defined styles and behaviors that can help you build UIs faster.

API Reference

Root

Contains all the parts of a number field. An input will also render when used within a form to ensure events propagate correctly.

Props

Prop Default Type
as'div'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

defaultValuenumber
disabledboolean

When true, prevents the user from interacting with the Number Field.

disableWheelChangeboolean

When true, prevents the value from changing on wheel scroll.

formatOptionsIntl.NumberFormatOptions

Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user.

idstring

Id of the element

invertWheelChangeboolean

When true, inverts the direction of the wheel change.

localestring

The locale to use for formatting dates

maxnumber

The largest value allowed for the input.

minnumber

The smallest value allowed for the input.

modelValuenumber | null
namestring

The name of the field. Submitted with its owning form as part of a name/value pair.

readonlyboolean

When true, the Number Field is read-only.

requiredboolean

When true, indicates that the user must set the value before the owning form can be submitted.

step1number

The amount that the input value changes with each increment or decrement 'tick'.

stepSnappingtrueboolean

When false, prevents the value from snapping to the nearest increment of the step value

Emits

Event Type
update:modelValue[val: number]

Event handler called when the value changes.

Slots

Slot Type
modelValuenumber
textValuestring

Data Attributes

Attribute Value
[data-disabled]Present when disabled

Input

Input

The input component that renders the text value based on value and format options.

Props

Prop Default Type
as'input'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

Data Attributes

Attribute Value
[data-disabled]Present when disabled

Increment

The button that increases the value.

Props

Prop Default Type
as'button'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

disabledboolean

Data Attributes

Attribute Value
[data-disabled]Present when disabled
[data-pressed]Present when pressed

Decrement

The button that decreases the value.

Props

Prop Default Type
as'button'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

disabledboolean

Data Attributes

Attribute Value
[data-disabled]Present when disabled
[data-pressed]Present when pressed

Example

Decimal

All options supported by Intl.NumberFormat are supported, including configuration of minimum and maximum fraction digits, sign display, grouping separators, etc.

<template>
  <ANumberFieldRoot
    :default-value="5"
    :format-options="{
      signDisplay: 'exceptZero',
      minimumFractionDigits: 1,
    }"
  >
  </ANumberFieldRoot>
</template>

Percentage

You can set formatOptions.style to percent to treat the value as a percentage. You need to set the step to 0.01 manually to allow an appropriate step size in this mode.

<template>
  <ANumberFieldRoot
    :default-value="0.05"
    :step="0.01"
    :format-options="{
      style: 'percent',
    }"
  >
  </ANumberFieldRoot>
</template>

Currency

You can set formatOptions.style to currency to treat the value as a currency value. The currency option must also be passed to set the currency code (e.g., USD).

If you need to allow the user to change the currency, you should include a separate dropdown next to the number field. The number field itself will not determine the currency from the user input.

<template>
  <ANumberFieldRoot
    :default-value="5"
    :format-options="{
      style: 'currency',
      currency: 'EUR',
      currencyDisplay: 'code',
      currencySign: 'accounting',
    }"
  >
  </ANumberFieldRoot>
</template>

Accessibility

Adheres to the Spinbutton WAI-ARIA design pattern.

Keyboard Interactions

Key Description
ArrowUp

Increase the value

ArrowDown

Decrease the value

PageUp

Increase the value by scale of 10

PageDown

Decrease the value by scale of 10

Home

Set value to minimum (if min is provided)

End

Set value to maximum (if max is provided)