@thunderid/react 1.10.1 → 1.11.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/auth/AcceptInvite/BaseAcceptInvite.cjs +1 -1
- package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.cjs +61 -0
- package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.cjs.map +1 -0
- package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.styles.cjs +26 -0
- package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.styles.cjs.map +1 -0
- package/dist/cjs/components/auth/DeviceGrant/DeviceGrant.cjs +192 -0
- package/dist/cjs/components/auth/DeviceGrant/DeviceGrant.cjs.map +1 -0
- package/dist/cjs/components/auth/InviteUser/BaseInviteUser.cjs +1 -1
- package/dist/cjs/components/auth/Recovery/BaseRecovery.cjs +2 -2
- package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs +15 -4
- package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs.map +1 -1
- package/dist/cjs/components/auth/SignUp/BaseSignUp.cjs +2 -2
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +17 -2
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/Consent.cjs +1 -1
- package/dist/cjs/components/primitives/Alert/Alert.cjs +1 -1
- package/dist/cjs/components/primitives/Card/Card.cjs +1 -1
- package/dist/cjs/components/primitives/Typography/Typography.styles.cjs +3 -0
- package/dist/cjs/components/primitives/Typography/Typography.styles.cjs.map +1 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs +1 -0
- package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs.map +1 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs +3 -0
- package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
- package/dist/cjs/hooks/management/useGrantedPermissions.cjs +6 -5
- package/dist/cjs/hooks/management/useGrantedPermissions.cjs.map +1 -1
- package/dist/cjs/index.cjs +6 -2
- package/dist/components/account/UserProfile/BaseUserProfile.js +1 -1
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js +1 -1
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.d.ts +17 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.d.ts.map +1 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.js +58 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.js.map +1 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.d.ts +4 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.d.ts.map +1 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.js +24 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.js.map +1 -0
- package/dist/components/auth/DeviceGrant/DeviceGrant.d.ts +37 -0
- package/dist/components/auth/DeviceGrant/DeviceGrant.d.ts.map +1 -0
- package/dist/components/auth/DeviceGrant/DeviceGrant.js +188 -0
- package/dist/components/auth/DeviceGrant/DeviceGrant.js.map +1 -0
- package/dist/components/auth/InviteUser/BaseInviteUser.js +1 -1
- package/dist/components/auth/Recovery/BaseRecovery.js +2 -2
- package/dist/components/auth/SignIn/BaseSignIn.d.ts +4 -0
- package/dist/components/auth/SignIn/BaseSignIn.d.ts.map +1 -1
- package/dist/components/auth/SignIn/BaseSignIn.js +16 -5
- package/dist/components/auth/SignIn/BaseSignIn.js.map +1 -1
- package/dist/components/auth/SignUp/BaseSignUp.js +2 -2
- package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
- package/dist/components/auth/flow/AuthOptionFactory.js +17 -2
- package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
- package/dist/components/auth/flow/Consent.js +1 -1
- package/dist/components/primitives/Alert/Alert.js +1 -1
- package/dist/components/primitives/Card/Card.js +1 -1
- package/dist/components/primitives/Typography/Typography.styles.d.ts.map +1 -1
- package/dist/components/primitives/Typography/Typography.styles.js +3 -0
- package/dist/components/primitives/Typography/Typography.styles.js.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDContext.d.ts +6 -0
- package/dist/contexts/ThunderID/ThunderIDContext.d.ts.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDContext.js +1 -0
- package/dist/contexts/ThunderID/ThunderIDContext.js.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.js +3 -0
- package/dist/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
- package/dist/hooks/management/useGrantedPermissions.d.ts +2 -1
- package/dist/hooks/management/useGrantedPermissions.d.ts.map +1 -1
- package/dist/hooks/management/useGrantedPermissions.js +7 -6
- package/dist/hooks/management/useGrantedPermissions.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/package.json +2 -2
|
@@ -4,8 +4,8 @@ const require_useTheme = require('../../../contexts/Theme/useTheme.cjs');
|
|
|
4
4
|
const require_useTranslation = require('../../../hooks/useTranslation.cjs');
|
|
5
5
|
const require_Button = require('../../primitives/Button/Button.cjs');
|
|
6
6
|
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
7
|
-
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
8
7
|
const require_Card = require('../../primitives/Card/Card.cjs');
|
|
8
|
+
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
9
9
|
const require_TextField = require('../../primitives/TextField/TextField.cjs');
|
|
10
10
|
const require_Checkbox = require('../../primitives/Checkbox/Checkbox.cjs');
|
|
11
11
|
const require_DatePicker = require('../../primitives/DatePicker/DatePicker.cjs');
|
|
@@ -8,8 +8,8 @@ const require_flowTransformer = require('../../../utils/flowTransformer.cjs');
|
|
|
8
8
|
const require_Spinner = require('../../primitives/Spinner/Spinner.cjs');
|
|
9
9
|
const require_Button = require('../../primitives/Button/Button.cjs');
|
|
10
10
|
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
11
|
-
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
12
11
|
const require_Card = require('../../primitives/Card/Card.cjs');
|
|
12
|
+
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
13
13
|
const require_isConsentApprovalBlocked = require('../../../utils/isConsentApprovalBlocked.cjs');
|
|
14
14
|
const require_AuthOptionFactory = require('../flow/AuthOptionFactory.cjs');
|
|
15
15
|
const require_useOAuthCallback = require('../../../hooks/auth/useOAuthCallback.cjs');
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_useTheme = require('../../../contexts/Theme/useTheme.cjs');
|
|
3
|
+
const require_useTranslation = require('../../../hooks/useTranslation.cjs');
|
|
4
|
+
const require_BaseDeviceGrant_styles = require('./BaseDeviceGrant.styles.cjs');
|
|
5
|
+
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
6
|
+
const require_Card = require('../../primitives/Card/Card.cjs');
|
|
7
|
+
const require_BaseSignIn = require('../SignIn/BaseSignIn.cjs');
|
|
8
|
+
let react = require("react");
|
|
9
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
10
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
11
|
+
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
12
|
+
|
|
13
|
+
//#region src/components/auth/DeviceGrant/BaseDeviceGrant.tsx
|
|
14
|
+
/** Renders the server-described Device Grant prompt independently of SDK orchestration. */
|
|
15
|
+
const BaseDeviceGrant = ({ components, className = "", completeMessage = void 0, completeDescription = void 0, failedMessage = void 0, failedDescription = void 0, error, isLoading, preferences, result = null, variant = "default",...signInProps }) => {
|
|
16
|
+
const { theme } = require_useTheme.default();
|
|
17
|
+
const { t } = require_useTranslation.default(preferences?.i18n);
|
|
18
|
+
const styles = require_BaseDeviceGrant_styles.default(theme);
|
|
19
|
+
if ((error || result) && components.length === 0) {
|
|
20
|
+
const isSuccess = result === "success" && !error;
|
|
21
|
+
const resolvedCompleteMessage = completeMessage ?? t("deviceGrant.messages.complete");
|
|
22
|
+
const resolvedCompleteDescription = completeDescription ?? t("deviceGrant.messages.completeDescription");
|
|
23
|
+
const resolvedFailedMessage = failedMessage ?? t("deviceGrant.messages.failed");
|
|
24
|
+
const resolvedFailedDescription = failedDescription ?? t("deviceGrant.messages.failedDescription");
|
|
25
|
+
const title = isSuccess ? resolvedCompleteMessage : resolvedFailedMessage;
|
|
26
|
+
const description = isSuccess ? resolvedCompleteDescription : !error || error.message === resolvedFailedMessage ? resolvedFailedDescription : error.message;
|
|
27
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Card.default, {
|
|
28
|
+
className: `${styles["terminalCard"]} ${className}`,
|
|
29
|
+
"data-testid": "device-grant-result",
|
|
30
|
+
variant,
|
|
31
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Typography.default, {
|
|
32
|
+
className: styles["terminalTitle"],
|
|
33
|
+
color: isSuccess ? "success" : "error",
|
|
34
|
+
component: "h2",
|
|
35
|
+
fontWeight: 600,
|
|
36
|
+
variant: "h6",
|
|
37
|
+
children: title
|
|
38
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Typography.default, {
|
|
39
|
+
className: styles["terminalDescription"],
|
|
40
|
+
color: "textSecondary",
|
|
41
|
+
component: "p",
|
|
42
|
+
variant: "caption",
|
|
43
|
+
children: description
|
|
44
|
+
})]
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return /* @__PURE__ */ (0, react.createElement)(require_BaseSignIn.default, {
|
|
48
|
+
...signInProps,
|
|
49
|
+
className,
|
|
50
|
+
key: components.map((component) => component.id).join("|"),
|
|
51
|
+
components,
|
|
52
|
+
error,
|
|
53
|
+
isLoading,
|
|
54
|
+
preferences
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
var BaseDeviceGrant_default = BaseDeviceGrant;
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
exports.default = BaseDeviceGrant_default;
|
|
61
|
+
//# sourceMappingURL=BaseDeviceGrant.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseDeviceGrant.cjs","names":["BaseDeviceGrant: FC<BaseDeviceGrantProps>","useTheme","useTranslation","useStyles","CardPrimitive","Typography","BaseSignIn"],"sources":["../../../../../src/components/auth/DeviceGrant/BaseDeviceGrant.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport type {EmbeddedFlowComponent} from '@thunderid/browser';\nimport {FC, ReactElement} from 'react';\nimport useStyles from './BaseDeviceGrant.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useTranslation from '../../../hooks/useTranslation';\nimport CardPrimitive from '../../primitives/Card/Card';\nimport Typography from '../../primitives/Typography/Typography';\nimport BaseSignIn, {type BaseSignInProps} from '../SignIn/BaseSignIn';\n\nexport type DeviceGrantResult = 'failure' | 'success' | null;\n\nexport interface BaseDeviceGrantProps extends Omit<BaseSignInProps, 'components' | 'onSubmit'> {\n components: EmbeddedFlowComponent[];\n completeMessage?: string;\n completeDescription?: string;\n failedMessage?: string;\n failedDescription?: string;\n onSubmit: NonNullable<BaseSignInProps['onSubmit']>;\n result?: DeviceGrantResult;\n}\n\n/** Renders the server-described Device Grant prompt independently of SDK orchestration. */\nconst BaseDeviceGrant: FC<BaseDeviceGrantProps> = ({\n components,\n className = '',\n completeMessage = undefined,\n completeDescription = undefined,\n failedMessage = undefined,\n failedDescription = undefined,\n error,\n isLoading,\n preferences,\n result = null,\n variant = 'default',\n ...signInProps\n}: BaseDeviceGrantProps): ReactElement => {\n const {theme} = useTheme();\n const {t} = useTranslation(preferences?.i18n);\n const styles = useStyles(theme);\n\n if ((error || result) && components.length === 0) {\n const isSuccess = result === 'success' && !error;\n const resolvedCompleteMessage = completeMessage ?? t('deviceGrant.messages.complete');\n const resolvedCompleteDescription = completeDescription ?? t('deviceGrant.messages.completeDescription');\n const resolvedFailedMessage = failedMessage ?? t('deviceGrant.messages.failed');\n const resolvedFailedDescription = failedDescription ?? t('deviceGrant.messages.failedDescription');\n const title = isSuccess ? resolvedCompleteMessage : resolvedFailedMessage;\n const description = isSuccess\n ? resolvedCompleteDescription\n : !error || error.message === resolvedFailedMessage\n ? resolvedFailedDescription\n : error.message;\n\n return (\n <CardPrimitive\n className={`${styles['terminalCard']} ${className}`}\n data-testid=\"device-grant-result\"\n variant={variant}\n >\n <Typography\n className={styles['terminalTitle']}\n color={isSuccess ? 'success' : 'error'}\n component=\"h2\"\n fontWeight={600}\n variant=\"h6\"\n >\n {title}\n </Typography>\n <Typography className={styles['terminalDescription']} color=\"textSecondary\" component=\"p\" variant=\"caption\">\n {description}\n </Typography>\n </CardPrimitive>\n );\n }\n\n return (\n <BaseSignIn\n {...signInProps}\n className={className}\n key={components.map((component: EmbeddedFlowComponent) => component.id).join('|')}\n components={components}\n error={error}\n isLoading={isLoading}\n preferences={preferences}\n />\n );\n};\n\nexport default BaseDeviceGrant;\n"],"mappings":";;;;;;;;;;;;;;AAyBA,MAAMA,mBAA6C,EACjD,YACA,YAAY,IACZ,kBAAkB,QAClB,sBAAsB,QACtB,gBAAgB,QAChB,oBAAoB,QACpB,OACA,WACA,aACA,SAAS,MACT,UAAU,UACV,GAAG,kBACqC;CACxC,MAAM,EAAC,UAASC,0BAAU;CAC1B,MAAM,EAAC,MAAKC,+BAAe,aAAa,KAAK;CAC7C,MAAM,SAASC,uCAAU,MAAM;AAE/B,MAAK,SAAS,WAAW,WAAW,WAAW,GAAG;EAChD,MAAM,YAAY,WAAW,aAAa,CAAC;EAC3C,MAAM,0BAA0B,mBAAmB,EAAE,gCAAgC;EACrF,MAAM,8BAA8B,uBAAuB,EAAE,2CAA2C;EACxG,MAAM,wBAAwB,iBAAiB,EAAE,8BAA8B;EAC/E,MAAM,4BAA4B,qBAAqB,EAAE,yCAAyC;EAClG,MAAM,QAAQ,YAAY,0BAA0B;EACpD,MAAM,cAAc,YAChB,8BACA,CAAC,SAAS,MAAM,YAAY,wBAC1B,4BACA,MAAM;AAEZ,SACE,4CAACC;GACC,WAAW,GAAG,OAAO,gBAAgB,GAAG;GACxC,eAAY;GACH;cAET,2CAACC;IACC,WAAW,OAAO;IAClB,OAAO,YAAY,YAAY;IAC/B,WAAU;IACV,YAAY;IACZ,SAAQ;cAEP;KACU,EACb,2CAACA;IAAW,WAAW,OAAO;IAAwB,OAAM;IAAgB,WAAU;IAAI,SAAQ;cAC/F;KACU;IACC;;AAIpB,QACE,yCAACC;EACC,GAAI;EACO;EACX,KAAK,WAAW,KAAK,cAAqC,UAAU,GAAG,CAAC,KAAK,IAAI;EACrE;EACL;EACI;EACE;GACb;;AAIN,8BAAe"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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/DeviceGrant/BaseDeviceGrant.styles.ts
|
|
7
|
+
const useStyles = (theme) => (0, react.useMemo)(() => ({
|
|
8
|
+
terminalCard: require_emotion.css`
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
width: 100%;
|
|
11
|
+
max-width: calc(${theme.vars.spacing.unit} * 60);
|
|
12
|
+
margin: 0 auto;
|
|
13
|
+
gap: ${theme.vars.spacing.unit};
|
|
14
|
+
`,
|
|
15
|
+
terminalDescription: require_emotion.css`
|
|
16
|
+
margin: 0;
|
|
17
|
+
`,
|
|
18
|
+
terminalTitle: require_emotion.css`
|
|
19
|
+
margin: 0;
|
|
20
|
+
`
|
|
21
|
+
}), [theme]);
|
|
22
|
+
var BaseDeviceGrant_styles_default = useStyles;
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
exports.default = BaseDeviceGrant_styles_default;
|
|
26
|
+
//# sourceMappingURL=BaseDeviceGrant.styles.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseDeviceGrant.styles.cjs","names":[],"sources":["../../../../../src/components/auth/DeviceGrant/BaseDeviceGrant.styles.ts"],"sourcesContent":["// Copyright 2025-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\nconst useStyles = (theme: Theme): Record<string, string> =>\n useMemo(\n () => ({\n terminalCard: css`\n box-sizing: border-box;\n width: 100%;\n max-width: calc(${theme.vars.spacing.unit} * 60);\n margin: 0 auto;\n gap: ${theme.vars.spacing.unit};\n `,\n terminalDescription: css`\n margin: 0;\n `,\n terminalTitle: css`\n margin: 0;\n `,\n }),\n [theme],\n );\n\nexport default useStyles;\n"],"mappings":";;;;;;AAOA,MAAM,aAAa,oCAER;CACL,cAAc,mBAAG;;;0BAGG,MAAM,KAAK,QAAQ,KAAK;;eAEnC,MAAM,KAAK,QAAQ,KAAK;;CAEjC,qBAAqB,mBAAG;;;CAGxB,eAAe,mBAAG;;;CAGnB,GACD,CAAC,MAAM,CACR;AAEH,qCAAe"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_useThunderID = require('../../../contexts/ThunderID/useThunderID.cjs');
|
|
3
|
+
const require_useTranslation = require('../../../hooks/useTranslation.cjs');
|
|
4
|
+
const require_flowTransformer = require('../../../utils/flowTransformer.cjs');
|
|
5
|
+
const require_BaseDeviceGrant = require('./BaseDeviceGrant.cjs');
|
|
6
|
+
let __thunderid_browser = require("@thunderid/browser");
|
|
7
|
+
__thunderid_browser = require_rolldown_runtime.__toESM(__thunderid_browser);
|
|
8
|
+
let react = require("react");
|
|
9
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
10
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
11
|
+
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
12
|
+
|
|
13
|
+
//#region src/components/auth/DeviceGrant/DeviceGrant.tsx
|
|
14
|
+
const clearVerificationParameters = () => {
|
|
15
|
+
if (!window.location.href) return;
|
|
16
|
+
const url = new URL(window.location.href);
|
|
17
|
+
url.searchParams.delete("user_code");
|
|
18
|
+
url.searchParams.delete("applicationId");
|
|
19
|
+
window.history.replaceState(window.history.state, "", url.toString());
|
|
20
|
+
};
|
|
21
|
+
const hasUserCodeInput = (components) => components.some((component) => component.ref === "user_code" || Array.isArray(component.components) && hasUserCodeInput(component.components));
|
|
22
|
+
/**
|
|
23
|
+
* Runs the application's configured Device Grant flow and exposes its state for custom renderers.
|
|
24
|
+
*/
|
|
25
|
+
const DeviceGrant = ({ children = void 0, className = "", onComplete = void 0, onError = void 0, preferences = {}, size = "medium", variant = "default",...baseProps }) => {
|
|
26
|
+
const { applicationId, baseUrl, meta } = require_useThunderID.default();
|
|
27
|
+
const { t } = require_useTranslation.default(preferences?.i18n);
|
|
28
|
+
const [components, setComponents] = (0, react.useState)([]);
|
|
29
|
+
const [additionalData, setAdditionalData] = (0, react.useState)({});
|
|
30
|
+
const [initialValues, setInitialValues] = (0, react.useState)({});
|
|
31
|
+
const [serverFieldErrors, setServerFieldErrors] = (0, react.useState)(null);
|
|
32
|
+
const [executionId, setExecutionId] = (0, react.useState)("");
|
|
33
|
+
const [challengeToken, setChallengeToken] = (0, react.useState)("");
|
|
34
|
+
const [error, setError] = (0, react.useState)(null);
|
|
35
|
+
const [isLoading, setIsLoading] = (0, react.useState)(() => {
|
|
36
|
+
if (applicationId) return true;
|
|
37
|
+
return typeof window !== "undefined" && Boolean(new URL(window.location.href).searchParams.get("applicationId"));
|
|
38
|
+
});
|
|
39
|
+
const [result, setResult] = (0, react.useState)(null);
|
|
40
|
+
const flowStartAttempted = (0, react.useRef)(false);
|
|
41
|
+
const verificationParametersRead = (0, react.useRef)(false);
|
|
42
|
+
const handleError = (0, react.useCallback)((flowError) => {
|
|
43
|
+
setComponents([]);
|
|
44
|
+
setAdditionalData({});
|
|
45
|
+
setServerFieldErrors(null);
|
|
46
|
+
setError(flowError);
|
|
47
|
+
setResult("failure");
|
|
48
|
+
onError?.(flowError);
|
|
49
|
+
}, [onError]);
|
|
50
|
+
const applyResponse = (0, react.useCallback)((response) => {
|
|
51
|
+
const normalized = require_flowTransformer.normalizeFlowResponse(response, t, {
|
|
52
|
+
throwOnError: false,
|
|
53
|
+
resolveTranslations: false
|
|
54
|
+
}, meta);
|
|
55
|
+
setExecutionId(response.executionId);
|
|
56
|
+
setChallengeToken(response.challengeToken ?? "");
|
|
57
|
+
setComponents(normalized.components);
|
|
58
|
+
setAdditionalData(normalized.additionalData);
|
|
59
|
+
setServerFieldErrors(response.data?.fieldErrors ?? null);
|
|
60
|
+
setError(response.error ? new Error(require_flowTransformer.extractErrorMessage(response, t)) : null);
|
|
61
|
+
if (response.flowStatus === __thunderid_browser.EmbeddedSignInFlowStatus.Complete) {
|
|
62
|
+
setResult("success");
|
|
63
|
+
onComplete?.(response);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (response.flowStatus === __thunderid_browser.EmbeddedSignInFlowStatus.Error) {
|
|
67
|
+
const flowError = new Error(require_flowTransformer.extractErrorMessage(response, t, "deviceGrant.messages.failed"));
|
|
68
|
+
setError(flowError);
|
|
69
|
+
setResult("failure");
|
|
70
|
+
onError?.(flowError);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
setResult(null);
|
|
74
|
+
}, [
|
|
75
|
+
meta,
|
|
76
|
+
onComplete,
|
|
77
|
+
onError,
|
|
78
|
+
t
|
|
79
|
+
]);
|
|
80
|
+
const startFlow = (0, react.useCallback)(async (appId) => {
|
|
81
|
+
setIsLoading(true);
|
|
82
|
+
setError(null);
|
|
83
|
+
try {
|
|
84
|
+
const response = await (0, __thunderid_browser.executeEmbeddedDeviceGrantFlow)({
|
|
85
|
+
baseUrl,
|
|
86
|
+
payload: {
|
|
87
|
+
applicationId: appId,
|
|
88
|
+
flowType: __thunderid_browser.EmbeddedFlowType.DeviceGrant,
|
|
89
|
+
inputs: {}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
clearVerificationParameters();
|
|
93
|
+
applyResponse(response);
|
|
94
|
+
} catch (flowError) {
|
|
95
|
+
handleError(flowError instanceof Error ? flowError : new Error(t("deviceGrant.errors.continue")));
|
|
96
|
+
} finally {
|
|
97
|
+
setIsLoading(false);
|
|
98
|
+
}
|
|
99
|
+
}, [
|
|
100
|
+
applyResponse,
|
|
101
|
+
baseUrl,
|
|
102
|
+
handleError,
|
|
103
|
+
t
|
|
104
|
+
]);
|
|
105
|
+
(0, react.useEffect)(() => {
|
|
106
|
+
const url = new URL(window.location.href);
|
|
107
|
+
if (!verificationParametersRead.current) {
|
|
108
|
+
verificationParametersRead.current = true;
|
|
109
|
+
const userCode = url.searchParams.get("user_code") ?? "";
|
|
110
|
+
if (userCode) setInitialValues({ user_code: userCode });
|
|
111
|
+
}
|
|
112
|
+
const applicationIdFromUrl = url.searchParams.get("applicationId");
|
|
113
|
+
const appId = applicationIdFromUrl?.trim() ? applicationIdFromUrl : applicationId;
|
|
114
|
+
if (flowStartAttempted.current) return;
|
|
115
|
+
if (!appId) {
|
|
116
|
+
flowStartAttempted.current = true;
|
|
117
|
+
handleError(new Error(t("deviceGrant.errors.start")));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
flowStartAttempted.current = true;
|
|
121
|
+
startFlow(appId);
|
|
122
|
+
}, [
|
|
123
|
+
applicationId,
|
|
124
|
+
handleError,
|
|
125
|
+
startFlow,
|
|
126
|
+
t
|
|
127
|
+
]);
|
|
128
|
+
const submit = async (payload, actionId) => {
|
|
129
|
+
setIsLoading(true);
|
|
130
|
+
setError(null);
|
|
131
|
+
setResult(null);
|
|
132
|
+
try {
|
|
133
|
+
if (!executionId) return;
|
|
134
|
+
applyResponse(await (0, __thunderid_browser.executeEmbeddedDeviceGrantFlow)({
|
|
135
|
+
baseUrl,
|
|
136
|
+
payload: {
|
|
137
|
+
action: payload.action ?? actionId,
|
|
138
|
+
challengeToken,
|
|
139
|
+
executionId,
|
|
140
|
+
inputs: {
|
|
141
|
+
...Object.fromEntries(Object.entries(payload.inputs ?? {}).filter(([key]) => !key.startsWith("__consent_opt__"))),
|
|
142
|
+
...!hasUserCodeInput(components) ? { user_code: void 0 } : {}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}));
|
|
146
|
+
} catch (flowError) {
|
|
147
|
+
handleError(flowError instanceof Error ? flowError : new Error(t("deviceGrant.errors.continue")));
|
|
148
|
+
} finally {
|
|
149
|
+
setIsLoading(false);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const handleBaseSubmit = (payload, component) => submit(payload, component.id);
|
|
153
|
+
const fieldErrors = (0, react.useMemo)(() => {
|
|
154
|
+
const errors = {};
|
|
155
|
+
(serverFieldErrors ?? []).forEach((fieldError) => {
|
|
156
|
+
if (!(fieldError.identifier in errors)) errors[fieldError.identifier] = fieldError.message;
|
|
157
|
+
});
|
|
158
|
+
return errors;
|
|
159
|
+
}, [serverFieldErrors]);
|
|
160
|
+
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: children({
|
|
161
|
+
additionalData,
|
|
162
|
+
components,
|
|
163
|
+
error,
|
|
164
|
+
fieldErrors,
|
|
165
|
+
initialValues,
|
|
166
|
+
isLoading,
|
|
167
|
+
meta,
|
|
168
|
+
onSubmit: submit,
|
|
169
|
+
result
|
|
170
|
+
}) });
|
|
171
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_BaseDeviceGrant.default, {
|
|
172
|
+
...baseProps,
|
|
173
|
+
className,
|
|
174
|
+
components,
|
|
175
|
+
additionalData,
|
|
176
|
+
error,
|
|
177
|
+
initialValues,
|
|
178
|
+
isLoading,
|
|
179
|
+
onError: handleError,
|
|
180
|
+
onSubmit: handleBaseSubmit,
|
|
181
|
+
preferences,
|
|
182
|
+
result,
|
|
183
|
+
serverFieldErrors,
|
|
184
|
+
size,
|
|
185
|
+
variant
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
var DeviceGrant_default = DeviceGrant;
|
|
189
|
+
|
|
190
|
+
//#endregion
|
|
191
|
+
exports.default = DeviceGrant_default;
|
|
192
|
+
//# sourceMappingURL=DeviceGrant.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceGrant.cjs","names":["DeviceGrant: FC<DeviceGrantProps>","useThunderID","useTranslation","normalizeFlowResponse","extractErrorMessage","EmbeddedSignInFlowStatus","EmbeddedFlowType","errors: Record<string, string>","BaseDeviceGrant"],"sources":["../../../../../src/components/auth/DeviceGrant/DeviceGrant.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {EmbeddedFlowType, EmbeddedSignInFlowStatus, executeEmbeddedDeviceGrantFlow} from '@thunderid/browser';\nimport type {EmbeddedFlowComponent, EmbeddedSignInFlowRequest, FlowMetadataResponse} from '@thunderid/browser';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport type {FC, ReactElement, ReactNode} from 'react';\nimport BaseDeviceGrant, {type BaseDeviceGrantProps, type DeviceGrantResult} from './BaseDeviceGrant';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {extractErrorMessage, normalizeFlowResponse} from '../../../utils/flowTransformer';\n\ntype EmbeddedDeviceGrantFlowResponse = Awaited<ReturnType<typeof executeEmbeddedDeviceGrantFlow>>;\ntype DeviceGrantFieldError = NonNullable<EmbeddedDeviceGrantFlowResponse['data']['fieldErrors']>[number];\n\n/** Values exposed to consumers that provide custom Device Grant UI. */\nexport interface DeviceGrantRenderProps {\n /** Additional values returned for the active flow step. */\n additionalData: Record<string, unknown>;\n /** Components returned by the configured flow. */\n components: EmbeddedFlowComponent[];\n /** Current flow error, when one needs to be shown. */\n error: Error | null;\n /** First server validation message for each field. */\n fieldErrors: Record<string, string>;\n /** Values prefilled from the verification URI. */\n initialValues: Record<string, string>;\n /** Whether a flow request is in progress. */\n isLoading: boolean;\n /** Flow metadata used to resolve application-specific template values. */\n meta: FlowMetadataResponse | null;\n /** Submits user-code input or continues the active flow. */\n onSubmit: (payload: EmbeddedSignInFlowRequest) => Promise<void>;\n /** Terminal flow result when the flow has no configured prompt to render. */\n result: DeviceGrantResult;\n}\n\nexport type DeviceGrantProps = Omit<\n BaseDeviceGrantProps,\n 'children' | 'components' | 'error' | 'initialValues' | 'isLoading' | 'onSubmit' | 'result' | 'serverFieldErrors'\n> & {\n /** Render props for Gate or other consumers that provide their own flow UI. */\n children?: (props: DeviceGrantRenderProps) => ReactNode;\n onComplete?: (response: EmbeddedDeviceGrantFlowResponse) => void;\n};\n\nconst clearVerificationParameters = (): void => {\n if (!window.location.href) return;\n const url = new URL(window.location.href);\n url.searchParams.delete('user_code');\n url.searchParams.delete('applicationId');\n window.history.replaceState(window.history.state, '', url.toString());\n};\n\nconst hasUserCodeInput = (components: EmbeddedFlowComponent[]): boolean =>\n components.some(\n (component: EmbeddedFlowComponent) =>\n component.ref === 'user_code' || (Array.isArray(component.components) && hasUserCodeInput(component.components)),\n );\n\n/**\n * Runs the application's configured Device Grant flow and exposes its state for custom renderers.\n */\nconst DeviceGrant: FC<DeviceGrantProps> = ({\n children = undefined,\n className = '',\n onComplete = undefined,\n onError = undefined,\n preferences = {},\n size = 'medium',\n variant = 'default',\n ...baseProps\n}: DeviceGrantProps): ReactElement => {\n const {applicationId, baseUrl, meta} = useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n const [components, setComponents] = useState<EmbeddedFlowComponent[]>([]);\n const [additionalData, setAdditionalData] = useState<Record<string, unknown>>({});\n const [initialValues, setInitialValues] = useState<Record<string, string>>({});\n const [serverFieldErrors, setServerFieldErrors] = useState<\n EmbeddedDeviceGrantFlowResponse['data']['fieldErrors'] | null\n >(null);\n const [executionId, setExecutionId] = useState('');\n const [challengeToken, setChallengeToken] = useState('');\n const [error, setError] = useState<Error | null>(null);\n const [isLoading, setIsLoading] = useState(() => {\n if (applicationId) return true;\n return typeof window !== 'undefined' && Boolean(new URL(window.location.href).searchParams.get('applicationId'));\n });\n const [result, setResult] = useState<DeviceGrantResult>(null);\n const flowStartAttempted = useRef(false);\n const verificationParametersRead = useRef(false);\n\n const handleError = useCallback(\n (flowError: Error): void => {\n setComponents([]);\n setAdditionalData({});\n setServerFieldErrors(null);\n setError(flowError);\n setResult('failure');\n onError?.(flowError);\n },\n [onError],\n );\n\n const applyResponse = useCallback(\n (response: EmbeddedDeviceGrantFlowResponse): void => {\n const normalized = normalizeFlowResponse(\n response,\n t,\n {\n throwOnError: false,\n resolveTranslations: false,\n },\n meta,\n );\n setExecutionId(response.executionId);\n setChallengeToken(response.challengeToken ?? '');\n setComponents(normalized.components);\n setAdditionalData(normalized.additionalData);\n setServerFieldErrors(response.data?.fieldErrors ?? null);\n setError(response.error ? new Error(extractErrorMessage(response, t)) : null);\n\n if (response.flowStatus === EmbeddedSignInFlowStatus.Complete) {\n setResult('success');\n onComplete?.(response);\n return;\n }\n\n if (response.flowStatus === EmbeddedSignInFlowStatus.Error) {\n const flowError = new Error(extractErrorMessage(response, t, 'deviceGrant.messages.failed'));\n setError(flowError);\n setResult('failure');\n onError?.(flowError);\n return;\n }\n\n setResult(null);\n },\n [meta, onComplete, onError, t],\n );\n\n const startFlow = useCallback(\n async (appId: string): Promise<void> => {\n setIsLoading(true);\n setError(null);\n try {\n const response = await executeEmbeddedDeviceGrantFlow({\n baseUrl,\n payload: {\n applicationId: appId,\n flowType: EmbeddedFlowType.DeviceGrant,\n inputs: {},\n },\n });\n clearVerificationParameters();\n applyResponse(response);\n } catch (flowError) {\n handleError(flowError instanceof Error ? flowError : new Error(t('deviceGrant.errors.continue')));\n } finally {\n setIsLoading(false);\n }\n },\n [applyResponse, baseUrl, handleError, t],\n );\n\n useEffect(() => {\n const url = new URL(window.location.href);\n if (!verificationParametersRead.current) {\n verificationParametersRead.current = true;\n const userCode = url.searchParams.get('user_code') ?? '';\n if (userCode) setInitialValues({user_code: userCode});\n }\n\n const applicationIdFromUrl = url.searchParams.get('applicationId');\n const appId = applicationIdFromUrl?.trim() ? applicationIdFromUrl : applicationId;\n if (flowStartAttempted.current) return;\n if (!appId) {\n flowStartAttempted.current = true;\n handleError(new Error(t('deviceGrant.errors.start')));\n return;\n }\n\n flowStartAttempted.current = true;\n void startFlow(appId);\n }, [applicationId, handleError, startFlow, t]);\n\n const submit = async (payload: EmbeddedSignInFlowRequest, actionId?: string): Promise<void> => {\n setIsLoading(true);\n setError(null);\n setResult(null);\n try {\n if (!executionId) return;\n\n const response = await executeEmbeddedDeviceGrantFlow({\n baseUrl,\n payload: {\n action: payload.action ?? actionId,\n challengeToken,\n executionId,\n inputs: {\n ...Object.fromEntries(\n Object.entries(payload.inputs ?? {}).filter(\n ([key]: [string, unknown]) => !key.startsWith('__consent_opt__'),\n ),\n ),\n ...(!hasUserCodeInput(components) ? {user_code: undefined} : {}),\n },\n },\n });\n applyResponse(response);\n } catch (flowError) {\n handleError(flowError instanceof Error ? flowError : new Error(t('deviceGrant.errors.continue')));\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleBaseSubmit = (payload: EmbeddedSignInFlowRequest, component: EmbeddedFlowComponent): Promise<void> =>\n submit(payload, component.id);\n\n const fieldErrors = useMemo<Record<string, string>>(() => {\n const errors: Record<string, string> = {};\n (serverFieldErrors ?? []).forEach((fieldError: DeviceGrantFieldError) => {\n if (!(fieldError.identifier in errors)) errors[fieldError.identifier] = fieldError.message;\n });\n\n return errors;\n }, [serverFieldErrors]);\n\n if (children) {\n return (\n <>\n {children({\n additionalData,\n components,\n error,\n fieldErrors,\n initialValues,\n isLoading,\n meta,\n onSubmit: submit,\n result,\n })}\n </>\n );\n }\n\n return (\n <BaseDeviceGrant\n {...baseProps}\n className={className}\n components={components}\n additionalData={additionalData}\n error={error}\n initialValues={initialValues}\n isLoading={isLoading}\n onError={handleError}\n onSubmit={handleBaseSubmit}\n preferences={preferences}\n result={result}\n serverFieldErrors={serverFieldErrors}\n size={size}\n variant={variant}\n />\n );\n};\n\nexport default DeviceGrant;\n"],"mappings":"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"}
|
|
@@ -7,8 +7,8 @@ const require_useTranslation = require('../../../hooks/useTranslation.cjs');
|
|
|
7
7
|
const require_flowTransformer = require('../../../utils/flowTransformer.cjs');
|
|
8
8
|
const require_Spinner = require('../../primitives/Spinner/Spinner.cjs');
|
|
9
9
|
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
10
|
-
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
11
10
|
const require_Card = require('../../primitives/Card/Card.cjs');
|
|
11
|
+
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
12
12
|
const require_AuthOptionFactory = require('../flow/AuthOptionFactory.cjs');
|
|
13
13
|
const require_BaseInviteUser_styles = require('./BaseInviteUser.styles.cjs');
|
|
14
14
|
let __thunderid_browser = require("@thunderid/browser");
|
|
@@ -10,10 +10,10 @@ const require_useTranslation = require('../../../hooks/useTranslation.cjs');
|
|
|
10
10
|
const require_flowTransformer = require('../../../utils/flowTransformer.cjs');
|
|
11
11
|
const require_useForm = require('../../../hooks/useForm.cjs');
|
|
12
12
|
const require_Spinner = require('../../primitives/Spinner/Spinner.cjs');
|
|
13
|
-
const require_composeAffixedInputs = require('../../../utils/composeAffixedInputs.cjs');
|
|
14
13
|
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
15
|
-
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
16
14
|
const require_Card = require('../../primitives/Card/Card.cjs');
|
|
15
|
+
const require_composeAffixedInputs = require('../../../utils/composeAffixedInputs.cjs');
|
|
16
|
+
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
17
17
|
const require_AuthOptionFactory = require('../flow/AuthOptionFactory.cjs');
|
|
18
18
|
const require_BaseSignUp_styles = require('../SignUp/BaseSignUp.styles.cjs');
|
|
19
19
|
const require_getAuthComponentHeadings = require('../../../utils/getAuthComponentHeadings.cjs');
|
|
@@ -10,11 +10,11 @@ const require_useTranslation = require('../../../hooks/useTranslation.cjs');
|
|
|
10
10
|
const require_flowTransformer = require('../../../utils/flowTransformer.cjs');
|
|
11
11
|
const require_useForm = require('../../../hooks/useForm.cjs');
|
|
12
12
|
const require_Spinner = require('../../primitives/Spinner/Spinner.cjs');
|
|
13
|
+
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
14
|
+
const require_Card = require('../../primitives/Card/Card.cjs');
|
|
13
15
|
const require_BaseSignIn_styles = require('./BaseSignIn.styles.cjs');
|
|
14
16
|
const require_composeAffixedInputs = require('../../../utils/composeAffixedInputs.cjs');
|
|
15
|
-
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
16
17
|
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
17
|
-
const require_Card = require('../../primitives/Card/Card.cjs');
|
|
18
18
|
const require_AuthOptionFactory = require('../flow/AuthOptionFactory.cjs');
|
|
19
19
|
let __thunderid_browser = require("@thunderid/browser");
|
|
20
20
|
__thunderid_browser = require_rolldown_runtime.__toESM(__thunderid_browser);
|
|
@@ -27,7 +27,7 @@ react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
|
27
27
|
/**
|
|
28
28
|
* Internal component that consumes FlowContext and renders the sign-in UI.
|
|
29
29
|
*/
|
|
30
|
-
const BaseSignInContent = ({ components = [], onSubmit, onError, error: externalError, id, className = "", inputClassName = "", buttonClassName = "", messageClassName = "", size = "medium", variant = "outlined", isLoading: externalIsLoading, children, additionalData = {}, isTimeoutDisabled = false, serverFieldErrors = null, revalidateOnChangeAfterBlur = false }) => {
|
|
30
|
+
const BaseSignInContent = ({ components = [], onSubmit, onError, error: externalError, id, className = "", inputClassName = "", buttonClassName = "", messageClassName = "", size = "medium", variant = "outlined", isLoading: externalIsLoading, initialValues, children, additionalData = {}, isTimeoutDisabled = false, serverFieldErrors = null, revalidateOnChangeAfterBlur = false }) => {
|
|
31
31
|
const { meta, vendor } = require_useThunderID.default();
|
|
32
32
|
const { theme } = require_useTheme.default();
|
|
33
33
|
const customRenderers = (0, react.useContext)(require_ComponentRendererContext.default);
|
|
@@ -98,7 +98,7 @@ const BaseSignInContent = ({ components = [], onSubmit, onError, error: external
|
|
|
98
98
|
processComponents(flowComponents);
|
|
99
99
|
return fields;
|
|
100
100
|
}, [t]);
|
|
101
|
-
const { values: formValues, touched: touchedFields, errors: formErrors, isValid: isFormValid, setValue: setFormValue, setTouched: setFormTouched, setTouchedFields, setErrors: setFormErrors, clearErrors: clearFormErrors, validateForm, touchAllFields, reset: resetForm, revalidateTouchedFields } = require_useForm.useForm({
|
|
101
|
+
const { values: formValues, touched: touchedFields, errors: formErrors, isValid: isFormValid, setValue: setFormValue, setValues: setFormValues, setTouched: setFormTouched, setTouchedFields, setErrors: setFormErrors, clearErrors: clearFormErrors, validateForm, touchAllFields, reset: resetForm, revalidateTouchedFields } = require_useForm.useForm({
|
|
102
102
|
fields: (0, react.useMemo)(() => components ? extractFormFields(components) : [], [components, extractFormFields]),
|
|
103
103
|
initialValues: {},
|
|
104
104
|
requiredMessage: t("validations.required.field.error"),
|
|
@@ -106,6 +106,17 @@ const BaseSignInContent = ({ components = [], onSubmit, onError, error: external
|
|
|
106
106
|
validateOnBlur: true,
|
|
107
107
|
validateOnChange: false
|
|
108
108
|
});
|
|
109
|
+
const initialValuesKey = (0, react.useMemo)(() => JSON.stringify(Object.entries(initialValues ?? {}).sort(([left], [right]) => left.localeCompare(right))), [initialValues]);
|
|
110
|
+
const appliedInitialValuesKeyRef = (0, react.useRef)(null);
|
|
111
|
+
(0, react.useEffect)(() => {
|
|
112
|
+
if (!initialValues || Object.keys(initialValues).length === 0 || appliedInitialValuesKeyRef.current === initialValuesKey) return;
|
|
113
|
+
appliedInitialValuesKeyRef.current = initialValuesKey;
|
|
114
|
+
setFormValues(initialValues);
|
|
115
|
+
}, [
|
|
116
|
+
initialValues,
|
|
117
|
+
initialValuesKey,
|
|
118
|
+
setFormValues
|
|
119
|
+
]);
|
|
109
120
|
(0, react.useEffect)(() => {
|
|
110
121
|
clearFormErrors();
|
|
111
122
|
if (!serverFieldErrors || serverFieldErrors.length === 0) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseSignIn.cjs","names":["BaseSignInContent: FC<BaseSignInProps>","useThunderID","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","useTranslation","useFlow","styles: any","useStyles","isLoading: boolean","handleError: any","errorMessage: string","extractErrorMessage","extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[]","fields: FormField[]","identifier: string","useForm","errors: Record<string, string>","touched: Record<string, boolean>","composedData: Record<string, any> | undefined","composeAffixedInputs","filteredInputs: Record<string, any>","payload: EmbeddedSignInFlowRequest","containerClasses: any","cx","inputClasses: any","buttonClasses: any","messageClasses: any","renderComponents: any","renderSignInComponents","renderProps: BaseSignInRenderProps","result: any","CardPrimitive","Spinner","AlertPrimitive","Typography","BaseSignIn: FC<BaseSignInProps>","content: ReactElement","FlowProvider","ComponentPreferencesContext"],"sources":["../../../../../src/components/auth/SignIn/BaseSignIn.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n withVendorCSSClassPrefix,\n EmbeddedSignInFlowRequest,\n EmbeddedFlowComponent,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n buildValidatorFromRules,\n} from '@thunderid/browser';\nimport {FC, useEffect, useMemo, useState, useCallback, useContext, ReactElement, ReactNode} from 'react';\nimport useStyles from './BaseSignIn.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport FlowProvider from '../../../contexts/Flow/FlowProvider';\nimport useFlow from '../../../contexts/Flow/useFlow';\nimport ComponentPreferencesContext from '../../../contexts/I18n/ComponentPreferencesContext';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport {FormField, useForm} from '../../../hooks/useForm';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport composeAffixedInputs from '../../../utils/composeAffixedInputs';\nimport {extractErrorMessage} from '../../../utils/flowTransformer';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../primitives/Card/Card';\nimport Spinner from '../../primitives/Spinner/Spinner';\nimport Typography from '../../primitives/Typography/Typography';\nimport {renderSignInComponents} from '../flow/AuthOptionFactory';\n\n/**\n * Render props for custom UI rendering\n */\nexport interface BaseSignInRenderProps {\n /**\n * Additional data from the current flow step (e.g. `source` lookups for `KEY_VALUE_LIST`)\n */\n additionalData: Record<string, unknown>;\n\n /**\n * Flow components\n */\n components: EmbeddedFlowComponent[];\n\n /**\n * API error (if any)\n */\n error?: Error | null;\n\n /**\n * Field validation errors\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Function to handle input changes\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission\n */\n handleSubmit: (component: EmbeddedFlowComponent, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state\n */\n isLoading: boolean;\n\n /**\n * Flag indicating if the step timer has reached zero\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Whether the form is valid\n */\n isValid: boolean;\n\n /**\n * Flow messages\n */\n messages: {message: string; type: string}[];\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Flow subtitle\n */\n subtitle: string;\n\n /**\n * Flow title\n */\n title: string;\n\n /**\n * Touched fields\n */\n touched: Record<string, boolean>;\n\n /**\n * Function to validate the form\n */\n validateForm: () => {fieldErrors: Record<string, string>; isValid: boolean};\n\n /**\n * Form values\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseSignIn component.\n */\nexport interface BaseSignInProps {\n /**\n * Additional data from the flow response.\n */\n additionalData?: Record<string, any>;\n\n /**\n * Custom CSS class name for the submit button.\n */\n buttonClassName?: string;\n\n /**\n * Render props function for custom UI\n */\n children?: (props: BaseSignInRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name for the form container.\n */\n className?: string;\n\n /**\n * Array of flow components to render.\n */\n components?: EmbeddedFlowComponent[];\n\n /**\n * Error object to display\n */\n error?: Error | null;\n\n /**\n * Custom CSS class name for error messages.\n */\n errorClassName?: string;\n\n /**\n * Custom CSS class name for form inputs.\n */\n inputClassName?: string;\n\n /**\n * Flag to determine if the component is ready to be rendered.\n */\n isLoading?: boolean;\n\n /**\n * Timer flag disabling actions\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Custom CSS class name for info messages.\n */\n messageClassName?: string;\n\n /**\n * Callback function called when authentication fails.\n * @param error - The error that occurred during authentication.\n */\n onError?: (error: Error) => void;\n\n /**\n * Function to handle form submission.\n * @param payload - The form data to submit.\n * @param component - The component that triggered the submission.\n */\n onSubmit?: (payload: EmbeddedSignInFlowRequest, component: EmbeddedFlowComponent) => Promise<void>;\n\n /**\n * Callback function called when authentication is successful.\n * @param authData - The authentication data returned upon successful completion.\n */\n onSuccess?: (authData: Record<string, any>) => void;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * HTML id attribute for the form container.\n */\n id?: string;\n\n /**\n * Field-level validation errors returned by the server in `data.fieldErrors` on the\n * most recent flow response. The component collapses these into the form's\n * `fieldErrors` state (first error per field wins), surfacing them through the same\n * render-prop / UI path as client-side validation errors. The full array is preserved\n * here for advanced consumers that want every failing rule per field.\n */\n serverFieldErrors?: FieldError[] | null;\n\n /**\n * When a field has been blurred at least once, re-run validation on every subsequent\n * keystroke so a rendered error clears the moment the value becomes valid. Doesn't\n * affect fields that have never been blurred — the user isn't shown errors while\n * initially typing. Default `false` preserves prior behavior.\n */\n revalidateOnChangeAfterBlur?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Internal component that consumes FlowContext and renders the sign-in UI.\n */\nconst BaseSignInContent: FC<BaseSignInProps> = ({\n components = [],\n onSubmit,\n onError,\n error: externalError,\n id,\n className = '',\n inputClassName = '',\n buttonClassName = '',\n messageClassName = '',\n size = 'medium',\n variant = 'outlined',\n isLoading: externalIsLoading,\n children,\n additionalData = {},\n isTimeoutDisabled = false,\n serverFieldErrors = null,\n revalidateOnChangeAfterBlur = false,\n}: BaseSignInProps): ReactElement => {\n const {meta, vendor} = useThunderID();\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const {t, currentLanguage} = useTranslation();\n const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [apiError, setApiError] = useState<Error | null>(null);\n\n const isLoading: boolean = externalIsLoading || isSubmitting;\n\n /**\n * Component type for which forms validation will be applicable\n */\n const acceptableType = [\n 'TEXT_INPUT',\n 'PASSWORD_INPUT',\n 'EMAIL_INPUT',\n 'PHONE_INPUT',\n 'OTP_INPUT',\n 'SELECT',\n 'DATE_INPUT',\n 'CUSTOM',\n ];\n\n /**\n * Handle error responses and extract meaningful error messages\n * Uses the transformer's extractErrorMessage function for consistency\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t);\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Clear existing messages and add the error message\n clearMessages();\n addMessage({\n message: errorMessage,\n type: 'error',\n });\n },\n [t, addMessage, clearMessages],\n );\n\n /**\n * Extract form fields from flow components\n */\n const extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[] = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): FormField[] => {\n const fields: FormField[] = [];\n\n const processComponents = (comps: EmbeddedFlowComponent[]): any => {\n comps.forEach((component: any) => {\n if (acceptableType.includes(component.type)) {\n const identifier: string = component.ref;\n const ruleValidator = buildValidatorFromRules(component.validation);\n fields.push({\n initialValue: '',\n name: identifier,\n required: component.required || false,\n validator: (value: string) => {\n if (component.required && (!value || value.trim() === '')) {\n return t('validations.required.field.error');\n }\n // Run declarative rules from meta.components[].validation.\n if (ruleValidator && value) {\n const ruleMessage = ruleValidator(value);\n if (ruleMessage) {\n return t(ruleMessage);\n }\n }\n // Add email validation if it's an email field\n if (\n (component.type === 'EMAIL_INPUT' || component.variant === 'EMAIL') &&\n value &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n ) {\n return t('field.email.invalid');\n }\n\n return null;\n },\n });\n }\n if (component.components) {\n processComponents(component.components);\n }\n });\n };\n\n processComponents(flowComponents);\n return fields;\n },\n [t],\n );\n\n const formFields: FormField[] = useMemo(\n () => (components ? extractFormFields(components) : []),\n [components, extractFormFields],\n );\n\n const form: ReturnType<typeof useForm> = useForm<Record<string, string>>({\n fields: formFields,\n initialValues: {},\n requiredMessage: t('validations.required.field.error'),\n revalidateOnChangeAfterBlur,\n validateOnBlur: true,\n validateOnChange: false,\n });\n\n const {\n values: formValues,\n touched: touchedFields,\n errors: formErrors,\n isValid: isFormValid,\n setValue: setFormValue,\n setTouched: setFormTouched,\n setTouchedFields,\n setErrors: setFormErrors,\n clearErrors: clearFormErrors,\n validateForm,\n touchAllFields,\n reset: resetForm,\n revalidateTouchedFields,\n } = form;\n\n // Project server-side fieldErrors into form state. `setTouchedFields` is used instead\n // of `setTouched` so client-side `validateField` doesn't wipe server errors when the\n // client rules happen to pass.\n useEffect(() => {\n clearFormErrors();\n if (!serverFieldErrors || serverFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of serverFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setTouchedFields(touched);\n setFormErrors(errors);\n }, [serverFieldErrors, setFormErrors, setTouchedFields, clearFormErrors]);\n\n // Re-translate displayed validation errors when the UI language changes.\n // revalidateTouchedFields is stable, so this effect fires only on language change.\n useEffect(() => {\n revalidateTouchedFields();\n }, [currentLanguage, revalidateTouchedFields]);\n\n /**\n * Handle input value changes.\n * Only updates the value without marking as touched.\n * Touched state is set on blur to avoid premature validation.\n */\n const handleInputChange = (name: string, value: string): void => {\n setFormValue(name, value);\n };\n\n /**\n * Handle input blur event.\n * Marks the field as touched, which triggers validation.\n */\n const handleInputBlur = (name: string): void => {\n setFormTouched(name, true);\n };\n\n /**\n * Handle component submission (for buttons and actions).\n */\n const handleSubmit = async (\n component: EmbeddedFlowComponent,\n data?: Record<string, any>,\n skipValidation?: boolean,\n ): Promise<void> => {\n // Only validate for form submit actions, skip for social/trigger actions\n if (!skipValidation) {\n // Mark all fields as touched before validation\n touchAllFields();\n\n const validation: ReturnType<typeof validateForm> = validateForm();\n\n if (!validation.isValid) {\n return;\n }\n }\n\n setIsSubmitting(true);\n setApiError(null);\n clearMessages();\n\n try {\n const composedData: Record<string, any> | undefined = data\n ? composeAffixedInputs(data as Record<string, string>, vendor)\n : undefined;\n\n // Filter out empty or undefined input values\n const filteredInputs: Record<string, any> = {};\n if (composedData) {\n Object.keys(composedData).forEach((key: any) => {\n if (composedData[key] !== undefined && composedData[key] !== null && composedData[key] !== '') {\n filteredInputs[key] = composedData[key];\n }\n });\n }\n\n let payload: EmbeddedSignInFlowRequest = {};\n\n // For V2, we always send inputs and action\n payload = {\n ...payload,\n ...(component.id && {action: component.id}),\n inputs: filteredInputs,\n };\n\n await onSubmit?.(payload, component);\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n // Generate CSS classes\n const containerClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin'),\n withVendorCSSClassPrefix(`signin--${size}`),\n withVendorCSSClassPrefix(`signin--${variant}`),\n ],\n className,\n );\n\n const inputClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__input'),\n size === 'small' && withVendorCSSClassPrefix('signin__input--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__input--large'),\n ],\n inputClassName,\n );\n\n const buttonClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__button'),\n size === 'small' && withVendorCSSClassPrefix('signin__button--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__button--large'),\n ],\n buttonClassName,\n );\n\n const messageClasses: any = cx([withVendorCSSClassPrefix('signin__messages')], messageClassName);\n\n /**\n * Render components based on flow data using the factory\n */\n const renderComponents: any = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): ReactElement[] =>\n renderSignInComponents(\n flowComponents,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData,\n buttonClassName: buttonClasses,\n inputClassName: inputClasses,\n isTimeoutDisabled,\n meta,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n vendor,\n },\n ),\n [\n additionalData,\n customRenderers,\n formValues,\n touchedFields,\n formErrors,\n isFormValid,\n meta,\n t,\n theme,\n isLoading,\n size,\n variant,\n vendor,\n inputClasses,\n buttonClasses,\n handleInputBlur,\n handleSubmit,\n isTimeoutDisabled,\n ],\n );\n\n // If render props are provided, use them\n if (children) {\n const renderProps: BaseSignInRenderProps = {\n additionalData,\n components,\n error: apiError,\n fieldErrors: formErrors,\n handleInputChange,\n handleSubmit,\n isLoading,\n isTimeoutDisabled,\n isValid: isFormValid,\n messages: flowMessages || [],\n meta,\n subtitle: flowSubtitle ?? '',\n title: flowTitle || t('signin.heading'),\n touched: touchedFields,\n validateForm: () => {\n const result: any = validateForm();\n return {fieldErrors: result.errors, isValid: result.isValid};\n },\n values: formValues,\n };\n\n return (\n <div id={id} className={containerClasses} data-testid=\"thunderid-signin\">\n {children(renderProps)}\n </div>\n );\n }\n\n // Default UI rendering\n if (isLoading) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n if (!components || components.length === 0) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">{t('errors.signin.components.not.available')}</Typography>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n {externalError && (\n <div className={styles.flowMessagesContainer}>\n <AlertPrimitive variant=\"error\" className={cx(styles.flowMessageItem, messageClasses)}>\n <AlertPrimitive.Description>{externalError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n {flowMessages && flowMessages.length > 0 && (\n <div className={styles.flowMessagesContainer}>\n {flowMessages.map((message: any, index: any) => (\n <AlertPrimitive\n key={index}\n variant={message.type === 'error' ? 'error' : 'info'}\n className={cx(styles.flowMessageItem, messageClasses)}\n >\n <AlertPrimitive.Description>{message.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n ))}\n </div>\n )}\n <div className={styles.contentContainer}>{renderComponents(components)}</div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\n/**\n * Base SignIn component that provides generic authentication flow.\n * This component handles component-driven UI rendering and can transform input\n * structure to component-driven format automatically.\n *\n * @example\n * // Default UI\n * ```tsx\n * import { BaseSignIn } from '@thunderid/react';\n *\n * const MySignIn = () => {\n * return (\n * <BaseSignIn\n * components={components}\n * onSubmit={async (payload) => {\n * return await handleAuth(payload);\n * }}\n * onSuccess={(authData) => {\n * console.log('Success:', authData);\n * }}\n * className=\"max-w-md mx-auto\"\n * />\n * );\n * };\n * ```\n *\n * @example\n * // Custom UI with render props\n * ```tsx\n * <BaseSignIn components={components} onSubmit={handleSubmit}>\n * {({values, errors, handleInputChange, handleSubmit, isLoading, components}) => (\n * <div className=\"custom-form\">\n * <input\n * name=\"username\"\n * value={values.username || ''}\n * onChange={(e) => handleInputChange('username', e.target.value)}\n * />\n * {errors.username && <span>{errors.username}</span>}\n * <button\n * onClick={() => handleSubmit(components[0], values)}\n * disabled={isLoading}\n * >\n * Sign In\n * </button>\n * </div>\n * )}\n * </BaseSignIn>\n * ```\n */\nconst BaseSignIn: FC<BaseSignInProps> = ({preferences, ...rest}: BaseSignInProps): ReactElement => {\n const content: ReactElement = (\n <FlowProvider>\n <BaseSignInContent {...rest} />\n </FlowProvider>\n );\n\n if (!preferences) return content;\n\n return <ComponentPreferencesContext.Provider value={preferences}>{content}</ComponentPreferencesContext.Provider>;\n};\n\nexport default BaseSignIn;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BaseSignIn.cjs","names":["BaseSignInContent: FC<BaseSignInProps>","useThunderID","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","useTranslation","useFlow","styles: any","useStyles","isLoading: boolean","handleError: any","errorMessage: string","extractErrorMessage","extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[]","fields: FormField[]","identifier: string","useForm","initialValuesKey: string","errors: Record<string, string>","touched: Record<string, boolean>","composedData: Record<string, any> | undefined","composeAffixedInputs","filteredInputs: Record<string, any>","payload: EmbeddedSignInFlowRequest","containerClasses: any","cx","inputClasses: any","buttonClasses: any","messageClasses: any","renderComponents: any","renderSignInComponents","renderProps: BaseSignInRenderProps","result: any","CardPrimitive","Spinner","AlertPrimitive","Typography","BaseSignIn: FC<BaseSignInProps>","content: ReactElement","FlowProvider","ComponentPreferencesContext"],"sources":["../../../../../src/components/auth/SignIn/BaseSignIn.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n withVendorCSSClassPrefix,\n EmbeddedSignInFlowRequest,\n EmbeddedFlowComponent,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n buildValidatorFromRules,\n} from '@thunderid/browser';\nimport {FC, useEffect, useMemo, useRef, useState, useCallback, useContext, ReactElement, ReactNode} from 'react';\nimport useStyles from './BaseSignIn.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport FlowProvider from '../../../contexts/Flow/FlowProvider';\nimport useFlow from '../../../contexts/Flow/useFlow';\nimport ComponentPreferencesContext from '../../../contexts/I18n/ComponentPreferencesContext';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport {FormField, useForm} from '../../../hooks/useForm';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport composeAffixedInputs from '../../../utils/composeAffixedInputs';\nimport {extractErrorMessage} from '../../../utils/flowTransformer';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../primitives/Card/Card';\nimport Spinner from '../../primitives/Spinner/Spinner';\nimport Typography from '../../primitives/Typography/Typography';\nimport {renderSignInComponents} from '../flow/AuthOptionFactory';\n\n/**\n * Render props for custom UI rendering\n */\nexport interface BaseSignInRenderProps {\n /**\n * Additional data from the current flow step (e.g. `source` lookups for `KEY_VALUE_LIST`)\n */\n additionalData: Record<string, unknown>;\n\n /**\n * Flow components\n */\n components: EmbeddedFlowComponent[];\n\n /**\n * API error (if any)\n */\n error?: Error | null;\n\n /**\n * Field validation errors\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Function to handle input changes\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission\n */\n handleSubmit: (component: EmbeddedFlowComponent, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state\n */\n isLoading: boolean;\n\n /**\n * Flag indicating if the step timer has reached zero\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Whether the form is valid\n */\n isValid: boolean;\n\n /**\n * Flow messages\n */\n messages: {message: string; type: string}[];\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Flow subtitle\n */\n subtitle: string;\n\n /**\n * Flow title\n */\n title: string;\n\n /**\n * Touched fields\n */\n touched: Record<string, boolean>;\n\n /**\n * Function to validate the form\n */\n validateForm: () => {fieldErrors: Record<string, string>; isValid: boolean};\n\n /**\n * Form values\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseSignIn component.\n */\nexport interface BaseSignInProps {\n /**\n * Additional data from the flow response.\n */\n additionalData?: Record<string, any>;\n\n /**\n * Custom CSS class name for the submit button.\n */\n buttonClassName?: string;\n\n /**\n * Render props function for custom UI\n */\n children?: (props: BaseSignInRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name for the form container.\n */\n className?: string;\n\n /**\n * Array of flow components to render.\n */\n components?: EmbeddedFlowComponent[];\n\n /**\n * Error object to display\n */\n error?: Error | null;\n\n /**\n * Custom CSS class name for error messages.\n */\n errorClassName?: string;\n\n /**\n * Custom CSS class name for form inputs.\n */\n inputClassName?: string;\n\n /**\n * Flag to determine if the component is ready to be rendered.\n */\n isLoading?: boolean;\n\n /**\n * Values to seed form fields with, such as a value supplied by a verification URI.\n */\n initialValues?: Record<string, string>;\n\n /**\n * Timer flag disabling actions\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Custom CSS class name for info messages.\n */\n messageClassName?: string;\n\n /**\n * Callback function called when authentication fails.\n * @param error - The error that occurred during authentication.\n */\n onError?: (error: Error) => void;\n\n /**\n * Function to handle form submission.\n * @param payload - The form data to submit.\n * @param component - The component that triggered the submission.\n */\n onSubmit?: (payload: EmbeddedSignInFlowRequest, component: EmbeddedFlowComponent) => Promise<void>;\n\n /**\n * Callback function called when authentication is successful.\n * @param authData - The authentication data returned upon successful completion.\n */\n onSuccess?: (authData: Record<string, any>) => void;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * HTML id attribute for the form container.\n */\n id?: string;\n\n /**\n * Field-level validation errors returned by the server in `data.fieldErrors` on the\n * most recent flow response. The component collapses these into the form's\n * `fieldErrors` state (first error per field wins), surfacing them through the same\n * render-prop / UI path as client-side validation errors. The full array is preserved\n * here for advanced consumers that want every failing rule per field.\n */\n serverFieldErrors?: FieldError[] | null;\n\n /**\n * When a field has been blurred at least once, re-run validation on every subsequent\n * keystroke so a rendered error clears the moment the value becomes valid. Doesn't\n * affect fields that have never been blurred — the user isn't shown errors while\n * initially typing. Default `false` preserves prior behavior.\n */\n revalidateOnChangeAfterBlur?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Internal component that consumes FlowContext and renders the sign-in UI.\n */\nconst BaseSignInContent: FC<BaseSignInProps> = ({\n components = [],\n onSubmit,\n onError,\n error: externalError,\n id,\n className = '',\n inputClassName = '',\n buttonClassName = '',\n messageClassName = '',\n size = 'medium',\n variant = 'outlined',\n isLoading: externalIsLoading,\n initialValues,\n children,\n additionalData = {},\n isTimeoutDisabled = false,\n serverFieldErrors = null,\n revalidateOnChangeAfterBlur = false,\n}: BaseSignInProps): ReactElement => {\n const {meta, vendor} = useThunderID();\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const {t, currentLanguage} = useTranslation();\n const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [apiError, setApiError] = useState<Error | null>(null);\n\n const isLoading: boolean = externalIsLoading || isSubmitting;\n\n /**\n * Component type for which forms validation will be applicable\n */\n const acceptableType = [\n 'TEXT_INPUT',\n 'PASSWORD_INPUT',\n 'EMAIL_INPUT',\n 'PHONE_INPUT',\n 'OTP_INPUT',\n 'SELECT',\n 'DATE_INPUT',\n 'CUSTOM',\n ];\n\n /**\n * Handle error responses and extract meaningful error messages\n * Uses the transformer's extractErrorMessage function for consistency\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t);\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Clear existing messages and add the error message\n clearMessages();\n addMessage({\n message: errorMessage,\n type: 'error',\n });\n },\n [t, addMessage, clearMessages],\n );\n\n /**\n * Extract form fields from flow components\n */\n const extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[] = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): FormField[] => {\n const fields: FormField[] = [];\n\n const processComponents = (comps: EmbeddedFlowComponent[]): any => {\n comps.forEach((component: any) => {\n if (acceptableType.includes(component.type)) {\n const identifier: string = component.ref;\n const ruleValidator = buildValidatorFromRules(component.validation);\n fields.push({\n initialValue: '',\n name: identifier,\n required: component.required || false,\n validator: (value: string) => {\n if (component.required && (!value || value.trim() === '')) {\n return t('validations.required.field.error');\n }\n // Run declarative rules from meta.components[].validation.\n if (ruleValidator && value) {\n const ruleMessage = ruleValidator(value);\n if (ruleMessage) {\n return t(ruleMessage);\n }\n }\n // Add email validation if it's an email field\n if (\n (component.type === 'EMAIL_INPUT' || component.variant === 'EMAIL') &&\n value &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n ) {\n return t('field.email.invalid');\n }\n\n return null;\n },\n });\n }\n if (component.components) {\n processComponents(component.components);\n }\n });\n };\n\n processComponents(flowComponents);\n return fields;\n },\n [t],\n );\n\n const formFields: FormField[] = useMemo(\n () => (components ? extractFormFields(components) : []),\n [components, extractFormFields],\n );\n\n const form: ReturnType<typeof useForm> = useForm<Record<string, string>>({\n fields: formFields,\n initialValues: {},\n requiredMessage: t('validations.required.field.error'),\n revalidateOnChangeAfterBlur,\n validateOnBlur: true,\n validateOnChange: false,\n });\n\n const {\n values: formValues,\n touched: touchedFields,\n errors: formErrors,\n isValid: isFormValid,\n setValue: setFormValue,\n setValues: setFormValues,\n setTouched: setFormTouched,\n setTouchedFields,\n setErrors: setFormErrors,\n clearErrors: clearFormErrors,\n validateForm,\n touchAllFields,\n reset: resetForm,\n revalidateTouchedFields,\n } = form;\n\n const initialValuesKey: string = useMemo(\n () => JSON.stringify(Object.entries(initialValues ?? {}).sort(([left], [right]) => left.localeCompare(right))),\n [initialValues],\n );\n const appliedInitialValuesKeyRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (\n !initialValues ||\n Object.keys(initialValues).length === 0 ||\n appliedInitialValuesKeyRef.current === initialValuesKey\n ) {\n return;\n }\n\n appliedInitialValuesKeyRef.current = initialValuesKey;\n setFormValues(initialValues);\n }, [initialValues, initialValuesKey, setFormValues]);\n\n // Project server-side fieldErrors into form state. `setTouchedFields` is used instead\n // of `setTouched` so client-side `validateField` doesn't wipe server errors when the\n // client rules happen to pass.\n useEffect(() => {\n clearFormErrors();\n if (!serverFieldErrors || serverFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of serverFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setTouchedFields(touched);\n setFormErrors(errors);\n }, [serverFieldErrors, setFormErrors, setTouchedFields, clearFormErrors]);\n\n // Re-translate displayed validation errors when the UI language changes.\n // revalidateTouchedFields is stable, so this effect fires only on language change.\n useEffect(() => {\n revalidateTouchedFields();\n }, [currentLanguage, revalidateTouchedFields]);\n\n /**\n * Handle input value changes.\n * Only updates the value without marking as touched.\n * Touched state is set on blur to avoid premature validation.\n */\n const handleInputChange = (name: string, value: string): void => {\n setFormValue(name, value);\n };\n\n /**\n * Handle input blur event.\n * Marks the field as touched, which triggers validation.\n */\n const handleInputBlur = (name: string): void => {\n setFormTouched(name, true);\n };\n\n /**\n * Handle component submission (for buttons and actions).\n */\n const handleSubmit = async (\n component: EmbeddedFlowComponent,\n data?: Record<string, any>,\n skipValidation?: boolean,\n ): Promise<void> => {\n // Only validate for form submit actions, skip for social/trigger actions\n if (!skipValidation) {\n // Mark all fields as touched before validation\n touchAllFields();\n\n const validation: ReturnType<typeof validateForm> = validateForm();\n\n if (!validation.isValid) {\n return;\n }\n }\n\n setIsSubmitting(true);\n setApiError(null);\n clearMessages();\n\n try {\n const composedData: Record<string, any> | undefined = data\n ? composeAffixedInputs(data as Record<string, string>, vendor)\n : undefined;\n\n // Filter out empty or undefined input values\n const filteredInputs: Record<string, any> = {};\n if (composedData) {\n Object.keys(composedData).forEach((key: any) => {\n if (composedData[key] !== undefined && composedData[key] !== null && composedData[key] !== '') {\n filteredInputs[key] = composedData[key];\n }\n });\n }\n\n let payload: EmbeddedSignInFlowRequest = {};\n\n // For V2, we always send inputs and action\n payload = {\n ...payload,\n ...(component.id && {action: component.id}),\n inputs: filteredInputs,\n };\n\n await onSubmit?.(payload, component);\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n // Generate CSS classes\n const containerClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin'),\n withVendorCSSClassPrefix(`signin--${size}`),\n withVendorCSSClassPrefix(`signin--${variant}`),\n ],\n className,\n );\n\n const inputClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__input'),\n size === 'small' && withVendorCSSClassPrefix('signin__input--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__input--large'),\n ],\n inputClassName,\n );\n\n const buttonClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__button'),\n size === 'small' && withVendorCSSClassPrefix('signin__button--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__button--large'),\n ],\n buttonClassName,\n );\n\n const messageClasses: any = cx([withVendorCSSClassPrefix('signin__messages')], messageClassName);\n\n /**\n * Render components based on flow data using the factory\n */\n const renderComponents: any = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): ReactElement[] =>\n renderSignInComponents(\n flowComponents,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData,\n buttonClassName: buttonClasses,\n inputClassName: inputClasses,\n isTimeoutDisabled,\n meta,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n vendor,\n },\n ),\n [\n additionalData,\n customRenderers,\n formValues,\n touchedFields,\n formErrors,\n isFormValid,\n meta,\n t,\n theme,\n isLoading,\n size,\n variant,\n vendor,\n inputClasses,\n buttonClasses,\n handleInputBlur,\n handleSubmit,\n isTimeoutDisabled,\n ],\n );\n\n // If render props are provided, use them\n if (children) {\n const renderProps: BaseSignInRenderProps = {\n additionalData,\n components,\n error: apiError,\n fieldErrors: formErrors,\n handleInputChange,\n handleSubmit,\n isLoading,\n isTimeoutDisabled,\n isValid: isFormValid,\n messages: flowMessages || [],\n meta,\n subtitle: flowSubtitle ?? '',\n title: flowTitle || t('signin.heading'),\n touched: touchedFields,\n validateForm: () => {\n const result: any = validateForm();\n return {fieldErrors: result.errors, isValid: result.isValid};\n },\n values: formValues,\n };\n\n return (\n <div id={id} className={containerClasses} data-testid=\"thunderid-signin\">\n {children(renderProps)}\n </div>\n );\n }\n\n // Default UI rendering\n if (isLoading) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n if (!components || components.length === 0) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">{t('errors.signin.components.not.available')}</Typography>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n {externalError && (\n <div className={styles.flowMessagesContainer}>\n <AlertPrimitive variant=\"error\" className={cx(styles.flowMessageItem, messageClasses)}>\n <AlertPrimitive.Description>{externalError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n {flowMessages && flowMessages.length > 0 && (\n <div className={styles.flowMessagesContainer}>\n {flowMessages.map((message: any, index: any) => (\n <AlertPrimitive\n key={index}\n variant={message.type === 'error' ? 'error' : 'info'}\n className={cx(styles.flowMessageItem, messageClasses)}\n >\n <AlertPrimitive.Description>{message.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n ))}\n </div>\n )}\n <div className={styles.contentContainer}>{renderComponents(components)}</div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\n/**\n * Base SignIn component that provides generic authentication flow.\n * This component handles component-driven UI rendering and can transform input\n * structure to component-driven format automatically.\n *\n * @example\n * // Default UI\n * ```tsx\n * import { BaseSignIn } from '@thunderid/react';\n *\n * const MySignIn = () => {\n * return (\n * <BaseSignIn\n * components={components}\n * onSubmit={async (payload) => {\n * return await handleAuth(payload);\n * }}\n * onSuccess={(authData) => {\n * console.log('Success:', authData);\n * }}\n * className=\"max-w-md mx-auto\"\n * />\n * );\n * };\n * ```\n *\n * @example\n * // Custom UI with render props\n * ```tsx\n * <BaseSignIn components={components} onSubmit={handleSubmit}>\n * {({values, errors, handleInputChange, handleSubmit, isLoading, components}) => (\n * <div className=\"custom-form\">\n * <input\n * name=\"username\"\n * value={values.username || ''}\n * onChange={(e) => handleInputChange('username', e.target.value)}\n * />\n * {errors.username && <span>{errors.username}</span>}\n * <button\n * onClick={() => handleSubmit(components[0], values)}\n * disabled={isLoading}\n * >\n * Sign In\n * </button>\n * </div>\n * )}\n * </BaseSignIn>\n * ```\n */\nconst BaseSignIn: FC<BaseSignInProps> = ({preferences, ...rest}: BaseSignInProps): ReactElement => {\n const content: ReactElement = (\n <FlowProvider>\n <BaseSignInContent {...rest} />\n </FlowProvider>\n );\n\n if (!preferences) return content;\n\n return <ComponentPreferencesContext.Provider value={preferences}>{content}</ComponentPreferencesContext.Provider>;\n};\n\nexport default BaseSignIn;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqPA,MAAMA,qBAA0C,EAC9C,aAAa,EAAE,EACf,UACA,SACA,OAAO,eACP,IACA,YAAY,IACZ,iBAAiB,IACjB,kBAAkB,IAClB,mBAAmB,IACnB,OAAO,UACP,UAAU,YACV,WAAW,mBACX,eACA,UACA,iBAAiB,EAAE,EACnB,oBAAoB,OACpB,oBAAoB,MACpB,8BAA8B,YACK;CACnC,MAAM,EAAC,MAAM,WAAUC,8BAAc;CACrC,MAAM,EAAC,UAASC,0BAAU;CAC1B,MAAMC,wCAAmDC,yCAAyB;CAClF,MAAM,EAAC,GAAG,oBAAmBC,gCAAgB;CAC7C,MAAM,EAAC,UAAU,cAAc,OAAO,WAAW,UAAU,cAAc,YAAY,kBAAiBC,yBAAS;CAC/G,MAAMC,SAAcC,kCAAU,OAAO,MAAM,KAAK,OAAO,KAAK,QAAQ;CAEpE,MAAM,CAAC,cAAc,uCAA4B,MAAM;CACvD,MAAM,CAAC,UAAU,mCAAsC,KAAK;CAE5D,MAAMC,YAAqB,qBAAqB;;;;CAKhD,MAAM,iBAAiB;EACrB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;;;;CAMD,MAAMC,sCACH,UAAe;EACd,MAAMC,eAAuBC,4CAAoB,OAAO,EAAE;AAG1D,cAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,aAAa,CAAC;AAGrE,iBAAe;AACf,aAAW;GACT,SAAS;GACT,MAAM;GACP,CAAC;IAEJ;EAAC;EAAG;EAAY;EAAc,CAC/B;;;;CAKD,MAAMC,4CACH,mBAAyD;EACxD,MAAMC,SAAsB,EAAE;EAE9B,MAAM,qBAAqB,UAAwC;AACjE,SAAM,SAAS,cAAmB;AAChC,QAAI,eAAe,SAAS,UAAU,KAAK,EAAE;KAC3C,MAAMC,aAAqB,UAAU;KACrC,MAAM,iEAAwC,UAAU,WAAW;AACnE,YAAO,KAAK;MACV,cAAc;MACd,MAAM;MACN,UAAU,UAAU,YAAY;MAChC,YAAY,UAAkB;AAC5B,WAAI,UAAU,aAAa,CAAC,SAAS,MAAM,MAAM,KAAK,IACpD,QAAO,EAAE,mCAAmC;AAG9C,WAAI,iBAAiB,OAAO;QAC1B,MAAM,cAAc,cAAc,MAAM;AACxC,YAAI,YACF,QAAO,EAAE,YAAY;;AAIzB,YACG,UAAU,SAAS,iBAAiB,UAAU,YAAY,YAC3D,SACA,CAAC,6BAA6B,KAAK,MAAM,CAEzC,QAAO,EAAE,sBAAsB;AAGjC,cAAO;;MAEV,CAAC;;AAEJ,QAAI,UAAU,WACZ,mBAAkB,UAAU,WAAW;KAEzC;;AAGJ,oBAAkB,eAAe;AACjC,SAAO;IAET,CAAC,EAAE,CACJ;CAgBD,MAAM,EACJ,QAAQ,YACR,SAAS,eACT,QAAQ,YACR,SAAS,aACT,UAAU,cACV,WAAW,eACX,YAAY,gBACZ,kBACA,WAAW,eACX,aAAa,iBACb,cACA,gBACA,OAAO,WACP,4BAvBuCC,wBAAgC;EACvE,iCALO,aAAa,kBAAkB,WAAW,GAAG,EAAE,EACtD,CAAC,YAAY,kBAAkB,CAChC;EAIC,eAAe,EAAE;EACjB,iBAAiB,EAAE,mCAAmC;EACtD;EACA,gBAAgB;EAChB,kBAAkB;EACnB,CAAC;CAmBF,MAAMC,4CACE,KAAK,UAAU,OAAO,QAAQ,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,KAAK,cAAc,MAAM,CAAC,CAAC,EAC9G,CAAC,cAAc,CAChB;CACD,MAAM,+CAAmD,KAAK;AAE9D,4BAAgB;AACd,MACE,CAAC,iBACD,OAAO,KAAK,cAAc,CAAC,WAAW,KACtC,2BAA2B,YAAY,iBAEvC;AAGF,6BAA2B,UAAU;AACrC,gBAAc,cAAc;IAC3B;EAAC;EAAe;EAAkB;EAAc,CAAC;AAKpD,4BAAgB;AACd,mBAAiB;AACjB,MAAI,CAAC,qBAAqB,kBAAkB,WAAW,EACrD;EAEF,MAAMC,SAAiC,EAAE;EACzC,MAAMC,UAAmC,EAAE;AAC3C,OAAK,MAAM,MAAM,kBACf,KAAI,EAAE,GAAG,cAAc,SAAS;AAC9B,UAAO,GAAG,cAAc,GAAG;AAC3B,WAAQ,GAAG,cAAc;;AAG7B,mBAAiB,QAAQ;AACzB,gBAAc,OAAO;IACpB;EAAC;EAAmB;EAAe;EAAkB;EAAgB,CAAC;AAIzE,4BAAgB;AACd,2BAAyB;IACxB,CAAC,iBAAiB,wBAAwB,CAAC;;;;;;CAO9C,MAAM,qBAAqB,MAAc,UAAwB;AAC/D,eAAa,MAAM,MAAM;;;;;;CAO3B,MAAM,mBAAmB,SAAuB;AAC9C,iBAAe,MAAM,KAAK;;;;;CAM5B,MAAM,eAAe,OACnB,WACA,MACA,mBACkB;AAElB,MAAI,CAAC,gBAAgB;AAEnB,mBAAgB;AAIhB,OAAI,CAFgD,cAAc,CAElD,QACd;;AAIJ,kBAAgB,KAAK;AACrB,cAAY,KAAK;AACjB,iBAAe;AAEf,MAAI;GACF,MAAMC,eAAgD,OAClDC,qCAAqB,MAAgC,OAAO,GAC5D;GAGJ,MAAMC,iBAAsC,EAAE;AAC9C,OAAI,aACF,QAAO,KAAK,aAAa,CAAC,SAAS,QAAa;AAC9C,QAAI,aAAa,SAAS,UAAa,aAAa,SAAS,QAAQ,aAAa,SAAS,GACzF,gBAAe,OAAO,aAAa;KAErC;GAGJ,IAAIC,UAAqC,EAAE;AAG3C,aAAU;IACR,GAAG;IACH,GAAI,UAAU,MAAM,EAAC,QAAQ,UAAU,IAAG;IAC1C,QAAQ;IACT;AAED,SAAM,WAAW,SAAS,UAAU;WAC7B,KAAK;AACZ,eAAY,IAAI;AAChB,aAAU,IAAa;YACf;AACR,mBAAgB,MAAM;;;CAK1B,MAAMC,mBAAwBC,mBAC5B;oDAC2B,SAAS;oDACT,WAAW,OAAO;oDAClB,WAAW,UAAU;EAC/C,EACD,UACD;CAED,MAAMC,eAAoBD,mBACxB;oDAC2B,gBAAgB;EACzC,SAAS,6DAAoC,uBAAuB;EACpE,SAAS,6DAAoC,uBAAuB;EACrE,EACD,eACD;CAED,MAAME,gBAAqBF,mBACzB;oDAC2B,iBAAiB;EAC1C,SAAS,6DAAoC,wBAAwB;EACrE,SAAS,6DAAoC,wBAAwB;EACtE,EACD,gBACD;CAED,MAAMG,iBAAsBH,mBAAG,mDAA0B,mBAAmB,CAAC,EAAE,iBAAiB;;;;CAKhG,MAAMI,2CACH,mBACCC,iDACE,gBACA,YACA,eACA,YACA,WACA,aACA,WACA,mBACA;EACE,kBAAkB;EAClB,QAAQ;EACR;EACA,iBAAiB;EACjB,gBAAgB;EAChB;EACA;EACA,aAAa;EACb,UAAU;EACV;EACA;EACA;EACA;EACD,CACF,EACH;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAGD,KAAI,UAAU;EACZ,MAAMC,cAAqC;GACzC;GACA;GACA,OAAO;GACP,aAAa;GACb;GACA;GACA;GACA;GACA,SAAS;GACT,UAAU,gBAAgB,EAAE;GAC5B;GACA,UAAU,gBAAgB;GAC1B,OAAO,aAAa,EAAE,iBAAiB;GACvC,SAAS;GACT,oBAAoB;IAClB,MAAMC,SAAc,cAAc;AAClC,WAAO;KAAC,aAAa,OAAO;KAAQ,SAAS,OAAO;KAAQ;;GAE9D,QAAQ;GACT;AAED,SACE,2CAAC;GAAQ;GAAI,WAAW;GAAkB,eAAY;aACnD,SAAS,YAAY;IAClB;;AAKV,KAAI,UACF,QACE,2CAACC;EACK;EACJ,WAAWR,mBAAG,kBAAkB,OAAO,KAAK;EAC5C,eAAY;EACH;YAET,2CAACQ,qBAAc,qBACb,2CAAC;GAAI,WAAY,OAAkC;aACjD,2CAACC,4BAAU;IACP,GACgB;GACV;AAIpB,KAAI,CAAC,cAAc,WAAW,WAAW,EACvC,QACE,2CAACD;EACK;EACJ,WAAWR,mBAAG,kBAAkB,OAAO,KAAK;EAC5C,eAAY;EACH;YAET,2CAACQ,qBAAc,qBACb,2CAACE;GAAe,SAAQ;aACtB,2CAACC;IAAW,SAAQ;cAAS,EAAE,yCAAyC;KAAc;IACvE,GACK;GACV;AAIpB,QACE,2CAACH;EACK;EACJ,WAAWR,mBAAG,kBAAkB,OAAO,KAAK;EAC5C,eAAY;EACH;YAET,4CAACQ,qBAAc;GACZ,iBACC,2CAAC;IAAI,WAAW,OAAO;cACrB,2CAACE;KAAe,SAAQ;KAAQ,WAAWV,mBAAG,OAAO,iBAAiB,eAAe;eACnF,2CAACU,sBAAe,yBAAa,cAAc,UAAqC;MACjE;KACb;GAEP,gBAAgB,aAAa,SAAS,KACrC,2CAAC;IAAI,WAAW,OAAO;cACpB,aAAa,KAAK,SAAc,UAC/B,2CAACA;KAEC,SAAS,QAAQ,SAAS,UAAU,UAAU;KAC9C,WAAWV,mBAAG,OAAO,iBAAiB,eAAe;eAErD,2CAACU,sBAAe,yBAAa,QAAQ,UAAqC;OAJrE,MAKU,CACjB;KACE;GAER,2CAAC;IAAI,WAAW,OAAO;cAAmB,iBAAiB,WAAW;KAAO;MACvD;GACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDpB,MAAME,cAAmC,EAAC,YAAa,GAAG,WAAyC;CACjG,MAAMC,UACJ,2CAACC,0CACC,2CAAC,qBAAkB,GAAI,OAAQ,GAClB;AAGjB,KAAI,CAAC,YAAa,QAAO;AAEzB,QAAO,2CAACC,4CAA4B;EAAS,OAAO;YAAc;GAA+C;;AAGnH,yBAAe"}
|
|
@@ -10,10 +10,10 @@ const require_useTranslation = require('../../../hooks/useTranslation.cjs');
|
|
|
10
10
|
const require_flowTransformer = require('../../../utils/flowTransformer.cjs');
|
|
11
11
|
const require_useForm = require('../../../hooks/useForm.cjs');
|
|
12
12
|
const require_Spinner = require('../../primitives/Spinner/Spinner.cjs');
|
|
13
|
-
const require_composeAffixedInputs = require('../../../utils/composeAffixedInputs.cjs');
|
|
14
13
|
const require_Typography = require('../../primitives/Typography/Typography.cjs');
|
|
15
|
-
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
16
14
|
const require_Card = require('../../primitives/Card/Card.cjs');
|
|
15
|
+
const require_composeAffixedInputs = require('../../../utils/composeAffixedInputs.cjs');
|
|
16
|
+
const require_Alert = require('../../primitives/Alert/Alert.cjs');
|
|
17
17
|
const require_AuthOptionFactory = require('../flow/AuthOptionFactory.cjs');
|
|
18
18
|
const require_passkey = require('../../../utils/passkey.cjs');
|
|
19
19
|
const require_BaseSignUp_styles = require('./BaseSignUp.styles.cjs');
|