224 lines
8.4 KiB
Plaintext
224 lines
8.4 KiB
Plaintext
import * as React from 'react';
|
|
import { FormControlState } from '../FormControl';
|
|
import { NumberInputAction } from './numberInputAction.types';
|
|
import { ActionWithContext } from '../utils/useControllableReducer.types';
|
|
export type StepDirection = 'up' | 'down';
|
|
/**
|
|
* The internal state of the NumberInput.
|
|
* Modify via the reducer only.
|
|
*/
|
|
export interface NumberInputState {
|
|
/**
|
|
* The clamped `value` of the `input` element.
|
|
*/
|
|
value: number | null;
|
|
/**
|
|
* The dirty `value` of the `input` element when it is in focus.
|
|
*/
|
|
inputValue: string;
|
|
}
|
|
/**
|
|
* Additional props passed to the number input reducer actions.
|
|
*/
|
|
export type NumberInputActionContext = {
|
|
min?: number;
|
|
max?: number;
|
|
step?: number;
|
|
shiftMultiplier: number;
|
|
/**
|
|
* A function that parses the raw input value
|
|
*/
|
|
getInputValueAsString: (val: string) => string;
|
|
};
|
|
export type NumberInputReducerAction = ActionWithContext<NumberInputAction, NumberInputActionContext>;
|
|
export interface UseNumberInputParameters {
|
|
/**
|
|
* The minimum value.
|
|
*/
|
|
min?: number;
|
|
/**
|
|
* The maximum value.
|
|
*/
|
|
max?: number;
|
|
/**
|
|
* The amount that the value changes on each increment or decrement.
|
|
*/
|
|
step?: number;
|
|
/**
|
|
* Multiplier applied to `step` if the shift key is held while incrementing
|
|
* or decrementing the value. Defaults to `10`.
|
|
*/
|
|
shiftMultiplier?: number;
|
|
/**
|
|
* The default value. Use when the component is not controlled.
|
|
*/
|
|
defaultValue?: number | null;
|
|
/**
|
|
* If `true`, the component is disabled.
|
|
* The prop defaults to the value (`false`) inherited from the parent FormControl component.
|
|
*/
|
|
disabled?: boolean;
|
|
/**
|
|
* If `true`, the `input` will indicate an error by setting the `aria-invalid` attribute.
|
|
* The prop defaults to the value (`false`) inherited from the parent FormControl component.
|
|
*/
|
|
error?: boolean;
|
|
onBlur?: (event?: React.FocusEvent<HTMLInputElement>) => void;
|
|
onClick?: React.MouseEventHandler;
|
|
/**
|
|
* Callback fired when the `input` value changes after each keypress, before clamping is applied.
|
|
* Note that `event.target.value` may contain values that fall outside of `min` and `max` or
|
|
* are otherwise "invalid".
|
|
*
|
|
* @param {React.ChangeEvent<HTMLInputElement>} event The event source of the callback.
|
|
*/
|
|
onInputChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
onFocus?: React.FocusEventHandler;
|
|
/**
|
|
* Callback fired after the value is clamped and changes - when the `input` is blurred or when
|
|
* the stepper buttons are triggered.
|
|
* Called with `undefined` when the value is unset.
|
|
*
|
|
* @param {React.FocusEvent<HTMLInputElement>|React.PointerEvent|React.KeyboardEvent} event The event source of the callback
|
|
* @param {number|undefined} value The new value of the component
|
|
*/
|
|
onChange?: (event: React.FocusEvent<HTMLInputElement> | React.PointerEvent | React.KeyboardEvent, value: number | null) => void;
|
|
/**
|
|
* The `id` attribute of the input element.
|
|
*/
|
|
inputId?: string;
|
|
/**
|
|
* The ref of the input element.
|
|
*/
|
|
inputRef?: React.Ref<HTMLInputElement>;
|
|
/**
|
|
* If `true`, the `input` element is required.
|
|
* The prop defaults to the value (`false`) inherited from the parent FormControl component.
|
|
*/
|
|
required?: boolean;
|
|
/**
|
|
* If `true`, the `input` element becomes read-only. The stepper buttons remain active,
|
|
* with the addition that they are now keyboard focusable.
|
|
* @default false
|
|
*/
|
|
readOnly?: boolean;
|
|
/**
|
|
* The current value. Use when the component is controlled.
|
|
* @default null
|
|
*/
|
|
value?: number | null;
|
|
/**
|
|
* The name of the component using useNumberInput.
|
|
* For debugging purposes.
|
|
* @default 'useNumberInput'
|
|
*/
|
|
componentName?: string;
|
|
}
|
|
export interface UseNumberInputRootSlotOwnProps {
|
|
onClick: React.MouseEventHandler | undefined;
|
|
}
|
|
export type UseNumberInputRootSlotProps<ExternalProps = {}> = Omit<ExternalProps, keyof UseNumberInputRootSlotOwnProps | 'onBlur' | 'onInputChange' | 'onFocus'> & UseNumberInputRootSlotOwnProps;
|
|
export interface UseNumberInputInputSlotOwnProps {
|
|
defaultValue: number | undefined;
|
|
id: string | undefined;
|
|
ref: React.RefCallback<HTMLInputElement> | null;
|
|
value: number | undefined;
|
|
role?: React.AriaRole;
|
|
'aria-disabled': React.AriaAttributes['aria-disabled'];
|
|
'aria-valuemax': React.AriaAttributes['aria-valuemax'];
|
|
'aria-valuemin': React.AriaAttributes['aria-valuemin'];
|
|
'aria-valuenow': React.AriaAttributes['aria-valuenow'];
|
|
'aria-valuetext': React.AriaAttributes['aria-valuetext'];
|
|
tabIndex?: number;
|
|
onBlur: React.FocusEventHandler;
|
|
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
|
onFocus: React.FocusEventHandler;
|
|
required: boolean;
|
|
disabled: boolean;
|
|
}
|
|
export type UseNumberInputInputSlotProps<ExternalProps = {}> = Omit<ExternalProps, keyof UseNumberInputInputSlotOwnProps> & UseNumberInputInputSlotOwnProps;
|
|
export interface UseNumberInputIncrementButtonSlotOwnProps {
|
|
'aria-controls': React.AriaAttributes['aria-controls'];
|
|
'aria-disabled': React.AriaAttributes['aria-disabled'];
|
|
disabled: boolean;
|
|
tabIndex?: number;
|
|
}
|
|
export type UseNumberInputIncrementButtonSlotProps<ExternalProps = {}> = Omit<ExternalProps, keyof UseNumberInputIncrementButtonSlotOwnProps> & UseNumberInputIncrementButtonSlotOwnProps;
|
|
export interface UseNumberInputDecrementButtonSlotOwnProps {
|
|
'aria-controls': React.AriaAttributes['aria-controls'];
|
|
'aria-disabled': React.AriaAttributes['aria-disabled'];
|
|
disabled: boolean;
|
|
tabIndex?: number;
|
|
}
|
|
export type UseNumberInputDecrementButtonSlotProps<ExternalProps = {}> = Omit<ExternalProps, keyof UseNumberInputDecrementButtonSlotOwnProps> & UseNumberInputDecrementButtonSlotOwnProps;
|
|
export interface UseNumberInputReturnValue {
|
|
/**
|
|
* If `true`, the component will be disabled.
|
|
* @default false
|
|
*/
|
|
disabled: boolean;
|
|
/**
|
|
* If `true`, the `input` will indicate an error by setting the `aria-invalid` attribute.
|
|
* @default false
|
|
*/
|
|
error: boolean;
|
|
/**
|
|
* If `true`, the `input` will be focused.
|
|
* @default false
|
|
*/
|
|
focused: boolean;
|
|
/**
|
|
* Return value from the `useFormControlContext` hook.
|
|
*/
|
|
formControlContext: FormControlState | undefined;
|
|
/**
|
|
* Resolver for the decrement button slot's props.
|
|
* @param externalProps props for the decrement button slot
|
|
* @returns props that should be spread on the decrement button slot
|
|
*/
|
|
getDecrementButtonProps: <ExternalProps extends Record<string, unknown> = {}>(externalProps?: ExternalProps) => UseNumberInputDecrementButtonSlotProps<ExternalProps>;
|
|
/**
|
|
* Resolver for the increment button slot's props.
|
|
* @param externalProps props for the increment button slot
|
|
* @returns props that should be spread on the increment button slot
|
|
*/
|
|
getIncrementButtonProps: <ExternalProps extends Record<string, unknown> = {}>(externalProps?: ExternalProps) => UseNumberInputIncrementButtonSlotProps<ExternalProps>;
|
|
/**
|
|
* Resolver for the input slot's props.
|
|
* @param externalProps props for the input slot
|
|
* @returns props that should be spread on the input slot
|
|
*/
|
|
getInputProps: <ExternalProps extends Record<string, unknown> = {}>(externalProps?: ExternalProps) => UseNumberInputInputSlotProps<ExternalProps>;
|
|
/**
|
|
* Resolver for the root slot's props.
|
|
* @param externalProps props for the root slot
|
|
* @returns props that should be spread on the root slot
|
|
*/
|
|
getRootProps: <ExternalProps extends Record<string, unknown> = {}>(externalProps?: ExternalProps) => UseNumberInputRootSlotProps<ExternalProps>;
|
|
/**
|
|
* If `true`, the `input` will indicate that it's required.
|
|
* @default false
|
|
*/
|
|
required: boolean;
|
|
/**
|
|
* The clamped `value` of the `input` element.
|
|
*/
|
|
value: number | null;
|
|
/**
|
|
* The dirty `value` of the `input` element when it is in focus.
|
|
*/
|
|
inputValue: string;
|
|
/**
|
|
* If `true`, the increment button will be disabled.
|
|
* e.g. when the `value` is already at `max`
|
|
* @default false
|
|
*/
|
|
isIncrementDisabled: boolean;
|
|
/**
|
|
* If `true`, the decrement button will be disabled.
|
|
* e.g. when the `value` is already at `min`
|
|
* @default false
|
|
*/
|
|
isDecrementDisabled: boolean;
|
|
}
|