@tatchi-xyz/sdk 0.32.2 → 0.32.3
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/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CvW8VMJJ.css → PasskeyAuthMenu-mMygL3xX.css} +136 -46
- package/dist/cjs/react/components/PasskeyAuthMenu/PasskeyAuthMenu-mMygL3xX.css.map +1 -0
- package/dist/cjs/react/components/PasskeyAuthMenu/client.js +2 -3
- package/dist/cjs/react/components/PasskeyAuthMenu/client.js.map +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/controller/mode.js +7 -2
- package/dist/cjs/react/components/PasskeyAuthMenu/controller/mode.js.map +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.js +4 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.js.map +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/hydrationContext.js +20 -0
- package/dist/cjs/react/components/PasskeyAuthMenu/hydrationContext.js.map +1 -0
- package/dist/cjs/react/components/PasskeyAuthMenu/passkeyAuthMenuCompat.js +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/shell.js +48 -27
- package/dist/cjs/react/components/PasskeyAuthMenu/shell.js.map +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/skeleton.js +155 -101
- package/dist/cjs/react/components/PasskeyAuthMenu/skeleton.js.map +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js +5 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js.map +1 -1
- package/dist/cjs/react/index.js +2 -2
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-C-muDjkN.css → PasskeyAuthMenu-BihXvuII.css} +136 -46
- package/dist/esm/react/components/PasskeyAuthMenu/PasskeyAuthMenu-BihXvuII.css.map +1 -0
- package/dist/esm/react/components/PasskeyAuthMenu/client.js +2 -3
- package/dist/esm/react/components/PasskeyAuthMenu/client.js.map +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/controller/mode.js +7 -3
- package/dist/esm/react/components/PasskeyAuthMenu/controller/mode.js.map +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.js +4 -1
- package/dist/esm/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.js.map +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/hydrationContext.js +17 -0
- package/dist/esm/react/components/PasskeyAuthMenu/hydrationContext.js.map +1 -0
- package/dist/esm/react/components/PasskeyAuthMenu/passkeyAuthMenuCompat.js +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/shell.js +48 -27
- package/dist/esm/react/components/PasskeyAuthMenu/shell.js.map +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/skeleton.js +155 -101
- package/dist/esm/react/components/PasskeyAuthMenu/skeleton.js.map +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js +5 -1
- package/dist/esm/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js.map +1 -1
- package/dist/esm/react/index.js +2 -2
- package/dist/esm/react/styles/styles.css +135 -45
- package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
- package/dist/types/src/react/components/PasskeyAuthMenu/client.d.ts +0 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/client.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/controller/mode.d.ts +6 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/controller/mode.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/hydrationContext.d.ts +10 -0
- package/dist/types/src/react/components/PasskeyAuthMenu/hydrationContext.d.ts.map +1 -0
- package/dist/types/src/react/components/PasskeyAuthMenu/shell.d.ts +2 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/shell.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/skeleton.d.ts +5 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/skeleton.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/ui/ContentSwitcher.d.ts.map +1 -1
- package/dist/workers/offline-export-sw.js +156 -1
- package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
- package/dist/workers/web3authn-signer.worker.js +1360 -2
- package/dist/workers/web3authn-vrf.worker.js +2857 -2
- package/package.json +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/PasskeyAuthMenu-CvW8VMJJ.css.map +0 -1
- package/dist/esm/react/components/PasskeyAuthMenu/PasskeyAuthMenu-C-muDjkN.css.map +0 -1
|
@@ -37,9 +37,13 @@ function getModeTitle(mode, headings) {
|
|
|
37
37
|
* - No IndexedDB/wallet-prefill logic yet (intentionally).
|
|
38
38
|
* - Pure state transitions to keep the baseline bundle small and predictable.
|
|
39
39
|
*/
|
|
40
|
-
function useAuthMenuMode({ defaultMode, accountExists, currentValue, setCurrentValue, headings }) {
|
|
40
|
+
function useAuthMenuMode({ defaultMode, accountExists, currentValue, setCurrentValue, headings, forceInitialRegister = false }) {
|
|
41
41
|
const preferredDefaultMode = resolveDefaultMode(accountExists, defaultMode);
|
|
42
|
-
const [mode, setMode] = react.default.useState(
|
|
42
|
+
const [mode, setMode] = react.default.useState(() => {
|
|
43
|
+
if (typeof defaultMode === "number") return defaultMode;
|
|
44
|
+
if (forceInitialRegister) return require_authMenuTypes.AuthMenuMode.Register;
|
|
45
|
+
return preferredDefaultMode;
|
|
46
|
+
});
|
|
43
47
|
const title = react.default.useMemo(() => getModeTitle(mode, headings), [mode, headings]);
|
|
44
48
|
const onSegmentChange = (nextMode) => {
|
|
45
49
|
setMode(nextMode);
|
|
@@ -63,5 +67,6 @@ function useAuthMenuMode({ defaultMode, accountExists, currentValue, setCurrentV
|
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
//#endregion
|
|
70
|
+
exports.getModeTitle = getModeTitle;
|
|
66
71
|
exports.useAuthMenuMode = useAuthMenuMode;
|
|
67
72
|
//# sourceMappingURL=mode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mode.js","names":["AuthMenuMode","defaults: Record<AuthMenuMode, AuthMenuTitle>","React"],"sources":["../../../../../../src/react/components/PasskeyAuthMenu/controller/mode.ts"],"sourcesContent":["import React from 'react';\nimport type { AuthMenuHeadings } from '../types';\nimport { AuthMenuMode } from '../types';\n\nexport interface AuthMenuTitle {\n title: string;\n subtitle: string;\n}\n\nexport function resolveDefaultMode(\n accountExists: boolean,\n requested?: AuthMenuMode | null,\n): AuthMenuMode {\n if (typeof requested === 'number') return requested;\n return accountExists ? AuthMenuMode.Login : AuthMenuMode.Register;\n}\n\nexport function getModeTitle(mode: AuthMenuMode, headings?: AuthMenuHeadings | null): AuthMenuTitle {\n const defaults: Record<AuthMenuMode, AuthMenuTitle> = {\n [AuthMenuMode.Login]: { title: 'Login', subtitle: 'Login with Passkey' },\n [AuthMenuMode.Register]: { title: 'Register Account', subtitle: 'Create a wallet with Passkey' },\n [AuthMenuMode.Sync]: { title: 'Sync Account', subtitle: 'Sync a wallet to this device with Passkey' },\n } as const;\n\n if (headings) {\n if (mode === AuthMenuMode.Login && headings.login) return headings.login;\n if (mode === AuthMenuMode.Register && headings.registration) return headings.registration;\n if (mode === AuthMenuMode.Sync && headings.syncAccount) return headings.syncAccount;\n }\n\n return defaults[mode] ?? defaults[AuthMenuMode.Login];\n}\n\nexport interface UseAuthMenuModeArgs {\n defaultMode?: AuthMenuMode;\n accountExists: boolean;\n currentValue: string;\n setCurrentValue: (v: string) => void;\n headings?: AuthMenuHeadings | null;\n}\n\nexport interface UseAuthMenuModeResult {\n mode: AuthMenuMode;\n setMode: React.Dispatch<React.SetStateAction<AuthMenuMode>>;\n title: AuthMenuTitle;\n onSegmentChange: (next: AuthMenuMode) => void;\n onInputChange: (val: string) => void;\n resetToDefault: () => void;\n}\n\n/**\n * `useAuthMenuMode`\n *\n * Minimal mode/title controller for PasskeyAuthMenu.\n * - No IndexedDB/wallet-prefill logic yet (intentionally).\n * - Pure state transitions to keep the baseline bundle small and predictable.\n */\nexport function useAuthMenuMode({\n defaultMode,\n accountExists,\n currentValue,\n setCurrentValue,\n headings,\n}: UseAuthMenuModeArgs): UseAuthMenuModeResult {\n const preferredDefaultMode = resolveDefaultMode(accountExists, defaultMode);\n const [mode, setMode] = React.useState<AuthMenuMode>(preferredDefaultMode);\n const title = React.useMemo(() => getModeTitle(mode, headings), [mode, headings]);\n\n const onSegmentChange = (nextMode: AuthMenuMode) => {\n setMode(nextMode);\n };\n\n const onInputChange = (val: string) => {\n setCurrentValue(val);\n };\n\n const resetToDefault = () => {\n const nextMode = resolveDefaultMode(accountExists, defaultMode);\n setMode(nextMode);\n setCurrentValue('');\n };\n\n return { mode, setMode, title, onSegmentChange, onInputChange, resetToDefault };\n}\n\nexport default useAuthMenuMode;\n"],"mappings":";;;;;;AASA,SAAgB,mBACd,eACA,WACc;AACd,KAAI,OAAO,cAAc,SAAU,QAAO;AAC1C,QAAO,gBAAgBA,mCAAa,QAAQA,mCAAa;;AAG3D,SAAgB,aAAa,MAAoB,UAAmD;CAClG,MAAMC,WAAgD;GACnDD,mCAAa,QAAQ;GAAE,OAAO;GAAS,UAAU;;GACjDA,mCAAa,WAAW;GAAE,OAAO;GAAoB,UAAU;;GAC/DA,mCAAa,OAAO;GAAE,OAAO;GAAgB,UAAU;;;AAG1D,KAAI,UAAU;AACZ,MAAI,SAASA,mCAAa,SAAS,SAAS,MAAO,QAAO,SAAS;AACnE,MAAI,SAASA,mCAAa,YAAY,SAAS,aAAc,QAAO,SAAS;AAC7E,MAAI,SAASA,mCAAa,QAAQ,SAAS,YAAa,QAAO,SAAS;;AAG1E,QAAO,SAAS,SAAS,SAASA,mCAAa;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"mode.js","names":["AuthMenuMode","defaults: Record<AuthMenuMode, AuthMenuTitle>","React"],"sources":["../../../../../../src/react/components/PasskeyAuthMenu/controller/mode.ts"],"sourcesContent":["import React from 'react';\nimport type { AuthMenuHeadings } from '../types';\nimport { AuthMenuMode } from '../types';\n\nexport interface AuthMenuTitle {\n title: string;\n subtitle: string;\n}\n\nexport function resolveDefaultMode(\n accountExists: boolean,\n requested?: AuthMenuMode | null,\n): AuthMenuMode {\n if (typeof requested === 'number') return requested;\n return accountExists ? AuthMenuMode.Login : AuthMenuMode.Register;\n}\n\nexport function getModeTitle(mode: AuthMenuMode, headings?: AuthMenuHeadings | null): AuthMenuTitle {\n const defaults: Record<AuthMenuMode, AuthMenuTitle> = {\n [AuthMenuMode.Login]: { title: 'Login', subtitle: 'Login with Passkey' },\n [AuthMenuMode.Register]: { title: 'Register Account', subtitle: 'Create a wallet with Passkey' },\n [AuthMenuMode.Sync]: { title: 'Sync Account', subtitle: 'Sync a wallet to this device with Passkey' },\n } as const;\n\n if (headings) {\n if (mode === AuthMenuMode.Login && headings.login) return headings.login;\n if (mode === AuthMenuMode.Register && headings.registration) return headings.registration;\n if (mode === AuthMenuMode.Sync && headings.syncAccount) return headings.syncAccount;\n }\n\n return defaults[mode] ?? defaults[AuthMenuMode.Login];\n}\n\nexport interface UseAuthMenuModeArgs {\n defaultMode?: AuthMenuMode;\n accountExists: boolean;\n currentValue: string;\n setCurrentValue: (v: string) => void;\n headings?: AuthMenuHeadings | null;\n /**\n * When true, forces the initial client render to start in Register mode, even if\n * `accountExists` suggests Login. This is used to align hydration with the shell skeleton.\n */\n forceInitialRegister?: boolean;\n}\n\nexport interface UseAuthMenuModeResult {\n mode: AuthMenuMode;\n setMode: React.Dispatch<React.SetStateAction<AuthMenuMode>>;\n title: AuthMenuTitle;\n onSegmentChange: (next: AuthMenuMode) => void;\n onInputChange: (val: string) => void;\n resetToDefault: () => void;\n}\n\n/**\n * `useAuthMenuMode`\n *\n * Minimal mode/title controller for PasskeyAuthMenu.\n * - No IndexedDB/wallet-prefill logic yet (intentionally).\n * - Pure state transitions to keep the baseline bundle small and predictable.\n */\nexport function useAuthMenuMode({\n defaultMode,\n accountExists,\n currentValue,\n setCurrentValue,\n headings,\n forceInitialRegister = false,\n}: UseAuthMenuModeArgs): UseAuthMenuModeResult {\n const preferredDefaultMode = resolveDefaultMode(accountExists, defaultMode);\n const [mode, setMode] = React.useState<AuthMenuMode>(() => {\n if (typeof defaultMode === 'number') return defaultMode;\n if (forceInitialRegister) return AuthMenuMode.Register;\n return preferredDefaultMode;\n });\n const title = React.useMemo(() => getModeTitle(mode, headings), [mode, headings]);\n\n const onSegmentChange = (nextMode: AuthMenuMode) => {\n setMode(nextMode);\n };\n\n const onInputChange = (val: string) => {\n setCurrentValue(val);\n };\n\n const resetToDefault = () => {\n const nextMode = resolveDefaultMode(accountExists, defaultMode);\n setMode(nextMode);\n setCurrentValue('');\n };\n\n return { mode, setMode, title, onSegmentChange, onInputChange, resetToDefault };\n}\n\nexport default useAuthMenuMode;\n"],"mappings":";;;;;;AASA,SAAgB,mBACd,eACA,WACc;AACd,KAAI,OAAO,cAAc,SAAU,QAAO;AAC1C,QAAO,gBAAgBA,mCAAa,QAAQA,mCAAa;;AAG3D,SAAgB,aAAa,MAAoB,UAAmD;CAClG,MAAMC,WAAgD;GACnDD,mCAAa,QAAQ;GAAE,OAAO;GAAS,UAAU;;GACjDA,mCAAa,WAAW;GAAE,OAAO;GAAoB,UAAU;;GAC/DA,mCAAa,OAAO;GAAE,OAAO;GAAgB,UAAU;;;AAG1D,KAAI,UAAU;AACZ,MAAI,SAASA,mCAAa,SAAS,SAAS,MAAO,QAAO,SAAS;AACnE,MAAI,SAASA,mCAAa,YAAY,SAAS,aAAc,QAAO,SAAS;AAC7E,MAAI,SAASA,mCAAa,QAAQ,SAAS,YAAa,QAAO,SAAS;;AAG1E,QAAO,SAAS,SAAS,SAASA,mCAAa;;;;;;;;;AAgCjD,SAAgB,gBAAgB,EAC9B,aACA,eACA,cACA,iBACA,UACA,uBAAuB,SACsB;CAC7C,MAAM,uBAAuB,mBAAmB,eAAe;CAC/D,MAAM,CAAC,MAAM,WAAWE,cAAM,eAA6B;AACzD,MAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,MAAI,qBAAsB,QAAOF,mCAAa;AAC9C,SAAO;;CAET,MAAM,QAAQE,cAAM,cAAc,aAAa,MAAM,WAAW,CAAC,MAAM;CAEvE,MAAM,mBAAmB,aAA2B;AAClD,UAAQ;;CAGV,MAAM,iBAAiB,QAAgB;AACrC,kBAAgB;;CAGlB,MAAM,uBAAuB;EAC3B,MAAM,WAAW,mBAAmB,eAAe;AACnD,UAAQ;AACR,kBAAgB;;AAGlB,QAAO;EAAE;EAAM;EAAS;EAAO;EAAiB;EAAe"}
|
package/dist/cjs/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.js');
|
|
2
2
|
const require_authMenuTypes = require('../authMenuTypes.js');
|
|
3
3
|
const require_mode = require('./mode.js');
|
|
4
|
+
const require_hydrationContext = require('../hydrationContext.js');
|
|
4
5
|
const require_proceedEligibility = require('./proceedEligibility.js');
|
|
5
6
|
let react = require("react");
|
|
6
7
|
react = require_rolldown_runtime.__toESM(react);
|
|
@@ -10,12 +11,14 @@ function usePasskeyAuthMenuController(props, runtime) {
|
|
|
10
11
|
const secure = typeof window !== "undefined" ? window.isSecureContext : true;
|
|
11
12
|
const currentValue = runtime.inputUsername;
|
|
12
13
|
const setCurrentValue = runtime.setInputUsername;
|
|
14
|
+
const forceInitialRegister = require_hydrationContext.usePasskeyAuthMenuForceInitialRegister();
|
|
13
15
|
const { mode, setMode, title, onSegmentChange: onSegmentChangeBase, onInputChange: onInputChangeBase, resetToDefault } = require_mode.useAuthMenuMode({
|
|
14
16
|
defaultMode: props.defaultMode,
|
|
15
17
|
accountExists: runtime.accountExists,
|
|
16
18
|
currentValue,
|
|
17
19
|
setCurrentValue,
|
|
18
|
-
headings: props.headings
|
|
20
|
+
headings: props.headings,
|
|
21
|
+
forceInitialRegister
|
|
19
22
|
});
|
|
20
23
|
const latestValueRef = react.default.useRef(currentValue);
|
|
21
24
|
react.default.useEffect(() => {
|
package/dist/cjs/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePasskeyAuthMenuController.js","names":["useAuthMenuMode","React","AuthMenuMode","getProceedEligibility","linkDevice: PasskeyAuthMenuLinkDeviceController"],"sources":["../../../../../../src/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.ts"],"sourcesContent":["import React from 'react';\nimport type { DeviceLinkingSSEEvent } from '@/core/types/sdkSentEvents';\nimport type { PasskeyAuthMenuRuntime } from '../adapters/tatchi';\nimport { AuthMenuMode, type PasskeyAuthMenuProps } from '../types';\nimport { useAuthMenuMode } from './mode';\nimport { getProceedEligibility } from './proceedEligibility';\n\nexport interface PasskeyAuthMenuLinkDeviceController {\n isOpen: boolean;\n onClose: () => void;\n onEvent: (event: DeviceLinkingSSEEvent) => void;\n onError: (error: Error) => void;\n}\n\nexport interface PasskeyAuthMenuController {\n mode: AuthMenuMode;\n title: { title: string; subtitle: string };\n waiting: boolean;\n showScanDevice: boolean;\n showEmailRecovery: boolean;\n currentValue: string;\n postfixText?: string;\n isUsingExistingAccount?: boolean;\n secure: boolean;\n canShowContinue: boolean;\n canSubmit: boolean;\n onSegmentChange: (next: AuthMenuMode) => void;\n onInputChange: (val: string) => void;\n onProceed: () => void;\n onResetToStart: () => void;\n openScanDevice: () => void;\n openEmailRecovery: () => void;\n closeEmailRecovery: () => void;\n closeLinkDeviceView: (reason: 'user' | 'flow') => void;\n linkDevice: PasskeyAuthMenuLinkDeviceController;\n}\n\nexport function usePasskeyAuthMenuController(\n props: Pick<\n PasskeyAuthMenuProps,\n 'onLogin' | 'onRegister' | 'onSyncAccount' | 'defaultMode' | 'headings' | 'linkDeviceOptions'\n >,\n runtime: PasskeyAuthMenuRuntime,\n): PasskeyAuthMenuController {\n const secure = typeof window !== 'undefined' ? window.isSecureContext : true;\n const currentValue = runtime.inputUsername;\n const setCurrentValue = runtime.setInputUsername;\n\n const { mode, setMode, title, onSegmentChange: onSegmentChangeBase, onInputChange: onInputChangeBase, resetToDefault } = useAuthMenuMode({\n defaultMode: props.defaultMode,\n accountExists: runtime.accountExists,\n currentValue,\n setCurrentValue,\n headings: props.headings,\n });\n\n const latestValueRef = React.useRef<string>(currentValue);\n React.useEffect(() => {\n latestValueRef.current = currentValue;\n }, [currentValue]);\n\n // Recent-login prefill state (from lazy feature island).\n const prefilledFromRecentRef = React.useRef(false);\n const prefilledValueRef = React.useRef<string>('');\n const prevModeRef = React.useRef<AuthMenuMode | null>(null);\n const lastUserSelectedModeRef = React.useRef<AuthMenuMode | null>(null);\n\n const clearPrefillMarkers = React.useCallback(() => {\n prefilledFromRecentRef.current = false;\n prefilledValueRef.current = '';\n }, []);\n\n const onSegmentChange = React.useCallback(\n (next: AuthMenuMode) => {\n lastUserSelectedModeRef.current = next;\n if (mode === AuthMenuMode.Login && next !== AuthMenuMode.Login) {\n if (prefilledFromRecentRef.current && currentValue === prefilledValueRef.current) {\n setCurrentValue('');\n }\n clearPrefillMarkers();\n }\n onSegmentChangeBase(next);\n },\n [mode, currentValue, setCurrentValue, onSegmentChangeBase, clearPrefillMarkers],\n );\n\n const onInputChange = React.useCallback(\n (val: string) => {\n if (val !== prefilledValueRef.current) {\n prefilledFromRecentRef.current = false;\n }\n onInputChangeBase(val);\n },\n [onInputChangeBase],\n );\n\n const { canShowContinue, canSubmit } = getProceedEligibility({\n mode,\n currentValue,\n accountExists: runtime.accountExists,\n secure,\n });\n\n const [waiting, setWaiting] = React.useState(false);\n const [showScanDevice, setShowScanDevice] = React.useState(false);\n const [showEmailRecovery, setShowEmailRecovery] = React.useState(false);\n\n // If the user is attempting to register but we discover the account already exists,\n // automatically switch them to the Login tab.\n React.useEffect(() => {\n if (waiting) return;\n if (mode !== AuthMenuMode.Register) return;\n if (!runtime.accountExists) return;\n if (lastUserSelectedModeRef.current === AuthMenuMode.Register) return;\n setMode(AuthMenuMode.Login);\n }, [mode, runtime.accountExists, setMode, waiting]);\n\n // Lazy feature-island: entering Login can prefill the last used account username.\n React.useEffect(() => {\n const prevMode = prevModeRef.current;\n prevModeRef.current = mode;\n\n const enteringLogin = mode === AuthMenuMode.Login && prevMode !== AuthMenuMode.Login;\n if (!enteringLogin) return;\n if (latestValueRef.current.trim().length > 0) return;\n\n let cancelled = false;\n void import('../features/recentLoginPrefill')\n .then(async (m) => {\n const result = await m.getRecentLoginPrefill(runtime.tatchiPasskey);\n if (cancelled || !result?.username) return;\n if (prevModeRef.current !== AuthMenuMode.Login) return;\n if (latestValueRef.current.trim().length > 0) return;\n\n setCurrentValue(result.username);\n prefilledFromRecentRef.current = true;\n prefilledValueRef.current = result.username;\n })\n .catch(() => {});\n\n return () => {\n cancelled = true;\n };\n }, [mode, runtime.tatchiPasskey, setCurrentValue]);\n\n const fallbackOnEvent = React.useCallback((event: DeviceLinkingSSEEvent) => {\n console.log('ShowQRCode event:', event);\n }, []);\n\n const fallbackOnError = React.useCallback((error: Error) => {\n console.error('ShowQRCode error:', error);\n }, []);\n\n const handleLinkDeviceEvent = props.linkDeviceOptions?.onEvent ?? fallbackOnEvent;\n const handleLinkDeviceError = props.linkDeviceOptions?.onError ?? fallbackOnError;\n const handleLinkDeviceCancelled = props.linkDeviceOptions?.onCancelled;\n\n const stopLinkDeviceFlow = React.useCallback(() => {\n const stopper = runtime.stopDevice2LinkingFlow;\n if (!stopper) return;\n void stopper().catch(() => {});\n }, [runtime.stopDevice2LinkingFlow]);\n\n const closeLinkDeviceView = React.useCallback(\n (reason: 'user' | 'flow') => {\n stopLinkDeviceFlow();\n setShowScanDevice(false);\n if (reason === 'user') {\n handleLinkDeviceCancelled?.();\n }\n },\n [stopLinkDeviceFlow, handleLinkDeviceCancelled],\n );\n\n const onResetToStart = React.useCallback(() => {\n setWaiting(false);\n if (showScanDevice) {\n closeLinkDeviceView('user');\n } else {\n setShowScanDevice(false);\n }\n setShowEmailRecovery(false);\n lastUserSelectedModeRef.current = null;\n resetToDefault();\n setCurrentValue('');\n clearPrefillMarkers();\n }, [showScanDevice, closeLinkDeviceView, resetToDefault, setCurrentValue, clearPrefillMarkers]);\n\n const onProceed = React.useCallback(() => {\n if (!canSubmit) return;\n\n setWaiting(true);\n\n void (async () => {\n try {\n if (mode === AuthMenuMode.Sync) {\n await props.onSyncAccount?.();\n setWaiting(false);\n setMode(AuthMenuMode.Login);\n } else if (mode === AuthMenuMode.Login) {\n await props.onLogin?.();\n setWaiting(false);\n closeLinkDeviceView('flow');\n setMode(AuthMenuMode.Login);\n } else {\n await props.onRegister?.();\n setWaiting(false);\n setMode(AuthMenuMode.Login);\n }\n } catch {\n if (mode === AuthMenuMode.Login) {\n setWaiting(false);\n closeLinkDeviceView('flow');\n setMode(mode);\n return;\n }\n onResetToStart();\n }\n })();\n }, [\n canSubmit,\n mode,\n props.onSyncAccount,\n props.onLogin,\n props.onRegister,\n setMode,\n closeLinkDeviceView,\n onResetToStart,\n ]);\n\n const openScanDevice = React.useCallback(() => {\n setShowEmailRecovery(false);\n setShowScanDevice(true);\n }, []);\n\n const openEmailRecovery = React.useCallback(() => {\n stopLinkDeviceFlow();\n setShowScanDevice(false);\n setShowEmailRecovery(true);\n }, [stopLinkDeviceFlow]);\n\n const closeEmailRecovery = React.useCallback(() => {\n setShowEmailRecovery(false);\n }, []);\n\n const linkDevice: PasskeyAuthMenuLinkDeviceController = React.useMemo(\n () => ({\n isOpen: showScanDevice,\n onClose: () => closeLinkDeviceView('flow'),\n onEvent: handleLinkDeviceEvent,\n onError: handleLinkDeviceError,\n }),\n [showScanDevice, closeLinkDeviceView, handleLinkDeviceEvent, handleLinkDeviceError],\n );\n\n return {\n mode,\n title,\n waiting,\n showScanDevice,\n showEmailRecovery,\n currentValue,\n postfixText: runtime.displayPostfix,\n isUsingExistingAccount: runtime.isUsingExistingAccount,\n secure,\n canShowContinue,\n canSubmit,\n onSegmentChange,\n onInputChange,\n onProceed,\n onResetToStart,\n openScanDevice,\n openEmailRecovery,\n closeEmailRecovery,\n closeLinkDeviceView,\n linkDevice,\n };\n}\n\nexport default usePasskeyAuthMenuController;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePasskeyAuthMenuController.js","names":["usePasskeyAuthMenuForceInitialRegister","useAuthMenuMode","React","AuthMenuMode","getProceedEligibility","linkDevice: PasskeyAuthMenuLinkDeviceController"],"sources":["../../../../../../src/react/components/PasskeyAuthMenu/controller/usePasskeyAuthMenuController.ts"],"sourcesContent":["import React from 'react';\nimport type { DeviceLinkingSSEEvent } from '@/core/types/sdkSentEvents';\nimport type { PasskeyAuthMenuRuntime } from '../adapters/tatchi';\nimport { AuthMenuMode, type PasskeyAuthMenuProps } from '../types';\nimport { usePasskeyAuthMenuForceInitialRegister } from '../hydrationContext';\nimport { useAuthMenuMode } from './mode';\nimport { getProceedEligibility } from './proceedEligibility';\n\nexport interface PasskeyAuthMenuLinkDeviceController {\n isOpen: boolean;\n onClose: () => void;\n onEvent: (event: DeviceLinkingSSEEvent) => void;\n onError: (error: Error) => void;\n}\n\nexport interface PasskeyAuthMenuController {\n mode: AuthMenuMode;\n title: { title: string; subtitle: string };\n waiting: boolean;\n showScanDevice: boolean;\n showEmailRecovery: boolean;\n currentValue: string;\n postfixText?: string;\n isUsingExistingAccount?: boolean;\n secure: boolean;\n canShowContinue: boolean;\n canSubmit: boolean;\n onSegmentChange: (next: AuthMenuMode) => void;\n onInputChange: (val: string) => void;\n onProceed: () => void;\n onResetToStart: () => void;\n openScanDevice: () => void;\n openEmailRecovery: () => void;\n closeEmailRecovery: () => void;\n closeLinkDeviceView: (reason: 'user' | 'flow') => void;\n linkDevice: PasskeyAuthMenuLinkDeviceController;\n}\n\nexport function usePasskeyAuthMenuController(\n props: Pick<\n PasskeyAuthMenuProps,\n 'onLogin' | 'onRegister' | 'onSyncAccount' | 'defaultMode' | 'headings' | 'linkDeviceOptions'\n >,\n runtime: PasskeyAuthMenuRuntime,\n): PasskeyAuthMenuController {\n const secure = typeof window !== 'undefined' ? window.isSecureContext : true;\n const currentValue = runtime.inputUsername;\n const setCurrentValue = runtime.setInputUsername;\n const forceInitialRegister = usePasskeyAuthMenuForceInitialRegister();\n\n const { mode, setMode, title, onSegmentChange: onSegmentChangeBase, onInputChange: onInputChangeBase, resetToDefault } = useAuthMenuMode({\n defaultMode: props.defaultMode,\n accountExists: runtime.accountExists,\n currentValue,\n setCurrentValue,\n headings: props.headings,\n forceInitialRegister,\n });\n\n const latestValueRef = React.useRef<string>(currentValue);\n React.useEffect(() => {\n latestValueRef.current = currentValue;\n }, [currentValue]);\n\n // Recent-login prefill state (from lazy feature island).\n const prefilledFromRecentRef = React.useRef(false);\n const prefilledValueRef = React.useRef<string>('');\n const prevModeRef = React.useRef<AuthMenuMode | null>(null);\n const lastUserSelectedModeRef = React.useRef<AuthMenuMode | null>(null);\n\n const clearPrefillMarkers = React.useCallback(() => {\n prefilledFromRecentRef.current = false;\n prefilledValueRef.current = '';\n }, []);\n\n const onSegmentChange = React.useCallback(\n (next: AuthMenuMode) => {\n lastUserSelectedModeRef.current = next;\n if (mode === AuthMenuMode.Login && next !== AuthMenuMode.Login) {\n if (prefilledFromRecentRef.current && currentValue === prefilledValueRef.current) {\n setCurrentValue('');\n }\n clearPrefillMarkers();\n }\n onSegmentChangeBase(next);\n },\n [mode, currentValue, setCurrentValue, onSegmentChangeBase, clearPrefillMarkers],\n );\n\n const onInputChange = React.useCallback(\n (val: string) => {\n if (val !== prefilledValueRef.current) {\n prefilledFromRecentRef.current = false;\n }\n onInputChangeBase(val);\n },\n [onInputChangeBase],\n );\n\n const { canShowContinue, canSubmit } = getProceedEligibility({\n mode,\n currentValue,\n accountExists: runtime.accountExists,\n secure,\n });\n\n const [waiting, setWaiting] = React.useState(false);\n const [showScanDevice, setShowScanDevice] = React.useState(false);\n const [showEmailRecovery, setShowEmailRecovery] = React.useState(false);\n\n // If the user is attempting to register but we discover the account already exists,\n // automatically switch them to the Login tab.\n React.useEffect(() => {\n if (waiting) return;\n if (mode !== AuthMenuMode.Register) return;\n if (!runtime.accountExists) return;\n if (lastUserSelectedModeRef.current === AuthMenuMode.Register) return;\n setMode(AuthMenuMode.Login);\n }, [mode, runtime.accountExists, setMode, waiting]);\n\n // Lazy feature-island: entering Login can prefill the last used account username.\n React.useEffect(() => {\n const prevMode = prevModeRef.current;\n prevModeRef.current = mode;\n\n const enteringLogin = mode === AuthMenuMode.Login && prevMode !== AuthMenuMode.Login;\n if (!enteringLogin) return;\n if (latestValueRef.current.trim().length > 0) return;\n\n let cancelled = false;\n void import('../features/recentLoginPrefill')\n .then(async (m) => {\n const result = await m.getRecentLoginPrefill(runtime.tatchiPasskey);\n if (cancelled || !result?.username) return;\n if (prevModeRef.current !== AuthMenuMode.Login) return;\n if (latestValueRef.current.trim().length > 0) return;\n\n setCurrentValue(result.username);\n prefilledFromRecentRef.current = true;\n prefilledValueRef.current = result.username;\n })\n .catch(() => {});\n\n return () => {\n cancelled = true;\n };\n }, [mode, runtime.tatchiPasskey, setCurrentValue]);\n\n const fallbackOnEvent = React.useCallback((event: DeviceLinkingSSEEvent) => {\n console.log('ShowQRCode event:', event);\n }, []);\n\n const fallbackOnError = React.useCallback((error: Error) => {\n console.error('ShowQRCode error:', error);\n }, []);\n\n const handleLinkDeviceEvent = props.linkDeviceOptions?.onEvent ?? fallbackOnEvent;\n const handleLinkDeviceError = props.linkDeviceOptions?.onError ?? fallbackOnError;\n const handleLinkDeviceCancelled = props.linkDeviceOptions?.onCancelled;\n\n const stopLinkDeviceFlow = React.useCallback(() => {\n const stopper = runtime.stopDevice2LinkingFlow;\n if (!stopper) return;\n void stopper().catch(() => {});\n }, [runtime.stopDevice2LinkingFlow]);\n\n const closeLinkDeviceView = React.useCallback(\n (reason: 'user' | 'flow') => {\n stopLinkDeviceFlow();\n setShowScanDevice(false);\n if (reason === 'user') {\n handleLinkDeviceCancelled?.();\n }\n },\n [stopLinkDeviceFlow, handleLinkDeviceCancelled],\n );\n\n const onResetToStart = React.useCallback(() => {\n setWaiting(false);\n if (showScanDevice) {\n closeLinkDeviceView('user');\n } else {\n setShowScanDevice(false);\n }\n setShowEmailRecovery(false);\n lastUserSelectedModeRef.current = null;\n resetToDefault();\n setCurrentValue('');\n clearPrefillMarkers();\n }, [showScanDevice, closeLinkDeviceView, resetToDefault, setCurrentValue, clearPrefillMarkers]);\n\n const onProceed = React.useCallback(() => {\n if (!canSubmit) return;\n\n setWaiting(true);\n\n void (async () => {\n try {\n if (mode === AuthMenuMode.Sync) {\n await props.onSyncAccount?.();\n setWaiting(false);\n setMode(AuthMenuMode.Login);\n } else if (mode === AuthMenuMode.Login) {\n await props.onLogin?.();\n setWaiting(false);\n closeLinkDeviceView('flow');\n setMode(AuthMenuMode.Login);\n } else {\n await props.onRegister?.();\n setWaiting(false);\n setMode(AuthMenuMode.Login);\n }\n } catch {\n if (mode === AuthMenuMode.Login) {\n setWaiting(false);\n closeLinkDeviceView('flow');\n setMode(mode);\n return;\n }\n onResetToStart();\n }\n })();\n }, [\n canSubmit,\n mode,\n props.onSyncAccount,\n props.onLogin,\n props.onRegister,\n setMode,\n closeLinkDeviceView,\n onResetToStart,\n ]);\n\n const openScanDevice = React.useCallback(() => {\n setShowEmailRecovery(false);\n setShowScanDevice(true);\n }, []);\n\n const openEmailRecovery = React.useCallback(() => {\n stopLinkDeviceFlow();\n setShowScanDevice(false);\n setShowEmailRecovery(true);\n }, [stopLinkDeviceFlow]);\n\n const closeEmailRecovery = React.useCallback(() => {\n setShowEmailRecovery(false);\n }, []);\n\n const linkDevice: PasskeyAuthMenuLinkDeviceController = React.useMemo(\n () => ({\n isOpen: showScanDevice,\n onClose: () => closeLinkDeviceView('flow'),\n onEvent: handleLinkDeviceEvent,\n onError: handleLinkDeviceError,\n }),\n [showScanDevice, closeLinkDeviceView, handleLinkDeviceEvent, handleLinkDeviceError],\n );\n\n return {\n mode,\n title,\n waiting,\n showScanDevice,\n showEmailRecovery,\n currentValue,\n postfixText: runtime.displayPostfix,\n isUsingExistingAccount: runtime.isUsingExistingAccount,\n secure,\n canShowContinue,\n canSubmit,\n onSegmentChange,\n onInputChange,\n onProceed,\n onResetToStart,\n openScanDevice,\n openEmailRecovery,\n closeEmailRecovery,\n closeLinkDeviceView,\n linkDevice,\n };\n}\n\nexport default usePasskeyAuthMenuController;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
|
|
2
|
+
let react = require("react");
|
|
3
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
4
|
+
|
|
5
|
+
//#region src/react/components/PasskeyAuthMenu/hydrationContext.ts
|
|
6
|
+
/**
|
|
7
|
+
* Internal context used by the SSR-safe shell to hint the client controller about
|
|
8
|
+
* initial hydration strategy (e.g., align first render with the skeleton).
|
|
9
|
+
*
|
|
10
|
+
* Default: false (normal behavior).
|
|
11
|
+
*/
|
|
12
|
+
const PasskeyAuthMenuHydrationContext = react.default.createContext(false);
|
|
13
|
+
function usePasskeyAuthMenuForceInitialRegister() {
|
|
14
|
+
return react.default.useContext(PasskeyAuthMenuHydrationContext);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.PasskeyAuthMenuHydrationContext = PasskeyAuthMenuHydrationContext;
|
|
19
|
+
exports.usePasskeyAuthMenuForceInitialRegister = usePasskeyAuthMenuForceInitialRegister;
|
|
20
|
+
//# sourceMappingURL=hydrationContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydrationContext.js","names":["React"],"sources":["../../../../../src/react/components/PasskeyAuthMenu/hydrationContext.ts"],"sourcesContent":["import React from 'react';\n\n/**\n * Internal context used by the SSR-safe shell to hint the client controller about\n * initial hydration strategy (e.g., align first render with the skeleton).\n *\n * Default: false (normal behavior).\n */\nexport const PasskeyAuthMenuHydrationContext = React.createContext<boolean>(false);\n\nexport function usePasskeyAuthMenuForceInitialRegister(): boolean {\n return React.useContext(PasskeyAuthMenuHydrationContext);\n}\n\n"],"mappings":";;;;;;;;;;;AAQA,MAAa,kCAAkCA,cAAM,cAAuB;AAE5E,SAAgB,yCAAkD;AAChE,QAAOA,cAAM,WAAW"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
const require_authMenuTypes = require('./authMenuTypes.js');
|
|
2
3
|
const require_skeleton = require('./skeleton.js');
|
|
3
4
|
const require_shell = require('./shell.js');
|
|
4
|
-
const require_authMenuTypes = require('./authMenuTypes.js');
|
|
5
5
|
|
|
6
6
|
//#region src/react/components/PasskeyAuthMenu/passkeyAuthMenuCompat.ts
|
|
7
7
|
var passkeyAuthMenuCompat_default = require_shell.PasskeyAuthMenu;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
2
|
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
|
|
3
3
|
const require_ThemeProvider = require('../theme/ThemeProvider.js');
|
|
4
|
+
require('./PasskeyAuthMenu.js');
|
|
4
5
|
const require_themeScope = require('./themeScope.js');
|
|
6
|
+
const require_authMenuTypes = require('./authMenuTypes.js');
|
|
5
7
|
const require_skeleton = require('./skeleton.js');
|
|
6
8
|
const require_preload = require('./preload.js');
|
|
9
|
+
const require_hydrationContext = require('./hydrationContext.js');
|
|
7
10
|
let react = require("react");
|
|
8
11
|
react = require_rolldown_runtime.__toESM(react);
|
|
9
12
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -12,6 +15,14 @@ react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
|
12
15
|
//#region src/react/components/PasskeyAuthMenu/shell.tsx
|
|
13
16
|
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.default.useLayoutEffect : react.default.useEffect;
|
|
14
17
|
const clientLazyCache = /* @__PURE__ */ new Map();
|
|
18
|
+
let didClientMountOnce = false;
|
|
19
|
+
let didAutoPreloadClientChunk = false;
|
|
20
|
+
function autoPreloadClientChunk() {
|
|
21
|
+
if (didAutoPreloadClientChunk) return;
|
|
22
|
+
didAutoPreloadClientChunk = true;
|
|
23
|
+
require_preload.preloadPasskeyAuthMenu();
|
|
24
|
+
}
|
|
25
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") autoPreloadClientChunk();
|
|
15
26
|
function getClientLazy(retryKey) {
|
|
16
27
|
const existing = clientLazyCache.get(retryKey);
|
|
17
28
|
if (existing) return existing;
|
|
@@ -49,44 +60,54 @@ var LazyErrorBoundary = class extends react.default.Component {
|
|
|
49
60
|
* - Client: lazy-loads the full implementation after mount.
|
|
50
61
|
*/
|
|
51
62
|
const PasskeyAuthMenu = (props) => {
|
|
52
|
-
const [isClient, setIsClient] = react.default.useState(
|
|
63
|
+
const [isClient, setIsClient] = react.default.useState(() => {
|
|
64
|
+
if (typeof window === "undefined") return false;
|
|
65
|
+
return didClientMountOnce;
|
|
66
|
+
});
|
|
67
|
+
const forceInitialRegisterRef = react.default.useRef(!didClientMountOnce && (props.defaultMode == null || props.defaultMode === require_authMenuTypes.AuthMenuMode.Register));
|
|
53
68
|
const [retryKey, setRetryKey] = react.default.useState(0);
|
|
54
69
|
const ClientLazy = react.default.useMemo(() => getClientLazy(retryKey), [retryKey]);
|
|
55
70
|
const { theme } = require_ThemeProvider.useTheme();
|
|
56
71
|
useIsomorphicLayoutEffect(() => {
|
|
72
|
+
didClientMountOnce = true;
|
|
57
73
|
setIsClient(true);
|
|
58
|
-
|
|
74
|
+
autoPreloadClientChunk();
|
|
59
75
|
}, []);
|
|
60
76
|
const skeleton = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_skeleton.PasskeyAuthMenuSkeletonInner, {
|
|
61
77
|
className: props.className,
|
|
62
|
-
style: props.style
|
|
78
|
+
style: props.style,
|
|
79
|
+
defaultMode: props.defaultMode,
|
|
80
|
+
headings: props.headings
|
|
63
81
|
});
|
|
64
82
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_themeScope.PasskeyAuthMenuThemeScope, {
|
|
65
83
|
theme,
|
|
66
|
-
children: isClient ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
84
|
+
children: isClient ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_hydrationContext.PasskeyAuthMenuHydrationContext.Provider, {
|
|
85
|
+
value: forceInitialRegisterRef.current,
|
|
86
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LazyErrorBoundary, {
|
|
87
|
+
onRetry: () => setRetryKey((k) => k + 1),
|
|
88
|
+
onError: () => invalidateClientLazy(retryKey),
|
|
89
|
+
fallback: ({ retry }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [skeleton, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
90
|
+
style: {
|
|
91
|
+
marginTop: 10,
|
|
92
|
+
fontSize: 12,
|
|
93
|
+
textAlign: "center",
|
|
94
|
+
opacity: .9
|
|
95
|
+
},
|
|
96
|
+
children: [
|
|
97
|
+
"Failed to load menu.",
|
|
98
|
+
" ",
|
|
99
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
100
|
+
type: "button",
|
|
101
|
+
onClick: retry,
|
|
102
|
+
style: { textDecoration: "underline" },
|
|
103
|
+
children: "Retry"
|
|
104
|
+
})
|
|
105
|
+
]
|
|
106
|
+
})] }),
|
|
107
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Suspense, {
|
|
108
|
+
fallback: skeleton,
|
|
109
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ClientLazy, { ...props })
|
|
110
|
+
})
|
|
90
111
|
})
|
|
91
112
|
}) : skeleton
|
|
92
113
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.js","names":["React","PasskeyAuthMenu: React.FC<PasskeyAuthMenuProps>","useTheme","PasskeyAuthMenuSkeletonInner","PasskeyAuthMenuThemeScope"],"sources":["../../../../../src/react/components/PasskeyAuthMenu/shell.tsx"],"sourcesContent":["import React from 'react';\nimport { PasskeyAuthMenuSkeletonInner } from './skeleton';\nimport { PasskeyAuthMenuThemeScope } from './themeScope';\nimport type
|
|
1
|
+
{"version":3,"file":"shell.js","names":["React","preloadPasskeyAuthMenu","PasskeyAuthMenu: React.FC<PasskeyAuthMenuProps>","AuthMenuMode","useTheme","PasskeyAuthMenuSkeletonInner","PasskeyAuthMenuThemeScope","PasskeyAuthMenuHydrationContext"],"sources":["../../../../../src/react/components/PasskeyAuthMenu/shell.tsx"],"sourcesContent":["import React from 'react';\nimport './PasskeyAuthMenu.css';\nimport { PasskeyAuthMenuSkeletonInner } from './skeleton';\nimport { PasskeyAuthMenuThemeScope } from './themeScope';\nimport { AuthMenuMode, type PasskeyAuthMenuProps } from './types';\nimport { useTheme } from '../theme';\nimport { preloadPasskeyAuthMenu } from './preload';\nimport { PasskeyAuthMenuHydrationContext } from './hydrationContext';\n\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\n\ntype PasskeyAuthMenuClientComponent = React.ComponentType<PasskeyAuthMenuProps>;\n\nconst clientLazyCache = new Map<number, React.LazyExoticComponent<PasskeyAuthMenuClientComponent>>();\n\nlet didClientMountOnce = false;\n\nlet didAutoPreloadClientChunk = false;\nfunction autoPreloadClientChunk() {\n if (didAutoPreloadClientChunk) return;\n didAutoPreloadClientChunk = true;\n void preloadPasskeyAuthMenu();\n}\n\n// If this module is imported in a browser bundle, start fetching the client chunk immediately.\n// This reduces the chance of a first-mount Suspense fallback flash without affecting SSR.\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n autoPreloadClientChunk();\n}\n\nfunction getClientLazy(retryKey: number): React.LazyExoticComponent<PasskeyAuthMenuClientComponent> {\n const existing = clientLazyCache.get(retryKey);\n if (existing) return existing;\n\n const next = React.lazy(() =>\n import('./client').then((m) => ({ default: m.PasskeyAuthMenuClient })),\n ) as unknown as React.LazyExoticComponent<PasskeyAuthMenuClientComponent>;\n\n clientLazyCache.set(retryKey, next);\n return next;\n}\n\nfunction invalidateClientLazy(retryKey: number) {\n clientLazyCache.delete(retryKey);\n}\n\nclass LazyErrorBoundary extends React.Component<\n {\n fallback: (args: { error: Error; retry: () => void }) => React.ReactNode;\n onRetry: () => void;\n onError?: (error: Error) => void;\n children: React.ReactNode;\n },\n { error: Error | null }\n> {\n state: { error: Error | null } = { error: null };\n\n static getDerivedStateFromError(error: Error): { error: Error } {\n return { error };\n }\n\n retry = () => {\n this.setState({ error: null });\n this.props.onRetry();\n };\n\n componentDidCatch(error: Error) {\n this.props.onError?.(error);\n }\n\n render() {\n if (this.state.error) {\n return this.props.fallback({ error: this.state.error, retry: this.retry });\n }\n return this.props.children;\n }\n}\n\n/**\n * `PasskeyAuthMenu` — SSR-safe shell.\n *\n * - Server: renders a skeleton only.\n * - Client: lazy-loads the full implementation after mount.\n */\nexport const PasskeyAuthMenu: React.FC<PasskeyAuthMenuProps> = (props) => {\n const [isClient, setIsClient] = React.useState(() => {\n if (typeof window === 'undefined') return false;\n return didClientMountOnce;\n });\n const forceInitialRegisterRef = React.useRef(\n !didClientMountOnce && (props.defaultMode == null || props.defaultMode === AuthMenuMode.Register),\n );\n const [retryKey, setRetryKey] = React.useState(0);\n const ClientLazy = React.useMemo(() => getClientLazy(retryKey), [retryKey]);\n\n // Align with the SDK Theme boundary when present (TatchiPasskeyProvider wraps one by default).\n // Falls back to system preference when used standalone.\n const { theme } = useTheme();\n\n useIsomorphicLayoutEffect(() => {\n didClientMountOnce = true;\n setIsClient(true);\n // Start fetching the client chunk immediately; the skeleton remains as the Suspense fallback.\n autoPreloadClientChunk();\n }, []);\n\n const skeleton = (\n <PasskeyAuthMenuSkeletonInner\n className={props.className}\n style={props.style}\n defaultMode={props.defaultMode}\n headings={props.headings}\n />\n );\n\n return (\n <PasskeyAuthMenuThemeScope theme={theme}>\n {isClient ? (\n <PasskeyAuthMenuHydrationContext.Provider value={forceInitialRegisterRef.current}>\n <LazyErrorBoundary\n onRetry={() => setRetryKey((k) => k + 1)}\n onError={() => invalidateClientLazy(retryKey)}\n fallback={({ retry }) => (\n <div>\n {skeleton}\n <div style={{ marginTop: 10, fontSize: 12, textAlign: 'center', opacity: 0.9 }}>\n Failed to load menu.{' '}\n <button type=\"button\" onClick={retry} style={{ textDecoration: 'underline' }}>\n Retry\n </button>\n </div>\n </div>\n )}\n >\n <React.Suspense fallback={skeleton}>\n <ClientLazy {...props} />\n </React.Suspense>\n </LazyErrorBoundary>\n </PasskeyAuthMenuHydrationContext.Provider>\n ) : (\n skeleton\n )}\n </PasskeyAuthMenuThemeScope>\n );\n};\n\nexport default PasskeyAuthMenu;\n"],"mappings":";;;;;;;;;;;;;;;AASA,MAAM,4BAA4B,OAAO,WAAW,cAAcA,cAAM,kBAAkBA,cAAM;AAIhG,MAAM,kCAAkB,IAAI;AAE5B,IAAI,qBAAqB;AAEzB,IAAI,4BAA4B;AAChC,SAAS,yBAAyB;AAChC,KAAI,0BAA2B;AAC/B,6BAA4B;AAC5B,CAAKC;;AAKP,IAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACvD;AAGF,SAAS,cAAc,UAA6E;CAClG,MAAM,WAAW,gBAAgB,IAAI;AACrC,KAAI,SAAU,QAAO;CAErB,MAAM,OAAOD,cAAM,gDACjB,gBAAmB,MAAM,OAAO,EAAE,SAAS,EAAE;AAG/C,iBAAgB,IAAI,UAAU;AAC9B,QAAO;;AAGT,SAAS,qBAAqB,UAAkB;AAC9C,iBAAgB,OAAO;;AAGzB,IAAM,oBAAN,cAAgCA,cAAM,UAQpC;CACA,QAAiC,EAAE,OAAO;CAE1C,OAAO,yBAAyB,OAAgC;AAC9D,SAAO,EAAE;;CAGX,cAAc;AACZ,OAAK,SAAS,EAAE,OAAO;AACvB,OAAK,MAAM;;CAGb,kBAAkB,OAAc;AAC9B,OAAK,MAAM,UAAU;;CAGvB,SAAS;AACP,MAAI,KAAK,MAAM,MACb,QAAO,KAAK,MAAM,SAAS;GAAE,OAAO,KAAK,MAAM;GAAO,OAAO,KAAK;;AAEpE,SAAO,KAAK,MAAM;;;;;;;;;AAUtB,MAAaE,mBAAmD,UAAU;CACxE,MAAM,CAAC,UAAU,eAAeF,cAAM,eAAe;AACnD,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,SAAO;;CAET,MAAM,0BAA0BA,cAAM,OACpC,CAAC,uBAAuB,MAAM,eAAe,QAAQ,MAAM,gBAAgBG,mCAAa;CAE1F,MAAM,CAAC,UAAU,eAAeH,cAAM,SAAS;CAC/C,MAAM,aAAaA,cAAM,cAAc,cAAc,WAAW,CAAC;CAIjE,MAAM,EAAE,UAAUI;AAElB,iCAAgC;AAC9B,uBAAqB;AACrB,cAAY;AAEZ;IACC;CAEH,MAAM,WACJ,2CAACC;EACC,WAAW,MAAM;EACjB,OAAO,MAAM;EACb,aAAa,MAAM;EACnB,UAAU,MAAM;;AAIpB,QACE,2CAACC;EAAiC;YAC/B,WACC,2CAACC,yDAAgC;GAAS,OAAO,wBAAwB;aACvE,2CAAC;IACC,eAAe,aAAa,MAAM,IAAI;IACtC,eAAe,qBAAqB;IACpC,WAAW,EAAE,YACX,4CAAC,oBACE,UACD,4CAAC;KAAI,OAAO;MAAE,WAAW;MAAI,UAAU;MAAI,WAAW;MAAU,SAAS;;;MAAO;MACzD;MACrB,2CAAC;OAAO,MAAK;OAAS,SAAS;OAAO,OAAO,EAAE,gBAAgB;iBAAe;;;;cAOpF,2CAACP,cAAM;KAAS,UAAU;eACxB,2CAAC,cAAW,GAAI;;;OAKtB;;;AAMR,oBAAe"}
|
|
@@ -1,120 +1,174 @@
|
|
|
1
1
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
2
|
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
|
|
3
3
|
const require_ThemeProvider = require('../theme/ThemeProvider.js');
|
|
4
|
-
require('./
|
|
4
|
+
const require_ArrowLeft = require('./ui/icons/ArrowLeft.js');
|
|
5
|
+
const require_Mail = require('./ui/icons/Mail.js');
|
|
6
|
+
const require_QRCodeIcon = require('../QRCodeIcon.js');
|
|
5
7
|
const require_themeScope = require('./themeScope.js');
|
|
8
|
+
const require_authMenuTypes = require('./authMenuTypes.js');
|
|
9
|
+
const require_mode = require('./controller/mode.js');
|
|
6
10
|
let react = require("react");
|
|
7
11
|
react = require_rolldown_runtime.__toESM(react);
|
|
8
12
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
13
|
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
10
14
|
|
|
11
15
|
//#region src/react/components/PasskeyAuthMenu/skeleton.tsx
|
|
12
|
-
const PasskeyAuthMenuSkeletonInner = react.default.forwardRef(({ className, style }, ref) => {
|
|
13
|
-
|
|
16
|
+
const PasskeyAuthMenuSkeletonInner = react.default.forwardRef(({ className, style, defaultMode, headings }, ref) => {
|
|
17
|
+
const mode = typeof defaultMode === "number" ? defaultMode : require_authMenuTypes.AuthMenuMode.Register;
|
|
18
|
+
const title = require_mode.getModeTitle(mode, headings ?? null);
|
|
19
|
+
const placeholder = mode === require_authMenuTypes.AuthMenuMode.Register ? "Pick a username" : mode === require_authMenuTypes.AuthMenuMode.Sync ? "Leave blank to discover accounts" : "Enter your username";
|
|
20
|
+
const segHelpText = mode === require_authMenuTypes.AuthMenuMode.Login ? "Sign in with your passkey" : mode === require_authMenuTypes.AuthMenuMode.Sync ? "Sync account (iCloud/Chrome sync)" : "Create a new account";
|
|
21
|
+
const segActiveWidth = "calc((100% - 18px) / 3)";
|
|
22
|
+
const segActiveX = mode === require_authMenuTypes.AuthMenuMode.Login ? `calc(5px + ${segActiveWidth} + 4px)` : mode === require_authMenuTypes.AuthMenuMode.Sync ? `calc(5px + ${segActiveWidth} + 4px + ${segActiveWidth} + 4px)` : "5px";
|
|
23
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
14
24
|
ref,
|
|
15
25
|
className: `w3a-signup-menu-root w3a-skeleton${className ? ` ${className}` : ""}`,
|
|
16
26
|
style,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
})]
|
|
34
|
-
}),
|
|
35
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36
|
-
className: "w3a-passkey-row",
|
|
37
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38
|
-
className: "w3a-input-pill w3a-skeleton-input",
|
|
39
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40
|
-
className: "w3a-skeleton-block",
|
|
41
|
-
style: {
|
|
42
|
-
width: "40%",
|
|
43
|
-
height: "18px",
|
|
44
|
-
marginLeft: "12px"
|
|
45
|
-
}
|
|
46
|
-
})
|
|
47
|
-
})
|
|
48
|
-
}),
|
|
49
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
50
|
-
className: "w3a-segmented-root",
|
|
51
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
52
|
-
className: "w3a-seg-track",
|
|
53
|
-
children: [
|
|
54
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55
|
-
className: "w3a-seg-button",
|
|
56
|
-
children: "Register"
|
|
57
|
-
}),
|
|
58
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
59
|
-
className: "w3a-seg-button",
|
|
60
|
-
children: "Login"
|
|
61
|
-
}),
|
|
62
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
63
|
-
className: "w3a-seg-button",
|
|
64
|
-
children: "Sync"
|
|
65
|
-
})
|
|
66
|
-
]
|
|
27
|
+
"data-mode": mode,
|
|
28
|
+
"data-waiting": "false",
|
|
29
|
+
"data-scan-device": "false",
|
|
30
|
+
"data-email-recovery": "false",
|
|
31
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
32
|
+
className: "w3a-content-switcher",
|
|
33
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
34
|
+
"aria-label": "Back",
|
|
35
|
+
type: "button",
|
|
36
|
+
className: "w3a-back-button",
|
|
37
|
+
disabled: true,
|
|
38
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ArrowLeft.ArrowLeftIcon, {
|
|
39
|
+
size: 18,
|
|
40
|
+
strokeWidth: 2.25,
|
|
41
|
+
style: { display: "block" }
|
|
67
42
|
})
|
|
68
|
-
}),
|
|
69
|
-
|
|
70
|
-
className: "w3a-seg-help-row",
|
|
43
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
44
|
+
className: "w3a-content-area",
|
|
71
45
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
72
|
-
className: "w3a-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
46
|
+
className: "w3a-content-sizer",
|
|
47
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
48
|
+
className: "w3a-signin-menu",
|
|
49
|
+
children: [
|
|
50
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
51
|
+
className: "w3a-header",
|
|
52
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
53
|
+
className: "w3a-title",
|
|
54
|
+
children: title.title
|
|
55
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
56
|
+
className: "w3a-subhead",
|
|
57
|
+
children: title.subtitle
|
|
58
|
+
})] })
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
61
|
+
className: "w3a-passkey-row",
|
|
62
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
63
|
+
className: "w3a-input-pill",
|
|
64
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
65
|
+
className: "w3a-input-wrap",
|
|
66
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
67
|
+
type: "text",
|
|
68
|
+
name: "passkey",
|
|
69
|
+
disabled: true,
|
|
70
|
+
placeholder,
|
|
71
|
+
className: "w3a-input",
|
|
72
|
+
"aria-disabled": "true",
|
|
73
|
+
autoCapitalize: "none",
|
|
74
|
+
autoCorrect: "off",
|
|
75
|
+
spellCheck: false,
|
|
76
|
+
inputMode: "text",
|
|
77
|
+
style: { pointerEvents: "none" }
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
81
|
+
style: {
|
|
82
|
+
position: "relative",
|
|
83
|
+
display: "inline-block"
|
|
84
|
+
},
|
|
85
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
86
|
+
"aria-label": "Continue",
|
|
87
|
+
type: "button",
|
|
88
|
+
className: "w3a-arrow-btn no-transition",
|
|
89
|
+
disabled: true
|
|
90
|
+
})
|
|
91
|
+
})]
|
|
92
|
+
}),
|
|
93
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
94
|
+
className: "w3a-seg",
|
|
95
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
96
|
+
className: "w3a-seg-active",
|
|
97
|
+
style: {
|
|
98
|
+
width: segActiveWidth,
|
|
99
|
+
transform: `translateX(${segActiveX})`,
|
|
100
|
+
opacity: .9,
|
|
101
|
+
background: "var(--w3a-passkey-auth-menu2-seg-active-bg)"
|
|
102
|
+
}
|
|
103
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
104
|
+
className: "w3a-seg-grid",
|
|
105
|
+
children: [
|
|
106
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
107
|
+
type: "button",
|
|
108
|
+
"aria-pressed": mode === require_authMenuTypes.AuthMenuMode.Register,
|
|
109
|
+
className: `w3a-seg-btn${mode === require_authMenuTypes.AuthMenuMode.Register ? " is-active" : ""} register`,
|
|
110
|
+
disabled: true,
|
|
111
|
+
children: "Register"
|
|
112
|
+
}),
|
|
113
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
114
|
+
type: "button",
|
|
115
|
+
"aria-pressed": mode === require_authMenuTypes.AuthMenuMode.Login,
|
|
116
|
+
className: `w3a-seg-btn${mode === require_authMenuTypes.AuthMenuMode.Login ? " is-active" : ""} login`,
|
|
117
|
+
disabled: true,
|
|
118
|
+
children: "Login"
|
|
119
|
+
}),
|
|
120
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
121
|
+
type: "button",
|
|
122
|
+
"aria-pressed": mode === require_authMenuTypes.AuthMenuMode.Sync,
|
|
123
|
+
className: `w3a-seg-btn${mode === require_authMenuTypes.AuthMenuMode.Sync ? " is-active" : ""} sync`,
|
|
124
|
+
disabled: true,
|
|
125
|
+
children: "Sync"
|
|
126
|
+
})
|
|
127
|
+
]
|
|
128
|
+
})]
|
|
129
|
+
}),
|
|
130
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
131
|
+
className: "w3a-seg-help-row",
|
|
132
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
133
|
+
className: "w3a-seg-help",
|
|
134
|
+
"aria-live": "polite",
|
|
135
|
+
children: segHelpText
|
|
136
|
+
})
|
|
137
|
+
}),
|
|
138
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
139
|
+
className: "w3a-scan-device-row",
|
|
140
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
141
|
+
className: "w3a-section-divider",
|
|
142
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
143
|
+
className: "w3a-section-divider-text",
|
|
144
|
+
children: "Already have an account?"
|
|
145
|
+
})
|
|
146
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
147
|
+
className: "w3a-secondary-actions",
|
|
148
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
149
|
+
className: "w3a-link-device-btn",
|
|
150
|
+
disabled: true,
|
|
151
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_QRCodeIcon.default, {
|
|
152
|
+
width: 18,
|
|
153
|
+
height: 18,
|
|
154
|
+
strokeWidth: 2
|
|
155
|
+
}), "Scan and Link Device"]
|
|
156
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
157
|
+
className: "w3a-link-device-btn",
|
|
158
|
+
disabled: true,
|
|
159
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Mail.MailIcon, {
|
|
160
|
+
size: 18,
|
|
161
|
+
strokeWidth: 2,
|
|
162
|
+
style: { display: "block" }
|
|
163
|
+
}), "Recover Account with Email"]
|
|
164
|
+
})]
|
|
165
|
+
})]
|
|
166
|
+
})
|
|
167
|
+
]
|
|
87
168
|
})
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
className: "w3a-link-device-btn",
|
|
92
|
-
disabled: true,
|
|
93
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
94
|
-
className: "w3a-skeleton-block",
|
|
95
|
-
style: {
|
|
96
|
-
width: "18px",
|
|
97
|
-
height: "18px",
|
|
98
|
-
marginRight: "8px",
|
|
99
|
-
borderRadius: "4px"
|
|
100
|
-
}
|
|
101
|
-
}), "Scan and Link Device"]
|
|
102
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
103
|
-
className: "w3a-link-device-btn",
|
|
104
|
-
disabled: true,
|
|
105
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
106
|
-
className: "w3a-skeleton-block",
|
|
107
|
-
style: {
|
|
108
|
-
width: "18px",
|
|
109
|
-
height: "18px",
|
|
110
|
-
marginRight: "8px",
|
|
111
|
-
borderRadius: "9999px"
|
|
112
|
-
}
|
|
113
|
-
}), "Recover Account with Email"]
|
|
114
|
-
})]
|
|
115
|
-
})]
|
|
116
|
-
})
|
|
117
|
-
]
|
|
169
|
+
})
|
|
170
|
+
})]
|
|
171
|
+
})
|
|
118
172
|
});
|
|
119
173
|
});
|
|
120
174
|
PasskeyAuthMenuSkeletonInner.displayName = "PasskeyAuthMenuSkeletonInner";
|