@thunderid/react 1.8.0 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/dist/cjs/components/account/UserProfile/BaseUserProfile.cjs +1 -1
  2. package/dist/cjs/components/admin/AgentDetails/AgentDetails.cjs +13 -2
  3. package/dist/cjs/components/admin/AgentDetails/AgentDetails.cjs.map +1 -1
  4. package/dist/cjs/components/admin/AgentDetails/BaseAgentDetails.cjs +25 -7
  5. package/dist/cjs/components/admin/AgentDetails/BaseAgentDetails.cjs.map +1 -1
  6. package/dist/cjs/components/admin/ApplicationDetails/ApplicationDetails.cjs +15 -2
  7. package/dist/cjs/components/admin/ApplicationDetails/ApplicationDetails.cjs.map +1 -1
  8. package/dist/cjs/components/admin/ApplicationDetails/BaseApplicationDetails.cjs +24 -7
  9. package/dist/cjs/components/admin/ApplicationDetails/BaseApplicationDetails.cjs.map +1 -1
  10. package/dist/cjs/components/admin/GroupMembers/GroupMembers.cjs +2 -1
  11. package/dist/cjs/components/admin/GroupMembers/GroupMembers.cjs.map +1 -1
  12. package/dist/cjs/components/admin/RoleAssignments/RoleAssignments.cjs +2 -1
  13. package/dist/cjs/components/admin/RoleAssignments/RoleAssignments.cjs.map +1 -1
  14. package/dist/cjs/components/admin/UserDetails/BaseUserDetails.cjs +32 -14
  15. package/dist/cjs/components/admin/UserDetails/BaseUserDetails.cjs.map +1 -1
  16. package/dist/cjs/components/admin/UserDetails/UserDetails.cjs +14 -2
  17. package/dist/cjs/components/admin/UserDetails/UserDetails.cjs.map +1 -1
  18. package/dist/cjs/components/admin/shared/AccountLifecycleParts.cjs +105 -0
  19. package/dist/cjs/components/admin/shared/AccountLifecycleParts.cjs.map +1 -0
  20. package/dist/cjs/components/admin/shared/ApplicationFormFields.cjs +1 -1
  21. package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs +4 -5
  22. package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
  23. package/dist/cjs/components/auth/SignIn/SignIn.cjs +5 -5
  24. package/dist/cjs/components/auth/SignIn/SignIn.cjs.map +1 -1
  25. package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +4 -5
  26. package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
  27. package/dist/cjs/components/auth/flow/Consent.cjs +53 -28
  28. package/dist/cjs/components/auth/flow/Consent.cjs.map +1 -1
  29. package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.cjs +104 -0
  30. package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.cjs.map +1 -0
  31. package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.styles.cjs +59 -0
  32. package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.styles.cjs.map +1 -0
  33. package/dist/cjs/components/auth/flow/ConsentDetailField.cjs +171 -0
  34. package/dist/cjs/components/auth/flow/ConsentDetailField.cjs.map +1 -0
  35. package/dist/cjs/components/auth/flow/ConsentDetailField.styles.cjs +85 -0
  36. package/dist/cjs/components/auth/flow/ConsentDetailField.styles.cjs.map +1 -0
  37. package/dist/cjs/components/auth/flow/ConsentDetailText.cjs +63 -0
  38. package/dist/cjs/components/auth/flow/ConsentDetailText.cjs.map +1 -0
  39. package/dist/cjs/components/auth/flow/ConsentDetailText.styles.cjs +83 -0
  40. package/dist/cjs/components/auth/flow/ConsentDetailText.styles.cjs.map +1 -0
  41. package/dist/cjs/components/auth/flow/FieldFactory.cjs +1 -1
  42. package/dist/cjs/components/auth/flow/resolveConsentText.cjs +25 -0
  43. package/dist/cjs/components/auth/flow/resolveConsentText.cjs.map +1 -0
  44. package/dist/cjs/components/primitives/KeyValueInput/KeyValueInput.cjs +1 -1
  45. package/dist/cjs/components/primitives/MultiInput/MultiInput.cjs +1 -1
  46. package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs +1 -1
  47. package/dist/cjs/contexts/Theme/ThemeProvider.cjs +36 -6
  48. package/dist/cjs/contexts/Theme/ThemeProvider.cjs.map +1 -1
  49. package/dist/cjs/contexts/Theme/ThemeRootContext.cjs +12 -0
  50. package/dist/cjs/contexts/Theme/ThemeRootContext.cjs.map +1 -0
  51. package/dist/cjs/hooks/auth/useConsentDetailField.cjs +357 -0
  52. package/dist/cjs/hooks/auth/useConsentDetailField.cjs.map +1 -0
  53. package/dist/cjs/hooks/management/useAccountLifecycle.cjs +59 -0
  54. package/dist/cjs/hooks/management/useAccountLifecycle.cjs.map +1 -0
  55. package/dist/cjs/index.cjs +66 -1
  56. package/dist/cjs/utils/formatConsentDetailValue.cjs +26 -0
  57. package/dist/cjs/utils/formatConsentDetailValue.cjs.map +1 -0
  58. package/dist/cjs/utils/getConsentDetailLayout.cjs +44 -0
  59. package/dist/cjs/utils/getConsentDetailLayout.cjs.map +1 -0
  60. package/dist/cjs/utils/getConsentDetailListDisplay.cjs +30 -0
  61. package/dist/cjs/utils/getConsentDetailListDisplay.cjs.map +1 -0
  62. package/dist/cjs/utils/isConsentApprovalBlocked.cjs +41 -0
  63. package/dist/cjs/utils/isConsentApprovalBlocked.cjs.map +1 -0
  64. package/dist/cjs/utils/isConsentDetailPlainList.cjs +24 -0
  65. package/dist/cjs/utils/isConsentDetailPlainList.cjs.map +1 -0
  66. package/dist/cjs/utils/isConsentDetailStructured.cjs +15 -0
  67. package/dist/cjs/utils/isConsentDetailStructured.cjs.map +1 -0
  68. package/dist/cjs/utils/isConsentDetailTextClamped.cjs +25 -0
  69. package/dist/cjs/utils/isConsentDetailTextClamped.cjs.map +1 -0
  70. package/dist/components/account/UserProfile/BaseUserProfile.js +1 -1
  71. package/dist/components/admin/AgentDetails/AgentDetails.d.ts +8 -1
  72. package/dist/components/admin/AgentDetails/AgentDetails.d.ts.map +1 -1
  73. package/dist/components/admin/AgentDetails/AgentDetails.js +13 -2
  74. package/dist/components/admin/AgentDetails/AgentDetails.js.map +1 -1
  75. package/dist/components/admin/AgentDetails/BaseAgentDetails.d.ts +21 -1
  76. package/dist/components/admin/AgentDetails/BaseAgentDetails.d.ts.map +1 -1
  77. package/dist/components/admin/AgentDetails/BaseAgentDetails.js +25 -7
  78. package/dist/components/admin/AgentDetails/BaseAgentDetails.js.map +1 -1
  79. package/dist/components/admin/ApplicationDetails/ApplicationDetails.d.ts +15 -1
  80. package/dist/components/admin/ApplicationDetails/ApplicationDetails.d.ts.map +1 -1
  81. package/dist/components/admin/ApplicationDetails/ApplicationDetails.js +15 -2
  82. package/dist/components/admin/ApplicationDetails/ApplicationDetails.js.map +1 -1
  83. package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.d.ts +20 -1
  84. package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.d.ts.map +1 -1
  85. package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.js +24 -7
  86. package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.js.map +1 -1
  87. package/dist/components/admin/GroupMembers/GroupMembers.d.ts +7 -0
  88. package/dist/components/admin/GroupMembers/GroupMembers.d.ts.map +1 -1
  89. package/dist/components/admin/GroupMembers/GroupMembers.js +2 -1
  90. package/dist/components/admin/GroupMembers/GroupMembers.js.map +1 -1
  91. package/dist/components/admin/RoleAssignments/RoleAssignments.d.ts +7 -0
  92. package/dist/components/admin/RoleAssignments/RoleAssignments.d.ts.map +1 -1
  93. package/dist/components/admin/RoleAssignments/RoleAssignments.js +2 -1
  94. package/dist/components/admin/RoleAssignments/RoleAssignments.js.map +1 -1
  95. package/dist/components/admin/UserDetails/BaseUserDetails.d.ts +22 -1
  96. package/dist/components/admin/UserDetails/BaseUserDetails.d.ts.map +1 -1
  97. package/dist/components/admin/UserDetails/BaseUserDetails.js +32 -14
  98. package/dist/components/admin/UserDetails/BaseUserDetails.js.map +1 -1
  99. package/dist/components/admin/UserDetails/UserDetails.d.ts +15 -1
  100. package/dist/components/admin/UserDetails/UserDetails.d.ts.map +1 -1
  101. package/dist/components/admin/UserDetails/UserDetails.js +14 -2
  102. package/dist/components/admin/UserDetails/UserDetails.js.map +1 -1
  103. package/dist/components/admin/shared/AccountLifecycleParts.d.ts +32 -0
  104. package/dist/components/admin/shared/AccountLifecycleParts.d.ts.map +1 -0
  105. package/dist/components/admin/shared/AccountLifecycleParts.js +101 -0
  106. package/dist/components/admin/shared/AccountLifecycleParts.js.map +1 -0
  107. package/dist/components/admin/shared/ApplicationFormFields.js +1 -1
  108. package/dist/components/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
  109. package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js +5 -6
  110. package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
  111. package/dist/components/auth/SignIn/SignIn.d.ts.map +1 -1
  112. package/dist/components/auth/SignIn/SignIn.js +6 -6
  113. package/dist/components/auth/SignIn/SignIn.js.map +1 -1
  114. package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
  115. package/dist/components/auth/flow/AuthOptionFactory.js +5 -6
  116. package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
  117. package/dist/components/auth/flow/Consent.d.ts +6 -0
  118. package/dist/components/auth/flow/Consent.d.ts.map +1 -1
  119. package/dist/components/auth/flow/Consent.js +54 -29
  120. package/dist/components/auth/flow/Consent.js.map +1 -1
  121. package/dist/components/auth/flow/ConsentAuthorizationDetail.d.ts +68 -0
  122. package/dist/components/auth/flow/ConsentAuthorizationDetail.d.ts.map +1 -0
  123. package/dist/components/auth/flow/ConsentAuthorizationDetail.js +100 -0
  124. package/dist/components/auth/flow/ConsentAuthorizationDetail.js.map +1 -0
  125. package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.d.ts +10 -0
  126. package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.d.ts.map +1 -0
  127. package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.js +57 -0
  128. package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.js.map +1 -0
  129. package/dist/components/auth/flow/ConsentDetailField.d.ts +39 -0
  130. package/dist/components/auth/flow/ConsentDetailField.d.ts.map +1 -0
  131. package/dist/components/auth/flow/ConsentDetailField.js +168 -0
  132. package/dist/components/auth/flow/ConsentDetailField.js.map +1 -0
  133. package/dist/components/auth/flow/ConsentDetailField.styles.d.ts +11 -0
  134. package/dist/components/auth/flow/ConsentDetailField.styles.d.ts.map +1 -0
  135. package/dist/components/auth/flow/ConsentDetailField.styles.js +83 -0
  136. package/dist/components/auth/flow/ConsentDetailField.styles.js.map +1 -0
  137. package/dist/components/auth/flow/ConsentDetailText.d.ts +53 -0
  138. package/dist/components/auth/flow/ConsentDetailText.d.ts.map +1 -0
  139. package/dist/components/auth/flow/ConsentDetailText.js +58 -0
  140. package/dist/components/auth/flow/ConsentDetailText.js.map +1 -0
  141. package/dist/components/auth/flow/ConsentDetailText.styles.d.ts +20 -0
  142. package/dist/components/auth/flow/ConsentDetailText.styles.d.ts.map +1 -0
  143. package/dist/components/auth/flow/ConsentDetailText.styles.js +80 -0
  144. package/dist/components/auth/flow/ConsentDetailText.styles.js.map +1 -0
  145. package/dist/components/auth/flow/FieldFactory.js +1 -1
  146. package/dist/components/auth/flow/resolveConsentText.d.ts +13 -0
  147. package/dist/components/auth/flow/resolveConsentText.d.ts.map +1 -0
  148. package/dist/components/auth/flow/resolveConsentText.js +23 -0
  149. package/dist/components/auth/flow/resolveConsentText.js.map +1 -0
  150. package/dist/components/primitives/KeyValueInput/KeyValueInput.js +1 -1
  151. package/dist/components/primitives/MultiInput/MultiInput.js +1 -1
  152. package/dist/components/primitives/PasswordField/PasswordField.js +1 -1
  153. package/dist/contexts/Theme/ThemeProvider.d.ts +2 -1
  154. package/dist/contexts/Theme/ThemeProvider.d.ts.map +1 -1
  155. package/dist/contexts/Theme/ThemeProvider.js +37 -7
  156. package/dist/contexts/Theme/ThemeProvider.js.map +1 -1
  157. package/dist/contexts/Theme/ThemeRootContext.d.ts +11 -0
  158. package/dist/contexts/Theme/ThemeRootContext.d.ts.map +1 -0
  159. package/dist/contexts/Theme/ThemeRootContext.js +10 -0
  160. package/dist/contexts/Theme/ThemeRootContext.js.map +1 -0
  161. package/dist/hooks/auth/useConsentDetailField.d.ts +130 -0
  162. package/dist/hooks/auth/useConsentDetailField.d.ts.map +1 -0
  163. package/dist/hooks/auth/useConsentDetailField.js +354 -0
  164. package/dist/hooks/auth/useConsentDetailField.js.map +1 -0
  165. package/dist/hooks/management/useAccountLifecycle.d.ts +49 -0
  166. package/dist/hooks/management/useAccountLifecycle.d.ts.map +1 -0
  167. package/dist/hooks/management/useAccountLifecycle.js +56 -0
  168. package/dist/hooks/management/useAccountLifecycle.js.map +1 -0
  169. package/dist/index.d.ts +16 -4
  170. package/dist/index.d.ts.map +1 -1
  171. package/dist/index.js +11 -3
  172. package/dist/utils/formatConsentDetailValue.d.ts +16 -0
  173. package/dist/utils/formatConsentDetailValue.d.ts.map +1 -0
  174. package/dist/utils/formatConsentDetailValue.js +25 -0
  175. package/dist/utils/formatConsentDetailValue.js.map +1 -0
  176. package/dist/utils/getConsentDetailLayout.d.ts +32 -0
  177. package/dist/utils/getConsentDetailLayout.d.ts.map +1 -0
  178. package/dist/utils/getConsentDetailLayout.js +43 -0
  179. package/dist/utils/getConsentDetailLayout.js.map +1 -0
  180. package/dist/utils/getConsentDetailListDisplay.d.ts +30 -0
  181. package/dist/utils/getConsentDetailListDisplay.d.ts.map +1 -0
  182. package/dist/utils/getConsentDetailListDisplay.js +30 -0
  183. package/dist/utils/getConsentDetailListDisplay.js.map +1 -0
  184. package/dist/utils/isConsentApprovalBlocked.d.ts +17 -0
  185. package/dist/utils/isConsentApprovalBlocked.d.ts.map +1 -0
  186. package/dist/utils/isConsentApprovalBlocked.js +39 -0
  187. package/dist/utils/isConsentApprovalBlocked.js.map +1 -0
  188. package/dist/utils/isConsentDetailPlainList.d.ts +15 -0
  189. package/dist/utils/isConsentDetailPlainList.d.ts.map +1 -0
  190. package/dist/utils/isConsentDetailPlainList.js +23 -0
  191. package/dist/utils/isConsentDetailPlainList.js.map +1 -0
  192. package/dist/utils/isConsentDetailStructured.d.ts +10 -0
  193. package/dist/utils/isConsentDetailStructured.d.ts.map +1 -0
  194. package/dist/utils/isConsentDetailStructured.js +14 -0
  195. package/dist/utils/isConsentDetailStructured.js.map +1 -0
  196. package/dist/utils/isConsentDetailTextClamped.d.ts +20 -0
  197. package/dist/utils/isConsentDetailTextClamped.d.ts.map +1 -0
  198. package/dist/utils/isConsentDetailTextClamped.js +24 -0
  199. package/dist/utils/isConsentDetailTextClamped.js.map +1 -0
  200. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentAuthorizationDetail.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/flow/ConsentAuthorizationDetail.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAM,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAA2B,MAAM,oBAAoB,CAAC;AAC5G,OAAO,EAAmB,EAAE,EAAE,SAAS,EAAY,MAAM,OAAO,CAAC;AAOjE,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAM7D;;GAEG;AACH,MAAM,WAAW,qCAAqC;IACpD,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,OAAO,EAAE,aAAa,CAAC;IACvB,0EAA0E;IAC1E,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,8FAA8F;IAC9F,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,kGAAkG;IAClG,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qCAAqC,KAAK,SAAS,CAAC;IACvE,+DAA+D;IAC/D,OAAO,EAAE,aAAa,CAAC;IACvB,gGAAgG;IAChG,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kEAAkE;IAClE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CACzB;AAED;;;;;;GAMG;AACH,QAAA,MAAM,0BAA0B,EAAE,EAAE,CAAC,+BAA+B,CAgGnE,CAAC;AAEF,eAAe,0BAA0B,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { cx } from "../../../styles/emotion.js";
2
+ import useTheme_default from "../../../contexts/Theme/useTheme.js";
3
+ import Typography_default from "../../primitives/Typography/Typography.js";
4
+ import ConsentAuthorizationDetail_styles_default from "./ConsentAuthorizationDetail.styles.js";
5
+ import Toggle_default from "../../primitives/Toggle/Toggle.js";
6
+ import { getConsentOptionalKey } from "./ConsentCheckboxList.js";
7
+ import resolveConsentText_default from "./resolveConsentText.js";
8
+ import ConsentDetailText_default from "./ConsentDetailText.js";
9
+ import getConsentDetailLayout_default, { CONSENT_DETAIL_DISPLAY_LIMITS } from "../../../utils/getConsentDetailLayout.js";
10
+ import ConsentDetailField_default from "./ConsentDetailField.js";
11
+ import { bem, withVendorCSSClassPrefix } from "@thunderid/browser";
12
+ import { useEffect } from "react";
13
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
+
15
+ //#region src/components/auth/flow/ConsentAuthorizationDetail.tsx
16
+ /**
17
+ * Renders one RFC 9396 authorization detail element: the server-rendered summary, the detail's fields,
18
+ * which are read-only unless the user may modify them, and a single toggle that approves or declines the
19
+ * detail as a whole. The summary and labels come from the server and are not translated again.
20
+ * Authorization details reach the consent step only on a sign-in started from an authorization request, so
21
+ * this renders in an authorization server UI (hosted login); an app-native sign-in flow cannot carry them.
22
+ */
23
+ const ConsentAuthorizationDetail = ({ children = void 0, element, formValues, onInputChange, purposeId, t = void 0 }) => {
24
+ const { theme, colorScheme } = useTheme_default();
25
+ const styles = ConsentAuthorizationDetail_styles_default(theme, colorScheme);
26
+ const key = getConsentOptionalKey(purposeId, element.name);
27
+ const isApproved = formValues[key] !== "false";
28
+ const rows = element.rows ?? [];
29
+ const summary = element.summary ?? element.detailType ?? element.name;
30
+ const handleChange = (checked) => {
31
+ onInputChange(key, checked ? "true" : "false");
32
+ };
33
+ useEffect(() => {
34
+ if (formValues[key] === void 0) onInputChange(key, "true");
35
+ }, [
36
+ formValues,
37
+ key,
38
+ onInputChange
39
+ ]);
40
+ if (children) return /* @__PURE__ */ jsx(Fragment$1, { children: children({
41
+ detailType: element.detailType,
42
+ element,
43
+ handleChange,
44
+ isApproved,
45
+ rows,
46
+ summary
47
+ }) });
48
+ return /* @__PURE__ */ jsxs("div", {
49
+ className: cx(withVendorCSSClassPrefix(bem("consent-authorization-detail")), styles["card"]),
50
+ children: [
51
+ /* @__PURE__ */ jsx(ConsentDetailText_default, {
52
+ id: `consent_authz_detail_${purposeId}_${element.name}_summary`,
53
+ className: withVendorCSSClassPrefix(bem("consent-authorization-detail", "summary")),
54
+ variant: "subtitle2",
55
+ fontWeight: "bold",
56
+ maxChars: CONSENT_DETAIL_DISPLAY_LIMITS.summaryChars,
57
+ maxLines: CONSENT_DETAIL_DISPLAY_LIMITS.summaryLines,
58
+ t,
59
+ text: summary
60
+ }),
61
+ rows.length > 0 && /* @__PURE__ */ jsx("div", {
62
+ className: cx(withVendorCSSClassPrefix(bem("consent-authorization-detail", "rows")), styles["rows"]),
63
+ children: rows.map((row) => {
64
+ const stacked = getConsentDetailLayout_default(row) === "stacked";
65
+ return /* @__PURE__ */ jsxs("div", {
66
+ className: cx(withVendorCSSClassPrefix(bem("consent-authorization-detail", "row")), stacked && withVendorCSSClassPrefix(bem("consent-authorization-detail", "row", "stacked")), stacked ? styles["stackedRow"] : styles["row"]),
67
+ children: [/* @__PURE__ */ jsx(Typography_default, {
68
+ variant: "body2",
69
+ className: cx(withVendorCSSClassPrefix(bem("consent-authorization-detail", "label")), styles["label"]),
70
+ children: row.label || row.path
71
+ }), /* @__PURE__ */ jsx("div", {
72
+ className: cx(withVendorCSSClassPrefix(bem("consent-authorization-detail", "value")), stacked ? styles["stackedValue"] : styles["value"]),
73
+ children: /* @__PURE__ */ jsx(ConsentDetailField_default, {
74
+ align: stacked ? "start" : "end",
75
+ detailId: element.name,
76
+ purposeId,
77
+ row,
78
+ formValues,
79
+ onInputChange,
80
+ t
81
+ })
82
+ })]
83
+ }, row.path);
84
+ })
85
+ }),
86
+ /* @__PURE__ */ jsx(Toggle_default, {
87
+ id: `consent_opt_${purposeId}_${element.name}`,
88
+ className: withVendorCSSClassPrefix(bem("consent-authorization-detail", "approve")),
89
+ label: resolveConsentText_default(t, "consent.authorization_details.approve"),
90
+ checked: isApproved,
91
+ onChange: (e) => handleChange(e.target.checked)
92
+ })
93
+ ]
94
+ });
95
+ };
96
+ var ConsentAuthorizationDetail_default = ConsentAuthorizationDetail;
97
+
98
+ //#endregion
99
+ export { ConsentAuthorizationDetail_default as default };
100
+ //# sourceMappingURL=ConsentAuthorizationDetail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentAuthorizationDetail.js","names":["ConsentAuthorizationDetail: FC<ConsentAuthorizationDetailProps>","useTheme","styles: Record<string, string>","useStyles","key: string","isApproved: boolean","rows: ConsentDetailRow[]","summary: string","ConsentDetailText","stacked: boolean","getConsentDetailLayout","Typography","ConsentDetailField","Toggle","resolveConsentText"],"sources":["../../../../src/components/auth/flow/ConsentAuthorizationDetail.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {bem, type ConsentDetailRow, type PromptElement, withVendorCSSClassPrefix} from '@thunderid/browser';\nimport {type ChangeEvent, FC, ReactNode, useEffect} from 'react';\nimport useStyles from './ConsentAuthorizationDetail.styles';\nimport {getConsentOptionalKey} from './ConsentCheckboxList';\nimport ConsentDetailField from './ConsentDetailField';\nimport ConsentDetailText from './ConsentDetailText';\nimport resolveConsentText from './resolveConsentText';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {UseTranslation} from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport getConsentDetailLayout, {CONSENT_DETAIL_DISPLAY_LIMITS} from '../../../utils/getConsentDetailLayout';\nimport Toggle from '../../primitives/Toggle/Toggle';\nimport Typography from '../../primitives/Typography/Typography';\n\n/**\n * Render props exposed by ConsentAuthorizationDetail when using the render-prop pattern.\n */\nexport interface ConsentAuthorizationDetailRenderProps {\n /** RFC 9396 authorization details type of the detail. */\n detailType?: string;\n /** The detail's consent element. */\n element: PromptElement;\n /** Call this when the user approves or declines the detail as a whole. */\n handleChange: (checked: boolean) => void;\n /**\n * Whether the detail is approved. A detail is the transaction the user is asked to allow, so it counts as\n * approved until the user declines it.\n */\n isApproved: boolean;\n /** Fields of the detail; render each with `ConsentDetailField` or `useConsentDetailField`. */\n rows: ConsentDetailRow[];\n /** Server-rendered sentence describing the detail, or its type or identifier when it has none. */\n summary: string;\n}\n\n/**\n * Props for the ConsentAuthorizationDetail component.\n */\nexport interface ConsentAuthorizationDetailProps {\n /**\n * Render-props callback. When provided, the default detail UI is replaced with whatever JSX the\n * callback returns.\n *\n * @example\n * ```tsx\n * <ConsentAuthorizationDetail purposeId={purpose.purposeId} element={element} formValues={formValues} onInputChange={onChange}>\n * {({summary, rows, isApproved, handleChange}) => (\n * <section>\n * <h3>{summary}</h3>\n * {rows.map(row => (\n * <ConsentDetailField key={row.path} purposeId={purpose.purposeId} detailId={element.name} row={row} formValues={formValues} onInputChange={onChange} />\n * ))}\n * <Switch checked={isApproved} onChange={e => handleChange(e.target.checked)} />\n * </section>\n * )}\n * </ConsentAuthorizationDetail>\n * ```\n */\n children?: (props: ConsentAuthorizationDetailRenderProps) => ReactNode;\n /** The authorization detail element of the consent purpose. */\n element: PromptElement;\n /** Current form values, holding the approval of the detail and the values the user modified. */\n formValues: Record<string, string>;\n /** Callback invoked with a consent form key and its new value. */\n onInputChange: (name: string, value: string) => void;\n /** The identifier of the authorization details purpose the detail belongs to. */\n purposeId: string;\n /** translation data */\n t?: UseTranslation['t'];\n}\n\n/**\n * Renders one RFC 9396 authorization detail element: the server-rendered summary, the detail's fields,\n * which are read-only unless the user may modify them, and a single toggle that approves or declines the\n * detail as a whole. The summary and labels come from the server and are not translated again.\n * Authorization details reach the consent step only on a sign-in started from an authorization request, so\n * this renders in an authorization server UI (hosted login); an app-native sign-in flow cannot carry them.\n */\nconst ConsentAuthorizationDetail: FC<ConsentAuthorizationDetailProps> = ({\n children = undefined,\n element,\n formValues,\n onInputChange,\n purposeId,\n t = undefined,\n}: ConsentAuthorizationDetailProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme);\n\n const key: string = getConsentOptionalKey(purposeId, element.name);\n const isApproved: boolean = formValues[key] !== 'false';\n const rows: ConsentDetailRow[] = element.rows ?? [];\n const summary: string = element.summary ?? element.detailType ?? element.name;\n\n const handleChange = (checked: boolean): void => {\n onInputChange(key, checked ? 'true' : 'false');\n };\n\n // The detail starts approved. The value is seeded into the form so the submitted decision matches the\n // toggle when the detail is rendered outside Consent, which seeds it the same way.\n useEffect(() => {\n if (formValues[key] === undefined) {\n onInputChange(key, 'true');\n }\n }, [formValues, key, onInputChange]);\n\n if (children) {\n return <>{children({detailType: element.detailType, element, handleChange, isApproved, rows, summary})}</>;\n }\n\n return (\n <div className={cx(withVendorCSSClassPrefix(bem('consent-authorization-detail')), styles['card'])}>\n <ConsentDetailText\n id={`consent_authz_detail_${purposeId}_${element.name}_summary`}\n className={withVendorCSSClassPrefix(bem('consent-authorization-detail', 'summary'))}\n variant=\"subtitle2\"\n fontWeight=\"bold\"\n maxChars={CONSENT_DETAIL_DISPLAY_LIMITS.summaryChars}\n maxLines={CONSENT_DETAIL_DISPLAY_LIMITS.summaryLines}\n t={t}\n text={summary}\n />\n {rows.length > 0 && (\n <div className={cx(withVendorCSSClassPrefix(bem('consent-authorization-detail', 'rows')), styles['rows'])}>\n {rows.map((row: ConsentDetailRow) => {\n const stacked: boolean = getConsentDetailLayout(row) === 'stacked';\n return (\n <div\n key={row.path}\n className={cx(\n withVendorCSSClassPrefix(bem('consent-authorization-detail', 'row')),\n stacked && withVendorCSSClassPrefix(bem('consent-authorization-detail', 'row', 'stacked')),\n stacked ? styles['stackedRow'] : styles['row'],\n )}\n >\n <Typography\n variant=\"body2\"\n className={cx(\n withVendorCSSClassPrefix(bem('consent-authorization-detail', 'label')),\n styles['label'],\n )}\n >\n {row.label || row.path}\n </Typography>\n <div\n className={cx(\n withVendorCSSClassPrefix(bem('consent-authorization-detail', 'value')),\n stacked ? styles['stackedValue'] : styles['value'],\n )}\n >\n <ConsentDetailField\n align={stacked ? 'start' : 'end'}\n detailId={element.name}\n purposeId={purposeId}\n row={row}\n formValues={formValues}\n onInputChange={onInputChange}\n t={t}\n />\n </div>\n </div>\n );\n })}\n </div>\n )}\n <Toggle\n id={`consent_opt_${purposeId}_${element.name}`}\n className={withVendorCSSClassPrefix(bem('consent-authorization-detail', 'approve'))}\n label={resolveConsentText(t, 'consent.authorization_details.approve')}\n checked={isApproved}\n onChange={(e: ChangeEvent<HTMLInputElement>): void => handleChange(e.target.checked)}\n />\n </div>\n );\n};\n\nexport default ConsentAuthorizationDetail;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiFA,MAAMA,8BAAmE,EACvE,WAAW,QACX,SACA,YACA,eACA,WACA,IAAI,aACiC;CACrC,MAAM,EAAC,OAAO,gBAA4CC,kBAAU;CACpE,MAAMC,SAAiCC,0CAAU,OAAO,YAAY;CAEpE,MAAMC,MAAc,sBAAsB,WAAW,QAAQ,KAAK;CAClE,MAAMC,aAAsB,WAAW,SAAS;CAChD,MAAMC,OAA2B,QAAQ,QAAQ,EAAE;CACnD,MAAMC,UAAkB,QAAQ,WAAW,QAAQ,cAAc,QAAQ;CAEzE,MAAM,gBAAgB,YAA2B;AAC/C,gBAAc,KAAK,UAAU,SAAS,QAAQ;;AAKhD,iBAAgB;AACd,MAAI,WAAW,SAAS,OACtB,eAAc,KAAK,OAAO;IAE3B;EAAC;EAAY;EAAK;EAAc,CAAC;AAEpC,KAAI,SACF,QAAO,4CAAG,SAAS;EAAC,YAAY,QAAQ;EAAY;EAAS;EAAc;EAAY;EAAM;EAAQ,CAAC,GAAI;AAG5G,QACE,qBAAC;EAAI,WAAW,GAAG,yBAAyB,IAAI,+BAA+B,CAAC,EAAE,OAAO,QAAQ;;GAC/F,oBAACC;IACC,IAAI,wBAAwB,UAAU,GAAG,QAAQ,KAAK;IACtD,WAAW,yBAAyB,IAAI,gCAAgC,UAAU,CAAC;IACnF,SAAQ;IACR,YAAW;IACX,UAAU,8BAA8B;IACxC,UAAU,8BAA8B;IACrC;IACH,MAAM;KACN;GACD,KAAK,SAAS,KACb,oBAAC;IAAI,WAAW,GAAG,yBAAyB,IAAI,gCAAgC,OAAO,CAAC,EAAE,OAAO,QAAQ;cACtG,KAAK,KAAK,QAA0B;KACnC,MAAMC,UAAmBC,+BAAuB,IAAI,KAAK;AACzD,YACE,qBAAC;MAEC,WAAW,GACT,yBAAyB,IAAI,gCAAgC,MAAM,CAAC,EACpE,WAAW,yBAAyB,IAAI,gCAAgC,OAAO,UAAU,CAAC,EAC1F,UAAU,OAAO,gBAAgB,OAAO,OACzC;iBAED,oBAACC;OACC,SAAQ;OACR,WAAW,GACT,yBAAyB,IAAI,gCAAgC,QAAQ,CAAC,EACtE,OAAO,SACR;iBAEA,IAAI,SAAS,IAAI;QACP,EACb,oBAAC;OACC,WAAW,GACT,yBAAyB,IAAI,gCAAgC,QAAQ,CAAC,EACtE,UAAU,OAAO,kBAAkB,OAAO,SAC3C;iBAED,oBAACC;QACC,OAAO,UAAU,UAAU;QAC3B,UAAU,QAAQ;QACP;QACN;QACO;QACG;QACZ;SACH;QACE;QA/BD,IAAI,KAgCL;MAER;KACE;GAER,oBAACC;IACC,IAAI,eAAe,UAAU,GAAG,QAAQ;IACxC,WAAW,yBAAyB,IAAI,gCAAgC,UAAU,CAAC;IACnF,OAAOC,2BAAmB,GAAG,wCAAwC;IACrE,SAAS;IACT,WAAW,MAA2C,aAAa,EAAE,OAAO,QAAQ;KACpF;;GACE;;AAIV,yCAAe"}
@@ -0,0 +1,10 @@
1
+ import { Theme } from '@thunderid/browser';
2
+ /**
3
+ * Creates styles for the ConsentAuthorizationDetail 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=ConsentAuthorizationDetail.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentAuthorizationDetail.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/flow/ConsentAuthorizationDetail.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC;;;;;GAKG;AACH,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,EAAE,aAAa,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CA6BzE,CAAC;AAEJ,eAAe,SAAS,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { css } from "../../../styles/emotion.js";
2
+ import { useMemo } from "react";
3
+
4
+ //#region src/components/auth/flow/ConsentAuthorizationDetail.styles.ts
5
+ /**
6
+ * Creates styles for the ConsentAuthorizationDetail component.
7
+ * @param theme - The theme object containing design tokens
8
+ * @param colorScheme - The current color scheme (used for memoization)
9
+ * @returns Object containing CSS class names for component styling
10
+ */
11
+ const useStyles = (theme, colorScheme) => useMemo(() => ({
12
+ card: css({ marginTop: "0.5rem" }),
13
+ label: css({
14
+ flex: "1 1 auto",
15
+ lineHeight: 1.45,
16
+ minWidth: 0,
17
+ overflowWrap: "anywhere"
18
+ }),
19
+ row: css({
20
+ alignItems: "center",
21
+ display: "flex",
22
+ flexWrap: "wrap",
23
+ gap: "4px 1rem",
24
+ justifyContent: "space-between"
25
+ }),
26
+ rows: css({
27
+ display: "flex",
28
+ flexDirection: "column",
29
+ gap: "8px",
30
+ margin: "0.5rem 0"
31
+ }),
32
+ stackedRow: css({
33
+ display: "flex",
34
+ flexDirection: "column",
35
+ gap: "4px"
36
+ }),
37
+ stackedValue: css({
38
+ display: "flex",
39
+ maxWidth: "100%",
40
+ minWidth: 0
41
+ }),
42
+ value: css({
43
+ alignItems: "center",
44
+ display: "flex",
45
+ gap: "6px",
46
+ justifyContent: "flex-end",
47
+ marginLeft: "auto",
48
+ maxWidth: "100%",
49
+ minWidth: 0,
50
+ textAlign: "right"
51
+ })
52
+ }), [theme, colorScheme]);
53
+ var ConsentAuthorizationDetail_styles_default = useStyles;
54
+
55
+ //#endregion
56
+ export { ConsentAuthorizationDetail_styles_default as default };
57
+ //# sourceMappingURL=ConsentAuthorizationDetail.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentAuthorizationDetail.styles.js","names":[],"sources":["../../../../src/components/auth/flow/ConsentAuthorizationDetail.styles.ts"],"sourcesContent":["// Copyright 2026 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 ConsentAuthorizationDetail 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 useMemo(\n () => ({\n card: css({marginTop: '0.5rem'}),\n label: css({flex: '1 1 auto', lineHeight: 1.45, minWidth: 0, overflowWrap: 'anywhere'}),\n // A short field sits beside its label and drops below it when the two do not fit; a long one is\n // stacked, the label above the value, so neither squeezes the other.\n row: css({\n alignItems: 'center',\n display: 'flex',\n flexWrap: 'wrap',\n gap: '4px 1rem',\n justifyContent: 'space-between',\n }),\n rows: css({display: 'flex', flexDirection: 'column', gap: '8px', margin: '0.5rem 0'}),\n stackedRow: css({display: 'flex', flexDirection: 'column', gap: '4px'}),\n stackedValue: css({display: 'flex', maxWidth: '100%', minWidth: 0}),\n value: css({\n alignItems: 'center',\n display: 'flex',\n gap: '6px',\n justifyContent: 'flex-end',\n marginLeft: 'auto',\n maxWidth: '100%',\n minWidth: 0,\n textAlign: 'right',\n }),\n }),\n [theme, colorScheme],\n );\n\nexport default useStyles;\n"],"mappings":";;;;;;;;;;AAaA,MAAM,aAAa,OAAc,gBAC/B,eACS;CACL,MAAM,IAAI,EAAC,WAAW,UAAS,CAAC;CAChC,OAAO,IAAI;EAAC,MAAM;EAAY,YAAY;EAAM,UAAU;EAAG,cAAc;EAAW,CAAC;CAGvF,KAAK,IAAI;EACP,YAAY;EACZ,SAAS;EACT,UAAU;EACV,KAAK;EACL,gBAAgB;EACjB,CAAC;CACF,MAAM,IAAI;EAAC,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAO,QAAQ;EAAW,CAAC;CACrF,YAAY,IAAI;EAAC,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAM,CAAC;CACvE,cAAc,IAAI;EAAC,SAAS;EAAQ,UAAU;EAAQ,UAAU;EAAE,CAAC;CACnE,OAAO,IAAI;EACT,YAAY;EACZ,SAAS;EACT,KAAK;EACL,gBAAgB;EAChB,YAAY;EACZ,UAAU;EACV,UAAU;EACV,WAAW;EACZ,CAAC;CACH,GACD,CAAC,OAAO,YAAY,CACrB;AAEH,gDAAe"}
@@ -0,0 +1,39 @@
1
+ import { type ConsentDetailRow } from '@thunderid/browser';
2
+ import { FC, ReactNode } from 'react';
3
+ import { type UseConsentDetailFieldResult } from '../../../hooks/auth/useConsentDetailField';
4
+ import { UseTranslation } from '../../../hooks/useTranslation';
5
+ /**
6
+ * Props for the ConsentDetailField component.
7
+ */
8
+ export interface ConsentDetailFieldProps {
9
+ /** Side the value is aligned to: `end` beside its label, `start` when stacked below it. Defaults to `end`. */
10
+ align?: 'start' | 'end';
11
+ /**
12
+ * Render-props callback. When provided, the default field UI is replaced with whatever it returns, given
13
+ * the field's headless state from `useConsentDetailField`.
14
+ */
15
+ children?: (field: UseConsentDetailFieldResult) => ReactNode;
16
+ /** Current form values, holding the JSON text of each field the user changed. */
17
+ formValues: Record<string, string>;
18
+ /** Callback invoked with a consent form key and its new value. */
19
+ onInputChange: (name: string, value: string) => void;
20
+ /** The identifier of the authorization detail the field belongs to. */
21
+ detailId: string;
22
+ /** The identifier of the consent purpose the authorization detail belongs to. */
23
+ purposeId: string;
24
+ /** The field to render. */
25
+ row: ConsentDetailRow;
26
+ /** translation data */
27
+ t?: UseTranslation['t'];
28
+ }
29
+ /**
30
+ * Renders one field of an authorization detail. A field the user may modify before
31
+ * approving is editable, bounded by the value that was shown: a number or a date can only move in
32
+ * the allowed direction, and items can only be removed from, or added to, a list as its rule allows. Every other field is read-only.
33
+ * A number or a date the user enters outside its bound, or that is not a value at all, is shown with an error and
34
+ * is not submitted: the field's modification is cleared and the field is marked invalid, which blocks approval
35
+ * until the user corrects it. The server checks whatever is submitted.
36
+ */
37
+ declare const ConsentDetailField: FC<ConsentDetailFieldProps>;
38
+ export default ConsentDetailField;
39
+ //# sourceMappingURL=ConsentDetailField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentDetailField.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/flow/ConsentDetailField.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAM,KAAK,gBAAgB,EAA2B,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAmB,EAAE,EAAoC,SAAS,EAAC,MAAM,OAAO,CAAC;AAKxF,OAA8B,EAE5B,KAAK,2BAA2B,EACjC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAQ7D;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,8GAA8G;IAC9G,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,SAAS,CAAC;IAC7D,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kEAAkE;IAClE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,GAAG,EAAE,gBAAgB,CAAC;IACtB,uBAAuB;IACvB,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,QAAA,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAyNnD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,168 @@
1
+ import { cx } from "../../../styles/emotion.js";
2
+ import useTheme_default from "../../../contexts/Theme/useTheme.js";
3
+ import ConsentDetailField_styles_default from "./ConsentDetailField.styles.js";
4
+ import resolveConsentText_default from "./resolveConsentText.js";
5
+ import ConsentDetailText_default, { ConsentDetailToggle } from "./ConsentDetailText.js";
6
+ import formatConsentDetailValue_default from "../../../utils/formatConsentDetailValue.js";
7
+ import isConsentDetailStructured_default from "../../../utils/isConsentDetailStructured.js";
8
+ import { CONSENT_DETAIL_DISPLAY_LIMITS } from "../../../utils/getConsentDetailLayout.js";
9
+ import isConsentDetailPlainList_default from "../../../utils/isConsentDetailPlainList.js";
10
+ import useConsentDetailField_default from "../../../hooks/auth/useConsentDetailField.js";
11
+ import TextField_default from "../../primitives/TextField/TextField.js";
12
+ import { bem, withVendorCSSClassPrefix } from "@thunderid/browser";
13
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
+
15
+ //#region src/components/auth/flow/ConsentDetailField.tsx
16
+ /**
17
+ * Renders one field of an authorization detail. A field the user may modify before
18
+ * approving is editable, bounded by the value that was shown: a number or a date can only move in
19
+ * the allowed direction, and items can only be removed from, or added to, a list as its rule allows. Every other field is read-only.
20
+ * A number or a date the user enters outside its bound, or that is not a value at all, is shown with an error and
21
+ * is not submitted: the field's modification is cleared and the field is marked invalid, which blocks approval
22
+ * until the user corrects it. The server checks whatever is submitted.
23
+ */
24
+ const ConsentDetailField = ({ align = "end", children = void 0, formValues, onInputChange, detailId, purposeId, row, t = void 0 }) => {
25
+ const field = useConsentDetailField_default({
26
+ detailId,
27
+ formValues,
28
+ onInputChange,
29
+ purposeId,
30
+ row,
31
+ t
32
+ });
33
+ const { inputId, label, listDisplay } = field;
34
+ const { theme, colorScheme } = useTheme_default();
35
+ const styles = ConsentDetailField_styles_default(theme, colorScheme, align);
36
+ const fieldClass = withVendorCSSClassPrefix(bem("consent-detail-field"));
37
+ const collapse = (items) => items.slice(0, listDisplay.visibleCount);
38
+ const listToggle = listDisplay.isCollapsible && /* @__PURE__ */ jsx(ConsentDetailToggle, {
39
+ expanded: field.isListExpanded,
40
+ hiddenCount: listDisplay.hiddenCount,
41
+ onToggle: field.handleListToggle,
42
+ t
43
+ });
44
+ const chipClass = (modifier) => cx(withVendorCSSClassPrefix(bem("consent-detail-field", "chip")), withVendorCSSClassPrefix(bem("consent-detail-field", "chip", modifier)), styles[`${modifier}Chip`]);
45
+ const chipLabelClass = cx(withVendorCSSClassPrefix(bem("consent-detail-field", "chip-label")), styles["chipLabel"]);
46
+ const chipsClass = cx(fieldClass, withVendorCSSClassPrefix(bem("consent-detail-field", "chips")), styles["chips"]);
47
+ const inputClass = cx(fieldClass, withVendorCSSClassPrefix(bem("consent-detail-field", "input")), styles["input"]);
48
+ const valueClass = cx(fieldClass, withVendorCSSClassPrefix(bem("consent-detail-field", "value")));
49
+ if (children) return /* @__PURE__ */ jsx(Fragment, { children: children(field) });
50
+ if (field.kind === "number" || field.kind === "date") return /* @__PURE__ */ jsx(TextField_default, {
51
+ id: inputId,
52
+ className: inputClass,
53
+ type: field.kind,
54
+ step: field.kind === "number" ? "any" : void 0,
55
+ "aria-label": label,
56
+ max: field.max,
57
+ min: field.min,
58
+ value: field.text,
59
+ error: field.error?.message,
60
+ onChange: (e) => field.handleChange(e.target.value),
61
+ onBlur: field.handleBlur
62
+ });
63
+ if (field.kind === "removeItems") return /* @__PURE__ */ jsxs("div", {
64
+ className: chipsClass,
65
+ role: "group",
66
+ "aria-label": label,
67
+ children: [collapse(field.items.map(({ selected, toggleable, value }, index) => /* @__PURE__ */ jsxs("button", {
68
+ id: `${inputId}_${index}`,
69
+ type: "button",
70
+ className: chipClass(selected ? "kept" : "removed"),
71
+ title: String(value),
72
+ "aria-pressed": selected,
73
+ "aria-label": resolveConsentText_default(t, selected ? "consent.authorization_details.remove_item" : "consent.authorization_details.add_back_item", { item: String(value) }),
74
+ disabled: !toggleable,
75
+ onClick: () => field.handleToggle(value),
76
+ children: [/* @__PURE__ */ jsx("span", {
77
+ className: chipLabelClass,
78
+ children: String(value)
79
+ }), selected && toggleable && /* @__PURE__ */ jsx("span", {
80
+ "aria-hidden": "true",
81
+ children: "×"
82
+ })]
83
+ }, String(value)))), listToggle]
84
+ });
85
+ if (field.kind === "addItems") return /* @__PURE__ */ jsxs("div", {
86
+ className: chipsClass,
87
+ role: "group",
88
+ "aria-label": label,
89
+ children: [
90
+ collapse(field.items.map(({ origin, value }, index) => {
91
+ if (origin === "shown") return /* @__PURE__ */ jsx("span", {
92
+ id: `${inputId}_${index}`,
93
+ className: chipClass("kept"),
94
+ title: String(value),
95
+ children: /* @__PURE__ */ jsx("span", {
96
+ className: chipLabelClass,
97
+ children: String(value)
98
+ })
99
+ }, String(value));
100
+ return /* @__PURE__ */ jsxs("button", {
101
+ id: `${inputId}_${origin}_${String(value)}`,
102
+ type: "button",
103
+ className: chipClass(origin === "added" ? "kept" : "offered"),
104
+ title: String(value),
105
+ "aria-label": resolveConsentText_default(t, origin === "added" ? "consent.authorization_details.remove_item" : "consent.authorization_details.add_item", { item: String(value) }),
106
+ onClick: () => field.handleToggle(value),
107
+ children: [/* @__PURE__ */ jsxs("span", {
108
+ className: chipLabelClass,
109
+ children: [origin === "offered" && "+ ", String(value)]
110
+ }), origin === "added" && /* @__PURE__ */ jsx("span", {
111
+ "aria-hidden": "true",
112
+ children: "×"
113
+ })]
114
+ }, `${origin}-${String(value)}`);
115
+ })),
116
+ listToggle,
117
+ field.isTypedItemAllowed && /* @__PURE__ */ jsx(TextField_default, {
118
+ id: `${inputId}_new`,
119
+ className: inputClass,
120
+ "aria-label": resolveConsentText_default(t, "consent.authorization_details.new_item", { label }),
121
+ value: field.text,
122
+ onChange: (e) => field.handleChange(e.target.value),
123
+ onKeyDown: (e) => {
124
+ if (e.key === "Enter") {
125
+ e.preventDefault();
126
+ field.handleAdd(e.currentTarget.value);
127
+ }
128
+ }
129
+ })
130
+ ]
131
+ });
132
+ const textAlign = align === "end" ? "right" : "left";
133
+ if (isConsentDetailPlainList_default(row.value) && listDisplay.isCollapsible) {
134
+ const items = row.value.slice(0, listDisplay.visibleCount);
135
+ return /* @__PURE__ */ jsxs("div", {
136
+ className: cx(fieldClass, withVendorCSSClassPrefix(bem("consent-detail-field", "list")), styles["listText"]),
137
+ children: [/* @__PURE__ */ jsx(ConsentDetailText_default, {
138
+ align: textAlign,
139
+ fontWeight: "bold",
140
+ maxChars: Number.POSITIVE_INFINITY,
141
+ maxLines: Number.POSITIVE_INFINITY,
142
+ text: formatConsentDetailValue_default(items)
143
+ }), listToggle]
144
+ });
145
+ }
146
+ if (isConsentDetailStructured_default(row.value)) return /* @__PURE__ */ jsx(ConsentDetailText_default, {
147
+ className: valueClass,
148
+ monospace: true,
149
+ maxChars: Number.POSITIVE_INFINITY,
150
+ maxLines: CONSENT_DETAIL_DISPLAY_LIMITS.structuredLines,
151
+ t,
152
+ text: formatConsentDetailValue_default(row.value, 2)
153
+ });
154
+ return /* @__PURE__ */ jsx(ConsentDetailText_default, {
155
+ className: valueClass,
156
+ align: textAlign,
157
+ fontWeight: "bold",
158
+ maxChars: CONSENT_DETAIL_DISPLAY_LIMITS.valueChars,
159
+ maxLines: CONSENT_DETAIL_DISPLAY_LIMITS.valueLines,
160
+ t,
161
+ text: formatConsentDetailValue_default(row.value)
162
+ });
163
+ };
164
+ var ConsentDetailField_default = ConsentDetailField;
165
+
166
+ //#endregion
167
+ export { ConsentDetailField_default as default };
168
+ //# sourceMappingURL=ConsentDetailField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentDetailField.js","names":["ConsentDetailField: FC<ConsentDetailFieldProps>","field: UseConsentDetailFieldResult","useConsentDetailField","useTheme","styles: Record<string, string>","useStyles","fieldClass: string","listToggle: ReactNode","chipLabelClass: string","chipsClass: string","inputClass: string","valueClass: string","TextField","resolveConsentText","textAlign: 'left' | 'right'","isConsentDetailPlainList","items: (string | number | boolean)[]","ConsentDetailText","formatConsentDetailValue","isConsentDetailStructured"],"sources":["../../../../src/components/auth/flow/ConsentDetailField.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {bem, type ConsentDetailRow, withVendorCSSClassPrefix} from '@thunderid/browser';\nimport {type ChangeEvent, FC, type KeyboardEvent, ReactElement, ReactNode} from 'react';\nimport useStyles from './ConsentDetailField.styles';\nimport ConsentDetailText, {ConsentDetailToggle} from './ConsentDetailText';\nimport resolveConsentText from './resolveConsentText';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useConsentDetailField, {\n type ConsentDetailListItem,\n type UseConsentDetailFieldResult,\n} from '../../../hooks/auth/useConsentDetailField';\nimport {UseTranslation} from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport formatConsentDetailValue from '../../../utils/formatConsentDetailValue';\nimport {CONSENT_DETAIL_DISPLAY_LIMITS} from '../../../utils/getConsentDetailLayout';\nimport isConsentDetailPlainList from '../../../utils/isConsentDetailPlainList';\nimport isConsentDetailStructured from '../../../utils/isConsentDetailStructured';\nimport TextField from '../../primitives/TextField/TextField';\n\n/**\n * Props for the ConsentDetailField component.\n */\nexport interface ConsentDetailFieldProps {\n /** Side the value is aligned to: `end` beside its label, `start` when stacked below it. Defaults to `end`. */\n align?: 'start' | 'end';\n /**\n * Render-props callback. When provided, the default field UI is replaced with whatever it returns, given\n * the field's headless state from `useConsentDetailField`.\n */\n children?: (field: UseConsentDetailFieldResult) => ReactNode;\n /** Current form values, holding the JSON text of each field the user changed. */\n formValues: Record<string, string>;\n /** Callback invoked with a consent form key and its new value. */\n onInputChange: (name: string, value: string) => void;\n /** The identifier of the authorization detail the field belongs to. */\n detailId: string;\n /** The identifier of the consent purpose the authorization detail belongs to. */\n purposeId: string;\n /** The field to render. */\n row: ConsentDetailRow;\n /** translation data */\n t?: UseTranslation['t'];\n}\n\n/**\n * Renders one field of an authorization detail. A field the user may modify before\n * approving is editable, bounded by the value that was shown: a number or a date can only move in\n * the allowed direction, and items can only be removed from, or added to, a list as its rule allows. Every other field is read-only.\n * A number or a date the user enters outside its bound, or that is not a value at all, is shown with an error and\n * is not submitted: the field's modification is cleared and the field is marked invalid, which blocks approval\n * until the user corrects it. The server checks whatever is submitted.\n */\nconst ConsentDetailField: FC<ConsentDetailFieldProps> = ({\n align = 'end',\n children = undefined,\n formValues,\n onInputChange,\n detailId,\n purposeId,\n row,\n t = undefined,\n}: ConsentDetailFieldProps): ReactElement => {\n const field: UseConsentDetailFieldResult = useConsentDetailField({\n detailId,\n formValues,\n onInputChange,\n purposeId,\n row,\n t,\n });\n const {inputId, label, listDisplay} = field;\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme, align);\n const fieldClass: string = withVendorCSSClassPrefix(bem('consent-detail-field'));\n const collapse = (items: ReactNode[]): ReactNode[] => items.slice(0, listDisplay.visibleCount);\n const listToggle: ReactNode = listDisplay.isCollapsible && (\n <ConsentDetailToggle\n expanded={field.isListExpanded}\n hiddenCount={listDisplay.hiddenCount}\n onToggle={field.handleListToggle}\n t={t}\n />\n );\n const chipClass = (modifier: 'kept' | 'removed' | 'offered'): string =>\n cx(\n withVendorCSSClassPrefix(bem('consent-detail-field', 'chip')),\n withVendorCSSClassPrefix(bem('consent-detail-field', 'chip', modifier)),\n styles[`${modifier}Chip`],\n );\n const chipLabelClass: string = cx(\n withVendorCSSClassPrefix(bem('consent-detail-field', 'chip-label')),\n styles['chipLabel'],\n );\n const chipsClass: string = cx(\n fieldClass,\n withVendorCSSClassPrefix(bem('consent-detail-field', 'chips')),\n styles['chips'],\n );\n const inputClass: string = cx(\n fieldClass,\n withVendorCSSClassPrefix(bem('consent-detail-field', 'input')),\n styles['input'],\n );\n const valueClass: string = cx(fieldClass, withVendorCSSClassPrefix(bem('consent-detail-field', 'value')));\n\n if (children) {\n return <>{children(field)}</>;\n }\n\n if (field.kind === 'number' || field.kind === 'date') {\n return (\n <TextField\n id={inputId}\n className={inputClass}\n type={field.kind}\n step={field.kind === 'number' ? 'any' : undefined}\n aria-label={label}\n max={field.max}\n min={field.min}\n value={field.text}\n error={field.error?.message}\n onChange={(e: ChangeEvent<HTMLInputElement>): void => field.handleChange(e.target.value)}\n onBlur={field.handleBlur}\n />\n );\n }\n\n if (field.kind === 'removeItems') {\n // A kept item can be removed, except the last one: to grant none of them the user declines the\n // detail instead. A removed item stays visible so the user can add it back.\n return (\n <div className={chipsClass} role=\"group\" aria-label={label}>\n {collapse(\n field.items.map(({selected, toggleable, value}: ConsentDetailListItem, index: number) => (\n <button\n key={String(value)}\n id={`${inputId}_${index}`}\n type=\"button\"\n className={chipClass(selected ? 'kept' : 'removed')}\n title={String(value)}\n aria-pressed={selected}\n aria-label={resolveConsentText(\n t,\n selected ? 'consent.authorization_details.remove_item' : 'consent.authorization_details.add_back_item',\n {item: String(value)},\n )}\n disabled={!toggleable}\n onClick={(): void => field.handleToggle(value)}\n >\n <span className={chipLabelClass}>{String(value)}</span>\n {selected && toggleable && <span aria-hidden=\"true\">×</span>}\n </button>\n )),\n )}\n {listToggle}\n </div>\n );\n }\n\n if (field.kind === 'addItems') {\n // The items shown cannot be removed, since removing one would grant more. Items the user adds can be\n // taken out again before approving.\n return (\n <div className={chipsClass} role=\"group\" aria-label={label}>\n {collapse(\n field.items.map(({origin, value}: ConsentDetailListItem, index: number) => {\n if (origin === 'shown') {\n return (\n <span\n key={String(value)}\n id={`${inputId}_${index}`}\n className={chipClass('kept')}\n title={String(value)}\n >\n <span className={chipLabelClass}>{String(value)}</span>\n </span>\n );\n }\n return (\n <button\n key={`${origin}-${String(value)}`}\n id={`${inputId}_${origin}_${String(value)}`}\n type=\"button\"\n className={chipClass(origin === 'added' ? 'kept' : 'offered')}\n title={String(value)}\n aria-label={resolveConsentText(\n t,\n origin === 'added'\n ? 'consent.authorization_details.remove_item'\n : 'consent.authorization_details.add_item',\n {item: String(value)},\n )}\n onClick={(): void => field.handleToggle(value)}\n >\n <span className={chipLabelClass}>\n {origin === 'offered' && '+ '}\n {String(value)}\n </span>\n {origin === 'added' && <span aria-hidden=\"true\">×</span>}\n </button>\n );\n }),\n )}\n {listToggle}\n {field.isTypedItemAllowed && (\n <TextField\n id={`${inputId}_new`}\n className={inputClass}\n aria-label={resolveConsentText(t, 'consent.authorization_details.new_item', {label})}\n value={field.text}\n onChange={(e: ChangeEvent<HTMLInputElement>): void => field.handleChange(e.target.value)}\n onKeyDown={(e: KeyboardEvent<HTMLInputElement>): void => {\n if (e.key === 'Enter') {\n e.preventDefault();\n field.handleAdd(e.currentTarget.value);\n }\n }}\n />\n )}\n </div>\n );\n }\n\n const textAlign: 'left' | 'right' = align === 'end' ? 'right' : 'left';\n\n // A long list of plain values shows its first items, the rest behind a toggle.\n if (isConsentDetailPlainList(row.value) && listDisplay.isCollapsible) {\n const items: (string | number | boolean)[] = row.value.slice(0, listDisplay.visibleCount);\n return (\n <div\n className={cx(fieldClass, withVendorCSSClassPrefix(bem('consent-detail-field', 'list')), styles['listText'])}\n >\n <ConsentDetailText\n align={textAlign}\n fontWeight=\"bold\"\n maxChars={Number.POSITIVE_INFINITY}\n maxLines={Number.POSITIVE_INFINITY}\n text={formatConsentDetailValue(items)}\n />\n {listToggle}\n </div>\n );\n }\n\n // Structured JSON reads as an indented block rather than one long line.\n if (isConsentDetailStructured(row.value)) {\n return (\n <ConsentDetailText\n className={valueClass}\n monospace\n maxChars={Number.POSITIVE_INFINITY}\n maxLines={CONSENT_DETAIL_DISPLAY_LIMITS.structuredLines}\n t={t}\n text={formatConsentDetailValue(row.value, 2)}\n />\n );\n }\n\n return (\n <ConsentDetailText\n className={valueClass}\n align={textAlign}\n fontWeight=\"bold\"\n maxChars={CONSENT_DETAIL_DISPLAY_LIMITS.valueChars}\n maxLines={CONSENT_DETAIL_DISPLAY_LIMITS.valueLines}\n t={t}\n text={formatConsentDetailValue(row.value)}\n />\n );\n};\n\nexport default ConsentDetailField;\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Theme } from '@thunderid/browser';
2
+ /**
3
+ * Creates styles for the ConsentDetailField component.
4
+ * @param theme - The theme object containing design tokens
5
+ * @param colorScheme - The current color scheme (used for memoization)
6
+ * @param align - Side the value is aligned to: `end` beside its label, `start` when stacked below it
7
+ * @returns Object containing CSS class names for component styling
8
+ */
9
+ declare const useStyles: (theme: Theme, colorScheme: string, align: "start" | "end") => Record<string, string>;
10
+ export default useStyles;
11
+ //# sourceMappingURL=ConsentDetailField.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentDetailField.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/flow/ConsentDetailField.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC;;;;;;GAMG;AACH,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,EAAE,aAAa,MAAM,EAAE,OAAO,OAAO,GAAG,KAAK,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CA2DnE,CAAC;AAElC,eAAe,SAAS,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { css } from "../../../styles/emotion.js";
2
+ import { useMemo } from "react";
3
+
4
+ //#region src/components/auth/flow/ConsentDetailField.styles.ts
5
+ /**
6
+ * Creates styles for the ConsentDetailField component.
7
+ * @param theme - The theme object containing design tokens
8
+ * @param colorScheme - The current color scheme (used for memoization)
9
+ * @param align - Side the value is aligned to: `end` beside its label, `start` when stacked below it
10
+ * @returns Object containing CSS class names for component styling
11
+ */
12
+ const useStyles = (theme, colorScheme, align) => useMemo(() => {
13
+ const chip = css({
14
+ alignItems: "center",
15
+ borderRadius: "9999px",
16
+ boxSizing: "border-box",
17
+ cursor: "pointer",
18
+ display: "inline-flex",
19
+ font: "inherit",
20
+ fontSize: "0.8125rem",
21
+ gap: "6px",
22
+ maxWidth: "100%",
23
+ minWidth: 0,
24
+ padding: "2px 10px",
25
+ "&:disabled": { cursor: "default" }
26
+ });
27
+ return {
28
+ chipLabel: css({
29
+ minWidth: 0,
30
+ overflow: "hidden",
31
+ textOverflow: "ellipsis",
32
+ whiteSpace: "nowrap"
33
+ }),
34
+ chips: css({
35
+ alignItems: "center",
36
+ display: "flex",
37
+ flexWrap: "wrap",
38
+ gap: "6px",
39
+ justifyContent: align === "end" ? "flex-end" : "flex-start",
40
+ maxWidth: "100%",
41
+ minWidth: 0,
42
+ ...align === "start" && {
43
+ contain: "inline-size",
44
+ width: "100%"
45
+ }
46
+ }),
47
+ input: css({ maxWidth: "10rem" }),
48
+ keptChip: css(chip, {
49
+ background: "transparent",
50
+ border: `1px solid ${theme.vars.colors.primary.main}`,
51
+ color: theme.vars.colors.primary.main
52
+ }),
53
+ listText: css({
54
+ alignItems: "baseline",
55
+ display: "flex",
56
+ flexWrap: "wrap",
57
+ gap: "2px 6px",
58
+ justifyContent: align === "end" ? "flex-end" : "flex-start",
59
+ maxWidth: "100%",
60
+ minWidth: 0
61
+ }),
62
+ offeredChip: css(chip, {
63
+ background: "transparent",
64
+ border: `1px dashed ${theme.vars.colors.border}`,
65
+ color: theme.vars.colors.text.secondary
66
+ }),
67
+ removedChip: css(chip, {
68
+ background: "transparent",
69
+ border: `1px solid ${theme.vars.colors.border}`,
70
+ color: theme.vars.colors.text.secondary,
71
+ textDecoration: "line-through"
72
+ })
73
+ };
74
+ }, [
75
+ theme,
76
+ colorScheme,
77
+ align
78
+ ]);
79
+ var ConsentDetailField_styles_default = useStyles;
80
+
81
+ //#endregion
82
+ export { ConsentDetailField_styles_default as default };
83
+ //# sourceMappingURL=ConsentDetailField.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentDetailField.styles.js","names":["chip: string"],"sources":["../../../../src/components/auth/flow/ConsentDetailField.styles.ts"],"sourcesContent":["// Copyright 2026 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 ConsentDetailField component.\n * @param theme - The theme object containing design tokens\n * @param colorScheme - The current color scheme (used for memoization)\n * @param align - Side the value is aligned to: `end` beside its label, `start` when stacked below it\n * @returns Object containing CSS class names for component styling\n */\nconst useStyles = (theme: Theme, colorScheme: string, align: 'start' | 'end'): Record<string, string> =>\n useMemo(() => {\n const chip: string = css({\n alignItems: 'center',\n borderRadius: '9999px',\n boxSizing: 'border-box',\n cursor: 'pointer',\n display: 'inline-flex',\n font: 'inherit',\n fontSize: '0.8125rem',\n gap: '6px',\n maxWidth: '100%',\n minWidth: 0,\n padding: '2px 10px',\n '&:disabled': {cursor: 'default'},\n });\n\n return {\n // A chip keeps to one line; a long item is cut short with an ellipsis and shown in full on hover.\n chipLabel: css({minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}),\n chips: css({\n alignItems: 'center',\n display: 'flex',\n flexWrap: 'wrap',\n gap: '6px',\n justifyContent: align === 'end' ? 'flex-end' : 'flex-start',\n maxWidth: '100%',\n minWidth: 0,\n // Stacked below its label, the list takes the row's width and wraps within it; a chip's one-line\n // label must not widen the screen it sits in.\n ...(align === 'start' && {contain: 'inline-size', width: '100%'}),\n }),\n input: css({maxWidth: '10rem'}),\n keptChip: css(chip, {\n background: 'transparent',\n border: `1px solid ${theme.vars.colors.primary.main}`,\n color: theme.vars.colors.primary.main,\n }),\n listText: css({\n alignItems: 'baseline',\n display: 'flex',\n flexWrap: 'wrap',\n gap: '2px 6px',\n justifyContent: align === 'end' ? 'flex-end' : 'flex-start',\n maxWidth: '100%',\n minWidth: 0,\n }),\n offeredChip: css(chip, {\n background: 'transparent',\n border: `1px dashed ${theme.vars.colors.border}`,\n color: theme.vars.colors.text.secondary,\n }),\n removedChip: css(chip, {\n background: 'transparent',\n border: `1px solid ${theme.vars.colors.border}`,\n color: theme.vars.colors.text.secondary,\n textDecoration: 'line-through',\n }),\n };\n }, [theme, colorScheme, align]);\n\nexport default useStyles;\n"],"mappings":";;;;;;;;;;;AAcA,MAAM,aAAa,OAAc,aAAqB,UACpD,cAAc;CACZ,MAAMA,OAAe,IAAI;EACvB,YAAY;EACZ,cAAc;EACd,WAAW;EACX,QAAQ;EACR,SAAS;EACT,MAAM;EACN,UAAU;EACV,KAAK;EACL,UAAU;EACV,UAAU;EACV,SAAS;EACT,cAAc,EAAC,QAAQ,WAAU;EAClC,CAAC;AAEF,QAAO;EAEL,WAAW,IAAI;GAAC,UAAU;GAAG,UAAU;GAAU,cAAc;GAAY,YAAY;GAAS,CAAC;EACjG,OAAO,IAAI;GACT,YAAY;GACZ,SAAS;GACT,UAAU;GACV,KAAK;GACL,gBAAgB,UAAU,QAAQ,aAAa;GAC/C,UAAU;GACV,UAAU;GAGV,GAAI,UAAU,WAAW;IAAC,SAAS;IAAe,OAAO;IAAO;GACjE,CAAC;EACF,OAAO,IAAI,EAAC,UAAU,SAAQ,CAAC;EAC/B,UAAU,IAAI,MAAM;GAClB,YAAY;GACZ,QAAQ,aAAa,MAAM,KAAK,OAAO,QAAQ;GAC/C,OAAO,MAAM,KAAK,OAAO,QAAQ;GAClC,CAAC;EACF,UAAU,IAAI;GACZ,YAAY;GACZ,SAAS;GACT,UAAU;GACV,KAAK;GACL,gBAAgB,UAAU,QAAQ,aAAa;GAC/C,UAAU;GACV,UAAU;GACX,CAAC;EACF,aAAa,IAAI,MAAM;GACrB,YAAY;GACZ,QAAQ,cAAc,MAAM,KAAK,OAAO;GACxC,OAAO,MAAM,KAAK,OAAO,KAAK;GAC/B,CAAC;EACF,aAAa,IAAI,MAAM;GACrB,YAAY;GACZ,QAAQ,aAAa,MAAM,KAAK,OAAO;GACvC,OAAO,MAAM,KAAK,OAAO,KAAK;GAC9B,gBAAgB;GACjB,CAAC;EACH;GACA;CAAC;CAAO;CAAa;CAAM,CAAC;AAEjC,wCAAe"}
@@ -0,0 +1,53 @@
1
+ import { FC } from 'react';
2
+ import { UseTranslation } from '../../../hooks/useTranslation';
3
+ /**
4
+ * Props for the ConsentDetailToggle component.
5
+ */
6
+ export interface ConsentDetailToggleProps {
7
+ /** Id of the element the toggle shows more or less of. */
8
+ controls?: string;
9
+ /** Whether everything is shown. */
10
+ expanded: boolean;
11
+ /** Number of items hidden while collapsed. When given, the collapsed label counts them. */
12
+ hiddenCount?: number;
13
+ /** Callback invoked with the next expanded state. */
14
+ onToggle: (expanded: boolean) => void;
15
+ /** translation data */
16
+ t?: UseTranslation['t'];
17
+ }
18
+ /**
19
+ * Button that expands or collapses long authorization detail content.
20
+ */
21
+ export declare const ConsentDetailToggle: FC<ConsentDetailToggleProps>;
22
+ /**
23
+ * Props for the ConsentDetailText component.
24
+ */
25
+ export interface ConsentDetailTextProps {
26
+ /** Alignment of the text. */
27
+ align?: 'left' | 'right';
28
+ /** Class name applied to the text. */
29
+ className?: string;
30
+ /** Weight of the text. */
31
+ fontWeight?: 'normal' | 'medium' | 'semibold' | 'bold';
32
+ /** Id of the text element. */
33
+ id?: string;
34
+ /** Number of characters above which the text is clamped. */
35
+ maxChars: number;
36
+ /** Number of lines the text is clamped to. */
37
+ maxLines: number;
38
+ /** Shows the text as a preformatted monospace block, for structured JSON. */
39
+ monospace?: boolean;
40
+ /** translation data */
41
+ t?: UseTranslation['t'];
42
+ /** Text to show. */
43
+ text: string;
44
+ /** Typography variant of the text. */
45
+ variant?: 'body2' | 'subtitle2';
46
+ }
47
+ /**
48
+ * Shows authorization detail text that wraps anywhere, so a long unbroken token such as an IBAN or a
49
+ * URL never overflows. Text longer than its limit is clamped behind a toggle.
50
+ */
51
+ declare const ConsentDetailText: FC<ConsentDetailTextProps>;
52
+ export default ConsentDetailText;
53
+ //# sourceMappingURL=ConsentDetailText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentDetailText.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/flow/ConsentDetailText.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAC,EAAE,EAAyB,MAAM,OAAO,CAAC;AAIjD,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAK7D;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,uBAAuB;IACvB,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CACzB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CA6B5D,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IACvD,8BAA8B;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uBAAuB;IACvB,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IACxB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,OAAO,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;CACjC;AAED;;;GAGG;AACH,QAAA,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAqCjD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}