@abstraxn/signer-react 3.3.10 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/src/ConnectButton.css.d.ts +2 -0
- package/dist/src/ConnectButton.css.js +1 -0
- package/dist/src/ConnectButton.d.ts +0 -1
- package/dist/src/ConnectButton.js +7 -6
- package/dist/src/ExternalWalletButtons.css.d.ts +2 -0
- package/dist/src/ExternalWalletButtons.css.js +1 -0
- package/dist/src/ExternalWalletButtons.d.ts +4 -1
- package/dist/src/ExternalWalletButtons.js +6 -1
- package/dist/src/WalletModal.css +2 -0
- package/dist/src/WalletModal.css.d.ts +2 -0
- package/dist/src/WalletModal.css.js +1 -0
- package/dist/src/WalletModal.d.ts +2 -2
- package/dist/src/WalletModal.js +113 -59
- package/dist/src/components/AbstraxnLogo.d.ts +17 -0
- package/dist/src/components/AbstraxnLogo.js +29 -0
- package/dist/src/components/AbstraxnProvider/AbstraxnProviderInner.js +406 -338
- package/dist/src/components/AbstraxnProvider/useAbstraxnProviderBase.d.ts +7 -0
- package/dist/src/components/AbstraxnProvider/useAbstraxnProviderBase.js +9 -0
- package/dist/src/components/AbstraxnProvider/useWalletInitialization.js +41 -6
- package/dist/src/components/OnboardingUI/OnboardingUI.css +99 -4
- package/dist/src/components/OnboardingUI/OnboardingUI.css.d.ts +2 -0
- package/dist/src/components/OnboardingUI/OnboardingUI.css.js +1 -0
- package/dist/src/components/OnboardingUI/OnboardingUIReact.d.ts +0 -1
- package/dist/src/components/OnboardingUI/OnboardingUIReact.js +46 -19
- package/dist/src/components/OnboardingUI/OnboardingUIWeb.d.ts +24 -1
- package/dist/src/components/OnboardingUI/OnboardingUIWeb.js +348 -160
- package/dist/src/components/OnboardingUI/components/Divider.d.ts +7 -0
- package/dist/src/components/OnboardingUI/components/Divider.js +9 -0
- package/dist/src/components/OnboardingUI/components/EmailForm.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/EmailForm.js +1 -2
- package/dist/src/components/OnboardingUI/components/MfaForm.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/MfaForm.js +2 -3
- package/dist/src/components/OnboardingUI/components/Modal.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/Modal.js +12 -4
- package/dist/src/components/OnboardingUI/components/OtpForm.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/OtpForm.js +2 -3
- package/dist/src/components/OnboardingUI/components/PasskeyButton.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/PasskeyButton.js +2 -2
- package/dist/src/components/OnboardingUI/components/SocialButtons.d.ts +0 -1
- package/dist/src/components/OnboardingUI/components/SocialButtons.js +3 -3
- package/dist/src/components/OnboardingUI/onboardingShadowContainer.d.ts +9 -0
- package/dist/src/components/OnboardingUI/onboardingShadowContainer.js +36 -0
- package/dist/src/components/ShadowHost/ShadowHost.d.ts +18 -0
- package/dist/src/components/ShadowHost/ShadowHost.js +123 -0
- package/dist/src/components/ShadowHost/ShadowHostContext.d.ts +10 -0
- package/dist/src/components/ShadowHost/ShadowHostContext.js +14 -0
- package/dist/src/components/ShadowHost/index.d.ts +2 -0
- package/dist/src/components/ShadowHost/index.js +3 -0
- package/dist/src/components/WalletModal/components/ChainSelector.css +9 -0
- package/dist/src/components/WalletModal/components/ChainSelector.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ChainSelector.css.js +1 -0
- package/dist/src/components/WalletModal/components/ChainSelector.d.ts +0 -1
- package/dist/src/components/WalletModal/components/ChainSelector.js +78 -23
- package/dist/src/components/WalletModal/components/CodeInput.d.ts +12 -0
- package/dist/src/components/WalletModal/components/CodeInput.js +39 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.d.ts +0 -2
- package/dist/src/components/WalletModal/components/ExportKeyModal.js +2 -4
- package/dist/src/components/WalletModal/components/ExportWarningModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ExportWarningModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/ExportWarningModal.d.ts +0 -2
- package/dist/src/components/WalletModal/components/ExportWarningModal.js +2 -4
- package/dist/src/components/WalletModal/components/ManageWalletModal.css +27 -1
- package/dist/src/components/WalletModal/components/ManageWalletModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ManageWalletModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/ManageWalletModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/ManageWalletModal.js +66 -148
- package/dist/src/components/WalletModal/components/MfaVerifyModal.d.ts +15 -0
- package/dist/src/components/WalletModal/components/MfaVerifyModal.js +98 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.css +2 -12
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.js +0 -1
- package/dist/src/components/WalletModal/components/ReceiveModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/ReceiveModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/ReceiveModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/ReceiveModal.js +2 -2
- package/dist/src/components/WalletModal/components/SendModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/SendModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/SendModal.d.ts +5 -2
- package/dist/src/components/WalletModal/components/SendModal.js +25 -82
- package/dist/src/components/WalletModal/components/SignMfaModalHost.d.ts +1 -0
- package/dist/src/components/WalletModal/components/SignMfaModalHost.js +50 -0
- package/dist/src/components/WalletModal/components/SuccessModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/SuccessModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/SuccessModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/SuccessModal.js +0 -1
- package/dist/src/components/WalletModal/components/TokenSelectorModal.css.d.ts +2 -0
- package/dist/src/components/WalletModal/components/TokenSelectorModal.css.js +1 -0
- package/dist/src/components/WalletModal/components/TokenSelectorModal.d.ts +0 -1
- package/dist/src/components/WalletModal/components/TokenSelectorModal.js +0 -1
- package/dist/src/components/WalletModal/components/UserAvatar.js +2 -1
- package/dist/src/components/WalletModal/components/index.d.ts +3 -0
- package/dist/src/components/WalletModal/components/index.js +2 -0
- package/dist/src/components/WalletModal/hooks/useSendTransaction.js +18 -6
- package/dist/src/components/icons.d.ts +2 -0
- package/dist/src/components/icons.js +4 -0
- package/dist/src/hooks.d.ts +58 -3
- package/dist/src/hooks.js +172 -30
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/signMfaBridge.d.ts +7 -0
- package/dist/src/signMfaBridge.js +20 -0
- package/dist/src/types.d.ts +4 -0
- package/dist/src/utils/shadowFocus.d.ts +8 -0
- package/dist/src/utils/shadowFocus.js +15 -0
- package/dist/src/utils/shadowRegistry.d.ts +23 -0
- package/dist/src/utils/shadowRegistry.js +36 -0
- package/package.json +9 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { User, WhoamiResponse } from "@abstraxn/signer-core";
|
|
2
2
|
import type { AbstraxnProviderConfig } from "../../types";
|
|
3
|
+
import type { TokenData } from "../WalletModal/components/TokenSelectorModal";
|
|
3
4
|
import { OnboardingUIWeb } from "../OnboardingUI";
|
|
4
5
|
import type { AbstraxnWallet } from "@abstraxn/signer-core";
|
|
5
6
|
export declare function useAbstraxnProviderBase(_config: AbstraxnProviderConfig): {
|
|
@@ -23,6 +24,12 @@ export declare function useAbstraxnProviderBase(_config: AbstraxnProviderConfig)
|
|
|
23
24
|
setResending: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
24
25
|
walletBalance: bigint | null;
|
|
25
26
|
setWalletBalance: import("react").Dispatch<import("react").SetStateAction<bigint | null>>;
|
|
27
|
+
tokenBalances: TokenData[];
|
|
28
|
+
setTokenBalances: import("react").Dispatch<import("react").SetStateAction<TokenData[]>>;
|
|
29
|
+
tokenBalancesLoading: boolean;
|
|
30
|
+
setTokenBalancesLoading: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
31
|
+
tokenBalancesError: Error | null;
|
|
32
|
+
setTokenBalancesError: import("react").Dispatch<import("react").SetStateAction<Error | null>>;
|
|
26
33
|
onboardingRef: import("react").RefObject<OnboardingUIWeb | null>;
|
|
27
34
|
otpIdRef: import("react").RefObject<string | null>;
|
|
28
35
|
walletRef: import("react").RefObject<AbstraxnWallet | null>;
|
|
@@ -14,6 +14,9 @@ export function useAbstraxnProviderBase(_config) {
|
|
|
14
14
|
const [loading, setLoading] = useState(false);
|
|
15
15
|
const [resending, setResending] = useState(false);
|
|
16
16
|
const [walletBalance, setWalletBalance] = useState(null);
|
|
17
|
+
const [tokenBalances, setTokenBalances] = useState([]);
|
|
18
|
+
const [tokenBalancesLoading, setTokenBalancesLoading] = useState(false);
|
|
19
|
+
const [tokenBalancesError, setTokenBalancesError] = useState(null);
|
|
17
20
|
const onboardingRef = useRef(null);
|
|
18
21
|
const otpIdRef = useRef(null);
|
|
19
22
|
const walletRef = useRef(null);
|
|
@@ -41,6 +44,12 @@ export function useAbstraxnProviderBase(_config) {
|
|
|
41
44
|
setResending,
|
|
42
45
|
walletBalance,
|
|
43
46
|
setWalletBalance,
|
|
47
|
+
tokenBalances,
|
|
48
|
+
setTokenBalances,
|
|
49
|
+
tokenBalancesLoading,
|
|
50
|
+
setTokenBalancesLoading,
|
|
51
|
+
tokenBalancesError,
|
|
52
|
+
setTokenBalancesError,
|
|
44
53
|
onboardingRef,
|
|
45
54
|
otpIdRef,
|
|
46
55
|
walletRef,
|
|
@@ -9,9 +9,29 @@ import { EVM_CHAINS, toCoreChain } from "../../chains";
|
|
|
9
9
|
import { hasAuthParams, isLinkAuthCallback } from "./utils";
|
|
10
10
|
export function useWalletInitialization({ config, walletRef, onboardingRef, otpIdRef, externalWalletsEnabled, setIsConnected, setAddress, setUser, setWhoami, setChainId, setError, setConnectionType, init, }) {
|
|
11
11
|
useEffect(() => {
|
|
12
|
-
// If wallet already exists (from previous mount), reuse it to prevent flicker
|
|
12
|
+
// If wallet already exists (from previous mount), reuse it to prevent flicker.
|
|
13
|
+
// StrictMode still destroys OnboardingUIWeb in cleanup — rebuild its shadow
|
|
14
|
+
// tree here so the OAuth success loader can paint again.
|
|
13
15
|
if (walletRef.current) {
|
|
14
|
-
|
|
16
|
+
const onboarding = onboardingRef.current;
|
|
17
|
+
if (onboarding && !onboarding.hasLiveShadow()) {
|
|
18
|
+
onboarding.init();
|
|
19
|
+
if (typeof window !== "undefined") {
|
|
20
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
21
|
+
const hasSuccess = urlParams.get("success") === "true";
|
|
22
|
+
const mfaRequired = urlParams.get("mfaRequired") === "true";
|
|
23
|
+
if (hasSuccess &&
|
|
24
|
+
!mfaRequired &&
|
|
25
|
+
!isLinkAuthCallback(urlParams)) {
|
|
26
|
+
onboarding.showLoadingModal();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return () => {
|
|
31
|
+
if (onboardingRef.current) {
|
|
32
|
+
onboardingRef.current.destroy();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
15
35
|
}
|
|
16
36
|
// Compute supported chains from chain config (outside useMemo since we're in useEffect)
|
|
17
37
|
// This should include ALL chains that might be shown in the UI (availableChains)
|
|
@@ -176,10 +196,21 @@ export function useWalletInitialization({ config, walletRef, onboardingRef, otpI
|
|
|
176
196
|
walletInstance.on("chainChanged", (newChainId) => {
|
|
177
197
|
setChainId(newChainId);
|
|
178
198
|
});
|
|
179
|
-
// Initialize OnboardingUI only if not already created (prevents flicker on config change)
|
|
180
|
-
|
|
199
|
+
// Initialize OnboardingUI only if not already created (prevents flicker on config change).
|
|
200
|
+
// A destroyed StrictMode instance leaves a non-null ref with no live shadow — treat that
|
|
201
|
+
// as "not created" so we rebuild instead of skipping OAuth loader setup.
|
|
202
|
+
if (onboardingRef.current?.hasLiveShadow()) {
|
|
181
203
|
return;
|
|
182
204
|
}
|
|
205
|
+
if (onboardingRef.current) {
|
|
206
|
+
try {
|
|
207
|
+
onboardingRef.current.destroy();
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// Ignore — instance may already be partially torn down.
|
|
211
|
+
}
|
|
212
|
+
onboardingRef.current = null;
|
|
213
|
+
}
|
|
183
214
|
const uiConfig = config.ui || {};
|
|
184
215
|
const onboarding = new OnboardingUIWeb({
|
|
185
216
|
logo: uiConfig.logo,
|
|
@@ -484,6 +515,7 @@ export function useWalletInitialization({ config, walletRef, onboardingRef, otpI
|
|
|
484
515
|
// Hide immediately - use synchronous approach to prevent flicker
|
|
485
516
|
// Only hide if NOT handling a callback
|
|
486
517
|
const onboardingAny = onboarding;
|
|
518
|
+
let oauthLoaderTimeout = null;
|
|
487
519
|
if (!shouldKeepOpen && onboardingAny.modalOverlay) {
|
|
488
520
|
// Hide immediately without delay to prevent flicker
|
|
489
521
|
onboardingAny.modalOverlay.classList.remove("onboarding-modal-open");
|
|
@@ -495,9 +527,9 @@ export function useWalletInitialization({ config, walletRef, onboardingRef, otpI
|
|
|
495
527
|
// Skip when mfaRequired=true so MFA verification screen can show instead.
|
|
496
528
|
const mfaRequired = urlParams.get("mfaRequired") === "true";
|
|
497
529
|
if (!mfaRequired) {
|
|
498
|
-
setTimeout(() => {
|
|
530
|
+
oauthLoaderTimeout = setTimeout(() => {
|
|
499
531
|
const onboardingInstance = onboardingRef.current;
|
|
500
|
-
if (onboardingInstance
|
|
532
|
+
if (onboardingInstance) {
|
|
501
533
|
onboardingInstance.showLoadingModal();
|
|
502
534
|
}
|
|
503
535
|
}, 150);
|
|
@@ -547,6 +579,9 @@ export function useWalletInitialization({ config, walletRef, onboardingRef, otpI
|
|
|
547
579
|
});
|
|
548
580
|
}
|
|
549
581
|
return () => {
|
|
582
|
+
if (oauthLoaderTimeout !== null) {
|
|
583
|
+
clearTimeout(oauthLoaderTimeout);
|
|
584
|
+
}
|
|
550
585
|
if (onboardingRef.current) {
|
|
551
586
|
onboardingRef.current.destroy();
|
|
552
587
|
}
|
|
@@ -18,9 +18,17 @@
|
|
|
18
18
|
.onboarding-container.onboarding-inline {
|
|
19
19
|
min-height: auto;
|
|
20
20
|
padding: 0;
|
|
21
|
+
justify-content: flex-start;
|
|
21
22
|
/* width: 100%; */
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
/* Let the host page scroll the full card (wallet buttons, etc.) instead of
|
|
26
|
+
nesting a second scrollbar inside a short embed. */
|
|
27
|
+
.onboarding-container.onboarding-inline .onboarding-card {
|
|
28
|
+
max-height: none;
|
|
29
|
+
overflow-y: visible;
|
|
30
|
+
}
|
|
31
|
+
|
|
24
32
|
/* Modal Styles */
|
|
25
33
|
.onboarding-modal-overlay {
|
|
26
34
|
position: fixed;
|
|
@@ -545,6 +553,20 @@
|
|
|
545
553
|
cursor: not-allowed;
|
|
546
554
|
}
|
|
547
555
|
|
|
556
|
+
.onboarding-button-loading {
|
|
557
|
+
display: inline-flex;
|
|
558
|
+
align-items: center;
|
|
559
|
+
justify-content: center;
|
|
560
|
+
gap: 8px;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
.onboarding-button-spinner {
|
|
564
|
+
flex-shrink: 0;
|
|
565
|
+
width: 16px;
|
|
566
|
+
height: 16px;
|
|
567
|
+
animation: onboarding-spin 1s linear infinite;
|
|
568
|
+
}
|
|
569
|
+
|
|
548
570
|
.onboarding-button-primary {
|
|
549
571
|
font-weight: 600;
|
|
550
572
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
@@ -628,6 +650,7 @@
|
|
|
628
650
|
.onboarding-social-grid {
|
|
629
651
|
display: grid;
|
|
630
652
|
grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));
|
|
653
|
+
justify-items: center;
|
|
631
654
|
gap: 12px;
|
|
632
655
|
width: 100%;
|
|
633
656
|
}
|
|
@@ -636,12 +659,13 @@
|
|
|
636
659
|
display: flex;
|
|
637
660
|
align-items: center;
|
|
638
661
|
justify-content: center;
|
|
639
|
-
width:
|
|
662
|
+
width: 100%;
|
|
640
663
|
height: 48px;
|
|
641
664
|
padding: 0;
|
|
642
665
|
border-radius: 12px;
|
|
643
666
|
border: 1.5px solid #e5e7eb;
|
|
644
667
|
background-color: #ffffff;
|
|
668
|
+
color: #111827;
|
|
645
669
|
cursor: pointer;
|
|
646
670
|
transition: all 0.2s ease;
|
|
647
671
|
}
|
|
@@ -649,6 +673,7 @@
|
|
|
649
673
|
.onboarding-theme-dark .onboarding-button-social-icon {
|
|
650
674
|
background-color: #374151;
|
|
651
675
|
border-color: #4b5563;
|
|
676
|
+
color: #ffffff;
|
|
652
677
|
}
|
|
653
678
|
|
|
654
679
|
.onboarding-button-social-icon:hover:not(:disabled) {
|
|
@@ -671,6 +696,60 @@
|
|
|
671
696
|
.onboarding-social-icon {
|
|
672
697
|
width: 20px;
|
|
673
698
|
height: 20px;
|
|
699
|
+
color: inherit;
|
|
700
|
+
fill: currentColor;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/* Passkey Button Styles */
|
|
704
|
+
.onboarding-button-passkey {
|
|
705
|
+
background-color: #374151;
|
|
706
|
+
color: #ffffff;
|
|
707
|
+
border: 1.5px solid #4b5563;
|
|
708
|
+
font-weight: 500;
|
|
709
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
710
|
+
font-size: 14px;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.onboarding-theme-dark .onboarding-button-passkey {
|
|
714
|
+
background-color: #4b5563;
|
|
715
|
+
color: #ffffff;
|
|
716
|
+
border-color: #6b7280;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.onboarding-button-passkey:hover:not(:disabled) {
|
|
720
|
+
background-color: #4b5563;
|
|
721
|
+
border-color: #6b7280;
|
|
722
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
|
723
|
+
transform: translateY(-1px);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
.onboarding-theme-dark .onboarding-button-passkey:hover:not(:disabled) {
|
|
727
|
+
background-color: #6b7280;
|
|
728
|
+
border-color: #9ca3af;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
.onboarding-passkey-icon {
|
|
732
|
+
width: 20px;
|
|
733
|
+
height: 20px;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
.onboarding-passkey-signup-link {
|
|
737
|
+
text-decoration: underline;
|
|
738
|
+
cursor: pointer;
|
|
739
|
+
font-size: 14px;
|
|
740
|
+
font-weight: 500;
|
|
741
|
+
margin-top: 12px;
|
|
742
|
+
display: block;
|
|
743
|
+
text-align: center;
|
|
744
|
+
transition: color 0.15s ease;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.onboarding-theme-light .onboarding-passkey-signup-link {
|
|
748
|
+
color: #2170f5;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.onboarding-theme-dark .onboarding-passkey-signup-link {
|
|
752
|
+
color: #2170f5;
|
|
674
753
|
}
|
|
675
754
|
|
|
676
755
|
.onboarding-divider {
|
|
@@ -978,6 +1057,9 @@
|
|
|
978
1057
|
}
|
|
979
1058
|
|
|
980
1059
|
.onboarding-otp-verification .onboarding-button {
|
|
1060
|
+
/* Match OTP inputs width: 6 × 44px + 5 × 10px gap = 314px */
|
|
1061
|
+
width: 314px;
|
|
1062
|
+
max-width: 100%;
|
|
981
1063
|
margin-top: 0;
|
|
982
1064
|
margin-bottom: 0;
|
|
983
1065
|
margin-left: auto;
|
|
@@ -992,6 +1074,7 @@
|
|
|
992
1074
|
font-size: 14px;
|
|
993
1075
|
margin: -6px 0 16px;
|
|
994
1076
|
color: #6b7280;
|
|
1077
|
+
text-align: center;
|
|
995
1078
|
}
|
|
996
1079
|
|
|
997
1080
|
.onboarding-theme-dark .onboarding-mfa-trouble-text {
|
|
@@ -999,13 +1082,20 @@
|
|
|
999
1082
|
}
|
|
1000
1083
|
|
|
1001
1084
|
.onboarding-mfa-backup-link {
|
|
1002
|
-
border: none;
|
|
1003
|
-
background: transparent;
|
|
1004
|
-
padding: 0;
|
|
1085
|
+
border: none !important;
|
|
1086
|
+
background: transparent !important;
|
|
1087
|
+
padding: 0 !important;
|
|
1088
|
+
margin: 0;
|
|
1005
1089
|
text-decoration: underline;
|
|
1006
1090
|
cursor: pointer;
|
|
1007
1091
|
font-weight: 600;
|
|
1008
1092
|
font-size: 14px;
|
|
1093
|
+
font-family: inherit;
|
|
1094
|
+
line-height: inherit;
|
|
1095
|
+
box-shadow: none !important;
|
|
1096
|
+
outline: none;
|
|
1097
|
+
appearance: none;
|
|
1098
|
+
-webkit-appearance: none;
|
|
1009
1099
|
}
|
|
1010
1100
|
|
|
1011
1101
|
.onboarding-theme-light .onboarding-mfa-backup-link {
|
|
@@ -1242,6 +1332,11 @@
|
|
|
1242
1332
|
gap: 8px;
|
|
1243
1333
|
}
|
|
1244
1334
|
|
|
1335
|
+
.onboarding-otp-verification .onboarding-button {
|
|
1336
|
+
/* 6 × 44px + 5 × 8px gap = 304px */
|
|
1337
|
+
width: 304px;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1245
1340
|
.onboarding-otp-input {
|
|
1246
1341
|
width: 44px;
|
|
1247
1342
|
min-width: 44px;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "/**\n * OnboardingUI Component Styles\n */\n\n.onboarding-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n padding: 20px;\n font-family: 'GeistSans', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* Inline mode - no extra height */\n.onboarding-container.onboarding-inline {\n min-height: auto;\n padding: 0;\n justify-content: flex-start;\n /* width: 100%; */\n}\n\n/* Let the host page scroll the full card (wallet buttons, etc.) instead of\n nesting a second scrollbar inside a short embed. */\n.onboarding-container.onboarding-inline .onboarding-card {\n max-height: none;\n overflow-y: visible;\n}\n\n/* Modal Styles */\n.onboarding-modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.6);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n display: none; /* Start hidden by default to prevent flicker */\n align-items: center;\n justify-content: center;\n z-index: 9999;\n opacity: 0;\n transition: opacity 0.3s ease-in-out;\n padding: 16px;\n overflow: hidden;\n overscroll-behavior: contain;\n}\n\n.onboarding-modal-overlay::-webkit-scrollbar {\n display: none;\n}\n\n.onboarding-modal-overlay {\n -ms-overflow-style: none;\n scrollbar-width: none;\n}\n\n.onboarding-modal-overlay.onboarding-modal-open {\n display: flex; /* Show when explicitly opened */\n opacity: 1;\n}\n\n.onboarding-modal-overlay.onboarding-modal-closing {\n opacity: 0;\n}\n\n.onboarding-modal-content {\n position: relative;\n width: 100%;\n max-width: 420px;\n max-height: calc(100vh - 32px);\n overflow: hidden;\n transform: scale(0.95);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n@media (max-width: 480px) {\n .onboarding-modal-content {\n max-width: 100%;\n max-height: 100vh;\n border-radius: 0;\n }\n \n .onboarding-modal-overlay {\n padding: 0;\n }\n}\n\n.onboarding-modal-overlay.onboarding-modal-open .onboarding-modal-content {\n transform: scale(1);\n}\n\n.onboarding-modal-overlay.onboarding-modal-closing .onboarding-modal-content {\n transform: scale(0.95);\n}\n\n.onboarding-modal-close {\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 20;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n margin: 0;\n border: none;\n border-radius: 8px;\n background: transparent;\n cursor: pointer;\n transition: background-color 0.2s, color 0.2s;\n}\n\n.onboarding-theme-light.onboarding-modal-close {\n color: #6b7280;\n}\n\n.onboarding-theme-dark.onboarding-modal-close {\n color: #9ca3af;\n}\n\n.onboarding-theme-light.onboarding-modal-close:hover {\n background-color: #f3f4f6;\n color: #111827;\n}\n\n.onboarding-theme-dark.onboarding-modal-close:hover {\n background-color: #2a2a2a;\n color: #ffffff;\n}\n\n/* Modal container adjustments */\n.onboarding-modal-content .onboarding-container {\n min-height: auto;\n padding: 0;\n}\n\n/* Light Theme */\n.onboarding-theme-light {\n color: #000000;\n}\n\n/* Dark Theme */\n.onboarding-theme-dark {\n color: #ffffff;\n}\n\n.onboarding-card {\n width: 100%;\n max-width: 420px;\n padding: 20px;\n border-radius: 16px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);\n background-color: inherit;\n position: relative;\n overflow-y: auto;\n overflow-x: visible;\n max-height: calc(100vh - 32px);\n overscroll-behavior: contain;\n}\n\n.onboarding-card.onboarding-card-otp,\n.onboarding-card.onboarding-otp-active {\n overflow-x: visible;\n overflow-y: visible;\n}\n\n.onboarding-card.onboarding-card-otp .onboarding-otp-back-button,\n.onboarding-card.onboarding-otp-active .onboarding-otp-back-button {\n position: absolute !important;\n top: 0 !important;\n left: 0 !important;\n right: auto !important;\n bottom: auto !important;\n}\n\n/* MFA card: ensure stacking so auth code form is on top when modal is used */\n.onboarding-card.onboarding-card-mfa {\n position: relative;\n z-index: 1;\n}\n\n.onboarding-card.onboarding-card-mfa .onboarding-otp-back-button {\n position: absolute !important;\n top: 0 !important;\n left: 0 !important;\n right: auto !important;\n bottom: auto !important;\n}\n\n.onboarding-card::-webkit-scrollbar {\n width: 6px;\n}\n\n.onboarding-card::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.onboarding-card::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.2);\n border-radius: 3px;\n}\n\n.onboarding-theme-dark .onboarding-card::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.2);\n}\n\n@media (max-width: 480px) {\n .onboarding-card {\n padding: 24px 20px;\n border-radius: 0;\n max-height: 100vh;\n }\n}\n\n.onboarding-theme-light .onboarding-card {\n background-color: #ffffff;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);\n border: 1px solid rgba(0, 0, 0, 0.06);\n}\n\n.onboarding-theme-dark .onboarding-card {\n background-color: #1f2937;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 1px rgba(255, 255, 255, 0.1);\n border: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n.onboarding-header {\n text-align: center;\n margin-bottom: 20px;\n}\n\n.onboarding-logo-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.onboarding-logo-container {\n display: flex;\n justify-content: center;\n align-items: center;\n margin-bottom: 6px;\n gap: 10px;\n}\n\n.onboarding-logo-img {\n max-width: 120px;\n max-height: 60px;\n object-fit: contain;\n}\n\n\n.onboarding-title {\n font-size: 24px;\n font-weight: 500;\n margin: 0;\n color: inherit;\n text-align: center;\n margin-bottom: 4px;\n letter-spacing: -0.01em;\n line-height: 1.2;\n}\n\n@media (max-width: 480px) {\n .onboarding-title {\n font-size: 24px;\n margin-bottom: 24px;\n }\n}\n\n.onboarding-theme-light .onboarding-title {\n color: #111827;\n}\n\n.onboarding-theme-dark .onboarding-title {\n color: #ffffff;\n}\n\n.onboarding-form {\n width: 100%;\n}\n\n.onboarding-input-group {\n margin-bottom: 8px;\n}\n\n.onboarding-input-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #374151;\n margin-bottom: 4px;\n letter-spacing: -0.01em;\n line-height: 1.5;\n text-align: left;\n width: 100%;\n}\n\n.onboarding-theme-dark .onboarding-input-label {\n color: #e5e7eb;\n}\n\n.onboarding-input-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.onboarding-input-icon {\n position: absolute;\n left: 14px;\n color: #9ca3af;\n pointer-events: none;\n z-index: 1;\n width: 18px;\n height: 18px;\n}\n\n.onboarding-theme-dark .onboarding-input-icon {\n color: #9ca3af;\n}\n\n.onboarding-input {\n width: 100%;\n padding: 10px 14px 10px 44px;\n font-size: 14px;\n border: 1.5px solid #e5e7eb;\n border-radius: 8px;\n background-color: inherit;\n color: inherit;\n transition: all 0.15s ease;\n box-sizing: border-box;\n font-weight: 400;\n letter-spacing: 0;\n line-height: 1.5;\n}\n\n.onboarding-theme-light .onboarding-input {\n background-color: #ffffff;\n border-color: #e5e7eb;\n}\n\n.onboarding-theme-light .onboarding-input:-webkit-autofill,\n.onboarding-theme-light .onboarding-input:-webkit-autofill:hover,\n.onboarding-theme-light .onboarding-input:-webkit-autofill:focus,\n.onboarding-theme-light .onboarding-input:-webkit-autofill:active {\n -webkit-box-shadow: 0 0 0 30px #ffffff inset !important;\n -webkit-text-fill-color: #111827 !important;\n transition: background-color 5000s ease-in-out 0s;\n}\n\n.onboarding-theme-dark .onboarding-input {\n background-color: #374151;\n color: #ffffff;\n}\n\n.onboarding-theme-dark .onboarding-input:-webkit-autofill,\n.onboarding-theme-dark .onboarding-input:-webkit-autofill:hover,\n.onboarding-theme-dark .onboarding-input:-webkit-autofill:focus,\n.onboarding-theme-dark .onboarding-input:-webkit-autofill:active {\n -webkit-box-shadow: 0 0 0 30px #374151 inset !important;\n -webkit-text-fill-color: #ffffff !important;\n color: #ffffff !important;\n transition: background-color 5000s ease-in-out 0s;\n}\n\n.onboarding-input:focus {\n outline: none;\n}\n\n.onboarding-theme-light .onboarding-input:focus {\n border-color: #111827;\n box-shadow: 0 0 0 3px rgba(17, 24, 39, 0.1);\n background-color: #ffffff;\n}\n\n.onboarding-theme-dark .onboarding-input {\n border-color: #4b5563;\n background-color: #374151;\n}\n\n.onboarding-theme-dark .onboarding-input:focus {\n border-color: #9ca3af;\n box-shadow: 0 0 0 3px rgba(156, 163, 175, 0.2);\n background-color: #374151;\n}\n\n.onboarding-input-arrow-button {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: #9ca3af;\n transition: background-color 0.2s ease, color 0.2s ease, transform 0.15s ease, box-shadow 0.2s ease;\n border-radius: 6px;\n padding: 0;\n z-index: 2;\n}\n\n/* Light mode: default state */\n.onboarding-theme-light .onboarding-input-arrow-button {\n color: #6b7280;\n}\n\n.onboarding-theme-light .onboarding-input-arrow-button:hover:not(:disabled) {\n background-color: rgba(139, 152, 202, 0.35);\n color: #1f2937;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n.onboarding-theme-light .onboarding-input-arrow-button:active:not(:disabled) {\n transform: translateY(-50%) scale(0.94);\n background-color: rgba(139, 152, 202, 0.5);\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);\n}\n\n.onboarding-theme-light .onboarding-input-arrow-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgba(139, 152, 202, 0.5);\n}\n\n/* Light mode: filled state (has email) */\n.onboarding-theme-light .onboarding-input-arrow-button-filled {\n background-color: rgba(139, 152, 202, 0.45);\n color: #1f2937;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n.onboarding-theme-light .onboarding-input-arrow-button-filled:hover:not(:disabled) {\n background-color: rgba(139, 152, 202, 0.6);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.onboarding-theme-light .onboarding-input-arrow-button-filled:active:not(:disabled) {\n transform: translateY(-50%) scale(0.94);\n background-color: rgba(139, 152, 202, 0.7);\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);\n}\n\n.onboarding-theme-light .onboarding-input-arrow-button-filled:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgba(139, 152, 202, 0.55);\n}\n\n/* Dark mode */\n.onboarding-theme-dark .onboarding-input-arrow-button:hover:not(:disabled) {\n color: #ffffff;\n background-color: rgba(255, 255, 255, 0.12);\n}\n\n.onboarding-theme-dark .onboarding-input-arrow-button:active:not(:disabled) {\n transform: translateY(-50%) scale(0.94);\n background-color: rgba(255, 255, 255, 0.18);\n}\n\n.onboarding-theme-dark .onboarding-input-arrow-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px #1f2937, 0 0 0 4px rgba(156, 163, 175, 0.4);\n}\n\n.onboarding-theme-dark .onboarding-input-arrow-button-filled {\n color: #ffffff;\n background-color: rgba(255, 255, 255, 0.12);\n}\n\n.onboarding-theme-dark .onboarding-input-arrow-button-filled:hover:not(:disabled) {\n background-color: rgba(255, 255, 255, 0.18);\n}\n\n.onboarding-theme-dark .onboarding-input-arrow-button-filled:active:not(:disabled) {\n transform: translateY(-50%) scale(0.94);\n background-color: rgba(255, 255, 255, 0.22);\n}\n\n.onboarding-input-arrow-button:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.onboarding-input-arrow-icon {\n width: 20px;\n height: 20px;\n}\n\n.onboarding-input:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.onboarding-email-readonly {\n cursor: not-allowed;\n}\n\n.onboarding-error {\n padding: 0;\n margin-top: 8px;\n margin-bottom: 12px;\n background-color: transparent !important;\n color: #dc2626;\n font-size: 13px;\n text-align: center;\n width: 100%;\n font-weight: 500;\n line-height: 1.4;\n word-break: break-word;\n}\n\n.onboarding-theme-dark .onboarding-error {\n background-color: transparent !important;\n color: #fca5a5;\n}\n\n.onboarding-button {\n width: 100%;\n padding: 11px 20px;\n font-size: 14px;\n font-weight: 600;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n margin-bottom: 6px;\n letter-spacing: 0;\n line-height: 1.5;\n box-shadow: none;\n min-height: 42px;\n}\n\n.onboarding-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.onboarding-button-loading {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.onboarding-button-spinner {\n flex-shrink: 0;\n width: 16px;\n height: 16px;\n animation: onboarding-spin 1s linear infinite;\n}\n\n.onboarding-button-primary {\n font-weight: 600;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n/* Light theme button */\n.onboarding-theme-light .onboarding-button-primary {\n background-color: #111827;\n color: #ffffff;\n}\n\n.onboarding-theme-light .onboarding-button-primary:hover:not(:disabled) {\n background-color: #1f2937;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n transform: translateY(-1px);\n}\n\n.onboarding-theme-light .onboarding-button-primary:active:not(:disabled) {\n background-color: #374151;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n transform: translateY(0);\n}\n\n/* Dark theme button */\n.onboarding-theme-dark .onboarding-button-primary {\n background-color: #4b5563;\n color: #ffffff;\n}\n\n.onboarding-theme-dark .onboarding-button-primary:hover:not(:disabled) {\n background-color: #6b7280;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n transform: translateY(-1px);\n}\n\n.onboarding-theme-dark .onboarding-button-primary:active:not(:disabled) {\n background-color: #6b7280;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n transform: translateY(0);\n}\n\n.onboarding-button-google {\n background-color: #ffffff;\n color: #1f2937;\n border: 1.5px solid #e5e7eb;\n font-weight: 500;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n font-size: 14px;\n}\n\n.onboarding-theme-dark .onboarding-button-google {\n background-color: #374151;\n color: #ffffff;\n border-color: #4b5563;\n}\n\n.onboarding-button-google:hover:not(:disabled) {\n background-color: #f9fafb;\n border-color: #d1d5db;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n transform: translateY(-1px);\n}\n\n.onboarding-theme-dark .onboarding-button-google:hover:not(:disabled) {\n background-color: #4b5563;\n border-color: #6b7280;\n}\n\n.onboarding-google-icon {\n width: 20px;\n height: 20px;\n}\n\n.onboarding-button-google {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.onboarding-social-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(48px, 1fr));\n justify-items: center;\n gap: 12px;\n width: 100%;\n}\n\n.onboarding-button-social-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 48px;\n padding: 0;\n border-radius: 12px;\n border: 1.5px solid #e5e7eb;\n background-color: #ffffff;\n color: #111827;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.onboarding-theme-dark .onboarding-button-social-icon {\n background-color: #374151;\n border-color: #4b5563;\n color: #ffffff;\n}\n\n.onboarding-button-social-icon:hover:not(:disabled) {\n background-color: #f9fafb;\n border-color: #d1d5db;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.onboarding-theme-dark .onboarding-button-social-icon:hover:not(:disabled) {\n background-color: #4b5563;\n border-color: #6b7280;\n}\n\n.onboarding-button-social-icon:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.onboarding-social-icon {\n width: 20px;\n height: 20px;\n color: inherit;\n fill: currentColor;\n}\n\n/* Passkey Button Styles */\n.onboarding-button-passkey {\n background-color: #374151;\n color: #ffffff;\n border: 1.5px solid #4b5563;\n font-weight: 500;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n font-size: 14px;\n}\n\n.onboarding-theme-dark .onboarding-button-passkey {\n background-color: #4b5563;\n color: #ffffff;\n border-color: #6b7280;\n}\n\n.onboarding-button-passkey:hover:not(:disabled) {\n background-color: #4b5563;\n border-color: #6b7280;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n transform: translateY(-1px);\n}\n\n.onboarding-theme-dark .onboarding-button-passkey:hover:not(:disabled) {\n background-color: #6b7280;\n border-color: #9ca3af;\n}\n\n.onboarding-passkey-icon {\n width: 20px;\n height: 20px;\n}\n\n.onboarding-passkey-signup-link {\n text-decoration: underline;\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n margin-top: 12px;\n display: block;\n text-align: center;\n transition: color 0.15s ease;\n}\n\n.onboarding-theme-light .onboarding-passkey-signup-link {\n color: #2170f5;\n}\n\n.onboarding-theme-dark .onboarding-passkey-signup-link {\n color: #2170f5;\n}\n\n.onboarding-divider {\n display: flex;\n align-items: center;\n margin: 10px 0;\n position: relative;\n}\n\n.onboarding-divider::before,\n.onboarding-divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background-color: #e5e7eb;\n}\n\n.onboarding-theme-dark .onboarding-divider::before,\n.onboarding-theme-dark .onboarding-divider::after {\n background-color: #4b5563;\n}\n\n.onboarding-divider-text {\n padding: 0 14px;\n font-size: 13px;\n color: #9ca3af;\n font-weight: 400;\n}\n\n.onboarding-theme-dark .onboarding-divider-text {\n color: #9ca3af;\n}\n\n\n.onboarding-footer {\n margin-top: 24px;\n padding: 0;\n text-align: center;\n background: transparent;\n border: none;\n border-radius: 0;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.onboarding-footer-text {\n font-size: 11px;\n color: #9ca3af;\n margin: 0;\n line-height: 1.5;\n font-weight: 400;\n letter-spacing: 0.01em;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.onboarding-theme-dark .onboarding-footer-text {\n color: #6b7280;\n}\n\n.onboarding-footer-brand {\n font-weight: 700;\n text-decoration: none;\n cursor: pointer;\n transition: opacity 0.15s ease;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.onboarding-theme-light .onboarding-footer-brand {\n color: #111827;\n}\n\n.onboarding-theme-dark .onboarding-footer-brand {\n color: #9ca3af;\n}\n\n.onboarding-footer-brand:hover {\n text-decoration: none;\n opacity: 0.8;\n}\n\n/* Modal container adjustments */\n.onboarding-modal-content .onboarding-container {\n min-height: auto;\n padding: 0;\n}\n\n.onboarding-modal-content .onboarding-card {\n margin: 0;\n}\n\n/* OTP Verification Screen */\n.onboarding-otp-verification {\n display: flex !important;\n flex-direction: column;\n align-items: center;\n text-align: center;\n width: 100%;\n visibility: visible;\n opacity: 1;\n position: relative;\n padding-top: 0;\n}\n\n.onboarding-otp-back-button {\n position: absolute;\n top: 0;\n left: 0;\n width: 40px;\n height: 40px;\n min-width: 40px;\n min-height: 40px;\n display: flex !important;\n align-items: center;\n justify-content: center;\n background-color: transparent !important;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #6b7280 !important;\n padding: 0;\n margin: 0;\n z-index: 100;\n box-shadow: none !important;\n visibility: visible !important;\n opacity: 1 !important;\n pointer-events: auto !important;\n}\n\n.onboarding-otp-back-button svg {\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n}\n\n@media (max-width: 480px) {\n .onboarding-otp-back-button {\n width: 36px;\n height: 36px;\n }\n\n .onboarding-otp-back-button svg {\n width: 18px;\n height: 18px;\n }\n}\n\n.onboarding-otp-back-button:hover:not(:disabled) {\n background-color: #f3f4f6 !important;\n color: #111827 !important;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05) !important;\n}\n\n.onboarding-otp-back-button:active:not(:disabled) {\n background-color: #e5e7eb !important;\n transform: scale(0.95);\n}\n\n.onboarding-otp-back-button:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.onboarding-theme-dark .onboarding-otp-back-button {\n background-color: transparent !important;\n color: #9ca3af !important;\n box-shadow: none !important;\n}\n\n.onboarding-theme-dark .onboarding-otp-back-button:hover:not(:disabled) {\n background-color: rgba(255, 255, 255, 0.1) !important;\n color: #ffffff !important;\n}\n\n.onboarding-theme-dark .onboarding-otp-back-button:active:not(:disabled) {\n background-color: rgba(255, 255, 255, 0.15) !important;\n}\n\n.onboarding-otp-icon-container {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n position: relative;\n background: transparent;\n border: 3px solid #eef2ff;\n}\n\n.onboarding-otp-icon-container::after {\n content: '';\n position: absolute;\n top: -3px;\n left: -3px;\n right: -3px;\n bottom: -3px;\n border-radius: 50%;\n border: 3px solid transparent;\n border-top-color: #363ff9;\n animation: onboarding-spin 2s linear infinite;\n}\n\n@keyframes onboarding-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.onboarding-theme-dark .onboarding-otp-icon-container {\n border-color: rgba(156, 163, 175, 0.2);\n}\n\n.onboarding-otp-icon-inner {\n width: 100%;\n height: 100%;\n background-color: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n}\n\n.onboarding-otp-icon {\n width: 28px;\n height: 28px;\n color: #363ff9;\n}\n\n.onboarding-otp-title {\n font-size: 22px;\n font-weight: 500;\n margin: 0 0 16px 0;\n color: inherit;\n line-height: 1.4;\n letter-spacing: -0.01em;\n}\n\n.onboarding-theme-light .onboarding-otp-title {\n color: #111827;\n}\n\n.onboarding-theme-dark .onboarding-otp-title {\n color: #ffffff;\n}\n\n.onboarding-otp-instruction {\n font-size: 14px;\n color: #6b7280;\n margin: 0 0 8px 0;\n line-height: 1.5;\n font-weight: 400;\n}\n\n.onboarding-theme-dark .onboarding-otp-instruction {\n color: #9ca3af;\n}\n\n.onboarding-otp-email {\n font-size: 15px;\n font-weight: 600;\n color: inherit;\n margin: 0 0 32px 0;\n line-height: 1.5;\n}\n\n.onboarding-theme-light .onboarding-otp-email {\n color: #111827;\n}\n\n.onboarding-theme-dark .onboarding-otp-email {\n color: #ffffff;\n}\n\n.onboarding-otp-inputs-container {\n display: flex !important;\n gap: 10px;\n justify-content: center;\n align-items: center;\n margin-bottom: 24px;\n width: 100%;\n padding: 0 10px;\n box-sizing: border-box;\n visibility: visible !important;\n opacity: 1 !important;\n min-height: 60px;\n flex-wrap: nowrap;\n}\n\n.onboarding-otp-inputs-single {\n padding: 0;\n}\n\n.onboarding-otp-verification .onboarding-form {\n width: 100%;\n margin-top: 0;\n}\n\n.onboarding-otp-verification .onboarding-button {\n /* Match OTP inputs width: 6 × 44px + 5 × 10px gap = 314px */\n width: 314px;\n max-width: 100%;\n margin-top: 0;\n margin-bottom: 0;\n margin-left: auto;\n margin-right: auto;\n}\n\n.onboarding-otp-verification .onboarding-button:disabled {\n cursor: not-allowed;\n}\n\n.onboarding-mfa-trouble-text {\n font-size: 14px;\n margin: -6px 0 16px;\n color: #6b7280;\n text-align: center;\n}\n\n.onboarding-theme-dark .onboarding-mfa-trouble-text {\n color: #9ca3af;\n}\n\n.onboarding-mfa-backup-link {\n border: none !important;\n background: transparent !important;\n padding: 0 !important;\n margin: 0;\n text-decoration: underline;\n cursor: pointer;\n font-weight: 600;\n font-size: 14px;\n font-family: inherit;\n line-height: inherit;\n box-shadow: none !important;\n outline: none;\n appearance: none;\n -webkit-appearance: none;\n}\n\n.onboarding-theme-light .onboarding-mfa-backup-link {\n color: #111827;\n}\n\n.onboarding-theme-dark .onboarding-mfa-backup-link {\n color: #e5e7eb;\n}\n\n.onboarding-mfa-backup-link:hover:not(:disabled) {\n opacity: 0.8;\n}\n\n.onboarding-mfa-backup-link:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.onboarding-mfa-backup-input {\n text-transform: uppercase;\n}\n\n.onboarding-mfa-backup-field {\n width: 100%;\n max-width: 320px;\n height: 52px;\n border: 1.5px solid #e5e7eb;\n border-radius: 8px;\n background-color: inherit;\n color: inherit;\n text-align: center;\n font-size: 18px;\n font-weight: 600;\n letter-spacing: 0.16em;\n padding: 0 14px;\n box-sizing: border-box;\n text-transform: uppercase;\n transition: all 0.15s ease;\n}\n\n.onboarding-theme-light .onboarding-mfa-backup-field {\n background-color: #ffffff;\n border-color: #e5e7eb;\n color: #000000;\n}\n\n.onboarding-theme-light .onboarding-mfa-backup-field:focus {\n outline: none;\n border-color: #111827;\n box-shadow: 0 0 0 3px rgba(17, 24, 39, 0.1);\n}\n\n.onboarding-theme-dark .onboarding-mfa-backup-field {\n border-color: #4b5563;\n background-color: #374151;\n color: #ffffff;\n}\n\n.onboarding-theme-dark .onboarding-mfa-backup-field:focus {\n outline: none;\n border-color: #9ca3af;\n box-shadow: 0 0 0 3px rgba(156, 163, 175, 0.2);\n background-color: #4b5563;\n}\n\n.onboarding-mfa-backup-field:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.onboarding-mfa-backup-example {\n margin: -6px 0 16px;\n font-size: 13px;\n color: #9ca3af;\n}\n\n.onboarding-otp-input {\n width: 44px !important;\n min-width: 44px !important;\n height: 52px !important;\n min-height: 52px !important;\n display: inline-block !important;\n visibility: visible !important;\n opacity: 1 !important;\n text-align: center;\n font-size: 20px;\n font-weight: 600;\n border: 1.5px solid #e5e7eb;\n border-radius: 8px;\n background-color: inherit;\n color: inherit;\n transition: all 0.15s ease;\n box-sizing: border-box;\n line-height: 1;\n flex-shrink: 0;\n padding: 0;\n margin: 0;\n}\n\n.onboarding-theme-light .onboarding-otp-input {\n background-color: #ffffff !important;\n border-color: #e5e7eb !important;\n color: #000000 !important;\n}\n\n.onboarding-otp-input:focus {\n outline: none;\n}\n\n.onboarding-theme-light .onboarding-otp-input:focus {\n border-color: #111827 !important;\n box-shadow: 0 0 0 3px rgba(17, 24, 39, 0.1) !important;\n background-color: #ffffff !important;\n color: #000000 !important;\n}\n\n.onboarding-theme-dark .onboarding-otp-input {\n border-color: #4b5563 !important;\n background-color: #374151 !important;\n color: #ffffff !important;\n}\n\n.onboarding-theme-dark .onboarding-otp-input:focus {\n border-color: #9ca3af !important;\n box-shadow: 0 0 0 3px rgba(156, 163, 175, 0.2) !important;\n background-color: #4b5563 !important;\n color: #ffffff !important;\n}\n\n.onboarding-otp-input:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.onboarding-otp-resend {\n text-align: center;\n margin-top: 24px;\n line-height: 1.5;\n}\n\n.onboarding-otp-resend-text {\n font-size: 13px;\n color: #6b7280;\n margin: 0;\n line-height: 1.5;\n font-weight: 400;\n}\n\n.onboarding-theme-dark .onboarding-otp-resend-text {\n color: #9ca3af;\n}\n\n.onboarding-otp-resend-link {\n color: #dc2626;\n text-decoration: underline;\n cursor: pointer;\n font-weight: 500;\n transition: color 0.15s ease;\n font-size: 13px;\n background: none;\n border: none;\n padding: 0;\n margin: 0;\n font-family: inherit;\n}\n\n.onboarding-otp-resend-link:hover {\n color: #b91c1c;\n text-decoration: underline;\n}\n\n.onboarding-otp-resend-link:active {\n color: #991b1b;\n}\n\n.onboarding-theme-dark .onboarding-otp-resend-link {\n color: #ef4444;\n}\n\n.onboarding-theme-dark .onboarding-otp-resend-link:hover {\n color: #dc2626;\n}\n\n.onboarding-otp-resend-cooldown {\n color: #9ca3af;\n font-size: 13px;\n}\n\n.onboarding-theme-dark .onboarding-otp-resend-cooldown {\n color: #6b7280;\n}\n\n.onboarding-otp-verification .onboarding-error {\n margin-bottom: 24px;\n margin-top: 0;\n text-align: center;\n}\n\n/* Additional Responsive Styles */\n@media (max-width: 480px) {\n .onboarding-container {\n padding: 12px;\n }\n\n .onboarding-card {\n padding: 24px 20px;\n }\n\n .onboarding-title {\n font-size: 24px;\n }\n\n .onboarding-input-group {\n margin-bottom: 16px;\n }\n\n .onboarding-button {\n width: 100%;\n padding: 14px 20px;\n }\n\n .onboarding-social-grid {\n grid-template-columns: 1fr;\n gap: 12px;\n }\n\n .onboarding-button-social-icon {\n width: 100%;\n justify-content: center;\n }\n\n .onboarding-otp-inputs-container {\n gap: 8px;\n }\n\n .onboarding-otp-verification .onboarding-button {\n /* 6 × 44px + 5 × 8px gap = 304px */\n width: 304px;\n }\n\n .onboarding-otp-input {\n width: 44px;\n min-width: 44px;\n height: 56px;\n min-height: 56px;\n font-size: 20px;\n }\n\n .onboarding-footer-text {\n font-size: 10px;\n }\n\n .onboarding-footer-brand {\n font-size: 10px;\n }\n\n .onboarding-footer-brand svg {\n width: 16px;\n height: 16px;\n }\n}\n\n@media (max-width: 360px) {\n .onboarding-card {\n padding: 20px 16px;\n }\n\n .onboarding-title {\n font-size: 22px;\n }\n\n .onboarding-otp-input {\n width: 40px;\n min-width: 40px;\n height: 56px;\n min-height: 56px;\n font-size: 18px;\n }\n}\n\n";
|
|
@@ -12,9 +12,13 @@ import { MfaForm } from "./components/MfaForm";
|
|
|
12
12
|
import { SocialButtons } from "./components/SocialButtons";
|
|
13
13
|
import { PasskeyButton } from "./components/PasskeyButton";
|
|
14
14
|
import { Modal } from "./components/Modal";
|
|
15
|
-
import {
|
|
15
|
+
import { Divider } from "./components/Divider";
|
|
16
|
+
import { ExternalWalletButtons, externalWalletButtonsCss } from "../../ExternalWalletButtons";
|
|
16
17
|
import { useAbstraxnWallet } from "../../hooks";
|
|
17
|
-
import "
|
|
18
|
+
import { ShadowHost } from "../ShadowHost";
|
|
19
|
+
import { AbstraxnLogo } from "../AbstraxnLogo";
|
|
20
|
+
import onboardingUiCss from "./OnboardingUI.css.js";
|
|
21
|
+
const ONBOARDING_UI_REACT_CSS_TEXTS = [onboardingUiCss, externalWalletButtonsCss];
|
|
18
22
|
export const OnboardingUIReact = ({ config = {}, modal = false, onClose, externalWalletsEnabled = false, availableConnectors = [], }) => {
|
|
19
23
|
const normalizeErrorMessage = (message) => {
|
|
20
24
|
let trimmed = message.trim();
|
|
@@ -109,9 +113,24 @@ export const OnboardingUIReact = ({ config = {}, modal = false, onClose, externa
|
|
|
109
113
|
const hasUserData = user && (user.id || user.email);
|
|
110
114
|
const isAlreadyAuthenticated = hasWhoamiData || hasUserData || isConnected;
|
|
111
115
|
// Process OAuth callbacks - show loading modal for OAuth flows (skip when MFA required; show MFA screen instead)
|
|
112
|
-
|
|
116
|
+
// Gated on isOAuthCallback (derived from URL params) alone, NOT oauthPending -
|
|
117
|
+
// that localStorage flag is also read-and-cleared by AbstraxnProviderInner.tsx's
|
|
118
|
+
// and useOAuthCallbacks.ts's own callback handlers; whichever of those runs first
|
|
119
|
+
// clears it, so relying on it here raced against them and could silently skip
|
|
120
|
+
// showing the loading modal even on a genuinely successful login.
|
|
121
|
+
console.log("[OnboardingUIReact] OAuth callback check:", { isOAuthCallback, oauthPending, success, isAlreadyAuthenticated, mfaRequired, error });
|
|
122
|
+
if (isOAuthCallback) {
|
|
113
123
|
if (success === "true" && !isAlreadyAuthenticated && !mfaRequired) {
|
|
114
|
-
// Set OAuth loading modal for OAuth callbacks
|
|
124
|
+
// Set OAuth loading modal for OAuth callbacks.
|
|
125
|
+
// The modal only renders when `!isInOtpFlow` (i.e. onboarding.step isn't
|
|
126
|
+
// "email"/"otp") - but a fresh page load after the OAuth redirect always
|
|
127
|
+
// starts step at its default "email", and nothing was moving it off that
|
|
128
|
+
// for the OAuth path (only the OTP-verification flow ever called
|
|
129
|
+
// setStep('loading')). So oauthLoading could be true while the modal still
|
|
130
|
+
// never rendered. isOtpLoadingStep already disambiguates step === "loading"
|
|
131
|
+
// caused by OAuth vs OTP via isOAuthCallback, confirming "loading" is the
|
|
132
|
+
// intended step value here.
|
|
133
|
+
onboarding.setStep("loading");
|
|
115
134
|
setOauthLoading(true);
|
|
116
135
|
setOauthError(null);
|
|
117
136
|
}
|
|
@@ -133,7 +152,7 @@ export const OnboardingUIReact = ({ config = {}, modal = false, onClose, externa
|
|
|
133
152
|
setOauthLoading(false);
|
|
134
153
|
}
|
|
135
154
|
// Also handle config.handleUrlParams if provided (only for OAuth)
|
|
136
|
-
if (config.handleUrlParams && isOAuthCallback
|
|
155
|
+
if (config.handleUrlParams && isOAuthCallback) {
|
|
137
156
|
if (success === "true" && !isAlreadyAuthenticated && !mfaRequired) {
|
|
138
157
|
onboarding.setLoading(true);
|
|
139
158
|
}
|
|
@@ -275,11 +294,11 @@ export const OnboardingUIReact = ({ config = {}, modal = false, onClose, externa
|
|
|
275
294
|
onClose?.();
|
|
276
295
|
};
|
|
277
296
|
// Helper to render modal content with header and footer
|
|
278
|
-
const renderModalContent = (children) => (_jsx("div", { className: `onboarding-container onboarding-theme-${theme} ${config.className || ""}`, children: _jsxs("div", { className: "onboarding-card", children: [_jsxs("div", { className: "onboarding-header", children: [config.logo && (_jsx("div", { className: "onboarding-logo-section", children: _jsx("div", { className: "onboarding-logo-container", children: _jsx("img", { src: config.logo, alt: "Logo", className: "onboarding-logo-img" }) }) })), _jsx("h1", { className: "onboarding-title", id: "onboarding-title", children: config.onboardTitle || "Sign In" })] }), children, config.showFooter !== false && (_jsx("div", { className: "onboarding-footer", children: _jsxs("p", { className: "onboarding-footer-text", children: ["Powered by", " ", _jsxs("a", { href: "https://abstraxn.com", target: "_blank", rel: "noopener noreferrer", className: "onboarding-footer-brand", style: {
|
|
297
|
+
const renderModalContent = (children) => (_jsx("div", { className: `onboarding-container onboarding-theme-${theme} ${config.className || ""}`, part: "container", children: _jsxs("div", { className: "onboarding-card", part: "card", children: [_jsxs("div", { className: "onboarding-header", children: [config.logo && (_jsx("div", { className: "onboarding-logo-section", children: _jsx("div", { className: "onboarding-logo-container", children: _jsx("img", { src: config.logo, alt: "Logo", className: "onboarding-logo-img" }) }) })), _jsx("h1", { className: "onboarding-title", id: "onboarding-title", children: config.onboardTitle || "Sign In" })] }), children, config.showFooter !== false && (_jsx("div", { className: "onboarding-footer", children: _jsxs("p", { className: "onboarding-footer-text", children: ["Powered by", " ", _jsxs("a", { href: "https://abstraxn.com", target: "_blank", rel: "noopener noreferrer", className: "onboarding-footer-brand", style: {
|
|
279
298
|
display: "inline-flex",
|
|
280
299
|
alignItems: "center",
|
|
281
300
|
gap: "6px",
|
|
282
|
-
}, children: [
|
|
301
|
+
}, children: [_jsx(AbstraxnLogo, { size: 20, gradientId: "abstraxn_logo_oauth_footer" }), _jsx("span", { children: "abstraxn" })] })] }) }))] }) }));
|
|
283
302
|
const showEmailForm = onboarding.step === "email" &&
|
|
284
303
|
authMethods.includes("otp") &&
|
|
285
304
|
!showExternalWallets;
|
|
@@ -296,36 +315,44 @@ export const OnboardingUIReact = ({ config = {}, modal = false, onClose, externa
|
|
|
296
315
|
const showExternalWalletsSection = onboarding.step === "email" &&
|
|
297
316
|
externalWalletsEnabled &&
|
|
298
317
|
availableConnectors.length > 0;
|
|
299
|
-
const content = (_jsx("div", { className: `onboarding-container onboarding-theme-${theme} ${config.className || ""}
|
|
318
|
+
const content = (_jsx("div", { className: `onboarding-container onboarding-theme-${theme}${modal ? "" : " onboarding-inline"} ${config.className || ""}`.trim(), part: "container", children: _jsxs("div", { className: `onboarding-card ${showOtpForm ? "onboarding-card-otp" : ""} ${showMfaForm ? "onboarding-card-mfa" : ""}`, part: "card", children: [!showOtpForm && !showMfaForm && (_jsxs("div", { className: "onboarding-header", children: [config.logo && (_jsx("div", { className: "onboarding-logo-section", children: _jsx("div", { className: "onboarding-logo-container", children: _jsx("img", { src: config.logo, alt: "Logo", className: "onboarding-logo-img" }) }) })), _jsx("h1", { className: "onboarding-title", id: "onboarding-title", children: config.onboardTitle || "Sign In" })] })), showEmailForm && (_jsx(EmailForm, { email: onboarding.email, onChange: onboarding.setEmail, onSubmit: onboarding.handleEmailSubmit, loading: onboarding.loading, error: onboarding.error, config: config, readOnly: !!emailForOtp })), showOtpForm && (_jsx(OtpForm, { email: onboarding.email, otp: onboarding.otp, onChange: onboarding.setOtp, onSubmit: onboarding.handleOtpSubmit, onResend: onboarding.handleResendOtp, onBack: onboarding.reset, loading: onboarding.loading, resending: onboarding.resending, requireManualVerify: onboarding.requireManualVerify, error: onboarding.error, resendCooldown: onboarding.resendCooldown, config: config })), showMfaForm && (_jsx(MfaForm, { code: onboarding.mfaCode, onChange: onboarding.setMfaCode, onSubmit: onboarding.handleMfaSubmit, onBack: onboarding.otpId
|
|
300
319
|
? () => onboarding.setStep("otp")
|
|
301
|
-
: () => onboarding.reset(), loading: onboarding.loading, error: onboarding.error, config: config })), onboarding.step === "error" && onboarding.error && (_jsxs("div", { className: "onboarding-error-container", children: [_jsx("div", { className: "onboarding-error", role: "alert", children: normalizeErrorMessage(onboarding.error) }), _jsx("button", { type: "button", className: "onboarding-button onboarding-button-primary", onClick: onboarding.reset, children: "Try Again" })] })), showSocialButtons && (showEmailForm || showOtpForm) &&
|
|
320
|
+
: () => onboarding.reset(), loading: onboarding.loading, error: onboarding.error, config: config })), onboarding.step === "error" && onboarding.error && (_jsxs("div", { className: "onboarding-error-container", children: [_jsx("div", { className: "onboarding-error", role: "alert", children: normalizeErrorMessage(onboarding.error) }), _jsx("button", { type: "button", className: "onboarding-button onboarding-button-primary", part: "button-primary", onClick: onboarding.reset, children: "Try Again" })] })), showSocialButtons && (showEmailForm || showOtpForm) && _jsx(Divider, {}), showSocialButtons && (_jsx(SocialButtons, { onGoogleLogin: authMethodsHook.handleGoogleLogin, onTwitterLogin: authMethodsHook.handleTwitterLogin, onDiscordLogin: authMethodsHook.handleDiscordLogin, loading: authMethodsHook.loading, config: config })), showPasskey && (_jsx(PasskeyButton, { onPasskeyLogin: authMethodsHook.handlePasskeyLogin, onPasskeySignup: authMethodsHook.handlePasskeySignup, loading: authMethodsHook.loading, config: config })), showExternalWalletsSection && (_jsxs(_Fragment, { children: [!showExternalWallets && _jsx(Divider, {}), _jsx("div", { style: { marginTop: showExternalWallets ? "0" : "12px" }, children: _jsx(ExternalWalletButtons, { onShowMoreWallets: () => setShowExternalWallets(true), onHideMoreWallets: () => setShowExternalWallets(false) }) })] })), config.showFooter !== false && (_jsx("div", { className: "onboarding-footer", children: _jsxs("p", { className: "onboarding-footer-text", children: ["Powered by", " ", _jsxs("a", { href: "https://abstraxn.com", target: "_blank", rel: "noopener noreferrer", className: "onboarding-footer-brand", style: {
|
|
302
321
|
display: "inline-flex",
|
|
303
322
|
alignItems: "center",
|
|
304
323
|
gap: "6px",
|
|
305
|
-
}, children: [
|
|
324
|
+
}, children: [_jsx(AbstraxnLogo, { size: 20, gradientId: "abstraxn_logo_main_footer" }), _jsx("span", { children: "abstraxn" })] })] }) }))] }) }));
|
|
306
325
|
// OAuth Loading Modal (only show for OAuth flows, never during OTP flow)
|
|
307
326
|
// Check if we're in OTP flow - only email and otp steps, not loading (loading can be OAuth too)
|
|
308
327
|
const isInOtpFlow = onboarding.step === "email" || onboarding.step === "otp";
|
|
309
328
|
// Show OAuth loading modal if oauthLoading is true and not in OTP flow
|
|
329
|
+
//
|
|
330
|
+
// Collapsed from an early-return chain into a single `result` variable so
|
|
331
|
+
// exactly one ShadowHost wrap can be applied at the bottom — same branches,
|
|
332
|
+
// same priority order, just deferred to one final return.
|
|
333
|
+
let result;
|
|
310
334
|
if (oauthLoading && !isInOtpFlow) {
|
|
311
|
-
|
|
335
|
+
result = (_jsx(Modal, { isOpen: true, onClose: () => {
|
|
312
336
|
setOauthLoading(false);
|
|
313
337
|
clearQueryParams();
|
|
314
|
-
}, closeOnBackdropClick: config.closeOnBackdropClick !== false, showCloseButton: showModalCloseButton, theme: theme, children: renderModalContent(_jsxs("div", { className: "onboarding-loading", style: { textAlign: "center", padding: "40px" }, children: [_jsxs("svg", { width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: {
|
|
338
|
+
}, closeOnBackdropClick: config.closeOnBackdropClick !== false, showCloseButton: showModalCloseButton, theme: theme, children: renderModalContent(_jsxs("div", { className: "onboarding-loading", style: { textAlign: "center", padding: "40px" }, children: [_jsxs("svg", { className: "onboarding-button-spinner", width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", style: { width: 48, height: 48 }, children: [_jsx("line", { x1: "12", y1: "2", x2: "12", y2: "6" }), _jsx("line", { x1: "12", y1: "18", x2: "12", y2: "22" }), _jsx("line", { x1: "4.93", y1: "4.93", x2: "7.76", y2: "7.76" }), _jsx("line", { x1: "16.24", y1: "16.24", x2: "19.07", y2: "19.07" }), _jsx("line", { x1: "2", y1: "12", x2: "6", y2: "12" }), _jsx("line", { x1: "18", y1: "12", x2: "22", y2: "12" }), _jsx("line", { x1: "4.93", y1: "19.07", x2: "7.76", y2: "16.24" }), _jsx("line", { x1: "16.24", y1: "7.76", x2: "19.07", y2: "4.93" })] }), _jsx("p", { style: { marginTop: "16px" }, children: "Authenticating..." })] })) }));
|
|
315
339
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
340
|
+
else if (oauthError) {
|
|
341
|
+
// OAuth Error Modal
|
|
342
|
+
result = (_jsx(Modal, { isOpen: true, onClose: () => {
|
|
319
343
|
setOauthError(null);
|
|
320
344
|
clearQueryParams();
|
|
321
|
-
}, closeOnBackdropClick: config.closeOnBackdropClick !== false, showCloseButton: showModalCloseButton, theme: theme, children: renderModalContent(_jsxs("div", { className: "onboarding-error-container", style: { padding: "40px", textAlign: "center" }, children: [_jsx("div", { className: "onboarding-error", role: "alert", children: normalizeErrorMessage(oauthError) }), _jsx("button", { type: "button", className: "onboarding-button onboarding-button-primary", onClick: () => {
|
|
345
|
+
}, closeOnBackdropClick: config.closeOnBackdropClick !== false, showCloseButton: showModalCloseButton, theme: theme, children: renderModalContent(_jsxs("div", { className: "onboarding-error-container", style: { padding: "40px", textAlign: "center" }, children: [_jsx("div", { className: "onboarding-error", role: "alert", children: normalizeErrorMessage(oauthError) }), _jsx("button", { type: "button", className: "onboarding-button onboarding-button-primary", part: "button-primary", onClick: () => {
|
|
322
346
|
setOauthError(null);
|
|
323
347
|
clearQueryParams();
|
|
324
348
|
}, style: { marginTop: "24px" }, children: "Close" })] })) }));
|
|
325
349
|
}
|
|
326
|
-
if (modal) {
|
|
327
|
-
|
|
350
|
+
else if (modal) {
|
|
351
|
+
result = (_jsx(Modal, { isOpen: true, onClose: handleClose, closeOnBackdropClick: config.closeOnBackdropClick !== false, showCloseButton: showModalCloseButton, theme: theme, children: content }));
|
|
328
352
|
}
|
|
329
|
-
|
|
353
|
+
else {
|
|
354
|
+
result = content;
|
|
355
|
+
}
|
|
356
|
+
return (_jsx(ShadowHost, { cssTexts: ONBOARDING_UI_REACT_CSS_TEXTS, customCSS: config.customCSS, children: result }));
|
|
330
357
|
};
|
|
331
358
|
//# sourceMappingURL=OnboardingUIReact.js.map
|
|
@@ -6,7 +6,11 @@ import type { OnboardingUIConfig, Theme } from "@abstraxn/signer-core";
|
|
|
6
6
|
* Works with vanilla JavaScript - no framework dependencies required.
|
|
7
7
|
*/
|
|
8
8
|
export declare class OnboardingUIWeb {
|
|
9
|
-
private
|
|
9
|
+
private stylesInjected;
|
|
10
|
+
private shadowContainer;
|
|
11
|
+
private shadowTeardown;
|
|
12
|
+
/** Pending OAuth loader timer from checkUrlParams — cleared in destroy() so StrictMode cleanup cannot paint into a torn-down shadow root. */
|
|
13
|
+
private pendingLoadingModalTimer;
|
|
10
14
|
private config;
|
|
11
15
|
private container;
|
|
12
16
|
private rootElement;
|
|
@@ -55,6 +59,13 @@ export declare class OnboardingUIWeb {
|
|
|
55
59
|
* Call this before init() to prevent flicker when external wallets are enabled
|
|
56
60
|
*/
|
|
57
61
|
showExternalWallets(): void;
|
|
62
|
+
/** True when this instance still owns an attached shadow container. */
|
|
63
|
+
hasLiveShadow(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Rebuild the shadow tree if destroy()/StrictMode tore it down.
|
|
66
|
+
* Safe to call before showLoadingModal / showOnboarding recovery paths.
|
|
67
|
+
*/
|
|
68
|
+
ensureLiveShadow(): void;
|
|
58
69
|
/**
|
|
59
70
|
* Initialize and render the component
|
|
60
71
|
*/
|
|
@@ -92,6 +103,18 @@ export declare class OnboardingUIWeb {
|
|
|
92
103
|
* Inject CSS styles into the document head (only once)
|
|
93
104
|
*/
|
|
94
105
|
private injectStyles;
|
|
106
|
+
/**
|
|
107
|
+
* Build a divider element (line + "or" text) matching `.onboarding-divider`
|
|
108
|
+
*/
|
|
109
|
+
private createDividerElement;
|
|
110
|
+
/**
|
|
111
|
+
* Footer text/brand colors, derived from config.colors.text with theme-based fallbacks
|
|
112
|
+
*/
|
|
113
|
+
private getFooterTextColors;
|
|
114
|
+
/**
|
|
115
|
+
* Passkey button colors, derived from config.colors with theme-based fallbacks
|
|
116
|
+
*/
|
|
117
|
+
private getPasskeyButtonColors;
|
|
95
118
|
/**
|
|
96
119
|
* Apply custom colors from config
|
|
97
120
|
*/
|