--- title: Number Field description: Number fields collect numeric input with increment/decrement steppers, locale formatting, and min/max constraints. category: Forms --- import { meta as NumberFieldMeta, Default } from '@/content/stories/number-field'; import Canvas from '@/components/component-docs/canvas'; import Demo from '@/components/component-docs/demo'; export const config = { dependencies: { components: [Canvas, Demo], scripts: [ '../../components/component-docs/demo.script.tsx', '../../components/component-docs/canvas.script.tsx', '../../components/component-docs/controls.script.tsx', ], }, }; # Number Field

Number fields collect numeric input with increment/decrement steppers, locale formatting, and min/max constraints.

## Try it ## Usage Set `minValue`, `maxValue`, and `step` to constrain input. Compose with `RuiNumberFieldGroup` and stepper buttons for the full pattern. ```tsx import { RuiNumberField, RuiNumberFieldGroup, RuiNumberFieldInput, RuiNumberFieldDecrementButton, RuiNumberFieldIncrementButton, RuiNumberFieldSteppers, } from '@ecopages/radiant-ui/number-field'; ``` ## Custom markup `` coordinates any light-DOM tree that matches its query contract. The `RuiNumberField` helpers stamp these targets; they are not required. ```tsx import '@ecopages/radiant-ui/number-field';
``` BEM classes are presentation-only. The host owns formatted input `value` and spinbutton `aria-*`. Set `name` on the host to submit the raw number with a native form (not the formatted display string). ## Step and commit behavior

`commitBehavior` controls whether out-of-range typed values snap to bounds or reject on blur.

## Disable scroll wheel

Set `wheelDisabled` to prevent accidental value changes when users scroll over a focused number field.

## Theming Number field surfaces map to **semantic surface roles**, never Tailwind palette steps: | Part | CSS roles | | --- | --- | | Group (`.rui-number-field__group`) | `border`, `background`, `rounded-control` | | Input (`.rui-number-field__input`) | `on-background` text | | Steppers (`.rui-number-field__steppers`) | `border` divider | | Stepper (`.rui-number-field__stepper`) | `on-surface`, `surface` hover, `surface-container-low` active | | Focus / invalid | `focus-ring` / `error` | Geometry shares control tokens (`--size-control-sm`, `--space-control-*`, `--radius-control`, `--text-control`) with `RuiInput` and `RuiButton` so form rows align. Override at the theme layer, not in component CSS. ## API `RuiNumberField` is a custom element (``). Standalone it renders the default input + stepper row; compose the view helpers for full control. ### Attributes | Attribute | Type | Default | Description | | --- | --- | --- | --- | | `value` | `number` | | Current value. | | `default-value` | `number` | | Initial value when uncontrolled. | | `min-value` | `number` | `-Infinity` | Lower bound; steppers and arrow keys snap to it. | | `max-value` | `number` | `Infinity` | Upper bound; steppers and arrow keys snap to it. | | `step` | `number` | `1` | Increment/decrement and snap interval. | | `disabled` | `boolean` | `false` | Disables input and steppers. | | `read-only` | `boolean` | `false` | Blocks editing; the value still displays formatted. | | `label` | `string` | `''` | Accessible name when there is no visible `RuiLabel`. | | `name` | `string` | `''` | Form field name on this host. Submits the raw number, not the formatted display. | | `locale` | `string` | `''` | BCP 47 locale tag, or comma-separated fallback list. | | `format-options` | `string` | `''` | JSON-serialized `Intl.NumberFormatOptions`. | | `commit-behavior` | `snap` ยท `validate` | `snap` | Blur behavior after editing. | | `increment-aria-label` | `string` | `Increment` | Accessible name for the increment stepper. | | `decrement-aria-label` | `string` | `Decrement` | Accessible name for the decrement stepper. | | `wheel-disabled` | `boolean` | `false` | Disables scroll-wheel value changes. | ### Light-DOM contract | Target | Required | Host writes | Author owns | | --- | --- | --- | --- | | `[data-number-field-input]` | yes | `id`, `role`, `inputmode`, `data-disabled`, `data-readonly`, `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, formatted `value` | text input; stamp `data-rui-control` for field wiring | | `[data-number-field-action="decrement"]` | no | `disabled`, `aria-label` | decrement button | | `[data-number-field-action="increment"]` | no | `disabled`, `aria-label` | increment button | | `[data-number-field-group]` | no | โ€” | presentation wrapper only | Nested hosts: none. ### Events | Event | Detail | Description | | --- | --- | --- | | `rui-change` | `{ value: number }` | Emitted when a value is committed (blur, stepper, or keyboard). | ### View helpers | Component | Target stamped | Notes | | --- | --- | --- | | `RuiNumberField` | default group when `children` omitted | Includes input and steppers. | | `RuiNumberFieldGroup` | `[data-number-field-group]` | Presentation only; not queried. | | `RuiNumberFieldInput` | `[data-number-field-input]` | Always stamps `data-rui-control`. | | `RuiNumberFieldIncrementButton` | `[data-number-field-action="increment"]` | Default label "Increment". | | `RuiNumberFieldDecrementButton` | `[data-number-field-action="decrement"]` | Default label "Decrement". | | `RuiNumberFieldSteppers` | stepper column wrapper | Presentation only. | ### CSS classes Public BEM classes (documented via `@cssclass`): | Class | Description | | --- | --- | | `.rui-number-field` | Root field wrapper. | | `.rui-number-field__group` | Control-height bordered row. | | `.rui-number-field__input` | Borderless text input. | | `.rui-number-field__steppers` | Trailing stepper column. | | `.rui-number-field__stepper` | Icon button cell (`+` / `โˆ’`). | ### Theme roles | Part | CSS variables consumed | | --- | --- | | Group | `--border`, `--background`, `--radius-control`, `--duration-normal` | | Input | `--on-background`, `--space-control-x`, `--space-control-y`, `--text-control` | | Steppers | `--size-control-sm` | | Stepper states | `--on-surface`, `--surface`, `--surface-container-low` | | Focus / invalid | `--focus-ring` / `--error` | ## Accessibility - Stepper buttons need accessible names; "Increment" and "Decrement" are provided by default. - Announce min and max constraints in helper text when the valid range is not obvious. - Disabled fields should explain why editing is unavailable.