import { default as React } from 'react'; import { NumericFormatProps } from 'react-number-format'; import { FormValidator } from '../../services/formValidation/index.js'; import { SlotClassNames, SlotStyles } from '../types/slots.types.js'; /** * How the stepper buttons are laid out. * * - `stacked` — chevrons stacked inside the field's right edge. Compact; suits a mouse. * - `split` — square `−` / `+` buttons flanking the field, each as tall and wide as the field. * Far apart with the field between them, so a mis-tap can't step the value the wrong way. * - `auto` — `split` on a coarse (touch) pointer, `stacked` otherwise. */ export type NumberInputArrowsLayout = 'auto' | 'stacked' | 'split'; /** Text NumberInput renders of its own, for translating it. */ export interface NumberInputLabels { /** The step-up button, read out by screen readers (default `Increase`). */ increase?: string; /** The step-down button, read out by screen readers (default `Decrease`). */ decrease?: string; } export type NumberInputSlots = 'root' | 'input' | 'arrows' | 'increaseButton' | 'decreaseButton'; export interface NumberInputProps extends Omit { value?: number | string; onChange?: (value: number | undefined) => void; formValidator?: FormValidator | null; label?: string; error?: string; className?: string; allowNegative?: boolean; decimalSeparator?: string; thousandSeparator?: string | boolean; prefix?: string; suffix?: string; decimalScale?: number; /** * Whether to pad the value to exactly `decimalScale` decimals. Default `true` * (e.g. with `decimalScale={2}`, `12` displays as `12.00`). Set `false` to make * `decimalScale` an upper limit only — the user may type fewer decimals and they * are kept as-is (`12` stays `12`, `12.1` stays `12.1`), while anything beyond * `decimalScale` is still truncated. */ fixedDecimalScale?: boolean; placeholder?: string; sign?: '+' | '-'; showArrows?: boolean; step?: number; /** * Lower bound. Constrains the steppers and the ArrowDown key, disables the decrease button * once reached, and clamps a typed value on blur and on Enter — the two moments it stops * being mid-edit. Typing is never blocked; see {@link NumberInputProps.max}. */ min?: number; /** * Upper bound. Behaves exactly like {@link NumberInputProps.min} in the other direction. * * Neither bound rejects a keystroke as it is typed — an edit passes through out-of-range * states on its way somewhere valid — and an empty field is never clamped. Use a * `formValidator` if out-of-range input must be *rejected* rather than corrected. */ max?: number; /** Stepper layout. Default `'auto'`. */ arrowsLayout?: NumberInputArrowsLayout; /** Accessible name for the increase button. Default `'Increase'`. */ /** Accessible name for the decrease button. Default `'Decrease'`. */ readOnly?: boolean; isRequired?: boolean; onKeyDown?: (e: React.KeyboardEvent) => void; /** Overrides the text NumberInput renders of its own. Merged per key. */ labels?: NumberInputLabels; /** Ref to the inner ``, for focusing the field. */ ref?: React.Ref; /** Classes for the inner elements. See `NumberInputSlots`. */ classNames?: SlotClassNames; /** Inline styles for the inner elements. See `NumberInputSlots`. */ styles?: SlotStyles; }