@unseen_fi/ui 0.1.1 → 0.1.2

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.
@@ -1,16 +1,2 @@
1
1
  import type { UnseenPayButtonProps } from "./types";
2
- /**
3
- * A drop-in "Pay with Unseen" button that opens a checkout modal.
4
- * The modal shows wallet picker, QR code / deeplinks, and "I have paid" confirmation.
5
- *
6
- * @example
7
- * ```tsx
8
- * <UnseenPayButton
9
- * amount={50_000_000}
10
- * reference="order_123"
11
- * description="Premium Plan"
12
- * onSuccess={(p) => console.log("Paid!", p.id)}
13
- * />
14
- * ```
15
- */
16
2
  export declare function UnseenPayButton({ amount, mint, reference, description, expiresIn, onSuccess, onError, onCreated, createPaymentSession, label, className, disabled, }: UnseenPayButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -7,20 +7,6 @@ const context_1 = require("./context");
7
7
  const hooks_1 = require("./hooks");
8
8
  const wallets_1 = require("./wallets");
9
9
  // ─── UnseenPayButton ─────────────────────────────────────────────────────────
10
- /**
11
- * A drop-in "Pay with Unseen" button that opens a checkout modal.
12
- * The modal shows wallet picker, QR code / deeplinks, and "I have paid" confirmation.
13
- *
14
- * @example
15
- * ```tsx
16
- * <UnseenPayButton
17
- * amount={50_000_000}
18
- * reference="order_123"
19
- * description="Premium Plan"
20
- * onSuccess={(p) => console.log("Paid!", p.id)}
21
- * />
22
- * ```
23
- */
24
10
  function UnseenPayButton({ amount, mint, reference, description, expiresIn, onSuccess, onError, onCreated, createPaymentSession, label = "Pay with Unseen", className, disabled, }) {
25
11
  const [modalOpen, setModalOpen] = (0, react_1.useState)(false);
26
12
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { className: className, style: className ? undefined : defaultButtonStyle, onClick: () => setModalOpen(true), disabled: disabled, children: [(0, jsx_runtime_1.jsx)(ShieldIcon, {}), label] }), modalOpen && ((0, jsx_runtime_1.jsx)(UnseenModal, { amount: amount, mint: mint, reference: reference, description: description, expiresIn: expiresIn, createPaymentSession: createPaymentSession, onSuccess: (p) => {
@@ -35,11 +21,11 @@ function UnseenModal({ amount, mint, reference, description, expiresIn, createPa
35
21
  const [step, setStep] = (0, react_1.useState)("creating");
36
22
  const [errorMsg, setErrorMsg] = (0, react_1.useState)("");
37
23
  const [selectedWallet, setSelectedWallet] = (0, react_1.useState)(null);
24
+ const [deeplink, setDeeplink] = (0, react_1.useState)("");
38
25
  const [verifyCountdown, setVerifyCountdown] = (0, react_1.useState)(60);
39
26
  // ─── Create payment on mount ────────────────────────────────────────────
40
27
  (0, react_1.useEffect)(() => {
41
28
  let cancelled = false;
42
- // Prefer the server-side creator (storefront / no-apiKey flow) when supplied.
43
29
  const initiator = createPaymentSession
44
30
  ? () => createPaymentSession({ amount, reference, description, mint, expiresIn })
45
31
  : () => createPayment({ amount, reference, description, mint, expiresIn });
@@ -61,16 +47,15 @@ function UnseenModal({ amount, mint, reference, description, expiresIn, createPa
61
47
  return () => { cancelled = true; };
62
48
  // eslint-disable-next-line react-hooks/exhaustive-deps
63
49
  }, []);
64
- // ─── Handle wallet selection ────────────────────────────────────────────
50
+ // ─── Handle wallet selection → show QR step ─────────────────────────────
65
51
  const handleWalletSelect = (0, react_1.useCallback)((wallet) => {
66
52
  if (!payment)
67
53
  return;
54
+ const checkoutUrl = payment.checkoutUrl || `${baseUrl}/pay/${payment.id}`;
55
+ const dl = wallet.deeplink(checkoutUrl);
68
56
  setSelectedWallet(wallet);
69
- // Open the checkout page in the wallet's in-app browser via deeplink
70
- const checkoutUrl = `${baseUrl}/pay/${payment.id}`;
71
- const deeplink = wallet.deeplink(checkoutUrl);
72
- window.open(deeplink, "_blank");
73
- setStep("waiting");
57
+ setDeeplink(dl);
58
+ setStep("qr-display");
74
59
  }, [payment, baseUrl]);
75
60
  // ─── Handle "I have paid" verification ──────────────────────────────────
76
61
  const handleVerify = (0, react_1.useCallback)(async () => {
@@ -79,7 +64,6 @@ function UnseenModal({ amount, mint, reference, description, expiresIn, createPa
79
64
  setStep("verifying");
80
65
  setVerifyCountdown(60);
81
66
  try {
82
- // Keep verifying for up to 60s to improve UX and reduce manual retries.
83
67
  const startedAt = Date.now();
84
68
  while (Date.now() - startedAt < 60000) {
85
69
  const result = await verify(payment.id);
@@ -97,7 +81,7 @@ function UnseenModal({ amount, mint, reference, description, expiresIn, createPa
97
81
  await new Promise((resolve) => setTimeout(resolve, 3000));
98
82
  }
99
83
  setErrorMsg("Still waiting for confirmation. Please try again in a few seconds.");
100
- setStep("waiting");
84
+ setStep("qr-display");
101
85
  }
102
86
  catch (err) {
103
87
  const e = err instanceof Error ? err : new Error(String(err));
@@ -115,7 +99,13 @@ function UnseenModal({ amount, mint, reference, description, expiresIn, createPa
115
99
  return () => clearInterval(timer);
116
100
  }, [step]);
117
101
  // ─── Render ─────────────────────────────────────────────────────────────
118
- return ((0, jsx_runtime_1.jsx)("div", { style: overlayStyle, onClick: onClose, children: (0, jsx_runtime_1.jsxs)("div", { style: modalStyle, onClick: (e) => e.stopPropagation(), children: [(0, jsx_runtime_1.jsxs)("div", { style: modalHeaderStyle, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [(0, jsx_runtime_1.jsx)(ShieldIcon, { size: 20 }), (0, jsx_runtime_1.jsx)("span", { style: { fontWeight: 600, fontSize: "16px", color: "#fff" }, children: "Unseen Pay" })] }), (0, jsx_runtime_1.jsx)("button", { style: closeButtonStyle, onClick: onClose, children: "\u2715" })] }), (0, jsx_runtime_1.jsxs)("div", { style: modalBodyStyle, children: [step === "creating" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)(Spinner, {}), (0, jsx_runtime_1.jsx)(StepText, { children: "Creating payment session..." })] })), step === "wallet-picker" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)(StepText, { children: "Choose your wallet" }), (0, jsx_runtime_1.jsx)(StepHint, { children: "Select a wallet to complete the private payment." }), (0, jsx_runtime_1.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px", width: "100%", marginTop: "8px" }, children: wallets_1.WALLETS.map((w) => ((0, jsx_runtime_1.jsxs)("button", { style: walletButtonStyle, onClick: () => handleWalletSelect(w), children: [(0, jsx_runtime_1.jsx)("div", { style: walletIconStyle, children: (0, jsx_runtime_1.jsx)("img", { src: w.icon, alt: `${w.name} logo`, style: walletLogoImageStyle }) }), (0, jsx_runtime_1.jsx)("span", { style: { fontWeight: 500, color: "#fff" }, children: w.name }), (0, jsx_runtime_1.jsx)("span", { style: { marginLeft: "auto", color: "rgba(255,255,255,0.3)", fontSize: "13px" }, children: "\u2192" })] }, w.id))) })] })), step === "waiting" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsxs)("div", { style: walletBadgeStyle, children: [selectedWallet && ((0, jsx_runtime_1.jsx)("div", { style: { ...walletIconStyle, width: "24px", height: "24px" }, children: (0, jsx_runtime_1.jsx)("img", { src: selectedWallet.icon, alt: `${selectedWallet.name} logo`, style: walletLogoImageStyle }) })), (0, jsx_runtime_1.jsxs)("span", { style: { fontSize: "13px", color: "rgba(255,255,255,0.5)" }, children: ["Opened in ", selectedWallet?.name ?? "wallet"] })] }), (0, jsx_runtime_1.jsx)(StepText, { children: "Complete payment in your wallet" }), (0, jsx_runtime_1.jsx)(StepHint, { children: "After signing the transaction in your wallet, come back here and confirm." }), errorMsg && ((0, jsx_runtime_1.jsx)("div", { style: inlineErrorStyle, children: errorMsg })), (0, jsx_runtime_1.jsx)("button", { style: confirmButtonStyle, onClick: handleVerify, children: "I have paid" }), (0, jsx_runtime_1.jsx)("button", { style: linkButtonStyle, onClick: () => { setStep("wallet-picker"); setErrorMsg(""); }, children: "Use a different wallet" })] })), step === "verifying" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)(Spinner, {}), (0, jsx_runtime_1.jsx)(StepText, { children: "Verifying on Solana..." }), (0, jsx_runtime_1.jsxs)(StepHint, { children: ["Checking your transaction on-chain (", verifyCountdown, "s)."] })] })), step === "confirmed" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)("div", { style: successCircle, children: (0, jsx_runtime_1.jsx)("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "#22c55e", strokeWidth: "2.5", children: (0, jsx_runtime_1.jsx)("polyline", { points: "20 6 9 17 4 12" }) }) }), (0, jsx_runtime_1.jsx)(StepText, { style: { color: "#22c55e" }, children: "Payment Confirmed!" }), (0, jsx_runtime_1.jsx)(StepHint, { children: "Your transaction has been verified on Solana." }), (0, jsx_runtime_1.jsx)("button", { style: confirmButtonStyle, onClick: onClose, children: "Done" })] })), step === "error" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)("div", { style: errorCircle, children: (0, jsx_runtime_1.jsxs)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "#ef4444", strokeWidth: "2", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, jsx_runtime_1.jsx)("line", { x1: "15", y1: "9", x2: "9", y2: "15" }), (0, jsx_runtime_1.jsx)("line", { x1: "9", y1: "9", x2: "15", y2: "15" })] }) }), (0, jsx_runtime_1.jsx)(StepText, { style: { color: "#ef4444" }, children: "Error" }), (0, jsx_runtime_1.jsx)(StepHint, { children: errorMsg }), (0, jsx_runtime_1.jsx)("button", { style: confirmButtonStyle, onClick: () => { setStep("wallet-picker"); setErrorMsg(""); }, children: "Try Again" })] }))] }), (0, jsx_runtime_1.jsx)("div", { style: modalFooterStyle, children: (0, jsx_runtime_1.jsx)("span", { style: { fontSize: "11px", color: "rgba(255,255,255,0.2)" }, children: "Powered by Unseen Finance \u2022 Privacy-preserving payments" }) })] }) }));
102
+ return ((0, jsx_runtime_1.jsx)("div", { style: overlayStyle, onClick: onClose, children: (0, jsx_runtime_1.jsxs)("div", { style: modalStyle, onClick: (e) => e.stopPropagation(), children: [(0, jsx_runtime_1.jsxs)("div", { style: modalHeaderStyle, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [(0, jsx_runtime_1.jsx)(ShieldIcon, { size: 18 }), (0, jsx_runtime_1.jsx)("span", { style: { fontWeight: 700, fontSize: "15px", color: "#1a0a3d" }, children: "Unseen Pay" })] }), (0, jsx_runtime_1.jsx)("button", { style: closeButtonStyle, onClick: onClose, children: "\u2715" })] }), (0, jsx_runtime_1.jsxs)("div", { style: modalBodyStyle, children: [step === "creating" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)(Spinner, {}), (0, jsx_runtime_1.jsx)(StepText, { children: "Setting up payment\u2026" }), (0, jsx_runtime_1.jsx)(StepHint, { children: "Creating a secure payment session for you." })] })), step === "wallet-picker" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)(StepText, { children: "Which wallet would you like to use?" }), (0, jsx_runtime_1.jsx)(StepHint, { children: "Select a wallet to complete this private payment." }), (0, jsx_runtime_1.jsx)("div", { style: walletRowStyle, children: wallets_1.WALLETS.map((w) => ((0, jsx_runtime_1.jsxs)("button", { style: walletCardStyle, onClick: () => handleWalletSelect(w), onMouseEnter: (e) => {
103
+ e.currentTarget.style.background = "rgba(123,47,255,0.1)";
104
+ e.currentTarget.style.borderColor = "rgba(123,47,255,0.35)";
105
+ }, onMouseLeave: (e) => {
106
+ e.currentTarget.style.background = "rgba(123,47,255,0.04)";
107
+ e.currentTarget.style.borderColor = "rgba(123,47,255,0.12)";
108
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: walletIconContainerStyle, children: (0, jsx_runtime_1.jsx)("img", { src: w.icon, alt: `${w.name} logo`, style: walletLogoImageStyle }) }), (0, jsx_runtime_1.jsx)("span", { style: walletNameStyle, children: w.name })] }, w.id))) })] })), step === "qr-display" && selectedWallet && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsxs)("div", { style: walletBadgeStyle, children: [(0, jsx_runtime_1.jsx)("img", { src: selectedWallet.icon, alt: selectedWallet.name, style: { width: "18px", height: "18px", borderRadius: "5px", objectFit: "cover" } }), (0, jsx_runtime_1.jsx)("span", { style: { fontSize: "12px", color: "#6b21a8", fontWeight: 600 }, children: selectedWallet.name })] }), (0, jsx_runtime_1.jsx)(StepText, { children: "Scan to pay" }), (0, jsx_runtime_1.jsx)(StepHint, { children: "Point another device's camera at this code to open in your wallet, or use the link below to pay on this device." }), (0, jsx_runtime_1.jsx)("div", { style: qrWrapperStyle, children: (0, jsx_runtime_1.jsx)("img", { src: `https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=${encodeURIComponent(deeplink)}&bgcolor=ffffff&color=1a0a3d&margin=8&qzone=1`, alt: "Payment QR code", width: 220, height: 220, style: { display: "block", borderRadius: "8px" } }) }), (0, jsx_runtime_1.jsxs)("button", { style: deepLinkButtonStyle, onClick: () => window.open(deeplink, "_blank"), children: ["Or open in ", selectedWallet.name, " directly \u2192"] }), errorMsg && (0, jsx_runtime_1.jsx)("div", { style: inlineErrorStyle, children: errorMsg }), (0, jsx_runtime_1.jsx)("button", { style: confirmButtonStyle, onClick: handleVerify, children: "I have paid" }), (0, jsx_runtime_1.jsx)("button", { style: linkButtonStyle, onClick: () => { setStep("wallet-picker"); setErrorMsg(""); setDeeplink(""); }, children: "Use a different wallet" })] })), step === "verifying" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)(Spinner, {}), (0, jsx_runtime_1.jsx)(StepText, { children: "Verifying on Solana\u2026" }), (0, jsx_runtime_1.jsxs)(StepHint, { children: ["Checking your transaction on-chain (", verifyCountdown, "s)."] })] })), step === "confirmed" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)("div", { style: successCircle, children: (0, jsx_runtime_1.jsx)("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "#16a34a", strokeWidth: "2.5", children: (0, jsx_runtime_1.jsx)("polyline", { points: "20 6 9 17 4 12" }) }) }), (0, jsx_runtime_1.jsx)(StepText, { style: { color: "#16a34a" }, children: "Payment Confirmed!" }), (0, jsx_runtime_1.jsx)(StepHint, { children: "Your transaction has been verified on Solana." }), (0, jsx_runtime_1.jsx)("button", { style: confirmButtonStyle, onClick: onClose, children: "Done" })] })), step === "error" && ((0, jsx_runtime_1.jsxs)(StepContent, { children: [(0, jsx_runtime_1.jsx)("div", { style: errorCircle, children: (0, jsx_runtime_1.jsxs)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "#dc2626", strokeWidth: "2", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, jsx_runtime_1.jsx)("line", { x1: "15", y1: "9", x2: "9", y2: "15" }), (0, jsx_runtime_1.jsx)("line", { x1: "9", y1: "9", x2: "15", y2: "15" })] }) }), (0, jsx_runtime_1.jsx)(StepText, { style: { color: "#dc2626" }, children: "Something went wrong" }), (0, jsx_runtime_1.jsx)(StepHint, { children: errorMsg }), (0, jsx_runtime_1.jsx)("button", { style: confirmButtonStyle, onClick: () => { setStep("wallet-picker"); setErrorMsg(""); }, children: "Try Again" })] }))] }), (0, jsx_runtime_1.jsx)("div", { style: modalFooterStyle, children: (0, jsx_runtime_1.jsx)("span", { style: { fontSize: "11px", color: "rgba(100,60,180,0.35)" }, children: "Powered by Unseen Finance \u00B7 Privacy-preserving payments on Solana" }) })] }) }));
119
109
  }
120
110
  // ─── Sub-components ──────────────────────────────────────────────────────────
121
111
  function StepContent({ children }) {
@@ -131,7 +121,7 @@ function Spinner() {
131
121
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("style", { children: `@keyframes unseen-spin { to { transform: rotate(360deg); } }` }), (0, jsx_runtime_1.jsx)("div", { style: spinnerStyle })] }));
132
122
  }
133
123
  function ShieldIcon({ size = 16 }) {
134
- return ((0, jsx_runtime_1.jsx)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: (0, jsx_runtime_1.jsx)("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) }));
124
+ return ((0, jsx_runtime_1.jsx)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "#7b2fff", strokeWidth: "2.5", children: (0, jsx_runtime_1.jsx)("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) }));
135
125
  }
136
126
  // ─── Styles ──────────────────────────────────────────────────────────────────
137
127
  const defaultButtonStyle = {
@@ -152,97 +142,109 @@ const defaultButtonStyle = {
152
142
  const overlayStyle = {
153
143
  position: "fixed",
154
144
  inset: 0,
155
- background: "rgba(0,0,0,0.7)",
156
- backdropFilter: "blur(8px)",
145
+ background: "rgba(10,4,30,0.55)",
146
+ backdropFilter: "blur(10px)",
157
147
  display: "flex",
158
148
  alignItems: "center",
159
149
  justifyContent: "center",
160
150
  zIndex: 999999,
161
151
  fontFamily: "'Inter', system-ui, sans-serif",
162
- color: "#fff",
163
152
  padding: "16px",
164
153
  };
165
154
  const modalStyle = {
166
- background: "rgba(18,16,31,0.98)",
167
- border: "1px solid rgba(255,255,255,0.08)",
155
+ background: "linear-gradient(145deg, #ffffff 0%, #f7f3ff 55%, #ede8ff 100%)",
156
+ border: "1px solid rgba(123,47,255,0.14)",
168
157
  borderRadius: "20px",
169
158
  width: "100%",
170
- maxWidth: "400px",
159
+ maxWidth: "420px",
171
160
  overflow: "hidden",
161
+ boxShadow: "0 24px 64px rgba(100,40,220,0.14), 0 4px 16px rgba(0,0,0,0.08)",
172
162
  };
173
163
  const modalHeaderStyle = {
174
164
  display: "flex",
175
165
  justifyContent: "space-between",
176
166
  alignItems: "center",
177
167
  padding: "16px 20px",
178
- borderBottom: "1px solid rgba(255,255,255,0.06)",
168
+ borderBottom: "1px solid rgba(123,47,255,0.08)",
169
+ background: "rgba(255,255,255,0.7)",
179
170
  };
180
171
  const closeButtonStyle = {
181
172
  background: "none",
182
173
  border: "none",
183
- color: "rgba(255,255,255,0.4)",
184
- fontSize: "16px",
174
+ color: "rgba(80,40,140,0.4)",
175
+ fontSize: "15px",
185
176
  cursor: "pointer",
186
177
  padding: "4px 8px",
187
178
  borderRadius: "6px",
179
+ lineHeight: 1,
188
180
  };
189
181
  const modalBodyStyle = {
190
- padding: "24px 20px",
191
- minHeight: "200px",
182
+ padding: "28px 24px",
183
+ minHeight: "220px",
192
184
  };
193
185
  const modalFooterStyle = {
194
186
  padding: "12px 20px",
195
- borderTop: "1px solid rgba(255,255,255,0.04)",
187
+ borderTop: "1px solid rgba(123,47,255,0.06)",
196
188
  textAlign: "center",
189
+ background: "rgba(255,255,255,0.5)",
197
190
  };
198
191
  const stepContainerStyle = {
199
192
  display: "flex",
200
193
  flexDirection: "column",
201
194
  alignItems: "center",
202
- gap: "12px",
195
+ gap: "14px",
203
196
  };
204
197
  const stepTextBase = {
205
198
  fontSize: "16px",
206
- fontWeight: 600,
207
- color: "#fff",
199
+ fontWeight: 700,
200
+ color: "#1a0a3d",
208
201
  margin: 0,
202
+ textAlign: "center",
209
203
  };
210
204
  const hintStyle = {
211
205
  fontSize: "13px",
212
- color: "rgba(255,255,255,0.35)",
206
+ color: "#6b7280",
213
207
  textAlign: "center",
214
208
  lineHeight: 1.6,
215
209
  margin: 0,
216
- maxWidth: "280px",
210
+ maxWidth: "300px",
217
211
  };
218
212
  const spinnerStyle = {
219
213
  width: "32px",
220
214
  height: "32px",
221
- border: "3px solid rgba(255,255,255,0.1)",
215
+ border: "3px solid rgba(123,47,255,0.12)",
222
216
  borderTopColor: "#7b2fff",
223
217
  borderRadius: "50%",
224
218
  animation: "unseen-spin 0.8s linear infinite",
225
219
  };
226
- const walletButtonStyle = {
220
+ // Wallet picker — horizontal row
221
+ const walletRowStyle = {
222
+ display: "flex",
223
+ flexDirection: "row",
224
+ justifyContent: "center",
225
+ gap: "14px",
226
+ width: "100%",
227
+ marginTop: "6px",
228
+ };
229
+ const walletCardStyle = {
227
230
  display: "flex",
231
+ flexDirection: "column",
228
232
  alignItems: "center",
229
- gap: "12px",
230
- padding: "14px 16px",
231
- background: "rgba(255,255,255,0.04)",
232
- border: "1px solid rgba(255,255,255,0.06)",
233
- borderRadius: "12px",
233
+ gap: "8px",
234
+ padding: "16px 20px",
235
+ background: "rgba(123,47,255,0.04)",
236
+ border: "1px solid rgba(123,47,255,0.12)",
237
+ borderRadius: "14px",
234
238
  cursor: "pointer",
235
239
  transition: "all 0.15s ease",
236
- width: "100%",
237
- textAlign: "left",
238
- fontSize: "15px",
239
- color: "#fff",
240
240
  fontFamily: "inherit",
241
+ flex: "1 1 0",
242
+ maxWidth: "110px",
241
243
  };
242
- const walletIconStyle = {
243
- width: "32px",
244
- height: "32px",
245
- borderRadius: "8px",
244
+ const walletIconContainerStyle = {
245
+ width: "52px",
246
+ height: "52px",
247
+ borderRadius: "12px",
246
248
  overflow: "hidden",
247
249
  flexShrink: 0,
248
250
  };
@@ -252,13 +254,40 @@ const walletLogoImageStyle = {
252
254
  objectFit: "cover",
253
255
  display: "block",
254
256
  };
257
+ const walletNameStyle = {
258
+ fontSize: "11px",
259
+ fontWeight: 600,
260
+ color: "#4b207a",
261
+ letterSpacing: "0.02em",
262
+ };
263
+ // QR display
264
+ const qrWrapperStyle = {
265
+ padding: "10px",
266
+ background: "#ffffff",
267
+ borderRadius: "14px",
268
+ border: "1px solid rgba(123,47,255,0.1)",
269
+ boxShadow: "0 2px 12px rgba(100,40,220,0.08)",
270
+ };
271
+ const deepLinkButtonStyle = {
272
+ background: "none",
273
+ border: "1px solid rgba(123,47,255,0.2)",
274
+ borderRadius: "8px",
275
+ color: "#7b2fff",
276
+ fontSize: "13px",
277
+ fontWeight: 500,
278
+ cursor: "pointer",
279
+ padding: "8px 16px",
280
+ fontFamily: "inherit",
281
+ transition: "all 0.15s ease",
282
+ };
255
283
  const walletBadgeStyle = {
256
- display: "flex",
284
+ display: "inline-flex",
257
285
  alignItems: "center",
258
- gap: "8px",
259
- background: "rgba(255,255,255,0.04)",
260
- borderRadius: "10px",
261
- padding: "8px 14px",
286
+ gap: "6px",
287
+ background: "rgba(123,47,255,0.07)",
288
+ border: "1px solid rgba(123,47,255,0.15)",
289
+ borderRadius: "20px",
290
+ padding: "5px 12px",
262
291
  };
263
292
  const confirmButtonStyle = {
264
293
  width: "100%",
@@ -271,13 +300,14 @@ const confirmButtonStyle = {
271
300
  fontWeight: 600,
272
301
  cursor: "pointer",
273
302
  fontFamily: "inherit",
274
- marginTop: "8px",
303
+ marginTop: "4px",
304
+ boxShadow: "0 4px 16px rgba(123,47,255,0.3)",
275
305
  };
276
306
  const linkButtonStyle = {
277
307
  background: "none",
278
308
  border: "none",
279
- color: "rgba(255,255,255,0.35)",
280
- fontSize: "13px",
309
+ color: "#9ca3af",
310
+ fontSize: "12px",
281
311
  cursor: "pointer",
282
312
  padding: "4px",
283
313
  fontFamily: "inherit",
@@ -285,10 +315,10 @@ const linkButtonStyle = {
285
315
  };
286
316
  const inlineErrorStyle = {
287
317
  fontSize: "13px",
288
- color: "#ef4444",
318
+ color: "#dc2626",
289
319
  textAlign: "center",
290
- background: "rgba(239,68,68,0.08)",
291
- border: "1px solid rgba(239,68,68,0.15)",
320
+ background: "rgba(220,38,38,0.05)",
321
+ border: "1px solid rgba(220,38,38,0.15)",
292
322
  borderRadius: "8px",
293
323
  padding: "8px 12px",
294
324
  width: "100%",
@@ -297,14 +327,14 @@ const successCircle = {
297
327
  width: "56px",
298
328
  height: "56px",
299
329
  borderRadius: "50%",
300
- background: "rgba(34,197,94,0.1)",
301
- border: "1px solid rgba(34,197,94,0.2)",
330
+ background: "rgba(22,163,74,0.08)",
331
+ border: "1px solid rgba(22,163,74,0.2)",
302
332
  display: "flex",
303
333
  alignItems: "center",
304
334
  justifyContent: "center",
305
335
  };
306
336
  const errorCircle = {
307
337
  ...successCircle,
308
- background: "rgba(239,68,68,0.1)",
309
- border: "1px solid rgba(239,68,68,0.2)",
338
+ background: "rgba(220,38,38,0.08)",
339
+ border: "1px solid rgba(220,38,38,0.2)",
310
340
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unseen_fi/ui",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "React components for Unseen Pay — wallet picker modal, QR checkout, and payment button",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",