@julo-ui/otp-input
Version:
React Input Component for entering sequences of digits
142 lines (139 loc) • 3.45 kB
JavaScript
import {
useHandleFocus
} from "./chunk-PREVC7KM.mjs";
import {
useHandleInputEvent
} from "./chunk-3PFL5PUX.mjs";
import {
useHandleValues
} from "./chunk-O4TAJTGC.mjs";
// src/use-otp-input.ts
import { useCallback, useId } from "react";
import { createDescendantContext } from "@chakra-ui/descendant";
import { _noop, callAllFn } from "@julo-ui/function-utils";
import { ariaAttr } from "@julo-ui/dom-utils";
var [
OtpInputDescendantsProvider,
useOtpInputDescendantsContext,
useOtpInputDescendants,
useOtpInputDescendant
] = createDescendantContext();
function useOtpInput(props) {
const {
autoFocus = false,
value,
defaultValue,
onChange = _noop,
onComplete = _noop,
placeholder,
manageFocus = true,
otp = true,
id: idProp,
isDisabled,
isInvalid,
type = "number",
mask,
...resRootProps
} = props;
const uuid = useId();
const id = idProp != null ? idProp : uuid;
const rootId = `otp-input-${id}`;
const fieldId = `otp-input-field-${id}`;
const descendants = useOtpInputDescendants();
const {
focusedIndex,
onFocusNext,
onBlur: onInputBlur,
onFocus: onInputFocus
} = useHandleFocus({ descendants, manageFocus, autoFocus });
const { values, setValue, setValues, clearValue, getNextValue } = useHandleValues({
onChange,
defaultValue,
value,
descendants,
onComplete,
onFocusNext
});
const { onChange: onInputChange, onKeyDown: onInputKeyDown } = useHandleInputEvent({
descendants,
getNextValue,
manageFocus,
onComplete,
setValue,
setValues,
type,
values,
onFocusNext
});
const getRootProps = useCallback(
(props2 = {}, forwardedRef = null) => ({
...resRootProps,
...props2,
id: rootId,
ref: forwardedRef
}),
[resRootProps, rootId]
);
const getInputProps = useCallback(
(props2 = { index: -1 }, forwardedRef = null) => {
const { index, onChange: onChange2, onKeyDown, onFocus, onBlur, ...resProps } = props2;
const hasFocus = focusedIndex === index;
const inputType = type === "number" ? "tel" : "text";
return {
"aria-label": "Please enter your otp code",
inputMode: type === "number" ? "numberic" : "text",
type: mask ? "password" : inputType,
ref: forwardedRef,
...resProps,
id: `${fieldId}-${index}`,
disabled: isDisabled,
"aria-invalid": ariaAttr(isInvalid),
onChange: callAllFn(
(e) => onInputChange(e, index),
onChange2
),
onKeyDown: callAllFn(
(e) => onInputKeyDown(e, index),
onKeyDown
),
onFocus: callAllFn(onInputFocus, onFocus),
onBlur: callAllFn(onInputBlur, onBlur),
value: values[index] || "",
autoComplete: otp ? "one-time-code" : "off",
placeholder: hasFocus ? "" : placeholder
};
},
[
fieldId,
focusedIndex,
isDisabled,
isInvalid,
mask,
onInputBlur,
onInputChange,
onInputFocus,
onInputKeyDown,
otp,
placeholder,
type,
values
]
);
return {
getRootProps,
getInputProps,
fieldId,
descendants,
values,
setValue,
setValues,
clearValue
};
}
export {
OtpInputDescendantsProvider,
useOtpInputDescendantsContext,
useOtpInputDescendants,
useOtpInputDescendant,
useOtpInput
};