UNPKG

kwikid-components-react

Version:

KwikID's Component Library in React

246 lines (239 loc) 9.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _kwikidToolkit = require("kwikid-toolkit"); var _react = _interopRequireWildcard(require("react")); var _Messages = _interopRequireDefault(require("../../messages/Messages")); var _InputOtp = require("./InputOtp.definition"); var _InputOtp2 = require("./InputOtp.style"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } // Constants for magic numbers moved to the top of the file const DEFAULT_OTP_LENGTH = 6; // Default OTP length const BASE_36 = 36; // For the random string conversion const RANDOM_STRING_START = 2; // Starting index for the random string const RANDOM_STRING_LENGTH = 9; // Length of the random ID suffix const KwikUIInputOtp = _ref => { let { customStyles = { wrapper: {}, container: {}, label: {}, input: {} }, disabled = false, id = "input_otp", label = undefined, otpLength = DEFAULT_OTP_LENGTH, messages = [], placeholder = undefined, required = true, shape = _InputOtp.IKwikUIInputOtpShape.CURVED, size = _InputOtp.IKwikUIInputOtpSize.M, updateOn = _InputOtp.IKwikUIInputOtpUpdateOn.CHANGE, value = undefined, onInput = undefined, onInputValidate = undefined, isInputCopyDisabled = false, isInputPasteDisabled = false, onInputCopyDisabled = undefined, onInputPasteDisabled = undefined, mode = _InputOtp.IKwikUIInputOtpMode.MULTIPLE } = _ref; // Create a unique ID prefix for this component instance const instanceIdPrefix = _react.default.useMemo(() => `${id}-${Math.random().toString(BASE_36).substr(RANDOM_STRING_START, RANDOM_STRING_LENGTH)}`, [id]); const [valid, setValid] = _react.default.useState(undefined); const [inputFocused, setInputFocused] = _react.default.useState(undefined); const [otpValues, setOtpValues] = _react.default.useState(Array(otpLength || DEFAULT_OTP_LENGTH).fill("")); const [finalOtpValue, setFinalOtpValue] = _react.default.useState(value); // Create a ref for the container element to scope our DOM queries const containerRef = _react.default.useRef(null); // Define handleOnInput at the top to avoid "used before defined" error const handleOnInput = newValue => { if (onInputValidate) { const validation = onInputValidate(id, newValue); setValid(validation === null || validation === void 0 ? void 0 : validation.isValid); } else { setValid(true); } // Use Number.isNaN instead of isNaN to fix linter error if (Number.isNaN(Number(newValue))) { newValue = ""; } if (onInput && !disabled) { onInput(id, newValue); } }; (0, _react.useEffect)(() => { if (value) { const updatedValue = value.split(""); setOtpValues(updatedValue); } else { setOtpValues(new Array(otpLength || DEFAULT_OTP_LENGTH).fill("")); } }, [otpLength]); (0, _react.useEffect)(() => { if (mode === "multiple" && (value === null || value === void 0 ? void 0 : value.length) === otpLength) { const updatedValue = value.split(""); if (updatedValue.length) { setOtpValues(updatedValue); } } else { setFinalOtpValue(value); } }, []); (0, _react.useEffect)(() => { const updatedValue = (finalOtpValue === null || finalOtpValue === void 0 ? void 0 : finalOtpValue.split("")) || []; if (updatedValue.length !== otpLength) { while (updatedValue.length !== otpLength) { updatedValue.push(""); } } setOtpValues(updatedValue); }, [mode]); const handleSingleChange = e => { if (/^\d*$/.test(e.target.value)) { setFinalOtpValue(e.target.value); handleOnInput(e.target.value); } }; const handleChange = (e, index) => { if (/^\d*$/.test(e.target.value)) { const newOtpValues = [...otpValues]; newOtpValues[index] = e.target.value; setOtpValues(newOtpValues); const newValue = newOtpValues.join(""); setFinalOtpValue(newValue); handleOnInput(newValue); if (e.target.value && index < otpLength - 1) { if (containerRef.current) { const nextField = containerRef.current.querySelector(`#${instanceIdPrefix}-box-${index + 1}`); if (nextField) { nextField.focus(); } } } } }; const handleOnKeyDown = (e, index) => { if (e.key === "Backspace" && otpValues[index] === "") { if (index > 0) { if (containerRef.current) { const prevField = containerRef.current.querySelector(`#${instanceIdPrefix}-box-${index - 1}`); if (prevField) { prevField.focus(); } } } } }; const handleOnInputCopy = e => { if (isInputCopyDisabled) { e.preventDefault(); if (onInputCopyDisabled) { onInputCopyDisabled(); } } }; const handleOnInputPaste = e => { if (isInputPasteDisabled) { e.preventDefault(); if (onInputPasteDisabled) { onInputPasteDisabled(); } } }; const handleOnClick = (_e, _index) => { // Find the first empty input in this OTP component and focus it if (containerRef.current && mode === "multiple") { // Find the index of the first empty value const firstEmptyIndex = otpValues.findIndex(value => value === ""); // Only proceed if there's an empty input and we're not at the end if (firstEmptyIndex !== -1) { // Find the input element for this index within this component instance const firstEmptyInput = containerRef.current.querySelector(`#${instanceIdPrefix}-box-${firstEmptyIndex}`); // Focus the first empty input if found if (firstEmptyInput) { firstEmptyInput.focus(); } } } }; return /*#__PURE__*/_react.default.createElement(_InputOtp2.KwikUIStyleInputOtpWrapper, { style: customStyles.wrapper }, label && mode === "multiple" && /*#__PURE__*/_react.default.createElement(_InputOtp2.KwikUIStyleInputOtpOutsideLabel, { size: size, disabled: disabled, style: customStyles.label }, label, required && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "\xA0*")), /*#__PURE__*/_react.default.createElement(_InputOtp2.KwikUIStyleInputOtpContainer, { ref: containerRef, size: size, shape: shape, disabled: disabled, className: ` input input-number ${valid === false ? "input-error" : ""} ${valid !== false && inputFocused ? "input-focused" : ""} `, style: customStyles.container }, mode === "multiple" ? /*#__PURE__*/_react.default.createElement(_InputOtp2.KwikUIStyleInputOtpBoxesContainer, null, otpValues.map((value, index) => /*#__PURE__*/_react.default.createElement(_InputOtp2.KwikUIStyleInputOtpBox, { key: index, size: size, shape: shape, disabled: disabled, style: customStyles.input }, /*#__PURE__*/_react.default.createElement("input", { disabled: disabled, id: `${instanceIdPrefix}-box-${index}`, type: "text", maxLength: 1, value: value, placeholder: placeholder ? placeholder.substring(0, 1) : "", onChange: e => handleChange(e, index), onFocus: () => setInputFocused(true), onBlur: () => { if (updateOn === "blur") { handleOnInput(otpValues.join("")); } setInputFocused(false); }, onKeyDown: e => handleOnKeyDown(e, index), onCopy: handleOnInputCopy, onPaste: handleOnInputPaste, onClick: e => handleOnClick(e, index), style: customStyles.input })))) : /*#__PURE__*/_react.default.createElement(_InputOtp2.KwikUIStyleInputOtpSingleContainer, { shape: shape, size: size, disabled: disabled }, label && /*#__PURE__*/_react.default.createElement(_InputOtp2.KwikUIStyleInputOtpLabel, { size: size, disabled: disabled, style: customStyles.label }, label, required && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "\xA0*")), /*#__PURE__*/_react.default.createElement("input", { disabled: disabled, id: id, type: "text", maxLength: otpLength, value: finalOtpValue, placeholder: placeholder, onChange: handleSingleChange, onFocus: () => setInputFocused(true), onBlur: e => { if (updateOn === "blur") { handleOnInput(e.target.value); } setInputFocused(false); }, onCopy: handleOnInputCopy, onPaste: handleOnInputPaste, style: customStyles.input }))), (0, _kwikidToolkit.isNotEmptyValue)(messages) && /*#__PURE__*/_react.default.createElement(_InputOtp2.KwikUIStyleInputOtpMessagesContainer, null, /*#__PURE__*/_react.default.createElement(_Messages.default, { messages: messages, size: size }))); }; var _default = exports.default = KwikUIInputOtp;