@workos-inc/widgets 1.14.1-next.1781375125093 → 1.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 1.14.1
|
|
3
|
+
## 1.14.1
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
7
|
- [#282](https://github.com/workos/widgets/pull/282) [`401070a`](https://github.com/workos/widgets/commit/401070ab62f3948c3b264db249ecda2b985afe76) Thanks [@workosbot](https://github.com/workosbot)! - Sync generated API from upstream OpenAPI spec.
|
|
8
8
|
|
|
9
|
+
- [#285](https://github.com/workos/widgets/pull/285) [`bd27a7e`](https://github.com/workos/widgets/commit/bd27a7eb40cbd0c393865fb2a341c952967fa143) Thanks [@kairadiant](https://github.com/kairadiant)! - Fix OTP input not clearing digit on backspace after error state.
|
|
10
|
+
|
|
9
11
|
## 1.14.0
|
|
10
12
|
|
|
11
13
|
### Minor Changes
|
|
@@ -186,13 +186,11 @@ const Input = React.forwardRef(
|
|
|
186
186
|
textAlign: "center"
|
|
187
187
|
},
|
|
188
188
|
onChange: (event) => {
|
|
189
|
-
if (event.target.validity.valid) {
|
|
189
|
+
if (event.target.validity.valid || event.target.value === "") {
|
|
190
190
|
const char2 = event.target.value;
|
|
191
191
|
const index2 = Number(event.target.dataset.index ?? -1);
|
|
192
192
|
otpContext.onCharChange(char2, index2);
|
|
193
|
-
|
|
194
|
-
focusSibling(event.currentTarget, { back: char2 === "" });
|
|
195
|
-
}
|
|
193
|
+
focusSibling(event.currentTarget, { back: char2 === "" });
|
|
196
194
|
}
|
|
197
195
|
},
|
|
198
196
|
onKeyDown: (event) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/otp-input.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n composeRefs,\n useComposedRefs,\n useControllableState,\n} from \"radix-ui/internal\";\nimport { Form } from \"radix-ui\";\nimport { Grid } from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { TextField } from \"./elements.js\";\n\ninterface OptContextType {\n value: string[];\n readOnly?: boolean;\n state?: \"valid\" | \"invalid\";\n onEnterPressed: () => void;\n onChildAdd: (input: HTMLInputElement) => void;\n onCharChange: (char: string, index: number) => void;\n allChildrenAdded: boolean;\n}\n\nconst OtpContext = React.createContext<OptContextType | undefined>(undefined);\n\ntype OtpRootProps = React.ComponentPropsWithoutRef<typeof Grid> & {\n onValueChange?: (value: string) => void;\n id?: string;\n name?: string;\n readOnly?: boolean;\n state?: \"valid\" | \"invalid\";\n value?: string;\n defaultValue?: string;\n autoSubmit?: boolean;\n};\n\nexport const Root = React.forwardRef<HTMLInputElement, OtpRootProps>(\n function Root(\n {\n name,\n id,\n defaultValue,\n value: valueProp,\n onValueChange,\n autoSubmit,\n children,\n readOnly,\n state,\n ...gridProps\n },\n forwardedRef,\n ) {\n const [lastCharIndex, setLastCharIndex] = React.useState<number>(0);\n const [allChildrenAdded, setAllChildrenAdded] =\n React.useState<boolean>(false);\n const childCount = React.Children.count(children);\n\n const [value, setValue] = useControllableState({\n prop: getValueAsArray(valueProp, childCount),\n defaultProp: getValueAsArray(defaultValue, childCount) ?? [],\n onChange: (value) => onValueChange?.(value.join(\"\")),\n });\n\n const hiddenInputRef = React.useRef<HTMLInputElement>(null);\n const childrenRefs = React.useRef<HTMLInputElement[]>([]);\n\n const attemptAutoSubmit = React.useCallback(\n (enterPressed = false) => {\n if (\n autoSubmit &&\n value &&\n value.every((char) => char !== \"\") &&\n (enterPressed || lastCharIndex + 1 === childCount)\n ) {\n hiddenInputRef.current?.form?.requestSubmit();\n }\n },\n [value, childCount, lastCharIndex, autoSubmit],\n );\n\n const handleEnterPressed = React.useCallback(\n () => attemptAutoSubmit(true),\n [attemptAutoSubmit],\n );\n\n const handleChildAdd = React.useCallback(\n (input: HTMLInputElement) => {\n if (input) {\n input.dataset.index = `${childrenRefs.current.length}`;\n childrenRefs.current.push(input);\n } else {\n childrenRefs.current.pop();\n }\n\n if (childrenRefs.current.length === childCount) {\n setAllChildrenAdded(true);\n }\n },\n [childCount],\n );\n\n const handleCharChange = React.useCallback(\n (char: string, index: number) => {\n setValue((previousValue) => {\n const arrayToCopy = previousValue ?? createEmptyArray(childCount);\n const newValue = [...arrayToCopy];\n newValue[index] = char;\n return newValue;\n });\n setLastCharIndex(index);\n },\n [childCount, setValue],\n );\n\n const otpContext = React.useMemo(\n () => ({\n value: value ?? createEmptyArray(childCount),\n readOnly,\n state,\n allChildrenAdded,\n onEnterPressed: handleEnterPressed,\n onChildAdd: handleChildAdd,\n onCharChange: handleCharChange,\n }),\n [\n value,\n allChildrenAdded,\n readOnly,\n state,\n childCount,\n handleEnterPressed,\n handleChildAdd,\n handleCharChange,\n ],\n );\n\n React.useEffect(attemptAutoSubmit, [attemptAutoSubmit]);\n\n return (\n <OtpContext.Provider value={otpContext}>\n <Grid\n columns={`repeat(${childCount}, 1fr)`}\n {...gridProps}\n onPaste={(event: React.ClipboardEvent<HTMLDivElement>) => {\n event.preventDefault();\n const pastedValue = event.clipboardData.getData(\"Text\");\n const sanitizedValue = pastedValue\n .replace(/[^\\d]/g, \"\")\n .slice(0, childCount);\n const value = sanitizedValue\n .padEnd(childCount, \"#\")\n .split(\"\")\n .map((char) => (char === \"#\" ? \"\" : char));\n\n setValue(value);\n setLastCharIndex(sanitizedValue.length - 1);\n\n const index = Math.min(sanitizedValue.length, childCount - 1);\n childrenRefs.current?.[index]?.focus();\n }}\n >\n {children}\n <input\n ref={composeRefs(forwardedRef, hiddenInputRef)}\n defaultValue={value?.join(\"\")}\n minLength={childCount}\n name={name}\n type=\"hidden\"\n />\n </Grid>\n </OtpContext.Provider>\n );\n },\n);\n\ninterface InputProps extends React.ComponentProps<typeof TextField> {\n autoComplete?: \"one-time-code\" | \"off\";\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n function Input(\n { style, readOnly, autoComplete = \"off\", ...props },\n forwardedRef,\n ) {\n const otpContext = useOptContext();\n const inputRef = React.useRef<HTMLInputElement>(null);\n const composedInputRef = useComposedRefs(\n forwardedRef,\n inputRef,\n otpContext.onChildAdd,\n );\n\n // FIXME: This should be refactored\n // eslint-disable-next-line react-hooks/refs\n const index = Number(inputRef.current?.dataset.index ?? -1);\n const char = otpContext.value[index] ?? \"\";\n\n return (\n <Form.Field name={`otp-${index}`} asChild>\n <Form.Control asChild>\n <TextField\n ref={composedInputRef}\n autoComplete={index === 0 ? autoComplete : \"off\"}\n color={otpContext.state === \"invalid\" ? \"red\" : undefined}\n inputMode=\"numeric\"\n maxLength={1}\n pattern=\"\\d{1}\"\n readOnly={readOnly ?? otpContext.readOnly}\n size=\"3\"\n value={char}\n variant={otpContext.state === \"invalid\" ? \"soft\" : undefined}\n style={{\n ...style,\n height: \"auto\",\n \"--text-field-padding\": 0,\n textAlign: \"center\",\n }}\n onChange={(event) => {\n // Only update the value if it matches the input pattern (number only)\n if (event.target.validity.valid) {\n const char = event.target.value;\n const index = Number(event.target.dataset.index ?? -1);\n otpContext.onCharChange(char, index);\n if (char !== \"\") {\n focusSibling(event.currentTarget, { back: char === \"\" });\n }\n }\n }}\n onKeyDown={(event) => {\n if (event.key === \"ArrowLeft\") {\n focusSibling(event.currentTarget, { back: true });\n event.preventDefault();\n } else if (event.key === \"ArrowRight\") {\n focusSibling(event.currentTarget);\n event.preventDefault();\n } else if (event.key === \"Backspace\" && char === \"\") {\n focusSibling(event.currentTarget, { back: true });\n } else if (event.key === \"Enter\" && char !== \"\") {\n otpContext.onEnterPressed();\n }\n }}\n {...props}\n />\n </Form.Control>\n </Form.Field>\n );\n },\n);\n\nconst useOptContext = () => {\n const optContext = React.useContext(OtpContext);\n\n if (!optContext) {\n throw new Error(\n \"OtpInput compound components cannot be rendered outside the OtpRoot component\",\n );\n }\n\n return optContext;\n};\n\nfunction focusSibling(input: HTMLInputElement, { back = false } = {}) {\n const sibling = back\n ? input.parentElement?.previousSibling\n : input.parentElement?.nextSibling;\n const siblingInput = sibling?.firstChild;\n if (siblingInput && siblingInput instanceof HTMLInputElement) {\n siblingInput?.focus();\n siblingInput?.select();\n }\n}\n\nconst getValueAsArray = (value: string | undefined, length: number) => {\n if (!value) {\n return undefined;\n }\n\n return createEmptyArray(length).map((_, index) => value?.[index] ?? \"\");\n};\n\nconst createEmptyArray = (length: number): string[] =>\n Array.from<string>({ length }).fill(\"\");\n"],"mappings":"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","names":["Root","value","Input","char","index"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/otp-input.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n composeRefs,\n useComposedRefs,\n useControllableState,\n} from \"radix-ui/internal\";\nimport { Form } from \"radix-ui\";\nimport { Grid } from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { TextField } from \"./elements.js\";\n\ninterface OptContextType {\n value: string[];\n readOnly?: boolean;\n state?: \"valid\" | \"invalid\";\n onEnterPressed: () => void;\n onChildAdd: (input: HTMLInputElement) => void;\n onCharChange: (char: string, index: number) => void;\n allChildrenAdded: boolean;\n}\n\nconst OtpContext = React.createContext<OptContextType | undefined>(undefined);\n\ntype OtpRootProps = React.ComponentPropsWithoutRef<typeof Grid> & {\n onValueChange?: (value: string) => void;\n id?: string;\n name?: string;\n readOnly?: boolean;\n state?: \"valid\" | \"invalid\";\n value?: string;\n defaultValue?: string;\n autoSubmit?: boolean;\n};\n\nexport const Root = React.forwardRef<HTMLInputElement, OtpRootProps>(\n function Root(\n {\n name,\n id,\n defaultValue,\n value: valueProp,\n onValueChange,\n autoSubmit,\n children,\n readOnly,\n state,\n ...gridProps\n },\n forwardedRef,\n ) {\n const [lastCharIndex, setLastCharIndex] = React.useState<number>(0);\n const [allChildrenAdded, setAllChildrenAdded] =\n React.useState<boolean>(false);\n const childCount = React.Children.count(children);\n\n const [value, setValue] = useControllableState({\n prop: getValueAsArray(valueProp, childCount),\n defaultProp: getValueAsArray(defaultValue, childCount) ?? [],\n onChange: (value) => onValueChange?.(value.join(\"\")),\n });\n\n const hiddenInputRef = React.useRef<HTMLInputElement>(null);\n const childrenRefs = React.useRef<HTMLInputElement[]>([]);\n\n const attemptAutoSubmit = React.useCallback(\n (enterPressed = false) => {\n if (\n autoSubmit &&\n value &&\n value.every((char) => char !== \"\") &&\n (enterPressed || lastCharIndex + 1 === childCount)\n ) {\n hiddenInputRef.current?.form?.requestSubmit();\n }\n },\n [value, childCount, lastCharIndex, autoSubmit],\n );\n\n const handleEnterPressed = React.useCallback(\n () => attemptAutoSubmit(true),\n [attemptAutoSubmit],\n );\n\n const handleChildAdd = React.useCallback(\n (input: HTMLInputElement) => {\n if (input) {\n input.dataset.index = `${childrenRefs.current.length}`;\n childrenRefs.current.push(input);\n } else {\n childrenRefs.current.pop();\n }\n\n if (childrenRefs.current.length === childCount) {\n setAllChildrenAdded(true);\n }\n },\n [childCount],\n );\n\n const handleCharChange = React.useCallback(\n (char: string, index: number) => {\n setValue((previousValue) => {\n const arrayToCopy = previousValue ?? createEmptyArray(childCount);\n const newValue = [...arrayToCopy];\n newValue[index] = char;\n return newValue;\n });\n setLastCharIndex(index);\n },\n [childCount, setValue],\n );\n\n const otpContext = React.useMemo(\n () => ({\n value: value ?? createEmptyArray(childCount),\n readOnly,\n state,\n allChildrenAdded,\n onEnterPressed: handleEnterPressed,\n onChildAdd: handleChildAdd,\n onCharChange: handleCharChange,\n }),\n [\n value,\n allChildrenAdded,\n readOnly,\n state,\n childCount,\n handleEnterPressed,\n handleChildAdd,\n handleCharChange,\n ],\n );\n\n React.useEffect(attemptAutoSubmit, [attemptAutoSubmit]);\n\n return (\n <OtpContext.Provider value={otpContext}>\n <Grid\n columns={`repeat(${childCount}, 1fr)`}\n {...gridProps}\n onPaste={(event: React.ClipboardEvent<HTMLDivElement>) => {\n event.preventDefault();\n const pastedValue = event.clipboardData.getData(\"Text\");\n const sanitizedValue = pastedValue\n .replace(/[^\\d]/g, \"\")\n .slice(0, childCount);\n const value = sanitizedValue\n .padEnd(childCount, \"#\")\n .split(\"\")\n .map((char) => (char === \"#\" ? \"\" : char));\n\n setValue(value);\n setLastCharIndex(sanitizedValue.length - 1);\n\n const index = Math.min(sanitizedValue.length, childCount - 1);\n childrenRefs.current?.[index]?.focus();\n }}\n >\n {children}\n <input\n ref={composeRefs(forwardedRef, hiddenInputRef)}\n defaultValue={value?.join(\"\")}\n minLength={childCount}\n name={name}\n type=\"hidden\"\n />\n </Grid>\n </OtpContext.Provider>\n );\n },\n);\n\ninterface InputProps extends React.ComponentProps<typeof TextField> {\n autoComplete?: \"one-time-code\" | \"off\";\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n function Input(\n { style, readOnly, autoComplete = \"off\", ...props },\n forwardedRef,\n ) {\n const otpContext = useOptContext();\n const inputRef = React.useRef<HTMLInputElement>(null);\n const composedInputRef = useComposedRefs(\n forwardedRef,\n inputRef,\n otpContext.onChildAdd,\n );\n\n // FIXME: This should be refactored\n // eslint-disable-next-line react-hooks/refs\n const index = Number(inputRef.current?.dataset.index ?? -1);\n const char = otpContext.value[index] ?? \"\";\n\n return (\n <Form.Field name={`otp-${index}`} asChild>\n <Form.Control asChild>\n <TextField\n ref={composedInputRef}\n autoComplete={index === 0 ? autoComplete : \"off\"}\n color={otpContext.state === \"invalid\" ? \"red\" : undefined}\n inputMode=\"numeric\"\n maxLength={1}\n pattern=\"\\d{1}\"\n readOnly={readOnly ?? otpContext.readOnly}\n size=\"3\"\n value={char}\n variant={otpContext.state === \"invalid\" ? \"soft\" : undefined}\n style={{\n ...style,\n height: \"auto\",\n \"--text-field-padding\": 0,\n textAlign: \"center\",\n }}\n onChange={(event) => {\n // Update the value if it matches the input pattern (number only) or is empty (backspace)\n if (event.target.validity.valid || event.target.value === \"\") {\n const char = event.target.value;\n const index = Number(event.target.dataset.index ?? -1);\n otpContext.onCharChange(char, index);\n focusSibling(event.currentTarget, { back: char === \"\" });\n }\n }}\n onKeyDown={(event) => {\n if (event.key === \"ArrowLeft\") {\n focusSibling(event.currentTarget, { back: true });\n event.preventDefault();\n } else if (event.key === \"ArrowRight\") {\n focusSibling(event.currentTarget);\n event.preventDefault();\n } else if (event.key === \"Backspace\" && char === \"\") {\n focusSibling(event.currentTarget, { back: true });\n } else if (event.key === \"Enter\" && char !== \"\") {\n otpContext.onEnterPressed();\n }\n }}\n {...props}\n />\n </Form.Control>\n </Form.Field>\n );\n },\n);\n\nconst useOptContext = () => {\n const optContext = React.useContext(OtpContext);\n\n if (!optContext) {\n throw new Error(\n \"OtpInput compound components cannot be rendered outside the OtpRoot component\",\n );\n }\n\n return optContext;\n};\n\nfunction focusSibling(input: HTMLInputElement, { back = false } = {}) {\n const sibling = back\n ? input.parentElement?.previousSibling\n : input.parentElement?.nextSibling;\n const siblingInput = sibling?.firstChild;\n if (siblingInput && siblingInput instanceof HTMLInputElement) {\n siblingInput?.focus();\n siblingInput?.select();\n }\n}\n\nconst getValueAsArray = (value: string | undefined, length: number) => {\n if (!value) {\n return undefined;\n }\n\n return createEmptyArray(length).map((_, index) => value?.[index] ?? \"\");\n};\n\nconst createEmptyArray = (length: number): string[] =>\n Array.from<string>({ length }).fill(\"\");\n"],"mappings":"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","names":["Root","value","Input","char","index"]}
|
|
@@ -156,13 +156,11 @@ const Input = React.forwardRef(
|
|
|
156
156
|
textAlign: "center"
|
|
157
157
|
},
|
|
158
158
|
onChange: (event) => {
|
|
159
|
-
if (event.target.validity.valid) {
|
|
159
|
+
if (event.target.validity.valid || event.target.value === "") {
|
|
160
160
|
const char2 = event.target.value;
|
|
161
161
|
const index2 = Number(event.target.dataset.index ?? -1);
|
|
162
162
|
otpContext.onCharChange(char2, index2);
|
|
163
|
-
|
|
164
|
-
focusSibling(event.currentTarget, { back: char2 === "" });
|
|
165
|
-
}
|
|
163
|
+
focusSibling(event.currentTarget, { back: char2 === "" });
|
|
166
164
|
}
|
|
167
165
|
},
|
|
168
166
|
onKeyDown: (event) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/otp-input.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n composeRefs,\n useComposedRefs,\n useControllableState,\n} from \"radix-ui/internal\";\nimport { Form } from \"radix-ui\";\nimport { Grid } from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { TextField } from \"./elements.js\";\n\ninterface OptContextType {\n value: string[];\n readOnly?: boolean;\n state?: \"valid\" | \"invalid\";\n onEnterPressed: () => void;\n onChildAdd: (input: HTMLInputElement) => void;\n onCharChange: (char: string, index: number) => void;\n allChildrenAdded: boolean;\n}\n\nconst OtpContext = React.createContext<OptContextType | undefined>(undefined);\n\ntype OtpRootProps = React.ComponentPropsWithoutRef<typeof Grid> & {\n onValueChange?: (value: string) => void;\n id?: string;\n name?: string;\n readOnly?: boolean;\n state?: \"valid\" | \"invalid\";\n value?: string;\n defaultValue?: string;\n autoSubmit?: boolean;\n};\n\nexport const Root = React.forwardRef<HTMLInputElement, OtpRootProps>(\n function Root(\n {\n name,\n id,\n defaultValue,\n value: valueProp,\n onValueChange,\n autoSubmit,\n children,\n readOnly,\n state,\n ...gridProps\n },\n forwardedRef,\n ) {\n const [lastCharIndex, setLastCharIndex] = React.useState<number>(0);\n const [allChildrenAdded, setAllChildrenAdded] =\n React.useState<boolean>(false);\n const childCount = React.Children.count(children);\n\n const [value, setValue] = useControllableState({\n prop: getValueAsArray(valueProp, childCount),\n defaultProp: getValueAsArray(defaultValue, childCount) ?? [],\n onChange: (value) => onValueChange?.(value.join(\"\")),\n });\n\n const hiddenInputRef = React.useRef<HTMLInputElement>(null);\n const childrenRefs = React.useRef<HTMLInputElement[]>([]);\n\n const attemptAutoSubmit = React.useCallback(\n (enterPressed = false) => {\n if (\n autoSubmit &&\n value &&\n value.every((char) => char !== \"\") &&\n (enterPressed || lastCharIndex + 1 === childCount)\n ) {\n hiddenInputRef.current?.form?.requestSubmit();\n }\n },\n [value, childCount, lastCharIndex, autoSubmit],\n );\n\n const handleEnterPressed = React.useCallback(\n () => attemptAutoSubmit(true),\n [attemptAutoSubmit],\n );\n\n const handleChildAdd = React.useCallback(\n (input: HTMLInputElement) => {\n if (input) {\n input.dataset.index = `${childrenRefs.current.length}`;\n childrenRefs.current.push(input);\n } else {\n childrenRefs.current.pop();\n }\n\n if (childrenRefs.current.length === childCount) {\n setAllChildrenAdded(true);\n }\n },\n [childCount],\n );\n\n const handleCharChange = React.useCallback(\n (char: string, index: number) => {\n setValue((previousValue) => {\n const arrayToCopy = previousValue ?? createEmptyArray(childCount);\n const newValue = [...arrayToCopy];\n newValue[index] = char;\n return newValue;\n });\n setLastCharIndex(index);\n },\n [childCount, setValue],\n );\n\n const otpContext = React.useMemo(\n () => ({\n value: value ?? createEmptyArray(childCount),\n readOnly,\n state,\n allChildrenAdded,\n onEnterPressed: handleEnterPressed,\n onChildAdd: handleChildAdd,\n onCharChange: handleCharChange,\n }),\n [\n value,\n allChildrenAdded,\n readOnly,\n state,\n childCount,\n handleEnterPressed,\n handleChildAdd,\n handleCharChange,\n ],\n );\n\n React.useEffect(attemptAutoSubmit, [attemptAutoSubmit]);\n\n return (\n <OtpContext.Provider value={otpContext}>\n <Grid\n columns={`repeat(${childCount}, 1fr)`}\n {...gridProps}\n onPaste={(event: React.ClipboardEvent<HTMLDivElement>) => {\n event.preventDefault();\n const pastedValue = event.clipboardData.getData(\"Text\");\n const sanitizedValue = pastedValue\n .replace(/[^\\d]/g, \"\")\n .slice(0, childCount);\n const value = sanitizedValue\n .padEnd(childCount, \"#\")\n .split(\"\")\n .map((char) => (char === \"#\" ? \"\" : char));\n\n setValue(value);\n setLastCharIndex(sanitizedValue.length - 1);\n\n const index = Math.min(sanitizedValue.length, childCount - 1);\n childrenRefs.current?.[index]?.focus();\n }}\n >\n {children}\n <input\n ref={composeRefs(forwardedRef, hiddenInputRef)}\n defaultValue={value?.join(\"\")}\n minLength={childCount}\n name={name}\n type=\"hidden\"\n />\n </Grid>\n </OtpContext.Provider>\n );\n },\n);\n\ninterface InputProps extends React.ComponentProps<typeof TextField> {\n autoComplete?: \"one-time-code\" | \"off\";\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n function Input(\n { style, readOnly, autoComplete = \"off\", ...props },\n forwardedRef,\n ) {\n const otpContext = useOptContext();\n const inputRef = React.useRef<HTMLInputElement>(null);\n const composedInputRef = useComposedRefs(\n forwardedRef,\n inputRef,\n otpContext.onChildAdd,\n );\n\n // FIXME: This should be refactored\n // eslint-disable-next-line react-hooks/refs\n const index = Number(inputRef.current?.dataset.index ?? -1);\n const char = otpContext.value[index] ?? \"\";\n\n return (\n <Form.Field name={`otp-${index}`} asChild>\n <Form.Control asChild>\n <TextField\n ref={composedInputRef}\n autoComplete={index === 0 ? autoComplete : \"off\"}\n color={otpContext.state === \"invalid\" ? \"red\" : undefined}\n inputMode=\"numeric\"\n maxLength={1}\n pattern=\"\\d{1}\"\n readOnly={readOnly ?? otpContext.readOnly}\n size=\"3\"\n value={char}\n variant={otpContext.state === \"invalid\" ? \"soft\" : undefined}\n style={{\n ...style,\n height: \"auto\",\n \"--text-field-padding\": 0,\n textAlign: \"center\",\n }}\n onChange={(event) => {\n // Only update the value if it matches the input pattern (number only)\n if (event.target.validity.valid) {\n const char = event.target.value;\n const index = Number(event.target.dataset.index ?? -1);\n otpContext.onCharChange(char, index);\n if (char !== \"\") {\n focusSibling(event.currentTarget, { back: char === \"\" });\n }\n }\n }}\n onKeyDown={(event) => {\n if (event.key === \"ArrowLeft\") {\n focusSibling(event.currentTarget, { back: true });\n event.preventDefault();\n } else if (event.key === \"ArrowRight\") {\n focusSibling(event.currentTarget);\n event.preventDefault();\n } else if (event.key === \"Backspace\" && char === \"\") {\n focusSibling(event.currentTarget, { back: true });\n } else if (event.key === \"Enter\" && char !== \"\") {\n otpContext.onEnterPressed();\n }\n }}\n {...props}\n />\n </Form.Control>\n </Form.Field>\n );\n },\n);\n\nconst useOptContext = () => {\n const optContext = React.useContext(OtpContext);\n\n if (!optContext) {\n throw new Error(\n \"OtpInput compound components cannot be rendered outside the OtpRoot component\",\n );\n }\n\n return optContext;\n};\n\nfunction focusSibling(input: HTMLInputElement, { back = false } = {}) {\n const sibling = back\n ? input.parentElement?.previousSibling\n : input.parentElement?.nextSibling;\n const siblingInput = sibling?.firstChild;\n if (siblingInput && siblingInput instanceof HTMLInputElement) {\n siblingInput?.focus();\n siblingInput?.select();\n }\n}\n\nconst getValueAsArray = (value: string | undefined, length: number) => {\n if (!value) {\n return undefined;\n }\n\n return createEmptyArray(length).map((_, index) => value?.[index] ?? \"\");\n};\n\nconst createEmptyArray = (length: number): string[] =>\n Array.from<string>({ length }).fill(\"\");\n"],"mappings":"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","names":["Root","value","Input","char","index"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/otp-input.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n composeRefs,\n useComposedRefs,\n useControllableState,\n} from \"radix-ui/internal\";\nimport { Form } from \"radix-ui\";\nimport { Grid } from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { TextField } from \"./elements.js\";\n\ninterface OptContextType {\n value: string[];\n readOnly?: boolean;\n state?: \"valid\" | \"invalid\";\n onEnterPressed: () => void;\n onChildAdd: (input: HTMLInputElement) => void;\n onCharChange: (char: string, index: number) => void;\n allChildrenAdded: boolean;\n}\n\nconst OtpContext = React.createContext<OptContextType | undefined>(undefined);\n\ntype OtpRootProps = React.ComponentPropsWithoutRef<typeof Grid> & {\n onValueChange?: (value: string) => void;\n id?: string;\n name?: string;\n readOnly?: boolean;\n state?: \"valid\" | \"invalid\";\n value?: string;\n defaultValue?: string;\n autoSubmit?: boolean;\n};\n\nexport const Root = React.forwardRef<HTMLInputElement, OtpRootProps>(\n function Root(\n {\n name,\n id,\n defaultValue,\n value: valueProp,\n onValueChange,\n autoSubmit,\n children,\n readOnly,\n state,\n ...gridProps\n },\n forwardedRef,\n ) {\n const [lastCharIndex, setLastCharIndex] = React.useState<number>(0);\n const [allChildrenAdded, setAllChildrenAdded] =\n React.useState<boolean>(false);\n const childCount = React.Children.count(children);\n\n const [value, setValue] = useControllableState({\n prop: getValueAsArray(valueProp, childCount),\n defaultProp: getValueAsArray(defaultValue, childCount) ?? [],\n onChange: (value) => onValueChange?.(value.join(\"\")),\n });\n\n const hiddenInputRef = React.useRef<HTMLInputElement>(null);\n const childrenRefs = React.useRef<HTMLInputElement[]>([]);\n\n const attemptAutoSubmit = React.useCallback(\n (enterPressed = false) => {\n if (\n autoSubmit &&\n value &&\n value.every((char) => char !== \"\") &&\n (enterPressed || lastCharIndex + 1 === childCount)\n ) {\n hiddenInputRef.current?.form?.requestSubmit();\n }\n },\n [value, childCount, lastCharIndex, autoSubmit],\n );\n\n const handleEnterPressed = React.useCallback(\n () => attemptAutoSubmit(true),\n [attemptAutoSubmit],\n );\n\n const handleChildAdd = React.useCallback(\n (input: HTMLInputElement) => {\n if (input) {\n input.dataset.index = `${childrenRefs.current.length}`;\n childrenRefs.current.push(input);\n } else {\n childrenRefs.current.pop();\n }\n\n if (childrenRefs.current.length === childCount) {\n setAllChildrenAdded(true);\n }\n },\n [childCount],\n );\n\n const handleCharChange = React.useCallback(\n (char: string, index: number) => {\n setValue((previousValue) => {\n const arrayToCopy = previousValue ?? createEmptyArray(childCount);\n const newValue = [...arrayToCopy];\n newValue[index] = char;\n return newValue;\n });\n setLastCharIndex(index);\n },\n [childCount, setValue],\n );\n\n const otpContext = React.useMemo(\n () => ({\n value: value ?? createEmptyArray(childCount),\n readOnly,\n state,\n allChildrenAdded,\n onEnterPressed: handleEnterPressed,\n onChildAdd: handleChildAdd,\n onCharChange: handleCharChange,\n }),\n [\n value,\n allChildrenAdded,\n readOnly,\n state,\n childCount,\n handleEnterPressed,\n handleChildAdd,\n handleCharChange,\n ],\n );\n\n React.useEffect(attemptAutoSubmit, [attemptAutoSubmit]);\n\n return (\n <OtpContext.Provider value={otpContext}>\n <Grid\n columns={`repeat(${childCount}, 1fr)`}\n {...gridProps}\n onPaste={(event: React.ClipboardEvent<HTMLDivElement>) => {\n event.preventDefault();\n const pastedValue = event.clipboardData.getData(\"Text\");\n const sanitizedValue = pastedValue\n .replace(/[^\\d]/g, \"\")\n .slice(0, childCount);\n const value = sanitizedValue\n .padEnd(childCount, \"#\")\n .split(\"\")\n .map((char) => (char === \"#\" ? \"\" : char));\n\n setValue(value);\n setLastCharIndex(sanitizedValue.length - 1);\n\n const index = Math.min(sanitizedValue.length, childCount - 1);\n childrenRefs.current?.[index]?.focus();\n }}\n >\n {children}\n <input\n ref={composeRefs(forwardedRef, hiddenInputRef)}\n defaultValue={value?.join(\"\")}\n minLength={childCount}\n name={name}\n type=\"hidden\"\n />\n </Grid>\n </OtpContext.Provider>\n );\n },\n);\n\ninterface InputProps extends React.ComponentProps<typeof TextField> {\n autoComplete?: \"one-time-code\" | \"off\";\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n function Input(\n { style, readOnly, autoComplete = \"off\", ...props },\n forwardedRef,\n ) {\n const otpContext = useOptContext();\n const inputRef = React.useRef<HTMLInputElement>(null);\n const composedInputRef = useComposedRefs(\n forwardedRef,\n inputRef,\n otpContext.onChildAdd,\n );\n\n // FIXME: This should be refactored\n // eslint-disable-next-line react-hooks/refs\n const index = Number(inputRef.current?.dataset.index ?? -1);\n const char = otpContext.value[index] ?? \"\";\n\n return (\n <Form.Field name={`otp-${index}`} asChild>\n <Form.Control asChild>\n <TextField\n ref={composedInputRef}\n autoComplete={index === 0 ? autoComplete : \"off\"}\n color={otpContext.state === \"invalid\" ? \"red\" : undefined}\n inputMode=\"numeric\"\n maxLength={1}\n pattern=\"\\d{1}\"\n readOnly={readOnly ?? otpContext.readOnly}\n size=\"3\"\n value={char}\n variant={otpContext.state === \"invalid\" ? \"soft\" : undefined}\n style={{\n ...style,\n height: \"auto\",\n \"--text-field-padding\": 0,\n textAlign: \"center\",\n }}\n onChange={(event) => {\n // Update the value if it matches the input pattern (number only) or is empty (backspace)\n if (event.target.validity.valid || event.target.value === \"\") {\n const char = event.target.value;\n const index = Number(event.target.dataset.index ?? -1);\n otpContext.onCharChange(char, index);\n focusSibling(event.currentTarget, { back: char === \"\" });\n }\n }}\n onKeyDown={(event) => {\n if (event.key === \"ArrowLeft\") {\n focusSibling(event.currentTarget, { back: true });\n event.preventDefault();\n } else if (event.key === \"ArrowRight\") {\n focusSibling(event.currentTarget);\n event.preventDefault();\n } else if (event.key === \"Backspace\" && char === \"\") {\n focusSibling(event.currentTarget, { back: true });\n } else if (event.key === \"Enter\" && char !== \"\") {\n otpContext.onEnterPressed();\n }\n }}\n {...props}\n />\n </Form.Control>\n </Form.Field>\n );\n },\n);\n\nconst useOptContext = () => {\n const optContext = React.useContext(OtpContext);\n\n if (!optContext) {\n throw new Error(\n \"OtpInput compound components cannot be rendered outside the OtpRoot component\",\n );\n }\n\n return optContext;\n};\n\nfunction focusSibling(input: HTMLInputElement, { back = false } = {}) {\n const sibling = back\n ? input.parentElement?.previousSibling\n : input.parentElement?.nextSibling;\n const siblingInput = sibling?.firstChild;\n if (siblingInput && siblingInput instanceof HTMLInputElement) {\n siblingInput?.focus();\n siblingInput?.select();\n }\n}\n\nconst getValueAsArray = (value: string | undefined, length: number) => {\n if (!value) {\n return undefined;\n }\n\n return createEmptyArray(length).map((_, index) => value?.[index] ?? \"\");\n};\n\nconst createEmptyArray = (length: number): string[] =>\n Array.from<string>({ length }).fill(\"\");\n"],"mappings":"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","names":["Root","value","Input","char","index"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workos-inc/widgets",
|
|
3
|
-
"version": "1.14.1
|
|
3
|
+
"version": "1.14.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -95,8 +95,8 @@
|
|
|
95
95
|
"tsx": "^4.21.0",
|
|
96
96
|
"typescript": "^5.9.3",
|
|
97
97
|
"use-debounce": "^10.1.0",
|
|
98
|
-
"@internal/
|
|
99
|
-
"@internal/
|
|
98
|
+
"@internal/typescript-config": "0.0.0",
|
|
99
|
+
"@internal/eslint-config": "0.0.0"
|
|
100
100
|
},
|
|
101
101
|
"peerDependenciesMeta": {
|
|
102
102
|
"swr": {
|