@stackvibe-studio/ui 0.1.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
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ "use client";
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -20,24 +21,143 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
21
  // src/index.ts
21
22
  var index_exports = {};
22
23
  __export(index_exports, {
24
+ Accordion: () => Accordion,
25
+ Alert: () => Alert,
26
+ Avatar: () => Avatar,
23
27
  Badge: () => Badge,
24
28
  Button: () => Button,
25
29
  Card: () => Card,
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,
26
40
  Input: () => Input,
41
+ Progress: () => Progress,
42
+ Select: () => Select,
43
+ Skeleton: () => Skeleton,
44
+ Switch: () => Switch,
45
+ Tabs: () => Tabs,
46
+ Textarea: () => Textarea,
47
+ Toaster: () => Toaster,
48
+ Tooltip: () => Tooltip,
27
49
  cx: () => cx,
28
- themeTokens: () => themeTokens
50
+ themeTokens: () => themeTokens,
51
+ toast: () => toast
29
52
  });
30
53
  module.exports = __toCommonJS(index_exports);
31
54
 
32
- // src/components/badge.tsx
55
+ // src/components/accordion.tsx
56
+ var import_react = require("react");
33
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");
106
+ var variantClasses = {
107
+ info: "border-cyan-500/40 bg-cyan-500/10 text-cyan-50",
108
+ success: "border-emerald-500/40 bg-emerald-500/10 text-emerald-50",
109
+ warning: "border-amber-500/40 bg-amber-500/10 text-amber-50",
110
+ danger: "border-rose-500/40 bg-rose-500/10 text-rose-50"
111
+ };
112
+ function Alert({ title, variant = "info", className = "", children, ...props }) {
113
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
114
+ "div",
115
+ {
116
+ ...props,
117
+ className: ["rounded-2xl border p-4 text-sm", variantClasses[variant], className].join(" "),
118
+ role: "alert",
119
+ 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 })
122
+ ]
123
+ }
124
+ );
125
+ }
126
+
127
+ // src/components/avatar.tsx
128
+ var import_jsx_runtime3 = require("react/jsx-runtime");
129
+ var sizeClasses = {
130
+ sm: "h-9 w-9 text-xs",
131
+ md: "h-12 w-12 text-sm",
132
+ lg: "h-16 w-16 text-base"
133
+ };
134
+ function Avatar({ src, alt = "avatar", fallback = "SV", size = "md", className = "", ...props }) {
135
+ return src ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
136
+ "img",
137
+ {
138
+ ...props,
139
+ src,
140
+ alt,
141
+ className: ["rounded-full object-cover ring-1 ring-white/10", sizeClasses[size], className].join(" ")
142
+ }
143
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
144
+ "div",
145
+ {
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(" "),
147
+ children: fallback
148
+ }
149
+ );
150
+ }
151
+
152
+ // src/components/badge.tsx
153
+ var import_jsx_runtime4 = require("react/jsx-runtime");
34
154
  var variants = {
35
155
  primary: "bg-violet-500/20 text-violet-200 ring-1 ring-violet-400/20",
36
156
  secondary: "bg-cyan-500/15 text-cyan-200 ring-1 ring-cyan-400/20",
37
157
  outline: "bg-transparent text-slate-200 ring-1 ring-white/10"
38
158
  };
39
159
  function Badge({ variant = "primary", className = "", ...props }) {
40
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
160
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
41
161
  "span",
42
162
  {
43
163
  ...props,
@@ -47,37 +167,38 @@ function Badge({ variant = "primary", className = "", ...props }) {
47
167
  }
48
168
 
49
169
  // src/components/button.tsx
50
- var import_jsx_runtime2 = require("react/jsx-runtime");
51
- var variantClasses = {
170
+ var import_jsx_runtime5 = require("react/jsx-runtime");
171
+ var variantClasses2 = {
52
172
  primary: "bg-violet-500 text-white hover:bg-violet-400",
53
173
  secondary: "bg-cyan-500 text-slate-950 hover:bg-cyan-400",
54
174
  ghost: "bg-white/5 text-white hover:bg-white/10",
55
175
  outline: "border border-white/15 bg-transparent text-white hover:bg-white/5"
56
176
  };
57
- var sizeClasses = {
177
+ var sizeClasses2 = {
58
178
  sm: "px-3 py-1.5 text-sm",
59
179
  md: "px-4 py-2 text-sm",
60
180
  lg: "px-5 py-3 text-base"
61
181
  };
62
- function Button({ variant = "primary", size = "md", className = "", ...props }) {
63
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
64
- "button",
65
- {
66
- ...props,
67
- className: [
68
- "inline-flex items-center justify-center rounded-xl font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400",
69
- variantClasses[variant],
70
- sizeClasses[size],
71
- className
72
- ].join(" ")
73
- }
74
- );
182
+ function Button(props) {
183
+ const { as = "button", variant = "primary", size = "md", className = "", ...rest } = props;
184
+ const commonClassName = [
185
+ "inline-flex items-center justify-center rounded-xl font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400",
186
+ variantClasses2[variant],
187
+ sizeClasses2[size],
188
+ className
189
+ ].join(" ");
190
+ if (as === "a") {
191
+ const { href, ...anchorProps } = rest;
192
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { ...anchorProps, href, className: commonClassName });
193
+ }
194
+ const { type = "button", ...buttonProps } = rest;
195
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { ...buttonProps, type, className: commonClassName });
75
196
  }
76
197
 
77
198
  // src/components/card.tsx
78
- var import_jsx_runtime3 = require("react/jsx-runtime");
199
+ var import_jsx_runtime6 = require("react/jsx-runtime");
79
200
  function Card({ as: Component = "div", className = "", ...props }) {
80
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
201
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
81
202
  Component,
82
203
  {
83
204
  ...props,
@@ -89,10 +210,230 @@ function Card({ as: Component = "div", className = "", ...props }) {
89
210
  );
90
211
  }
91
212
 
213
+ // src/components/checkbox.tsx
214
+ var import_jsx_runtime7 = require("react/jsx-runtime");
215
+ function Checkbox({ className = "", ...props }) {
216
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
217
+ "input",
218
+ {
219
+ ...props,
220
+ type: "checkbox",
221
+ className: ["h-4 w-4 rounded border border-white/20 bg-slate-900 text-violet-500 focus:ring-violet-400/40", className].join(" ")
222
+ }
223
+ );
224
+ }
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
+
92
433
  // src/components/input.tsx
93
- var import_jsx_runtime4 = require("react/jsx-runtime");
434
+ var import_jsx_runtime11 = require("react/jsx-runtime");
94
435
  function Input({ className = "", ...props }) {
95
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
436
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
96
437
  "input",
97
438
  {
98
439
  ...props,
@@ -104,6 +445,292 @@ function Input({ className = "", ...props }) {
104
445
  );
105
446
  }
106
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
+
496
+ // src/components/select.tsx
497
+ var import_jsx_runtime13 = require("react/jsx-runtime");
498
+ function Select({ className = "", children, ...props }) {
499
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
500
+ "select",
501
+ {
502
+ ...props,
503
+ className: [
504
+ "w-full rounded-xl border border-white/10 bg-slate-900 px-3 py-2 text-sm text-white focus:border-violet-400 focus:outline-none focus:ring-2 focus:ring-violet-400/30",
505
+ className
506
+ ].join(" "),
507
+ children
508
+ }
509
+ );
510
+ }
511
+
512
+ // src/components/skeleton.tsx
513
+ var import_jsx_runtime14 = require("react/jsx-runtime");
514
+ var roundedClasses = {
515
+ sm: "rounded-md",
516
+ md: "rounded-xl",
517
+ lg: "rounded-2xl",
518
+ full: "rounded-full"
519
+ };
520
+ function Skeleton({ className = "", rounded = "md", ...props }) {
521
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
522
+ "div",
523
+ {
524
+ ...props,
525
+ className: ["animate-pulse bg-slate-700/70", roundedClasses[rounded], className].join(" "),
526
+ "aria-hidden": "true"
527
+ }
528
+ );
529
+ }
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
+
570
+ // src/components/tabs.tsx
571
+ var import_react5 = require("react");
572
+ var import_jsx_runtime16 = require("react/jsx-runtime");
573
+ function Tabs({ items, defaultTab, className = "" }) {
574
+ const initialTab = defaultTab ?? items[0]?.id ?? "";
575
+ const [activeTab, setActiveTab] = (0, import_react5.useState)(initialTab);
576
+ const activeItem = items.find((item) => item.id === activeTab) ?? items[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)(
579
+ "button",
580
+ {
581
+ type: "button",
582
+ onClick: () => setActiveTab(item.id),
583
+ className: [
584
+ "rounded-full px-3 py-1.5 text-sm transition",
585
+ item.id === activeItem?.id ? "bg-violet-500 text-white shadow-lg shadow-violet-500/20" : "bg-slate-800 text-slate-300 hover:bg-slate-700 hover:text-white"
586
+ ].join(" "),
587
+ children: item.label
588
+ },
589
+ item.id
590
+ )) }),
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 })
592
+ ] });
593
+ }
594
+
595
+ // src/components/textarea.tsx
596
+ var import_jsx_runtime17 = require("react/jsx-runtime");
597
+ function Textarea({ className = "", ...props }) {
598
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
599
+ "textarea",
600
+ {
601
+ ...props,
602
+ className: [
603
+ "w-full rounded-xl border border-white/10 bg-slate-900 px-3 py-2 text-sm text-white placeholder:text-slate-400 focus:border-violet-400 focus:outline-none focus:ring-2 focus:ring-violet-400/30",
604
+ className
605
+ ].join(" ")
606
+ }
607
+ );
608
+ }
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
+
107
734
  // src/tokens/index.ts
108
735
  var themeTokens = {
109
736
  colors: {
@@ -122,10 +749,32 @@ var themeTokens = {
122
749
  var cx = (...classes) => classes.filter(Boolean).join(" ");
123
750
  // Annotate the CommonJS export names for ESM import in node:
124
751
  0 && (module.exports = {
752
+ Accordion,
753
+ Alert,
754
+ Avatar,
125
755
  Badge,
126
756
  Button,
127
757
  Card,
758
+ Checkbox,
759
+ Dialog,
760
+ DialogDescription,
761
+ DialogFooter,
762
+ DialogHeader,
763
+ DialogTitle,
764
+ Drawer,
765
+ DrawerHeader,
766
+ DrawerTitle,
767
+ DropdownMenu,
128
768
  Input,
769
+ Progress,
770
+ Select,
771
+ Skeleton,
772
+ Switch,
773
+ Tabs,
774
+ Textarea,
775
+ Toaster,
776
+ Tooltip,
129
777
  cx,
130
- themeTokens
778
+ themeTokens,
779
+ toast
131
780
  });