@thunderid/react 1.12.0 → 1.13.0

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.
Files changed (24) hide show
  1. package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +6 -3
  2. package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
  3. package/dist/cjs/components/auth/flow/FieldFactory.cjs +2 -1
  4. package/dist/cjs/components/auth/flow/FieldFactory.cjs.map +1 -1
  5. package/dist/cjs/components/primitives/OtpField/OtpField.cjs +10 -5
  6. package/dist/cjs/components/primitives/OtpField/OtpField.cjs.map +1 -1
  7. package/dist/cjs/components/primitives/OtpField/OtpField.styles.cjs +16 -8
  8. package/dist/cjs/components/primitives/OtpField/OtpField.styles.cjs.map +1 -1
  9. package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
  10. package/dist/components/auth/flow/AuthOptionFactory.js +6 -3
  11. package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
  12. package/dist/components/auth/flow/FieldFactory.d.ts +4 -0
  13. package/dist/components/auth/flow/FieldFactory.d.ts.map +1 -1
  14. package/dist/components/auth/flow/FieldFactory.js +2 -1
  15. package/dist/components/auth/flow/FieldFactory.js.map +1 -1
  16. package/dist/components/primitives/OtpField/OtpField.d.ts +4 -0
  17. package/dist/components/primitives/OtpField/OtpField.d.ts.map +1 -1
  18. package/dist/components/primitives/OtpField/OtpField.js +11 -6
  19. package/dist/components/primitives/OtpField/OtpField.js.map +1 -1
  20. package/dist/components/primitives/OtpField/OtpField.styles.d.ts +1 -1
  21. package/dist/components/primitives/OtpField/OtpField.styles.d.ts.map +1 -1
  22. package/dist/components/primitives/OtpField/OtpField.styles.js +16 -8
  23. package/dist/components/primitives/OtpField/OtpField.styles.js.map +1 -1
  24. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"OtpField.js","names":["OtpField: FC<OtpInputProps>","useTheme","styles: Record<string, string>","useStyles","inputRefs: MutableRefObject<HTMLInputElement[]>","fieldId: string","helperTextId: string | undefined","newOtp: string[]","newValue: string","otpValue: string","rawData: string","pastedData: string","nextEmptyIndex: number","focusIndex: number","FormControl","InputLabel"],"sources":["../../../../src/components/primitives/OtpField/OtpField.tsx"],"sourcesContent":["// Copyright 2024 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {withVendorCSSClassPrefix, bem} from '@thunderid/browser';\nimport {\n ClipboardEvent,\n FC,\n KeyboardEvent,\n ChangeEvent,\n MutableRefObject,\n useRef,\n useEffect,\n useState,\n CSSProperties,\n useId,\n} from 'react';\nimport useStyles from './OtpField.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport FormControl from '../FormControl/FormControl';\nimport InputLabel from '../InputLabel/InputLabel';\n\nexport type OtpFieldType = 'text' | 'number' | 'password';\n\nexport interface OtpInputProps {\n /**\n * Auto focus the first input on mount\n */\n autoFocus?: boolean;\n /**\n * Additional CSS class names\n */\n className?: string;\n /**\n * Whether the field is disabled\n */\n disabled?: boolean;\n /**\n * Error message to display below the OTP input\n */\n error?: string;\n /**\n * Helper text to display below the OTP input\n */\n helperText?: string;\n /**\n * Label text to display above the OTP input\n */\n label?: string;\n /**\n * Number of OTP input fields\n */\n length?: number;\n /**\n * Callback function called when OTP value changes\n */\n onChange?: (event: {target: {value: string}}) => void;\n /**\n * Callback function called when OTP input is complete\n */\n onComplete?: (value: string) => void;\n /**\n * Pattern for numeric input validation\n */\n pattern?: string;\n /**\n * Placeholder character for each input field\n */\n placeholder?: string;\n /**\n * Whether the field is required\n */\n required?: boolean;\n /**\n * Custom container style\n */\n style?: CSSProperties;\n /**\n * Type of input (text, number, password)\n */\n type?: OtpFieldType;\n /**\n * Upper-case entered characters before emitting them\n */\n uppercase?: boolean;\n /**\n * Current OTP value\n */\n value?: string;\n}\n\nconst OtpField: FC<OtpInputProps> = ({\n label,\n error,\n className,\n required,\n disabled,\n helperText,\n length = 6,\n value = '',\n onChange,\n onComplete,\n type = 'text',\n placeholder = '',\n style = {},\n autoFocus = false,\n pattern,\n uppercase = false,\n}: OtpInputProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme, !!disabled, !!error, length);\n const [otp, setOtp] = useState<string[]>(Array(length).fill(''));\n const inputRefs: MutableRefObject<HTMLInputElement[]> = useRef<HTMLInputElement[]>([]);\n const fieldId: string = useId();\n const labelId = `${fieldId}-label`;\n const helperTextId: string | undefined = error || helperText ? `${fieldId}-helper-text` : undefined;\n\n useEffect(() => {\n inputRefs.current = inputRefs.current.slice(0, length);\n }, [length]);\n\n useEffect(() => {\n if (value) {\n const newOtp: string[] = value.split('').slice(0, length);\n while (newOtp.length < length) {\n newOtp.push('');\n }\n setOtp(newOtp);\n } else {\n setOtp(Array(length).fill(''));\n }\n }, [value, length]);\n\n useEffect(() => {\n if (autoFocus && inputRefs.current[0]) {\n inputRefs.current[0].focus();\n }\n }, [autoFocus]);\n\n const handleChange = (index: number, event: ChangeEvent<HTMLInputElement>): void => {\n const newValue: string = uppercase ? event.target.value.toUpperCase() : event.target.value;\n\n if (newValue.length > 1) return;\n\n if (type === 'number' && newValue && !/^\\d$/.test(newValue)) return;\n\n if (pattern && newValue && !new RegExp(pattern).test(newValue)) return;\n\n const newOtp: string[] = [...otp];\n newOtp[index] = newValue;\n setOtp(newOtp);\n\n const otpValue: string = newOtp.join('');\n\n onChange?.({target: {value: otpValue}});\n\n if (newValue && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n\n if (newOtp.every((digit: string) => digit !== '') && onComplete) {\n onComplete(otpValue);\n }\n };\n\n const handleKeyDown = (index: number, event: KeyboardEvent<HTMLInputElement>): void => {\n if (event.key === 'Backspace') {\n if (!otp[index] && index > 0) {\n const newOtp: string[] = [...otp];\n\n newOtp[index - 1] = '';\n setOtp(newOtp);\n inputRefs.current[index - 1]?.focus();\n onChange?.({target: {value: newOtp.join('')}});\n } else if (otp[index]) {\n const newOtp: string[] = [...otp];\n\n newOtp[index] = '';\n setOtp(newOtp);\n onChange?.({target: {value: newOtp.join('')}});\n }\n } else if (event.key === 'ArrowLeft' && index > 0) {\n inputRefs.current[index - 1]?.focus();\n } else if (event.key === 'ArrowRight' && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n } else if (event.key === 'Enter') {\n event.preventDefault();\n\n if (otp.every((digit: string) => digit !== '') && onComplete) {\n onComplete(otp.join(''));\n }\n }\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLInputElement>): void => {\n event.preventDefault();\n\n const rawData: string = event.clipboardData.getData('text');\n // Filter first and let the copy loop below bound the result, so surrounding text such as\n // \"Your code is 123456\" does not push the code itself past the cut-off.\n const pastedData: string = uppercase ? rawData.toUpperCase() : rawData;\n\n let validData = '';\n\n Array.from(pastedData).forEach((char: string) => {\n if (type === 'number' && !/^\\d$/.test(char)) return;\n if (pattern && !new RegExp(pattern).test(char)) return;\n validData += char;\n });\n\n const newOtp: string[] = Array(length).fill('');\n\n for (let i = 0; i < Math.min(validData.length, length); i += 1) {\n newOtp[i] = validData[i];\n }\n\n setOtp(newOtp);\n onChange?.({target: {value: newOtp.join('')}});\n\n const nextEmptyIndex: number = newOtp.findIndex((digit: string) => digit === '');\n const focusIndex: number = nextEmptyIndex !== -1 ? nextEmptyIndex : length - 1;\n\n inputRefs.current[focusIndex]?.focus();\n\n if (newOtp.every((digit: string) => digit !== '') && onComplete) {\n onComplete(newOtp.join(''));\n }\n };\n\n return (\n <FormControl\n error={error}\n helperText={helperText}\n helperTextId={helperTextId}\n className={cx(withVendorCSSClassPrefix(bem('otp-field')), className)}\n helperTextAlign=\"center\"\n style={style}\n >\n {label && (\n <InputLabel id={labelId} required={required} error={!!error}>\n {label}\n </InputLabel>\n )}\n <div\n role=\"group\"\n aria-labelledby={label ? labelId : undefined}\n aria-describedby={helperTextId}\n className={cx(withVendorCSSClassPrefix(bem('otp-field', 'input-container')), styles['inputContainer'])}\n >\n {Array.from({length}, (_: unknown, index: number) => (\n <input\n key={index}\n ref={(el: HTMLInputElement | null): void => {\n if (el) inputRefs.current[index] = el;\n }}\n type={type === 'password' ? 'password' : 'text'}\n inputMode={type === 'number' ? 'numeric' : 'text'}\n value={otp[index] || ''}\n onChange={(event: ChangeEvent<HTMLInputElement>): void => handleChange(index, event)}\n onKeyDown={(event: KeyboardEvent<HTMLInputElement>): void => handleKeyDown(index, event)}\n onPaste={handlePaste}\n className={cx(withVendorCSSClassPrefix(bem('otp-field', 'input')), styles['input'], {\n [withVendorCSSClassPrefix(bem('otp-field', 'input', 'error'))]: !!error,\n [styles['inputError']]: !!error,\n [withVendorCSSClassPrefix(bem('otp-field', 'input', 'disabled'))]: !!disabled,\n [styles['inputDisabled']]: !!disabled,\n })}\n maxLength={1}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={`${label || 'OTP'} digit ${index + 1}`}\n aria-invalid={!!error}\n aria-required={required}\n aria-describedby={helperTextId}\n autoComplete=\"one-time-code\"\n />\n ))}\n </div>\n </FormControl>\n );\n};\n\nexport default OtpField;\n"],"mappings":"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"}
1
+ {"version":3,"file":"OtpField.js","names":["OtpField: FC<OtpInputProps>","useTheme","styles: Record<string, string>","useStyles","inputRefs: MutableRefObject<HTMLInputElement[]>","fieldId: string","helperTextId: string | undefined","newOtp: string[]","newValue: string","otpValue: string","rawData: string","normalizedData: string","pastedData: string","nextEmptyIndex: number","focusIndex: number","FormControl","InputLabel"],"sources":["../../../../src/components/primitives/OtpField/OtpField.tsx"],"sourcesContent":["// Copyright 2024 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {withVendorCSSClassPrefix, bem} from '@thunderid/browser';\nimport {\n ClipboardEvent,\n FC,\n KeyboardEvent,\n ChangeEvent,\n MutableRefObject,\n useRef,\n useEffect,\n useState,\n CSSProperties,\n Fragment,\n useId,\n} from 'react';\nimport useStyles from './OtpField.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport FormControl from '../FormControl/FormControl';\nimport InputLabel from '../InputLabel/InputLabel';\n\nexport type OtpFieldType = 'text' | 'number' | 'password';\n\nexport interface OtpInputProps {\n /**\n * Auto focus the first input on mount\n */\n autoFocus?: boolean;\n /**\n * Additional CSS class names\n */\n className?: string;\n /**\n * Whether the field is disabled\n */\n disabled?: boolean;\n /**\n * Error message to display below the OTP input\n */\n error?: string;\n /**\n * Helper text to display below the OTP input\n */\n helperText?: string;\n /**\n * Label text to display above the OTP input\n */\n label?: string;\n /**\n * Number of OTP input fields\n */\n length?: number;\n /**\n * Add a visual separator after this many characters without including it in the field value.\n */\n separatorAfter?: number;\n /**\n * Callback function called when OTP value changes\n */\n onChange?: (event: {target: {value: string}}) => void;\n /**\n * Callback function called when OTP input is complete\n */\n onComplete?: (value: string) => void;\n /**\n * Pattern for numeric input validation\n */\n pattern?: string;\n /**\n * Placeholder character for each input field\n */\n placeholder?: string;\n /**\n * Whether the field is required\n */\n required?: boolean;\n /**\n * Custom container style\n */\n style?: CSSProperties;\n /**\n * Type of input (text, number, password)\n */\n type?: OtpFieldType;\n /**\n * Upper-case entered characters before emitting them\n */\n uppercase?: boolean;\n /**\n * Current OTP value\n */\n value?: string;\n}\n\nconst OtpField: FC<OtpInputProps> = ({\n label,\n error,\n className,\n required,\n disabled,\n helperText,\n length = 6,\n separatorAfter,\n value = '',\n onChange,\n onComplete,\n type = 'text',\n placeholder = '',\n style = {},\n autoFocus = false,\n pattern,\n uppercase = false,\n}: OtpInputProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme, !!disabled, !!error, length, separatorAfter);\n const [otp, setOtp] = useState<string[]>(Array(length).fill(''));\n const inputRefs: MutableRefObject<HTMLInputElement[]> = useRef<HTMLInputElement[]>([]);\n const fieldId: string = useId();\n const labelId = `${fieldId}-label`;\n const helperTextId: string | undefined = error || helperText ? `${fieldId}-helper-text` : undefined;\n\n useEffect(() => {\n inputRefs.current = inputRefs.current.slice(0, length);\n }, [length]);\n\n useEffect(() => {\n if (value) {\n const newOtp: string[] = value.split('').slice(0, length);\n while (newOtp.length < length) {\n newOtp.push('');\n }\n setOtp(newOtp);\n } else {\n setOtp(Array(length).fill(''));\n }\n }, [value, length]);\n\n useEffect(() => {\n if (autoFocus && inputRefs.current[0]) {\n inputRefs.current[0].focus();\n }\n }, [autoFocus]);\n\n const handleChange = (index: number, event: ChangeEvent<HTMLInputElement>): void => {\n const newValue: string = uppercase ? event.target.value.toUpperCase() : event.target.value;\n\n if (newValue.length > 1) return;\n\n if (type === 'number' && newValue && !/^\\d$/.test(newValue)) return;\n\n if (pattern && newValue && !new RegExp(pattern).test(newValue)) return;\n\n const newOtp: string[] = [...otp];\n newOtp[index] = newValue;\n setOtp(newOtp);\n\n const otpValue: string = newOtp.join('');\n\n onChange?.({target: {value: otpValue}});\n\n if (newValue && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n\n if (newOtp.every((digit: string) => digit !== '') && onComplete) {\n onComplete(otpValue);\n }\n };\n\n const handleKeyDown = (index: number, event: KeyboardEvent<HTMLInputElement>): void => {\n if (event.key === 'Backspace') {\n if (!otp[index] && index > 0) {\n const newOtp: string[] = [...otp];\n\n newOtp[index - 1] = '';\n setOtp(newOtp);\n inputRefs.current[index - 1]?.focus();\n onChange?.({target: {value: newOtp.join('')}});\n } else if (otp[index]) {\n const newOtp: string[] = [...otp];\n\n newOtp[index] = '';\n setOtp(newOtp);\n onChange?.({target: {value: newOtp.join('')}});\n }\n } else if (event.key === 'ArrowLeft' && index > 0) {\n inputRefs.current[index - 1]?.focus();\n } else if (event.key === 'ArrowRight' && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n } else if (event.key === 'Enter') {\n event.preventDefault();\n\n if (otp.every((digit: string) => digit !== '') && onComplete) {\n onComplete(otp.join(''));\n }\n }\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLInputElement>): void => {\n event.preventDefault();\n\n const rawData: string = event.clipboardData.getData('text');\n // Filter first and let the copy loop below bound the result, so surrounding text such as\n // \"Your code is 123456\" does not push the code itself past the cut-off.\n const normalizedData: string = separatorAfter ? rawData.replace(/[-\\s]/g, '') : rawData;\n const pastedData: string = uppercase ? normalizedData.toUpperCase() : normalizedData;\n\n let validData = '';\n\n Array.from(pastedData).forEach((char: string) => {\n if (type === 'number' && !/^\\d$/.test(char)) return;\n if (pattern && !new RegExp(pattern).test(char)) return;\n validData += char;\n });\n\n const newOtp: string[] = Array(length).fill('');\n\n for (let i = 0; i < Math.min(validData.length, length); i += 1) {\n newOtp[i] = validData[i];\n }\n\n setOtp(newOtp);\n onChange?.({target: {value: newOtp.join('')}});\n\n const nextEmptyIndex: number = newOtp.findIndex((digit: string) => digit === '');\n const focusIndex: number = nextEmptyIndex !== -1 ? nextEmptyIndex : length - 1;\n\n inputRefs.current[focusIndex]?.focus();\n\n if (newOtp.every((digit: string) => digit !== '') && onComplete) {\n onComplete(newOtp.join(''));\n }\n };\n\n return (\n <FormControl\n error={error}\n helperText={helperText}\n helperTextId={helperTextId}\n className={cx(withVendorCSSClassPrefix(bem('otp-field')), className)}\n helperTextAlign=\"center\"\n style={style}\n >\n {label && (\n <InputLabel id={labelId} required={required} error={!!error}>\n {label}\n </InputLabel>\n )}\n <div\n role=\"group\"\n aria-labelledby={label ? labelId : undefined}\n aria-describedby={helperTextId}\n className={cx(withVendorCSSClassPrefix(bem('otp-field', 'input-container')), styles['inputContainer'])}\n >\n {Array.from({length}, (_: unknown, index: number) => (\n <Fragment key={index}>\n <input\n ref={(el: HTMLInputElement | null): void => {\n if (el) inputRefs.current[index] = el;\n }}\n type={type === 'password' ? 'password' : 'text'}\n inputMode={type === 'number' ? 'numeric' : 'text'}\n value={otp[index] || ''}\n onChange={(event: ChangeEvent<HTMLInputElement>): void => handleChange(index, event)}\n onKeyDown={(event: KeyboardEvent<HTMLInputElement>): void => handleKeyDown(index, event)}\n onPaste={handlePaste}\n className={cx(withVendorCSSClassPrefix(bem('otp-field', 'input')), styles['input'], {\n [withVendorCSSClassPrefix(bem('otp-field', 'input', 'error'))]: !!error,\n [styles['inputError']]: !!error,\n [withVendorCSSClassPrefix(bem('otp-field', 'input', 'disabled'))]: !!disabled,\n [styles['inputDisabled']]: !!disabled,\n })}\n maxLength={1}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={`${label || 'OTP'} digit ${index + 1}`}\n aria-invalid={!!error}\n aria-required={required}\n aria-describedby={helperTextId}\n autoComplete=\"one-time-code\"\n />\n {separatorAfter === index + 1 && (\n <span\n className={cx(withVendorCSSClassPrefix(bem('otp-field', 'separator')), styles['separator'])}\n aria-hidden=\"true\"\n >\n -\n </span>\n )}\n </Fragment>\n ))}\n </div>\n </FormControl>\n );\n};\n\nexport default OtpField;\n"],"mappings":"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"}
@@ -9,6 +9,6 @@ export type OtpFieldType = 'text' | 'number' | 'password';
9
9
  * @param length - Number of OTP input fields
10
10
  * @returns Object containing CSS class names for component styling
11
11
  */
12
- declare const useStyles: (theme: Theme, colorScheme: string, disabled: boolean, hasError: boolean, length: number) => Record<string, string>;
12
+ declare const useStyles: (theme: Theme, colorScheme: string, disabled: boolean, hasError: boolean, length: number, separatorAfter?: number) => Record<string, string>;
13
13
  export default useStyles;
14
14
  //# sourceMappingURL=OtpField.styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"OtpField.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/OtpField/OtpField.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE1D;;;;;;;;GAQG;AACH,QAAA,MAAM,SAAS,GACb,OAAO,KAAK,EACZ,aAAa,MAAM,EACnB,UAAU,OAAO,EACjB,UAAU,OAAO,EACjB,QAAQ,MAAM,KACb,MAAM,CAAC,MAAM,EAAE,MAAM,CA+D8B,CAAC;AAEvD,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"OtpField.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/OtpField/OtpField.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE1D;;;;;;;;GAQG;AACH,QAAA,MAAM,SAAS,GACb,OAAO,KAAK,EACZ,aAAa,MAAM,EACnB,UAAU,OAAO,EACjB,UAAU,OAAO,EACjB,QAAQ,MAAM,EACd,iBAAiB,MAAM,KACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAwE8C,CAAC;AAEvE,eAAe,SAAS,CAAC"}
@@ -11,17 +11,18 @@ import { useMemo } from "react";
11
11
  * @param length - Number of OTP input fields
12
12
  * @returns Object containing CSS class names for component styling
13
13
  */
14
- const useStyles = (theme, colorScheme, disabled, hasError, length) => useMemo(() => {
14
+ const useStyles = (theme, colorScheme, disabled, hasError, length, separatorAfter) => useMemo(() => {
15
+ const isGrouped = separatorAfter !== void 0 && separatorAfter > 0 && separatorAfter < length;
15
16
  const inputContainer = css`
16
17
  display: flex;
17
- gap: ${theme.vars.spacing.unit};
18
- justify-content: space-between;
18
+ gap: calc(${theme.vars.spacing.unit} * ${isGrouped ? .5 : 1});
19
+ justify-content: ${isGrouped ? "center" : "space-between"};
19
20
  align-items: center;
20
- flex-wrap: wrap;
21
+ flex-wrap: ${isGrouped ? "nowrap" : "wrap"};
21
22
  `;
22
23
  const input = css`
23
- width: calc(${theme.vars.spacing.unit} * 6);
24
- height: calc(${theme.vars.spacing.unit} * 6);
24
+ width: calc(${theme.vars.spacing.unit} * ${isGrouped ? 3.5 : 6});
25
+ height: calc(${theme.vars.spacing.unit} * ${isGrouped ? 4.5 : 6});
25
26
  text-align: center;
26
27
  font-size: ${theme.vars.typography.fontSizes.xl};
27
28
  font-family: ${theme.vars.typography.fontFamily};
@@ -66,14 +67,21 @@ const useStyles = (theme, colorScheme, disabled, hasError, length) => useMemo(()
66
67
  cursor: not-allowed;
67
68
  opacity: 0.6;
68
69
  `,
69
- inputError
70
+ inputError,
71
+ separator: css`
72
+ flex: none;
73
+ color: ${theme.vars.colors.text.secondary};
74
+ font-size: ${theme.vars.typography.fontSizes.xl};
75
+ font-weight: 500;
76
+ `
70
77
  };
71
78
  }, [
72
79
  theme,
73
80
  colorScheme,
74
81
  disabled,
75
82
  hasError,
76
- length
83
+ length,
84
+ separatorAfter
77
85
  ]);
78
86
  var OtpField_styles_default = useStyles;
79
87
 
@@ -1 +1 @@
1
- {"version":3,"file":"OtpField.styles.js","names":["inputContainer: string","input: string","inputError: string"],"sources":["../../../../src/components/primitives/OtpField/OtpField.styles.ts"],"sourcesContent":["// Copyright 2024 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\nimport {css} from '../../../styles/emotion';\n\nexport type OtpFieldType = 'text' | 'number' | 'password';\n\n/**\n * Creates styles for the OtpField component using BEM methodology\n * @param theme - The theme object containing design tokens\n * @param colorScheme - The current color scheme (used for memoization)\n * @param disabled - Whether the component is disabled\n * @param hasError - Whether the component has an error\n * @param length - Number of OTP input fields\n * @returns Object containing CSS class names for component styling\n */\nconst useStyles = (\n theme: Theme,\n colorScheme: string,\n disabled: boolean,\n hasError: boolean,\n length: number,\n): Record<string, string> =>\n useMemo(() => {\n const inputContainer: string = css`\n display: flex;\n gap: ${theme.vars.spacing.unit};\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n `;\n\n const input: string = css`\n width: calc(${theme.vars.spacing.unit} * 6);\n height: calc(${theme.vars.spacing.unit} * 6);\n text-align: center;\n font-size: ${theme.vars.typography.fontSizes.xl};\n font-family: ${theme.vars.typography.fontFamily};\n font-weight: 500;\n border: 2px solid ${hasError ? theme.vars.colors.error.main : theme.vars.colors.border};\n border-radius: ${theme.vars.components?.Field?.root?.borderRadius || theme.vars.borderRadius.medium};\n color: ${theme.vars.colors.text.primary};\n background-color: ${disabled ? theme.vars.colors.background.disabled : theme.vars.colors.background.surface};\n outline: none;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease;\n\n &:focus {\n border-color: ${hasError ? theme.vars.colors.error.main : theme.vars.colors.primary.main};\n box-shadow: 0 0 0 2px ${hasError ? `${theme.vars.colors.error.main}20` : `${theme.vars.colors.primary.main}20`};\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n &::placeholder {\n color: ${theme.vars.colors.text.secondary};\n opacity: 0.7;\n }\n `;\n\n const inputError: string = css`\n border-color: ${theme.vars.colors.error.main};\n\n &:focus {\n border-color: ${theme.vars.colors.error.main};\n box-shadow: 0 0 0 2px ${theme.vars.colors.error.main}20;\n }\n `;\n\n const inputDisabled: string = css`\n background-color: ${theme.vars.colors.background.disabled};\n cursor: not-allowed;\n opacity: 0.6;\n `;\n\n return {\n input,\n inputContainer,\n inputDisabled,\n inputError,\n };\n }, [theme, colorScheme, disabled, hasError, length]);\n\nexport default useStyles;\n"],"mappings":";;;;;;;;;;;;;AAkBA,MAAM,aACJ,OACA,aACA,UACA,UACA,WAEA,cAAc;CACZ,MAAMA,iBAAyB,GAAG;;aAEzB,MAAM,KAAK,QAAQ,KAAK;;;;;CAMjC,MAAMC,QAAgB,GAAG;oBACT,MAAM,KAAK,QAAQ,KAAK;qBACvB,MAAM,KAAK,QAAQ,KAAK;;mBAE1B,MAAM,KAAK,WAAW,UAAU,GAAG;qBACjC,MAAM,KAAK,WAAW,WAAW;;0BAE5B,WAAW,MAAM,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,OAAO;uBACtE,MAAM,KAAK,YAAY,OAAO,MAAM,gBAAgB,MAAM,KAAK,aAAa,OAAO;eAC3F,MAAM,KAAK,OAAO,KAAK,QAAQ;0BACpB,WAAW,MAAM,KAAK,OAAO,WAAW,WAAW,MAAM,KAAK,OAAO,WAAW,QAAQ;;;;;;;wBAO1F,WAAW,MAAM,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK;gCACjE,WAAW,GAAG,MAAM,KAAK,OAAO,MAAM,KAAK,MAAM,GAAG,MAAM,KAAK,OAAO,QAAQ,KAAK,IAAI;;;;;;;;;iBAStG,MAAM,KAAK,OAAO,KAAK,UAAU;;;;CAK9C,MAAMC,aAAqB,GAAG;sBACZ,MAAM,KAAK,OAAO,MAAM,KAAK;;;wBAG3B,MAAM,KAAK,OAAO,MAAM,KAAK;gCACrB,MAAM,KAAK,OAAO,MAAM,KAAK;;;AAUzD,QAAO;EACL;EACA;EACA,eAT4B,GAAG;0BACX,MAAM,KAAK,OAAO,WAAW,SAAS;;;;EAS1D;EACD;GACA;CAAC;CAAO;CAAa;CAAU;CAAU;CAAO,CAAC;AAEtD,8BAAe"}
1
+ {"version":3,"file":"OtpField.styles.js","names":["inputContainer: string","input: string","inputError: string"],"sources":["../../../../src/components/primitives/OtpField/OtpField.styles.ts"],"sourcesContent":["// Copyright 2024 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\nimport {css} from '../../../styles/emotion';\n\nexport type OtpFieldType = 'text' | 'number' | 'password';\n\n/**\n * Creates styles for the OtpField component using BEM methodology\n * @param theme - The theme object containing design tokens\n * @param colorScheme - The current color scheme (used for memoization)\n * @param disabled - Whether the component is disabled\n * @param hasError - Whether the component has an error\n * @param length - Number of OTP input fields\n * @returns Object containing CSS class names for component styling\n */\nconst useStyles = (\n theme: Theme,\n colorScheme: string,\n disabled: boolean,\n hasError: boolean,\n length: number,\n separatorAfter?: number,\n): Record<string, string> =>\n useMemo(() => {\n const isGrouped = separatorAfter !== undefined && separatorAfter > 0 && separatorAfter < length;\n const inputContainer: string = css`\n display: flex;\n gap: calc(${theme.vars.spacing.unit} * ${isGrouped ? 0.5 : 1});\n justify-content: ${isGrouped ? 'center' : 'space-between'};\n align-items: center;\n flex-wrap: ${isGrouped ? 'nowrap' : 'wrap'};\n `;\n\n const input: string = css`\n width: calc(${theme.vars.spacing.unit} * ${isGrouped ? 3.5 : 6});\n height: calc(${theme.vars.spacing.unit} * ${isGrouped ? 4.5 : 6});\n text-align: center;\n font-size: ${theme.vars.typography.fontSizes.xl};\n font-family: ${theme.vars.typography.fontFamily};\n font-weight: 500;\n border: 2px solid ${hasError ? theme.vars.colors.error.main : theme.vars.colors.border};\n border-radius: ${theme.vars.components?.Field?.root?.borderRadius || theme.vars.borderRadius.medium};\n color: ${theme.vars.colors.text.primary};\n background-color: ${disabled ? theme.vars.colors.background.disabled : theme.vars.colors.background.surface};\n outline: none;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease;\n\n &:focus {\n border-color: ${hasError ? theme.vars.colors.error.main : theme.vars.colors.primary.main};\n box-shadow: 0 0 0 2px ${hasError ? `${theme.vars.colors.error.main}20` : `${theme.vars.colors.primary.main}20`};\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n &::placeholder {\n color: ${theme.vars.colors.text.secondary};\n opacity: 0.7;\n }\n `;\n\n const inputError: string = css`\n border-color: ${theme.vars.colors.error.main};\n\n &:focus {\n border-color: ${theme.vars.colors.error.main};\n box-shadow: 0 0 0 2px ${theme.vars.colors.error.main}20;\n }\n `;\n\n const inputDisabled: string = css`\n background-color: ${theme.vars.colors.background.disabled};\n cursor: not-allowed;\n opacity: 0.6;\n `;\n\n const separator: string = css`\n flex: none;\n color: ${theme.vars.colors.text.secondary};\n font-size: ${theme.vars.typography.fontSizes.xl};\n font-weight: 500;\n `;\n\n return {\n input,\n inputContainer,\n inputDisabled,\n inputError,\n separator,\n };\n }, [theme, colorScheme, disabled, hasError, length, separatorAfter]);\n\nexport default useStyles;\n"],"mappings":";;;;;;;;;;;;;AAkBA,MAAM,aACJ,OACA,aACA,UACA,UACA,QACA,mBAEA,cAAc;CACZ,MAAM,YAAY,mBAAmB,UAAa,iBAAiB,KAAK,iBAAiB;CACzF,MAAMA,iBAAyB,GAAG;;kBAEpB,MAAM,KAAK,QAAQ,KAAK,KAAK,YAAY,KAAM,EAAE;yBAC1C,YAAY,WAAW,gBAAgB;;mBAE7C,YAAY,WAAW,OAAO;;CAG7C,MAAMC,QAAgB,GAAG;oBACT,MAAM,KAAK,QAAQ,KAAK,KAAK,YAAY,MAAM,EAAE;qBAChD,MAAM,KAAK,QAAQ,KAAK,KAAK,YAAY,MAAM,EAAE;;mBAEnD,MAAM,KAAK,WAAW,UAAU,GAAG;qBACjC,MAAM,KAAK,WAAW,WAAW;;0BAE5B,WAAW,MAAM,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,OAAO;uBACtE,MAAM,KAAK,YAAY,OAAO,MAAM,gBAAgB,MAAM,KAAK,aAAa,OAAO;eAC3F,MAAM,KAAK,OAAO,KAAK,QAAQ;0BACpB,WAAW,MAAM,KAAK,OAAO,WAAW,WAAW,MAAM,KAAK,OAAO,WAAW,QAAQ;;;;;;;wBAO1F,WAAW,MAAM,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK;gCACjE,WAAW,GAAG,MAAM,KAAK,OAAO,MAAM,KAAK,MAAM,GAAG,MAAM,KAAK,OAAO,QAAQ,KAAK,IAAI;;;;;;;;;iBAStG,MAAM,KAAK,OAAO,KAAK,UAAU;;;;CAK9C,MAAMC,aAAqB,GAAG;sBACZ,MAAM,KAAK,OAAO,MAAM,KAAK;;;wBAG3B,MAAM,KAAK,OAAO,MAAM,KAAK;gCACrB,MAAM,KAAK,OAAO,MAAM,KAAK;;;AAiBzD,QAAO;EACL;EACA;EACA,eAhB4B,GAAG;0BACX,MAAM,KAAK,OAAO,WAAW,SAAS;;;;EAgB1D;EACA,WAZwB,GAAG;;eAElB,MAAM,KAAK,OAAO,KAAK,UAAU;mBAC7B,MAAM,KAAK,WAAW,UAAU,GAAG;;;EAUjD;GACA;CAAC;CAAO;CAAa;CAAU;CAAU;CAAQ;CAAe,CAAC;AAEtE,8BAAe"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thunderid/react",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "React SDK for ThunderID",
5
5
  "keywords": [
6
6
  "thunderid",