@vezham/input-otp
Version:
InputOTP is a component that allows users to enter otp input. It can be used to get user otp in forms.
274 lines (272 loc) • 9.87 kB
JavaScript
"use client";
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/use-input-otp.ts
var use_input_otp_exports = {};
__export(use_input_otp_exports, {
useInputOtp: () => useInputOtp
});
module.exports = __toCommonJS(use_input_otp_exports);
var import_system = require("@vezham/system");
var import_theme = require("@vezham/theme");
var import_react_utils = require("@vezham/react-utils");
var import_shared_utils = require("@vezham/shared-utils");
var import_react = require("react");
var import_utils = require("@react-aria/utils");
var import_utils2 = require("@react-stately/utils");
var import_form = require("@react-stately/form");
var import_form2 = require("@react-aria/form");
var import_focus = require("@react-aria/focus");
var import_form3 = require("@vezham/form");
function useInputOtp(originalProps) {
var _a, _b, _c, _d;
const globalContext = (0, import_system.useProviderContext)();
const { validationBehavior: formValidationBehavior } = (0, import_form3.useSlottedContext)(import_form3.FormContext) || {};
const [props, variantProps] = (0, import_system.mapPropsVariants)(originalProps, import_theme.inputOtp.variantKeys);
const {
ref,
baseRef,
as,
className,
classNames,
length = 4,
autoFocus,
"aria-label": ariaLabel = "One-time password input",
onValueChange = () => {
},
allowedKeys = "^[0-9]*$",
validationBehavior = (_a = formValidationBehavior != null ? formValidationBehavior : globalContext == null ? void 0 : globalContext.validationBehavior) != null ? _a : "native",
type,
name,
maxLength,
minLength,
textAlign = "center",
onComplete = () => {
},
pushPasswordManagerStrategy,
pasteTransformer,
containerClassName,
noScriptCSSFallback,
onChange,
inputMode,
...otherProps
} = props;
const Component = as || "div";
const inputRef = (0, import_react_utils.useDOMRef)(ref);
const baseDomRef = (0, import_react_utils.useDOMRef)(baseRef);
const { isFocusVisible, isFocused, focusProps } = (0, import_focus.useFocusRing)({
autoFocus,
isTextInput: true
});
const handleValueChange = (0, import_react.useCallback)(
(value2) => {
onValueChange(value2 != null ? value2 : "");
},
[onValueChange]
);
const [value, setValue] = (0, import_utils2.useControlledState)(
props.value,
(_b = props.defaultValue) != null ? _b : "",
handleValueChange
);
const disableAnimation = (_d = (_c = originalProps.disableAnimation) != null ? _c : globalContext == null ? void 0 : globalContext.disableAnimation) != null ? _d : false;
const isDisabled = originalProps.isDisabled;
const baseStyles = (0, import_shared_utils.clsx)(classNames == null ? void 0 : classNames.base, className);
const validationState = (0, import_form.useFormValidationState)({
...props,
validationBehavior,
value
});
(0, import_utils.useFormReset)(inputRef, value, setValue);
(0, import_form2.useFormValidation)({ ...props, validationBehavior }, validationState, inputRef);
const {
isInvalid: isAriaInvalid,
validationErrors,
validationDetails
} = validationState.displayValidation;
const isReadOnly = originalProps.isReadOnly;
const isRequired = originalProps.isRequired;
const isInvalid = originalProps.isInvalid || isAriaInvalid;
const errorMessage = typeof props.errorMessage === "function" ? props.errorMessage({ isInvalid, validationErrors, validationDetails }) : props.errorMessage || (validationErrors == null ? void 0 : validationErrors.join(" "));
const description = props.description;
const hasHelper = !!description || !!errorMessage;
const slots = (0, import_react.useMemo)(
() => (0, import_theme.inputOtp)({
...variantProps,
disableAnimation,
isInvalid,
isReadOnly
}),
[(0, import_shared_utils.objectToDeps)(variantProps), disableAnimation, isInvalid, isReadOnly]
);
const getBaseProps = (0, import_react.useCallback)(
(props2 = {}) => {
return {
ref: baseDomRef,
className: slots.base({
class: baseStyles
}),
"data-slot": "base",
"data-disabled": (0, import_shared_utils.dataAttr)(isDisabled),
"data-invalid": (0, import_shared_utils.dataAttr)(isInvalid),
"data-required": (0, import_shared_utils.dataAttr)(originalProps == null ? void 0 : originalProps.isRequired),
"data-readonly": (0, import_shared_utils.dataAttr)(originalProps == null ? void 0 : originalProps.isReadOnly),
"data-filled": (0, import_shared_utils.dataAttr)(value.length === length),
"aria-label": ariaLabel,
"aria-required": (0, import_shared_utils.dataAttr)(originalProps.isRequired),
"aria-readonly": (0, import_shared_utils.dataAttr)(originalProps == null ? void 0 : originalProps.isReadOnly),
role: "base",
...(0, import_utils.mergeProps)(
(0, import_react_utils.filterDOMProps)(otherProps, {
enabled: true
}),
(0, import_react_utils.filterDOMProps)(props2)
),
onChange: (e) => {
var _a2;
const val = (_a2 = e.target) == null ? void 0 : _a2.value;
const regex = new RegExp(allowedKeys);
if (regex.test(val)) {
onChange == null ? void 0 : onChange(e);
}
}
};
},
[baseDomRef, slots, baseStyles, isDisabled, isInvalid, isRequired, isReadOnly, value, length]
);
const getInputOtpProps = (0, import_react.useCallback)(
(props2 = {}) => {
var _a2;
const otpProps = {
...focusProps,
required: isRequired,
disabled: isDisabled,
readOnly: isReadOnly,
pattern: allowedKeys,
maxLength: maxLength != null ? maxLength : length,
minLength: minLength != null ? minLength : length,
textAlign,
ref: inputRef,
name,
value,
autoFocus,
onChange: setValue,
onBlur: (0, import_utils.chain)(focusProps.onBlur, props2 == null ? void 0 : props2.onBlur),
onComplete,
pushPasswordManagerStrategy,
pasteTransformer,
noScriptCSSFallback,
inputMode: inputMode != null ? inputMode : (0, import_shared_utils.isPatternNumeric)(allowedKeys) ? "numeric" : "text",
containerClassName: (_a2 = slots.wrapper) == null ? void 0 : _a2.call(slots, { class: (0, import_shared_utils.clsx)(classNames == null ? void 0 : classNames.wrapper, containerClassName) }),
...props2
};
return otpProps;
},
[
inputMode,
isRequired,
isDisabled,
isReadOnly,
allowedKeys,
inputRef,
name,
value,
length,
setValue,
props.onBlur,
onComplete,
autoFocus
]
);
const getSegmentWrapperProps = (0, import_react.useCallback)(
(props2 = {}) => {
return {
className: slots.segmentWrapper({
class: (0, import_shared_utils.clsx)(classNames == null ? void 0 : classNames.segmentWrapper, props2 == null ? void 0 : props2.className)
}),
"data-slot": "segment-wrapper",
"data-disabled": (0, import_shared_utils.dataAttr)(isDisabled),
"aria-label": ariaLabel,
...props2
};
},
[classNames == null ? void 0 : classNames.segmentWrapper, isDisabled]
);
const getHelperWrapperProps = (0, import_react.useCallback)(
(props2 = {}) => {
return {
className: slots.helperWrapper({
class: (0, import_shared_utils.clsx)(classNames == null ? void 0 : classNames.helperWrapper, props2 == null ? void 0 : props2.className)
}),
"data-slot": "helper-wrapper",
...props2
};
},
[classNames == null ? void 0 : classNames.helperWrapper]
);
const getErrorMessageProps = (0, import_react.useCallback)(
(props2 = {}) => {
return {
className: slots.errorMessage({
class: (0, import_shared_utils.clsx)(classNames == null ? void 0 : classNames.errorMessage, props2 == null ? void 0 : props2.className)
}),
"data-slot": "error-message",
...props2
};
},
[classNames == null ? void 0 : classNames.errorMessage]
);
const getDescriptionProps = (0, import_react.useCallback)(
(props2 = {}) => {
return {
className: slots.description({
class: (0, import_shared_utils.clsx)(classNames == null ? void 0 : classNames.description, props2 == null ? void 0 : props2.className)
}),
"data-slot": "description",
...props2
};
},
[classNames == null ? void 0 : classNames.description]
);
return {
Component,
inputRef,
length,
value,
type,
slots,
hasHelper,
classNames,
isInvalid,
description,
errorMessage,
isFocusVisible,
isFocused,
getBaseProps,
getInputOtpProps,
getSegmentWrapperProps,
getHelperWrapperProps,
getErrorMessageProps,
getDescriptionProps
};
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
useInputOtp
});