Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
ARC UI ARC Radiant Components
v3.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip

Number Input

A numeric stepper input with decrement and increment buttons flanking a central text field, supporting min/max clamping, step increments, and keyboard shortcuts.

Components Number Input
input interactive
<arc-number-input>

Overview

NumberInput combines a native numeric text field with decrement and increment buttons to create a precise, user-friendly numeric stepper. The three elements are presented as a unified control with a shared border and rounded corners, where the buttons sit on either side of the input field separated by subtle inner borders. When the control receives focus, the entire border shifts to accent-primary with a focus ring, providing clear visual feedback. The component enforces value boundaries through automatic clamping. When `min` or `max` props are set, the value is clamped to stay within range, and the corresponding button becomes disabled and visually dimmed when the limit is reached. The `step` prop controls the increment granularity for both button clicks and keyboard interactions. Holding Shift while pressing arrow keys multiplies the step by 10, enabling quick large adjustments without repeated clicks. When a `label` is provided, it renders as an uppercase accent-font label above the control, connected to the input via a generated `id` and `for` attribute for accessibility. The events mirror the native control: typing fires `arc-input` alone on each keystroke, and the value commits with `arc-change` on blur or Enter. A stepper button click or an arrow key fires both, because each of those is an edit and a commit in one gesture. Every event carries the new value in its detail.

Guidelines

When to use

  • Use NumberInput when the user needs to enter or adjust an exact numeric value
  • Set `min` and `max` to prevent invalid values and provide clear boundary feedback
  • Choose a `step` that matches your data precision — 1 for integers, 0.1 for decimals
  • Provide a `label` so the input is properly announced by screen readers
  • Use the Shift+Arrow shortcut tip in help text for power users who need fast adjustments

When not to use

  • Do not use NumberInput for approximate values or large ranges — use Slider instead
  • Do not omit `min` and `max` when there are logical boundaries for the value
  • Do not set a `step` of 0 — it prevents the buttons from changing the value
  • Do not use NumberInput for non-numeric data like phone numbers — use a standard Input with a pattern
  • Avoid stacking many number inputs without labels — each one needs context for usability

Features

  • Inline decrement and increment buttons flanking a centered numeric text field
  • Automatic value clamping to `min` and `max` boundaries with buttons disabled at limits
  • Configurable `step` for increment granularity, with Shift+Arrow for 10x step multiplier
  • Focus-within styling applies accent-primary border and ring to the entire control group
  • Label rendered as uppercase accent-font text above the control with proper `for` association
  • Native `spinbutton` ARIA role with `aria-valuenow`, `aria-valuemin`, and `aria-valuemax`
  • Hides browser-native spin buttons for a clean cross-platform appearance
  • Disabled state at 40% opacity with pointer events blocked

Preview

Usage

This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.

<arc-number-input label="Quantity" value="3" min="1" max="99" step="1"></arc-number-input>
import { NumberInput } from '@arclux/arc-ui-react';

export default function Example() {
  return (
    <NumberInput label="Quantity" value={3} min={1} max={99} step={1} />
  );
}
<script setup>
import { NumberInput } from '@arclux/arc-ui-vue';
</script>

<template>
  <NumberInput label="Quantity" :value="3" :min="1" :max="99" :step="1" />
</template>
<script>
  import { NumberInput } from '@arclux/arc-ui-svelte';
</script>

<NumberInput label="Quantity" value={3} min={1} max={99} step={1} />
import { Component } from '@angular/core';
import { NumberInput } from '@arclux/arc-ui-angular';

@Component({
  imports: [NumberInput],
  template: `
    <arc-number-input label="Quantity" [value]="3" [min]="1" [max]="99" [step]="1"></arc-number-input>
  `,
})
export class MyComponent {}
import { NumberInput } from '@arclux/arc-ui-solid';

export default function Example() {
  return (
    <NumberInput label="Quantity" value={3} min={1} max={99} step={1} />
  );
}
import { NumberInput } from '@arclux/arc-ui-preact';

export default function Example() {
  return (
    <NumberInput label="Quantity" value={3} min={1} max={99} step={1} />
  );
}

API

size 'sm' | 'md' | 'lg' 'md'
Control size. `md` is the default; `sm` and `lg` scale the field padding.
value number 0
Current numeric value. Reflected as an attribute and updated on user interaction.
min number undefined
Minimum allowed value. The decrement button is disabled when the value reaches this limit.
max number undefined
Maximum allowed value. The increment button is disabled when the value reaches this limit.
step number 1
Increment and decrement step size. Arrow keys use this value, Shift+Arrow uses 10x this value.
label string ''
Label text displayed above the control in uppercase accent font.
name string ''
disabled boolean false
Disables interaction, reducing opacity to 40% and blocking pointer events.
readonly boolean false
Prevents value changes from typing, stepper buttons, and arrow keys while keeping the field focusable and its value submitted.
formAssociated boolean true
properties object { required: { type: Boolean, reflect: true }, readonly: { type: Boolean, reflect: true }, }
Lit merges static properties up the prototype chain, so every consumer gets these without declaring them. `required` participates in constraint validation below; `readonly` reflects for styling and is enforced by each component's interaction handlers (the mixin can't know which gestures mutate state).
autoValidates boolean true
Components that run their own constraint-validation logic (pattern checks, range checks) opt out of the automatic required sync by overriding this to false, and own the whole validity flag set instead.
form
validity
validationMessage
required boolean false

Events

arc-input detail: { value: number }
Fired on every edit, including each keystroke while typing. Use for live previews.
arc-change detail: { value: number }
Fired when the value is committed: blur or Enter after typing, or immediately on a stepper click or arrow key, which are edit and commit in one gesture.

See Also