UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

216 lines (212 loc) • 7.21 kB
"use client"; const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs'); const require_dom = require('../../utils/dom.cjs'); const require_effect = require('../../utils/effect.cjs'); const require_ref = require('../../utils/ref.cjs'); const require_utils_index = require('../../utils/index.cjs'); const require_use_field_props = require('../field/use-field-props.cjs'); const require_hooks_use_event_listener_index = require('../../hooks/use-event-listener/index.cjs'); const require_hooks_use_counter_index = require('../../hooks/use-counter/index.cjs'); const require_use_number_counter = require('./use-number-counter.cjs'); let react = require("react"); react = require_rolldown_runtime.__toESM(react); //#region src/components/number-input/use-number-input.ts const defaultFormat = (value) => value.toString(); const defaultParse = (value) => value; const isDefaultValidCharacter = (char) => /^[Ee0-9+\-.]$/.test(char); const isValidNumericKeyboardEvent = ({ key, altKey, ctrlKey, metaKey }, isValid) => { const modifierKey = ctrlKey || altKey || metaKey; if (!(key.length === 1) || modifierKey) return true; return isValid(key); }; const getStepRatio = ({ ctrlKey, metaKey, shiftKey }) => { let ratio = 1; if (metaKey || ctrlKey) ratio = .1; if (shiftKey) ratio = 10; return ratio; }; const useNumberInput = (props = {}) => { const { props: { allowMouseWheel, clampValueOnBlur = true, defaultValue, disabled, focusInputOnChange = true, format = defaultFormat, getAriaValueText, isValidCharacter = isDefaultValidCharacter, keepWithinRange = true, max: maxValue = Number.MAX_SAFE_INTEGER, min: minValue = Number.MIN_SAFE_INTEGER, parse = defaultParse, precision, readOnly, step = 1, value: valueProp, onChange: onChangeProp,...rest }, ariaProps, dataProps, eventProps } = require_use_field_props.useFieldProps(props); const interactive = !(readOnly || disabled); const inputRef = (0, react.useRef)(null); const { cast, max, min, out, setValue, update, value, valueAsNumber,...counter } = require_hooks_use_counter_index.useCounter({ defaultValue, keepWithinRange, max: maxValue, min: minValue, precision, step, value: valueProp, onChange: onChangeProp }); const selectionRef = (0, react.useRef)(null); const valueText = (0, react.useMemo)(() => { let text = getAriaValueText?.(value); if (text != null) return text; text = value.toString(); return !text ? void 0 : text; }, [value, getAriaValueText]); const sanitize = (0, react.useCallback)((value$1) => value$1.split("").filter(isValidCharacter).join(""), [isValidCharacter]); const increment = (0, react.useCallback)((value$1 = step) => { if (!interactive) return; counter.increment(value$1); if (!focusInputOnChange) return; requestAnimationFrame(() => { inputRef.current?.focus(); }); }, [ interactive, counter, step, focusInputOnChange ]); const decrement = (0, react.useCallback)((value$1 = step) => { if (!interactive) return; counter.decrement(value$1); if (!focusInputOnChange) return; requestAnimationFrame(() => { inputRef.current?.focus(); }); }, [ interactive, counter, step, focusInputOnChange ]); const onChange = (0, react.useCallback)((ev) => { if (require_dom.isComposing(ev)) return; const { selectionEnd, selectionStart, value: value$1 } = ev.currentTarget; update(sanitize(parse(value$1))); selectionRef.current = { end: selectionEnd, start: selectionStart }; }, [ parse, sanitize, update ]); const onFocus = (0, react.useCallback)((ev) => { if (!selectionRef.current) return; const { end, start } = selectionRef.current; const { selectionStart, value: value$1 } = ev.currentTarget; ev.currentTarget.selectionStart = start ?? value$1.length; ev.currentTarget.selectionEnd = end ?? selectionStart; }, []); const onBlur = (0, react.useCallback)(() => { if (!clampValueOnBlur) return; let nextValue = value; if (value === "") return; if (/^[eE]/.test(value.toString())) setValue(""); else { if (valueAsNumber < minValue) nextValue = minValue; if (valueAsNumber > maxValue) nextValue = maxValue; cast(nextValue); } }, [ cast, clampValueOnBlur, maxValue, minValue, setValue, value, valueAsNumber ]); const onKeyDown = (0, react.useCallback)((ev) => { if (require_dom.isComposing(ev)) return; if (!isValidNumericKeyboardEvent(ev, isValidCharacter)) ev.preventDefault(); const stepValue = getStepRatio(ev) * step; require_dom.runKeyAction(ev, { ArrowDown: () => decrement(stepValue), ArrowUp: () => increment(stepValue), End: () => update(maxValue), Home: () => update(minValue) }); }, [ decrement, increment, isValidCharacter, maxValue, minValue, step, update ]); const { getDecrementProps, getIncrementProps } = require_use_number_counter.useNumberCounter({ "aria-disabled": (0, require_utils_index.utils_exports.ariaAttr)(!interactive), decrement, disabled, increment, keepWithinRange, max, min, ...dataProps }); require_effect.useSafeLayoutEffect(() => { if (!inputRef.current) return; if (!(inputRef.current.value != value)) return; setValue(sanitize(parse(inputRef.current.value))); }, [parse, sanitize]); require_hooks_use_event_listener_index.useEventListener(inputRef.current, "wheel", (ev) => { const focused = (inputRef.current?.ownerDocument ?? document).activeElement === inputRef.current; if (!allowMouseWheel || !focused) return; ev.preventDefault(); const stepValue = getStepRatio(ev) * step; const direction = Math.sign(ev.deltaY); if (direction === -1) increment(stepValue); else if (direction === 1) decrement(stepValue); }, { passive: false }); return { getDecrementProps, getIncrementProps, getInputProps: (0, react.useCallback)(({ ref,...props$1 } = {}) => ({ ...ariaProps, ...dataProps, type: "text", "aria-invalid": (0, require_utils_index.utils_exports.ariaAttr)(ariaProps["aria-invalid"] ?? out), "aria-valuemax": maxValue, "aria-valuemin": minValue, "aria-valuenow": Number.isNaN(valueAsNumber) ? void 0 : valueAsNumber, "aria-valuetext": valueText, autoComplete: "off", autoCorrect: "off", disabled, inputMode: "decimal", max: maxValue, min: minValue, pattern: "[0-9]*(.[0-9]+)?", readOnly, role: "spinbutton", step, value: format(value), ...rest, ...props$1, ref: require_ref.mergeRefs(ref, rest.ref, inputRef), onBlur: (0, require_utils_index.utils_exports.handlerAll)(eventProps.onBlur, props$1.onBlur, onBlur), onChange: (0, require_utils_index.utils_exports.handlerAll)(props$1.onChange, onChange), onFocus: (0, require_utils_index.utils_exports.handlerAll)(eventProps.onFocus, props$1.onFocus, onFocus), onKeyDown: (0, require_utils_index.utils_exports.handlerAll)(rest.onKeyDown, props$1.onKeyDown, onKeyDown) }), [ format, out, value, valueText, ariaProps, dataProps, eventProps, maxValue, minValue, valueAsNumber, disabled, readOnly, step, rest, onKeyDown, onBlur, onFocus, onChange ]) }; }; //#endregion exports.useNumberInput = useNumberInput; //# sourceMappingURL=use-number-input.cjs.map