@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/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/alert.tsx
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, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsx)("p", { className: "mb-1 font-medium", children: title }) : null,
57
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children })
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 import_jsx_runtime2 = require("react/jsx-runtime");
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, import_jsx_runtime2.jsx)(
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, import_jsx_runtime2.jsx)(
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 import_jsx_runtime3 = require("react/jsx-runtime");
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, import_jsx_runtime3.jsx)(
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 import_jsx_runtime4 = require("react/jsx-runtime");
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, import_jsx_runtime4.jsx)("a", { ...anchorProps, href, className: commonClassName });
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, import_jsx_runtime4.jsx)("button", { ...buttonProps, type, className: commonClassName });
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 import_jsx_runtime5 = require("react/jsx-runtime");
199
+ var import_jsx_runtime6 = require("react/jsx-runtime");
136
200
  function Card({ as: Component = "div", className = "", ...props }) {
137
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
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 import_jsx_runtime6 = require("react/jsx-runtime");
214
+ var import_jsx_runtime7 = require("react/jsx-runtime");
151
215
  function Checkbox({ className = "", ...props }) {
152
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
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 import_jsx_runtime7 = require("react/jsx-runtime");
434
+ var import_jsx_runtime11 = require("react/jsx-runtime");
164
435
  function Input({ className = "", ...props }) {
165
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
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 import_jsx_runtime8 = require("react/jsx-runtime");
497
+ var import_jsx_runtime13 = require("react/jsx-runtime");
179
498
  function Select({ className = "", children, ...props }) {
180
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
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 import_jsx_runtime9 = require("react/jsx-runtime");
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, import_jsx_runtime9.jsx)(
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 import_react = require("react");
214
- var import_jsx_runtime10 = require("react/jsx-runtime");
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, import_react.useState)(initialTab);
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, import_jsx_runtime10.jsxs)("div", { className, children: [
220
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mb-4 flex flex-wrap gap-2", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
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, import_jsx_runtime10.jsx)("div", { className: "rounded-2xl border border-white/10 bg-slate-950/60 p-4 text-sm text-slate-200", children: activeItem?.content })
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 import_jsx_runtime11 = require("react/jsx-runtime");
596
+ var import_jsx_runtime17 = require("react/jsx-runtime");
239
597
  function Textarea({ className = "", ...props }) {
240
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
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
  });