Files
wdi-dashboard/node_modules/@chakra-ui/pin-input/dist/chunk-7FMJRAMH.mjs.map
2024-08-16 15:06:52 +05:30

1 line
15 KiB
Plaintext

{"version":3,"sources":["../src/use-pin-input.ts"],"sourcesContent":["import { createDescendantContext } from \"@chakra-ui/descendant\"\nimport { useControllableState } from \"@chakra-ui/react-use-controllable-state\"\nimport { ariaAttr, callAllHandlers } from \"@chakra-ui/shared-utils\"\nimport { createContext } from \"@chakra-ui/react-context\"\nimport { mergeRefs } from \"@chakra-ui/react-use-merge-refs\"\nimport { useCallback, useEffect, useState, useId } from \"react\"\n\n/* -------------------------------------------------------------------------------------------------\n * Create context to track descendants and their indices\n * -----------------------------------------------------------------------------------------------*/\n\nexport const [\n PinInputDescendantsProvider,\n usePinInputDescendantsContext,\n usePinInputDescendants,\n usePinInputDescendant,\n] = createDescendantContext<HTMLInputElement>()\n\n/* -------------------------------------------------------------------------------------------------\n * Create context that stores pin-input logic\n * -----------------------------------------------------------------------------------------------*/\n\nexport type PinInputContext = Omit<UsePinInputReturn, \"descendants\"> & {\n /**\n * Sets the pin input component to the disabled state\n */\n isDisabled?: boolean\n /**\n * Sets the pin input component to the invalid state\n */\n isInvalid?: boolean\n}\n\nexport const [PinInputProvider, usePinInputContext] =\n createContext<PinInputContext>({\n name: \"PinInputContext\",\n errorMessage:\n \"usePinInputContext: `context` is undefined. Seems you forgot to all pin input fields within `<PinInput />`\",\n })\n\n/* -------------------------------------------------------------------------------------------------\n * usePinInput hook\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface UsePinInputProps {\n /**\n * If `true`, the pin input receives focus on mount\n */\n autoFocus?: boolean\n /**\n * The value of the pin input. This is the value\n * that will be returned when the pin input is filled\n */\n value?: string\n /**\n * The default value of the pin input\n */\n defaultValue?: string\n /**\n * Function called on input change\n */\n onChange?: (value: string) => void\n /**\n * Function called when all inputs have valid values\n */\n onComplete?: (value: string) => void\n /**\n * The placeholder for the pin input\n */\n placeholder?: string\n /**\n * If `true`, focus will move automatically to the next input once filled\n * @default true\n */\n manageFocus?: boolean\n /**\n * If `true`, the pin input component signals to its fields that they should\n * use `autocomplete=\"one-time-code\"`.\n */\n otp?: boolean\n /**\n * The top-level id string that will be applied to the input fields.\n * The index of the input will be appended to this top-level id.\n *\n * @example\n * if id=\"foo\", the first input will have `foo-0`\n */\n id?: string\n /**\n * If `true`, the pin input component is put in the disabled state\n */\n isDisabled?: boolean\n /**\n * If `true`, the pin input component is put in the invalid state\n */\n isInvalid?: boolean\n /**\n * The type of values the pin-input should allow\n */\n type?: \"alphanumeric\" | \"number\"\n /**\n * If `true`, the input's value will be masked just like `type=password`\n */\n mask?: boolean\n}\n\nconst toArray = (value?: string) => value?.split(\"\")\n\nfunction validate(value: string, type: UsePinInputProps[\"type\"]) {\n const NUMERIC_REGEX = /^[0-9]+$/\n const ALPHA_NUMERIC_REGEX = /^[a-zA-Z0-9]+$/i\n const regex = type === \"alphanumeric\" ? ALPHA_NUMERIC_REGEX : NUMERIC_REGEX\n return regex.test(value)\n}\n\n/* -------------------------------------------------------------------------------------------------\n * usePinInput - handles the general pin input logic\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal\n */\nexport function usePinInput(props: UsePinInputProps = {}) {\n const {\n autoFocus,\n value,\n defaultValue,\n onChange,\n onComplete,\n placeholder = \"○\",\n manageFocus = true,\n otp = false,\n id: idProp,\n isDisabled,\n isInvalid,\n type = \"number\",\n mask,\n } = props\n\n const uuid = useId()\n const id = idProp ?? `pin-input-${uuid}`\n\n const descendants = usePinInputDescendants()\n\n const [moveFocus, setMoveFocus] = useState(true)\n const [focusedIndex, setFocusedIndex] = useState(-1)\n\n const [values, setValues] = useControllableState<string[]>({\n defaultValue: toArray(defaultValue) || [],\n value: toArray(value),\n onChange: (values) => onChange?.(values.join(\"\")),\n })\n\n useEffect(() => {\n if (autoFocus) {\n const first = descendants.first()\n if (first) {\n requestAnimationFrame(() => {\n first.node.focus()\n })\n }\n }\n // We don't want to listen for updates to `autoFocus` since it only runs initially\n // eslint-disable-next-line\n }, [descendants])\n\n const focusNext = useCallback(\n (index: number) => {\n if (!moveFocus || !manageFocus) return\n const next = descendants.next(index, false)\n if (next) {\n requestAnimationFrame(() => {\n next.node.focus()\n })\n }\n },\n [descendants, moveFocus, manageFocus],\n )\n\n const setValue = useCallback(\n (value: string, index: number, handleFocus: boolean = true) => {\n const nextValues = [...values]\n nextValues[index] = value\n setValues(nextValues)\n\n const isComplete =\n value !== \"\" &&\n nextValues.length === descendants.count() &&\n nextValues.every(\n (inputValue) => inputValue != null && inputValue !== \"\",\n )\n\n if (isComplete) {\n onComplete?.(nextValues.join(\"\"))\n } else {\n if (handleFocus) focusNext(index)\n }\n },\n [values, setValues, focusNext, onComplete, descendants],\n )\n\n const clear = useCallback(() => {\n const values: string[] = Array(descendants.count()).fill(\"\")\n setValues(values)\n const first = descendants.first()\n first?.node?.focus()\n }, [descendants, setValues])\n\n const getNextValue = useCallback((value: string, eventValue: string) => {\n let nextValue = eventValue\n if (value?.length > 0) {\n if (value[0] === eventValue.charAt(0)) {\n nextValue = eventValue.charAt(1)\n } else if (value[0] === eventValue.charAt(1)) {\n nextValue = eventValue.charAt(0)\n }\n }\n return nextValue\n }, [])\n\n const getInputProps = useCallback(\n (props: InputProps & { index: number }): InputProps => {\n const { index, ...rest } = props\n\n /**\n * Improved from: https://github.com/uber/baseweb/blob/master/src/pin-code/pin-code.js\n */\n const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const eventValue = event.target.value\n const currentValue = values[index]\n const nextValue = getNextValue(currentValue, eventValue)\n\n // if the value was removed using backspace\n if (nextValue === \"\") {\n setValue(\"\", index)\n return\n }\n\n // in the case of an autocomplete or copy and paste\n if (eventValue.length > 2) {\n // see if we can use the string to fill out our values\n if (validate(eventValue, type)) {\n // Ensure the value matches the number of inputs\n const nextValue = eventValue\n .split(\"\")\n .filter((_, index) => index < descendants.count())\n\n setValues(nextValue)\n\n // if pasting fills the entire input fields, trigger `onComplete`\n if (nextValue.length === descendants.count()) {\n onComplete?.(nextValue.join(\"\"))\n }\n }\n } else {\n // only set if the new value is a number\n if (validate(nextValue, type)) {\n setValue(nextValue, index)\n }\n\n setMoveFocus(true)\n }\n }\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === \"Backspace\" && manageFocus) {\n if ((event.target as HTMLInputElement).value === \"\") {\n const prevInput = descendants.prev(index, false)\n if (prevInput) {\n setValue(\"\", index - 1, false)\n prevInput.node?.focus()\n setMoveFocus(true)\n }\n } else {\n setMoveFocus(false)\n }\n }\n }\n\n const onFocus = () => {\n setFocusedIndex(index)\n }\n\n const onBlur = () => {\n setFocusedIndex(-1)\n }\n\n const hasFocus = focusedIndex === index\n const inputType = type === \"number\" ? \"tel\" : \"text\"\n\n return {\n \"aria-label\": \"Please enter your pin code\",\n inputMode: type === \"number\" ? \"numeric\" : \"text\",\n type: mask ? \"password\" : inputType,\n ...rest,\n id: `${id}-${index}`,\n disabled: isDisabled,\n \"aria-invalid\": ariaAttr(isInvalid),\n onChange: callAllHandlers(rest.onChange, onChange),\n onKeyDown: callAllHandlers(rest.onKeyDown, onKeyDown),\n onFocus: callAllHandlers(rest.onFocus, onFocus),\n onBlur: callAllHandlers(rest.onBlur, onBlur),\n value: values[index] || \"\",\n autoComplete: otp ? \"one-time-code\" : \"off\",\n placeholder: hasFocus ? \"\" : placeholder,\n }\n },\n [\n descendants,\n focusedIndex,\n getNextValue,\n id,\n isDisabled,\n mask,\n isInvalid,\n manageFocus,\n onComplete,\n otp,\n placeholder,\n setValue,\n setValues,\n type,\n values,\n ],\n )\n\n return {\n // prop getter\n getInputProps,\n // state\n id,\n descendants,\n values,\n // actions\n setValue,\n setValues,\n clear,\n }\n}\n\nexport type UsePinInputReturn = ReturnType<typeof usePinInput>\n\nexport interface UsePinInputFieldProps extends InputProps {\n ref?: React.Ref<HTMLInputElement>\n}\n\n/**\n * @internal\n */\nexport function usePinInputField(\n props: UsePinInputFieldProps = {},\n ref: React.Ref<any> = null,\n) {\n const { getInputProps } = usePinInputContext()\n const { index, register } = usePinInputDescendant()\n\n return getInputProps({\n ...props,\n ref: mergeRefs(register, ref),\n index,\n })\n}\n\ninterface InputProps\n extends Omit<\n React.ComponentPropsWithRef<\"input\">,\n \"color\" | \"height\" | \"width\"\n > {}\n"],"mappings":"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","names":["values","value","props","onChange","nextValue","index"]}