import { default as React } from 'react'; import { DataProps } from '../types/slots.types.js'; import { MaskSelection, MaskState } from './mask.js'; export type { MaskSelection, MaskState }; /** * What a correction hook is handed. Both states are the value as the mask shapes it, exactly as * long as the mask, with its literals in place. */ export interface BeforeMaskedStateChangeStates { previousState: MaskState; nextState: MaskState; } export interface MaskedInputProps extends DataProps, Omit, 'onChange' | 'value' | 'defaultValue'> { /** The inner ``. `Input` leaves the ref to a `customInput`, so this is the way to it. */ ref?: React.Ref; /** `9` takes a digit, every other character is a literal: `99:99`, `99.99.9999`. */ mask: string; /** Shown in a slot with no digit in it yet. Default `_`. */ maskPlaceholder?: string; /** * The masked value, e.g. `11.11.2025` or `1_.__.____`. Anything else is coerced to the mask, * reading each slot positionally, so a value from elsewhere cannot leave the field a shape the * next keystroke would be measured against wrongly. `''` means empty, and shows nothing until * the field is focused. */ value?: string; /** * Called with the new masked value, or `''` once the last digit is gone. A string rather than an * event, which is what `Input`'s own handler accepts, so there is no synthetic event to forge. */ onChange?: (value: string) => void; /** * Last word on what the field becomes, for corrections that depend on the value as a whole — * clamping an hour past 23, padding a day typed as `4` to `04`. Returning `nextState` unchanged * accepts the mask's own answer. Called only for a change the user made. */ beforeMaskedStateChange?: (states: BeforeMaskedStateChangeStates) => MaskState; }