Number Input
A number field formatted at rest in the reader's locale, with steppers you can hold, arrows, bounds and precision.
Rendering Number Input…
Installation
Copy the source into your project with the CLI. It lands under @/components/ui and is yours to edit.
npx mlola-ui add number-inputUsage
import { NumberInput } from "@/components/ui/number-input";
export default function Example() {
return <NumberInput label="Seats" defaultValue={5} min={1} max={50} hint="Up to 50 on this plan." locale="en-US" />;
}Styling comes from the engine stylesheet and the nearest theme. Set it once at the root:
<html data-theme="graphite" data-mode="light">HTML
The markup the example above renders, at rest. The interaction lives in the React component; from another framework, set the attributes below as the state changes.
<div class="ml-input-field ml-number-input">
<label class="ml-input-label" id="number-input-1-label" for="number-input-1">Seats</label>
<div class="ml-number-input-control">
<input class="ml-number-input-field" id="number-input-1" role="spinbutton" inputMode="decimal" autoComplete="off" aria-valuenow="5" aria-valuemin="1" aria-valuemax="50" aria-valuetext="5" aria-describedby="number-input-1-hint" value="5"/>
<span class="ml-number-input-buttons"><button class="ml-number-input-step" type="button" tabindex="-1" aria-label="Decrease"><svg class="mlola-glyph" width="0.9em" height="0.9em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="var(--mlola-glyph-stroke, var(--ml-icon-stroke, 1.75))" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true" data-optical-size="default" style="color:var(--mlola-glyph-color, currentColor);scale:var(--mlola-glyph-optical-scale, 1);transform-origin:center"><path d="M5 12h14" pathLength="1"></path></svg></button><button class="ml-number-input-step" type="button" tabindex="-1" aria-label="Increase"><svg class="mlola-glyph" width="0.9em" height="0.9em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="var(--mlola-glyph-stroke, var(--ml-icon-stroke, 1.75))" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true" data-optical-size="default" style="color:var(--mlola-glyph-color, currentColor);scale:var(--mlola-glyph-optical-scale, 1);transform-origin:center"><path d="M12 5v14M5 12h14" pathLength="1"></path></svg></button></span>
</div>
<p class="ml-input-hint" id="number-input-1-hint">Up to 50 on this plan.</p>
</div>Classes and attributes
A class names each element; data-* and aria-* attributes carry its variant and state. The values listed are the ones the stylesheet draws; the default needs no attribute.
| Class | Attributes |
|---|---|
ml-number-input | — |
ml-number-input-control | data-disableddata-invalid |
ml-number-input-field | — |
ml-number-input-buttons | — |
ml-number-input-step | — |
Accessibility and theming
- Semantic elements, accessible names and state relationships are part of the contract.
- Keyboard, pointer and touch paths are operable; focus stays visible in every theme.
- Light and dark modes pass WCAG AA contrast in all 5 canonical themes.
- Reduced motion and forced colors keep meaning and operation.
Dependencies
Installed alongside this component. No third-party UI runtime is ever added.
- input
@mlola-ui/icons