@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.
- package/dist/cjs/components/account/UserProfile/BaseUserProfile.cjs +1 -1
- package/dist/cjs/components/admin/AgentDetails/AgentDetails.cjs +13 -2
- package/dist/cjs/components/admin/AgentDetails/AgentDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/AgentDetails/BaseAgentDetails.cjs +25 -7
- package/dist/cjs/components/admin/AgentDetails/BaseAgentDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/ApplicationDetails/ApplicationDetails.cjs +15 -2
- package/dist/cjs/components/admin/ApplicationDetails/ApplicationDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/ApplicationDetails/BaseApplicationDetails.cjs +24 -7
- package/dist/cjs/components/admin/ApplicationDetails/BaseApplicationDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/GroupMembers/GroupMembers.cjs +2 -1
- package/dist/cjs/components/admin/GroupMembers/GroupMembers.cjs.map +1 -1
- package/dist/cjs/components/admin/RoleAssignments/RoleAssignments.cjs +2 -1
- package/dist/cjs/components/admin/RoleAssignments/RoleAssignments.cjs.map +1 -1
- package/dist/cjs/components/admin/UserDetails/BaseUserDetails.cjs +32 -14
- package/dist/cjs/components/admin/UserDetails/BaseUserDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/UserDetails/UserDetails.cjs +14 -2
- package/dist/cjs/components/admin/UserDetails/UserDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/shared/AccountLifecycleParts.cjs +105 -0
- package/dist/cjs/components/admin/shared/AccountLifecycleParts.cjs.map +1 -0
- package/dist/cjs/components/admin/shared/ApplicationFormFields.cjs +1 -1
- package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs +4 -5
- package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
- package/dist/cjs/components/auth/SignIn/SignIn.cjs +5 -5
- package/dist/cjs/components/auth/SignIn/SignIn.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +4 -5
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/Consent.cjs +53 -28
- package/dist/cjs/components/auth/flow/Consent.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.cjs +104 -0
- package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.styles.cjs +59 -0
- package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.styles.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentDetailField.cjs +171 -0
- package/dist/cjs/components/auth/flow/ConsentDetailField.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentDetailField.styles.cjs +85 -0
- package/dist/cjs/components/auth/flow/ConsentDetailField.styles.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentDetailText.cjs +63 -0
- package/dist/cjs/components/auth/flow/ConsentDetailText.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentDetailText.styles.cjs +83 -0
- package/dist/cjs/components/auth/flow/ConsentDetailText.styles.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/FieldFactory.cjs +1 -1
- package/dist/cjs/components/auth/flow/resolveConsentText.cjs +25 -0
- package/dist/cjs/components/auth/flow/resolveConsentText.cjs.map +1 -0
- package/dist/cjs/components/primitives/KeyValueInput/KeyValueInput.cjs +1 -1
- package/dist/cjs/components/primitives/MultiInput/MultiInput.cjs +1 -1
- package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs +1 -1
- package/dist/cjs/contexts/Theme/ThemeProvider.cjs +36 -6
- package/dist/cjs/contexts/Theme/ThemeProvider.cjs.map +1 -1
- package/dist/cjs/contexts/Theme/ThemeRootContext.cjs +12 -0
- package/dist/cjs/contexts/Theme/ThemeRootContext.cjs.map +1 -0
- package/dist/cjs/hooks/auth/useConsentDetailField.cjs +357 -0
- package/dist/cjs/hooks/auth/useConsentDetailField.cjs.map +1 -0
- package/dist/cjs/hooks/management/useAccountLifecycle.cjs +59 -0
- package/dist/cjs/hooks/management/useAccountLifecycle.cjs.map +1 -0
- package/dist/cjs/index.cjs +66 -1
- package/dist/cjs/utils/formatConsentDetailValue.cjs +26 -0
- package/dist/cjs/utils/formatConsentDetailValue.cjs.map +1 -0
- package/dist/cjs/utils/getConsentDetailLayout.cjs +44 -0
- package/dist/cjs/utils/getConsentDetailLayout.cjs.map +1 -0
- package/dist/cjs/utils/getConsentDetailListDisplay.cjs +30 -0
- package/dist/cjs/utils/getConsentDetailListDisplay.cjs.map +1 -0
- package/dist/cjs/utils/isConsentApprovalBlocked.cjs +41 -0
- package/dist/cjs/utils/isConsentApprovalBlocked.cjs.map +1 -0
- package/dist/cjs/utils/isConsentDetailPlainList.cjs +24 -0
- package/dist/cjs/utils/isConsentDetailPlainList.cjs.map +1 -0
- package/dist/cjs/utils/isConsentDetailStructured.cjs +15 -0
- package/dist/cjs/utils/isConsentDetailStructured.cjs.map +1 -0
- package/dist/cjs/utils/isConsentDetailTextClamped.cjs +25 -0
- package/dist/cjs/utils/isConsentDetailTextClamped.cjs.map +1 -0
- package/dist/components/account/UserProfile/BaseUserProfile.js +1 -1
- package/dist/components/admin/AgentDetails/AgentDetails.d.ts +8 -1
- package/dist/components/admin/AgentDetails/AgentDetails.d.ts.map +1 -1
- package/dist/components/admin/AgentDetails/AgentDetails.js +13 -2
- package/dist/components/admin/AgentDetails/AgentDetails.js.map +1 -1
- package/dist/components/admin/AgentDetails/BaseAgentDetails.d.ts +21 -1
- package/dist/components/admin/AgentDetails/BaseAgentDetails.d.ts.map +1 -1
- package/dist/components/admin/AgentDetails/BaseAgentDetails.js +25 -7
- package/dist/components/admin/AgentDetails/BaseAgentDetails.js.map +1 -1
- package/dist/components/admin/ApplicationDetails/ApplicationDetails.d.ts +15 -1
- package/dist/components/admin/ApplicationDetails/ApplicationDetails.d.ts.map +1 -1
- package/dist/components/admin/ApplicationDetails/ApplicationDetails.js +15 -2
- package/dist/components/admin/ApplicationDetails/ApplicationDetails.js.map +1 -1
- package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.d.ts +20 -1
- package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.d.ts.map +1 -1
- package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.js +24 -7
- package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.js.map +1 -1
- package/dist/components/admin/GroupMembers/GroupMembers.d.ts +7 -0
- package/dist/components/admin/GroupMembers/GroupMembers.d.ts.map +1 -1
- package/dist/components/admin/GroupMembers/GroupMembers.js +2 -1
- package/dist/components/admin/GroupMembers/GroupMembers.js.map +1 -1
- package/dist/components/admin/RoleAssignments/RoleAssignments.d.ts +7 -0
- package/dist/components/admin/RoleAssignments/RoleAssignments.d.ts.map +1 -1
- package/dist/components/admin/RoleAssignments/RoleAssignments.js +2 -1
- package/dist/components/admin/RoleAssignments/RoleAssignments.js.map +1 -1
- package/dist/components/admin/UserDetails/BaseUserDetails.d.ts +22 -1
- package/dist/components/admin/UserDetails/BaseUserDetails.d.ts.map +1 -1
- package/dist/components/admin/UserDetails/BaseUserDetails.js +32 -14
- package/dist/components/admin/UserDetails/BaseUserDetails.js.map +1 -1
- package/dist/components/admin/UserDetails/UserDetails.d.ts +15 -1
- package/dist/components/admin/UserDetails/UserDetails.d.ts.map +1 -1
- package/dist/components/admin/UserDetails/UserDetails.js +14 -2
- package/dist/components/admin/UserDetails/UserDetails.js.map +1 -1
- package/dist/components/admin/shared/AccountLifecycleParts.d.ts +32 -0
- package/dist/components/admin/shared/AccountLifecycleParts.d.ts.map +1 -0
- package/dist/components/admin/shared/AccountLifecycleParts.js +101 -0
- package/dist/components/admin/shared/AccountLifecycleParts.js.map +1 -0
- package/dist/components/admin/shared/ApplicationFormFields.js +1 -1
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js +5 -6
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
- package/dist/components/auth/SignIn/SignIn.d.ts.map +1 -1
- package/dist/components/auth/SignIn/SignIn.js +6 -6
- package/dist/components/auth/SignIn/SignIn.js.map +1 -1
- package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
- package/dist/components/auth/flow/AuthOptionFactory.js +5 -6
- package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
- package/dist/components/auth/flow/Consent.d.ts +6 -0
- package/dist/components/auth/flow/Consent.d.ts.map +1 -1
- package/dist/components/auth/flow/Consent.js +54 -29
- package/dist/components/auth/flow/Consent.js.map +1 -1
- package/dist/components/auth/flow/ConsentAuthorizationDetail.d.ts +68 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.js +100 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.js.map +1 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.d.ts +10 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.js +57 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.js.map +1 -0
- package/dist/components/auth/flow/ConsentDetailField.d.ts +39 -0
- package/dist/components/auth/flow/ConsentDetailField.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentDetailField.js +168 -0
- package/dist/components/auth/flow/ConsentDetailField.js.map +1 -0
- package/dist/components/auth/flow/ConsentDetailField.styles.d.ts +11 -0
- package/dist/components/auth/flow/ConsentDetailField.styles.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentDetailField.styles.js +83 -0
- package/dist/components/auth/flow/ConsentDetailField.styles.js.map +1 -0
- package/dist/components/auth/flow/ConsentDetailText.d.ts +53 -0
- package/dist/components/auth/flow/ConsentDetailText.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentDetailText.js +58 -0
- package/dist/components/auth/flow/ConsentDetailText.js.map +1 -0
- package/dist/components/auth/flow/ConsentDetailText.styles.d.ts +20 -0
- package/dist/components/auth/flow/ConsentDetailText.styles.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentDetailText.styles.js +80 -0
- package/dist/components/auth/flow/ConsentDetailText.styles.js.map +1 -0
- package/dist/components/auth/flow/FieldFactory.js +1 -1
- package/dist/components/auth/flow/resolveConsentText.d.ts +13 -0
- package/dist/components/auth/flow/resolveConsentText.d.ts.map +1 -0
- package/dist/components/auth/flow/resolveConsentText.js +23 -0
- package/dist/components/auth/flow/resolveConsentText.js.map +1 -0
- package/dist/components/primitives/KeyValueInput/KeyValueInput.js +1 -1
- package/dist/components/primitives/MultiInput/MultiInput.js +1 -1
- package/dist/components/primitives/PasswordField/PasswordField.js +1 -1
- package/dist/contexts/Theme/ThemeProvider.d.ts +2 -1
- package/dist/contexts/Theme/ThemeProvider.d.ts.map +1 -1
- package/dist/contexts/Theme/ThemeProvider.js +37 -7
- package/dist/contexts/Theme/ThemeProvider.js.map +1 -1
- package/dist/contexts/Theme/ThemeRootContext.d.ts +11 -0
- package/dist/contexts/Theme/ThemeRootContext.d.ts.map +1 -0
- package/dist/contexts/Theme/ThemeRootContext.js +10 -0
- package/dist/contexts/Theme/ThemeRootContext.js.map +1 -0
- package/dist/hooks/auth/useConsentDetailField.d.ts +130 -0
- package/dist/hooks/auth/useConsentDetailField.d.ts.map +1 -0
- package/dist/hooks/auth/useConsentDetailField.js +354 -0
- package/dist/hooks/auth/useConsentDetailField.js.map +1 -0
- package/dist/hooks/management/useAccountLifecycle.d.ts +49 -0
- package/dist/hooks/management/useAccountLifecycle.d.ts.map +1 -0
- package/dist/hooks/management/useAccountLifecycle.js +56 -0
- package/dist/hooks/management/useAccountLifecycle.js.map +1 -0
- package/dist/index.d.ts +16 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/utils/formatConsentDetailValue.d.ts +16 -0
- package/dist/utils/formatConsentDetailValue.d.ts.map +1 -0
- package/dist/utils/formatConsentDetailValue.js +25 -0
- package/dist/utils/formatConsentDetailValue.js.map +1 -0
- package/dist/utils/getConsentDetailLayout.d.ts +32 -0
- package/dist/utils/getConsentDetailLayout.d.ts.map +1 -0
- package/dist/utils/getConsentDetailLayout.js +43 -0
- package/dist/utils/getConsentDetailLayout.js.map +1 -0
- package/dist/utils/getConsentDetailListDisplay.d.ts +30 -0
- package/dist/utils/getConsentDetailListDisplay.d.ts.map +1 -0
- package/dist/utils/getConsentDetailListDisplay.js +30 -0
- package/dist/utils/getConsentDetailListDisplay.js.map +1 -0
- package/dist/utils/isConsentApprovalBlocked.d.ts +17 -0
- package/dist/utils/isConsentApprovalBlocked.d.ts.map +1 -0
- package/dist/utils/isConsentApprovalBlocked.js +39 -0
- package/dist/utils/isConsentApprovalBlocked.js.map +1 -0
- package/dist/utils/isConsentDetailPlainList.d.ts +15 -0
- package/dist/utils/isConsentDetailPlainList.d.ts.map +1 -0
- package/dist/utils/isConsentDetailPlainList.js +23 -0
- package/dist/utils/isConsentDetailPlainList.js.map +1 -0
- package/dist/utils/isConsentDetailStructured.d.ts +10 -0
- package/dist/utils/isConsentDetailStructured.d.ts.map +1 -0
- package/dist/utils/isConsentDetailStructured.js +14 -0
- package/dist/utils/isConsentDetailStructured.js.map +1 -0
- package/dist/utils/isConsentDetailTextClamped.d.ts +20 -0
- package/dist/utils/isConsentDetailTextClamped.d.ts.map +1 -0
- package/dist/utils/isConsentDetailTextClamped.js +24 -0
- package/dist/utils/isConsentDetailTextClamped.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_emotion = require('../../../styles/emotion.cjs');
|
|
3
|
+
const require_useTheme = require('../../../contexts/Theme/useTheme.cjs');
|
|
4
|
+
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
5
|
+
const require_ConsentAuthorizationDetail_styles = require('./ConsentAuthorizationDetail.styles.cjs');
|
|
6
|
+
const require_Toggle = require('../../primitives/Toggle/Toggle.cjs');
|
|
7
|
+
const require_ConsentCheckboxList = require('./ConsentCheckboxList.cjs');
|
|
8
|
+
const require_resolveConsentText = require('./resolveConsentText.cjs');
|
|
9
|
+
const require_ConsentDetailText = require('./ConsentDetailText.cjs');
|
|
10
|
+
const require_getConsentDetailLayout = require('../../../utils/getConsentDetailLayout.cjs');
|
|
11
|
+
const require_ConsentDetailField = require('./ConsentDetailField.cjs');
|
|
12
|
+
let __thunderid_browser = require("@thunderid/browser");
|
|
13
|
+
__thunderid_browser = require_rolldown_runtime.__toESM(__thunderid_browser);
|
|
14
|
+
let react = require("react");
|
|
15
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
16
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
17
|
+
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
18
|
+
|
|
19
|
+
//#region src/components/auth/flow/ConsentAuthorizationDetail.tsx
|
|
20
|
+
/**
|
|
21
|
+
* Renders one RFC 9396 authorization detail element: the server-rendered summary, the detail's fields,
|
|
22
|
+
* which are read-only unless the user may modify them, and a single toggle that approves or declines the
|
|
23
|
+
* detail as a whole. The summary and labels come from the server and are not translated again.
|
|
24
|
+
* Authorization details reach the consent step only on a sign-in started from an authorization request, so
|
|
25
|
+
* this renders in an authorization server UI (hosted login); an app-native sign-in flow cannot carry them.
|
|
26
|
+
*/
|
|
27
|
+
const ConsentAuthorizationDetail = ({ children = void 0, element, formValues, onInputChange, purposeId, t = void 0 }) => {
|
|
28
|
+
const { theme, colorScheme } = require_useTheme.default();
|
|
29
|
+
const styles = require_ConsentAuthorizationDetail_styles.default(theme, colorScheme);
|
|
30
|
+
const key = require_ConsentCheckboxList.getConsentOptionalKey(purposeId, element.name);
|
|
31
|
+
const isApproved = formValues[key] !== "false";
|
|
32
|
+
const rows = element.rows ?? [];
|
|
33
|
+
const summary = element.summary ?? element.detailType ?? element.name;
|
|
34
|
+
const handleChange = (checked) => {
|
|
35
|
+
onInputChange(key, checked ? "true" : "false");
|
|
36
|
+
};
|
|
37
|
+
(0, react.useEffect)(() => {
|
|
38
|
+
if (formValues[key] === void 0) onInputChange(key, "true");
|
|
39
|
+
}, [
|
|
40
|
+
formValues,
|
|
41
|
+
key,
|
|
42
|
+
onInputChange
|
|
43
|
+
]);
|
|
44
|
+
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: children({
|
|
45
|
+
detailType: element.detailType,
|
|
46
|
+
element,
|
|
47
|
+
handleChange,
|
|
48
|
+
isApproved,
|
|
49
|
+
rows,
|
|
50
|
+
summary
|
|
51
|
+
}) });
|
|
52
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
53
|
+
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-authorization-detail")), styles["card"]),
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ConsentDetailText.default, {
|
|
56
|
+
id: `consent_authz_detail_${purposeId}_${element.name}_summary`,
|
|
57
|
+
className: (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-authorization-detail", "summary")),
|
|
58
|
+
variant: "subtitle2",
|
|
59
|
+
fontWeight: "bold",
|
|
60
|
+
maxChars: require_getConsentDetailLayout.CONSENT_DETAIL_DISPLAY_LIMITS.summaryChars,
|
|
61
|
+
maxLines: require_getConsentDetailLayout.CONSENT_DETAIL_DISPLAY_LIMITS.summaryLines,
|
|
62
|
+
t,
|
|
63
|
+
text: summary
|
|
64
|
+
}),
|
|
65
|
+
rows.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
66
|
+
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-authorization-detail", "rows")), styles["rows"]),
|
|
67
|
+
children: rows.map((row) => {
|
|
68
|
+
const stacked = require_getConsentDetailLayout.default(row) === "stacked";
|
|
69
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
70
|
+
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-authorization-detail", "row")), stacked && (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-authorization-detail", "row", "stacked")), stacked ? styles["stackedRow"] : styles["row"]),
|
|
71
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Typography.default, {
|
|
72
|
+
variant: "body2",
|
|
73
|
+
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-authorization-detail", "label")), styles["label"]),
|
|
74
|
+
children: row.label || row.path
|
|
75
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
76
|
+
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-authorization-detail", "value")), stacked ? styles["stackedValue"] : styles["value"]),
|
|
77
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ConsentDetailField.default, {
|
|
78
|
+
align: stacked ? "start" : "end",
|
|
79
|
+
detailId: element.name,
|
|
80
|
+
purposeId,
|
|
81
|
+
row,
|
|
82
|
+
formValues,
|
|
83
|
+
onInputChange,
|
|
84
|
+
t
|
|
85
|
+
})
|
|
86
|
+
})]
|
|
87
|
+
}, row.path);
|
|
88
|
+
})
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Toggle.default, {
|
|
91
|
+
id: `consent_opt_${purposeId}_${element.name}`,
|
|
92
|
+
className: (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-authorization-detail", "approve")),
|
|
93
|
+
label: require_resolveConsentText.default(t, "consent.authorization_details.approve"),
|
|
94
|
+
checked: isApproved,
|
|
95
|
+
onChange: (e) => handleChange(e.target.checked)
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
var ConsentAuthorizationDetail_default = ConsentAuthorizationDetail;
|
|
101
|
+
|
|
102
|
+
//#endregion
|
|
103
|
+
exports.default = ConsentAuthorizationDetail_default;
|
|
104
|
+
//# sourceMappingURL=ConsentAuthorizationDetail.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsentAuthorizationDetail.cjs","names":["ConsentAuthorizationDetail: FC<ConsentAuthorizationDetailProps>","useTheme","styles: Record<string, string>","useStyles","key: string","getConsentOptionalKey","isApproved: boolean","rows: ConsentDetailRow[]","summary: string","cx","ConsentDetailText","CONSENT_DETAIL_DISPLAY_LIMITS","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,0BAAU;CACpE,MAAMC,SAAiCC,kDAAU,OAAO,YAAY;CAEpE,MAAMC,MAAcC,kDAAsB,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,4BAAgB;AACd,MAAI,WAAW,SAAS,OACtB,eAAc,KAAK,OAAO;IAE3B;EAAC;EAAY;EAAK;EAAc,CAAC;AAEpC,KAAI,SACF,QAAO,mFAAG,SAAS;EAAC,YAAY,QAAQ;EAAY;EAAS;EAAc;EAAY;EAAM;EAAQ,CAAC,GAAI;AAG5G,QACE,4CAAC;EAAI,WAAWC,kGAAgC,+BAA+B,CAAC,EAAE,OAAO,QAAQ;;GAC/F,2CAACC;IACC,IAAI,wBAAwB,UAAU,GAAG,QAAQ,KAAK;IACtD,0FAAwC,gCAAgC,UAAU,CAAC;IACnF,SAAQ;IACR,YAAW;IACX,UAAUC,6DAA8B;IACxC,UAAUA,6DAA8B;IACrC;IACH,MAAM;KACN;GACD,KAAK,SAAS,KACb,2CAAC;IAAI,WAAWF,kGAAgC,gCAAgC,OAAO,CAAC,EAAE,OAAO,QAAQ;cACtG,KAAK,KAAK,QAA0B;KACnC,MAAMG,UAAmBC,uCAAuB,IAAI,KAAK;AACzD,YACE,4CAAC;MAEC,WAAWJ,kGACoB,gCAAgC,MAAM,CAAC,EACpE,0FAAwC,gCAAgC,OAAO,UAAU,CAAC,EAC1F,UAAU,OAAO,gBAAgB,OAAO,OACzC;iBAED,2CAACK;OACC,SAAQ;OACR,WAAWL,kGACoB,gCAAgC,QAAQ,CAAC,EACtE,OAAO,SACR;iBAEA,IAAI,SAAS,IAAI;QACP,EACb,2CAAC;OACC,WAAWA,kGACoB,gCAAgC,QAAQ,CAAC,EACtE,UAAU,OAAO,kBAAkB,OAAO,SAC3C;iBAED,2CAACM;QACC,OAAO,UAAU,UAAU;QAC3B,UAAU,QAAQ;QACP;QACN;QACO;QACG;QACZ;SACH;QACE;QA/BD,IAAI,KAgCL;MAER;KACE;GAER,2CAACC;IACC,IAAI,eAAe,UAAU,GAAG,QAAQ;IACxC,0FAAwC,gCAAgC,UAAU,CAAC;IACnF,OAAOC,mCAAmB,GAAG,wCAAwC;IACrE,SAAS;IACT,WAAW,MAA2C,aAAa,EAAE,OAAO,QAAQ;KACpF;;GACE;;AAIV,yCAAe"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_emotion = require('../../../styles/emotion.cjs');
|
|
3
|
+
let react = require("react");
|
|
4
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
5
|
+
|
|
6
|
+
//#region src/components/auth/flow/ConsentAuthorizationDetail.styles.ts
|
|
7
|
+
/**
|
|
8
|
+
* Creates styles for the ConsentAuthorizationDetail component.
|
|
9
|
+
* @param theme - The theme object containing design tokens
|
|
10
|
+
* @param colorScheme - The current color scheme (used for memoization)
|
|
11
|
+
* @returns Object containing CSS class names for component styling
|
|
12
|
+
*/
|
|
13
|
+
const useStyles = (theme, colorScheme) => (0, react.useMemo)(() => ({
|
|
14
|
+
card: require_emotion.css({ marginTop: "0.5rem" }),
|
|
15
|
+
label: require_emotion.css({
|
|
16
|
+
flex: "1 1 auto",
|
|
17
|
+
lineHeight: 1.45,
|
|
18
|
+
minWidth: 0,
|
|
19
|
+
overflowWrap: "anywhere"
|
|
20
|
+
}),
|
|
21
|
+
row: require_emotion.css({
|
|
22
|
+
alignItems: "center",
|
|
23
|
+
display: "flex",
|
|
24
|
+
flexWrap: "wrap",
|
|
25
|
+
gap: "4px 1rem",
|
|
26
|
+
justifyContent: "space-between"
|
|
27
|
+
}),
|
|
28
|
+
rows: require_emotion.css({
|
|
29
|
+
display: "flex",
|
|
30
|
+
flexDirection: "column",
|
|
31
|
+
gap: "8px",
|
|
32
|
+
margin: "0.5rem 0"
|
|
33
|
+
}),
|
|
34
|
+
stackedRow: require_emotion.css({
|
|
35
|
+
display: "flex",
|
|
36
|
+
flexDirection: "column",
|
|
37
|
+
gap: "4px"
|
|
38
|
+
}),
|
|
39
|
+
stackedValue: require_emotion.css({
|
|
40
|
+
display: "flex",
|
|
41
|
+
maxWidth: "100%",
|
|
42
|
+
minWidth: 0
|
|
43
|
+
}),
|
|
44
|
+
value: require_emotion.css({
|
|
45
|
+
alignItems: "center",
|
|
46
|
+
display: "flex",
|
|
47
|
+
gap: "6px",
|
|
48
|
+
justifyContent: "flex-end",
|
|
49
|
+
marginLeft: "auto",
|
|
50
|
+
maxWidth: "100%",
|
|
51
|
+
minWidth: 0,
|
|
52
|
+
textAlign: "right"
|
|
53
|
+
})
|
|
54
|
+
}), [theme, colorScheme]);
|
|
55
|
+
var ConsentAuthorizationDetail_styles_default = useStyles;
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
exports.default = ConsentAuthorizationDetail_styles_default;
|
|
59
|
+
//# sourceMappingURL=ConsentAuthorizationDetail.styles.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsentAuthorizationDetail.styles.cjs","names":["css"],"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,0CAEtB;CACL,MAAMA,oBAAI,EAAC,WAAW,UAAS,CAAC;CAChC,OAAOA,oBAAI;EAAC,MAAM;EAAY,YAAY;EAAM,UAAU;EAAG,cAAc;EAAW,CAAC;CAGvF,KAAKA,oBAAI;EACP,YAAY;EACZ,SAAS;EACT,UAAU;EACV,KAAK;EACL,gBAAgB;EACjB,CAAC;CACF,MAAMA,oBAAI;EAAC,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAO,QAAQ;EAAW,CAAC;CACrF,YAAYA,oBAAI;EAAC,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAM,CAAC;CACvE,cAAcA,oBAAI;EAAC,SAAS;EAAQ,UAAU;EAAQ,UAAU;EAAE,CAAC;CACnE,OAAOA,oBAAI;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,171 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_emotion = require('../../../styles/emotion.cjs');
|
|
3
|
+
const require_useTheme = require('../../../contexts/Theme/useTheme.cjs');
|
|
4
|
+
const require_ConsentDetailField_styles = require('./ConsentDetailField.styles.cjs');
|
|
5
|
+
const require_resolveConsentText = require('./resolveConsentText.cjs');
|
|
6
|
+
const require_ConsentDetailText = require('./ConsentDetailText.cjs');
|
|
7
|
+
const require_formatConsentDetailValue = require('../../../utils/formatConsentDetailValue.cjs');
|
|
8
|
+
const require_isConsentDetailStructured = require('../../../utils/isConsentDetailStructured.cjs');
|
|
9
|
+
const require_getConsentDetailLayout = require('../../../utils/getConsentDetailLayout.cjs');
|
|
10
|
+
const require_isConsentDetailPlainList = require('../../../utils/isConsentDetailPlainList.cjs');
|
|
11
|
+
const require_useConsentDetailField = require('../../../hooks/auth/useConsentDetailField.cjs');
|
|
12
|
+
const require_TextField = require('../../primitives/TextField/TextField.cjs');
|
|
13
|
+
let __thunderid_browser = require("@thunderid/browser");
|
|
14
|
+
__thunderid_browser = require_rolldown_runtime.__toESM(__thunderid_browser);
|
|
15
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
16
|
+
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
17
|
+
|
|
18
|
+
//#region src/components/auth/flow/ConsentDetailField.tsx
|
|
19
|
+
/**
|
|
20
|
+
* Renders one field of an authorization detail. A field the user may modify before
|
|
21
|
+
* approving is editable, bounded by the value that was shown: a number or a date can only move in
|
|
22
|
+
* 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.
|
|
23
|
+
* 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
|
|
24
|
+
* is not submitted: the field's modification is cleared and the field is marked invalid, which blocks approval
|
|
25
|
+
* until the user corrects it. The server checks whatever is submitted.
|
|
26
|
+
*/
|
|
27
|
+
const ConsentDetailField = ({ align = "end", children = void 0, formValues, onInputChange, detailId, purposeId, row, t = void 0 }) => {
|
|
28
|
+
const field = require_useConsentDetailField.default({
|
|
29
|
+
detailId,
|
|
30
|
+
formValues,
|
|
31
|
+
onInputChange,
|
|
32
|
+
purposeId,
|
|
33
|
+
row,
|
|
34
|
+
t
|
|
35
|
+
});
|
|
36
|
+
const { inputId, label, listDisplay } = field;
|
|
37
|
+
const { theme, colorScheme } = require_useTheme.default();
|
|
38
|
+
const styles = require_ConsentDetailField_styles.default(theme, colorScheme, align);
|
|
39
|
+
const fieldClass = (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-field"));
|
|
40
|
+
const collapse = (items) => items.slice(0, listDisplay.visibleCount);
|
|
41
|
+
const listToggle = listDisplay.isCollapsible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ConsentDetailText.ConsentDetailToggle, {
|
|
42
|
+
expanded: field.isListExpanded,
|
|
43
|
+
hiddenCount: listDisplay.hiddenCount,
|
|
44
|
+
onToggle: field.handleListToggle,
|
|
45
|
+
t
|
|
46
|
+
});
|
|
47
|
+
const chipClass = (modifier) => require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-field", "chip")), (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-field", "chip", modifier)), styles[`${modifier}Chip`]);
|
|
48
|
+
const chipLabelClass = require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-field", "chip-label")), styles["chipLabel"]);
|
|
49
|
+
const chipsClass = require_emotion.cx(fieldClass, (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-field", "chips")), styles["chips"]);
|
|
50
|
+
const inputClass = require_emotion.cx(fieldClass, (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-field", "input")), styles["input"]);
|
|
51
|
+
const valueClass = require_emotion.cx(fieldClass, (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-field", "value")));
|
|
52
|
+
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: children(field) });
|
|
53
|
+
if (field.kind === "number" || field.kind === "date") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_TextField.default, {
|
|
54
|
+
id: inputId,
|
|
55
|
+
className: inputClass,
|
|
56
|
+
type: field.kind,
|
|
57
|
+
step: field.kind === "number" ? "any" : void 0,
|
|
58
|
+
"aria-label": label,
|
|
59
|
+
max: field.max,
|
|
60
|
+
min: field.min,
|
|
61
|
+
value: field.text,
|
|
62
|
+
error: field.error?.message,
|
|
63
|
+
onChange: (e) => field.handleChange(e.target.value),
|
|
64
|
+
onBlur: field.handleBlur
|
|
65
|
+
});
|
|
66
|
+
if (field.kind === "removeItems") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
67
|
+
className: chipsClass,
|
|
68
|
+
role: "group",
|
|
69
|
+
"aria-label": label,
|
|
70
|
+
children: [collapse(field.items.map(({ selected, toggleable, value }, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
71
|
+
id: `${inputId}_${index}`,
|
|
72
|
+
type: "button",
|
|
73
|
+
className: chipClass(selected ? "kept" : "removed"),
|
|
74
|
+
title: String(value),
|
|
75
|
+
"aria-pressed": selected,
|
|
76
|
+
"aria-label": require_resolveConsentText.default(t, selected ? "consent.authorization_details.remove_item" : "consent.authorization_details.add_back_item", { item: String(value) }),
|
|
77
|
+
disabled: !toggleable,
|
|
78
|
+
onClick: () => field.handleToggle(value),
|
|
79
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
80
|
+
className: chipLabelClass,
|
|
81
|
+
children: String(value)
|
|
82
|
+
}), selected && toggleable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
83
|
+
"aria-hidden": "true",
|
|
84
|
+
children: "×"
|
|
85
|
+
})]
|
|
86
|
+
}, String(value)))), listToggle]
|
|
87
|
+
});
|
|
88
|
+
if (field.kind === "addItems") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
89
|
+
className: chipsClass,
|
|
90
|
+
role: "group",
|
|
91
|
+
"aria-label": label,
|
|
92
|
+
children: [
|
|
93
|
+
collapse(field.items.map(({ origin, value }, index) => {
|
|
94
|
+
if (origin === "shown") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
95
|
+
id: `${inputId}_${index}`,
|
|
96
|
+
className: chipClass("kept"),
|
|
97
|
+
title: String(value),
|
|
98
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
99
|
+
className: chipLabelClass,
|
|
100
|
+
children: String(value)
|
|
101
|
+
})
|
|
102
|
+
}, String(value));
|
|
103
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
104
|
+
id: `${inputId}_${origin}_${String(value)}`,
|
|
105
|
+
type: "button",
|
|
106
|
+
className: chipClass(origin === "added" ? "kept" : "offered"),
|
|
107
|
+
title: String(value),
|
|
108
|
+
"aria-label": require_resolveConsentText.default(t, origin === "added" ? "consent.authorization_details.remove_item" : "consent.authorization_details.add_item", { item: String(value) }),
|
|
109
|
+
onClick: () => field.handleToggle(value),
|
|
110
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
111
|
+
className: chipLabelClass,
|
|
112
|
+
children: [origin === "offered" && "+ ", String(value)]
|
|
113
|
+
}), origin === "added" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
114
|
+
"aria-hidden": "true",
|
|
115
|
+
children: "×"
|
|
116
|
+
})]
|
|
117
|
+
}, `${origin}-${String(value)}`);
|
|
118
|
+
})),
|
|
119
|
+
listToggle,
|
|
120
|
+
field.isTypedItemAllowed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_TextField.default, {
|
|
121
|
+
id: `${inputId}_new`,
|
|
122
|
+
className: inputClass,
|
|
123
|
+
"aria-label": require_resolveConsentText.default(t, "consent.authorization_details.new_item", { label }),
|
|
124
|
+
value: field.text,
|
|
125
|
+
onChange: (e) => field.handleChange(e.target.value),
|
|
126
|
+
onKeyDown: (e) => {
|
|
127
|
+
if (e.key === "Enter") {
|
|
128
|
+
e.preventDefault();
|
|
129
|
+
field.handleAdd(e.currentTarget.value);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
]
|
|
134
|
+
});
|
|
135
|
+
const textAlign = align === "end" ? "right" : "left";
|
|
136
|
+
if (require_isConsentDetailPlainList.default(row.value) && listDisplay.isCollapsible) {
|
|
137
|
+
const items = row.value.slice(0, listDisplay.visibleCount);
|
|
138
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
139
|
+
className: require_emotion.cx(fieldClass, (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-field", "list")), styles["listText"]),
|
|
140
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ConsentDetailText.default, {
|
|
141
|
+
align: textAlign,
|
|
142
|
+
fontWeight: "bold",
|
|
143
|
+
maxChars: Number.POSITIVE_INFINITY,
|
|
144
|
+
maxLines: Number.POSITIVE_INFINITY,
|
|
145
|
+
text: require_formatConsentDetailValue.default(items)
|
|
146
|
+
}), listToggle]
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (require_isConsentDetailStructured.default(row.value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ConsentDetailText.default, {
|
|
150
|
+
className: valueClass,
|
|
151
|
+
monospace: true,
|
|
152
|
+
maxChars: Number.POSITIVE_INFINITY,
|
|
153
|
+
maxLines: require_getConsentDetailLayout.CONSENT_DETAIL_DISPLAY_LIMITS.structuredLines,
|
|
154
|
+
t,
|
|
155
|
+
text: require_formatConsentDetailValue.default(row.value, 2)
|
|
156
|
+
});
|
|
157
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ConsentDetailText.default, {
|
|
158
|
+
className: valueClass,
|
|
159
|
+
align: textAlign,
|
|
160
|
+
fontWeight: "bold",
|
|
161
|
+
maxChars: require_getConsentDetailLayout.CONSENT_DETAIL_DISPLAY_LIMITS.valueChars,
|
|
162
|
+
maxLines: require_getConsentDetailLayout.CONSENT_DETAIL_DISPLAY_LIMITS.valueLines,
|
|
163
|
+
t,
|
|
164
|
+
text: require_formatConsentDetailValue.default(row.value)
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
var ConsentDetailField_default = ConsentDetailField;
|
|
168
|
+
|
|
169
|
+
//#endregion
|
|
170
|
+
exports.default = ConsentDetailField_default;
|
|
171
|
+
//# sourceMappingURL=ConsentDetailField.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsentDetailField.cjs","names":["ConsentDetailField: FC<ConsentDetailFieldProps>","field: UseConsentDetailFieldResult","useConsentDetailField","useTheme","styles: Record<string, string>","useStyles","fieldClass: string","listToggle: ReactNode","ConsentDetailToggle","cx","chipLabelClass: string","chipsClass: string","inputClass: string","valueClass: string","TextField","resolveConsentText","textAlign: 'left' | 'right'","isConsentDetailPlainList","items: (string | number | boolean)[]","ConsentDetailText","formatConsentDetailValue","isConsentDetailStructured","CONSENT_DETAIL_DISPLAY_LIMITS"],"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,85 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_emotion = require('../../../styles/emotion.cjs');
|
|
3
|
+
let react = require("react");
|
|
4
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
5
|
+
|
|
6
|
+
//#region src/components/auth/flow/ConsentDetailField.styles.ts
|
|
7
|
+
/**
|
|
8
|
+
* Creates styles for the ConsentDetailField component.
|
|
9
|
+
* @param theme - The theme object containing design tokens
|
|
10
|
+
* @param colorScheme - The current color scheme (used for memoization)
|
|
11
|
+
* @param align - Side the value is aligned to: `end` beside its label, `start` when stacked below it
|
|
12
|
+
* @returns Object containing CSS class names for component styling
|
|
13
|
+
*/
|
|
14
|
+
const useStyles = (theme, colorScheme, align) => (0, react.useMemo)(() => {
|
|
15
|
+
const chip = require_emotion.css({
|
|
16
|
+
alignItems: "center",
|
|
17
|
+
borderRadius: "9999px",
|
|
18
|
+
boxSizing: "border-box",
|
|
19
|
+
cursor: "pointer",
|
|
20
|
+
display: "inline-flex",
|
|
21
|
+
font: "inherit",
|
|
22
|
+
fontSize: "0.8125rem",
|
|
23
|
+
gap: "6px",
|
|
24
|
+
maxWidth: "100%",
|
|
25
|
+
minWidth: 0,
|
|
26
|
+
padding: "2px 10px",
|
|
27
|
+
"&:disabled": { cursor: "default" }
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
chipLabel: require_emotion.css({
|
|
31
|
+
minWidth: 0,
|
|
32
|
+
overflow: "hidden",
|
|
33
|
+
textOverflow: "ellipsis",
|
|
34
|
+
whiteSpace: "nowrap"
|
|
35
|
+
}),
|
|
36
|
+
chips: require_emotion.css({
|
|
37
|
+
alignItems: "center",
|
|
38
|
+
display: "flex",
|
|
39
|
+
flexWrap: "wrap",
|
|
40
|
+
gap: "6px",
|
|
41
|
+
justifyContent: align === "end" ? "flex-end" : "flex-start",
|
|
42
|
+
maxWidth: "100%",
|
|
43
|
+
minWidth: 0,
|
|
44
|
+
...align === "start" && {
|
|
45
|
+
contain: "inline-size",
|
|
46
|
+
width: "100%"
|
|
47
|
+
}
|
|
48
|
+
}),
|
|
49
|
+
input: require_emotion.css({ maxWidth: "10rem" }),
|
|
50
|
+
keptChip: require_emotion.css(chip, {
|
|
51
|
+
background: "transparent",
|
|
52
|
+
border: `1px solid ${theme.vars.colors.primary.main}`,
|
|
53
|
+
color: theme.vars.colors.primary.main
|
|
54
|
+
}),
|
|
55
|
+
listText: require_emotion.css({
|
|
56
|
+
alignItems: "baseline",
|
|
57
|
+
display: "flex",
|
|
58
|
+
flexWrap: "wrap",
|
|
59
|
+
gap: "2px 6px",
|
|
60
|
+
justifyContent: align === "end" ? "flex-end" : "flex-start",
|
|
61
|
+
maxWidth: "100%",
|
|
62
|
+
minWidth: 0
|
|
63
|
+
}),
|
|
64
|
+
offeredChip: require_emotion.css(chip, {
|
|
65
|
+
background: "transparent",
|
|
66
|
+
border: `1px dashed ${theme.vars.colors.border}`,
|
|
67
|
+
color: theme.vars.colors.text.secondary
|
|
68
|
+
}),
|
|
69
|
+
removedChip: require_emotion.css(chip, {
|
|
70
|
+
background: "transparent",
|
|
71
|
+
border: `1px solid ${theme.vars.colors.border}`,
|
|
72
|
+
color: theme.vars.colors.text.secondary,
|
|
73
|
+
textDecoration: "line-through"
|
|
74
|
+
})
|
|
75
|
+
};
|
|
76
|
+
}, [
|
|
77
|
+
theme,
|
|
78
|
+
colorScheme,
|
|
79
|
+
align
|
|
80
|
+
]);
|
|
81
|
+
var ConsentDetailField_styles_default = useStyles;
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
exports.default = ConsentDetailField_styles_default;
|
|
85
|
+
//# sourceMappingURL=ConsentDetailField.styles.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsentDetailField.styles.cjs","names":["chip: string","css"],"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,mCACtC;CACZ,MAAMA,OAAeC,oBAAI;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,WAAWA,oBAAI;GAAC,UAAU;GAAG,UAAU;GAAU,cAAc;GAAY,YAAY;GAAS,CAAC;EACjG,OAAOA,oBAAI;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,OAAOA,oBAAI,EAAC,UAAU,SAAQ,CAAC;EAC/B,UAAUA,oBAAI,MAAM;GAClB,YAAY;GACZ,QAAQ,aAAa,MAAM,KAAK,OAAO,QAAQ;GAC/C,OAAO,MAAM,KAAK,OAAO,QAAQ;GAClC,CAAC;EACF,UAAUA,oBAAI;GACZ,YAAY;GACZ,SAAS;GACT,UAAU;GACV,KAAK;GACL,gBAAgB,UAAU,QAAQ,aAAa;GAC/C,UAAU;GACV,UAAU;GACX,CAAC;EACF,aAAaA,oBAAI,MAAM;GACrB,YAAY;GACZ,QAAQ,cAAc,MAAM,KAAK,OAAO;GACxC,OAAO,MAAM,KAAK,OAAO,KAAK;GAC/B,CAAC;EACF,aAAaA,oBAAI,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,63 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_emotion = require('../../../styles/emotion.cjs');
|
|
3
|
+
const require_useTheme = require('../../../contexts/Theme/useTheme.cjs');
|
|
4
|
+
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
5
|
+
const require_ConsentDetailText_styles = require('./ConsentDetailText.styles.cjs');
|
|
6
|
+
const require_resolveConsentText = require('./resolveConsentText.cjs');
|
|
7
|
+
const require_isConsentDetailTextClamped = require('../../../utils/isConsentDetailTextClamped.cjs');
|
|
8
|
+
let __thunderid_browser = require("@thunderid/browser");
|
|
9
|
+
__thunderid_browser = require_rolldown_runtime.__toESM(__thunderid_browser);
|
|
10
|
+
let react = require("react");
|
|
11
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
12
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
13
|
+
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
14
|
+
|
|
15
|
+
//#region src/components/auth/flow/ConsentDetailText.tsx
|
|
16
|
+
/**
|
|
17
|
+
* Button that expands or collapses long authorization detail content.
|
|
18
|
+
*/
|
|
19
|
+
const ConsentDetailToggle = ({ controls = void 0, expanded, hiddenCount = void 0, onToggle, t = void 0 }) => {
|
|
20
|
+
const { theme, colorScheme } = require_useTheme.default();
|
|
21
|
+
const styles = require_ConsentDetailText_styles.useToggleStyles(theme, colorScheme);
|
|
22
|
+
let label = require_resolveConsentText.default(t, "consent.authorization_details.show_less");
|
|
23
|
+
if (!expanded) label = hiddenCount === void 0 ? require_resolveConsentText.default(t, "consent.authorization_details.show_more") : require_resolveConsentText.default(t, "consent.authorization_details.more_items", { count: hiddenCount });
|
|
24
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
25
|
+
type: "button",
|
|
26
|
+
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-text", "toggle")), styles["toggle"]),
|
|
27
|
+
"aria-controls": controls,
|
|
28
|
+
"aria-expanded": expanded,
|
|
29
|
+
onClick: () => onToggle(!expanded),
|
|
30
|
+
children: label
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Shows authorization detail text that wraps anywhere, so a long unbroken token such as an IBAN or a
|
|
35
|
+
* URL never overflows. Text longer than its limit is clamped behind a toggle.
|
|
36
|
+
*/
|
|
37
|
+
const ConsentDetailText = ({ align = "left", className = void 0, fontWeight = void 0, id = void 0, maxChars, maxLines, monospace = false, t = void 0, text, variant = "body2" }) => {
|
|
38
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
39
|
+
const { theme, colorScheme } = require_useTheme.default();
|
|
40
|
+
const styles = require_ConsentDetailText_styles.default(theme, colorScheme, align, monospace, maxLines);
|
|
41
|
+
const long = require_isConsentDetailTextClamped.default(text, maxChars, maxLines);
|
|
42
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
43
|
+
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-text")), styles["container"]),
|
|
44
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Typography.default, {
|
|
45
|
+
id,
|
|
46
|
+
variant,
|
|
47
|
+
fontWeight,
|
|
48
|
+
className: require_emotion.cx((0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-text", "text")), styles["text"], monospace && (0, __thunderid_browser.withVendorCSSClassPrefix)((0, __thunderid_browser.bem)("consent-detail-text", "text", "monospace")), monospace && styles["monospace"], long && !expanded && styles["clamp"], className),
|
|
49
|
+
children: text
|
|
50
|
+
}), long && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConsentDetailToggle, {
|
|
51
|
+
controls: id,
|
|
52
|
+
expanded,
|
|
53
|
+
onToggle: setExpanded,
|
|
54
|
+
t
|
|
55
|
+
})]
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
var ConsentDetailText_default = ConsentDetailText;
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
exports.ConsentDetailToggle = ConsentDetailToggle;
|
|
62
|
+
exports.default = ConsentDetailText_default;
|
|
63
|
+
//# sourceMappingURL=ConsentDetailText.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsentDetailText.cjs","names":["ConsentDetailToggle: FC<ConsentDetailToggleProps>","useTheme","styles: Record<string, string>","useToggleStyles","label: string","resolveConsentText","cx","ConsentDetailText: FC<ConsentDetailTextProps>","useStyles","long: boolean","isConsentDetailTextClamped","Typography"],"sources":["../../../../../src/components/auth/flow/ConsentDetailText.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {bem, withVendorCSSClassPrefix} from '@thunderid/browser';\nimport {FC, ReactElement, useState} from 'react';\nimport useStyles, {useToggleStyles} from './ConsentDetailText.styles';\nimport resolveConsentText from './resolveConsentText';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport {UseTranslation} from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport isConsentDetailTextClamped from '../../../utils/isConsentDetailTextClamped';\nimport Typography from '../../primitives/Typography/Typography';\n\n/**\n * Props for the ConsentDetailToggle component.\n */\nexport interface ConsentDetailToggleProps {\n /** Id of the element the toggle shows more or less of. */\n controls?: string;\n /** Whether everything is shown. */\n expanded: boolean;\n /** Number of items hidden while collapsed. When given, the collapsed label counts them. */\n hiddenCount?: number;\n /** Callback invoked with the next expanded state. */\n onToggle: (expanded: boolean) => void;\n /** translation data */\n t?: UseTranslation['t'];\n}\n\n/**\n * Button that expands or collapses long authorization detail content.\n */\nexport const ConsentDetailToggle: FC<ConsentDetailToggleProps> = ({\n controls = undefined,\n expanded,\n hiddenCount = undefined,\n onToggle,\n t = undefined,\n}: ConsentDetailToggleProps): ReactElement => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const styles: Record<string, string> = useToggleStyles(theme, colorScheme);\n\n let label: string = resolveConsentText(t, 'consent.authorization_details.show_less');\n if (!expanded) {\n label =\n hiddenCount === undefined\n ? resolveConsentText(t, 'consent.authorization_details.show_more')\n : resolveConsentText(t, 'consent.authorization_details.more_items', {count: hiddenCount});\n }\n\n return (\n <button\n type=\"button\"\n className={cx(withVendorCSSClassPrefix(bem('consent-detail-text', 'toggle')), styles['toggle'])}\n aria-controls={controls}\n aria-expanded={expanded}\n onClick={(): void => onToggle(!expanded)}\n >\n {label}\n </button>\n );\n};\n\n/**\n * Props for the ConsentDetailText component.\n */\nexport interface ConsentDetailTextProps {\n /** Alignment of the text. */\n align?: 'left' | 'right';\n /** Class name applied to the text. */\n className?: string;\n /** Weight of the text. */\n fontWeight?: 'normal' | 'medium' | 'semibold' | 'bold';\n /** Id of the text element. */\n id?: string;\n /** Number of characters above which the text is clamped. */\n maxChars: number;\n /** Number of lines the text is clamped to. */\n maxLines: number;\n /** Shows the text as a preformatted monospace block, for structured JSON. */\n monospace?: boolean;\n /** translation data */\n t?: UseTranslation['t'];\n /** Text to show. */\n text: string;\n /** Typography variant of the text. */\n variant?: 'body2' | 'subtitle2';\n}\n\n/**\n * Shows authorization detail text that wraps anywhere, so a long unbroken token such as an IBAN or a\n * URL never overflows. Text longer than its limit is clamped behind a toggle.\n */\nconst ConsentDetailText: FC<ConsentDetailTextProps> = ({\n align = 'left',\n className = undefined,\n fontWeight = undefined,\n id = undefined,\n maxChars,\n maxLines,\n monospace = false,\n t = undefined,\n text,\n variant = 'body2',\n}: ConsentDetailTextProps): ReactElement => {\n const [expanded, setExpanded] = useState<boolean>(false);\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme, align, monospace, maxLines);\n const long: boolean = isConsentDetailTextClamped(text, maxChars, maxLines);\n\n return (\n <div className={cx(withVendorCSSClassPrefix(bem('consent-detail-text')), styles['container'])}>\n <Typography\n id={id}\n variant={variant}\n fontWeight={fontWeight}\n className={cx(\n withVendorCSSClassPrefix(bem('consent-detail-text', 'text')),\n styles['text'],\n monospace && withVendorCSSClassPrefix(bem('consent-detail-text', 'text', 'monospace')),\n monospace && styles['monospace'],\n long && !expanded && styles['clamp'],\n className,\n )}\n >\n {text}\n </Typography>\n {long && <ConsentDetailToggle controls={id} expanded={expanded} onToggle={setExpanded} t={t} />}\n </div>\n );\n};\n\nexport default ConsentDetailText;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgCA,MAAaA,uBAAqD,EAChE,WAAW,QACX,UACA,cAAc,QACd,UACA,IAAI,aACwC;CAC5C,MAAM,EAAC,OAAO,gBAA4CC,0BAAU;CACpE,MAAMC,SAAiCC,iDAAgB,OAAO,YAAY;CAE1E,IAAIC,QAAgBC,mCAAmB,GAAG,0CAA0C;AACpF,KAAI,CAAC,SACH,SACE,gBAAgB,SACZA,mCAAmB,GAAG,0CAA0C,GAChEA,mCAAmB,GAAG,4CAA4C,EAAC,OAAO,aAAY,CAAC;AAG/F,QACE,2CAAC;EACC,MAAK;EACL,WAAWC,kGAAgC,uBAAuB,SAAS,CAAC,EAAE,OAAO,UAAU;EAC/F,iBAAe;EACf,iBAAe;EACf,eAAqB,SAAS,CAAC,SAAS;YAEvC;GACM;;;;;;AAkCb,MAAMC,qBAAiD,EACrD,QAAQ,QACR,YAAY,QACZ,aAAa,QACb,KAAK,QACL,UACA,UACA,YAAY,OACZ,IAAI,QACJ,MACA,UAAU,cACgC;CAC1C,MAAM,CAAC,UAAU,mCAAiC,MAAM;CACxD,MAAM,EAAC,OAAO,gBAA4CN,0BAAU;CACpE,MAAMC,SAAiCM,yCAAU,OAAO,aAAa,OAAO,WAAW,SAAS;CAChG,MAAMC,OAAgBC,2CAA2B,MAAM,UAAU,SAAS;AAE1E,QACE,4CAAC;EAAI,WAAWJ,kGAAgC,sBAAsB,CAAC,EAAE,OAAO,aAAa;aAC3F,2CAACK;GACK;GACK;GACG;GACZ,WAAWL,kGACoB,uBAAuB,OAAO,CAAC,EAC5D,OAAO,SACP,4FAA0C,uBAAuB,QAAQ,YAAY,CAAC,EACtF,aAAa,OAAO,cACpB,QAAQ,CAAC,YAAY,OAAO,UAC5B,UACD;aAEA;IACU,EACZ,QAAQ,2CAAC;GAAoB,UAAU;GAAc;GAAU,UAAU;GAAgB;IAAK;GAC3F;;AAIV,gCAAe"}
|