Skip to content

MaskedInput / NumericInput

Two related primitives:

  • <MaskedInput> — text input with a react-imask pattern. For phone numbers, dates, custom strings.
  • <NumericInput> — formatted number input with thousands separator + radix. For currency and percentage fields.
import from "@na/ui/components/MaskedInput" ▶ Open in Storybook packages/ui/src/components/MaskedInput.tsx

When to use

  • Phone numbers with country-specific patterns.
  • Date inputs where a calendar is overkill (use DatePicker for picking; MaskedInput for typing).
  • Currency / percentage fields with thousands separators.

Don’t use MaskedInput for: free-form text (Input), single-character codes (InputOTP), date selection (DatePicker).

Phone

<MaskedInput
mask={{ mask: '+1 (000) 000-0000' }}
placeholder="+1 (___) ___-____"
/>

Date

<MaskedInput mask={{ mask: '00/00/0000' }} placeholder="MM/DD/YYYY" />

Currency

<NumericInput> adds the prefix / suffix decorations and pre-configures imask for numeric formatting.

<NumericInput prefix="$" suffix="USD" defaultValue="1000" />

Percentage

<NumericInput suffix="%" max={100} min={0} defaultValue="42" />

API

MaskedInput

Prop Type Default Description
mask * ReactMaskOpts IMask pattern. See https://imask.js.org/ — string masks, Number, Date, RegExp, function, or pipe.
value string Controlled formatted value.
defaultValue string Initial value for uncontrolled mode.
onValueChange (formatted: string, unmasked: string) => void Fires on every accepted change.
...rest InputHTMLAttributes All native input attributes (placeholder, disabled, name, …).

NumericInput

Prop Type Default Description
thousandsSeparator string "," Localized thousands separator.
radix string "." Localized decimal separator.
allowNegative boolean false Allow negative values.
scale number 2 Maximum digits after the radix.
min number Smallest numeric value.
max number Largest numeric value.
prefix string Visible prefix (currency symbol).
suffix string Visible suffix (unit).
padFractionalZeros boolean false Pad to scale zeros (e.g., 1.5 → 1.50).

Design guidelines

✓ Do

  • Use NumericInput for any field where a thousands separator improves readability ($1,234,567).
  • Set max/min to bound the user — IMask clamps on commit.
  • Pair currency inputs with a visible prefix or suffix that names the unit.

✗ Don't

  • Use MaskedInput for date selection. The DatePicker calendar is far more usable.
  • Mask passwords. PasswordInput exists.
  • Block paste. Users paste phone numbers from contacts; the mask should accept and re-format.

Accessibility

  • Native <input type="text"> semantics — works with all assistive tech.
  • The visible mask placeholder (“+1 (_) _-”) is also the screen-reader description if the user enables verbose mode.
  • For currency fields, pair the prefix / suffix with aria-label on the input that names the value type (“Amount in USD”).

▶ Open MaskedInput stories in Storybook