@ab-org/predicate-market-sdk 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +246 -0
- package/dist/auth/autoReconnect.d.ts +11 -0
- package/dist/auth/autoReconnect.js +36 -0
- package/dist/auth/bundledConfig.d.ts +2 -0
- package/dist/auth/bundledConfig.js +19 -0
- package/dist/auth/config.d.ts +29 -0
- package/dist/auth/config.js +53 -0
- package/dist/auth/google.d.ts +43 -0
- package/dist/auth/google.js +147 -0
- package/dist/auth/twitter.d.ts +7 -0
- package/dist/auth/twitter.js +94 -0
- package/dist/constants/chains.d.ts +22 -0
- package/dist/constants/chains.js +23 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +19 -0
- package/dist/modules/api.d.ts +144 -0
- package/dist/modules/api.js +93 -0
- package/dist/modules/balanceQuery.d.ts +20 -0
- package/dist/modules/balanceQuery.js +58 -0
- package/dist/modules/deposit.d.ts +31 -0
- package/dist/modules/deposit.js +57 -0
- package/dist/modules/marketData.d.ts +8 -0
- package/dist/modules/marketData.js +113 -0
- package/dist/modules/withdraw.d.ts +31 -0
- package/dist/modules/withdraw.js +60 -0
- package/dist/modules/withdrawExecutor.d.ts +47 -0
- package/dist/modules/withdrawExecutor.js +208 -0
- package/dist/policyAdapter.d.ts +11 -0
- package/dist/policyAdapter.js +38 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.js +1 -0
- package/dist/ui/DepositModal.d.ts +36 -0
- package/dist/ui/DepositModal.js +326 -0
- package/dist/ui/SignInModal.d.ts +22 -0
- package/dist/ui/SignInModal.js +74 -0
- package/dist/ui/SignInModal.sections.d.ts +33 -0
- package/dist/ui/SignInModal.sections.js +45 -0
- package/dist/ui/SignInModal.shared.d.ts +15 -0
- package/dist/ui/SignInModal.shared.js +87 -0
- package/dist/ui/WalletSelectionModal.d.ts +14 -0
- package/dist/ui/WalletSelectionModal.js +54 -0
- package/dist/ui/WithdrawModal.d.ts +47 -0
- package/dist/ui/WithdrawModal.js +528 -0
- package/dist/ui/components/CloseButton.d.ts +4 -0
- package/dist/ui/components/CloseButton.js +15 -0
- package/dist/ui/components/Countdown.d.ts +16 -0
- package/dist/ui/components/Countdown.js +42 -0
- package/dist/ui/components/DepositDetailsPanel.d.ts +8 -0
- package/dist/ui/components/DepositDetailsPanel.js +117 -0
- package/dist/ui/components/DropdownField.d.ts +19 -0
- package/dist/ui/components/DropdownField.js +81 -0
- package/dist/ui/components/Field.d.ts +10 -0
- package/dist/ui/components/Field.js +21 -0
- package/dist/ui/components/LoginRequiredOverlay.d.ts +6 -0
- package/dist/ui/components/LoginRequiredOverlay.js +31 -0
- package/dist/ui/components/ModalCard.d.ts +9 -0
- package/dist/ui/components/ModalCard.js +14 -0
- package/dist/ui/components/ModalFrame.d.ts +9 -0
- package/dist/ui/components/ModalFrame.js +18 -0
- package/dist/ui/components/PrimaryButton.d.ts +2 -0
- package/dist/ui/components/PrimaryButton.js +14 -0
- package/dist/ui/components/QRCodePanel.d.ts +4 -0
- package/dist/ui/components/QRCodePanel.js +43 -0
- package/dist/ui/components/Select.d.ts +12 -0
- package/dist/ui/components/Select.js +29 -0
- package/dist/ui/components/StepIndicator.d.ts +7 -0
- package/dist/ui/components/StepIndicator.js +35 -0
- package/dist/ui/components/Success.d.ts +1 -0
- package/dist/ui/components/Success.js +4 -0
- package/dist/ui/components/Toast.d.ts +8 -0
- package/dist/ui/components/Toast.js +51 -0
- package/dist/ui/hooks/useSession.d.ts +2 -0
- package/dist/ui/hooks/useSession.js +10 -0
- package/dist/ui/signInTypes.d.ts +25 -0
- package/dist/ui/signInTypes.js +1 -0
- package/dist/ui/theme.d.ts +31 -0
- package/dist/ui/theme.js +31 -0
- package/dist/ui/useSignInModalController.d.ts +25 -0
- package/dist/ui/useSignInModalController.js +173 -0
- package/dist/utils/env.d.ts +1 -0
- package/dist/utils/env.js +61 -0
- package/dist/utils/explorer.d.ts +3 -0
- package/dist/utils/explorer.js +47 -0
- package/dist/walletUtils.d.ts +3 -0
- package/dist/walletUtils.js +3 -0
- package/package.json +41 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { colors } from "../theme.js";
|
|
3
|
+
export const CloseButton = ({ onClick }) => (_jsx("button", { type: "button", onClick: onClick, "aria-label": "Close", style: {
|
|
4
|
+
width: 30,
|
|
5
|
+
height: 30,
|
|
6
|
+
borderRadius: "50%",
|
|
7
|
+
background: colors.card,
|
|
8
|
+
border: "none",
|
|
9
|
+
cursor: "pointer",
|
|
10
|
+
display: "flex",
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
justifyContent: "center",
|
|
13
|
+
padding: 0,
|
|
14
|
+
flexShrink: 0,
|
|
15
|
+
}, children: _jsx("svg", { width: "17", height: "17", viewBox: "0 0 17 17", fill: "none", children: _jsx("path", { d: "M4.25 4.25L12.75 12.75M12.75 4.25L4.25 12.75", stroke: colors.textPrimary, strokeWidth: "1.5", strokeLinecap: "round" }) }) }));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface CountdownProps {
|
|
2
|
+
/** 过期时间:ISO 字符串或时间戳(毫秒) */
|
|
3
|
+
expiresAt: string | number;
|
|
4
|
+
/** 过期时显示文案,默认 "Expired" */
|
|
5
|
+
expiredLabel?: string;
|
|
6
|
+
/** 自定义样式 */
|
|
7
|
+
style?: React.CSSProperties;
|
|
8
|
+
/** 是否已过期(由外部控制,用于与 quoteExpired 等联动时不再倒计时) */
|
|
9
|
+
isExpired?: boolean;
|
|
10
|
+
/** 倒计时归零时调用一次(可用于自动重新询价等) */
|
|
11
|
+
onExpired?: () => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 倒计时组件:每秒更新,显示距 expiresAt 的剩余时间(MM:SS)。
|
|
15
|
+
*/
|
|
16
|
+
export declare function Countdown({ expiresAt, expiredLabel, style, isExpired, onExpired, }: CountdownProps): import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useRef } from "react";
|
|
3
|
+
import { colors, fonts } from "../theme.js";
|
|
4
|
+
function getRemaining(expiresAt) {
|
|
5
|
+
const end = typeof expiresAt === "string" ? new Date(expiresAt).getTime() : expiresAt;
|
|
6
|
+
return Math.max(0, Math.floor((end - Date.now()) / 1000));
|
|
7
|
+
}
|
|
8
|
+
function formatRemaining(seconds) {
|
|
9
|
+
const m = Math.floor(seconds / 60);
|
|
10
|
+
const s = seconds % 60;
|
|
11
|
+
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 倒计时组件:每秒更新,显示距 expiresAt 的剩余时间(MM:SS)。
|
|
15
|
+
*/
|
|
16
|
+
export function Countdown({ expiresAt, expiredLabel = "Expired", style, isExpired = false, onExpired, }) {
|
|
17
|
+
const [remaining, setRemaining] = useState(() => getRemaining(expiresAt));
|
|
18
|
+
const hasFiredExpired = useRef(false);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
hasFiredExpired.current = false;
|
|
21
|
+
}, [expiresAt]);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (isExpired) {
|
|
24
|
+
setRemaining(0);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const tick = () => {
|
|
28
|
+
const r = getRemaining(expiresAt);
|
|
29
|
+
setRemaining(r);
|
|
30
|
+
if (r <= 0 && onExpired && !hasFiredExpired.current) {
|
|
31
|
+
hasFiredExpired.current = true;
|
|
32
|
+
onExpired();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
tick();
|
|
36
|
+
const id = setInterval(tick, 1000);
|
|
37
|
+
return () => clearInterval(id);
|
|
38
|
+
}, [expiresAt, isExpired, onExpired]);
|
|
39
|
+
const text = remaining <= 0 ? expiredLabel : formatRemaining(remaining);
|
|
40
|
+
const color = remaining <= 0 ? colors.warning : colors.textSecondary;
|
|
41
|
+
return (_jsxs("span", { style: { fontSize: 12, color, fontFamily: fonts.family, ...style }, children: ["Expires in ", _jsx("span", { style: { fontWeight: 600, color: "#fff" }, children: text })] }));
|
|
42
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface DepositDetailsPanelProps {
|
|
3
|
+
address: string;
|
|
4
|
+
tokenIcon?: ReactNode;
|
|
5
|
+
minimumDeposit?: string;
|
|
6
|
+
onCopyAddress?: () => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const DepositDetailsPanel: ({ address, tokenIcon, minimumDeposit, onCopyAddress, }: DepositDetailsPanelProps) => import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import qrcode from "qrcode-generator";
|
|
4
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
5
|
+
/* ─── QR matrix generation ──────────────────── */
|
|
6
|
+
function generateMatrix(data) {
|
|
7
|
+
const qr = qrcode(0, "H");
|
|
8
|
+
qr.addData(data);
|
|
9
|
+
qr.make();
|
|
10
|
+
const count = qr.getModuleCount();
|
|
11
|
+
const matrix = [];
|
|
12
|
+
for (let r = 0; r < count; r++) {
|
|
13
|
+
const row = [];
|
|
14
|
+
for (let c = 0; c < count; c++) {
|
|
15
|
+
row.push(qr.isDark(r, c));
|
|
16
|
+
}
|
|
17
|
+
matrix.push(row);
|
|
18
|
+
}
|
|
19
|
+
return matrix;
|
|
20
|
+
}
|
|
21
|
+
function isFinderZone(row, col, size) {
|
|
22
|
+
return ((row < 7 && col < 7) ||
|
|
23
|
+
(row < 7 && col >= size - 7) ||
|
|
24
|
+
(row >= size - 7 && col < 7));
|
|
25
|
+
}
|
|
26
|
+
/* ─── Styled finder eye (rounded nested rects) ── */
|
|
27
|
+
const FinderEye = ({ ox, oy, s }) => (_jsxs(_Fragment, { children: [_jsx("rect", { x: ox, y: oy, width: 7 * s, height: 7 * s, rx: s * 1.4, ry: s * 1.4, fill: "#fff" }), _jsx("rect", { x: ox + s, y: oy + s, width: 5 * s, height: 5 * s, rx: s * 0.9, ry: s * 0.9, fill: colors.background }), _jsx("rect", { x: ox + 2 * s, y: oy + 2 * s, width: 3 * s, height: 3 * s, rx: s * 0.7, ry: s * 0.7, fill: "#fff" })] }));
|
|
28
|
+
/* ─── Styled SVG QR ─────────────────────────── */
|
|
29
|
+
const SVG_SIZE = 220;
|
|
30
|
+
const QUIET_ZONE = 2;
|
|
31
|
+
const StyledQR = ({ data }) => {
|
|
32
|
+
const matrix = useMemo(() => generateMatrix(data), [data]);
|
|
33
|
+
const n = matrix.length;
|
|
34
|
+
const total = n + QUIET_ZONE * 2;
|
|
35
|
+
const cell = SVG_SIZE / total;
|
|
36
|
+
const off = QUIET_ZONE * cell;
|
|
37
|
+
const dotR = cell * 0.42;
|
|
38
|
+
const centerClearR = 3;
|
|
39
|
+
const cx = n / 2;
|
|
40
|
+
const cy = n / 2;
|
|
41
|
+
const dots = [];
|
|
42
|
+
for (let r = 0; r < n; r++) {
|
|
43
|
+
for (let c = 0; c < n; c++) {
|
|
44
|
+
if (!matrix[r][c])
|
|
45
|
+
continue;
|
|
46
|
+
if (isFinderZone(r, c, n))
|
|
47
|
+
continue;
|
|
48
|
+
if (Math.abs(c - cx) < centerClearR && Math.abs(r - cy) < centerClearR)
|
|
49
|
+
continue;
|
|
50
|
+
dots.push(_jsx("circle", { cx: off + c * cell + cell / 2, cy: off + r * cell + cell / 2, r: dotR, fill: "#fff" }, `${r}-${c}`));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return (_jsxs("svg", { width: SVG_SIZE, height: SVG_SIZE, viewBox: `0 0 ${SVG_SIZE} ${SVG_SIZE}`, style: { borderRadius: 12 }, children: [_jsx("rect", { width: SVG_SIZE, height: SVG_SIZE, fill: colors.background }), _jsx(FinderEye, { ox: off, oy: off, s: cell }), _jsx(FinderEye, { ox: off + (n - 7) * cell, oy: off, s: cell }), _jsx(FinderEye, { ox: off, oy: off + (n - 7) * cell, s: cell }), dots] }));
|
|
54
|
+
};
|
|
55
|
+
/* ─── Copy icon ─────────────────────────────── */
|
|
56
|
+
const CopyIcon = () => (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [_jsx("rect", { x: "4.5", y: "4.5", width: "7", height: "7", rx: "1.5", stroke: colors.textPrimary, strokeWidth: "1.2" }), _jsx("path", { d: "M9.5 4.5V3.5C9.5 2.67 8.83 2 8 2H3.5C2.67 2 2 2.67 2 3.5V8C2 8.83 2.67 9.5 3.5 9.5H4.5", stroke: colors.textPrimary, strokeWidth: "1.2" })] }));
|
|
57
|
+
/* ─── Main ──────────────────────────────────── */
|
|
58
|
+
export const DepositDetailsPanel = ({ address, tokenIcon, minimumDeposit, onCopyAddress, }) => {
|
|
59
|
+
const handleCopy = () => {
|
|
60
|
+
navigator.clipboard?.writeText(address);
|
|
61
|
+
onCopyAddress?.();
|
|
62
|
+
};
|
|
63
|
+
return (_jsxs("div", { style: {
|
|
64
|
+
display: "flex",
|
|
65
|
+
flexDirection: "column",
|
|
66
|
+
alignItems: "center",
|
|
67
|
+
gap: 16,
|
|
68
|
+
padding: "20px",
|
|
69
|
+
borderRadius: radii.card,
|
|
70
|
+
border: `1px solid ${colors.border}`,
|
|
71
|
+
fontFamily: fonts.family,
|
|
72
|
+
}, children: [_jsxs("div", { style: { position: "relative", display: "inline-flex" }, children: [_jsx(StyledQR, { data: address }), tokenIcon && (_jsx("div", { style: {
|
|
73
|
+
position: "absolute",
|
|
74
|
+
top: "50%",
|
|
75
|
+
left: "50%",
|
|
76
|
+
transform: "translate(-50%, -50%)",
|
|
77
|
+
width: 36,
|
|
78
|
+
height: 36,
|
|
79
|
+
borderRadius: "50%",
|
|
80
|
+
background: "#3B5998",
|
|
81
|
+
display: "flex",
|
|
82
|
+
alignItems: "center",
|
|
83
|
+
justifyContent: "center",
|
|
84
|
+
boxShadow: `0 0 0 3px ${colors.background}`,
|
|
85
|
+
}, children: tokenIcon }))] }), _jsx("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: 8 }, children: _jsx("div", { style: {
|
|
86
|
+
padding: "10px 14px",
|
|
87
|
+
borderRadius: radii.input,
|
|
88
|
+
background: "rgba(255,255,255,0.05)",
|
|
89
|
+
fontSize: 13,
|
|
90
|
+
color: colors.textPrimary,
|
|
91
|
+
wordBreak: "break-all",
|
|
92
|
+
lineHeight: 1.5,
|
|
93
|
+
}, children: address }) }), minimumDeposit && (_jsxs("div", { style: {
|
|
94
|
+
width: "100%",
|
|
95
|
+
display: "flex",
|
|
96
|
+
justifyContent: "space-between",
|
|
97
|
+
fontSize: 13,
|
|
98
|
+
}, children: [_jsx("span", { style: { color: colors.textSecondary }, children: "Minimum deposit" }), _jsx("span", { style: { color: colors.textPrimary, fontWeight: 500 }, children: minimumDeposit })] })), _jsxs("button", { type: "button", onClick: handleCopy, style: {
|
|
99
|
+
display: "flex",
|
|
100
|
+
alignItems: "center",
|
|
101
|
+
gap: 6,
|
|
102
|
+
padding: "10px 28px",
|
|
103
|
+
borderRadius: radii.pill,
|
|
104
|
+
border: `1px solid ${colors.borderStrong}`,
|
|
105
|
+
background: "transparent",
|
|
106
|
+
color: colors.textPrimary,
|
|
107
|
+
fontSize: 14,
|
|
108
|
+
fontWeight: 500,
|
|
109
|
+
cursor: "pointer",
|
|
110
|
+
fontFamily: fonts.family,
|
|
111
|
+
transition: "background .15s",
|
|
112
|
+
}, onMouseEnter: (e) => {
|
|
113
|
+
e.currentTarget.style.background = "rgba(255,255,255,0.06)";
|
|
114
|
+
}, onMouseLeave: (e) => {
|
|
115
|
+
e.currentTarget.style.background = "transparent";
|
|
116
|
+
}, children: [_jsx(CopyIcon, {}), "Copy address"] })] }));
|
|
117
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface SelectOption {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
subtitle?: string;
|
|
6
|
+
icon?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export interface DropdownFieldProps {
|
|
9
|
+
label: string;
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
value?: string;
|
|
12
|
+
icon?: ReactNode;
|
|
13
|
+
focused?: boolean;
|
|
14
|
+
options?: SelectOption[];
|
|
15
|
+
onSelect?: (id: string) => void;
|
|
16
|
+
/** @deprecated Use `options` + `onSelect` instead. */
|
|
17
|
+
onClick?: () => void;
|
|
18
|
+
}
|
|
19
|
+
export declare const DropdownField: ({ label, placeholder, value, icon, focused, options, onSelect, onClick, }: DropdownFieldProps) => import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect } from "react";
|
|
3
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
4
|
+
const Chevron = ({ up }) => (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", style: { transition: "transform .2s", transform: up ? "rotate(180deg)" : "none" }, children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: colors.textSecondary, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
5
|
+
export const DropdownField = ({ label, placeholder, value, icon, focused, options, onSelect, onClick, }) => {
|
|
6
|
+
const [open, setOpen] = useState(false);
|
|
7
|
+
const [triggerFocused, setTriggerFocused] = useState(false);
|
|
8
|
+
const ref = useRef(null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!open)
|
|
11
|
+
return;
|
|
12
|
+
const handler = (e) => {
|
|
13
|
+
if (ref.current && !ref.current.contains(e.target))
|
|
14
|
+
setOpen(false);
|
|
15
|
+
};
|
|
16
|
+
document.addEventListener("mousedown", handler);
|
|
17
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
18
|
+
}, [open]);
|
|
19
|
+
const hasOptions = options && options.length > 0;
|
|
20
|
+
const handleClick = () => {
|
|
21
|
+
if (hasOptions) {
|
|
22
|
+
setOpen((p) => !p);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
onClick?.();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const handleSelect = (id) => {
|
|
29
|
+
onSelect?.(id);
|
|
30
|
+
setOpen(false);
|
|
31
|
+
};
|
|
32
|
+
const selected = hasOptions ? options.find((o) => o.id === value) : undefined;
|
|
33
|
+
return (_jsxs("div", { ref: ref, style: { display: "flex", flexDirection: "column", gap: 8, width: "100%", position: "relative" }, children: [_jsx("span", { style: {
|
|
34
|
+
fontSize: 14,
|
|
35
|
+
fontWeight: 400,
|
|
36
|
+
lineHeight: 1.4,
|
|
37
|
+
color: colors.textPrimary,
|
|
38
|
+
fontFamily: fonts.family,
|
|
39
|
+
}, children: label }), _jsxs("button", { type: "button", onClick: handleClick, onFocus: () => setTriggerFocused(true), onBlur: () => setTriggerFocused(false), style: {
|
|
40
|
+
display: "flex",
|
|
41
|
+
alignItems: "center",
|
|
42
|
+
justifyContent: "space-between",
|
|
43
|
+
height: 44,
|
|
44
|
+
padding: "0 16px",
|
|
45
|
+
borderRadius: radii.input,
|
|
46
|
+
border: `1px solid ${open || triggerFocused ? colors.borderFocused : colors.border}`,
|
|
47
|
+
background: "transparent",
|
|
48
|
+
cursor: "pointer",
|
|
49
|
+
fontFamily: fonts.family,
|
|
50
|
+
width: "100%",
|
|
51
|
+
boxSizing: "border-box",
|
|
52
|
+
}, children: [_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [selected?.icon ?? icon, _jsx("span", { style: {
|
|
53
|
+
fontSize: 14,
|
|
54
|
+
lineHeight: 1.4,
|
|
55
|
+
color: value ? colors.textPrimary : colors.textSecondary,
|
|
56
|
+
fontFamily: fonts.family,
|
|
57
|
+
}, children: selected?.label ?? value ?? placeholder })] }), _jsx(Chevron, { up: open })] }), open && hasOptions && (_jsx("div", { className: "dropdown-list-item", style: {
|
|
58
|
+
position: "absolute",
|
|
59
|
+
top: "calc(100% + 4px)",
|
|
60
|
+
left: 0,
|
|
61
|
+
right: 0,
|
|
62
|
+
zIndex: 10,
|
|
63
|
+
borderRadius: radii.input,
|
|
64
|
+
border: `1px solid ${colors.border}`,
|
|
65
|
+
background: colors.card,
|
|
66
|
+
overflow: "hidden",
|
|
67
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.4)",
|
|
68
|
+
}, children: options.map((opt) => (_jsxs("button", { type: "button", onClick: () => handleSelect(opt.id), style: {
|
|
69
|
+
display: "flex",
|
|
70
|
+
alignItems: "center",
|
|
71
|
+
gap: 10,
|
|
72
|
+
width: "100%",
|
|
73
|
+
padding: "10px 16px",
|
|
74
|
+
border: "none",
|
|
75
|
+
background: opt.id === value ? "rgba(255,255,255,0.06)" : "transparent",
|
|
76
|
+
cursor: "pointer",
|
|
77
|
+
fontFamily: fonts.family,
|
|
78
|
+
textAlign: "left",
|
|
79
|
+
transition: "background .12s",
|
|
80
|
+
}, onMouseEnter: (e) => { e.currentTarget.style.background = "rgba(255,255,255,0.08)"; }, onMouseLeave: (e) => { e.currentTarget.style.background = opt.id === value ? "rgba(255,255,255,0.06)" : "transparent"; }, children: [opt.icon && (_jsx("div", { style: { width: 28, height: 28, flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: opt.icon })), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 1 }, children: [_jsx("span", { style: { fontSize: 14, fontWeight: 500, color: colors.textPrimary }, children: opt.label }), opt.subtitle && (_jsx("span", { style: { fontSize: 12, color: colors.textSecondary }, children: opt.subtitle }))] })] }, opt.id))) }))] }));
|
|
81
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ChangeEventHandler } from "react";
|
|
2
|
+
export interface FieldProps {
|
|
3
|
+
label: string;
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
value?: string;
|
|
6
|
+
onChange?: ChangeEventHandler<HTMLInputElement>;
|
|
7
|
+
prefix?: React.ReactNode;
|
|
8
|
+
suffix?: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare const Field: ({ label, placeholder, value, onChange, prefix, suffix }: FieldProps) => import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
3
|
+
export const Field = ({ label, placeholder, value, onChange, prefix, suffix }) => {
|
|
4
|
+
return (_jsxs("label", { style: { display: "flex", flexDirection: "column", gap: 8, fontFamily: fonts.family }, children: [_jsx("span", { style: { fontSize: 14, color: colors.textSecondary }, children: label }), _jsxs("div", { style: {
|
|
5
|
+
display: "flex",
|
|
6
|
+
alignItems: "center",
|
|
7
|
+
background: colors.cardRaised,
|
|
8
|
+
borderRadius: radii.md,
|
|
9
|
+
border: `1px solid ${colors.borderStrong}`,
|
|
10
|
+
padding: "0 14px",
|
|
11
|
+
}, children: [prefix && _jsx("span", { style: { marginRight: 8, color: colors.textSecondary }, children: prefix }), _jsx("input", { value: value, onChange: onChange, placeholder: placeholder, style: {
|
|
12
|
+
flex: 1,
|
|
13
|
+
border: "none",
|
|
14
|
+
outline: "none",
|
|
15
|
+
background: "transparent",
|
|
16
|
+
color: colors.textPrimary,
|
|
17
|
+
fontSize: 16,
|
|
18
|
+
fontFamily: fonts.family,
|
|
19
|
+
padding: "16px 0",
|
|
20
|
+
} }), suffix && _jsx("span", { style: { marginLeft: 8 }, children: suffix })] })] }));
|
|
21
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ModalFrame } from "./ModalFrame.js";
|
|
3
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
4
|
+
const LockIcon = () => (_jsxs("svg", { width: "48", height: "48", viewBox: "0 0 48 48", fill: "none", children: [_jsx("rect", { x: "10", y: "22", width: "28", height: "20", rx: "4", stroke: colors.textSecondary, strokeWidth: "2" }), _jsx("path", { d: "M16 22V16C16 11.5817 19.5817 8 24 8C28.4183 8 32 11.5817 32 16V22", stroke: colors.textSecondary, strokeWidth: "2", strokeLinecap: "round" }), _jsx("circle", { cx: "24", cy: "33", r: "3", fill: colors.textSecondary })] }));
|
|
5
|
+
export const LoginRequiredOverlay = ({ title, onSignIn, onClose, }) => (_jsx(ModalFrame, { onClose: onClose, contentStyle: { padding: "48px 24px" }, children: _jsxs("div", { style: {
|
|
6
|
+
display: "flex",
|
|
7
|
+
flexDirection: "column",
|
|
8
|
+
alignItems: "center",
|
|
9
|
+
gap: 24,
|
|
10
|
+
textAlign: "center",
|
|
11
|
+
}, children: [_jsx(LockIcon, {}), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [_jsx("h2", { style: {
|
|
12
|
+
margin: 0,
|
|
13
|
+
fontSize: 20,
|
|
14
|
+
fontWeight: 600,
|
|
15
|
+
color: colors.textPrimary,
|
|
16
|
+
}, children: title }), _jsx("p", { style: {
|
|
17
|
+
margin: 0,
|
|
18
|
+
fontSize: 14,
|
|
19
|
+
color: colors.textSecondary,
|
|
20
|
+
lineHeight: 1.5,
|
|
21
|
+
}, children: "Please sign in to continue" })] }), onSignIn && (_jsx("button", { type: "button", onClick: onSignIn, style: {
|
|
22
|
+
padding: "12px 48px",
|
|
23
|
+
borderRadius: radii.full,
|
|
24
|
+
border: "none",
|
|
25
|
+
background: colors.textPrimary,
|
|
26
|
+
color: "#15181D",
|
|
27
|
+
fontSize: 16,
|
|
28
|
+
fontWeight: 500,
|
|
29
|
+
fontFamily: fonts.family,
|
|
30
|
+
cursor: "pointer",
|
|
31
|
+
}, children: "Sign In" }))] }) }));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PropsWithChildren, ReactNode } from "react";
|
|
2
|
+
export interface ModalCardProps extends PropsWithChildren {
|
|
3
|
+
title: string;
|
|
4
|
+
subtitle?: string;
|
|
5
|
+
icon?: ReactNode;
|
|
6
|
+
width?: number | string;
|
|
7
|
+
footer?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare const ModalCard: ({ title, subtitle, icon, width, footer, children }: ModalCardProps) => import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
3
|
+
export const ModalCard = ({ title, subtitle, icon, width = 420, footer, children }) => {
|
|
4
|
+
return (_jsxs("div", { style: {
|
|
5
|
+
width,
|
|
6
|
+
borderRadius: radii.xl,
|
|
7
|
+
background: colors.card,
|
|
8
|
+
border: `1px solid ${colors.border}`,
|
|
9
|
+
padding: "32px",
|
|
10
|
+
color: colors.textPrimary,
|
|
11
|
+
fontFamily: fonts.family,
|
|
12
|
+
boxShadow: "0 30px 90px rgba(0,0,0,0.55)",
|
|
13
|
+
}, children: [_jsxs("header", { style: { display: "flex", alignItems: "center", gap: 16, marginBottom: 24 }, children: [icon && _jsx("div", { children: icon }), _jsxs("div", { children: [_jsx("div", { style: { fontSize: 22, fontWeight: 600 }, children: title }), subtitle && (_jsx("div", { style: { fontSize: 14, color: colors.textSecondary, marginTop: 4 }, children: subtitle }))] })] }), _jsx("div", { style: { display: "flex", flexDirection: "column", gap: 20 }, children: children }), footer && _jsx("div", { style: { marginTop: 32 }, children: footer })] }));
|
|
14
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
export interface ModalFrameProps {
|
|
3
|
+
onClose?: () => void;
|
|
4
|
+
width?: number;
|
|
5
|
+
cardStyle?: CSSProperties;
|
|
6
|
+
contentStyle?: CSSProperties;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare const ModalFrame: ({ onClose, width, cardStyle, contentStyle, children, }: ModalFrameProps) => import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { CloseButton } from "./CloseButton.js";
|
|
3
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
4
|
+
export const ModalFrame = ({ onClose, width = 500, cardStyle, contentStyle, children, }) => (_jsx("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }, children: _jsxs("div", { style: { display: "flex", gap: 14, alignItems: "flex-start" }, children: [_jsx("div", { style: {
|
|
5
|
+
width,
|
|
6
|
+
background: colors.card,
|
|
7
|
+
borderRadius: radii.card,
|
|
8
|
+
overflow: "hidden",
|
|
9
|
+
...cardStyle,
|
|
10
|
+
}, children: _jsx("div", { style: {
|
|
11
|
+
display: "flex",
|
|
12
|
+
flexDirection: "column",
|
|
13
|
+
minHeight: 0,
|
|
14
|
+
fontFamily: fonts.family,
|
|
15
|
+
color: colors.textPrimary,
|
|
16
|
+
boxSizing: "border-box",
|
|
17
|
+
...contentStyle,
|
|
18
|
+
}, children: children }) }), _jsx(CloseButton, { onClick: onClose })] }) }));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
3
|
+
export const PrimaryButton = ({ children, ...rest }) => (_jsx("button", { ...rest, style: {
|
|
4
|
+
width: "100%",
|
|
5
|
+
padding: "16px 20px",
|
|
6
|
+
borderRadius: radii.md,
|
|
7
|
+
border: "none",
|
|
8
|
+
background: `linear-gradient(135deg, ${colors.accent} 0%, ${colors.accentStrong} 100%)`,
|
|
9
|
+
color: colors.background,
|
|
10
|
+
fontSize: 16,
|
|
11
|
+
fontWeight: 600,
|
|
12
|
+
fontFamily: fonts.family,
|
|
13
|
+
cursor: "pointer",
|
|
14
|
+
}, children: children }));
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
3
|
+
const generateBlocks = (address) => {
|
|
4
|
+
const chars = Array.from(address.replace(/[^0-9a-f]/gi, ""));
|
|
5
|
+
return chars.map((char, index) => {
|
|
6
|
+
const intensity = (parseInt(char, 16) / 15) * 100;
|
|
7
|
+
return (_jsx("div", { style: {
|
|
8
|
+
width: 10,
|
|
9
|
+
height: 10,
|
|
10
|
+
background: `rgba(255,255,255,${intensity / 140})`,
|
|
11
|
+
} }, `${char}-${index}`));
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
export const QRCodePanel = ({ address }) => {
|
|
15
|
+
return (_jsxs("div", { style: {
|
|
16
|
+
borderRadius: radii.lg,
|
|
17
|
+
border: `1px solid ${colors.border}`,
|
|
18
|
+
padding: 20,
|
|
19
|
+
width: 200,
|
|
20
|
+
display: "flex",
|
|
21
|
+
flexDirection: "column",
|
|
22
|
+
alignItems: "center",
|
|
23
|
+
gap: 12,
|
|
24
|
+
background: colors.cardRaised,
|
|
25
|
+
}, children: [_jsx("div", { style: {
|
|
26
|
+
width: 160,
|
|
27
|
+
height: 160,
|
|
28
|
+
borderRadius: radii.sm,
|
|
29
|
+
background: colors.background,
|
|
30
|
+
padding: 12,
|
|
31
|
+
display: "grid",
|
|
32
|
+
gridTemplateColumns: "repeat(12, 10px)",
|
|
33
|
+
gap: 2,
|
|
34
|
+
}, children: generateBlocks(address) }), _jsx("button", { type: "button", style: {
|
|
35
|
+
borderRadius: radii.sm,
|
|
36
|
+
border: `1px solid ${colors.borderStrong}`,
|
|
37
|
+
background: "transparent",
|
|
38
|
+
color: colors.textSecondary,
|
|
39
|
+
padding: "6px 12px",
|
|
40
|
+
cursor: "pointer",
|
|
41
|
+
fontFamily: fonts.family,
|
|
42
|
+
}, onClick: () => navigator.clipboard?.writeText(address), children: "Copy address" })] }));
|
|
43
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface SelectOption {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
badge?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface SelectProps {
|
|
7
|
+
label: string;
|
|
8
|
+
value: string;
|
|
9
|
+
options: SelectOption[];
|
|
10
|
+
onChange?: (value: string) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const Select: ({ label, value, options, onChange }: SelectProps) => import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { colors, fonts, radii } from "../theme.js";
|
|
3
|
+
export const Select = ({ label, value, options, onChange }) => {
|
|
4
|
+
const handleChange = (event) => onChange?.(event.target.value);
|
|
5
|
+
return (_jsxs("label", { style: { display: "flex", flexDirection: "column", gap: 8, fontFamily: fonts.family }, children: [_jsx("span", { style: { fontSize: 14, color: colors.textSecondary }, children: label }), _jsxs("div", { style: {
|
|
6
|
+
position: "relative",
|
|
7
|
+
borderRadius: radii.md,
|
|
8
|
+
background: colors.cardRaised,
|
|
9
|
+
border: `1px solid ${colors.borderStrong}`,
|
|
10
|
+
}, children: [_jsx("select", { value: value, onChange: handleChange, style: {
|
|
11
|
+
width: "100%",
|
|
12
|
+
appearance: "none",
|
|
13
|
+
border: "none",
|
|
14
|
+
outline: "none",
|
|
15
|
+
background: "transparent",
|
|
16
|
+
color: colors.textPrimary,
|
|
17
|
+
fontSize: 16,
|
|
18
|
+
padding: "16px 48px 16px 16px",
|
|
19
|
+
fontFamily: fonts.family,
|
|
20
|
+
}, children: options.map((option) => (_jsxs("option", { value: option.value, style: { color: "black" }, children: [option.label, option.badge ? ` (${option.badge})` : ""] }, option.value))) }), _jsx("span", { style: {
|
|
21
|
+
position: "absolute",
|
|
22
|
+
right: 16,
|
|
23
|
+
top: 0,
|
|
24
|
+
bottom: 0,
|
|
25
|
+
display: "flex",
|
|
26
|
+
alignItems: "center",
|
|
27
|
+
color: colors.textSecondary,
|
|
28
|
+
}, children: "\u25BE" })] })] }));
|
|
29
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface StepIndicatorProps {
|
|
2
|
+
steps: number;
|
|
3
|
+
/** When provided, each dot is highlighted when the corresponding value is true; otherwise uses activeStep (i <= activeStep). */
|
|
4
|
+
stepActive?: boolean[];
|
|
5
|
+
activeStep?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const StepIndicator: ({ steps, stepActive, activeStep }: StepIndicatorProps) => import("react/jsx-runtime.js").JSX.Element;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { colors } from "../theme.js";
|
|
3
|
+
export const StepIndicator = ({ steps, stepActive, activeStep = 0 }) => {
|
|
4
|
+
return (_jsx("div", { style: {
|
|
5
|
+
display: "flex",
|
|
6
|
+
flexDirection: "column",
|
|
7
|
+
alignItems: "center",
|
|
8
|
+
width: 20,
|
|
9
|
+
paddingTop: 4,
|
|
10
|
+
flexShrink: 0,
|
|
11
|
+
}, children: Array.from({ length: steps }, (_, i) => {
|
|
12
|
+
const isActive = stepActive && stepActive.length > i ? stepActive[i] : i <= activeStep;
|
|
13
|
+
const isLast = i === steps - 1;
|
|
14
|
+
return (_jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [_jsx("div", { style: {
|
|
15
|
+
width: 20,
|
|
16
|
+
height: 20,
|
|
17
|
+
borderRadius: "50%",
|
|
18
|
+
border: `2px solid ${isActive ? colors.stepActive : colors.stepInactive}`,
|
|
19
|
+
display: "flex",
|
|
20
|
+
alignItems: "center",
|
|
21
|
+
justifyContent: "center",
|
|
22
|
+
boxSizing: "border-box",
|
|
23
|
+
}, children: _jsx("div", { style: {
|
|
24
|
+
width: 7.5,
|
|
25
|
+
height: 7.5,
|
|
26
|
+
borderRadius: "50%",
|
|
27
|
+
background: isActive ? colors.stepActive : colors.stepInactive,
|
|
28
|
+
} }) }), !isLast && (_jsx("div", { style: {
|
|
29
|
+
width: 1,
|
|
30
|
+
height: 87,
|
|
31
|
+
background: isActive ? colors.stepActive : colors.stepInactive,
|
|
32
|
+
opacity: 0.3,
|
|
33
|
+
} }))] }, i));
|
|
34
|
+
}) }));
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SuccessIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export const SuccessIcon = () => {
|
|
3
|
+
return (_jsxs("svg", { width: "80", height: "81", viewBox: "0 0 80 81", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("path", { d: "M40 80.5C62.0914 80.5 80 62.5914 80 40.5C80 18.4086 62.0914 0.5 40 0.5C17.9086 0.5 0 18.4086 0 40.5C0 62.5914 17.9086 80.5 40 80.5Z", fill: "#627EEA" }), _jsx("path", { d: "M38.999 16.5V34.2437L53.9962 40.9451L38.999 16.5Z", fill: "white", fillOpacity: "0.602" }), _jsx("path", { d: "M38.9991 16.5L24 40.9451L38.9991 34.2437V16.5Z", fill: "white" }), _jsx("path", { d: "M38.999 52.4434V64.4999L54.0061 43.7376L38.999 52.4434Z", fill: "white", fillOpacity: "0.602" }), _jsx("path", { d: "M38.9991 64.4999V52.4414L24 43.7376L38.9991 64.4999Z", fill: "white" }), _jsx("path", { d: "M38.999 49.653L53.9962 40.9451L38.999 34.2477V49.653Z", fill: "white", fillOpacity: "0.2" }), _jsx("path", { d: "M24 40.9451L38.9991 49.653V34.2477L24 40.9451Z", fill: "white", fillOpacity: "0.602" }), _jsx("g", { filter: "url(#filter0_ii_34_1690)", children: _jsx("circle", { cx: "40", cy: "40", r: "40", fill: "url(#paint0_linear_34_1690)" }) }), _jsx("path", { d: "M25.8057 35.9858L38.7921 49.0324L56.7734 30.9678", stroke: "#58AE36", strokeWidth: "5.16129", fill: "none" }), _jsxs("defs", { children: [_jsxs("filter", { id: "filter0_ii_34_1690", x: "0", y: "0", width: "80", height: "80", filterUnits: "userSpaceOnUse", colorInterpolationFilters: "sRGB", children: [_jsx("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }), _jsx("feBlend", { mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }), _jsx("feColorMatrix", { in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), _jsx("feOffset", { dx: "-1.29032", dy: "-1.29032" }), _jsx("feComposite", { in2: "hardAlpha", operator: "arithmetic", k2: "-1", k3: "1" }), _jsx("feColorMatrix", { type: "matrix", values: "0 0 0 0 0.584745 0 0 0 0 1 0 0 0 0 0.420982 0 0 0 1 0" }), _jsx("feBlend", { mode: "multiply", in2: "shape", result: "effect1_innerShadow_34_1690" }), _jsx("feColorMatrix", { in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), _jsx("feOffset", { dx: "1.29032", dy: "1.29032" }), _jsx("feComposite", { in2: "hardAlpha", operator: "arithmetic", k2: "-1", k3: "1" }), _jsx("feColorMatrix", { type: "matrix", values: "0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0" }), _jsx("feBlend", { mode: "normal", in2: "effect1_innerShadow_34_1690", result: "effect2_innerShadow_34_1690" })] }), _jsxs("linearGradient", { id: "paint0_linear_34_1690", x1: "27.4722", y1: "7.62951", x2: "70.4313", y2: "26.563", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#BBFFA1" }), _jsx("stop", { offset: "1", stopColor: "#ACFE8B" })] })] })] }));
|
|
4
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type ToastVariant = "success" | "error" | "info";
|
|
2
|
+
export interface ToastProps {
|
|
3
|
+
message: string;
|
|
4
|
+
variant?: ToastVariant;
|
|
5
|
+
duration?: number;
|
|
6
|
+
onClose?: () => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const Toast: ({ message, variant, duration, onClose }: ToastProps) => import("react/jsx-runtime.js").JSX.Element;
|