@thunderid/react 1.3.3 → 1.4.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 (159) hide show
  1. package/dist/cjs/components/presentation/ChangeCredential/BaseChangeCredential.cjs +1 -1
  2. package/dist/cjs/components/presentation/auth/AcceptInvite/BaseAcceptInvite.cjs +1 -1
  3. package/dist/cjs/components/presentation/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
  4. package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs +56 -17
  5. package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs.map +1 -1
  6. package/dist/cjs/components/presentation/auth/InviteUser/BaseInviteUser.cjs +21 -5
  7. package/dist/cjs/components/presentation/auth/InviteUser/BaseInviteUser.cjs.map +1 -1
  8. package/dist/cjs/components/presentation/auth/InviteUser/InviteUser.cjs +6 -0
  9. package/dist/cjs/components/presentation/auth/InviteUser/InviteUser.cjs.map +1 -1
  10. package/dist/cjs/components/primitives/AuthFlowSelect/AuthFlowSelect.cjs +21 -0
  11. package/dist/cjs/components/primitives/AuthFlowSelect/AuthFlowSelect.cjs.map +1 -0
  12. package/dist/cjs/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.cjs +32 -0
  13. package/dist/cjs/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.cjs.map +1 -0
  14. package/dist/cjs/components/primitives/CopyableText/CopyableText.cjs +41 -21
  15. package/dist/cjs/components/primitives/CopyableText/CopyableText.cjs.map +1 -1
  16. package/dist/cjs/components/primitives/CopyableText/CopyableText.styles.cjs +5 -2
  17. package/dist/cjs/components/primitives/CopyableText/CopyableText.styles.cjs.map +1 -1
  18. package/dist/cjs/components/primitives/Icons/Copy.cjs +33 -0
  19. package/dist/cjs/components/primitives/Icons/Copy.cjs.map +1 -0
  20. package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs +2 -1
  21. package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs.map +1 -1
  22. package/dist/cjs/components/primitives/Select/ResourceSelect.cjs +104 -0
  23. package/dist/cjs/components/primitives/Select/ResourceSelect.cjs.map +1 -0
  24. package/dist/cjs/components/primitives/Select/Select.cjs +72 -21
  25. package/dist/cjs/components/primitives/Select/Select.cjs.map +1 -1
  26. package/dist/cjs/components/primitives/Select/Select.styles.cjs +19 -3
  27. package/dist/cjs/components/primitives/Select/Select.styles.cjs.map +1 -1
  28. package/dist/cjs/components/primitives/Select/useSelectMessages.cjs +21 -0
  29. package/dist/cjs/components/primitives/Select/useSelectMessages.cjs.map +1 -0
  30. package/dist/cjs/components/primitives/TextField/TextField.cjs +19 -3
  31. package/dist/cjs/components/primitives/TextField/TextField.cjs.map +1 -1
  32. package/dist/cjs/components/primitives/TextField/TextField.styles.cjs +18 -5
  33. package/dist/cjs/components/primitives/TextField/TextField.styles.cjs.map +1 -1
  34. package/dist/cjs/components/primitives/UserSelect/BaseUserSelect.cjs +33 -0
  35. package/dist/cjs/components/primitives/UserSelect/BaseUserSelect.cjs.map +1 -0
  36. package/dist/cjs/components/primitives/UserSelect/UserSelect.cjs +21 -0
  37. package/dist/cjs/components/primitives/UserSelect/UserSelect.cjs.map +1 -0
  38. package/dist/cjs/components/primitives/UserTypeSelect/BaseUserTypeSelect.cjs +31 -0
  39. package/dist/cjs/components/primitives/UserTypeSelect/BaseUserTypeSelect.cjs.map +1 -0
  40. package/dist/cjs/components/primitives/UserTypeSelect/UserTypeSelect.cjs +21 -0
  41. package/dist/cjs/components/primitives/UserTypeSelect/UserTypeSelect.cjs.map +1 -0
  42. package/dist/cjs/hooks/useFetchAuthFlows.cjs +36 -0
  43. package/dist/cjs/hooks/useFetchAuthFlows.cjs.map +1 -0
  44. package/dist/cjs/hooks/useFetchUserTypes.cjs +34 -0
  45. package/dist/cjs/hooks/useFetchUserTypes.cjs.map +1 -0
  46. package/dist/cjs/hooks/useFetchUsers.cjs +35 -0
  47. package/dist/cjs/hooks/useFetchUsers.cjs.map +1 -0
  48. package/dist/cjs/hooks/useInfiniteOptions.cjs +129 -0
  49. package/dist/cjs/hooks/useInfiniteOptions.cjs.map +1 -0
  50. package/dist/cjs/hooks/useManagementEndpoint.cjs.map +1 -1
  51. package/dist/cjs/index.cjs +56 -0
  52. package/dist/cjs/utils/createAuthenticatedFetcher.cjs +1 -0
  53. package/dist/cjs/utils/createAuthenticatedFetcher.cjs.map +1 -1
  54. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.js +1 -1
  55. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
  56. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.js +1 -1
  57. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
  58. package/dist/components/presentation/auth/AuthOptionFactory.d.ts +9 -1
  59. package/dist/components/presentation/auth/AuthOptionFactory.d.ts.map +1 -1
  60. package/dist/components/presentation/auth/AuthOptionFactory.js +56 -17
  61. package/dist/components/presentation/auth/AuthOptionFactory.js.map +1 -1
  62. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.d.ts +18 -2
  63. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.d.ts.map +1 -1
  64. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.js +22 -6
  65. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.js.map +1 -1
  66. package/dist/components/presentation/auth/InviteUser/InviteUser.d.ts +2 -1
  67. package/dist/components/presentation/auth/InviteUser/InviteUser.d.ts.map +1 -1
  68. package/dist/components/presentation/auth/InviteUser/InviteUser.js +6 -0
  69. package/dist/components/presentation/auth/InviteUser/InviteUser.js.map +1 -1
  70. package/dist/components/primitives/AuthFlowSelect/AuthFlowSelect.d.ts +11 -0
  71. package/dist/components/primitives/AuthFlowSelect/AuthFlowSelect.d.ts.map +1 -0
  72. package/dist/components/primitives/AuthFlowSelect/AuthFlowSelect.js +19 -0
  73. package/dist/components/primitives/AuthFlowSelect/AuthFlowSelect.js.map +1 -0
  74. package/dist/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.d.ts +14 -0
  75. package/dist/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.d.ts.map +1 -0
  76. package/dist/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.js +29 -0
  77. package/dist/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.js.map +1 -0
  78. package/dist/components/primitives/CopyableText/CopyableText.d.ts +9 -0
  79. package/dist/components/primitives/CopyableText/CopyableText.d.ts.map +1 -1
  80. package/dist/components/primitives/CopyableText/CopyableText.js +40 -21
  81. package/dist/components/primitives/CopyableText/CopyableText.js.map +1 -1
  82. package/dist/components/primitives/CopyableText/CopyableText.styles.d.ts.map +1 -1
  83. package/dist/components/primitives/CopyableText/CopyableText.styles.js +5 -2
  84. package/dist/components/primitives/CopyableText/CopyableText.styles.js.map +1 -1
  85. package/dist/components/primitives/Icons/Copy.d.ts +7 -0
  86. package/dist/components/primitives/Icons/Copy.d.ts.map +1 -0
  87. package/dist/components/primitives/Icons/Copy.js +31 -0
  88. package/dist/components/primitives/Icons/Copy.js.map +1 -0
  89. package/dist/components/primitives/PasswordField/PasswordField.d.ts +9 -1
  90. package/dist/components/primitives/PasswordField/PasswordField.d.ts.map +1 -1
  91. package/dist/components/primitives/PasswordField/PasswordField.js +2 -1
  92. package/dist/components/primitives/PasswordField/PasswordField.js.map +1 -1
  93. package/dist/components/primitives/Select/ResourceSelect.d.ts +36 -0
  94. package/dist/components/primitives/Select/ResourceSelect.d.ts.map +1 -0
  95. package/dist/components/primitives/Select/ResourceSelect.js +100 -0
  96. package/dist/components/primitives/Select/ResourceSelect.js.map +1 -0
  97. package/dist/components/primitives/Select/Select.d.ts +22 -13
  98. package/dist/components/primitives/Select/Select.d.ts.map +1 -1
  99. package/dist/components/primitives/Select/Select.js +72 -22
  100. package/dist/components/primitives/Select/Select.js.map +1 -1
  101. package/dist/components/primitives/Select/Select.styles.d.ts.map +1 -1
  102. package/dist/components/primitives/Select/Select.styles.js +19 -3
  103. package/dist/components/primitives/Select/Select.styles.js.map +1 -1
  104. package/dist/components/primitives/Select/__tests__/selectTestUtils.d.ts +6 -0
  105. package/dist/components/primitives/Select/__tests__/selectTestUtils.d.ts.map +1 -0
  106. package/dist/components/primitives/Select/useSelectMessages.d.ts +9 -0
  107. package/dist/components/primitives/Select/useSelectMessages.d.ts.map +1 -0
  108. package/dist/components/primitives/Select/useSelectMessages.js +18 -0
  109. package/dist/components/primitives/Select/useSelectMessages.js.map +1 -0
  110. package/dist/components/primitives/TextField/TextField.d.ts +8 -0
  111. package/dist/components/primitives/TextField/TextField.d.ts.map +1 -1
  112. package/dist/components/primitives/TextField/TextField.js +19 -3
  113. package/dist/components/primitives/TextField/TextField.js.map +1 -1
  114. package/dist/components/primitives/TextField/TextField.styles.d.ts +2 -1
  115. package/dist/components/primitives/TextField/TextField.styles.d.ts.map +1 -1
  116. package/dist/components/primitives/TextField/TextField.styles.js +18 -5
  117. package/dist/components/primitives/TextField/TextField.styles.js.map +1 -1
  118. package/dist/components/primitives/UserSelect/BaseUserSelect.d.ts +15 -0
  119. package/dist/components/primitives/UserSelect/BaseUserSelect.d.ts.map +1 -0
  120. package/dist/components/primitives/UserSelect/BaseUserSelect.js +30 -0
  121. package/dist/components/primitives/UserSelect/BaseUserSelect.js.map +1 -0
  122. package/dist/components/primitives/UserSelect/UserSelect.d.ts +11 -0
  123. package/dist/components/primitives/UserSelect/UserSelect.d.ts.map +1 -0
  124. package/dist/components/primitives/UserSelect/UserSelect.js +19 -0
  125. package/dist/components/primitives/UserSelect/UserSelect.js.map +1 -0
  126. package/dist/components/primitives/UserTypeSelect/BaseUserTypeSelect.d.ts +14 -0
  127. package/dist/components/primitives/UserTypeSelect/BaseUserTypeSelect.d.ts.map +1 -0
  128. package/dist/components/primitives/UserTypeSelect/BaseUserTypeSelect.js +28 -0
  129. package/dist/components/primitives/UserTypeSelect/BaseUserTypeSelect.js.map +1 -0
  130. package/dist/components/primitives/UserTypeSelect/UserTypeSelect.d.ts +11 -0
  131. package/dist/components/primitives/UserTypeSelect/UserTypeSelect.d.ts.map +1 -0
  132. package/dist/components/primitives/UserTypeSelect/UserTypeSelect.js +19 -0
  133. package/dist/components/primitives/UserTypeSelect/UserTypeSelect.js.map +1 -0
  134. package/dist/hooks/useFetchAuthFlows.d.ts +9 -0
  135. package/dist/hooks/useFetchAuthFlows.d.ts.map +1 -0
  136. package/dist/hooks/useFetchAuthFlows.js +33 -0
  137. package/dist/hooks/useFetchAuthFlows.js.map +1 -0
  138. package/dist/hooks/useFetchUserTypes.d.ts +8 -0
  139. package/dist/hooks/useFetchUserTypes.d.ts.map +1 -0
  140. package/dist/hooks/useFetchUserTypes.js +31 -0
  141. package/dist/hooks/useFetchUserTypes.js.map +1 -0
  142. package/dist/hooks/useFetchUsers.d.ts +8 -0
  143. package/dist/hooks/useFetchUsers.d.ts.map +1 -0
  144. package/dist/hooks/useFetchUsers.js +32 -0
  145. package/dist/hooks/useFetchUsers.js.map +1 -0
  146. package/dist/hooks/useInfiniteOptions.d.ts +31 -0
  147. package/dist/hooks/useInfiniteOptions.d.ts.map +1 -0
  148. package/dist/hooks/useInfiniteOptions.js +126 -0
  149. package/dist/hooks/useInfiniteOptions.js.map +1 -0
  150. package/dist/hooks/useManagementEndpoint.d.ts +1 -1
  151. package/dist/hooks/useManagementEndpoint.d.ts.map +1 -1
  152. package/dist/hooks/useManagementEndpoint.js.map +1 -1
  153. package/dist/index.d.ts +18 -1
  154. package/dist/index.d.ts.map +1 -1
  155. package/dist/index.js +12 -2
  156. package/dist/utils/createAuthenticatedFetcher.d.ts.map +1 -1
  157. package/dist/utils/createAuthenticatedFetcher.js +1 -0
  158. package/dist/utils/createAuthenticatedFetcher.js.map +1 -1
  159. package/package.json +2 -2
@@ -1,16 +1,24 @@
1
1
  import { FC } from 'react';
2
2
  import { TextFieldProps } from '../TextField/TextField';
3
- export interface PasswordFieldProps extends Omit<TextFieldProps, 'type' | 'endIcon' | 'onEndIconClick' | 'onChange'> {
3
+ export interface PasswordFieldProps extends Omit<TextFieldProps, 'type' | 'endIcon' | 'endIconLabel' | 'onEndIconClick' | 'onChange'> {
4
4
  /**
5
5
  * The browser autofill hint. Defaults to `current-password`; set `new-password` on the
6
6
  * fields of a change-password or sign-up form so password managers offer to generate and
7
7
  * store a new credential instead of filling the existing one.
8
8
  */
9
9
  autoComplete?: string;
10
+ /**
11
+ * Accessible name of the toggle button while the password is visible
12
+ */
13
+ hideLabel?: string;
10
14
  /**
11
15
  * Callback function when the field value changes
12
16
  */
13
17
  onChange: (value: string) => void;
18
+ /**
19
+ * Accessible name of the toggle button while the password is hidden
20
+ */
21
+ showLabel?: string;
14
22
  }
15
23
  /**
16
24
  * Password field component with show/hide toggle functionality.
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordField.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/PasswordField/PasswordField.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAc,EAAE,EAAqB,MAAM,OAAO,CAAC;AAM1D,OAAkB,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAC;AAEjE,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,UAAU,CAAC;IAClH;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;;;GAGG;AACH,QAAA,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CA2CzC,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"PasswordField.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/PasswordField/PasswordField.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAc,EAAE,EAAqB,MAAM,OAAO,CAAC;AAM1D,OAAkB,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAC;AAEjE,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,gBAAgB,GAAG,UAAU,CAAC;IACjG;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,QAAA,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CA8CzC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -13,7 +13,7 @@ import { jsx } from "react/jsx-runtime";
13
13
  * Password field component with show/hide toggle functionality.
14
14
  * This component extends TextField and adds password visibility toggle functionality.
15
15
  */
16
- const PasswordField = ({ autoComplete = "current-password", onChange, className, disabled, error,...textFieldProps }) => {
16
+ const PasswordField = ({ autoComplete = "current-password", hideLabel = "Hide password", onChange, showLabel = "Show password", className, disabled, error,...textFieldProps }) => {
17
17
  const { theme, colorScheme } = useTheme_default();
18
18
  const [showPassword, setShowPassword] = useState(false);
19
19
  const styles = PasswordField_styles_default(theme, colorScheme, showPassword, !!disabled, !!error);
@@ -29,6 +29,7 @@ const PasswordField = ({ autoComplete = "current-password", onChange, className,
29
29
  autoComplete,
30
30
  disabled,
31
31
  error,
32
+ endIconLabel: showPassword ? hideLabel : showLabel,
32
33
  endIcon: /* @__PURE__ */ jsx(IconComponent, {
33
34
  width: 16,
34
35
  height: 16,
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordField.js","names":["PasswordField: FC<PasswordFieldProps>","useTheme","styles: Record<string, string>","useStyles","IconComponent: FC<SVGProps<SVGSVGElement>>","EyeOff","Eye","TextField"],"sources":["../../../../src/components/primitives/PasswordField/PasswordField.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {withVendorCSSClassPrefix, bem} from '@thunderid/browser';\nimport {ChangeEvent, FC, SVGProps, useState} from 'react';\nimport useStyles from './PasswordField.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport Eye from '../Icons/Eye';\nimport EyeOff from '../Icons/EyeOff';\nimport TextField, {TextFieldProps} from '../TextField/TextField';\n\nexport interface PasswordFieldProps extends Omit<TextFieldProps, 'type' | 'endIcon' | 'onEndIconClick' | 'onChange'> {\n /**\n * The browser autofill hint. Defaults to `current-password`; set `new-password` on the\n * fields of a change-password or sign-up form so password managers offer to generate and\n * store a new credential instead of filling the existing one.\n */\n autoComplete?: string;\n /**\n * Callback function when the field value changes\n */\n onChange: (value: string) => void;\n}\n\n/**\n * Password field component with show/hide toggle functionality.\n * This component extends TextField and adds password visibility toggle functionality.\n */\nconst PasswordField: FC<PasswordFieldProps> = ({\n autoComplete = 'current-password',\n onChange,\n className,\n disabled,\n error,\n ...textFieldProps\n}: PasswordFieldProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const [showPassword, setShowPassword] = useState(false);\n const styles: Record<string, string> = useStyles(theme, colorScheme, showPassword, !!disabled, !!error);\n\n const togglePasswordVisibility = (): void => {\n if (!disabled) {\n setShowPassword(!showPassword);\n }\n };\n\n const IconComponent: FC<SVGProps<SVGSVGElement>> = showPassword ? EyeOff : Eye;\n\n return (\n <TextField\n {...textFieldProps}\n className={cx(withVendorCSSClassPrefix(bem('password-field')), className)}\n type={showPassword ? 'text' : 'password'}\n onChange={(e: ChangeEvent<HTMLInputElement>): void => onChange(e.target.value)}\n autoComplete={autoComplete}\n disabled={disabled}\n error={error}\n endIcon={\n <IconComponent\n width={16}\n height={16}\n className={cx(\n withVendorCSSClassPrefix(bem('password-field', 'toggle-icon')),\n styles['toggleIcon'],\n showPassword ? styles['visibleIcon'] : styles['hiddenIcon'],\n )}\n />\n }\n onEndIconClick={togglePasswordVisibility}\n />\n );\n};\n\nexport default PasswordField;\n"],"mappings":";;;;;;;;;;;;;;;AA6BA,MAAMA,iBAAyC,EAC7C,eAAe,oBACf,UACA,WACA,UACA,MACA,GAAG,qBACqB;CACxB,MAAM,EAAC,OAAO,gBAA4CC,kBAAU;CACpE,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;CACvD,MAAMC,SAAiCC,6BAAU,OAAO,aAAa,cAAc,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM;CAEvG,MAAM,iCAAuC;AAC3C,MAAI,CAAC,SACH,iBAAgB,CAAC,aAAa;;CAIlC,MAAMC,gBAA6C,eAAeC,iBAASC;AAE3E,QACE,oBAACC;EACC,GAAI;EACJ,WAAW,GAAG,yBAAyB,IAAI,iBAAiB,CAAC,EAAE,UAAU;EACzE,MAAM,eAAe,SAAS;EAC9B,WAAW,MAA2C,SAAS,EAAE,OAAO,MAAM;EAChE;EACJ;EACH;EACP,SACE,oBAAC;GACC,OAAO;GACP,QAAQ;GACR,WAAW,GACT,yBAAyB,IAAI,kBAAkB,cAAc,CAAC,EAC9D,OAAO,eACP,eAAe,OAAO,iBAAiB,OAAO,cAC/C;IACD;EAEJ,gBAAgB;GAChB;;AAIN,4BAAe"}
1
+ {"version":3,"file":"PasswordField.js","names":["PasswordField: FC<PasswordFieldProps>","useTheme","styles: Record<string, string>","useStyles","IconComponent: FC<SVGProps<SVGSVGElement>>","EyeOff","Eye","TextField"],"sources":["../../../../src/components/primitives/PasswordField/PasswordField.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {withVendorCSSClassPrefix, bem} from '@thunderid/browser';\nimport {ChangeEvent, FC, SVGProps, useState} from 'react';\nimport useStyles from './PasswordField.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport Eye from '../Icons/Eye';\nimport EyeOff from '../Icons/EyeOff';\nimport TextField, {TextFieldProps} from '../TextField/TextField';\n\nexport interface PasswordFieldProps\n extends Omit<TextFieldProps, 'type' | 'endIcon' | 'endIconLabel' | 'onEndIconClick' | 'onChange'> {\n /**\n * The browser autofill hint. Defaults to `current-password`; set `new-password` on the\n * fields of a change-password or sign-up form so password managers offer to generate and\n * store a new credential instead of filling the existing one.\n */\n autoComplete?: string;\n /**\n * Accessible name of the toggle button while the password is visible\n */\n hideLabel?: string;\n /**\n * Callback function when the field value changes\n */\n onChange: (value: string) => void;\n /**\n * Accessible name of the toggle button while the password is hidden\n */\n showLabel?: string;\n}\n\n/**\n * Password field component with show/hide toggle functionality.\n * This component extends TextField and adds password visibility toggle functionality.\n */\nconst PasswordField: FC<PasswordFieldProps> = ({\n autoComplete = 'current-password',\n hideLabel = 'Hide password',\n onChange,\n showLabel = 'Show password',\n className,\n disabled,\n error,\n ...textFieldProps\n}: PasswordFieldProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const [showPassword, setShowPassword] = useState(false);\n const styles: Record<string, string> = useStyles(theme, colorScheme, showPassword, !!disabled, !!error);\n\n const togglePasswordVisibility = (): void => {\n if (!disabled) {\n setShowPassword(!showPassword);\n }\n };\n\n const IconComponent: FC<SVGProps<SVGSVGElement>> = showPassword ? EyeOff : Eye;\n\n return (\n <TextField\n {...textFieldProps}\n className={cx(withVendorCSSClassPrefix(bem('password-field')), className)}\n type={showPassword ? 'text' : 'password'}\n onChange={(e: ChangeEvent<HTMLInputElement>): void => onChange(e.target.value)}\n autoComplete={autoComplete}\n disabled={disabled}\n error={error}\n endIconLabel={showPassword ? hideLabel : showLabel}\n endIcon={\n <IconComponent\n width={16}\n height={16}\n className={cx(\n withVendorCSSClassPrefix(bem('password-field', 'toggle-icon')),\n styles['toggleIcon'],\n showPassword ? styles['visibleIcon'] : styles['hiddenIcon'],\n )}\n />\n }\n onEndIconClick={togglePasswordVisibility}\n />\n );\n};\n\nexport default PasswordField;\n"],"mappings":";;;;;;;;;;;;;;;AAsCA,MAAMA,iBAAyC,EAC7C,eAAe,oBACf,YAAY,iBACZ,UACA,YAAY,iBACZ,WACA,UACA,MACA,GAAG,qBACqB;CACxB,MAAM,EAAC,OAAO,gBAA4CC,kBAAU;CACpE,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;CACvD,MAAMC,SAAiCC,6BAAU,OAAO,aAAa,cAAc,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM;CAEvG,MAAM,iCAAuC;AAC3C,MAAI,CAAC,SACH,iBAAgB,CAAC,aAAa;;CAIlC,MAAMC,gBAA6C,eAAeC,iBAASC;AAE3E,QACE,oBAACC;EACC,GAAI;EACJ,WAAW,GAAG,yBAAyB,IAAI,iBAAiB,CAAC,EAAE,UAAU;EACzE,MAAM,eAAe,SAAS;EAC9B,WAAW,MAA2C,SAAS,EAAE,OAAO,MAAM;EAChE;EACJ;EACH;EACP,cAAc,eAAe,YAAY;EACzC,SACE,oBAAC;GACC,OAAO;GACP,QAAQ;GACR,WAAW,GACT,yBAAyB,IAAI,kBAAkB,cAAc,CAAC,EAC9D,OAAO,eACP,eAAe,OAAO,iBAAiB,OAAO,cAC/C;IACD;EAEJ,gBAAgB;GAChB;;AAIN,4BAAe"}
@@ -0,0 +1,36 @@
1
+ import type { EmbeddedFlowComponent, EmbeddedFlowComponentType, FetchSelectPage, SelectOptionDefaults, SelectOptionMapping } from '@thunderid/browser';
2
+ import { FC } from 'react';
3
+ import { SelectProps } from './Select';
4
+ export interface ResourceSelectProps extends Omit<SelectProps, 'loading' | 'onError' | 'onLoadMore' | 'options'> {
5
+ /** Block name for the picker's CSS class, e.g. `user-select`. */
6
+ bemBlock: string;
7
+ /** The flow component the page function is called for. Defaults to one built from `type`. */
8
+ component?: EmbeddedFlowComponent;
9
+ defaults?: SelectOptionDefaults;
10
+ /** Wording used when the translations for the keys under `messageKey` are empty. */
11
+ fallbackMessages: {
12
+ ariaLabel: string;
13
+ empty: string;
14
+ };
15
+ /** Loads one page of the resource. Nothing is requested while this is unset. */
16
+ fetchPage?: FetchSelectPage;
17
+ filter?: string;
18
+ mapping?: SelectOptionMapping;
19
+ /** Translation key group under `elements.fields`, e.g. `user_select`. */
20
+ messageKey: string;
21
+ /** Called with the error of every failed load. The list itself shows no error. */
22
+ onError?: (error: Error) => void;
23
+ /** Options per request. Defaults to 30 and is capped at 100. */
24
+ pageSize?: number;
25
+ /** What is loaded, in the words of the failure log, e.g. `users`. */
26
+ resource: string;
27
+ /** The flow component type this picker stands for. */
28
+ type: EmbeddedFlowComponentType;
29
+ }
30
+ /**
31
+ * The part the `USER_SELECT`, `AUTH_FLOW_SELECT` and `USER_TYPE_SELECT` pickers share: a {@link Select} that loads
32
+ * one resource page by page. The list restarts when the page function, filter or page size changes.
33
+ */
34
+ declare const ResourceSelect: FC<ResourceSelectProps>;
35
+ export default ResourceSelect;
36
+ //# sourceMappingURL=ResourceSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourceSelect.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Select/ResourceSelect.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,qBAAqB,EACrB,yBAAyB,EACzB,eAAe,EAEf,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,EAAE,EAA6B,MAAM,OAAO,CAAC;AACrD,OAAe,EAAC,WAAW,EAAC,MAAM,UAAU,CAAC;AAK7C,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;IAC9G,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,oFAAoF;IACpF,gBAAgB,EAAE;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC;IACrD,gFAAgF;IAChF,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,IAAI,EAAE,yBAAyB,CAAC;CACjC;AAID;;;GAGG;AACH,QAAA,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CA6F3C,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { cx } from "../../../styles/emotion.js";
2
+ import useTranslation_default from "../../../hooks/useTranslation.js";
3
+ import useInfiniteOptions_default from "../../../hooks/useInfiniteOptions.js";
4
+ import Select_default from "./Select.js";
5
+ import { SelectConstants, bem, createResourceOptionsLoader, resolvePageSize, withVendorCSSClassPrefix } from "@thunderid/browser";
6
+ import { useEffect, useMemo, useRef } from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+
9
+ //#region src/components/primitives/Select/ResourceSelect.tsx
10
+ const NO_PAGES = () => Promise.resolve({
11
+ nextOffset: null,
12
+ options: []
13
+ });
14
+ /**
15
+ * The part the `USER_SELECT`, `AUTH_FLOW_SELECT` and `USER_TYPE_SELECT` pickers share: a {@link Select} that loads
16
+ * one resource page by page. The list restarts when the page function, filter or page size changes.
17
+ */
18
+ const ResourceSelect = ({ "aria-label": ariaLabel, bemBlock, className, component, defaults, emptyText, fallbackMessages, fetchPage, filter, id, label, mapping, messageKey, name, onError, pageSize = SelectConstants.DEFAULT_PAGE_SIZE, placeholder, resource, type,...rest }) => {
19
+ const { t } = useTranslation_default();
20
+ const effectivePageSize = resolvePageSize(pageSize);
21
+ const live = useRef({
22
+ component,
23
+ defaults,
24
+ mapping
25
+ });
26
+ useEffect(() => {
27
+ live.current = {
28
+ component,
29
+ defaults,
30
+ mapping
31
+ };
32
+ });
33
+ const load = useMemo(() => createResourceOptionsLoader({
34
+ get component() {
35
+ return live.current.component ?? {
36
+ id: id ?? name ?? bemBlock,
37
+ type
38
+ };
39
+ },
40
+ get defaults() {
41
+ return live.current.defaults;
42
+ },
43
+ fetchPage: fetchPage ?? NO_PAGES,
44
+ filter,
45
+ get mapping() {
46
+ return live.current.mapping;
47
+ },
48
+ pageSize: effectivePageSize,
49
+ resource
50
+ }), [
51
+ bemBlock,
52
+ effectivePageSize,
53
+ fetchPage,
54
+ filter,
55
+ id,
56
+ name,
57
+ resource,
58
+ type
59
+ ]);
60
+ const { hasMore, loading, onLoadMore, options, reset } = useInfiniteOptions_default({
61
+ load,
62
+ onError
63
+ });
64
+ const previousLoadRef = useRef(null);
65
+ useEffect(() => {
66
+ const previousLoad = previousLoadRef.current;
67
+ previousLoadRef.current = load;
68
+ if (previousLoad !== null && previousLoad !== load) reset();
69
+ if (fetchPage) onLoadMore();
70
+ }, [
71
+ fetchPage,
72
+ load,
73
+ onLoadMore,
74
+ reset
75
+ ]);
76
+ const accessibleName = [
77
+ ariaLabel,
78
+ label,
79
+ placeholder,
80
+ t(`elements.fields.${messageKey}.aria_label`)
81
+ ].find((text) => Boolean(text)) ?? fallbackMessages.ariaLabel;
82
+ return /* @__PURE__ */ jsx(Select_default, {
83
+ ...rest,
84
+ "aria-label": accessibleName,
85
+ className: cx(withVendorCSSClassPrefix(bem(bemBlock)), className),
86
+ emptyText: emptyText ?? (t(`elements.fields.${messageKey}.empty`) || fallbackMessages.empty),
87
+ id,
88
+ label,
89
+ loading,
90
+ name,
91
+ onLoadMore: fetchPage && hasMore ? onLoadMore : void 0,
92
+ options,
93
+ placeholder
94
+ });
95
+ };
96
+ var ResourceSelect_default = ResourceSelect;
97
+
98
+ //#endregion
99
+ export { ResourceSelect_default as default };
100
+ //# sourceMappingURL=ResourceSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourceSelect.js","names":["NO_PAGES: FetchSelectPage","ResourceSelect: FC<ResourceSelectProps>","useTranslation","effectivePageSize: number","load: ResourceOptionsLoader","useInfiniteOptions","previousLoad: ResourceOptionsLoader | null","accessibleName: string","Select"],"sources":["../../../../src/components/primitives/Select/ResourceSelect.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n bem,\n createResourceOptionsLoader,\n SelectConstants,\n resolvePageSize,\n withVendorCSSClassPrefix,\n} from '@thunderid/browser';\nimport type {\n EmbeddedFlowComponent,\n EmbeddedFlowComponentType,\n FetchSelectPage,\n ResourceOptionsLoader,\n SelectOptionDefaults,\n SelectOptionMapping,\n} from '@thunderid/browser';\nimport {FC, useEffect, useMemo, useRef} from 'react';\nimport Select, {SelectProps} from './Select';\nimport useInfiniteOptions from '../../../hooks/useInfiniteOptions';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\n\nexport interface ResourceSelectProps extends Omit<SelectProps, 'loading' | 'onError' | 'onLoadMore' | 'options'> {\n /** Block name for the picker's CSS class, e.g. `user-select`. */\n bemBlock: string;\n /** The flow component the page function is called for. Defaults to one built from `type`. */\n component?: EmbeddedFlowComponent;\n defaults?: SelectOptionDefaults;\n /** Wording used when the translations for the keys under `messageKey` are empty. */\n fallbackMessages: {ariaLabel: string; empty: string};\n /** Loads one page of the resource. Nothing is requested while this is unset. */\n fetchPage?: FetchSelectPage;\n filter?: string;\n mapping?: SelectOptionMapping;\n /** Translation key group under `elements.fields`, e.g. `user_select`. */\n messageKey: string;\n /** Called with the error of every failed load. The list itself shows no error. */\n onError?: (error: Error) => void;\n /** Options per request. Defaults to 30 and is capped at 100. */\n pageSize?: number;\n /** What is loaded, in the words of the failure log, e.g. `users`. */\n resource: string;\n /** The flow component type this picker stands for. */\n type: EmbeddedFlowComponentType;\n}\n\nconst NO_PAGES: FetchSelectPage = () => Promise.resolve({nextOffset: null, options: []});\n\n/**\n * The part the `USER_SELECT`, `AUTH_FLOW_SELECT` and `USER_TYPE_SELECT` pickers share: a {@link Select} that loads\n * one resource page by page. The list restarts when the page function, filter or page size changes.\n */\nconst ResourceSelect: FC<ResourceSelectProps> = ({\n 'aria-label': ariaLabel,\n bemBlock,\n className,\n component,\n defaults,\n emptyText,\n fallbackMessages,\n fetchPage,\n filter,\n id,\n label,\n mapping,\n messageKey,\n name,\n onError,\n pageSize = SelectConstants.DEFAULT_PAGE_SIZE,\n placeholder,\n resource,\n type,\n ...rest\n}: ResourceSelectProps) => {\n const {t} = useTranslation();\n const effectivePageSize: number = resolvePageSize(pageSize);\n\n const live = useRef({component, defaults, mapping});\n\n useEffect(() => {\n live.current = {component, defaults, mapping};\n });\n\n // Only the page function, filter and page size restart the list. Mapping, defaults and component are read when\n // a page loads, so a parent that passes a new object on every render does not reload it.\n const load: ResourceOptionsLoader = useMemo(\n () =>\n createResourceOptionsLoader({\n get component(): EmbeddedFlowComponent {\n return live.current.component ?? ({id: id ?? name ?? bemBlock, type} as EmbeddedFlowComponent);\n },\n get defaults(): SelectOptionDefaults | undefined {\n return live.current.defaults;\n },\n fetchPage: fetchPage ?? NO_PAGES,\n filter,\n get mapping(): SelectOptionMapping | undefined {\n return live.current.mapping;\n },\n pageSize: effectivePageSize,\n resource,\n }),\n [bemBlock, effectivePageSize, fetchPage, filter, id, name, resource, type],\n );\n const {hasMore, loading, onLoadMore, options, reset} = useInfiniteOptions({load, onError});\n\n const previousLoadRef = useRef<ResourceOptionsLoader | null>(null);\n\n // The first batch is requested when the picker renders. A different page function, filter or page size starts\n // the list again from the beginning.\n useEffect(() => {\n const previousLoad: ResourceOptionsLoader | null = previousLoadRef.current;\n\n previousLoadRef.current = load;\n\n if (previousLoad !== null && previousLoad !== load) {\n reset();\n }\n\n if (fetchPage) {\n onLoadMore();\n }\n }, [fetchPage, load, onLoadMore, reset]);\n\n // The first of these that is not empty names the select. An empty string is not a name, which is why this is not a\n // chain of `??`.\n const accessibleName: string =\n [ariaLabel, label, placeholder, t(`elements.fields.${messageKey}.aria_label`)].find((text) => Boolean(text)) ??\n fallbackMessages.ariaLabel;\n\n return (\n <Select\n {...rest}\n aria-label={accessibleName}\n className={cx(withVendorCSSClassPrefix(bem(bemBlock)), className)}\n emptyText={emptyText ?? (t(`elements.fields.${messageKey}.empty`) || fallbackMessages.empty)}\n id={id}\n label={label}\n loading={loading}\n name={name}\n onLoadMore={fetchPage && hasMore ? onLoadMore : undefined}\n options={options}\n placeholder={placeholder}\n />\n );\n};\n\nexport default ResourceSelect;\n"],"mappings":";;;;;;;;;AAgDA,MAAMA,iBAAkC,QAAQ,QAAQ;CAAC,YAAY;CAAM,SAAS,EAAE;CAAC,CAAC;;;;;AAMxF,MAAMC,kBAA2C,EAC/C,cAAc,WACd,UACA,WACA,WACA,UACA,WACA,kBACA,WACA,QACA,IACA,OACA,SACA,YACA,MACA,SACA,WAAW,gBAAgB,mBAC3B,aACA,UACA,KACA,GAAG,WACsB;CACzB,MAAM,EAAC,MAAKC,wBAAgB;CAC5B,MAAMC,oBAA4B,gBAAgB,SAAS;CAE3D,MAAM,OAAO,OAAO;EAAC;EAAW;EAAU;EAAQ,CAAC;AAEnD,iBAAgB;AACd,OAAK,UAAU;GAAC;GAAW;GAAU;GAAQ;GAC7C;CAIF,MAAMC,OAA8B,cAEhC,4BAA4B;EAC1B,IAAI,YAAmC;AACrC,UAAO,KAAK,QAAQ,aAAc;IAAC,IAAI,MAAM,QAAQ;IAAU;IAAK;;EAEtE,IAAI,WAA6C;AAC/C,UAAO,KAAK,QAAQ;;EAEtB,WAAW,aAAa;EACxB;EACA,IAAI,UAA2C;AAC7C,UAAO,KAAK,QAAQ;;EAEtB,UAAU;EACV;EACD,CAAC,EACJ;EAAC;EAAU;EAAmB;EAAW;EAAQ;EAAI;EAAM;EAAU;EAAK,CAC3E;CACD,MAAM,EAAC,SAAS,SAAS,YAAY,SAAS,UAASC,2BAAmB;EAAC;EAAM;EAAQ,CAAC;CAE1F,MAAM,kBAAkB,OAAqC,KAAK;AAIlE,iBAAgB;EACd,MAAMC,eAA6C,gBAAgB;AAEnE,kBAAgB,UAAU;AAE1B,MAAI,iBAAiB,QAAQ,iBAAiB,KAC5C,QAAO;AAGT,MAAI,UACF,aAAY;IAEb;EAAC;EAAW;EAAM;EAAY;EAAM,CAAC;CAIxC,MAAMC,iBACJ;EAAC;EAAW;EAAO;EAAa,EAAE,mBAAmB,WAAW,aAAa;EAAC,CAAC,MAAM,SAAS,QAAQ,KAAK,CAAC,IAC5G,iBAAiB;AAEnB,QACE,oBAACC;EACC,GAAI;EACJ,cAAY;EACZ,WAAW,GAAG,yBAAyB,IAAI,SAAS,CAAC,EAAE,UAAU;EACjE,WAAW,cAAc,EAAE,mBAAmB,WAAW,QAAQ,IAAI,iBAAiB;EAClF;EACG;EACE;EACH;EACN,YAAY,aAAa,UAAU,aAAa;EACvC;EACI;GACb;;AAIN,6BAAe"}
@@ -1,14 +1,6 @@
1
+ import type { SelectOption, SelectOptionInput } from '@thunderid/browser';
1
2
  import { FC, SelectHTMLAttributes } from 'react';
2
- export interface SelectOption {
3
- /**
4
- * The text that will be displayed in the select
5
- */
6
- label: string;
7
- /**
8
- * The value that will be submitted with the form
9
- */
10
- value: string;
11
- }
3
+ export type { SelectOption, SelectOptionInput };
12
4
  export interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'className'> {
13
5
  /**
14
6
  * Additional CSS class names
@@ -18,6 +10,10 @@ export interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement
18
10
  * Whether the field is disabled
19
11
  */
20
12
  disabled?: boolean;
13
+ /**
14
+ * Text shown below the select when it has no options, nothing is loading and there is nothing more to load
15
+ */
16
+ emptyText?: string;
21
17
  /**
22
18
  * Error message to display below the select
23
19
  */
@@ -31,17 +27,30 @@ export interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement
31
27
  */
32
28
  label?: string;
33
29
  /**
34
- * The options to display in the select
30
+ * Whether options are being fetched. The load more option waits, and a select with no options shows a loading message
35
31
  */
36
- options: SelectOption[];
32
+ loading?: boolean;
37
33
  /**
38
- * Placeholder text for the default/empty option
34
+ * Called when the load more option, listed after the last one, is chosen. Choosing it does not change the selection.
35
+ * The option is listed only when this is set, so pass it only while more options may be available
36
+ */
37
+ onLoadMore?: () => void;
38
+ /**
39
+ * The options to display: strings, numbers, or `{label, value, disabled?}` objects
40
+ */
41
+ options?: readonly (SelectOptionInput | null | undefined)[] | null;
42
+ /**
43
+ * Placeholder text for the default/empty option. While the field is not required, choosing it clears the selection
39
44
  */
40
45
  placeholder?: string;
41
46
  /**
42
47
  * Whether the field is required
43
48
  */
44
49
  required?: boolean;
50
+ /**
51
+ * Label of the selected option while `value` is not among `options`, such as a value loaded from saved data
52
+ */
53
+ selectedOption?: SelectOption;
45
54
  }
46
55
  declare const Select: FC<SelectProps>;
47
56
  export default Select;
@@ -1 +1 @@
1
- {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Select/Select.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAC,EAAE,EAAE,oBAAoB,EAAC,MAAM,OAAO,CAAC;AAO/C,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAC7F;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAuD3B,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Select/Select.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAc,EAAE,EAAa,oBAAoB,EAA6B,MAAM,OAAO,CAAC;AAQnG,YAAY,EAAC,YAAY,EAAE,iBAAiB,EAAC,CAAC;AAE9C,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAC7F;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;IACnE;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,cAAc,CAAC,EAAE,YAAY,CAAC;CAC/B;AAED,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAwH3B,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -3,40 +3,90 @@ import useTheme_default from "../../../contexts/Theme/useTheme.js";
3
3
  import FormControl_default from "../FormControl/FormControl.js";
4
4
  import InputLabel_default from "../InputLabel/InputLabel.js";
5
5
  import Select_styles_default from "./Select.styles.js";
6
- import { bem, withVendorCSSClassPrefix } from "@thunderid/browser";
6
+ import useSelectMessages_default from "./useSelectMessages.js";
7
+ import { SelectConstants, bem, normalizeSelectOptions, withVendorCSSClassPrefix } from "@thunderid/browser";
8
+ import { useEffect, useMemo, useRef } from "react";
7
9
  import { jsx, jsxs } from "react/jsx-runtime";
8
10
 
9
11
  //#region src/components/primitives/Select/Select.tsx
10
- const Select = ({ label, error, className, required, disabled, helperText, placeholder, options, style = {},...rest }) => {
12
+ const Select = ({ label, error, className, required, disabled, helperText, placeholder, options = void 0, emptyText = void 0, loading = false, onLoadMore = void 0, onChange = void 0, selectedOption = void 0, style = {},...rest }) => {
11
13
  const { theme, colorScheme } = useTheme_default();
14
+ const messages = useSelectMessages_default();
12
15
  const hasError = !!error;
13
16
  const styles = Select_styles_default(theme, colorScheme, disabled ?? false, hasError);
17
+ const items = useMemo(() => normalizeSelectOptions(options), [options]);
18
+ const selectRef = useRef(null);
19
+ const chosenValueRef = useRef("");
20
+ useEffect(() => {
21
+ const current = selectRef.current?.value;
22
+ if (current !== void 0 && current !== SelectConstants.LOAD_MORE_OPTION_VALUE) chosenValueRef.current = current;
23
+ });
24
+ const handleChange = (event) => {
25
+ if (event.target.value !== SelectConstants.LOAD_MORE_OPTION_VALUE) {
26
+ chosenValueRef.current = event.target.value;
27
+ onChange?.(event);
28
+ return;
29
+ }
30
+ event.target.value = chosenValueRef.current;
31
+ onLoadMore?.();
32
+ };
14
33
  const selectClassName = cx(withVendorCSSClassPrefix(bem("select", "input")), styles["select"], hasError && styles["selectError"], disabled && styles["selectDisabled"]);
34
+ const showsSelectedOption = selectedOption !== void 0 && rest.value !== void 0 && String(rest.value) === selectedOption.value && !items.some((item) => item.value === selectedOption.value);
35
+ let statusText;
36
+ if (loading) statusText = items.length === 0 ? messages.loading : messages.loadingMore;
37
+ else if (items.length === 0 && !onLoadMore) statusText = emptyText;
38
+ const hasStatus = onLoadMore !== void 0 || emptyText !== void 0 || loading;
39
+ const showsLoadMore = onLoadMore !== void 0 && (items.length > 0 || !loading);
15
40
  return /* @__PURE__ */ jsxs(FormControl_default, {
16
41
  error,
17
42
  helperText,
18
43
  className: cx(withVendorCSSClassPrefix(bem("select")), className),
19
44
  style,
20
- children: [label && /* @__PURE__ */ jsx(InputLabel_default, {
21
- required,
22
- error: hasError,
23
- children: label
24
- }), /* @__PURE__ */ jsxs("select", {
25
- className: selectClassName,
26
- disabled,
27
- "aria-invalid": hasError,
28
- "aria-required": required,
29
- ...rest,
30
- children: [placeholder && /* @__PURE__ */ jsx("option", {
31
- value: "",
32
- disabled: true,
33
- children: placeholder
34
- }), options.map((option) => /* @__PURE__ */ jsx("option", {
35
- value: option.value,
36
- className: styles["option"],
37
- children: option.label
38
- }, option.value))]
39
- })]
45
+ children: [
46
+ label && /* @__PURE__ */ jsx(InputLabel_default, {
47
+ required,
48
+ error: hasError,
49
+ children: label
50
+ }),
51
+ /* @__PURE__ */ jsxs("select", {
52
+ className: selectClassName,
53
+ disabled,
54
+ "aria-invalid": hasError,
55
+ "aria-required": required,
56
+ "aria-busy": loading || void 0,
57
+ ...rest,
58
+ ref: selectRef,
59
+ onChange: onLoadMore ? handleChange : onChange,
60
+ children: [
61
+ placeholder && /* @__PURE__ */ jsx("option", {
62
+ value: "",
63
+ disabled: Boolean(required),
64
+ children: placeholder
65
+ }),
66
+ showsSelectedOption && /* @__PURE__ */ jsx("option", {
67
+ value: selectedOption?.value,
68
+ children: selectedOption?.label
69
+ }),
70
+ items.map((option) => /* @__PURE__ */ jsx("option", {
71
+ value: option.value,
72
+ disabled: option.disabled,
73
+ className: styles["option"],
74
+ children: option.label
75
+ }, option.value)),
76
+ showsLoadMore && /* @__PURE__ */ jsx("option", {
77
+ value: SelectConstants.LOAD_MORE_OPTION_VALUE,
78
+ disabled: loading,
79
+ className: cx(withVendorCSSClassPrefix(bem("select", "load-more")), styles["option"], styles["loadMore"]),
80
+ children: loading ? messages.loadingMore : messages.loadMore
81
+ })
82
+ ]
83
+ }),
84
+ hasStatus && /* @__PURE__ */ jsx("span", {
85
+ role: "status",
86
+ className: styles["status"],
87
+ children: statusText
88
+ })
89
+ ]
40
90
  });
41
91
  };
42
92
  var Select_default = Select;
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","names":["Select: FC<SelectProps>","useTheme","styles: Record<string, string>","useStyles","selectClassName: string","FormControl","InputLabel"],"sources":["../../../../src/components/primitives/Select/Select.tsx"],"sourcesContent":["// Copyright 2024 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {withVendorCSSClassPrefix, bem} from '@thunderid/browser';\nimport {FC, SelectHTMLAttributes} from 'react';\nimport useStyles from './Select.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport FormControl from '../FormControl/FormControl';\nimport InputLabel from '../InputLabel/InputLabel';\n\nexport interface SelectOption {\n /**\n * The text that will be displayed in the select\n */\n label: string;\n /**\n * The value that will be submitted with the form\n */\n value: string;\n}\n\nexport interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'className'> {\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 select\n */\n error?: string;\n /**\n * Helper text to display below the select\n */\n helperText?: string;\n /**\n * Label text to display above the select\n */\n label?: string;\n /**\n * The options to display in the select\n */\n options: SelectOption[];\n /**\n * Placeholder text for the default/empty option\n */\n placeholder?: string;\n /**\n * Whether the field is required\n */\n required?: boolean;\n}\n\nconst Select: FC<SelectProps> = ({\n label,\n error,\n className,\n required,\n disabled,\n helperText,\n placeholder,\n options,\n style = {},\n ...rest\n}: SelectProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const hasError = !!error;\n const styles: Record<string, string> = useStyles(theme, colorScheme, disabled ?? false, hasError);\n\n const selectClassName: string = cx(\n withVendorCSSClassPrefix(bem('select', 'input')),\n styles['select'],\n hasError && styles['selectError'],\n disabled && styles['selectDisabled'],\n );\n\n return (\n <FormControl\n error={error}\n helperText={helperText}\n className={cx(withVendorCSSClassPrefix(bem('select')), className)}\n style={style}\n >\n {label && (\n <InputLabel required={required} error={hasError}>\n {label}\n </InputLabel>\n )}\n <select\n className={selectClassName}\n disabled={disabled}\n aria-invalid={hasError}\n aria-required={required}\n {...rest}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {options.map((option: SelectOption) => (\n <option key={option.value} value={option.value} className={styles['option']}>\n {option.label}\n </option>\n ))}\n </select>\n </FormControl>\n );\n};\n\nexport default Select;\n"],"mappings":";;;;;;;;;AAyDA,MAAMA,UAA2B,EAC/B,OACA,OACA,WACA,UACA,UACA,YACA,aACA,SACA,QAAQ,EAAE,CACV,GAAG,WACc;CACjB,MAAM,EAAC,OAAO,gBAA4CC,kBAAU;CACpE,MAAM,WAAW,CAAC,CAAC;CACnB,MAAMC,SAAiCC,sBAAU,OAAO,aAAa,YAAY,OAAO,SAAS;CAEjG,MAAMC,kBAA0B,GAC9B,yBAAyB,IAAI,UAAU,QAAQ,CAAC,EAChD,OAAO,WACP,YAAY,OAAO,gBACnB,YAAY,OAAO,kBACpB;AAED,QACE,qBAACC;EACQ;EACK;EACZ,WAAW,GAAG,yBAAyB,IAAI,SAAS,CAAC,EAAE,UAAU;EAC1D;aAEN,SACC,oBAACC;GAAqB;GAAU,OAAO;aACpC;IACU,EAEf,qBAAC;GACC,WAAW;GACD;GACV,gBAAc;GACd,iBAAe;GACf,GAAI;cAEH,eACC,oBAAC;IAAO,OAAM;IAAG;cACd;KACM,EAEV,QAAQ,KAAK,WACZ,oBAAC;IAA0B,OAAO,OAAO;IAAO,WAAW,OAAO;cAC/D,OAAO;MADG,OAAO,MAEX,CACT;IACK;GACG;;AAIlB,qBAAe"}
1
+ {"version":3,"file":"Select.js","names":["Select: FC<SelectProps>","useTheme","messages: SelectMessages","useSelectMessages","styles: Record<string, string>","useStyles","items: SelectOption[]","selectRef: RefObject<HTMLSelectElement | null>","chosenValueRef: RefObject<string>","current: string | undefined","selectClassName: string","showsSelectedOption: boolean","statusText: string | undefined","hasStatus: boolean","showsLoadMore: boolean","FormControl","InputLabel"],"sources":["../../../../src/components/primitives/Select/Select.tsx"],"sourcesContent":["// Copyright 2024 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {bem, normalizeSelectOptions, SelectConstants, withVendorCSSClassPrefix} from '@thunderid/browser';\nimport type {SelectOption, SelectOptionInput} from '@thunderid/browser';\nimport {ChangeEvent, FC, RefObject, SelectHTMLAttributes, useEffect, useMemo, useRef} from 'react';\nimport useStyles from './Select.styles';\nimport useSelectMessages, {SelectMessages} from './useSelectMessages';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport FormControl from '../FormControl/FormControl';\nimport InputLabel from '../InputLabel/InputLabel';\n\nexport type {SelectOption, SelectOptionInput};\n\nexport interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'className'> {\n /**\n * Additional CSS class names\n */\n className?: string;\n /**\n * Whether the field is disabled\n */\n disabled?: boolean;\n /**\n * Text shown below the select when it has no options, nothing is loading and there is nothing more to load\n */\n emptyText?: string;\n /**\n * Error message to display below the select\n */\n error?: string;\n /**\n * Helper text to display below the select\n */\n helperText?: string;\n /**\n * Label text to display above the select\n */\n label?: string;\n /**\n * Whether options are being fetched. The load more option waits, and a select with no options shows a loading message\n */\n loading?: boolean;\n /**\n * Called when the load more option, listed after the last one, is chosen. Choosing it does not change the selection.\n * The option is listed only when this is set, so pass it only while more options may be available\n */\n onLoadMore?: () => void;\n /**\n * The options to display: strings, numbers, or `{label, value, disabled?}` objects\n */\n options?: readonly (SelectOptionInput | null | undefined)[] | null;\n /**\n * Placeholder text for the default/empty option. While the field is not required, choosing it clears the selection\n */\n placeholder?: string;\n /**\n * Whether the field is required\n */\n required?: boolean;\n /**\n * Label of the selected option while `value` is not among `options`, such as a value loaded from saved data\n */\n selectedOption?: SelectOption;\n}\n\nconst Select: FC<SelectProps> = ({\n label,\n error,\n className,\n required,\n disabled,\n helperText,\n placeholder,\n options = undefined,\n emptyText = undefined,\n loading = false,\n onLoadMore = undefined,\n onChange = undefined,\n selectedOption = undefined,\n style = {},\n ...rest\n}: SelectProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const messages: SelectMessages = useSelectMessages();\n const hasError = !!error;\n const styles: Record<string, string> = useStyles(theme, colorScheme, disabled ?? false, hasError);\n const items: SelectOption[] = useMemo(() => normalizeSelectOptions(options), [options]);\n const selectRef: RefObject<HTMLSelectElement | null> = useRef<HTMLSelectElement>(null);\n const chosenValueRef: RefObject<string> = useRef<string>('');\n\n // The value to put back when the load more option is chosen, since choosing it is not a selection.\n useEffect(() => {\n const current: string | undefined = selectRef.current?.value;\n\n if (current !== undefined && current !== SelectConstants.LOAD_MORE_OPTION_VALUE) {\n chosenValueRef.current = current;\n }\n });\n\n const handleChange = (event: ChangeEvent<HTMLSelectElement>): void => {\n if (event.target.value !== SelectConstants.LOAD_MORE_OPTION_VALUE) {\n chosenValueRef.current = event.target.value;\n onChange?.(event);\n\n return;\n }\n\n event.target.value = chosenValueRef.current;\n onLoadMore?.();\n };\n\n const selectClassName: string = cx(\n withVendorCSSClassPrefix(bem('select', 'input')),\n styles['select'],\n hasError && styles['selectError'],\n disabled && styles['selectDisabled'],\n );\n\n const showsSelectedOption: boolean =\n selectedOption !== undefined &&\n rest.value !== undefined &&\n String(rest.value) === selectedOption.value &&\n !items.some((item: SelectOption) => item.value === selectedOption.value);\n\n let statusText: string | undefined;\n\n if (loading) {\n statusText = items.length === 0 ? messages.loading : messages.loadingMore;\n } else if (items.length === 0 && !onLoadMore) {\n statusText = emptyText;\n }\n\n const hasStatus: boolean = onLoadMore !== undefined || emptyText !== undefined || loading;\n const showsLoadMore: boolean = onLoadMore !== undefined && (items.length > 0 || !loading);\n\n return (\n <FormControl\n error={error}\n helperText={helperText}\n className={cx(withVendorCSSClassPrefix(bem('select')), className)}\n style={style}\n >\n {label && (\n <InputLabel required={required} error={hasError}>\n {label}\n </InputLabel>\n )}\n <select\n className={selectClassName}\n disabled={disabled}\n aria-invalid={hasError}\n aria-required={required}\n aria-busy={loading || undefined}\n {...rest}\n ref={selectRef}\n onChange={onLoadMore ? handleChange : onChange}\n >\n {placeholder && (\n <option value=\"\" disabled={Boolean(required)}>\n {placeholder}\n </option>\n )}\n {showsSelectedOption && <option value={selectedOption?.value}>{selectedOption?.label}</option>}\n {items.map((option: SelectOption) => (\n <option key={option.value} value={option.value} disabled={option.disabled} className={styles['option']}>\n {option.label}\n </option>\n ))}\n {showsLoadMore && (\n <option\n value={SelectConstants.LOAD_MORE_OPTION_VALUE}\n disabled={loading}\n className={cx(withVendorCSSClassPrefix(bem('select', 'load-more')), styles['option'], styles['loadMore'])}\n >\n {loading ? messages.loadingMore : messages.loadMore}\n </option>\n )}\n </select>\n {hasStatus && (\n <span role=\"status\" className={styles['status']}>\n {statusText}\n </span>\n )}\n </FormControl>\n );\n};\n\nexport default Select;\n"],"mappings":";;;;;;;;;;;AAmEA,MAAMA,UAA2B,EAC/B,OACA,OACA,WACA,UACA,UACA,YACA,aACA,UAAU,QACV,YAAY,QACZ,UAAU,OACV,aAAa,QACb,WAAW,QACX,iBAAiB,QACjB,QAAQ,EAAE,CACV,GAAG,WACc;CACjB,MAAM,EAAC,OAAO,gBAA4CC,kBAAU;CACpE,MAAMC,WAA2BC,2BAAmB;CACpD,MAAM,WAAW,CAAC,CAAC;CACnB,MAAMC,SAAiCC,sBAAU,OAAO,aAAa,YAAY,OAAO,SAAS;CACjG,MAAMC,QAAwB,cAAc,uBAAuB,QAAQ,EAAE,CAAC,QAAQ,CAAC;CACvF,MAAMC,YAAiD,OAA0B,KAAK;CACtF,MAAMC,iBAAoC,OAAe,GAAG;AAG5D,iBAAgB;EACd,MAAMC,UAA8B,UAAU,SAAS;AAEvD,MAAI,YAAY,UAAa,YAAY,gBAAgB,uBACvD,gBAAe,UAAU;GAE3B;CAEF,MAAM,gBAAgB,UAAgD;AACpE,MAAI,MAAM,OAAO,UAAU,gBAAgB,wBAAwB;AACjE,kBAAe,UAAU,MAAM,OAAO;AACtC,cAAW,MAAM;AAEjB;;AAGF,QAAM,OAAO,QAAQ,eAAe;AACpC,gBAAc;;CAGhB,MAAMC,kBAA0B,GAC9B,yBAAyB,IAAI,UAAU,QAAQ,CAAC,EAChD,OAAO,WACP,YAAY,OAAO,gBACnB,YAAY,OAAO,kBACpB;CAED,MAAMC,sBACJ,mBAAmB,UACnB,KAAK,UAAU,UACf,OAAO,KAAK,MAAM,KAAK,eAAe,SACtC,CAAC,MAAM,MAAM,SAAuB,KAAK,UAAU,eAAe,MAAM;CAE1E,IAAIC;AAEJ,KAAI,QACF,cAAa,MAAM,WAAW,IAAI,SAAS,UAAU,SAAS;UACrD,MAAM,WAAW,KAAK,CAAC,WAChC,cAAa;CAGf,MAAMC,YAAqB,eAAe,UAAa,cAAc,UAAa;CAClF,MAAMC,gBAAyB,eAAe,WAAc,MAAM,SAAS,KAAK,CAAC;AAEjF,QACE,qBAACC;EACQ;EACK;EACZ,WAAW,GAAG,yBAAyB,IAAI,SAAS,CAAC,EAAE,UAAU;EAC1D;;GAEN,SACC,oBAACC;IAAqB;IAAU,OAAO;cACpC;KACU;GAEf,qBAAC;IACC,WAAW;IACD;IACV,gBAAc;IACd,iBAAe;IACf,aAAW,WAAW;IACtB,GAAI;IACJ,KAAK;IACL,UAAU,aAAa,eAAe;;KAErC,eACC,oBAAC;MAAO,OAAM;MAAG,UAAU,QAAQ,SAAS;gBACzC;OACM;KAEV,uBAAuB,oBAAC;MAAO,OAAO,gBAAgB;gBAAQ,gBAAgB;OAAe;KAC7F,MAAM,KAAK,WACV,oBAAC;MAA0B,OAAO,OAAO;MAAO,UAAU,OAAO;MAAU,WAAW,OAAO;gBAC1F,OAAO;QADG,OAAO,MAEX,CACT;KACD,iBACC,oBAAC;MACC,OAAO,gBAAgB;MACvB,UAAU;MACV,WAAW,GAAG,yBAAyB,IAAI,UAAU,YAAY,CAAC,EAAE,OAAO,WAAW,OAAO,YAAY;gBAExG,UAAU,SAAS,cAAc,SAAS;OACpC;;KAEJ;GACR,aACC,oBAAC;IAAK,MAAK;IAAS,WAAW,OAAO;cACnC;KACI;;GAEG;;AAIlB,qBAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"Select.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Select/Select.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC;;;;;;;GAOG;AACH,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,EAAE,aAAa,MAAM,EAAE,UAAU,OAAO,EAAE,UAAU,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAgFpE,CAAC;AAE/C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"Select.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Select/Select.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC;;;;;;;GAOG;AACH,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,EAAE,aAAa,MAAM,EAAE,UAAU,OAAO,EAAE,UAAU,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAkGpE,CAAC;AAE/C,eAAe,SAAS,CAAC"}
@@ -63,8 +63,7 @@ const useStyles = (theme, colorScheme, disabled, hasError) => useMemo(() => {
63
63
  opacity: 0.6;
64
64
  cursor: not-allowed;
65
65
  `;
66
- return {
67
- option: css`
66
+ const option = css`
68
67
  padding: calc(${theme.vars.spacing.unit} / 2) ${theme.vars.spacing.unit};
69
68
  color: ${theme.vars.colors.text.primary};
70
69
  background-color: ${theme.vars.colors.background.surface};
@@ -77,10 +76,27 @@ const useStyles = (theme, colorScheme, disabled, hasError) => useMemo(() => {
77
76
  background-color: ${theme.vars.colors.primary.main};
78
77
  color: ${theme.vars.colors.primary.contrastText};
79
78
  }
79
+ `;
80
+ const status = css`
81
+ display: block;
82
+ margin-top: calc(${theme.vars.spacing.unit} / 2);
83
+ font-size: ${theme.vars.typography.fontSizes.sm};
84
+ color: ${theme.vars.colors.text.secondary};
85
+
86
+ &:empty {
87
+ display: none;
88
+ }
89
+ `;
90
+ return {
91
+ loadMore: css`
92
+ color: ${theme.vars.colors.primary.main};
93
+ font-weight: ${theme.vars.typography.fontWeights.medium};
80
94
  `,
95
+ option,
81
96
  select,
82
97
  selectDisabled,
83
- selectError
98
+ selectError,
99
+ status
84
100
  };
85
101
  }, [
86
102
  theme,
@@ -1 +1 @@
1
- {"version":3,"file":"Select.styles.js","names":["select: string","selectError: string","selectDisabled: string"],"sources":["../../../../src/components/primitives/Select/Select.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\n/**\n * Creates styles for the Select 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 * @returns Object containing CSS class names for component styling\n */\nconst useStyles = (theme: Theme, colorScheme: string, disabled: boolean, hasError: boolean): Record<string, string> =>\n useMemo(() => {\n const dropdownArrowColor: string = theme.colors.text.secondary.replace('#', '');\n const dropdownArrow = `data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23${dropdownArrowColor}%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E`;\n\n const select: string = css`\n width: 100%;\n padding: ${theme.vars.spacing.unit} calc(${theme.vars.spacing.unit} * 1.5);\n border: 1px 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 font-size: ${theme.vars.typography.fontSizes.md};\n font-family: ${theme.vars.typography.fontFamily};\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 appearance: none;\n background-image: url('${dropdownArrow}');\n background-repeat: no-repeat;\n background-position: right 0.7em top 50%;\n background-size: 0.65em auto;\n cursor: ${disabled ? 'not-allowed' : 'pointer'};\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 opacity: 0.6;\n cursor: not-allowed;\n }\n\n &:hover:not(:disabled) {\n border-color: ${hasError ? theme.vars.colors.error.main : theme.vars.colors.primary.main};\n }\n `;\n\n const selectError: 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 &:hover:not(:disabled) {\n border-color: ${theme.vars.colors.error.main};\n }\n `;\n\n const selectDisabled: string = css`\n background-color: ${theme.vars.colors.background.disabled};\n opacity: 0.6;\n cursor: not-allowed;\n `;\n\n const option: string = css`\n padding: calc(${theme.vars.spacing.unit} / 2) ${theme.vars.spacing.unit};\n color: ${theme.vars.colors.text.primary};\n background-color: ${theme.vars.colors.background.surface};\n\n &:hover {\n background-color: ${theme.vars.colors.action.hover};\n }\n\n &:checked {\n background-color: ${theme.vars.colors.primary.main};\n color: ${theme.vars.colors.primary.contrastText};\n }\n `;\n\n return {\n option,\n select,\n selectDisabled,\n selectError,\n };\n }, [theme, colorScheme, disabled, hasError]);\n\nexport default useStyles;\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,aAAa,OAAc,aAAqB,UAAmB,aACvE,cAAc;CAEZ,MAAM,gBAAgB,yKADa,MAAM,OAAO,KAAK,UAAU,QAAQ,KAAK,GAAG,CACmI;CAElN,MAAMA,SAAiB,GAAG;;iBAEb,MAAM,KAAK,QAAQ,KAAK,QAAQ,MAAM,KAAK,QAAQ,KAAK;0BAC/C,WAAW,MAAM,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,OAAO;uBACtE,MAAM,KAAK,YAAY,OAAO,MAAM,gBAAgB,MAAM,KAAK,aAAa,OAAO;mBACvF,MAAM,KAAK,WAAW,UAAU,GAAG;qBACjC,MAAM,KAAK,WAAW,WAAW;eACvC,MAAM,KAAK,OAAO,KAAK,QAAQ;0BACpB,WAAW,MAAM,KAAK,OAAO,WAAW,WAAW,MAAM,KAAK,OAAO,WAAW,QAAQ;;;;;;+BAMnF,cAAc;;;;gBAI7B,WAAW,gBAAgB,UAAU;;;wBAG7B,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;;;;;;;;;wBAS/F,WAAW,MAAM,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK;;;CAI7F,MAAMC,cAAsB,GAAG;sBACb,MAAM,KAAK,OAAO,MAAM,KAAK;;;wBAG3B,MAAM,KAAK,OAAO,MAAM,KAAK;gCACrB,MAAM,KAAK,OAAO,MAAM,KAAK;;;;wBAIrC,MAAM,KAAK,OAAO,MAAM,KAAK;;;CAIjD,MAAMC,iBAAyB,GAAG;0BACZ,MAAM,KAAK,OAAO,WAAW,SAAS;;;;AAoB5D,QAAO;EACL,QAhBqB,GAAG;sBACR,MAAM,KAAK,QAAQ,KAAK,QAAQ,MAAM,KAAK,QAAQ,KAAK;eAC/D,MAAM,KAAK,OAAO,KAAK,QAAQ;0BACpB,MAAM,KAAK,OAAO,WAAW,QAAQ;;;4BAGnC,MAAM,KAAK,OAAO,OAAO,MAAM;;;;4BAI/B,MAAM,KAAK,OAAO,QAAQ,KAAK;iBAC1C,MAAM,KAAK,OAAO,QAAQ,aAAa;;;EAMlD;EACA;EACA;EACD;GACA;CAAC;CAAO;CAAa;CAAU;CAAS,CAAC;AAE9C,4BAAe"}
1
+ {"version":3,"file":"Select.styles.js","names":["select: string","selectError: string","selectDisabled: string","option: string","status: string"],"sources":["../../../../src/components/primitives/Select/Select.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\n/**\n * Creates styles for the Select 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 * @returns Object containing CSS class names for component styling\n */\nconst useStyles = (theme: Theme, colorScheme: string, disabled: boolean, hasError: boolean): Record<string, string> =>\n useMemo(() => {\n const dropdownArrowColor: string = theme.colors.text.secondary.replace('#', '');\n const dropdownArrow = `data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23${dropdownArrowColor}%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E`;\n\n const select: string = css`\n width: 100%;\n padding: ${theme.vars.spacing.unit} calc(${theme.vars.spacing.unit} * 1.5);\n border: 1px 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 font-size: ${theme.vars.typography.fontSizes.md};\n font-family: ${theme.vars.typography.fontFamily};\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 appearance: none;\n background-image: url('${dropdownArrow}');\n background-repeat: no-repeat;\n background-position: right 0.7em top 50%;\n background-size: 0.65em auto;\n cursor: ${disabled ? 'not-allowed' : 'pointer'};\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 opacity: 0.6;\n cursor: not-allowed;\n }\n\n &:hover:not(:disabled) {\n border-color: ${hasError ? theme.vars.colors.error.main : theme.vars.colors.primary.main};\n }\n `;\n\n const selectError: 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 &:hover:not(:disabled) {\n border-color: ${theme.vars.colors.error.main};\n }\n `;\n\n const selectDisabled: string = css`\n background-color: ${theme.vars.colors.background.disabled};\n opacity: 0.6;\n cursor: not-allowed;\n `;\n\n const option: string = css`\n padding: calc(${theme.vars.spacing.unit} / 2) ${theme.vars.spacing.unit};\n color: ${theme.vars.colors.text.primary};\n background-color: ${theme.vars.colors.background.surface};\n\n &:hover {\n background-color: ${theme.vars.colors.action.hover};\n }\n\n &:checked {\n background-color: ${theme.vars.colors.primary.main};\n color: ${theme.vars.colors.primary.contrastText};\n }\n `;\n\n const status: string = css`\n display: block;\n margin-top: calc(${theme.vars.spacing.unit} / 2);\n font-size: ${theme.vars.typography.fontSizes.sm};\n color: ${theme.vars.colors.text.secondary};\n\n &:empty {\n display: none;\n }\n `;\n\n const loadMore: string = css`\n color: ${theme.vars.colors.primary.main};\n font-weight: ${theme.vars.typography.fontWeights.medium};\n `;\n\n return {\n loadMore,\n option,\n select,\n selectDisabled,\n selectError,\n status,\n };\n }, [theme, colorScheme, disabled, hasError]);\n\nexport default useStyles;\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,aAAa,OAAc,aAAqB,UAAmB,aACvE,cAAc;CAEZ,MAAM,gBAAgB,yKADa,MAAM,OAAO,KAAK,UAAU,QAAQ,KAAK,GAAG,CACmI;CAElN,MAAMA,SAAiB,GAAG;;iBAEb,MAAM,KAAK,QAAQ,KAAK,QAAQ,MAAM,KAAK,QAAQ,KAAK;0BAC/C,WAAW,MAAM,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,OAAO;uBACtE,MAAM,KAAK,YAAY,OAAO,MAAM,gBAAgB,MAAM,KAAK,aAAa,OAAO;mBACvF,MAAM,KAAK,WAAW,UAAU,GAAG;qBACjC,MAAM,KAAK,WAAW,WAAW;eACvC,MAAM,KAAK,OAAO,KAAK,QAAQ;0BACpB,WAAW,MAAM,KAAK,OAAO,WAAW,WAAW,MAAM,KAAK,OAAO,WAAW,QAAQ;;;;;;+BAMnF,cAAc;;;;gBAI7B,WAAW,gBAAgB,UAAU;;;wBAG7B,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;;;;;;;;;wBAS/F,WAAW,MAAM,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK;;;CAI7F,MAAMC,cAAsB,GAAG;sBACb,MAAM,KAAK,OAAO,MAAM,KAAK;;;wBAG3B,MAAM,KAAK,OAAO,MAAM,KAAK;gCACrB,MAAM,KAAK,OAAO,MAAM,KAAK;;;;wBAIrC,MAAM,KAAK,OAAO,MAAM,KAAK;;;CAIjD,MAAMC,iBAAyB,GAAG;0BACZ,MAAM,KAAK,OAAO,WAAW,SAAS;;;;CAK5D,MAAMC,SAAiB,GAAG;sBACR,MAAM,KAAK,QAAQ,KAAK,QAAQ,MAAM,KAAK,QAAQ,KAAK;eAC/D,MAAM,KAAK,OAAO,KAAK,QAAQ;0BACpB,MAAM,KAAK,OAAO,WAAW,QAAQ;;;4BAGnC,MAAM,KAAK,OAAO,OAAO,MAAM;;;;4BAI/B,MAAM,KAAK,OAAO,QAAQ,KAAK;iBAC1C,MAAM,KAAK,OAAO,QAAQ,aAAa;;;CAIpD,MAAMC,SAAiB,GAAG;;yBAEL,MAAM,KAAK,QAAQ,KAAK;mBAC9B,MAAM,KAAK,WAAW,UAAU,GAAG;eACvC,MAAM,KAAK,OAAO,KAAK,UAAU;;;;;;AAY5C,QAAO;EACL,UANuB,GAAG;eACjB,MAAM,KAAK,OAAO,QAAQ,KAAK;qBACzB,MAAM,KAAK,WAAW,YAAY,OAAO;;EAKxD;EACA;EACA;EACA;EACA;EACD;GACA;CAAC;CAAO;CAAa;CAAU;CAAS,CAAC;AAE9C,4BAAe"}
@@ -0,0 +1,6 @@
1
+ export declare const getSelectControl: () => HTMLSelectElement;
2
+ export declare const getAllSelectControls: () => HTMLSelectElement[];
3
+ export declare const readSelectedLabel: (control: HTMLElement) => string;
4
+ export declare const chooseOption: (control: HTMLElement, optionLabel: string) => void;
5
+ export declare const changeEventWith: (value: string) => unknown;
6
+ //# sourceMappingURL=selectTestUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectTestUtils.d.ts","sourceRoot":"","sources":["../../../../../src/components/primitives/Select/__tests__/selectTestUtils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB,QAAO,iBAAoE,CAAC;AAEzG,eAAO,MAAM,oBAAoB,QAAO,iBAAiB,EAAwD,CAAC;AAElH,eAAO,MAAM,iBAAiB,GAAI,SAAS,WAAW,KAAG,MACa,CAAC;AAEvE,eAAO,MAAM,YAAY,GAAI,SAAS,WAAW,EAAE,aAAa,MAAM,KAAG,IAUxE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,OAI/C,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { SelectMessages } from '@thunderid/browser';
2
+ export type { SelectMessages };
3
+ /**
4
+ * The wording of `Select`: the active translations when there is an I18n provider, English otherwise, so `Select`
5
+ * works without a provider.
6
+ */
7
+ declare const useSelectMessages: () => SelectMessages;
8
+ export default useSelectMessages;
9
+ //# sourceMappingURL=useSelectMessages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSelectMessages.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Select/useSelectMessages.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAIvD,YAAY,EAAC,cAAc,EAAC,CAAC;AAE7B;;;GAGG;AACH,QAAA,MAAM,iBAAiB,QAAO,cAI7B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import I18nContext_default from "../../../contexts/I18n/I18nContext.js";
2
+ import { getSelectMessages } from "@thunderid/browser";
3
+ import { useContext, useMemo } from "react";
4
+
5
+ //#region src/components/primitives/Select/useSelectMessages.ts
6
+ /**
7
+ * The wording of `Select`: the active translations when there is an I18n provider, English otherwise, so `Select`
8
+ * works without a provider.
9
+ */
10
+ const useSelectMessages = () => {
11
+ const i18n = useContext(I18nContext_default);
12
+ return useMemo(() => getSelectMessages(i18n ? (key) => i18n.t(key) : void 0), [i18n]);
13
+ };
14
+ var useSelectMessages_default = useSelectMessages;
15
+
16
+ //#endregion
17
+ export { useSelectMessages_default as default };
18
+ //# sourceMappingURL=useSelectMessages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSelectMessages.js","names":["i18n: ContextType<typeof I18nContext>","I18nContext"],"sources":["../../../../src/components/primitives/Select/useSelectMessages.ts"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {getSelectMessages} from '@thunderid/browser';\nimport type {SelectMessages} from '@thunderid/browser';\nimport {ContextType, useContext, useMemo} from 'react';\nimport I18nContext from '../../../contexts/I18n/I18nContext';\n\nexport type {SelectMessages};\n\n/**\n * The wording of `Select`: the active translations when there is an I18n provider, English otherwise, so `Select`\n * works without a provider.\n */\nconst useSelectMessages = (): SelectMessages => {\n const i18n: ContextType<typeof I18nContext> = useContext(I18nContext);\n\n return useMemo((): SelectMessages => getSelectMessages(i18n ? (key: string) => i18n.t(key) : undefined), [i18n]);\n};\n\nexport default useSelectMessages;\n"],"mappings":";;;;;;;;;AAcA,MAAM,0BAA0C;CAC9C,MAAMA,OAAwC,WAAWC,oBAAY;AAErE,QAAO,cAA8B,kBAAkB,QAAQ,QAAgB,KAAK,EAAE,IAAI,GAAG,OAAU,EAAE,CAAC,KAAK,CAAC;;AAGlH,gCAAe"}
@@ -8,10 +8,18 @@ export interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElemen
8
8
  * Whether the field is disabled
9
9
  */
10
10
  disabled?: boolean;
11
+ /**
12
+ * Extra content shown inside the field, at its end after the end icon, such as an action button
13
+ */
14
+ endAdornment?: ReactNode;
11
15
  /**
12
16
  * Icon to display at the end (right) of the input
13
17
  */
14
18
  endIcon?: ReactNode;
19
+ /**
20
+ * Accessible name of the end icon when it is a button, that is when `onEndIconClick` is set
21
+ */
22
+ endIconLabel?: string;
15
23
  /**
16
24
  * Error message to display below the input
17
25
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TextField.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/TextField/TextField.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAC,EAAE,EAAE,mBAAmB,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AAOzD,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC9F;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,QAAA,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CA0FjC,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"TextField.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/TextField/TextField.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAC,EAAE,EAAE,mBAAmB,EAAiB,SAAS,EAAC,MAAM,OAAO,CAAC;AAOxE,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC9F;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAcD,QAAA,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAsGjC,CAAC;AAEF,eAAe,SAAS,CAAC"}