Active Foundation · Example
Reading a typed number
Reading a typed numberClient
- status
- valid
- value
- 1234.5
- number
- 1234.5
- rejection
- (none)
Full source examples/format/number-input.tsx
// apps/docs/examples/format/number-input.tsx'use client';
import {useId, useState} from 'react';
import { classifyNumberInput, getNumberInputPlaceholder,} from '@workspace/active-format';import { DescriptionItem, DescriptionList,} from '@workspace/active-ui/components/composed/description-list';import { Field, FieldLabel,} from '@workspace/active-ui/components/primitives/field';import {Input} from '@workspace/active-ui/components/primitives/input';import { NativeSelect, NativeSelectOption,} from '@workspace/active-ui/components/primitives/native-select';
/** * Reading a typed number back with the same grammar that writes it. The * result says whether the text is empty, incomplete, invalid or valid, and * why a text is refused. Grouping separators are refused while typing and * accepted in pasted text. */export default function NumberInput() { const inputId = useId(); const languageId = useId(); const modeId = useId(); const [language, setLanguage] = useState('nl'); const [mode, setMode] = useState<'typing' | 'paste'>('typing'); const [text, setText] = useState('1234,5'); const result = classifyNumberInput(text, language, {mode, maxDecimals: 2}); return ( <div className="flex flex-col gap-4"> <div className="grid gap-3 sm:grid-cols-3"> <Field> <FieldLabel htmlFor={languageId}>Language</FieldLabel> <NativeSelect id={languageId} value={language} onChange={(event) => setLanguage(event.target.value)} > {['nl', 'en', 'de', 'fr'].map((option) => ( <NativeSelectOption key={option} value={option}> {option} </NativeSelectOption> ))} </NativeSelect> </Field> <Field> <FieldLabel htmlFor={modeId}>Input</FieldLabel> <NativeSelect id={modeId} value={mode} onChange={(event) => setMode(event.target.value === 'paste' ? 'paste' : 'typing') } > <NativeSelectOption value="typing">Typed</NativeSelectOption> <NativeSelectOption value="paste">Pasted</NativeSelectOption> </NativeSelect> </Field> <Field> <FieldLabel htmlFor={inputId}> Amount (at most two decimals) </FieldLabel> <Input id={inputId} value={text} placeholder={getNumberInputPlaceholder(language, 2)} onChange={(event) => setText(event.target.value)} inputMode="decimal" /> </Field> </div> <DescriptionList orientation="inline" columns={1}> <DescriptionItem label="status"> <span className="font-mono" data-testid="number-status"> {result.status} </span> </DescriptionItem> <DescriptionItem label="value"> <span className="font-mono">{result.value || '(none)'}</span> </DescriptionItem> <DescriptionItem label="number"> <span className="font-mono">{result.number ?? 'null'}</span> </DescriptionItem> <DescriptionItem label="rejection"> <span className="font-mono">{result.rejection ?? '(none)'}</span> </DescriptionItem> </DescriptionList> </div> );}