Sakuga Back to Sakuga
Theme
Sound
Jump to a component

Core · Forms

NumberField

NumberField is a number you type or step a unit at a time: its name, a step down, the value with its unit, a step up.

@anicanon/sakuga/uiv1.0Used onWeb

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Web only

NumberField is made for the web, and isn’t part of Sakuga for iOS yet.

Android

Web only

NumberField is made for the web, and isn’t part of Sakuga for Android yet.

Use it for
A number where one unit matters, typed or stepped a unit at a time: a 1px border, 2° of rotation, a font size.
Not for

Guidelines

  • Use it, not a slider, when one unit matters: a 1px border, 2° of rotation, a font size. A slider is for a feel (strength, mix), where the readout is the point.
  • unit follows the value ("px", "°", "pt"). Steps call onStep with −1 or +1; without onStep the buttons only draw, and readOnly turns them off.
  • What is typed goes to onChange as a number (the unit dropped, kept inside min and max) on Enter or leaving the field, and an arrow pressed after typing hands it over first. Without onChange, the field goes back to value.
  • In a narrow inspector stack one per row; two may share a row only when both fit at their longest value.
  • The value box is as wide as the value and its unit ("24.99 USD"), 72 px at least, and follows what is typed. A label longer than its room wraps onto a second line instead of running under the steps.
  • The value is a spinbutton: Up and Down step it through onStep, as the buttons do. min and max give the range a screen reader is told.
NumberFieldExample.jsxReact
import { NumberField } from '@anicanon/sakuga/ui';

export default function NumberFieldExample() {
  return (
    <>
      <NumberField label="Border" value={1} unit="px" />
      <NumberField label="Rotate" value={-6} unit="°" />
    </>
  );
}

PropsNumberFieldProps

labelrequired
string
valuerequired
string | number
unit
string
Shown after the value: a symbol on the number ("px", "°", "%"), a word after a space ("days", "fps").
onStep
(delta: -1 | 1) => void
Called with −1 or +1. Without it the buttons only draw.
onChange
(value: number) => void
Called with the typed number (unit dropped, inside min and max) on Enter or leaving the field; without it what is typed goes back to value.
readOnly
boolean
The value can't change: the buttons are off too.
id
string
className
string
min
number
The range a screen reader is told.
max
number
NumberFieldExample.swiftiOS · coming soon
NumberFieldExample.ktAndroid · coming soon

Each token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.

Colour

num-labelNumberField: the number's name.
text-mutedneutral-600#5c5b67
text-mutedneutral-400#a3a3a7
num-bgNumberField: the value box.
bg-canvasneutral-50#f6f6f8
bg-canvasneutral-950#07070a
num-borderNumberField: the value box's edge.
border-controlshade-a52rgba(11,10,16,0.52)
border-controlwhite-a45rgba(255,255,255,0.45)
num-fgNumberField: the value.
text-primaryneutral-925#0b0a10
text-primaryneutral-0#ffffff
num-focusNumberField: the value box's edge while typing.
accentcamellia-600#c2335f
accentcamellia-400#f4779f

Space and shape

num-gap
gap-md
8px
num-row-column-2
its own value
minmax(72px, max-content)
num-row-gap
gap-2xs
2px
num-input-height
size-control-sm
36px
num-input-padding-x
inset-sm
8px
num-input-radius
radius-sm
8px
num-input-inset-ring-width
line-hairline
1px
num-input-focus-inset-ring-width
line-strong
2px
num-forced-edge-width
line-hairline
1px
num-forced-focus-width
line-strong
2px

Type

num-label-font
text-micro
700 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
num-input-font
text-label
600 14px/20px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif

Checked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.

Result
No issues found, in light or in dark.
By design
A spinbutton named by label that takes typing, handed over on Enter or leaving it: Up and Down step it through onStep and its value is read with its unit, and min and max give its range. Tab also reaches the "Less" and "More" buttons on either side ("More duration"), whose steps are said aloud.
Not tested
The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.