import { NumberParser } from '@internationalized/number';
import { Machine, EventObject, Service } from '@zag-js/core';
import { PropTypes, RequiredBy, LocaleProperties, CommonProperties } from '@zag-js/types';
interface ValueChangeDetails {
value: string;
valueAsNumber: number;
}
interface FocusChangeDetails extends ValueChangeDetails {
focused: boolean;
}
type ValidityState = "rangeUnderflow" | "rangeOverflow";
interface ValueInvalidDetails extends ValueChangeDetails {
reason: ValidityState;
}
type InputMode = "text" | "tel" | "numeric" | "decimal";
type ElementIds = Partial<{
root: string;
label: string;
input: string;
incrementTrigger: string;
decrementTrigger: string;
scrubber: string;
}>;
interface IntlTranslations {
/**
* Function that returns the human-readable value.
* It is used to set the `aria-valuetext` property of the input
*/
valueText?: ((value: string) => string) | undefined;
/**
* The label foe the increment button
*/
incrementLabel?: string | undefined;
/**
* The label for the decrement button
*/
decrementLabel?: string | undefined;
}
interface NumberInputProps extends LocaleProperties, CommonProperties {
/**
* The ids of the elements in the number input. Useful for composition.
*/
ids?: ElementIds | undefined;
/**
* The name attribute of the number input. Useful for form submission.
*/
name?: string | undefined;
/**
* The associate form of the input element.
*/
form?: string | undefined;
/**
* Whether the number input is disabled.
*/
disabled?: boolean | undefined;
/**
* Whether the number input is readonly
*/
readOnly?: boolean | undefined;
/**
* Whether the number input value is invalid.
*/
invalid?: boolean | undefined;
/**
* Whether the number input is required
*/
required?: boolean | undefined;
/**
* The pattern used to check the element's value against
*
* @default "-?[0-9]*(.[0-9]+)?"
*/
pattern?: string | undefined;
/**
* The controlled value of the input
*/
value?: string | undefined;
/**
* The initial value of the input when rendered.
* Use when you don't need to control the value of the input.
*/
defaultValue?: string | undefined;
/**
* The minimum value of the number input
* @default Number.MIN_SAFE_INTEGER
*/
min?: number | undefined;
/**
* The maximum value of the number input
* @default Number.MAX_SAFE_INTEGER
*/
max?: number | undefined;
/**
* The amount to increment or decrement the value by
* @default 1
*/
step?: number | undefined;
/**
* Whether to allow mouse wheel to change the value
*/
allowMouseWheel?: boolean | undefined;
/**
* Whether to allow the value overflow the min/max range
* @default true
*/
allowOverflow?: boolean | undefined;
/**
* Whether to clamp the value when the input loses focus (blur)
* @default true
*/
clampValueOnBlur?: boolean | undefined;
/**
* Whether to focus input when the value changes
* @default true
*/
focusInputOnChange?: boolean | undefined;
/**
* Specifies the localized strings that identifies the accessibility elements and their states
*/
translations?: IntlTranslations | undefined;
/**
* The options to pass to the `Intl.NumberFormat` constructor
*/
formatOptions?: Intl.NumberFormatOptions | undefined;
/**
* Hints at the type of data that might be entered by the user. It also determines
* the type of keyboard shown to the user on mobile devices
* @default "decimal"
*/
inputMode?: InputMode | undefined;
/**
* Function invoked when the value changes
*/
onValueChange?: ((details: ValueChangeDetails) => void) | undefined;
/**
* Function invoked when the value overflows or underflows the min/max range
*/
onValueInvalid?: ((details: ValueInvalidDetails) => void) | undefined;
/**
* Function invoked when the number input is focused
*/
onFocusChange?: ((details: FocusChangeDetails) => void) | undefined;
/**
* Function invoked when the value is committed (when the input is blurred or the Enter key is pressed)
*/
onValueCommit?: ((details: ValueChangeDetails) => void) | undefined;
/**
* Whether to spin the value when the increment/decrement button is pressed
* @default true
*/
spinOnPress?: boolean | undefined;
}
type PropsWithDefault = "dir" | "locale" | "focusInputOnChange" | "clampValueOnBlur" | "allowOverflow" | "inputMode" | "pattern" | "translations" | "step" | "spinOnPress" | "min" | "max" | "step" | "translations";
type ComputedContext = Readonly<{
/**
* The value of the input as a number
*/
valueAsNumber: number;
/**
* Whether the value is at the min
*/
isAtMin: boolean;
/**
* Whether the value is at the max
*/
isAtMax: boolean;
/**
* Whether the value is out of the min/max range
*/
isOutOfRange: boolean;
/**
* Whether the value is empty
*/
isValueEmpty: boolean;
/**
* Whether the color picker is disabled
*/
isDisabled: boolean;
/**
* Whether the increment button is enabled
*/
canIncrement: boolean;
/**
* Whether the decrement button is enabled
*/
canDecrement: boolean;
/**
* The `aria-valuetext` attribute of the input
*/
valueText: string | undefined;
/**
* The formatted value of the input
*/
formattedValue: string;
/**
* Whether the writing direction is RTL
*/
isRtl: boolean;
/**
* The number i18n formatter
*/
formatter: Intl.NumberFormat;
/**
* The number i18n parser
*/
parser: NumberParser;
}>;
type HintValue = "increment" | "decrement";
interface PrivateContext {
/**
* The hint that determines if we're incrementing or decrementing
*/
hint: HintValue | null;
/**
* The scrubber cursor position
*/
scrubberCursorPoint: {
x: number;
y: number;
} | null;
/**
* Whether the checkbox's fieldset is disabled
*/
fieldsetDisabled: boolean;
/**
* The value of the input
*/
value: string;
}
interface NumberInputSchema {
state: "idle" | "focused" | "spinning" | "before:spin" | "scrubbing";
tag: "focus";
props: RequiredBy;
context: PrivateContext;
computed: ComputedContext;
action: string;
event: EventObject;
guard: string;
effect: string;
}
type NumberInputService = Service;
type NumberInputMachine = Machine;
interface NumberInputApi {
/**
* Whether the input is focused.
*/
focused: boolean;
/**
* Whether the input is invalid.
*/
invalid: boolean;
/**
* Whether the input value is empty.
*/
empty: boolean;
/**
* The formatted value of the input.
*/
value: string;
/**
* The value of the input as a number.
*/
valueAsNumber: number;
/**
* Function to set the value of the input.
*/
setValue: (value: number) => void;
/**
* Function to clear the value of the input.
*/
clearValue: VoidFunction;
/**
* Function to increment the value of the input by the step.
*/
increment: VoidFunction;
/**
* Function to decrement the value of the input by the step.
*/
decrement: VoidFunction;
/**
* Function to set the value of the input to the max.
*/
setToMax: VoidFunction;
/**
* Function to set the value of the input to the min.
*/
setToMin: VoidFunction;
/**
* Function to focus the input.
*/
focus: VoidFunction;
getRootProps: () => T["element"];
getLabelProps: () => T["label"];
getControlProps: () => T["element"];
getValueTextProps: () => T["element"];
getInputProps: () => T["input"];
getDecrementTriggerProps: () => T["button"];
getIncrementTriggerProps: () => T["button"];
getScrubberProps: () => T["element"];
}
export type { ElementIds, FocusChangeDetails, HintValue, InputMode, IntlTranslations, NumberInputApi, NumberInputMachine, NumberInputProps, NumberInputSchema, NumberInputService, ValidityState, ValueChangeDetails, ValueInvalidDetails };