@thunderid/react 1.0.8 → 1.2.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 (230) hide show
  1. package/dist/api/updateMeCredentials.d.ts +33 -0
  2. package/dist/api/updateMeCredentials.d.ts.map +1 -0
  3. package/dist/api/updateMeCredentials.js +29 -0
  4. package/dist/api/updateMeCredentials.js.map +1 -0
  5. package/dist/cjs/api/updateMeCredentials.cjs +31 -0
  6. package/dist/cjs/api/updateMeCredentials.cjs.map +1 -0
  7. package/dist/cjs/components/presentation/ChangeCredential/BaseChangeCredential.cjs +187 -0
  8. package/dist/cjs/components/presentation/ChangeCredential/BaseChangeCredential.cjs.map +1 -0
  9. package/dist/cjs/components/presentation/ChangeCredential/BaseChangeCredential.styles.cjs +108 -0
  10. package/dist/cjs/components/presentation/ChangeCredential/BaseChangeCredential.styles.cjs.map +1 -0
  11. package/dist/cjs/components/presentation/ChangeCredential/ChangeCredential.cjs +123 -0
  12. package/dist/cjs/components/presentation/ChangeCredential/ChangeCredential.cjs.map +1 -0
  13. package/dist/cjs/components/presentation/LanguageSwitcher/BaseLanguageSwitcher.cjs +1 -1
  14. package/dist/cjs/components/presentation/UserDropdown/BaseUserDropdown.cjs +2 -2
  15. package/dist/cjs/components/presentation/UserDropdown/BaseUserDropdown.cjs.map +1 -1
  16. package/dist/cjs/components/presentation/UserDropdown/UserDropdown.cjs +8 -4
  17. package/dist/cjs/components/presentation/UserDropdown/UserDropdown.cjs.map +1 -1
  18. package/dist/cjs/components/presentation/UserProfile/BaseUserProfile.styles.cjs +2 -0
  19. package/dist/cjs/components/presentation/UserProfile/BaseUserProfile.styles.cjs.map +1 -1
  20. package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs +13 -0
  21. package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs.map +1 -1
  22. package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs +69 -66
  23. package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs.map +1 -1
  24. package/dist/cjs/components/primitives/KeyValueList/KeyValueList.cjs +41 -0
  25. package/dist/cjs/components/primitives/KeyValueList/KeyValueList.cjs.map +1 -0
  26. package/dist/cjs/components/primitives/KeyValueList/KeyValueList.styles.cjs +46 -0
  27. package/dist/cjs/components/primitives/KeyValueList/KeyValueList.styles.cjs.map +1 -0
  28. package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs +2 -2
  29. package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs.map +1 -1
  30. package/dist/cjs/contexts/Theme/ThemeProvider.cjs +26 -4
  31. package/dist/cjs/contexts/Theme/ThemeProvider.cjs.map +1 -1
  32. package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs +2 -0
  33. package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs.map +1 -1
  34. package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs +7 -1
  35. package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
  36. package/dist/cjs/hooks/agents/useCreateAgent.cjs +26 -0
  37. package/dist/cjs/hooks/agents/useCreateAgent.cjs.map +1 -0
  38. package/dist/cjs/hooks/agents/useDeleteAgent.cjs +26 -0
  39. package/dist/cjs/hooks/agents/useDeleteAgent.cjs.map +1 -0
  40. package/dist/cjs/hooks/agents/useGetAgent.cjs +30 -0
  41. package/dist/cjs/hooks/agents/useGetAgent.cjs.map +1 -0
  42. package/dist/cjs/hooks/agents/useGetAgents.cjs +31 -0
  43. package/dist/cjs/hooks/agents/useGetAgents.cjs.map +1 -0
  44. package/dist/cjs/hooks/agents/useUpdateAgent.cjs +27 -0
  45. package/dist/cjs/hooks/agents/useUpdateAgent.cjs.map +1 -0
  46. package/dist/cjs/hooks/applications/useCreateApplication.cjs +31 -0
  47. package/dist/cjs/hooks/applications/useCreateApplication.cjs.map +1 -0
  48. package/dist/cjs/hooks/applications/useDeleteApplication.cjs +26 -0
  49. package/dist/cjs/hooks/applications/useDeleteApplication.cjs.map +1 -0
  50. package/dist/cjs/hooks/applications/useGetApplication.cjs +35 -0
  51. package/dist/cjs/hooks/applications/useGetApplication.cjs.map +1 -0
  52. package/dist/cjs/hooks/applications/useGetApplications.cjs +36 -0
  53. package/dist/cjs/hooks/applications/useGetApplications.cjs.map +1 -0
  54. package/dist/cjs/hooks/applications/useUpdateApplication.cjs +27 -0
  55. package/dist/cjs/hooks/applications/useUpdateApplication.cjs.map +1 -0
  56. package/dist/cjs/hooks/useManagementEndpoint.cjs +25 -0
  57. package/dist/cjs/hooks/useManagementEndpoint.cjs.map +1 -0
  58. package/dist/cjs/hooks/useResourceMutation.cjs +72 -0
  59. package/dist/cjs/hooks/useResourceMutation.cjs.map +1 -0
  60. package/dist/cjs/hooks/useResourceQuery.cjs +86 -0
  61. package/dist/cjs/hooks/useResourceQuery.cjs.map +1 -0
  62. package/dist/cjs/hooks/users/useCreateUser.cjs +26 -0
  63. package/dist/cjs/hooks/users/useCreateUser.cjs.map +1 -0
  64. package/dist/cjs/hooks/users/useDeleteUser.cjs +26 -0
  65. package/dist/cjs/hooks/users/useDeleteUser.cjs.map +1 -0
  66. package/dist/cjs/hooks/users/useGetUser.cjs +30 -0
  67. package/dist/cjs/hooks/users/useGetUser.cjs.map +1 -0
  68. package/dist/cjs/hooks/users/useGetUsers.cjs +38 -0
  69. package/dist/cjs/hooks/users/useGetUsers.cjs.map +1 -0
  70. package/dist/cjs/hooks/users/useUpdateUser.cjs +27 -0
  71. package/dist/cjs/hooks/users/useUpdateUser.cjs.map +1 -0
  72. package/dist/cjs/index.cjs +152 -0
  73. package/dist/cjs/utils/createAuthenticatedFetcher.cjs +43 -0
  74. package/dist/cjs/utils/createAuthenticatedFetcher.cjs.map +1 -0
  75. package/dist/cjs/utils/createResourceInvalidator.cjs +38 -0
  76. package/dist/cjs/utils/createResourceInvalidator.cjs.map +1 -0
  77. package/dist/components/actions/SignInButton/BaseSignInButton.js +2 -2
  78. package/dist/components/actions/SignInButton/BaseSignInButton.js.map +1 -1
  79. package/dist/components/actions/SignOutButton/BaseSignOutButton.js +2 -2
  80. package/dist/components/actions/SignOutButton/BaseSignOutButton.js.map +1 -1
  81. package/dist/components/actions/SignUpButton/BaseSignUpButton.js +2 -2
  82. package/dist/components/actions/SignUpButton/BaseSignUpButton.js.map +1 -1
  83. package/dist/components/adapters/FlowTimer.js +2 -2
  84. package/dist/components/adapters/FlowTimer.js.map +1 -1
  85. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.d.ts +100 -0
  86. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.d.ts.map +1 -0
  87. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.js +183 -0
  88. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.js.map +1 -0
  89. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.styles.d.ts +10 -0
  90. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.styles.d.ts.map +1 -0
  91. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.styles.js +108 -0
  92. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.styles.js.map +1 -0
  93. package/dist/components/presentation/ChangeCredential/ChangeCredential.d.ts +55 -0
  94. package/dist/components/presentation/ChangeCredential/ChangeCredential.d.ts.map +1 -0
  95. package/dist/components/presentation/ChangeCredential/ChangeCredential.js +119 -0
  96. package/dist/components/presentation/ChangeCredential/ChangeCredential.js.map +1 -0
  97. package/dist/components/presentation/LanguageSwitcher/BaseLanguageSwitcher.js +3 -3
  98. package/dist/components/presentation/LanguageSwitcher/BaseLanguageSwitcher.js.map +1 -1
  99. package/dist/components/presentation/UserDropdown/BaseUserDropdown.d.ts +5 -0
  100. package/dist/components/presentation/UserDropdown/BaseUserDropdown.d.ts.map +1 -1
  101. package/dist/components/presentation/UserDropdown/BaseUserDropdown.js +2 -2
  102. package/dist/components/presentation/UserDropdown/BaseUserDropdown.js.map +1 -1
  103. package/dist/components/presentation/UserDropdown/UserDropdown.d.ts +12 -0
  104. package/dist/components/presentation/UserDropdown/UserDropdown.d.ts.map +1 -1
  105. package/dist/components/presentation/UserDropdown/UserDropdown.js +11 -7
  106. package/dist/components/presentation/UserDropdown/UserDropdown.js.map +1 -1
  107. package/dist/components/presentation/UserProfile/BaseUserProfile.js +8 -8
  108. package/dist/components/presentation/UserProfile/BaseUserProfile.js.map +1 -1
  109. package/dist/components/presentation/UserProfile/BaseUserProfile.styles.d.ts.map +1 -1
  110. package/dist/components/presentation/UserProfile/BaseUserProfile.styles.js +2 -0
  111. package/dist/components/presentation/UserProfile/BaseUserProfile.styles.js.map +1 -1
  112. package/dist/components/presentation/auth/AuthOptionFactory.d.ts.map +1 -1
  113. package/dist/components/presentation/auth/AuthOptionFactory.js +14 -1
  114. package/dist/components/presentation/auth/AuthOptionFactory.js.map +1 -1
  115. package/dist/components/presentation/auth/SignIn/SignIn.js +2 -2
  116. package/dist/components/presentation/auth/SignIn/SignIn.js.map +1 -1
  117. package/dist/components/presentation/auth/SignUp/BaseSignUp.d.ts.map +1 -1
  118. package/dist/components/presentation/auth/SignUp/BaseSignUp.js +69 -66
  119. package/dist/components/presentation/auth/SignUp/BaseSignUp.js.map +1 -1
  120. package/dist/components/primitives/AffixedField/AffixedField.js +2 -2
  121. package/dist/components/primitives/AffixedField/AffixedField.js.map +1 -1
  122. package/dist/components/primitives/KeyValueList/KeyValueList.d.ts +19 -0
  123. package/dist/components/primitives/KeyValueList/KeyValueList.d.ts.map +1 -0
  124. package/dist/components/primitives/KeyValueList/KeyValueList.js +38 -0
  125. package/dist/components/primitives/KeyValueList/KeyValueList.js.map +1 -0
  126. package/dist/components/primitives/KeyValueList/KeyValueList.styles.d.ts +4 -0
  127. package/dist/components/primitives/KeyValueList/KeyValueList.styles.d.ts.map +1 -0
  128. package/dist/components/primitives/KeyValueList/KeyValueList.styles.js +44 -0
  129. package/dist/components/primitives/KeyValueList/KeyValueList.styles.js.map +1 -0
  130. package/dist/components/primitives/PasswordField/PasswordField.d.ts +6 -0
  131. package/dist/components/primitives/PasswordField/PasswordField.d.ts.map +1 -1
  132. package/dist/components/primitives/PasswordField/PasswordField.js +2 -2
  133. package/dist/components/primitives/PasswordField/PasswordField.js.map +1 -1
  134. package/dist/contexts/Theme/ThemeProvider.d.ts +1 -1
  135. package/dist/contexts/Theme/ThemeProvider.d.ts.map +1 -1
  136. package/dist/contexts/Theme/ThemeProvider.js +27 -5
  137. package/dist/contexts/Theme/ThemeProvider.js.map +1 -1
  138. package/dist/contexts/ThunderID/ThunderIDContext.d.ts +12 -1
  139. package/dist/contexts/ThunderID/ThunderIDContext.d.ts.map +1 -1
  140. package/dist/contexts/ThunderID/ThunderIDContext.js +2 -0
  141. package/dist/contexts/ThunderID/ThunderIDContext.js.map +1 -1
  142. package/dist/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
  143. package/dist/contexts/ThunderID/ThunderIDProvider.js +7 -1
  144. package/dist/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
  145. package/dist/hooks/agents/useCreateAgent.d.ts +11 -0
  146. package/dist/hooks/agents/useCreateAgent.d.ts.map +1 -0
  147. package/dist/hooks/agents/useCreateAgent.js +24 -0
  148. package/dist/hooks/agents/useCreateAgent.js.map +1 -0
  149. package/dist/hooks/agents/useDeleteAgent.d.ts +10 -0
  150. package/dist/hooks/agents/useDeleteAgent.d.ts.map +1 -0
  151. package/dist/hooks/agents/useDeleteAgent.js +24 -0
  152. package/dist/hooks/agents/useDeleteAgent.js.map +1 -0
  153. package/dist/hooks/agents/useGetAgent.d.ts +12 -0
  154. package/dist/hooks/agents/useGetAgent.d.ts.map +1 -0
  155. package/dist/hooks/agents/useGetAgent.js +28 -0
  156. package/dist/hooks/agents/useGetAgent.js.map +1 -0
  157. package/dist/hooks/agents/useGetAgents.d.ts +19 -0
  158. package/dist/hooks/agents/useGetAgents.d.ts.map +1 -0
  159. package/dist/hooks/agents/useGetAgents.js +29 -0
  160. package/dist/hooks/agents/useGetAgents.js.map +1 -0
  161. package/dist/hooks/agents/useUpdateAgent.d.ts +18 -0
  162. package/dist/hooks/agents/useUpdateAgent.d.ts.map +1 -0
  163. package/dist/hooks/agents/useUpdateAgent.js +25 -0
  164. package/dist/hooks/agents/useUpdateAgent.js.map +1 -0
  165. package/dist/hooks/applications/useCreateApplication.d.ts +16 -0
  166. package/dist/hooks/applications/useCreateApplication.d.ts.map +1 -0
  167. package/dist/hooks/applications/useCreateApplication.js +29 -0
  168. package/dist/hooks/applications/useCreateApplication.js.map +1 -0
  169. package/dist/hooks/applications/useDeleteApplication.d.ts +10 -0
  170. package/dist/hooks/applications/useDeleteApplication.d.ts.map +1 -0
  171. package/dist/hooks/applications/useDeleteApplication.js +24 -0
  172. package/dist/hooks/applications/useDeleteApplication.js.map +1 -0
  173. package/dist/hooks/applications/useGetApplication.d.ts +17 -0
  174. package/dist/hooks/applications/useGetApplication.d.ts.map +1 -0
  175. package/dist/hooks/applications/useGetApplication.js +33 -0
  176. package/dist/hooks/applications/useGetApplication.js.map +1 -0
  177. package/dist/hooks/applications/useGetApplications.d.ts +24 -0
  178. package/dist/hooks/applications/useGetApplications.d.ts.map +1 -0
  179. package/dist/hooks/applications/useGetApplications.js +34 -0
  180. package/dist/hooks/applications/useGetApplications.js.map +1 -0
  181. package/dist/hooks/applications/useUpdateApplication.d.ts +18 -0
  182. package/dist/hooks/applications/useUpdateApplication.d.ts.map +1 -0
  183. package/dist/hooks/applications/useUpdateApplication.js +25 -0
  184. package/dist/hooks/applications/useUpdateApplication.js.map +1 -0
  185. package/dist/hooks/useManagementEndpoint.d.ts +22 -0
  186. package/dist/hooks/useManagementEndpoint.d.ts.map +1 -0
  187. package/dist/hooks/useManagementEndpoint.js +23 -0
  188. package/dist/hooks/useManagementEndpoint.js.map +1 -0
  189. package/dist/hooks/useResourceMutation.d.ts +51 -0
  190. package/dist/hooks/useResourceMutation.d.ts.map +1 -0
  191. package/dist/hooks/useResourceMutation.js +70 -0
  192. package/dist/hooks/useResourceMutation.js.map +1 -0
  193. package/dist/hooks/useResourceQuery.d.ts +45 -0
  194. package/dist/hooks/useResourceQuery.d.ts.map +1 -0
  195. package/dist/hooks/useResourceQuery.js +83 -0
  196. package/dist/hooks/useResourceQuery.js.map +1 -0
  197. package/dist/hooks/users/useCreateUser.d.ts +11 -0
  198. package/dist/hooks/users/useCreateUser.d.ts.map +1 -0
  199. package/dist/hooks/users/useCreateUser.js +24 -0
  200. package/dist/hooks/users/useCreateUser.js.map +1 -0
  201. package/dist/hooks/users/useDeleteUser.d.ts +10 -0
  202. package/dist/hooks/users/useDeleteUser.d.ts.map +1 -0
  203. package/dist/hooks/users/useDeleteUser.js +24 -0
  204. package/dist/hooks/users/useDeleteUser.js.map +1 -0
  205. package/dist/hooks/users/useGetUser.d.ts +12 -0
  206. package/dist/hooks/users/useGetUser.d.ts.map +1 -0
  207. package/dist/hooks/users/useGetUser.js +28 -0
  208. package/dist/hooks/users/useGetUser.js.map +1 -0
  209. package/dist/hooks/users/useGetUsers.d.ts +17 -0
  210. package/dist/hooks/users/useGetUsers.d.ts.map +1 -0
  211. package/dist/hooks/users/useGetUsers.js +36 -0
  212. package/dist/hooks/users/useGetUsers.js.map +1 -0
  213. package/dist/hooks/users/useUpdateUser.d.ts +18 -0
  214. package/dist/hooks/users/useUpdateUser.d.ts.map +1 -0
  215. package/dist/hooks/users/useUpdateUser.js +25 -0
  216. package/dist/hooks/users/useUpdateUser.js.map +1 -0
  217. package/dist/index.d.ts +32 -1
  218. package/dist/index.d.ts.map +1 -1
  219. package/dist/index.js +21 -2
  220. package/dist/models/config.d.ts +13 -1
  221. package/dist/models/config.d.ts.map +1 -1
  222. package/dist/utils/createAuthenticatedFetcher.d.ts +14 -0
  223. package/dist/utils/createAuthenticatedFetcher.d.ts.map +1 -0
  224. package/dist/utils/createAuthenticatedFetcher.js +41 -0
  225. package/dist/utils/createAuthenticatedFetcher.js.map +1 -0
  226. package/dist/utils/createResourceInvalidator.d.ts +29 -0
  227. package/dist/utils/createResourceInvalidator.d.ts.map +1 -0
  228. package/dist/utils/createResourceInvalidator.js +36 -0
  229. package/dist/utils/createResourceInvalidator.js.map +1 -0
  230. package/package.json +4 -4
@@ -0,0 +1,183 @@
1
+ import { cx } from "../../../styles/emotion.js";
2
+ import useTheme_default from "../../../contexts/Theme/useTheme.js";
3
+ import useTranslation_default from "../../../hooks/useTranslation.js";
4
+ import Button_default from "../../primitives/Button/Button.js";
5
+ import Typography_default from "../../primitives/Typography/Typography.js";
6
+ import Alert_default from "../../primitives/Alert/Alert.js";
7
+ import X_default from "../../primitives/Icons/X.js";
8
+ import PasswordField_default from "../../primitives/PasswordField/PasswordField.js";
9
+ import BaseChangeCredential_styles_default from "./BaseChangeCredential.styles.js";
10
+ import Check_default from "../../primitives/Icons/Check.js";
11
+ import { bem, evaluateChangePasswordForm, withVendorCSSClassPrefix } from "@thunderid/browser";
12
+ import { useMemo, useState } from "react";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+
15
+ //#region src/components/presentation/ChangeCredential/BaseChangeCredential.tsx
16
+ /**
17
+ * Presentational change-credential form with just the two fields a first-time or
18
+ * unverified credential change needs: new value and confirmation.
19
+ *
20
+ * Holds no context and performs no network calls: it renders the fields, evaluates the
21
+ * policy for the checklist and the submit gate, and hands validated values to `onSubmit`.
22
+ * Use {@link ChangeCredential} for the context-wired variant.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <BaseChangeCredential
27
+ * policy={{regex: '^.{12,}$'}}
28
+ * onSubmit={({newPassword}) => save(newPassword)}
29
+ * />
30
+ * ```
31
+ */
32
+ const BaseChangeCredential = ({ cardLayout = false, className = "", credentialDisplayName = "Password", error = null, fieldErrors = {}, loading = false, onSubmit = void 0, policy = {}, preferences = void 0, showRequirements = true, success = false, title = void 0, unavailable = false }) => {
33
+ const { theme, colorScheme } = useTheme_default();
34
+ const styles = BaseChangeCredential_styles_default(theme, colorScheme);
35
+ const { t } = useTranslation_default(preferences?.i18n);
36
+ const labelParams = {
37
+ credential: credentialDisplayName,
38
+ credentialLower: credentialDisplayName.toLowerCase()
39
+ };
40
+ const resolvedTitle = title ?? t("user.change_password.heading", labelParams);
41
+ const [newPassword, setNewPassword] = useState("");
42
+ const [confirmPassword, setConfirmPassword] = useState("");
43
+ const [submitted, setSubmitted] = useState(false);
44
+ const [prevSuccess, setPrevSuccess] = useState(success);
45
+ if (success !== prevSuccess) {
46
+ setPrevSuccess(success);
47
+ if (success) {
48
+ setNewPassword("");
49
+ setConfirmPassword("");
50
+ setSubmitted(false);
51
+ }
52
+ }
53
+ const { confirmMatches, isValid, ruleResults } = useMemo(() => evaluateChangePasswordForm({
54
+ confirmPassword,
55
+ newPassword
56
+ }, policy), [
57
+ confirmPassword,
58
+ newPassword,
59
+ policy
60
+ ]);
61
+ const interactionDisabled = loading || unavailable;
62
+ const canSubmit = !interactionDisabled && isValid;
63
+ const handleSubmit = (event) => {
64
+ event.preventDefault();
65
+ setSubmitted(true);
66
+ if (!canSubmit) return;
67
+ onSubmit?.({ newPassword });
68
+ };
69
+ const renderRequirement = (rule) => /* @__PURE__ */ jsxs("li", {
70
+ "data-passed": rule.passed,
71
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "requirement")), styles["requirement"], rule.passed ? styles["requirementPassed"] : styles["requirementPending"]),
72
+ children: [/* @__PURE__ */ jsx("span", {
73
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "requirement-icon")), styles["requirementIcon"]),
74
+ children: rule.passed ? /* @__PURE__ */ jsx(Check_default, {
75
+ width: 14,
76
+ height: 14
77
+ }) : /* @__PURE__ */ jsx(X_default, {
78
+ width: 14,
79
+ height: 14
80
+ })
81
+ }), /* @__PURE__ */ jsx(Typography_default, {
82
+ variant: "body2",
83
+ component: "span",
84
+ children: t(rule.messageKey, rule.params)
85
+ })]
86
+ }, rule.key);
87
+ const confirmError = submitted && !confirmMatches ? t("user.change_password.mismatch.error", labelParams) : void 0;
88
+ const newPasswordError = fieldErrors["newPassword"];
89
+ const form = /* @__PURE__ */ jsxs("form", {
90
+ noValidate: true,
91
+ onSubmit: handleSubmit,
92
+ className: cx(withVendorCSSClassPrefix("change-credential"), styles["root"], cardLayout ? styles["card"] : "", className),
93
+ children: [
94
+ resolvedTitle && /* @__PURE__ */ jsx(Typography_default, {
95
+ variant: "h5",
96
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "heading")), styles["heading"]),
97
+ children: resolvedTitle
98
+ }),
99
+ error && /* @__PURE__ */ jsxs(Alert_default, {
100
+ variant: "error",
101
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "alert")), styles["alert"]),
102
+ children: [/* @__PURE__ */ jsx(Alert_default.Title, { children: t("errors.heading") || "Error" }), /* @__PURE__ */ jsx(Alert_default.Description, { children: error })]
103
+ }),
104
+ success && /* @__PURE__ */ jsx(Alert_default, {
105
+ variant: "success",
106
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "alert")), styles["alert"]),
107
+ children: /* @__PURE__ */ jsx(Alert_default.Description, { children: t("user.change_password.success", labelParams) })
108
+ }),
109
+ /* @__PURE__ */ jsxs("div", {
110
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "fields")), styles["fields"]),
111
+ children: [
112
+ /* @__PURE__ */ jsx(PasswordField_default, {
113
+ name: "newPassword",
114
+ autoComplete: "new-password",
115
+ label: t("user.change_password.new.label", labelParams),
116
+ placeholder: t("user.change_password.new.placeholder", labelParams),
117
+ value: newPassword,
118
+ onChange: setNewPassword,
119
+ disabled: interactionDisabled,
120
+ error: newPasswordError,
121
+ required: true
122
+ }),
123
+ showRequirements && ruleResults.length > 0 && /* @__PURE__ */ jsxs("div", {
124
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "requirements"))),
125
+ children: [/* @__PURE__ */ jsx(Typography_default, {
126
+ variant: "body2",
127
+ component: "p",
128
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "requirements-heading")), styles["requirementsHeading"]),
129
+ children: t("user.change_password.requirements.heading", labelParams)
130
+ }), /* @__PURE__ */ jsx("ul", {
131
+ className: styles["requirements"],
132
+ children: ruleResults.map(renderRequirement)
133
+ })]
134
+ }),
135
+ /* @__PURE__ */ jsx(PasswordField_default, {
136
+ name: "confirmPassword",
137
+ autoComplete: "new-password",
138
+ label: t("user.change_password.confirm.label", labelParams),
139
+ placeholder: t("user.change_password.confirm.placeholder", labelParams),
140
+ value: confirmPassword,
141
+ onChange: setConfirmPassword,
142
+ disabled: interactionDisabled,
143
+ error: confirmError,
144
+ required: true
145
+ })
146
+ ]
147
+ }),
148
+ /* @__PURE__ */ jsx("div", {
149
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "actions")), styles["actions"]),
150
+ children: /* @__PURE__ */ jsx(Button_default, {
151
+ type: "submit",
152
+ color: "primary",
153
+ variant: "solid",
154
+ loading,
155
+ disabled: !canSubmit,
156
+ children: t("user.change_password.submit", labelParams)
157
+ })
158
+ })
159
+ ]
160
+ });
161
+ if (!unavailable) return form;
162
+ return /* @__PURE__ */ jsxs("div", {
163
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "unavailable")), styles["unavailableRoot"], className),
164
+ children: [/* @__PURE__ */ jsx("div", {
165
+ "aria-hidden": "true",
166
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "unavailable-content")), styles["unavailableContent"]),
167
+ children: form
168
+ }), /* @__PURE__ */ jsx("div", {
169
+ role: "status",
170
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "unavailable-overlay")), styles["unavailableOverlay"]),
171
+ children: /* @__PURE__ */ jsxs(Alert_default, {
172
+ variant: "warning",
173
+ className: cx(withVendorCSSClassPrefix(bem("change-credential", "alert")), styles["alert"]),
174
+ children: [/* @__PURE__ */ jsx(Alert_default.Title, { children: t("user.change_password.unavailable.heading", labelParams) }), /* @__PURE__ */ jsx(Alert_default.Description, { children: t("user.change_password.unavailable.description", labelParams) })]
175
+ })
176
+ })]
177
+ });
178
+ };
179
+ var BaseChangeCredential_default = BaseChangeCredential;
180
+
181
+ //#endregion
182
+ export { BaseChangeCredential_default as default };
183
+ //# sourceMappingURL=BaseChangeCredential.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseChangeCredential.js","names":["BaseChangeCredential: FC<BaseChangeCredentialProps>","useTheme","styles: Record<string, string>","useStyles","useTranslation","labelParams: Record<string, string>","resolvedTitle: string","interactionDisabled: boolean","canSubmit: boolean","Check","X","Typography","confirmError: string | undefined","newPasswordError: string | undefined","form: ReactElement","AlertPrimitive","PasswordField","Button"],"sources":["../../../../src/components/presentation/ChangeCredential/BaseChangeCredential.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ChangePasswordFormEvaluation,\n PasswordPolicy,\n PasswordRuleResult,\n Preferences,\n bem,\n evaluateChangePasswordForm,\n withVendorCSSClassPrefix,\n} from '@thunderid/browser';\nimport {FC, FormEvent, ReactElement, useMemo, useState} from 'react';\nimport useStyles from './BaseChangeCredential.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\nimport Button from '../../primitives/Button/Button';\nimport Check from '../../primitives/Icons/Check';\nimport X from '../../primitives/Icons/X';\nimport PasswordField from '../../primitives/PasswordField/PasswordField';\nimport Typography from '../../primitives/Typography/Typography';\n\n/**\n * The values collected by the form and handed to `onSubmit`.\n *\n * There is deliberately no current-value field here. The self-service credential write\n * endpoint does not verify the account's existing value today, so a field the server\n * ignores would only teach the user a false sense of security.\n */\nexport interface ChangePasswordValues {\n /**\n * The value to set.\n */\n newPassword: string;\n}\n\nexport interface BaseChangeCredentialProps {\n /**\n * Whether to wrap the form in a bordered card.\n */\n cardLayout?: boolean;\n /**\n * Additional CSS class names\n */\n className?: string;\n /**\n * The human-readable name of the credential, substituted into every default label,\n * placeholder and message (for example \"Change {credential}\", \"New {credential}\").\n * Defaults to `Password`. {@link ChangeCredential} resolves this from the attribute's own\n * `displayName` in the user schema; set it directly here when using this presentational\n * component without that context.\n */\n credentialDisplayName?: string;\n /**\n * A form-level error, typically a server failure that maps to no single field.\n */\n error?: string | null;\n /**\n * Server-supplied errors keyed by field name (`newPassword`).\n */\n fieldErrors?: Record<string, string>;\n /**\n * Whether a submission is in flight.\n */\n loading?: boolean;\n /**\n * Called with the collected values once client-side validation passes.\n */\n onSubmit?: (values: ChangePasswordValues) => void;\n /**\n * The rules the new value must satisfy. Defaults to no rules, in which case the checklist\n * is empty and the only submit gate is a non-empty value; the caller is expected to source\n * this from the user type schema (see {@link ChangeCredential}) or supply its own.\n */\n policy?: PasswordPolicy;\n /**\n * Component-level preference overrides, including i18n.\n */\n preferences?: Preferences;\n /**\n * Whether to render the live requirement checklist. Defaults to `true`.\n */\n showRequirements?: boolean;\n /**\n * Whether the last submission succeeded.\n */\n success?: boolean;\n /**\n * Overrides the default \"Change {credential}\" heading. Pass an empty string to omit the\n * heading entirely, for example when an app's own surrounding layout (a card header, a\n * dialog title) already names the credential and a second heading would be redundant.\n * Defaults to the translated `user.change_password.heading` string.\n */\n title?: string;\n /**\n * Whether the account cannot have this credential changed at all, because the user type's\n * schema defines no attribute of this name. The form is rendered inert behind an\n * explanatory message rather than hidden, so an integrator who placed the component can see\n * why it is not usable instead of finding an empty space.\n */\n unavailable?: boolean;\n}\n\n/**\n * Presentational change-credential form with just the two fields a first-time or\n * unverified credential change needs: new value and confirmation.\n *\n * Holds no context and performs no network calls: it renders the fields, evaluates the\n * policy for the checklist and the submit gate, and hands validated values to `onSubmit`.\n * Use {@link ChangeCredential} for the context-wired variant.\n *\n * @example\n * ```tsx\n * <BaseChangeCredential\n * policy={{regex: '^.{12,}$'}}\n * onSubmit={({newPassword}) => save(newPassword)}\n * />\n * ```\n */\nconst BaseChangeCredential: FC<BaseChangeCredentialProps> = ({\n cardLayout = false,\n className = '',\n credentialDisplayName = 'Password',\n error = null,\n fieldErrors = {},\n loading = false,\n onSubmit = undefined,\n policy = {},\n preferences = undefined,\n showRequirements = true,\n success = false,\n title = undefined,\n unavailable = false,\n}: BaseChangeCredentialProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme);\n const {t} = useTranslation(preferences?.i18n);\n\n // Substituted into every default label, placeholder and message. A caller-supplied\n // translation that carries no `{credential}`/`{credentialLower}` placeholder is unaffected.\n const labelParams: Record<string, string> = {\n credential: credentialDisplayName,\n credentialLower: credentialDisplayName.toLowerCase(),\n };\n\n // `title` overrides the default heading; an explicit empty string omits it entirely.\n const resolvedTitle: string = title ?? t('user.change_password.heading', labelParams);\n\n const [newPassword, setNewPassword] = useState<string>('');\n const [confirmPassword, setConfirmPassword] = useState<string>('');\n const [submitted, setSubmitted] = useState<boolean>(false);\n\n // Clear the entered values once the container reports the write succeeded, so a shared\n // machine is not left with the new credential sitting in the form. Adjusting state during\n // render (rather than in an effect) is React's documented way to reset on a prop change and\n // avoids the extra commit an effect would cause.\n const [prevSuccess, setPrevSuccess] = useState<boolean>(success);\n\n if (success !== prevSuccess) {\n setPrevSuccess(success);\n\n if (success) {\n setNewPassword('');\n setConfirmPassword('');\n setSubmitted(false);\n }\n }\n\n const {confirmMatches, isValid, ruleResults}: ChangePasswordFormEvaluation = useMemo(\n () => evaluateChangePasswordForm({confirmPassword, newPassword}, policy),\n [confirmPassword, newPassword, policy],\n );\n\n // A schema with no attribute of this name makes every control pointless, so they are\n // disabled outright rather than left focusable behind the overlay.\n const interactionDisabled: boolean = loading || unavailable;\n const canSubmit: boolean = !interactionDisabled && isValid;\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault();\n setSubmitted(true);\n\n if (!canSubmit) {\n return;\n }\n\n onSubmit?.({newPassword});\n };\n\n const renderRequirement = (rule: PasswordRuleResult): ReactElement => (\n <li\n key={rule.key}\n data-passed={rule.passed}\n className={cx(\n withVendorCSSClassPrefix(bem('change-credential', 'requirement')),\n styles['requirement'],\n rule.passed ? styles['requirementPassed'] : styles['requirementPending'],\n )}\n >\n <span\n className={cx(\n withVendorCSSClassPrefix(bem('change-credential', 'requirement-icon')),\n styles['requirementIcon'],\n )}\n >\n {rule.passed ? <Check width={14} height={14} /> : <X width={14} height={14} />}\n </span>\n <Typography variant=\"body2\" component=\"span\">\n {t(rule.messageKey, rule.params)}\n </Typography>\n </li>\n );\n\n // Only surface the local error once the user has attempted a submit, so the form does\n // not flag fields the user has not finished filling in.\n const confirmError: string | undefined =\n submitted && !confirmMatches ? t('user.change_password.mismatch.error', labelParams) : undefined;\n const newPasswordError: string | undefined = fieldErrors['newPassword'];\n\n const form: ReactElement = (\n <form\n noValidate\n onSubmit={handleSubmit}\n className={cx(\n withVendorCSSClassPrefix('change-credential'),\n styles['root'],\n cardLayout ? styles['card'] : '',\n className,\n )}\n >\n {resolvedTitle && (\n <Typography\n variant=\"h5\"\n className={cx(withVendorCSSClassPrefix(bem('change-credential', 'heading')), styles['heading'])}\n >\n {resolvedTitle}\n </Typography>\n )}\n\n {error && (\n <AlertPrimitive\n variant=\"error\"\n className={cx(withVendorCSSClassPrefix(bem('change-credential', 'alert')), styles['alert'])}\n >\n <AlertPrimitive.Title>{t('errors.heading') || 'Error'}</AlertPrimitive.Title>\n <AlertPrimitive.Description>{error}</AlertPrimitive.Description>\n </AlertPrimitive>\n )}\n\n {success && (\n <AlertPrimitive\n variant=\"success\"\n className={cx(withVendorCSSClassPrefix(bem('change-credential', 'alert')), styles['alert'])}\n >\n <AlertPrimitive.Description>{t('user.change_password.success', labelParams)}</AlertPrimitive.Description>\n </AlertPrimitive>\n )}\n\n <div className={cx(withVendorCSSClassPrefix(bem('change-credential', 'fields')), styles['fields'])}>\n <PasswordField\n name=\"newPassword\"\n autoComplete=\"new-password\"\n label={t('user.change_password.new.label', labelParams)}\n placeholder={t('user.change_password.new.placeholder', labelParams)}\n value={newPassword}\n onChange={setNewPassword}\n disabled={interactionDisabled}\n error={newPasswordError}\n required\n />\n\n {showRequirements && ruleResults.length > 0 && (\n <div className={cx(withVendorCSSClassPrefix(bem('change-credential', 'requirements')))}>\n <Typography\n variant=\"body2\"\n component=\"p\"\n className={cx(\n withVendorCSSClassPrefix(bem('change-credential', 'requirements-heading')),\n styles['requirementsHeading'],\n )}\n >\n {t('user.change_password.requirements.heading', labelParams)}\n </Typography>\n <ul className={styles['requirements']}>{ruleResults.map(renderRequirement)}</ul>\n </div>\n )}\n\n <PasswordField\n name=\"confirmPassword\"\n autoComplete=\"new-password\"\n label={t('user.change_password.confirm.label', labelParams)}\n placeholder={t('user.change_password.confirm.placeholder', labelParams)}\n value={confirmPassword}\n onChange={setConfirmPassword}\n disabled={interactionDisabled}\n error={confirmError}\n required\n />\n </div>\n\n <div className={cx(withVendorCSSClassPrefix(bem('change-credential', 'actions')), styles['actions'])}>\n <Button type=\"submit\" color=\"primary\" variant=\"solid\" loading={loading} disabled={!canSubmit}>\n {t('user.change_password.submit', labelParams)}\n </Button>\n </div>\n </form>\n );\n\n if (!unavailable) {\n return form;\n }\n\n return (\n <div\n className={cx(\n withVendorCSSClassPrefix(bem('change-credential', 'unavailable')),\n styles['unavailableRoot'],\n className,\n )}\n >\n <div\n aria-hidden=\"true\"\n className={cx(\n withVendorCSSClassPrefix(bem('change-credential', 'unavailable-content')),\n styles['unavailableContent'],\n )}\n >\n {form}\n </div>\n\n <div\n role=\"status\"\n className={cx(\n withVendorCSSClassPrefix(bem('change-credential', 'unavailable-overlay')),\n styles['unavailableOverlay'],\n )}\n >\n <AlertPrimitive\n variant=\"warning\"\n className={cx(withVendorCSSClassPrefix(bem('change-credential', 'alert')), styles['alert'])}\n >\n <AlertPrimitive.Title>{t('user.change_password.unavailable.heading', labelParams)}</AlertPrimitive.Title>\n <AlertPrimitive.Description>\n {t('user.change_password.unavailable.description', labelParams)}\n </AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n </div>\n );\n};\n\nexport default BaseChangeCredential;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyHA,MAAMA,wBAAuD,EAC3D,aAAa,OACb,YAAY,IACZ,wBAAwB,YACxB,QAAQ,MACR,cAAc,EAAE,EAChB,UAAU,OACV,WAAW,QACX,SAAS,EAAE,EACX,cAAc,QACd,mBAAmB,MACnB,UAAU,OACV,QAAQ,QACR,cAAc,YACiB;CAC/B,MAAM,EAAC,OAAO,gBAA4CC,kBAAU;CACpE,MAAMC,SAAiCC,oCAAU,OAAO,YAAY;CACpE,MAAM,EAAC,MAAKC,uBAAe,aAAa,KAAK;CAI7C,MAAMC,cAAsC;EAC1C,YAAY;EACZ,iBAAiB,sBAAsB,aAAa;EACrD;CAGD,MAAMC,gBAAwB,SAAS,EAAE,gCAAgC,YAAY;CAErF,MAAM,CAAC,aAAa,kBAAkB,SAAiB,GAAG;CAC1D,MAAM,CAAC,iBAAiB,sBAAsB,SAAiB,GAAG;CAClE,MAAM,CAAC,WAAW,gBAAgB,SAAkB,MAAM;CAM1D,MAAM,CAAC,aAAa,kBAAkB,SAAkB,QAAQ;AAEhE,KAAI,YAAY,aAAa;AAC3B,iBAAe,QAAQ;AAEvB,MAAI,SAAS;AACX,kBAAe,GAAG;AAClB,sBAAmB,GAAG;AACtB,gBAAa,MAAM;;;CAIvB,MAAM,EAAC,gBAAgB,SAAS,gBAA6C,cACrE,2BAA2B;EAAC;EAAiB;EAAY,EAAE,OAAO,EACxE;EAAC;EAAiB;EAAa;EAAO,CACvC;CAID,MAAMC,sBAA+B,WAAW;CAChD,MAAMC,YAAqB,CAAC,uBAAuB;CAEnD,MAAM,gBAAgB,UAA4C;AAChE,QAAM,gBAAgB;AACtB,eAAa,KAAK;AAElB,MAAI,CAAC,UACH;AAGF,aAAW,EAAC,aAAY,CAAC;;CAG3B,MAAM,qBAAqB,SACzB,qBAAC;EAEC,eAAa,KAAK;EAClB,WAAW,GACT,yBAAyB,IAAI,qBAAqB,cAAc,CAAC,EACjE,OAAO,gBACP,KAAK,SAAS,OAAO,uBAAuB,OAAO,sBACpD;aAED,oBAAC;GACC,WAAW,GACT,yBAAyB,IAAI,qBAAqB,mBAAmB,CAAC,EACtE,OAAO,mBACR;aAEA,KAAK,SAAS,oBAACC;IAAM,OAAO;IAAI,QAAQ;KAAM,GAAG,oBAACC;IAAE,OAAO;IAAI,QAAQ;KAAM;IACzE,EACP,oBAACC;GAAW,SAAQ;GAAQ,WAAU;aACnC,EAAE,KAAK,YAAY,KAAK,OAAO;IACrB;IAlBR,KAAK,IAmBP;CAKP,MAAMC,eACJ,aAAa,CAAC,iBAAiB,EAAE,uCAAuC,YAAY,GAAG;CACzF,MAAMC,mBAAuC,YAAY;CAEzD,MAAMC,OACJ,qBAAC;EACC;EACA,UAAU;EACV,WAAW,GACT,yBAAyB,oBAAoB,EAC7C,OAAO,SACP,aAAa,OAAO,UAAU,IAC9B,UACD;;GAEA,iBACC,oBAACH;IACC,SAAQ;IACR,WAAW,GAAG,yBAAyB,IAAI,qBAAqB,UAAU,CAAC,EAAE,OAAO,WAAW;cAE9F;KACU;GAGd,SACC,qBAACI;IACC,SAAQ;IACR,WAAW,GAAG,yBAAyB,IAAI,qBAAqB,QAAQ,CAAC,EAAE,OAAO,SAAS;eAE3F,oBAACA,cAAe,mBAAO,EAAE,iBAAiB,IAAI,UAA+B,EAC7E,oBAACA,cAAe,yBAAa,QAAmC;KACjD;GAGlB,WACC,oBAACA;IACC,SAAQ;IACR,WAAW,GAAG,yBAAyB,IAAI,qBAAqB,QAAQ,CAAC,EAAE,OAAO,SAAS;cAE3F,oBAACA,cAAe,yBAAa,EAAE,gCAAgC,YAAY,GAA8B;KAC1F;GAGnB,qBAAC;IAAI,WAAW,GAAG,yBAAyB,IAAI,qBAAqB,SAAS,CAAC,EAAE,OAAO,UAAU;;KAChG,oBAACC;MACC,MAAK;MACL,cAAa;MACb,OAAO,EAAE,kCAAkC,YAAY;MACvD,aAAa,EAAE,wCAAwC,YAAY;MACnE,OAAO;MACP,UAAU;MACV,UAAU;MACV,OAAO;MACP;OACA;KAED,oBAAoB,YAAY,SAAS,KACxC,qBAAC;MAAI,WAAW,GAAG,yBAAyB,IAAI,qBAAqB,eAAe,CAAC,CAAC;iBACpF,oBAACL;OACC,SAAQ;OACR,WAAU;OACV,WAAW,GACT,yBAAyB,IAAI,qBAAqB,uBAAuB,CAAC,EAC1E,OAAO,uBACR;iBAEA,EAAE,6CAA6C,YAAY;QACjD,EACb,oBAAC;OAAG,WAAW,OAAO;iBAAkB,YAAY,IAAI,kBAAkB;QAAM;OAC5E;KAGR,oBAACK;MACC,MAAK;MACL,cAAa;MACb,OAAO,EAAE,sCAAsC,YAAY;MAC3D,aAAa,EAAE,4CAA4C,YAAY;MACvE,OAAO;MACP,UAAU;MACV,UAAU;MACV,OAAO;MACP;OACA;;KACE;GAEN,oBAAC;IAAI,WAAW,GAAG,yBAAyB,IAAI,qBAAqB,UAAU,CAAC,EAAE,OAAO,WAAW;cAClG,oBAACC;KAAO,MAAK;KAAS,OAAM;KAAU,SAAQ;KAAiB;KAAS,UAAU,CAAC;eAChF,EAAE,+BAA+B,YAAY;MACvC;KACL;;GACD;AAGT,KAAI,CAAC,YACH,QAAO;AAGT,QACE,qBAAC;EACC,WAAW,GACT,yBAAyB,IAAI,qBAAqB,cAAc,CAAC,EACjE,OAAO,oBACP,UACD;aAED,oBAAC;GACC,eAAY;GACZ,WAAW,GACT,yBAAyB,IAAI,qBAAqB,sBAAsB,CAAC,EACzE,OAAO,sBACR;aAEA;IACG,EAEN,oBAAC;GACC,MAAK;GACL,WAAW,GACT,yBAAyB,IAAI,qBAAqB,sBAAsB,CAAC,EACzE,OAAO,sBACR;aAED,qBAACF;IACC,SAAQ;IACR,WAAW,GAAG,yBAAyB,IAAI,qBAAqB,QAAQ,CAAC,EAAE,OAAO,SAAS;eAE3F,oBAACA,cAAe,mBAAO,EAAE,4CAA4C,YAAY,GAAwB,EACzG,oBAACA,cAAe,yBACb,EAAE,gDAAgD,YAAY,GACpC;KACd;IACb;GACF;;AAIV,mCAAe"}
@@ -0,0 +1,10 @@
1
+ import { Theme } from '@thunderid/browser';
2
+ /**
3
+ * Creates styles for the BaseChangeCredential component
4
+ * @param theme - The theme object containing design tokens
5
+ * @param colorScheme - The current color scheme (used for memoization)
6
+ * @returns Object containing CSS class names for component styling
7
+ */
8
+ declare const useStyles: (theme: Theme, colorScheme: string) => Record<string, string>;
9
+ export default useStyles;
10
+ //# sourceMappingURL=BaseChangeCredential.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseChangeCredential.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/presentation/ChangeCredential/BaseChangeCredential.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAGzC;;;;;GAKG;AACH,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,EAAE,aAAa,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CA8G3E,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { css } from "../../../styles/emotion.js";
2
+
3
+ //#region src/components/presentation/ChangeCredential/BaseChangeCredential.styles.ts
4
+ /**
5
+ * Creates styles for the BaseChangeCredential component
6
+ * @param theme - The theme object containing design tokens
7
+ * @param colorScheme - The current color scheme (used for memoization)
8
+ * @returns Object containing CSS class names for component styling
9
+ */
10
+ const useStyles = (theme, colorScheme) => {
11
+ const root = css`
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: calc(${theme.vars.spacing.unit} * 2);
15
+ width: 100%;
16
+ `;
17
+ const card = css`
18
+ padding: calc(${theme.vars.spacing.unit} * 3);
19
+ border: 1px solid ${theme.vars.colors.border};
20
+ border-radius: ${theme.vars.borderRadius.large};
21
+ `;
22
+ const heading = css`
23
+ margin: 0;
24
+ `;
25
+ const fields = css`
26
+ display: flex;
27
+ flex-direction: column;
28
+ gap: calc(${theme.vars.spacing.unit} * 2);
29
+ `;
30
+ const requirements = css`
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: calc(${theme.vars.spacing.unit} / 2);
34
+ margin: 0;
35
+ padding: 0;
36
+ list-style: none;
37
+ `;
38
+ const requirementsHeading = css`
39
+ margin: 0 0 calc(${theme.vars.spacing.unit} / 2) 0;
40
+ opacity: 0.8;
41
+ `;
42
+ const requirement = css`
43
+ display: flex;
44
+ align-items: center;
45
+ gap: ${theme.vars.spacing.unit};
46
+ `;
47
+ const requirementPassed = css`
48
+ color: ${theme.vars.colors.success.main};
49
+ `;
50
+ const requirementPending = css`
51
+ opacity: 0.7;
52
+ `;
53
+ const requirementIcon = css`
54
+ flex-shrink: 0;
55
+ width: 14px;
56
+ height: 14px;
57
+ `;
58
+ const alert = css`
59
+ width: 100%;
60
+ `;
61
+ const actions = css`
62
+ display: flex;
63
+ gap: ${theme.vars.spacing.unit};
64
+ align-items: center;
65
+ justify-content: flex-end;
66
+ `;
67
+ const unavailableRoot = css`
68
+ position: relative;
69
+ display: flex;
70
+ width: 100%;
71
+ `;
72
+ return {
73
+ actions,
74
+ alert,
75
+ card,
76
+ colorScheme,
77
+ fields,
78
+ heading,
79
+ requirement,
80
+ requirementIcon,
81
+ requirementPassed,
82
+ requirementPending,
83
+ requirements,
84
+ requirementsHeading,
85
+ root,
86
+ unavailableContent: css`
87
+ width: 100%;
88
+ filter: blur(3px);
89
+ opacity: 0.55;
90
+ pointer-events: none;
91
+ user-select: none;
92
+ `,
93
+ unavailableOverlay: css`
94
+ position: absolute;
95
+ inset: 0;
96
+ display: flex;
97
+ align-items: center;
98
+ justify-content: center;
99
+ padding: calc(${theme.vars.spacing.unit} * 2);
100
+ `,
101
+ unavailableRoot
102
+ };
103
+ };
104
+ var BaseChangeCredential_styles_default = useStyles;
105
+
106
+ //#endregion
107
+ export { BaseChangeCredential_styles_default as default };
108
+ //# sourceMappingURL=BaseChangeCredential.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseChangeCredential.styles.js","names":["root: string","card: string","heading: string","fields: string","requirements: string","requirementsHeading: string","requirement: string","requirementPassed: string","requirementPending: string","requirementIcon: string","alert: string","actions: string","unavailableRoot: string"],"sources":["../../../../src/components/presentation/ChangeCredential/BaseChangeCredential.styles.ts"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {Theme} from '@thunderid/browser';\nimport {css} from '../../../styles/emotion';\n\n/**\n * Creates styles for the BaseChangeCredential component\n * @param theme - The theme object containing design tokens\n * @param colorScheme - The current color scheme (used for memoization)\n * @returns Object containing CSS class names for component styling\n */\nconst useStyles = (theme: Theme, colorScheme: string): Record<string, string> => {\n const root: string = css`\n display: flex;\n flex-direction: column;\n gap: calc(${theme.vars.spacing.unit} * 2);\n width: 100%;\n `;\n\n const card: string = css`\n padding: calc(${theme.vars.spacing.unit} * 3);\n border: 1px solid ${theme.vars.colors.border};\n border-radius: ${theme.vars.borderRadius.large};\n `;\n\n const heading: string = css`\n margin: 0;\n `;\n\n const fields: string = css`\n display: flex;\n flex-direction: column;\n gap: calc(${theme.vars.spacing.unit} * 2);\n `;\n\n const requirements: string = css`\n display: flex;\n flex-direction: column;\n gap: calc(${theme.vars.spacing.unit} / 2);\n margin: 0;\n padding: 0;\n list-style: none;\n `;\n\n const requirementsHeading: string = css`\n margin: 0 0 calc(${theme.vars.spacing.unit} / 2) 0;\n opacity: 0.8;\n `;\n\n const requirement: string = css`\n display: flex;\n align-items: center;\n gap: ${theme.vars.spacing.unit};\n `;\n\n const requirementPassed: string = css`\n color: ${theme.vars.colors.success.main};\n `;\n\n const requirementPending: string = css`\n opacity: 0.7;\n `;\n\n const requirementIcon: string = css`\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n `;\n\n const alert: string = css`\n width: 100%;\n `;\n\n const actions: string = css`\n display: flex;\n gap: ${theme.vars.spacing.unit};\n align-items: center;\n justify-content: flex-end;\n `;\n\n const unavailableRoot: string = css`\n position: relative;\n display: flex;\n width: 100%;\n `;\n\n const unavailableContent: string = css`\n width: 100%;\n filter: blur(3px);\n opacity: 0.55;\n pointer-events: none;\n user-select: none;\n `;\n\n const unavailableOverlay: string = css`\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: calc(${theme.vars.spacing.unit} * 2);\n `;\n\n return {\n actions,\n alert,\n card,\n colorScheme,\n fields,\n heading,\n requirement,\n requirementIcon,\n requirementPassed,\n requirementPending,\n requirements,\n requirementsHeading,\n root,\n unavailableContent,\n unavailableOverlay,\n unavailableRoot,\n };\n};\n\nexport default useStyles;\n"],"mappings":";;;;;;;;;AAYA,MAAM,aAAa,OAAc,gBAAgD;CAC/E,MAAMA,OAAe,GAAG;;;gBAGV,MAAM,KAAK,QAAQ,KAAK;;;CAItC,MAAMC,OAAe,GAAG;oBACN,MAAM,KAAK,QAAQ,KAAK;wBACpB,MAAM,KAAK,OAAO,OAAO;qBAC5B,MAAM,KAAK,aAAa,MAAM;;CAGjD,MAAMC,UAAkB,GAAG;;;CAI3B,MAAMC,SAAiB,GAAG;;;gBAGZ,MAAM,KAAK,QAAQ,KAAK;;CAGtC,MAAMC,eAAuB,GAAG;;;gBAGlB,MAAM,KAAK,QAAQ,KAAK;;;;;CAMtC,MAAMC,sBAA8B,GAAG;uBAClB,MAAM,KAAK,QAAQ,KAAK;;;CAI7C,MAAMC,cAAsB,GAAG;;;WAGtB,MAAM,KAAK,QAAQ,KAAK;;CAGjC,MAAMC,oBAA4B,GAAG;aAC1B,MAAM,KAAK,OAAO,QAAQ,KAAK;;CAG1C,MAAMC,qBAA6B,GAAG;;;CAItC,MAAMC,kBAA0B,GAAG;;;;;CAMnC,MAAMC,QAAgB,GAAG;;;CAIzB,MAAMC,UAAkB,GAAG;;WAElB,MAAM,KAAK,QAAQ,KAAK;;;;CAKjC,MAAMC,kBAA0B,GAAG;;;;;AAuBnC,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,oBA/BiC,GAAG;;;;;;;EAgCpC,oBAxBiC,GAAG;;;;;;oBAMpB,MAAM,KAAK,QAAQ,KAAK;;EAmBxC;EACD;;AAGH,0CAAe"}
@@ -0,0 +1,55 @@
1
+ import { FC } from 'react';
2
+ import { BaseChangeCredentialProps } from './BaseChangeCredential';
3
+ export interface ChangeCredentialProps extends Omit<BaseChangeCredentialProps, 'credentialDisplayName' | 'error' | 'fieldErrors' | 'loading' | 'onSubmit' | 'success'> {
4
+ /**
5
+ * The credential attribute this instance manages, any attribute the user's entity type
6
+ * schema declares `credential: true` (for example `password` or `pin`). Defaults to
7
+ * `password`. Render the component once per credential to let a user manage more than one,
8
+ * for example `<ChangeCredential />` for the password and
9
+ * `<ChangeCredential attribute="pin" />` for a PIN.
10
+ */
11
+ attribute?: string;
12
+ /**
13
+ * Called after the credential has been changed successfully.
14
+ */
15
+ onSuccess?: () => void;
16
+ }
17
+ /**
18
+ * ChangeCredential lets the signed-in user set a new value for one of their own credentials.
19
+ *
20
+ * It collects only a new value and its confirmation. The self-service credential write path
21
+ * does not verify the account's existing value today, so this component does not ask for one;
22
+ * once server-side current-value verification ships, that field returns without a breaking
23
+ * change to this component's public props.
24
+ *
25
+ * It reads the applicable rules from the user schema already resolved by the ThunderID
26
+ * provider, so it adds no network request beyond the write itself, and posts to
27
+ * `/users/me/update-credentials` with the access token attached by the SDK's HTTP client.
28
+ *
29
+ * Defaults to managing the `password` credential. To manage a different one (for example a
30
+ * PIN declared on the user type schema), set `attribute`; render the component once per
31
+ * credential to let a user manage several. Every default label, placeholder and message is
32
+ * built from the attribute's own `displayName` in the schema (`GET /users/me/meta`), so it
33
+ * always matches whatever an admin named the attribute there; when the schema carries no
34
+ * `displayName` for it, it falls back to the attribute name title-cased (`pin` -> `Pin`).
35
+ * Override individual strings via `preferences.i18n` for full control (including other
36
+ * languages) if the schema-derived name isn't the right fit.
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * // Basic usage, manages the password
41
+ * <ChangeCredential onSuccess={() => toast('Password updated')} />
42
+ *
43
+ * // With an explicit rule instead of the schema-derived policy
44
+ * <ChangeCredential
45
+ * policy={{regex: '^.{12,}$'}}
46
+ * />
47
+ *
48
+ * // Managing a different credential declared on the schema; labels use the schema's own
49
+ * // displayName for it automatically
50
+ * <ChangeCredential attribute="pin" />
51
+ * ```
52
+ */
53
+ declare const ChangeCredential: FC<ChangeCredentialProps>;
54
+ export default ChangeCredential;
55
+ //# sourceMappingURL=ChangeCredential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChangeCredential.d.ts","sourceRoot":"","sources":["../../../../src/components/presentation/ChangeCredential/ChangeCredential.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAC,EAAE,EAAoB,MAAM,OAAO,CAAC;AAC5C,OAA6B,EAAC,yBAAyB,EAAuB,MAAM,wBAAwB,CAAC;AAY7G,MAAM,WAAW,qBACf,SAAQ,IAAI,CACV,yBAAyB,EACzB,uBAAuB,GAAG,OAAO,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CACvF;IACD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,QAAA,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CA8E/C,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,119 @@
1
+ import useThunderID_default from "../../../contexts/ThunderID/useThunderID.js";
2
+ import useUser_default from "../../../contexts/User/useUser.js";
3
+ import useTranslation_default from "../../../hooks/useTranslation.js";
4
+ import BaseChangeCredential_default from "./BaseChangeCredential.js";
5
+ import updateMeCredentials_default from "../../../api/updateMeCredentials.js";
6
+ import { CredentialConstants, mapCredentialUpdateError, resolveChangeCredentialPolicy, resolveResourceEndpoint, supportsCredential } from "@thunderid/browser";
7
+ import { useMemo, useState } from "react";
8
+ import { jsx } from "react/jsx-runtime";
9
+
10
+ //#region src/components/presentation/ChangeCredential/ChangeCredential.tsx
11
+ /**
12
+ * Title-cases a credential attribute name for use as a display-name fallback when the schema
13
+ * declares no `displayName` for it, e.g. `pin` -> `Pin`.
14
+ */
15
+ const defaultDisplayName = (attribute) => attribute.charAt(0).toUpperCase() + attribute.slice(1);
16
+ /**
17
+ * ChangeCredential lets the signed-in user set a new value for one of their own credentials.
18
+ *
19
+ * It collects only a new value and its confirmation. The self-service credential write path
20
+ * does not verify the account's existing value today, so this component does not ask for one;
21
+ * once server-side current-value verification ships, that field returns without a breaking
22
+ * change to this component's public props.
23
+ *
24
+ * It reads the applicable rules from the user schema already resolved by the ThunderID
25
+ * provider, so it adds no network request beyond the write itself, and posts to
26
+ * `/users/me/update-credentials` with the access token attached by the SDK's HTTP client.
27
+ *
28
+ * Defaults to managing the `password` credential. To manage a different one (for example a
29
+ * PIN declared on the user type schema), set `attribute`; render the component once per
30
+ * credential to let a user manage several. Every default label, placeholder and message is
31
+ * built from the attribute's own `displayName` in the schema (`GET /users/me/meta`), so it
32
+ * always matches whatever an admin named the attribute there; when the schema carries no
33
+ * `displayName` for it, it falls back to the attribute name title-cased (`pin` -> `Pin`).
34
+ * Override individual strings via `preferences.i18n` for full control (including other
35
+ * languages) if the schema-derived name isn't the right fit.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * // Basic usage, manages the password
40
+ * <ChangeCredential onSuccess={() => toast('Password updated')} />
41
+ *
42
+ * // With an explicit rule instead of the schema-derived policy
43
+ * <ChangeCredential
44
+ * policy={{regex: '^.{12,}$'}}
45
+ * />
46
+ *
47
+ * // Managing a different credential declared on the schema; labels use the schema's own
48
+ * // displayName for it automatically
49
+ * <ChangeCredential attribute="pin" />
50
+ * ```
51
+ */
52
+ const ChangeCredential = ({ attribute = CredentialConstants.PASSWORD, onSuccess = void 0, policy = void 0, preferences = void 0,...rest }) => {
53
+ const { baseUrl, endpoints, instanceId, preferences: contextPreferences } = useThunderID_default();
54
+ const { userSchema } = useUser_default();
55
+ const resolvedDisplayName = userSchema?.[attribute]?.displayName ?? defaultDisplayName(attribute);
56
+ const resolvedPreferences = useMemo(() => ({
57
+ ...contextPreferences,
58
+ ...preferences,
59
+ user: {
60
+ ...contextPreferences?.user,
61
+ ...preferences?.user
62
+ }
63
+ }), [contextPreferences, preferences]);
64
+ const { t } = useTranslation_default(resolvedPreferences?.i18n);
65
+ const [error, setError] = useState(null);
66
+ const [fieldErrors, setFieldErrors] = useState({});
67
+ const [loading, setLoading] = useState(false);
68
+ const [success, setSuccess] = useState(false);
69
+ const resolvedPolicy = useMemo(() => resolveChangeCredentialPolicy(userSchema, attribute, policy), [
70
+ userSchema,
71
+ attribute,
72
+ policy
73
+ ]);
74
+ const handleSubmit = async ({ newPassword }) => {
75
+ setError(null);
76
+ setFieldErrors({});
77
+ setSuccess(false);
78
+ setLoading(true);
79
+ try {
80
+ await updateMeCredentials_default({
81
+ baseUrl,
82
+ instanceId,
83
+ payload: { [attribute]: newPassword },
84
+ url: resolveResourceEndpoint("usersMeCredentials", { endpoints })
85
+ });
86
+ setSuccess(true);
87
+ onSuccess?.();
88
+ } catch (caughtError) {
89
+ const { field, message, messageKey } = mapCredentialUpdateError(caughtError);
90
+ const text = message ?? t(messageKey, {
91
+ credential: resolvedDisplayName,
92
+ credentialLower: resolvedDisplayName.toLowerCase()
93
+ });
94
+ if (field) setFieldErrors({ [field]: text });
95
+ else setError(text);
96
+ } finally {
97
+ setLoading(false);
98
+ }
99
+ };
100
+ return /* @__PURE__ */ jsx(BaseChangeCredential_default, {
101
+ ...rest,
102
+ credentialDisplayName: resolvedDisplayName,
103
+ error,
104
+ fieldErrors,
105
+ loading,
106
+ policy: resolvedPolicy,
107
+ preferences: resolvedPreferences,
108
+ success,
109
+ unavailable: !supportsCredential(userSchema, attribute),
110
+ onSubmit: (values) => {
111
+ handleSubmit(values);
112
+ }
113
+ });
114
+ };
115
+ var ChangeCredential_default = ChangeCredential;
116
+
117
+ //#endregion
118
+ export { ChangeCredential_default as default };
119
+ //# sourceMappingURL=ChangeCredential.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChangeCredential.js","names":["ChangeCredential: FC<ChangeCredentialProps>","useThunderID","useUser","resolvedDisplayName: string","useTranslation","resolvedPolicy: PasswordPolicy","updateMeCredentials","caughtError: unknown","text: string","BaseChangeCredential"],"sources":["../../../../src/components/presentation/ChangeCredential/ChangeCredential.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n CredentialConstants,\n CredentialUpdateErrorResult,\n PasswordPolicy,\n mapCredentialUpdateError,\n resolveChangeCredentialPolicy,\n resolveResourceEndpoint,\n supportsCredential,\n} from '@thunderid/browser';\nimport {FC, useMemo, useState} from 'react';\nimport BaseChangeCredential, {BaseChangeCredentialProps, ChangePasswordValues} from './BaseChangeCredential';\nimport updateMeCredentials from '../../../api/updateMeCredentials';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport useUser from '../../../contexts/User/useUser';\nimport useTranslation from '../../../hooks/useTranslation';\n\n/**\n * Title-cases a credential attribute name for use as a display-name fallback when the schema\n * declares no `displayName` for it, e.g. `pin` -> `Pin`.\n */\nconst defaultDisplayName = (attribute: string): string => attribute.charAt(0).toUpperCase() + attribute.slice(1);\n\nexport interface ChangeCredentialProps\n extends Omit<\n BaseChangeCredentialProps,\n 'credentialDisplayName' | 'error' | 'fieldErrors' | 'loading' | 'onSubmit' | 'success'\n > {\n /**\n * The credential attribute this instance manages, any attribute the user's entity type\n * schema declares `credential: true` (for example `password` or `pin`). Defaults to\n * `password`. Render the component once per credential to let a user manage more than one,\n * for example `<ChangeCredential />` for the password and\n * `<ChangeCredential attribute=\"pin\" />` for a PIN.\n */\n attribute?: string;\n /**\n * Called after the credential has been changed successfully.\n */\n onSuccess?: () => void;\n}\n\n/**\n * ChangeCredential lets the signed-in user set a new value for one of their own credentials.\n *\n * It collects only a new value and its confirmation. The self-service credential write path\n * does not verify the account's existing value today, so this component does not ask for one;\n * once server-side current-value verification ships, that field returns without a breaking\n * change to this component's public props.\n *\n * It reads the applicable rules from the user schema already resolved by the ThunderID\n * provider, so it adds no network request beyond the write itself, and posts to\n * `/users/me/update-credentials` with the access token attached by the SDK's HTTP client.\n *\n * Defaults to managing the `password` credential. To manage a different one (for example a\n * PIN declared on the user type schema), set `attribute`; render the component once per\n * credential to let a user manage several. Every default label, placeholder and message is\n * built from the attribute's own `displayName` in the schema (`GET /users/me/meta`), so it\n * always matches whatever an admin named the attribute there; when the schema carries no\n * `displayName` for it, it falls back to the attribute name title-cased (`pin` -> `Pin`).\n * Override individual strings via `preferences.i18n` for full control (including other\n * languages) if the schema-derived name isn't the right fit.\n *\n * @example\n * ```tsx\n * // Basic usage, manages the password\n * <ChangeCredential onSuccess={() => toast('Password updated')} />\n *\n * // With an explicit rule instead of the schema-derived policy\n * <ChangeCredential\n * policy={{regex: '^.{12,}$'}}\n * />\n *\n * // Managing a different credential declared on the schema; labels use the schema's own\n * // displayName for it automatically\n * <ChangeCredential attribute=\"pin\" />\n * ```\n */\nconst ChangeCredential: FC<ChangeCredentialProps> = ({\n attribute = CredentialConstants.PASSWORD,\n onSuccess = undefined,\n policy = undefined,\n preferences = undefined,\n ...rest\n}: ChangeCredentialProps) => {\n const {baseUrl, endpoints, instanceId, preferences: contextPreferences} = useThunderID();\n const {userSchema} = useUser();\n const resolvedDisplayName: string = userSchema?.[attribute]?.displayName ?? defaultDisplayName(attribute);\n\n const resolvedPreferences = useMemo(\n () => ({\n ...contextPreferences,\n ...preferences,\n user: {...contextPreferences?.user, ...preferences?.user},\n }),\n [contextPreferences, preferences],\n );\n const {t} = useTranslation(resolvedPreferences?.i18n);\n\n const [error, setError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n const [loading, setLoading] = useState<boolean>(false);\n const [success, setSuccess] = useState<boolean>(false);\n\n const resolvedPolicy: PasswordPolicy = useMemo(\n () => resolveChangeCredentialPolicy(userSchema, attribute, policy),\n [userSchema, attribute, policy],\n );\n\n const handleSubmit = async ({newPassword}: ChangePasswordValues): Promise<void> => {\n setError(null);\n setFieldErrors({});\n setSuccess(false);\n setLoading(true);\n\n try {\n await updateMeCredentials({\n baseUrl,\n instanceId,\n payload: {[attribute]: newPassword},\n url: resolveResourceEndpoint('usersMeCredentials', {endpoints}),\n });\n\n setSuccess(true);\n onSuccess?.();\n } catch (caughtError: unknown) {\n const {field, message, messageKey}: CredentialUpdateErrorResult = mapCredentialUpdateError(caughtError);\n const text: string =\n message ?? t(messageKey, {credential: resolvedDisplayName, credentialLower: resolvedDisplayName.toLowerCase()});\n\n if (field) {\n setFieldErrors({[field]: text});\n } else {\n setError(text);\n }\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <BaseChangeCredential\n {...rest}\n credentialDisplayName={resolvedDisplayName}\n error={error}\n fieldErrors={fieldErrors}\n loading={loading}\n policy={resolvedPolicy}\n preferences={resolvedPreferences}\n success={success}\n unavailable={!supportsCredential(userSchema, attribute)}\n onSubmit={(values: ChangePasswordValues): void => {\n void handleSubmit(values);\n }}\n />\n );\n};\n\nexport default ChangeCredential;\n"],"mappings":";;;;;;;;;;;;;;AAuBA,MAAM,sBAAsB,cAA8B,UAAU,OAAO,EAAE,CAAC,aAAa,GAAG,UAAU,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDhH,MAAMA,oBAA+C,EACnD,YAAY,oBAAoB,UAChC,YAAY,QACZ,SAAS,QACT,cAAc,OACd,GAAG,WACwB;CAC3B,MAAM,EAAC,SAAS,WAAW,YAAY,aAAa,uBAAsBC,sBAAc;CACxF,MAAM,EAAC,eAAcC,iBAAS;CAC9B,MAAMC,sBAA8B,aAAa,YAAY,eAAe,mBAAmB,UAAU;CAEzG,MAAM,sBAAsB,eACnB;EACL,GAAG;EACH,GAAG;EACH,MAAM;GAAC,GAAG,oBAAoB;GAAM,GAAG,aAAa;GAAK;EAC1D,GACD,CAAC,oBAAoB,YAAY,CAClC;CACD,MAAM,EAAC,MAAKC,uBAAe,qBAAqB,KAAK;CAErD,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CACvD,MAAM,CAAC,aAAa,kBAAkB,SAAiC,EAAE,CAAC;CAC1E,MAAM,CAAC,SAAS,cAAc,SAAkB,MAAM;CACtD,MAAM,CAAC,SAAS,cAAc,SAAkB,MAAM;CAEtD,MAAMC,iBAAiC,cAC/B,8BAA8B,YAAY,WAAW,OAAO,EAClE;EAAC;EAAY;EAAW;EAAO,CAChC;CAED,MAAM,eAAe,OAAO,EAAC,kBAAsD;AACjF,WAAS,KAAK;AACd,iBAAe,EAAE,CAAC;AAClB,aAAW,MAAM;AACjB,aAAW,KAAK;AAEhB,MAAI;AACF,SAAMC,4BAAoB;IACxB;IACA;IACA,SAAS,GAAE,YAAY,aAAY;IACnC,KAAK,wBAAwB,sBAAsB,EAAC,WAAU,CAAC;IAChE,CAAC;AAEF,cAAW,KAAK;AAChB,gBAAa;WACNC,aAAsB;GAC7B,MAAM,EAAC,OAAO,SAAS,eAA2C,yBAAyB,YAAY;GACvG,MAAMC,OACJ,WAAW,EAAE,YAAY;IAAC,YAAY;IAAqB,iBAAiB,oBAAoB,aAAa;IAAC,CAAC;AAEjH,OAAI,MACF,gBAAe,GAAE,QAAQ,MAAK,CAAC;OAE/B,UAAS,KAAK;YAER;AACR,cAAW,MAAM;;;AAIrB,QACE,oBAACC;EACC,GAAI;EACJ,uBAAuB;EAChB;EACM;EACJ;EACT,QAAQ;EACR,aAAa;EACJ;EACT,aAAa,CAAC,mBAAmB,YAAY,UAAU;EACvD,WAAW,WAAuC;AAChD,GAAK,aAAa,OAAO;;GAE3B;;AAIN,+BAAe"}
@@ -1,10 +1,10 @@
1
1
  import { cx } from "../../../styles/emotion.js";
2
2
  import useTheme_default from "../../../contexts/Theme/useTheme.js";
3
- import BaseLanguageSwitcher_styles_default from "./BaseLanguageSwitcher.styles.js";
4
3
  import Check_default from "../../primitives/Icons/Check.js";
4
+ import BaseLanguageSwitcher_styles_default from "./BaseLanguageSwitcher.styles.js";
5
5
  import ChevronDown_default from "../../primitives/Icons/ChevronDown.js";
6
6
  import { useEffect, useState } from "react";
7
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { FloatingFocusManager, FloatingPortal, autoUpdate, flip, offset, shift, useClick, useDismiss, useFloating, useInteractions, useRole } from "@floating-ui/react";
9
9
 
10
10
  //#region src/components/presentation/LanguageSwitcher/BaseLanguageSwitcher.tsx
@@ -42,7 +42,7 @@ const BaseLanguageSwitcher = ({ children, className, currentLanguage, isLoading
42
42
  })
43
43
  ]);
44
44
  const currentOption = languages.find((l) => l.code === currentLanguage);
45
- if (children) return /* @__PURE__ */ jsx(Fragment, { children: children({
45
+ if (children) return /* @__PURE__ */ jsx(Fragment$1, { children: children({
46
46
  currentLanguage,
47
47
  isLoading,
48
48
  languages,
@@ -1 +1 @@
1
- {"version":3,"file":"BaseLanguageSwitcher.js","names":["BaseLanguageSwitcher: FC<BaseLanguageSwitcherProps>","useTheme","styles: Record<string, string>","useStyles","hasMultipleLanguages: boolean","currentOption: LanguageOption | undefined","ChevronDown","Check"],"sources":["../../../../src/components/presentation/LanguageSwitcher/BaseLanguageSwitcher.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingPortal,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useInteractions,\n useRole,\n} from '@floating-ui/react';\nimport {FC, ReactElement, ReactNode, useEffect, useState} from 'react';\nimport useStyles from './BaseLanguageSwitcher.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport Check from '../../primitives/Icons/Check';\nimport ChevronDown from '../../primitives/Icons/ChevronDown';\n\n/**\n * A resolved language option with display name and emoji flag.\n */\nexport interface LanguageOption {\n /** BCP 47 language tag (e.g. \"en\", \"fr\", \"en-US\") */\n code: string;\n /** Human-readable display name resolved via Intl.DisplayNames */\n displayName: string;\n /** Flag emoji or globe emoji for the language */\n emoji: string;\n}\n\n/**\n * Render props exposed to consumers when using the render-prop pattern.\n */\nexport interface LanguageSwitcherRenderProps {\n /** The currently active language code */\n currentLanguage: string;\n /** Whether a language switch is in progress */\n isLoading: boolean;\n /** Resolved language options */\n languages: LanguageOption[];\n /** Call this to switch to a different language */\n onLanguageChange: (language: string) => void;\n}\n\nexport interface BaseLanguageSwitcherProps {\n /**\n * Render-props callback. When provided, the default dropdown UI is replaced with\n * whatever JSX the callback returns.\n *\n * @example\n * ```tsx\n * <BaseLanguageSwitcher {...props}>\n * {({languages, currentLanguage, onLanguageChange}) => (\n * <select value={currentLanguage} onChange={e => onLanguageChange(e.target.value)}>\n * {languages.map(l => <option key={l.code} value={l.code}>{l.emoji} {l.displayName}</option>)}\n * </select>\n * )}\n * </BaseLanguageSwitcher>\n * ```\n */\n children?: (props: LanguageSwitcherRenderProps) => ReactNode;\n /** Additional CSS class applied to the root element (default UI only) */\n className?: string;\n /** The currently active language code */\n currentLanguage: string;\n /** Whether a language switch is in progress */\n isLoading?: boolean;\n /** Resolved language options to display */\n languages: LanguageOption[];\n /** Called when the user selects a language */\n onLanguageChange: (language: string) => void;\n}\n\n/**\n * Pure-UI language switcher dropdown.\n * Accepts resolved `LanguageOption[]` (code + displayName + emoji) and delegates\n * language switching to the `onLanguageChange` callback.\n *\n * Supports render props for full UI customisation.\n */\nconst BaseLanguageSwitcher: FC<BaseLanguageSwitcherProps> = ({\n children,\n className,\n currentLanguage,\n isLoading = false,\n languages,\n onLanguageChange,\n}: BaseLanguageSwitcherProps): ReactElement => {\n const {theme, colorScheme} = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme);\n const [isOpen, setIsOpen] = useState(false);\n const hasMultipleLanguages: boolean = languages.length > 1;\n\n useEffect(() => {\n if (!hasMultipleLanguages && isOpen) {\n setIsOpen(false);\n }\n }, [hasMultipleLanguages, isOpen]);\n\n const {refs, floatingStyles, context} = useFloating({\n middleware: [offset(4), flip(), shift()],\n onOpenChange: setIsOpen,\n open: isOpen,\n whileElementsMounted: autoUpdate,\n });\n\n const click: ReturnType<typeof useClick> = useClick(context, {enabled: hasMultipleLanguages});\n const dismiss: ReturnType<typeof useDismiss> = useDismiss(context, {enabled: hasMultipleLanguages});\n const role: ReturnType<typeof useRole> = useRole(context, {enabled: hasMultipleLanguages, role: 'listbox'});\n const {getReferenceProps, getFloatingProps} = useInteractions([click, dismiss, role]);\n\n const currentOption: LanguageOption | undefined = languages.find((l: LanguageOption) => l.code === currentLanguage);\n\n if (children) {\n return (\n <>\n {children({\n currentLanguage,\n isLoading,\n languages,\n onLanguageChange,\n })}\n </>\n );\n }\n\n return (\n <div className={cx(styles['root'], className)}>\n <button\n ref={refs.setReference}\n type=\"button\"\n disabled={isLoading}\n aria-label=\"Switch language\"\n {...getReferenceProps()}\n className={styles['trigger']}\n >\n {currentOption && <span className={styles['triggerEmoji']}>{currentOption.emoji}</span>}\n <span className={styles['triggerLabel']}>{currentOption?.displayName ?? currentLanguage}</span>\n {hasMultipleLanguages && <ChevronDown />}\n </button>\n\n {isOpen && hasMultipleLanguages && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false}>\n <div\n ref={refs.setFloating}\n style={floatingStyles}\n {...getFloatingProps()}\n className={styles['content']}\n role=\"listbox\"\n aria-label=\"Select language\"\n >\n {languages.map((lang: LanguageOption) => (\n <button\n key={lang.code}\n type=\"button\"\n role=\"option\"\n aria-selected={lang.code === currentLanguage}\n className={cx(styles['option'], lang.code === currentLanguage && styles['optionActive'])}\n onClick={() => {\n onLanguageChange(lang.code);\n setIsOpen(false);\n }}\n >\n <span className={styles['optionEmoji']}>{lang.emoji}</span>\n <span className={styles['optionLabel']}>{lang.displayName}</span>\n {lang.code === currentLanguage && (\n <span className={styles['checkIcon']}>\n <Check />\n </span>\n )}\n </button>\n ))}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n );\n};\n\nexport default BaseLanguageSwitcher;\n"],"mappings":";;;;;;;;;;;;;;;;;AAqFA,MAAMA,wBAAuD,EAC3D,UACA,WACA,iBACA,YAAY,OACZ,WACA,uBAC6C;CAC7C,MAAM,EAAC,OAAO,gBAAeC,kBAAU;CACvC,MAAMC,SAAiCC,oCAAU,OAAO,YAAY;CACpE,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;CAC3C,MAAMC,uBAAgC,UAAU,SAAS;AAEzD,iBAAgB;AACd,MAAI,CAAC,wBAAwB,OAC3B,WAAU,MAAM;IAEjB,CAAC,sBAAsB,OAAO,CAAC;CAElC,MAAM,EAAC,MAAM,gBAAgB,YAAW,YAAY;EAClD,YAAY;GAAC,OAAO,EAAE;GAAE,MAAM;GAAE,OAAO;GAAC;EACxC,cAAc;EACd,MAAM;EACN,sBAAsB;EACvB,CAAC;CAKF,MAAM,EAAC,mBAAmB,qBAAoB,gBAAgB;EAHnB,SAAS,SAAS,EAAC,SAAS,sBAAqB,CAAC;EAC9C,WAAW,SAAS,EAAC,SAAS,sBAAqB,CAAC;EAC1D,QAAQ,SAAS;GAAC,SAAS;GAAsB,MAAM;GAAU,CAAC;EACvB,CAAC;CAErF,MAAMC,gBAA4C,UAAU,MAAM,MAAsB,EAAE,SAAS,gBAAgB;AAEnH,KAAI,SACF,QACE,0CACG,SAAS;EACR;EACA;EACA;EACA;EACD,CAAC,GACD;AAIP,QACE,qBAAC;EAAI,WAAW,GAAG,OAAO,SAAS,UAAU;aAC3C,qBAAC;GACC,KAAK,KAAK;GACV,MAAK;GACL,UAAU;GACV,cAAW;GACX,GAAI,mBAAmB;GACvB,WAAW,OAAO;;IAEjB,iBAAiB,oBAAC;KAAK,WAAW,OAAO;eAAkB,cAAc;MAAa;IACvF,oBAAC;KAAK,WAAW,OAAO;eAAkB,eAAe,eAAe;MAAuB;IAC9F,wBAAwB,oBAACC,wBAAc;;IACjC,EAER,UAAU,wBACT,oBAAC,4BACC,oBAAC;GAA8B;GAAS,OAAO;aAC7C,oBAAC;IACC,KAAK,KAAK;IACV,OAAO;IACP,GAAI,kBAAkB;IACtB,WAAW,OAAO;IAClB,MAAK;IACL,cAAW;cAEV,UAAU,KAAK,SACd,qBAAC;KAEC,MAAK;KACL,MAAK;KACL,iBAAe,KAAK,SAAS;KAC7B,WAAW,GAAG,OAAO,WAAW,KAAK,SAAS,mBAAmB,OAAO,gBAAgB;KACxF,eAAe;AACb,uBAAiB,KAAK,KAAK;AAC3B,gBAAU,MAAM;;;MAGlB,oBAAC;OAAK,WAAW,OAAO;iBAAiB,KAAK;QAAa;MAC3D,oBAAC;OAAK,WAAW,OAAO;iBAAiB,KAAK;QAAmB;MAChE,KAAK,SAAS,mBACb,oBAAC;OAAK,WAAW,OAAO;iBACtB,oBAACC,kBAAQ;QACJ;;OAfJ,KAAK,KAiBH,CACT;KACE;IACe,GACR;GAEf;;AAIV,mCAAe"}
1
+ {"version":3,"file":"BaseLanguageSwitcher.js","names":["BaseLanguageSwitcher: FC<BaseLanguageSwitcherProps>","useTheme","styles: Record<string, string>","useStyles","hasMultipleLanguages: boolean","currentOption: LanguageOption | undefined","ChevronDown","Check"],"sources":["../../../../src/components/presentation/LanguageSwitcher/BaseLanguageSwitcher.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingPortal,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useInteractions,\n useRole,\n} from '@floating-ui/react';\nimport {FC, ReactElement, ReactNode, useEffect, useState} from 'react';\nimport useStyles from './BaseLanguageSwitcher.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {cx} from '../../../styles/emotion';\nimport Check from '../../primitives/Icons/Check';\nimport ChevronDown from '../../primitives/Icons/ChevronDown';\n\n/**\n * A resolved language option with display name and emoji flag.\n */\nexport interface LanguageOption {\n /** BCP 47 language tag (e.g. \"en\", \"fr\", \"en-US\") */\n code: string;\n /** Human-readable display name resolved via Intl.DisplayNames */\n displayName: string;\n /** Flag emoji or globe emoji for the language */\n emoji: string;\n}\n\n/**\n * Render props exposed to consumers when using the render-prop pattern.\n */\nexport interface LanguageSwitcherRenderProps {\n /** The currently active language code */\n currentLanguage: string;\n /** Whether a language switch is in progress */\n isLoading: boolean;\n /** Resolved language options */\n languages: LanguageOption[];\n /** Call this to switch to a different language */\n onLanguageChange: (language: string) => void;\n}\n\nexport interface BaseLanguageSwitcherProps {\n /**\n * Render-props callback. When provided, the default dropdown UI is replaced with\n * whatever JSX the callback returns.\n *\n * @example\n * ```tsx\n * <BaseLanguageSwitcher {...props}>\n * {({languages, currentLanguage, onLanguageChange}) => (\n * <select value={currentLanguage} onChange={e => onLanguageChange(e.target.value)}>\n * {languages.map(l => <option key={l.code} value={l.code}>{l.emoji} {l.displayName}</option>)}\n * </select>\n * )}\n * </BaseLanguageSwitcher>\n * ```\n */\n children?: (props: LanguageSwitcherRenderProps) => ReactNode;\n /** Additional CSS class applied to the root element (default UI only) */\n className?: string;\n /** The currently active language code */\n currentLanguage: string;\n /** Whether a language switch is in progress */\n isLoading?: boolean;\n /** Resolved language options to display */\n languages: LanguageOption[];\n /** Called when the user selects a language */\n onLanguageChange: (language: string) => void;\n}\n\n/**\n * Pure-UI language switcher dropdown.\n * Accepts resolved `LanguageOption[]` (code + displayName + emoji) and delegates\n * language switching to the `onLanguageChange` callback.\n *\n * Supports render props for full UI customisation.\n */\nconst BaseLanguageSwitcher: FC<BaseLanguageSwitcherProps> = ({\n children,\n className,\n currentLanguage,\n isLoading = false,\n languages,\n onLanguageChange,\n}: BaseLanguageSwitcherProps): ReactElement => {\n const {theme, colorScheme} = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme);\n const [isOpen, setIsOpen] = useState(false);\n const hasMultipleLanguages: boolean = languages.length > 1;\n\n useEffect(() => {\n if (!hasMultipleLanguages && isOpen) {\n setIsOpen(false);\n }\n }, [hasMultipleLanguages, isOpen]);\n\n const {refs, floatingStyles, context} = useFloating({\n middleware: [offset(4), flip(), shift()],\n onOpenChange: setIsOpen,\n open: isOpen,\n whileElementsMounted: autoUpdate,\n });\n\n const click: ReturnType<typeof useClick> = useClick(context, {enabled: hasMultipleLanguages});\n const dismiss: ReturnType<typeof useDismiss> = useDismiss(context, {enabled: hasMultipleLanguages});\n const role: ReturnType<typeof useRole> = useRole(context, {enabled: hasMultipleLanguages, role: 'listbox'});\n const {getReferenceProps, getFloatingProps} = useInteractions([click, dismiss, role]);\n\n const currentOption: LanguageOption | undefined = languages.find((l: LanguageOption) => l.code === currentLanguage);\n\n if (children) {\n return (\n <>\n {children({\n currentLanguage,\n isLoading,\n languages,\n onLanguageChange,\n })}\n </>\n );\n }\n\n return (\n <div className={cx(styles['root'], className)}>\n <button\n ref={refs.setReference}\n type=\"button\"\n disabled={isLoading}\n aria-label=\"Switch language\"\n {...getReferenceProps()}\n className={styles['trigger']}\n >\n {currentOption && <span className={styles['triggerEmoji']}>{currentOption.emoji}</span>}\n <span className={styles['triggerLabel']}>{currentOption?.displayName ?? currentLanguage}</span>\n {hasMultipleLanguages && <ChevronDown />}\n </button>\n\n {isOpen && hasMultipleLanguages && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false}>\n <div\n ref={refs.setFloating}\n style={floatingStyles}\n {...getFloatingProps()}\n className={styles['content']}\n role=\"listbox\"\n aria-label=\"Select language\"\n >\n {languages.map((lang: LanguageOption) => (\n <button\n key={lang.code}\n type=\"button\"\n role=\"option\"\n aria-selected={lang.code === currentLanguage}\n className={cx(styles['option'], lang.code === currentLanguage && styles['optionActive'])}\n onClick={() => {\n onLanguageChange(lang.code);\n setIsOpen(false);\n }}\n >\n <span className={styles['optionEmoji']}>{lang.emoji}</span>\n <span className={styles['optionLabel']}>{lang.displayName}</span>\n {lang.code === currentLanguage && (\n <span className={styles['checkIcon']}>\n <Check />\n </span>\n )}\n </button>\n ))}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n );\n};\n\nexport default BaseLanguageSwitcher;\n"],"mappings":";;;;;;;;;;;;;;;;;AAqFA,MAAMA,wBAAuD,EAC3D,UACA,WACA,iBACA,YAAY,OACZ,WACA,uBAC6C;CAC7C,MAAM,EAAC,OAAO,gBAAeC,kBAAU;CACvC,MAAMC,SAAiCC,oCAAU,OAAO,YAAY;CACpE,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;CAC3C,MAAMC,uBAAgC,UAAU,SAAS;AAEzD,iBAAgB;AACd,MAAI,CAAC,wBAAwB,OAC3B,WAAU,MAAM;IAEjB,CAAC,sBAAsB,OAAO,CAAC;CAElC,MAAM,EAAC,MAAM,gBAAgB,YAAW,YAAY;EAClD,YAAY;GAAC,OAAO,EAAE;GAAE,MAAM;GAAE,OAAO;GAAC;EACxC,cAAc;EACd,MAAM;EACN,sBAAsB;EACvB,CAAC;CAKF,MAAM,EAAC,mBAAmB,qBAAoB,gBAAgB;EAHnB,SAAS,SAAS,EAAC,SAAS,sBAAqB,CAAC;EAC9C,WAAW,SAAS,EAAC,SAAS,sBAAqB,CAAC;EAC1D,QAAQ,SAAS;GAAC,SAAS;GAAsB,MAAM;GAAU,CAAC;EACvB,CAAC;CAErF,MAAMC,gBAA4C,UAAU,MAAM,MAAsB,EAAE,SAAS,gBAAgB;AAEnH,KAAI,SACF,QACE,4CACG,SAAS;EACR;EACA;EACA;EACA;EACD,CAAC,GACD;AAIP,QACE,qBAAC;EAAI,WAAW,GAAG,OAAO,SAAS,UAAU;aAC3C,qBAAC;GACC,KAAK,KAAK;GACV,MAAK;GACL,UAAU;GACV,cAAW;GACX,GAAI,mBAAmB;GACvB,WAAW,OAAO;;IAEjB,iBAAiB,oBAAC;KAAK,WAAW,OAAO;eAAkB,cAAc;MAAa;IACvF,oBAAC;KAAK,WAAW,OAAO;eAAkB,eAAe,eAAe;MAAuB;IAC9F,wBAAwB,oBAACC,wBAAc;;IACjC,EAER,UAAU,wBACT,oBAAC,4BACC,oBAAC;GAA8B;GAAS,OAAO;aAC7C,oBAAC;IACC,KAAK,KAAK;IACV,OAAO;IACP,GAAI,kBAAkB;IACtB,WAAW,OAAO;IAClB,MAAK;IACL,cAAW;cAEV,UAAU,KAAK,SACd,qBAAC;KAEC,MAAK;KACL,MAAK;KACL,iBAAe,KAAK,SAAS;KAC7B,WAAW,GAAG,OAAO,WAAW,KAAK,SAAS,mBAAmB,OAAO,gBAAgB;KACxF,eAAe;AACb,uBAAiB,KAAK,KAAK;AAC3B,gBAAU,MAAM;;;MAGlB,oBAAC;OAAK,WAAW,OAAO;iBAAiB,KAAK;QAAa;MAC3D,oBAAC;OAAK,WAAW,OAAO;iBAAiB,KAAK;QAAmB;MAChE,KAAK,SAAS,mBACb,oBAAC;OAAK,WAAW,OAAO;iBACtB,oBAACC,kBAAQ;QACJ;;OAfJ,KAAK,KAiBH,CACT;KACE;IACe,GACR;GAEf;;AAIV,mCAAe"}
@@ -33,6 +33,11 @@ export interface BaseUserDropdownProps {
33
33
  * Whether the user data is currently loading
34
34
  */
35
35
  isLoading?: boolean;
36
+ /**
37
+ * Label for the "Manage Profile" menu item. Defaults to `'Manage Profile'`; set this
38
+ * to relabel the action (e.g. `'Manage Account'`) without replacing the whole item.
39
+ */
40
+ manageProfileLabel?: string;
36
41
  /**
37
42
  * Menu items to display in the dropdown
38
43
  */