@loafmarkets/ui 0.1.349 → 0.1.351

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/index.d.mts CHANGED
@@ -586,6 +586,8 @@ type LoginPopupProps = {
586
586
  onSubmitReferralCode?: (code: string) => Promise<void> | void;
587
587
  /** Handler invoked when the user selects "Sign in with Wallet". */
588
588
  onWalletLogin?: () => Promise<void> | void;
589
+ /** Handler invoked when the user selects "Sign in with Passkey". When omitted, the button is hidden. */
590
+ onPasskeyLogin?: () => Promise<void> | void;
589
591
  /** Current KYC status — used to show "Resume Verification" when previously started. */
590
592
  kycStatus?: 'NOT_STARTED' | 'PENDING' | 'ON_HOLD' | 'VERIFIED' | 'REJECTED';
591
593
  };
@@ -982,8 +984,9 @@ type ToastContextValue = {
982
984
  update: (id: string, patch: Partial<Omit<ToastData, 'id'>>) => void;
983
985
  dismiss: (id: string) => void;
984
986
  };
985
- declare function ToastProvider({ children }: {
987
+ declare function ToastProvider({ children, maxVisible }: {
986
988
  children: React__default.ReactNode;
989
+ maxVisible?: number;
987
990
  }): react_jsx_runtime.JSX.Element;
988
991
  declare function useToast(): ToastContextValue;
989
992
 
package/dist/index.d.ts CHANGED
@@ -586,6 +586,8 @@ type LoginPopupProps = {
586
586
  onSubmitReferralCode?: (code: string) => Promise<void> | void;
587
587
  /** Handler invoked when the user selects "Sign in with Wallet". */
588
588
  onWalletLogin?: () => Promise<void> | void;
589
+ /** Handler invoked when the user selects "Sign in with Passkey". When omitted, the button is hidden. */
590
+ onPasskeyLogin?: () => Promise<void> | void;
589
591
  /** Current KYC status — used to show "Resume Verification" when previously started. */
590
592
  kycStatus?: 'NOT_STARTED' | 'PENDING' | 'ON_HOLD' | 'VERIFIED' | 'REJECTED';
591
593
  };
@@ -982,8 +984,9 @@ type ToastContextValue = {
982
984
  update: (id: string, patch: Partial<Omit<ToastData, 'id'>>) => void;
983
985
  dismiss: (id: string) => void;
984
986
  };
985
- declare function ToastProvider({ children }: {
987
+ declare function ToastProvider({ children, maxVisible }: {
986
988
  children: React__default.ReactNode;
989
+ maxVisible?: number;
987
990
  }): react_jsx_runtime.JSX.Element;
988
991
  declare function useToast(): ToastContextValue;
989
992
 
package/dist/index.js CHANGED
@@ -6445,6 +6445,7 @@ var LoginPopup = ({
6445
6445
  onClose,
6446
6446
  onOpenEarlyAccess,
6447
6447
  onWalletLogin,
6448
+ onPasskeyLogin,
6448
6449
  isAuthenticated,
6449
6450
  currentUser,
6450
6451
  onSendEmailCode,
@@ -6555,6 +6556,20 @@ var LoginPopup = ({
6555
6556
  onOpenEarlyAccess();
6556
6557
  }
6557
6558
  };
6559
+ const handlePasskeyLogin = async () => {
6560
+ if (!onPasskeyLogin) return;
6561
+ setError("");
6562
+ setLoading(true);
6563
+ try {
6564
+ await onPasskeyLogin();
6565
+ onClose();
6566
+ } catch (err) {
6567
+ const message = err instanceof Error ? err.message : "Passkey sign-in failed";
6568
+ setError(message);
6569
+ } finally {
6570
+ setLoading(false);
6571
+ }
6572
+ };
6558
6573
  const handleEmailClick = (signUp = false) => {
6559
6574
  setIsSignUp(signUp);
6560
6575
  setView("email");
@@ -6689,7 +6704,11 @@ var LoginPopup = ({
6689
6704
  try {
6690
6705
  await onVerifyEmailCode({ code, email });
6691
6706
  if (isSignUp) {
6692
- setView(onSubmitReferralCode ? "referral" : "funding");
6707
+ if (onSubmitReferralCode) {
6708
+ setView("referral");
6709
+ } else {
6710
+ onClose();
6711
+ }
6693
6712
  setLoading(false);
6694
6713
  return;
6695
6714
  }
@@ -6812,6 +6831,10 @@ var LoginPopup = ({
6812
6831
  /* @__PURE__ */ jsxRuntime.jsxs(LoginButton, { onClick: handleWalletLogin, children: [
6813
6832
  /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" }) }),
6814
6833
  "Sign in with Wallet"
6834
+ ] }),
6835
+ onPasskeyLogin && /* @__PURE__ */ jsxRuntime.jsxs(LoginButton, { onClick: handlePasskeyLogin, disabled: loading, children: [
6836
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C9.79 2 8 3.79 8 6v4H6c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-8c0-1.1-.9-2-2-2h-2V6c0-2.21-1.79-4-4-4zm-2 4c0-1.1.9-2 2-2s2 .9 2 2v4h-4V6zm2 9a2 2 0 100 4 2 2 0 000-4z" }) }),
6837
+ "Sign in with Passkey"
6815
6838
  ] })
6816
6839
  ] }),
6817
6840
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", marginTop: "0.5rem", marginBottom: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -6898,7 +6921,8 @@ var LoginPopup = ({
6898
6921
  loading ? /* @__PURE__ */ jsxRuntime.jsxs(AccountCreationLoader, { children: [
6899
6922
  /* @__PURE__ */ jsxRuntime.jsx(SpinnerRing, {}),
6900
6923
  /* @__PURE__ */ jsxRuntime.jsx(AccountCreationText, { children: isSignUp ? "Preparing your account\u2026" : "Signing you in\u2026" }),
6901
- /* @__PURE__ */ jsxRuntime.jsx(AccountCreationSubtext, { children: "This may take a few seconds" })
6924
+ /* @__PURE__ */ jsxRuntime.jsx(AccountCreationSubtext, { children: "This may take a few seconds" }),
6925
+ /* @__PURE__ */ jsxRuntime.jsx(PreparingFacts, {})
6902
6926
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6903
6927
  /* @__PURE__ */ jsxRuntime.jsxs(BackButton, { onClick: () => setView("email"), children: [
6904
6928
  /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" }) }),
@@ -7101,7 +7125,7 @@ var LoginPopup = ({
7101
7125
  setReferralLoading(true);
7102
7126
  try {
7103
7127
  await onSubmitReferralCode?.(trimmed);
7104
- setView("funding");
7128
+ onClose();
7105
7129
  } catch (err) {
7106
7130
  setReferralError(err instanceof Error ? err.message : "Invalid referral code. Please try again.");
7107
7131
  } finally {
@@ -7128,7 +7152,7 @@ var LoginPopup = ({
7128
7152
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })
7129
7153
  ] }) }),
7130
7154
  /* @__PURE__ */ jsxRuntime.jsx(OnboardingHeading, { children: "Do you have a referral code?" }),
7131
- /* @__PURE__ */ jsxRuntime.jsx(OnboardingSubtext, { style: { marginBottom: "1.5rem" }, children: "Enter your code to unlock full access, or skip to continue." }),
7155
+ /* @__PURE__ */ jsxRuntime.jsx(OnboardingSubtext, { style: { marginBottom: "1.5rem" }, children: "Enter your code to unlock $100k in testnet USD, or skip to continue." }),
7132
7156
  /* @__PURE__ */ jsxRuntime.jsxs(EmailFormContainer, { style: { width: "100%", marginBottom: 0 }, children: [
7133
7157
  /* @__PURE__ */ jsxRuntime.jsx(
7134
7158
  EmailInput,
@@ -7161,7 +7185,7 @@ var LoginPopup = ({
7161
7185
  OnboardingSkipButton,
7162
7186
  {
7163
7187
  type: "button",
7164
- onClick: () => setView("funding"),
7188
+ onClick: onClose,
7165
7189
  style: { marginTop: "0.75rem" },
7166
7190
  children: "Skip for now"
7167
7191
  }
@@ -8003,6 +8027,59 @@ var SpinnerRing = styled9__default.default.div`
8003
8027
  to { transform: rotate(360deg); }
8004
8028
  }
8005
8029
  `;
8030
+ var PREPARING_FACTS = [
8031
+ "Property is the world's largest asset class \u2014 worth over US$300 trillion.",
8032
+ "Loaf settles trades in about 1 second. Traditional property takes ~90 days.",
8033
+ "Our matching engine processes orders in 30 microseconds.",
8034
+ "Every token is backed 1:1 by land-title-registered property.",
8035
+ "Own a slice of premium real estate \u2014 no mortgage, no paperwork.",
8036
+ "Buy and sell property as easily as a stock, on a live orderbook.",
8037
+ "Earn rental yield on the exact fraction of property you own.",
8038
+ "Title-backed by the NSW Land Registry \u2014 real ownership, on-chain.",
8039
+ "Loaf ran the world's first property IPO."
8040
+ ];
8041
+ var FactCard = styled9__default.default.div`
8042
+ margin-top: 1.5rem;
8043
+ max-width: 340px;
8044
+ padding: 0.85rem 1.1rem;
8045
+ border: 1px solid rgba(230, 198, 86, 0.18);
8046
+ border-radius: 12px;
8047
+ background: rgba(230, 198, 86, 0.05);
8048
+ text-align: center;
8049
+ `;
8050
+ var FactLabel = styled9__default.default.div`
8051
+ font-size: 0.6rem;
8052
+ letter-spacing: 0.12em;
8053
+ text-transform: uppercase;
8054
+ font-weight: 700;
8055
+ color: var(--color-accent, #e6c656);
8056
+ margin-bottom: 0.4rem;
8057
+ `;
8058
+ var FactText = styled9__default.default.p`
8059
+ margin: 0;
8060
+ font-size: 0.85rem;
8061
+ line-height: 1.5;
8062
+ color: var(--color-text, #eaecef);
8063
+ animation: factFade 0.5s ease;
8064
+
8065
+ @keyframes factFade {
8066
+ from { opacity: 0; transform: translateY(4px); }
8067
+ to { opacity: 1; transform: translateY(0); }
8068
+ }
8069
+ `;
8070
+ var PreparingFacts = () => {
8071
+ const [index, setIndex] = React5.useState(() => Math.floor(Math.random() * PREPARING_FACTS.length));
8072
+ React5.useEffect(() => {
8073
+ const id = setInterval(() => {
8074
+ setIndex((i) => (i + 1) % PREPARING_FACTS.length);
8075
+ }, 4e3);
8076
+ return () => clearInterval(id);
8077
+ }, []);
8078
+ return /* @__PURE__ */ jsxRuntime.jsxs(FactCard, { children: [
8079
+ /* @__PURE__ */ jsxRuntime.jsx(FactLabel, { children: "Did you know?" }),
8080
+ /* @__PURE__ */ jsxRuntime.jsx(FactText, { children: PREPARING_FACTS[index] }, index)
8081
+ ] });
8082
+ };
8006
8083
  LoginPopup.displayName = "LoginPopup";
8007
8084
  var PropertyCompareBar = React5__namespace.forwardRef(
8008
8085
  ({
@@ -18080,13 +18157,16 @@ function ToastItem({ toast, onDismiss }) {
18080
18157
  ] });
18081
18158
  }
18082
18159
  var ToastContext = React5.createContext(null);
18083
- function ToastProvider({ children }) {
18160
+ function ToastProvider({ children, maxVisible }) {
18084
18161
  const [toasts, setToasts] = React5.useState([]);
18085
18162
  const addToast = React5.useCallback((data) => {
18086
18163
  const id = `toast-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
18087
- setToasts((prev) => [...prev, { ...data, id }]);
18164
+ setToasts((prev) => {
18165
+ const next = [...prev, { ...data, id }];
18166
+ return maxVisible && next.length > maxVisible ? next.slice(next.length - maxVisible) : next;
18167
+ });
18088
18168
  return id;
18089
- }, []);
18169
+ }, [maxVisible]);
18090
18170
  const update = React5.useCallback((id, patch) => {
18091
18171
  setToasts((prev) => prev.map((t) => t.id === id ? { ...t, ...patch } : t));
18092
18172
  }, []);