@stackvibe-studio/ui 0.2.0 → 0.3.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/README.md +44 -33
- package/dist/components/accordion.d.ts +13 -0
- package/dist/components/button.d.ts +1 -1
- package/dist/components/dialog.d.ts +24 -0
- package/dist/components/drawer.d.ts +17 -0
- package/dist/components/dropdown-menu.d.ts +16 -0
- package/dist/components/progress.d.ts +8 -0
- package/dist/components/switch.d.ts +10 -0
- package/dist/components/toast.d.ts +15 -0
- package/dist/components/tooltip.d.ts +8 -0
- package/dist/index.cjs +529 -32
- package/dist/index.d.ts +8 -0
- package/dist/index.js +513 -31
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,24 +21,88 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
|
+
Accordion: () => Accordion,
|
|
24
25
|
Alert: () => Alert,
|
|
25
26
|
Avatar: () => Avatar,
|
|
26
27
|
Badge: () => Badge,
|
|
27
28
|
Button: () => Button,
|
|
28
29
|
Card: () => Card,
|
|
29
30
|
Checkbox: () => Checkbox,
|
|
31
|
+
Dialog: () => Dialog,
|
|
32
|
+
DialogDescription: () => DialogDescription,
|
|
33
|
+
DialogFooter: () => DialogFooter,
|
|
34
|
+
DialogHeader: () => DialogHeader,
|
|
35
|
+
DialogTitle: () => DialogTitle,
|
|
36
|
+
Drawer: () => Drawer,
|
|
37
|
+
DrawerHeader: () => DrawerHeader,
|
|
38
|
+
DrawerTitle: () => DrawerTitle,
|
|
39
|
+
DropdownMenu: () => DropdownMenu,
|
|
30
40
|
Input: () => Input,
|
|
41
|
+
Progress: () => Progress,
|
|
31
42
|
Select: () => Select,
|
|
32
43
|
Skeleton: () => Skeleton,
|
|
44
|
+
Switch: () => Switch,
|
|
33
45
|
Tabs: () => Tabs,
|
|
34
46
|
Textarea: () => Textarea,
|
|
47
|
+
Toaster: () => Toaster,
|
|
48
|
+
Tooltip: () => Tooltip,
|
|
35
49
|
cx: () => cx,
|
|
36
|
-
themeTokens: () => themeTokens
|
|
50
|
+
themeTokens: () => themeTokens,
|
|
51
|
+
toast: () => toast
|
|
37
52
|
});
|
|
38
53
|
module.exports = __toCommonJS(index_exports);
|
|
39
54
|
|
|
40
|
-
// src/components/
|
|
55
|
+
// src/components/accordion.tsx
|
|
56
|
+
var import_react = require("react");
|
|
41
57
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
58
|
+
function Accordion({
|
|
59
|
+
items,
|
|
60
|
+
type = "single",
|
|
61
|
+
defaultOpen = [],
|
|
62
|
+
className = ""
|
|
63
|
+
}) {
|
|
64
|
+
const [openIds, setOpenIds] = (0, import_react.useState)(defaultOpen);
|
|
65
|
+
const toggle = (id) => {
|
|
66
|
+
if (type === "single") {
|
|
67
|
+
setOpenIds(openIds.includes(id) ? [] : [id]);
|
|
68
|
+
} else {
|
|
69
|
+
setOpenIds(
|
|
70
|
+
openIds.includes(id) ? openIds.filter((item) => item !== id) : [...openIds, id]
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: ["divide-y divide-white/10 rounded-2xl border border-white/10 bg-slate-900/60 overflow-hidden", className].join(" "), children: items.map((item) => {
|
|
75
|
+
const isOpen = openIds.includes(item.id);
|
|
76
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "transition duration-150", children: [
|
|
77
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
78
|
+
"button",
|
|
79
|
+
{
|
|
80
|
+
type: "button",
|
|
81
|
+
onClick: () => toggle(item.id),
|
|
82
|
+
className: "flex w-full items-center justify-between px-5 py-4 text-left font-medium text-white hover:bg-white/5 transition cursor-pointer",
|
|
83
|
+
"aria-expanded": isOpen,
|
|
84
|
+
children: [
|
|
85
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.title }),
|
|
86
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
87
|
+
"svg",
|
|
88
|
+
{
|
|
89
|
+
className: `h-4 w-4 transform text-slate-400 transition-transform duration-200 ${isOpen ? "rotate-180 text-violet-400" : ""}`,
|
|
90
|
+
fill: "none",
|
|
91
|
+
viewBox: "0 0 24 24",
|
|
92
|
+
stroke: "currentColor",
|
|
93
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
),
|
|
99
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-5 pb-4 pt-1 text-sm text-slate-300 leading-relaxed border-t border-white/5 animate-in fade-in duration-200", children: item.content })
|
|
100
|
+
] }, item.id);
|
|
101
|
+
}) });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/components/alert.tsx
|
|
105
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
42
106
|
var variantClasses = {
|
|
43
107
|
info: "border-cyan-500/40 bg-cyan-500/10 text-cyan-50",
|
|
44
108
|
success: "border-emerald-500/40 bg-emerald-500/10 text-emerald-50",
|
|
@@ -46,29 +110,29 @@ var variantClasses = {
|
|
|
46
110
|
danger: "border-rose-500/40 bg-rose-500/10 text-rose-50"
|
|
47
111
|
};
|
|
48
112
|
function Alert({ title, variant = "info", className = "", children, ...props }) {
|
|
49
|
-
return /* @__PURE__ */ (0,
|
|
113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
50
114
|
"div",
|
|
51
115
|
{
|
|
52
116
|
...props,
|
|
53
117
|
className: ["rounded-2xl border p-4 text-sm", variantClasses[variant], className].join(" "),
|
|
54
118
|
role: "alert",
|
|
55
119
|
children: [
|
|
56
|
-
title ? /* @__PURE__ */ (0,
|
|
57
|
-
/* @__PURE__ */ (0,
|
|
120
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mb-1 font-medium", children: title }) : null,
|
|
121
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children })
|
|
58
122
|
]
|
|
59
123
|
}
|
|
60
124
|
);
|
|
61
125
|
}
|
|
62
126
|
|
|
63
127
|
// src/components/avatar.tsx
|
|
64
|
-
var
|
|
128
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
65
129
|
var sizeClasses = {
|
|
66
130
|
sm: "h-9 w-9 text-xs",
|
|
67
131
|
md: "h-12 w-12 text-sm",
|
|
68
132
|
lg: "h-16 w-16 text-base"
|
|
69
133
|
};
|
|
70
134
|
function Avatar({ src, alt = "avatar", fallback = "SV", size = "md", className = "", ...props }) {
|
|
71
|
-
return src ? /* @__PURE__ */ (0,
|
|
135
|
+
return src ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
72
136
|
"img",
|
|
73
137
|
{
|
|
74
138
|
...props,
|
|
@@ -76,7 +140,7 @@ function Avatar({ src, alt = "avatar", fallback = "SV", size = "md", className =
|
|
|
76
140
|
alt,
|
|
77
141
|
className: ["rounded-full object-cover ring-1 ring-white/10", sizeClasses[size], className].join(" ")
|
|
78
142
|
}
|
|
79
|
-
) : /* @__PURE__ */ (0,
|
|
143
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
80
144
|
"div",
|
|
81
145
|
{
|
|
82
146
|
className: ["flex items-center justify-center rounded-full bg-violet-500/20 font-semibold text-violet-100 ring-1 ring-violet-400/20", sizeClasses[size], className].join(" "),
|
|
@@ -86,14 +150,14 @@ function Avatar({ src, alt = "avatar", fallback = "SV", size = "md", className =
|
|
|
86
150
|
}
|
|
87
151
|
|
|
88
152
|
// src/components/badge.tsx
|
|
89
|
-
var
|
|
153
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
90
154
|
var variants = {
|
|
91
155
|
primary: "bg-violet-500/20 text-violet-200 ring-1 ring-violet-400/20",
|
|
92
156
|
secondary: "bg-cyan-500/15 text-cyan-200 ring-1 ring-cyan-400/20",
|
|
93
157
|
outline: "bg-transparent text-slate-200 ring-1 ring-white/10"
|
|
94
158
|
};
|
|
95
159
|
function Badge({ variant = "primary", className = "", ...props }) {
|
|
96
|
-
return /* @__PURE__ */ (0,
|
|
160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
97
161
|
"span",
|
|
98
162
|
{
|
|
99
163
|
...props,
|
|
@@ -103,7 +167,7 @@ function Badge({ variant = "primary", className = "", ...props }) {
|
|
|
103
167
|
}
|
|
104
168
|
|
|
105
169
|
// src/components/button.tsx
|
|
106
|
-
var
|
|
170
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
107
171
|
var variantClasses2 = {
|
|
108
172
|
primary: "bg-violet-500 text-white hover:bg-violet-400",
|
|
109
173
|
secondary: "bg-cyan-500 text-slate-950 hover:bg-cyan-400",
|
|
@@ -125,16 +189,16 @@ function Button(props) {
|
|
|
125
189
|
].join(" ");
|
|
126
190
|
if (as === "a") {
|
|
127
191
|
const { href, ...anchorProps } = rest;
|
|
128
|
-
return /* @__PURE__ */ (0,
|
|
192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { ...anchorProps, href, className: commonClassName });
|
|
129
193
|
}
|
|
130
194
|
const { type = "button", ...buttonProps } = rest;
|
|
131
|
-
return /* @__PURE__ */ (0,
|
|
195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { ...buttonProps, type, className: commonClassName });
|
|
132
196
|
}
|
|
133
197
|
|
|
134
198
|
// src/components/card.tsx
|
|
135
|
-
var
|
|
199
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
136
200
|
function Card({ as: Component = "div", className = "", ...props }) {
|
|
137
|
-
return /* @__PURE__ */ (0,
|
|
201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
138
202
|
Component,
|
|
139
203
|
{
|
|
140
204
|
...props,
|
|
@@ -147,9 +211,9 @@ function Card({ as: Component = "div", className = "", ...props }) {
|
|
|
147
211
|
}
|
|
148
212
|
|
|
149
213
|
// src/components/checkbox.tsx
|
|
150
|
-
var
|
|
214
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
151
215
|
function Checkbox({ className = "", ...props }) {
|
|
152
|
-
return /* @__PURE__ */ (0,
|
|
216
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
153
217
|
"input",
|
|
154
218
|
{
|
|
155
219
|
...props,
|
|
@@ -159,10 +223,217 @@ function Checkbox({ className = "", ...props }) {
|
|
|
159
223
|
);
|
|
160
224
|
}
|
|
161
225
|
|
|
226
|
+
// src/components/dialog.tsx
|
|
227
|
+
var import_react2 = require("react");
|
|
228
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
229
|
+
function Dialog({ open, onOpenChange, children, className = "" }) {
|
|
230
|
+
const dialogRef = (0, import_react2.useRef)(null);
|
|
231
|
+
(0, import_react2.useEffect)(() => {
|
|
232
|
+
const handleKeyDown = (e) => {
|
|
233
|
+
if (e.key === "Escape" && open) {
|
|
234
|
+
onOpenChange(false);
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
if (open) {
|
|
238
|
+
document.body.style.overflow = "hidden";
|
|
239
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
240
|
+
} else {
|
|
241
|
+
document.body.style.overflow = "";
|
|
242
|
+
}
|
|
243
|
+
return () => {
|
|
244
|
+
document.body.style.overflow = "";
|
|
245
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
246
|
+
};
|
|
247
|
+
}, [open, onOpenChange]);
|
|
248
|
+
if (!open) return null;
|
|
249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
250
|
+
"div",
|
|
251
|
+
{
|
|
252
|
+
role: "dialog",
|
|
253
|
+
"aria-modal": "true",
|
|
254
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-950/80 backdrop-blur-md animate-in fade-in duration-200",
|
|
255
|
+
onClick: (e) => {
|
|
256
|
+
if (e.target === e.currentTarget) onOpenChange(false);
|
|
257
|
+
},
|
|
258
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
259
|
+
"div",
|
|
260
|
+
{
|
|
261
|
+
ref: dialogRef,
|
|
262
|
+
className: [
|
|
263
|
+
"relative w-full max-w-lg rounded-3xl border border-white/10 bg-slate-900/95 p-6 shadow-2xl shadow-violet-500/10 text-white animate-in zoom-in-95 duration-200",
|
|
264
|
+
className
|
|
265
|
+
].join(" "),
|
|
266
|
+
children: [
|
|
267
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
268
|
+
"button",
|
|
269
|
+
{
|
|
270
|
+
type: "button",
|
|
271
|
+
onClick: () => onOpenChange(false),
|
|
272
|
+
"aria-label": "Close dialog",
|
|
273
|
+
className: "absolute right-5 top-5 rounded-xl border border-white/10 bg-white/5 p-1.5 text-slate-400 hover:bg-white/10 hover:text-white transition cursor-pointer",
|
|
274
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
275
|
+
}
|
|
276
|
+
),
|
|
277
|
+
children
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
function DialogHeader({ children, className = "" }) {
|
|
285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: ["mb-4 space-y-1.5", className].join(" "), children });
|
|
286
|
+
}
|
|
287
|
+
function DialogTitle({ children, className = "" }) {
|
|
288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { className: ["text-xl font-bold tracking-tight text-white", className].join(" "), children });
|
|
289
|
+
}
|
|
290
|
+
function DialogDescription({ children, className = "" }) {
|
|
291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: ["text-sm text-slate-300 leading-relaxed", className].join(" "), children });
|
|
292
|
+
}
|
|
293
|
+
function DialogFooter({ children, className = "" }) {
|
|
294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: ["mt-6 flex flex-wrap items-center justify-end gap-3", className].join(" "), children });
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// src/components/drawer.tsx
|
|
298
|
+
var import_react3 = require("react");
|
|
299
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
300
|
+
function Drawer({
|
|
301
|
+
open,
|
|
302
|
+
onOpenChange,
|
|
303
|
+
position = "right",
|
|
304
|
+
children,
|
|
305
|
+
className = ""
|
|
306
|
+
}) {
|
|
307
|
+
(0, import_react3.useEffect)(() => {
|
|
308
|
+
const handleKeyDown = (e) => {
|
|
309
|
+
if (e.key === "Escape" && open) onOpenChange(false);
|
|
310
|
+
};
|
|
311
|
+
if (open) {
|
|
312
|
+
document.body.style.overflow = "hidden";
|
|
313
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
314
|
+
} else {
|
|
315
|
+
document.body.style.overflow = "";
|
|
316
|
+
}
|
|
317
|
+
return () => {
|
|
318
|
+
document.body.style.overflow = "";
|
|
319
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
320
|
+
};
|
|
321
|
+
}, [open, onOpenChange]);
|
|
322
|
+
if (!open) return null;
|
|
323
|
+
const positionClasses = {
|
|
324
|
+
right: "inset-y-0 right-0 w-full max-w-md border-l border-white/10 animate-in slide-in-from-right duration-300",
|
|
325
|
+
left: "inset-y-0 left-0 w-full max-w-md border-r border-white/10 animate-in slide-in-from-left duration-300",
|
|
326
|
+
bottom: "inset-x-0 bottom-0 max-h-[85vh] w-full border-t border-white/10 rounded-t-3xl animate-in slide-in-from-bottom duration-300"
|
|
327
|
+
};
|
|
328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
329
|
+
"div",
|
|
330
|
+
{
|
|
331
|
+
role: "dialog",
|
|
332
|
+
"aria-modal": "true",
|
|
333
|
+
className: "fixed inset-0 z-50 bg-slate-950/80 backdrop-blur-sm animate-in fade-in duration-200",
|
|
334
|
+
onClick: (e) => {
|
|
335
|
+
if (e.target === e.currentTarget) onOpenChange(false);
|
|
336
|
+
},
|
|
337
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
338
|
+
"div",
|
|
339
|
+
{
|
|
340
|
+
className: [
|
|
341
|
+
"fixed bg-slate-900/95 p-6 shadow-2xl text-white overflow-y-auto",
|
|
342
|
+
positionClasses[position],
|
|
343
|
+
className
|
|
344
|
+
].join(" "),
|
|
345
|
+
children: [
|
|
346
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
347
|
+
"button",
|
|
348
|
+
{
|
|
349
|
+
type: "button",
|
|
350
|
+
onClick: () => onOpenChange(false),
|
|
351
|
+
"aria-label": "Close drawer",
|
|
352
|
+
className: "absolute right-5 top-5 rounded-xl border border-white/10 bg-white/5 p-1.5 text-slate-400 hover:bg-white/10 hover:text-white transition cursor-pointer",
|
|
353
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
354
|
+
}
|
|
355
|
+
),
|
|
356
|
+
children
|
|
357
|
+
]
|
|
358
|
+
}
|
|
359
|
+
)
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
function DrawerHeader({ children, className = "" }) {
|
|
364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: ["mb-6 space-y-1.5", className].join(" "), children });
|
|
365
|
+
}
|
|
366
|
+
function DrawerTitle({ children, className = "" }) {
|
|
367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { className: ["text-xl font-bold tracking-tight text-white", className].join(" "), children });
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// src/components/dropdown-menu.tsx
|
|
371
|
+
var import_react4 = require("react");
|
|
372
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
373
|
+
function DropdownMenu({
|
|
374
|
+
trigger,
|
|
375
|
+
items,
|
|
376
|
+
align = "right",
|
|
377
|
+
className = ""
|
|
378
|
+
}) {
|
|
379
|
+
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
380
|
+
const menuRef = (0, import_react4.useRef)(null);
|
|
381
|
+
(0, import_react4.useEffect)(() => {
|
|
382
|
+
const handleClickOutside = (e) => {
|
|
383
|
+
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
384
|
+
setOpen(false);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
if (open) {
|
|
388
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
389
|
+
}
|
|
390
|
+
return () => {
|
|
391
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
392
|
+
};
|
|
393
|
+
}, [open]);
|
|
394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref: menuRef, className: "relative inline-block text-left", children: [
|
|
395
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { onClick: () => setOpen(!open), className: "cursor-pointer", children: trigger }),
|
|
396
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
397
|
+
"div",
|
|
398
|
+
{
|
|
399
|
+
role: "menu",
|
|
400
|
+
className: [
|
|
401
|
+
"absolute z-50 mt-2 min-w-[12rem] rounded-2xl border border-white/10 bg-slate-900/95 p-1.5 shadow-2xl backdrop-blur-xl animate-in fade-in zoom-in-95 duration-150",
|
|
402
|
+
align === "right" ? "right-0" : "left-0",
|
|
403
|
+
className
|
|
404
|
+
].join(" "),
|
|
405
|
+
children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
406
|
+
"button",
|
|
407
|
+
{
|
|
408
|
+
type: "button",
|
|
409
|
+
role: "menuitem",
|
|
410
|
+
disabled: item.disabled,
|
|
411
|
+
onClick: () => {
|
|
412
|
+
if (!item.disabled) {
|
|
413
|
+
item.onClick?.();
|
|
414
|
+
setOpen(false);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
className: [
|
|
418
|
+
"flex w-full items-center gap-2.5 rounded-xl px-3 py-2 text-xs font-medium transition cursor-pointer text-left",
|
|
419
|
+
item.disabled ? "opacity-40 cursor-not-allowed text-slate-400" : item.destructive ? "text-rose-400 hover:bg-rose-500/10 hover:text-rose-300" : "text-slate-200 hover:bg-white/10 hover:text-white"
|
|
420
|
+
].join(" "),
|
|
421
|
+
children: [
|
|
422
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "h-4 w-4 shrink-0", children: item.icon }),
|
|
423
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "flex-1", children: item.label })
|
|
424
|
+
]
|
|
425
|
+
},
|
|
426
|
+
item.id
|
|
427
|
+
))
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
] });
|
|
431
|
+
}
|
|
432
|
+
|
|
162
433
|
// src/components/input.tsx
|
|
163
|
-
var
|
|
434
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
164
435
|
function Input({ className = "", ...props }) {
|
|
165
|
-
return /* @__PURE__ */ (0,
|
|
436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
166
437
|
"input",
|
|
167
438
|
{
|
|
168
439
|
...props,
|
|
@@ -174,10 +445,58 @@ function Input({ className = "", ...props }) {
|
|
|
174
445
|
);
|
|
175
446
|
}
|
|
176
447
|
|
|
448
|
+
// src/components/progress.tsx
|
|
449
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
450
|
+
var variantGradients = {
|
|
451
|
+
primary: "from-violet-600 to-indigo-500",
|
|
452
|
+
secondary: "from-cyan-500 to-blue-500",
|
|
453
|
+
success: "from-emerald-500 to-teal-400",
|
|
454
|
+
warning: "from-amber-500 to-orange-400"
|
|
455
|
+
};
|
|
456
|
+
function Progress({
|
|
457
|
+
value = 0,
|
|
458
|
+
max = 100,
|
|
459
|
+
variant = "primary",
|
|
460
|
+
showLabel = false,
|
|
461
|
+
className = "",
|
|
462
|
+
...props
|
|
463
|
+
}) {
|
|
464
|
+
const percentage = Math.min(Math.max(value / max * 100, 0), 100);
|
|
465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: ["w-full space-y-1.5", className].join(" "), ...props, children: [
|
|
466
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex justify-between text-xs font-semibold text-slate-300", children: [
|
|
467
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Progress" }),
|
|
468
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "font-mono", children: [
|
|
469
|
+
Math.round(percentage),
|
|
470
|
+
"%"
|
|
471
|
+
] })
|
|
472
|
+
] }),
|
|
473
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
474
|
+
"div",
|
|
475
|
+
{
|
|
476
|
+
role: "progressbar",
|
|
477
|
+
"aria-valuenow": value,
|
|
478
|
+
"aria-valuemin": 0,
|
|
479
|
+
"aria-valuemax": max,
|
|
480
|
+
className: "relative h-2.5 w-full overflow-hidden rounded-full bg-slate-800 ring-1 ring-white/10",
|
|
481
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
482
|
+
"div",
|
|
483
|
+
{
|
|
484
|
+
className: [
|
|
485
|
+
"h-full rounded-full bg-gradient-to-r transition-all duration-300 ease-out shadow-sm",
|
|
486
|
+
variantGradients[variant]
|
|
487
|
+
].join(" "),
|
|
488
|
+
style: { width: `${percentage}%` }
|
|
489
|
+
}
|
|
490
|
+
)
|
|
491
|
+
}
|
|
492
|
+
)
|
|
493
|
+
] });
|
|
494
|
+
}
|
|
495
|
+
|
|
177
496
|
// src/components/select.tsx
|
|
178
|
-
var
|
|
497
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
179
498
|
function Select({ className = "", children, ...props }) {
|
|
180
|
-
return /* @__PURE__ */ (0,
|
|
499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
181
500
|
"select",
|
|
182
501
|
{
|
|
183
502
|
...props,
|
|
@@ -191,7 +510,7 @@ function Select({ className = "", children, ...props }) {
|
|
|
191
510
|
}
|
|
192
511
|
|
|
193
512
|
// src/components/skeleton.tsx
|
|
194
|
-
var
|
|
513
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
195
514
|
var roundedClasses = {
|
|
196
515
|
sm: "rounded-md",
|
|
197
516
|
md: "rounded-xl",
|
|
@@ -199,7 +518,7 @@ var roundedClasses = {
|
|
|
199
518
|
full: "rounded-full"
|
|
200
519
|
};
|
|
201
520
|
function Skeleton({ className = "", rounded = "md", ...props }) {
|
|
202
|
-
return /* @__PURE__ */ (0,
|
|
521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
203
522
|
"div",
|
|
204
523
|
{
|
|
205
524
|
...props,
|
|
@@ -209,15 +528,54 @@ function Skeleton({ className = "", rounded = "md", ...props }) {
|
|
|
209
528
|
);
|
|
210
529
|
}
|
|
211
530
|
|
|
531
|
+
// src/components/switch.tsx
|
|
532
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
533
|
+
function Switch({
|
|
534
|
+
checked,
|
|
535
|
+
defaultChecked = false,
|
|
536
|
+
onCheckedChange,
|
|
537
|
+
disabled = false,
|
|
538
|
+
className = "",
|
|
539
|
+
id,
|
|
540
|
+
"aria-label": ariaLabel
|
|
541
|
+
}) {
|
|
542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
543
|
+
"button",
|
|
544
|
+
{
|
|
545
|
+
type: "button",
|
|
546
|
+
role: "switch",
|
|
547
|
+
id,
|
|
548
|
+
"aria-label": ariaLabel,
|
|
549
|
+
"aria-checked": checked ?? defaultChecked,
|
|
550
|
+
disabled,
|
|
551
|
+
onClick: () => onCheckedChange?.(!checked),
|
|
552
|
+
className: [
|
|
553
|
+
"relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950 disabled:cursor-not-allowed disabled:opacity-50",
|
|
554
|
+
checked ?? defaultChecked ? "bg-violet-600" : "bg-slate-800",
|
|
555
|
+
className
|
|
556
|
+
].join(" "),
|
|
557
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
558
|
+
"span",
|
|
559
|
+
{
|
|
560
|
+
className: [
|
|
561
|
+
"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out",
|
|
562
|
+
checked ?? defaultChecked ? "translate-x-5" : "translate-x-0"
|
|
563
|
+
].join(" ")
|
|
564
|
+
}
|
|
565
|
+
)
|
|
566
|
+
}
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
|
|
212
570
|
// src/components/tabs.tsx
|
|
213
|
-
var
|
|
214
|
-
var
|
|
571
|
+
var import_react5 = require("react");
|
|
572
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
215
573
|
function Tabs({ items, defaultTab, className = "" }) {
|
|
216
574
|
const initialTab = defaultTab ?? items[0]?.id ?? "";
|
|
217
|
-
const [activeTab, setActiveTab] = (0,
|
|
575
|
+
const [activeTab, setActiveTab] = (0, import_react5.useState)(initialTab);
|
|
218
576
|
const activeItem = items.find((item) => item.id === activeTab) ?? items[0];
|
|
219
|
-
return /* @__PURE__ */ (0,
|
|
220
|
-
/* @__PURE__ */ (0,
|
|
577
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className, children: [
|
|
578
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "mb-4 flex flex-wrap gap-2", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
221
579
|
"button",
|
|
222
580
|
{
|
|
223
581
|
type: "button",
|
|
@@ -230,14 +588,14 @@ function Tabs({ items, defaultTab, className = "" }) {
|
|
|
230
588
|
},
|
|
231
589
|
item.id
|
|
232
590
|
)) }),
|
|
233
|
-
/* @__PURE__ */ (0,
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "rounded-2xl border border-white/10 bg-slate-950/60 p-4 text-sm text-slate-200", children: activeItem?.content })
|
|
234
592
|
] });
|
|
235
593
|
}
|
|
236
594
|
|
|
237
595
|
// src/components/textarea.tsx
|
|
238
|
-
var
|
|
596
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
239
597
|
function Textarea({ className = "", ...props }) {
|
|
240
|
-
return /* @__PURE__ */ (0,
|
|
598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
241
599
|
"textarea",
|
|
242
600
|
{
|
|
243
601
|
...props,
|
|
@@ -249,6 +607,130 @@ function Textarea({ className = "", ...props }) {
|
|
|
249
607
|
);
|
|
250
608
|
}
|
|
251
609
|
|
|
610
|
+
// src/components/toast.tsx
|
|
611
|
+
var import_react6 = require("react");
|
|
612
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
613
|
+
var toasts = [];
|
|
614
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
615
|
+
function notify() {
|
|
616
|
+
listeners.forEach((l) => l([...toasts]));
|
|
617
|
+
}
|
|
618
|
+
var toast = {
|
|
619
|
+
show(message, options) {
|
|
620
|
+
const id = Math.random().toString(36).substring(2, 9);
|
|
621
|
+
const newToast = {
|
|
622
|
+
id,
|
|
623
|
+
message,
|
|
624
|
+
type: options?.type || "info",
|
|
625
|
+
title: options?.title,
|
|
626
|
+
duration: options?.duration || 4e3
|
|
627
|
+
};
|
|
628
|
+
toasts = [...toasts, newToast];
|
|
629
|
+
notify();
|
|
630
|
+
setTimeout(() => {
|
|
631
|
+
toast.dismiss(id);
|
|
632
|
+
}, newToast.duration);
|
|
633
|
+
return id;
|
|
634
|
+
},
|
|
635
|
+
success(message, title) {
|
|
636
|
+
return toast.show(message, { type: "success", title });
|
|
637
|
+
},
|
|
638
|
+
error(message, title) {
|
|
639
|
+
return toast.show(message, { type: "error", title });
|
|
640
|
+
},
|
|
641
|
+
info(message, title) {
|
|
642
|
+
return toast.show(message, { type: "info", title });
|
|
643
|
+
},
|
|
644
|
+
dismiss(id) {
|
|
645
|
+
toasts = toasts.filter((t) => t.id !== id);
|
|
646
|
+
notify();
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
function Toaster() {
|
|
650
|
+
const [activeToasts, setActiveToasts] = (0, import_react6.useState)([]);
|
|
651
|
+
(0, import_react6.useEffect)(() => {
|
|
652
|
+
listeners.add(setActiveToasts);
|
|
653
|
+
return () => {
|
|
654
|
+
listeners.delete(setActiveToasts);
|
|
655
|
+
};
|
|
656
|
+
}, []);
|
|
657
|
+
if (activeToasts.length === 0) return null;
|
|
658
|
+
const typeStyles = {
|
|
659
|
+
success: "border-emerald-500/40 bg-slate-900/95 text-emerald-100 shadow-emerald-500/10",
|
|
660
|
+
error: "border-rose-500/40 bg-slate-900/95 text-rose-100 shadow-rose-500/10",
|
|
661
|
+
info: "border-cyan-500/40 bg-slate-900/95 text-cyan-100 shadow-cyan-500/10",
|
|
662
|
+
warning: "border-amber-500/40 bg-slate-900/95 text-amber-100 shadow-amber-500/10"
|
|
663
|
+
};
|
|
664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fixed bottom-5 right-5 z-50 flex flex-col gap-2.5 max-w-sm w-full pointer-events-none", children: activeToasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
665
|
+
"div",
|
|
666
|
+
{
|
|
667
|
+
className: [
|
|
668
|
+
"pointer-events-auto flex items-start justify-between rounded-2xl border p-4 shadow-xl backdrop-blur-md animate-in slide-in-from-bottom-5 duration-200",
|
|
669
|
+
typeStyles[t.type || "info"]
|
|
670
|
+
].join(" "),
|
|
671
|
+
children: [
|
|
672
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-1", children: [
|
|
673
|
+
t.title && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "font-semibold text-xs tracking-wide uppercase text-white", children: t.title }),
|
|
674
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium", children: t.message })
|
|
675
|
+
] }),
|
|
676
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
677
|
+
"button",
|
|
678
|
+
{
|
|
679
|
+
type: "button",
|
|
680
|
+
onClick: () => toast.dismiss(t.id),
|
|
681
|
+
className: "ml-3 text-slate-400 hover:text-white transition cursor-pointer",
|
|
682
|
+
children: "\xD7"
|
|
683
|
+
}
|
|
684
|
+
)
|
|
685
|
+
]
|
|
686
|
+
},
|
|
687
|
+
t.id
|
|
688
|
+
)) });
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// src/components/tooltip.tsx
|
|
692
|
+
var import_react7 = require("react");
|
|
693
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
694
|
+
function Tooltip({
|
|
695
|
+
content,
|
|
696
|
+
children,
|
|
697
|
+
side = "top",
|
|
698
|
+
className = ""
|
|
699
|
+
}) {
|
|
700
|
+
const [isVisible, setIsVisible] = (0, import_react7.useState)(false);
|
|
701
|
+
const sideClasses = {
|
|
702
|
+
top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
703
|
+
bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
|
|
704
|
+
left: "right-full top-1/2 -translate-y-1/2 mr-2",
|
|
705
|
+
right: "left-full top-1/2 -translate-y-1/2 ml-2"
|
|
706
|
+
};
|
|
707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
708
|
+
"div",
|
|
709
|
+
{
|
|
710
|
+
className: "relative inline-flex",
|
|
711
|
+
onMouseEnter: () => setIsVisible(true),
|
|
712
|
+
onMouseLeave: () => setIsVisible(false),
|
|
713
|
+
onFocus: () => setIsVisible(true),
|
|
714
|
+
onBlur: () => setIsVisible(false),
|
|
715
|
+
children: [
|
|
716
|
+
children,
|
|
717
|
+
isVisible && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
718
|
+
"div",
|
|
719
|
+
{
|
|
720
|
+
role: "tooltip",
|
|
721
|
+
className: [
|
|
722
|
+
"absolute z-50 whitespace-nowrap rounded-lg border border-white/10 bg-slate-900/95 px-2.5 py-1 text-xs font-medium text-slate-200 shadow-xl backdrop-blur-md animate-in fade-in zoom-in-95 duration-150 pointer-events-none",
|
|
723
|
+
sideClasses[side],
|
|
724
|
+
className
|
|
725
|
+
].join(" "),
|
|
726
|
+
children: content
|
|
727
|
+
}
|
|
728
|
+
)
|
|
729
|
+
]
|
|
730
|
+
}
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
|
|
252
734
|
// src/tokens/index.ts
|
|
253
735
|
var themeTokens = {
|
|
254
736
|
colors: {
|
|
@@ -267,17 +749,32 @@ var themeTokens = {
|
|
|
267
749
|
var cx = (...classes) => classes.filter(Boolean).join(" ");
|
|
268
750
|
// Annotate the CommonJS export names for ESM import in node:
|
|
269
751
|
0 && (module.exports = {
|
|
752
|
+
Accordion,
|
|
270
753
|
Alert,
|
|
271
754
|
Avatar,
|
|
272
755
|
Badge,
|
|
273
756
|
Button,
|
|
274
757
|
Card,
|
|
275
758
|
Checkbox,
|
|
759
|
+
Dialog,
|
|
760
|
+
DialogDescription,
|
|
761
|
+
DialogFooter,
|
|
762
|
+
DialogHeader,
|
|
763
|
+
DialogTitle,
|
|
764
|
+
Drawer,
|
|
765
|
+
DrawerHeader,
|
|
766
|
+
DrawerTitle,
|
|
767
|
+
DropdownMenu,
|
|
276
768
|
Input,
|
|
769
|
+
Progress,
|
|
277
770
|
Select,
|
|
278
771
|
Skeleton,
|
|
772
|
+
Switch,
|
|
279
773
|
Tabs,
|
|
280
774
|
Textarea,
|
|
775
|
+
Toaster,
|
|
776
|
+
Tooltip,
|
|
281
777
|
cx,
|
|
282
|
-
themeTokens
|
|
778
|
+
themeTokens,
|
|
779
|
+
toast
|
|
283
780
|
});
|