@exitvibing/hqui 0.1.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.mjs ADDED
@@ -0,0 +1,988 @@
1
+ // src/lib/cn.ts
2
+ import { clsx } from "clsx";
3
+ import { twMerge } from "tailwind-merge";
4
+ function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ // src/components/Button.tsx
9
+ import { forwardRef } from "react";
10
+ import { jsx } from "react/jsx-runtime";
11
+ var variants = {
12
+ primary: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
13
+ secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
14
+ destructive: "bg-[hsl(var(--red))] text-white shadow-sm hover:bg-[hsl(var(--red))]/90",
15
+ outline: "border border-border bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground",
16
+ ghost: "hover:bg-accent hover:text-accent-foreground",
17
+ purple: "bg-[hsl(var(--purple))] text-white shadow-sm hover:bg-[hsl(var(--purple))]/90",
18
+ orange: "bg-[hsl(var(--orange))] text-white shadow-sm hover:bg-[hsl(var(--orange))]/90",
19
+ blue: "bg-[hsl(var(--blue))] text-white shadow-sm hover:bg-[hsl(var(--blue))]/90",
20
+ green: "bg-[hsl(var(--green))] text-white shadow-sm hover:bg-[hsl(var(--green))]/90"
21
+ };
22
+ var sizes = {
23
+ sm: "h-8 rounded-md px-3 text-xs gap-1.5",
24
+ default: "h-9 px-4 py-2 text-sm gap-2",
25
+ lg: "h-10 rounded-md px-6 text-base gap-2",
26
+ icon: "h-9 w-9 p-0"
27
+ };
28
+ var Button = forwardRef(
29
+ ({ className, variant = "primary", size = "default", ...props }, ref) => {
30
+ return /* @__PURE__ */ jsx(
31
+ "button",
32
+ {
33
+ ref,
34
+ className: cn(
35
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
36
+ variants[variant],
37
+ sizes[size],
38
+ className
39
+ ),
40
+ ...props
41
+ }
42
+ );
43
+ }
44
+ );
45
+ Button.displayName = "Button";
46
+
47
+ // src/components/Card.tsx
48
+ import { forwardRef as forwardRef2 } from "react";
49
+ import { jsx as jsx2 } from "react/jsx-runtime";
50
+ var Card = forwardRef2(
51
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx2(
52
+ "div",
53
+ {
54
+ ref,
55
+ className: cn(
56
+ "rounded-xl border border-border bg-card text-card-foreground shadow-sm transition-shadow hover:shadow-md",
57
+ className
58
+ ),
59
+ ...props
60
+ }
61
+ )
62
+ );
63
+ Card.displayName = "Card";
64
+ var CardHeader = forwardRef2(({ className, ...props }, ref) => /* @__PURE__ */ jsx2(
65
+ "div",
66
+ {
67
+ ref,
68
+ className: cn("flex flex-col space-y-1.5 p-6 pb-4", className),
69
+ ...props
70
+ }
71
+ ));
72
+ CardHeader.displayName = "CardHeader";
73
+ var CardTitle = forwardRef2(({ className, ...props }, ref) => /* @__PURE__ */ jsx2(
74
+ "h3",
75
+ {
76
+ ref,
77
+ className: cn("font-semibold leading-none tracking-tight", className),
78
+ ...props
79
+ }
80
+ ));
81
+ CardTitle.displayName = "CardTitle";
82
+ var CardDescription = forwardRef2(({ className, ...props }, ref) => /* @__PURE__ */ jsx2(
83
+ "p",
84
+ {
85
+ ref,
86
+ className: cn("text-sm text-muted-foreground", className),
87
+ ...props
88
+ }
89
+ ));
90
+ CardDescription.displayName = "CardDescription";
91
+ var CardContent = forwardRef2(({ className, ...props }, ref) => /* @__PURE__ */ jsx2("div", { ref, className: cn("p-6 pt-0", className), ...props }));
92
+ CardContent.displayName = "CardContent";
93
+ var CardFooter = forwardRef2(({ className, ...props }, ref) => /* @__PURE__ */ jsx2(
94
+ "div",
95
+ {
96
+ ref,
97
+ className: cn("flex items-center p-6 pt-0", className),
98
+ ...props
99
+ }
100
+ ));
101
+ CardFooter.displayName = "CardFooter";
102
+
103
+ // src/components/Input.tsx
104
+ import { forwardRef as forwardRef3 } from "react";
105
+ import { jsx as jsx3 } from "react/jsx-runtime";
106
+ var Input = forwardRef3(
107
+ ({ className, type = "text", ...props }, ref) => {
108
+ return /* @__PURE__ */ jsx3(
109
+ "input",
110
+ {
111
+ type,
112
+ className: cn(
113
+ "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
114
+ className
115
+ ),
116
+ ref,
117
+ ...props
118
+ }
119
+ );
120
+ }
121
+ );
122
+ Input.displayName = "Input";
123
+
124
+ // src/components/Checkbox.tsx
125
+ import React4, { forwardRef as forwardRef4 } from "react";
126
+ import { Check } from "lucide-react";
127
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
128
+ var Checkbox = forwardRef4(
129
+ ({ className, label, id, ...props }, ref) => {
130
+ const defaultId = React4.useId();
131
+ const inputId = id || defaultId;
132
+ return /* @__PURE__ */ jsxs(
133
+ "label",
134
+ {
135
+ htmlFor: inputId,
136
+ className: cn(
137
+ "flex items-center gap-2 cursor-pointer select-none",
138
+ className
139
+ ),
140
+ children: [
141
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
142
+ /* @__PURE__ */ jsx4(
143
+ "input",
144
+ {
145
+ id: inputId,
146
+ type: "checkbox",
147
+ className: "peer h-4 w-4 shrink-0 rounded-sm border border-foreground/30 shadow appearance-none focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 checked:bg-foreground checked:border-foreground",
148
+ ref,
149
+ ...props
150
+ }
151
+ ),
152
+ /* @__PURE__ */ jsx4(
153
+ Check,
154
+ {
155
+ className: "absolute h-3 w-3 text-background pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity",
156
+ strokeWidth: 3
157
+ }
158
+ )
159
+ ] }),
160
+ label && /* @__PURE__ */ jsx4("span", { className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: label })
161
+ ]
162
+ }
163
+ );
164
+ }
165
+ );
166
+ Checkbox.displayName = "Checkbox";
167
+
168
+ // src/components/ProgressBar.tsx
169
+ import { forwardRef as forwardRef5 } from "react";
170
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
171
+ var colorClasses = {
172
+ white: "bg-foreground",
173
+ purple: "bg-[hsl(var(--purple))]",
174
+ orange: "bg-[hsl(var(--orange))]",
175
+ blue: "bg-[hsl(var(--blue))]",
176
+ green: "bg-[hsl(var(--green))]"
177
+ };
178
+ var ProgressBar = forwardRef5(
179
+ ({
180
+ className,
181
+ value = 0,
182
+ max = 100,
183
+ showLabel = false,
184
+ color = "white",
185
+ ...props
186
+ }, ref) => {
187
+ const percentage = Math.min(Math.max(0, value / max * 100), 100);
188
+ return /* @__PURE__ */ jsxs2("div", { className: cn("flex items-center gap-3", showLabel && "w-full"), children: [
189
+ /* @__PURE__ */ jsx5(
190
+ "div",
191
+ {
192
+ ref,
193
+ role: "progressbar",
194
+ "aria-valuemin": 0,
195
+ "aria-valuemax": max,
196
+ "aria-valuenow": value,
197
+ className: cn(
198
+ "relative h-2 w-full overflow-hidden rounded-full bg-secondary",
199
+ className
200
+ ),
201
+ ...props,
202
+ children: /* @__PURE__ */ jsx5(
203
+ "div",
204
+ {
205
+ className: cn(
206
+ "h-full rounded-full transition-all duration-500 ease-out",
207
+ colorClasses[color]
208
+ ),
209
+ style: { width: `${percentage}%` }
210
+ }
211
+ )
212
+ }
213
+ ),
214
+ showLabel && /* @__PURE__ */ jsxs2("span", { className: "text-xs font-medium text-muted-foreground tabular-nums w-10 text-right", children: [
215
+ Math.round(percentage),
216
+ "%"
217
+ ] })
218
+ ] });
219
+ }
220
+ );
221
+ ProgressBar.displayName = "ProgressBar";
222
+
223
+ // src/components/Table.tsx
224
+ import {
225
+ forwardRef as forwardRef6
226
+ } from "react";
227
+ import { jsx as jsx6 } from "react/jsx-runtime";
228
+ var Table = forwardRef6(({ className, ...props }, ref) => /* @__PURE__ */ jsx6("div", { className: "relative w-full overflow-auto rounded-lg border border-border", children: /* @__PURE__ */ jsx6(
229
+ "table",
230
+ {
231
+ ref,
232
+ className: cn("w-full caption-bottom text-sm", className),
233
+ ...props
234
+ }
235
+ ) }));
236
+ Table.displayName = "Table";
237
+ var TableHeader = forwardRef6(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
238
+ "thead",
239
+ {
240
+ ref,
241
+ className: cn("bg-muted/50 [&_tr]:border-b", className),
242
+ ...props
243
+ }
244
+ ));
245
+ TableHeader.displayName = "TableHeader";
246
+ var TableBody = forwardRef6(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
247
+ "tbody",
248
+ {
249
+ ref,
250
+ className: cn("[&_tr:last-child]:border-0", className),
251
+ ...props
252
+ }
253
+ ));
254
+ TableBody.displayName = "TableBody";
255
+ var TableRow = forwardRef6(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
256
+ "tr",
257
+ {
258
+ ref,
259
+ className: cn(
260
+ "border-b border-border transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
261
+ className
262
+ ),
263
+ ...props
264
+ }
265
+ ));
266
+ TableRow.displayName = "TableRow";
267
+ var TableHead = forwardRef6(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
268
+ "th",
269
+ {
270
+ ref,
271
+ className: cn(
272
+ "h-10 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
273
+ className
274
+ ),
275
+ ...props
276
+ }
277
+ ));
278
+ TableHead.displayName = "TableHead";
279
+ var TableCell = forwardRef6(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
280
+ "td",
281
+ {
282
+ ref,
283
+ className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className),
284
+ ...props
285
+ }
286
+ ));
287
+ TableCell.displayName = "TableCell";
288
+
289
+ // src/components/HighlightText.tsx
290
+ import { forwardRef as forwardRef7 } from "react";
291
+ import { jsx as jsx7 } from "react/jsx-runtime";
292
+ var HighlightText = forwardRef7(
293
+ ({ className, children, ...props }, ref) => {
294
+ return /* @__PURE__ */ jsx7(
295
+ "span",
296
+ {
297
+ ref,
298
+ className: cn(
299
+ "bg-foreground text-background px-1.5 py-0.5 rounded font-medium",
300
+ className
301
+ ),
302
+ ...props,
303
+ children
304
+ }
305
+ );
306
+ }
307
+ );
308
+ HighlightText.displayName = "HighlightText";
309
+
310
+ // src/components/Badge.tsx
311
+ import { forwardRef as forwardRef8 } from "react";
312
+ import { jsx as jsx8 } from "react/jsx-runtime";
313
+ var colorVariants = {
314
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/80",
315
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
316
+ outline: "border border-border text-foreground",
317
+ white: "bg-foreground/10 text-foreground border border-foreground/20",
318
+ destructive: "bg-[hsl(var(--red))] text-white shadow hover:bg-[hsl(var(--red))]/80",
319
+ purple: "bg-[hsl(var(--purple))]/15 text-[hsl(var(--purple))] border border-[hsl(var(--purple))]/20",
320
+ orange: "bg-[hsl(var(--orange))]/15 text-[hsl(var(--orange))] border border-[hsl(var(--orange))]/20",
321
+ blue: "bg-[hsl(var(--blue))]/15 text-[hsl(var(--blue))] border border-[hsl(var(--blue))]/20",
322
+ green: "bg-[hsl(var(--green))]/15 text-[hsl(var(--green))] border border-[hsl(var(--green))]/20",
323
+ red: "bg-[hsl(var(--red))]/15 text-[hsl(var(--red))] border border-[hsl(var(--red))]/20"
324
+ };
325
+ var Badge = forwardRef8(
326
+ ({ className, variant = "default", ...props }, ref) => {
327
+ return /* @__PURE__ */ jsx8(
328
+ "span",
329
+ {
330
+ ref,
331
+ className: cn(
332
+ "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-semibold transition-colors",
333
+ colorVariants[variant],
334
+ className
335
+ ),
336
+ ...props
337
+ }
338
+ );
339
+ }
340
+ );
341
+ Badge.displayName = "Badge";
342
+
343
+ // src/components/Separator.tsx
344
+ import { forwardRef as forwardRef9 } from "react";
345
+ import { jsx as jsx9 } from "react/jsx-runtime";
346
+ var Separator = forwardRef9(
347
+ ({ className, orientation = "horizontal", ...props }, ref) => {
348
+ return /* @__PURE__ */ jsx9(
349
+ "div",
350
+ {
351
+ ref,
352
+ role: "separator",
353
+ "aria-orientation": orientation,
354
+ className: cn(
355
+ "shrink-0 bg-border",
356
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
357
+ className
358
+ ),
359
+ ...props
360
+ }
361
+ );
362
+ }
363
+ );
364
+ Separator.displayName = "Separator";
365
+
366
+ // src/components/Tabs.tsx
367
+ import { createContext, useContext, useState, forwardRef as forwardRef10 } from "react";
368
+ import { jsx as jsx10 } from "react/jsx-runtime";
369
+ var TabsContext = createContext({
370
+ value: "",
371
+ onValueChange: () => {
372
+ }
373
+ });
374
+ var Tabs = forwardRef10(
375
+ ({
376
+ className,
377
+ defaultValue = "",
378
+ value: controlledValue,
379
+ onValueChange,
380
+ children,
381
+ ...props
382
+ }, ref) => {
383
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
384
+ const isControlled = controlledValue !== void 0;
385
+ const currentValue = isControlled ? controlledValue : uncontrolledValue;
386
+ const handleChange = (newValue) => {
387
+ if (!isControlled) setUncontrolledValue(newValue);
388
+ onValueChange?.(newValue);
389
+ };
390
+ return /* @__PURE__ */ jsx10(
391
+ TabsContext.Provider,
392
+ {
393
+ value: { value: currentValue, onValueChange: handleChange },
394
+ children: /* @__PURE__ */ jsx10("div", { ref, className: cn("w-full", className), ...props, children })
395
+ }
396
+ );
397
+ }
398
+ );
399
+ Tabs.displayName = "Tabs";
400
+ var TabsList = forwardRef10(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(
401
+ "div",
402
+ {
403
+ ref,
404
+ className: cn(
405
+ "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
406
+ className
407
+ ),
408
+ ...props
409
+ }
410
+ ));
411
+ TabsList.displayName = "TabsList";
412
+ var TabsTrigger = forwardRef10(
413
+ ({ className, value, ...props }, ref) => {
414
+ const ctx = useContext(TabsContext);
415
+ const isActive = ctx.value === value;
416
+ return /* @__PURE__ */ jsx10(
417
+ "button",
418
+ {
419
+ ref,
420
+ type: "button",
421
+ role: "tab",
422
+ "aria-selected": isActive,
423
+ "data-state": isActive ? "active" : "inactive",
424
+ className: cn(
425
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
426
+ isActive ? "bg-background text-foreground shadow" : "hover:bg-background/50 hover:text-foreground",
427
+ className
428
+ ),
429
+ onClick: () => ctx.onValueChange(value),
430
+ ...props
431
+ }
432
+ );
433
+ }
434
+ );
435
+ TabsTrigger.displayName = "TabsTrigger";
436
+ var TabsContent = forwardRef10(
437
+ ({ className, value, ...props }, ref) => {
438
+ const ctx = useContext(TabsContext);
439
+ if (ctx.value !== value) return null;
440
+ return /* @__PURE__ */ jsx10(
441
+ "div",
442
+ {
443
+ ref,
444
+ role: "tabpanel",
445
+ className: cn(
446
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 animate-fade-in",
447
+ className
448
+ ),
449
+ ...props
450
+ }
451
+ );
452
+ }
453
+ );
454
+ TabsContent.displayName = "TabsContent";
455
+
456
+ // src/components/Switch.tsx
457
+ import React11, { forwardRef as forwardRef11 } from "react";
458
+ import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
459
+ var Switch = forwardRef11(
460
+ ({ className, label, id, ...props }, ref) => {
461
+ const defaultId = React11.useId();
462
+ const inputId = id || defaultId;
463
+ return /* @__PURE__ */ jsxs3(
464
+ "label",
465
+ {
466
+ htmlFor: inputId,
467
+ className: cn(
468
+ "inline-flex items-center gap-2 cursor-pointer select-none",
469
+ className
470
+ ),
471
+ children: [
472
+ /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
473
+ /* @__PURE__ */ jsx11(
474
+ "input",
475
+ {
476
+ id: inputId,
477
+ type: "checkbox",
478
+ role: "switch",
479
+ className: "peer sr-only",
480
+ ref,
481
+ ...props
482
+ }
483
+ ),
484
+ /* @__PURE__ */ jsx11("div", { className: "h-5 w-9 rounded-full border-2 border-transparent bg-input transition-colors peer-checked:bg-foreground peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-background peer-disabled:cursor-not-allowed peer-disabled:opacity-50" }),
485
+ /* @__PURE__ */ jsx11("div", { className: "absolute left-0.5 top-0.5 h-4 w-4 rounded-full bg-background shadow-lg transition-transform peer-checked:translate-x-4 peer-checked:bg-background" })
486
+ ] }),
487
+ label && /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium leading-none", children: label })
488
+ ]
489
+ }
490
+ );
491
+ }
492
+ );
493
+ Switch.displayName = "Switch";
494
+
495
+ // src/components/Tooltip.tsx
496
+ import {
497
+ forwardRef as forwardRef12,
498
+ useState as useState2,
499
+ useRef,
500
+ useEffect,
501
+ useCallback
502
+ } from "react";
503
+ import { Fragment, jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
504
+ var Tooltip = forwardRef12(
505
+ ({ className, content, side = "top", delayMs = 200, children, ...props }, ref) => {
506
+ const [visible, setVisible] = useState2(false);
507
+ const timeoutRef = useRef();
508
+ const wrapperRef = useRef(null);
509
+ const tooltipRef = useRef(null);
510
+ const [position, setPosition] = useState2({ top: 0, left: 0 });
511
+ const show = () => {
512
+ timeoutRef.current = setTimeout(() => setVisible(true), delayMs);
513
+ };
514
+ const hide = () => {
515
+ clearTimeout(timeoutRef.current);
516
+ setVisible(false);
517
+ };
518
+ const updatePosition = useCallback(() => {
519
+ if (!wrapperRef.current || !tooltipRef.current) return;
520
+ const trigger = wrapperRef.current.getBoundingClientRect();
521
+ const tip = tooltipRef.current.getBoundingClientRect();
522
+ const gap = 8;
523
+ let top = 0;
524
+ let left = 0;
525
+ switch (side) {
526
+ case "top":
527
+ top = trigger.top - tip.height - gap;
528
+ left = trigger.left + trigger.width / 2 - tip.width / 2;
529
+ break;
530
+ case "bottom":
531
+ top = trigger.bottom + gap;
532
+ left = trigger.left + trigger.width / 2 - tip.width / 2;
533
+ break;
534
+ case "left":
535
+ top = trigger.top + trigger.height / 2 - tip.height / 2;
536
+ left = trigger.left - tip.width - gap;
537
+ break;
538
+ case "right":
539
+ top = trigger.top + trigger.height / 2 - tip.height / 2;
540
+ left = trigger.right + gap;
541
+ break;
542
+ }
543
+ setPosition({ top, left });
544
+ }, [side]);
545
+ useEffect(() => {
546
+ if (visible) {
547
+ requestAnimationFrame(updatePosition);
548
+ }
549
+ }, [visible, updatePosition]);
550
+ useEffect(() => {
551
+ return () => clearTimeout(timeoutRef.current);
552
+ }, []);
553
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
554
+ /* @__PURE__ */ jsx12(
555
+ "div",
556
+ {
557
+ ref: (node) => {
558
+ wrapperRef.current = node;
559
+ if (typeof ref === "function") ref(node);
560
+ else if (ref)
561
+ ref.current = node;
562
+ },
563
+ className: cn("inline-flex", className),
564
+ onMouseEnter: show,
565
+ onMouseLeave: hide,
566
+ onFocus: show,
567
+ onBlur: hide,
568
+ ...props,
569
+ children
570
+ }
571
+ ),
572
+ visible && /* @__PURE__ */ jsx12(
573
+ "div",
574
+ {
575
+ ref: tooltipRef,
576
+ role: "tooltip",
577
+ className: "fixed z-[9999] rounded-md bg-foreground px-3 py-1.5 text-xs text-background shadow-md whitespace-nowrap pointer-events-none",
578
+ style: {
579
+ top: position.top,
580
+ left: position.left,
581
+ animation: "popup-fade-in 0.1s ease-out"
582
+ },
583
+ children: content
584
+ }
585
+ )
586
+ ] });
587
+ }
588
+ );
589
+ Tooltip.displayName = "Tooltip";
590
+
591
+ // src/components/ThemeToggle.tsx
592
+ import { forwardRef as forwardRef13, useEffect as useEffect2, useState as useState3 } from "react";
593
+ import { Moon, Sun } from "lucide-react";
594
+ import { jsx as jsx13 } from "react/jsx-runtime";
595
+ var ThemeToggle = forwardRef13(
596
+ ({ className, defaultTheme }, ref) => {
597
+ const [isDark, setIsDark] = useState3(() => {
598
+ if (typeof window === "undefined") return defaultTheme === "dark";
599
+ return document.documentElement.classList.contains("dark");
600
+ });
601
+ useEffect2(() => {
602
+ if (isDark) {
603
+ document.documentElement.classList.add("dark");
604
+ } else {
605
+ document.documentElement.classList.remove("dark");
606
+ }
607
+ }, [isDark]);
608
+ return /* @__PURE__ */ jsx13(
609
+ Button,
610
+ {
611
+ ref,
612
+ variant: "ghost",
613
+ size: "icon",
614
+ className: cn("rounded-full", className),
615
+ onClick: () => setIsDark((prev) => !prev),
616
+ "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode",
617
+ children: isDark ? /* @__PURE__ */ jsx13(Sun, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx13(Moon, { className: "h-4 w-4" })
618
+ }
619
+ );
620
+ }
621
+ );
622
+ ThemeToggle.displayName = "ThemeToggle";
623
+
624
+ // src/components/extended/Counter.tsx
625
+ import { useState as useState4, forwardRef as forwardRef14 } from "react";
626
+ import { Plus, Minus } from "lucide-react";
627
+ import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
628
+ var Counter = forwardRef14(
629
+ ({
630
+ initialValue = 0,
631
+ min = Number.MIN_SAFE_INTEGER,
632
+ max = Number.MAX_SAFE_INTEGER,
633
+ step = 1,
634
+ onChange,
635
+ className
636
+ }, ref) => {
637
+ const [value, setValue] = useState4(initialValue);
638
+ const handleIncrement = () => {
639
+ const next = Math.min(max, value + step);
640
+ setValue(next);
641
+ onChange?.(next);
642
+ };
643
+ const handleDecrement = () => {
644
+ const next = Math.max(min, value - step);
645
+ setValue(next);
646
+ onChange?.(next);
647
+ };
648
+ return /* @__PURE__ */ jsxs5(
649
+ "div",
650
+ {
651
+ ref,
652
+ className: cn(
653
+ "inline-flex items-center rounded-lg border border-border bg-card",
654
+ className
655
+ ),
656
+ children: [
657
+ /* @__PURE__ */ jsx14(
658
+ Button,
659
+ {
660
+ variant: "ghost",
661
+ size: "icon",
662
+ className: "h-8 w-8 rounded-r-none",
663
+ onClick: handleDecrement,
664
+ disabled: value <= min,
665
+ children: /* @__PURE__ */ jsx14(Minus, { className: "h-3.5 w-3.5" })
666
+ }
667
+ ),
668
+ /* @__PURE__ */ jsx14("span", { className: "w-10 text-center text-sm font-medium tabular-nums border-x border-border", children: value }),
669
+ /* @__PURE__ */ jsx14(
670
+ Button,
671
+ {
672
+ variant: "ghost",
673
+ size: "icon",
674
+ className: "h-8 w-8 rounded-l-none",
675
+ onClick: handleIncrement,
676
+ disabled: value >= max,
677
+ children: /* @__PURE__ */ jsx14(Plus, { className: "h-3.5 w-3.5" })
678
+ }
679
+ )
680
+ ]
681
+ }
682
+ );
683
+ }
684
+ );
685
+ Counter.displayName = "Counter";
686
+
687
+ // src/components/extended/ArrowButton.tsx
688
+ import { forwardRef as forwardRef15 } from "react";
689
+ import { ChevronLeft, ChevronRight } from "lucide-react";
690
+ import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
691
+ var ArrowButton = forwardRef15(
692
+ ({ direction = "right", text, className, children, ...props }, ref) => {
693
+ const Icon = direction === "left" ? ChevronLeft : ChevronRight;
694
+ return /* @__PURE__ */ jsxs6(
695
+ Button,
696
+ {
697
+ ref,
698
+ className: cn("gap-1", !text && !children && "px-2", className),
699
+ ...props,
700
+ children: [
701
+ direction === "left" && /* @__PURE__ */ jsx15(Icon, { className: "h-4 w-4" }),
702
+ (text || children) && /* @__PURE__ */ jsx15("span", { children: text || children }),
703
+ direction === "right" && /* @__PURE__ */ jsx15(Icon, { className: "h-4 w-4" })
704
+ ]
705
+ }
706
+ );
707
+ }
708
+ );
709
+ ArrowButton.displayName = "ArrowButton";
710
+
711
+ // src/components/extended/ChooseList.tsx
712
+ import { forwardRef as forwardRef16 } from "react";
713
+ import { ChevronDown } from "lucide-react";
714
+ import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
715
+ var ChooseList = forwardRef16(
716
+ ({ className, options, ...props }, ref) => {
717
+ return /* @__PURE__ */ jsxs7("div", { className: "relative inline-block w-full", children: [
718
+ /* @__PURE__ */ jsx16(
719
+ "select",
720
+ {
721
+ ref,
722
+ className: cn(
723
+ "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring appearance-none cursor-pointer pr-10",
724
+ className
725
+ ),
726
+ ...props,
727
+ children: options.map((opt) => /* @__PURE__ */ jsx16(
728
+ "option",
729
+ {
730
+ value: opt.value,
731
+ className: "bg-card text-foreground",
732
+ children: opt.label
733
+ },
734
+ opt.value
735
+ ))
736
+ }
737
+ ),
738
+ /* @__PURE__ */ jsx16("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center px-3 text-muted-foreground", children: /* @__PURE__ */ jsx16(ChevronDown, { className: "h-4 w-4" }) })
739
+ ] });
740
+ }
741
+ );
742
+ ChooseList.displayName = "ChooseList";
743
+
744
+ // src/components/extended/Popup.tsx
745
+ import { forwardRef as forwardRef17, useEffect as useEffect3 } from "react";
746
+ import { X } from "lucide-react";
747
+ import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
748
+ var Popup = forwardRef17(
749
+ ({ className, open, onClose, title, children, ...props }, ref) => {
750
+ useEffect3(() => {
751
+ if (open) {
752
+ document.body.style.overflow = "hidden";
753
+ } else {
754
+ document.body.style.overflow = "";
755
+ }
756
+ return () => {
757
+ document.body.style.overflow = "";
758
+ };
759
+ }, [open]);
760
+ useEffect3(() => {
761
+ const handleEscape = (e) => {
762
+ if (e.key === "Escape") onClose();
763
+ };
764
+ if (open) document.addEventListener("keydown", handleEscape);
765
+ return () => document.removeEventListener("keydown", handleEscape);
766
+ }, [open, onClose]);
767
+ if (!open) return null;
768
+ return /* @__PURE__ */ jsxs8("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
769
+ /* @__PURE__ */ jsx17(
770
+ "div",
771
+ {
772
+ className: "fixed inset-0 bg-background/80 backdrop-blur-sm",
773
+ style: { animation: "popup-fade-in 0.15s ease-out" },
774
+ onClick: onClose
775
+ }
776
+ ),
777
+ /* @__PURE__ */ jsxs8(
778
+ "div",
779
+ {
780
+ ref,
781
+ role: "dialog",
782
+ "aria-modal": "true",
783
+ className: cn(
784
+ "relative z-50 w-full max-w-lg rounded-xl border border-border bg-card p-6 shadow-2xl",
785
+ className
786
+ ),
787
+ style: { animation: "popup-scale-in 0.15s ease-out" },
788
+ ...props,
789
+ children: [
790
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between mb-4", children: [
791
+ title && /* @__PURE__ */ jsx17("h2", { className: "text-lg font-semibold tracking-tight", children: title }),
792
+ /* @__PURE__ */ jsx17(
793
+ Button,
794
+ {
795
+ variant: "ghost",
796
+ size: "icon",
797
+ className: "h-7 w-7 rounded-full ml-auto",
798
+ onClick: onClose,
799
+ "aria-label": "Close popup",
800
+ children: /* @__PURE__ */ jsx17(X, { className: "h-4 w-4" })
801
+ }
802
+ )
803
+ ] }),
804
+ /* @__PURE__ */ jsx17("div", { className: "text-sm text-muted-foreground", children })
805
+ ]
806
+ }
807
+ )
808
+ ] });
809
+ }
810
+ );
811
+ Popup.displayName = "Popup";
812
+
813
+ // src/components/extended/StatusBar.tsx
814
+ import { forwardRef as forwardRef18 } from "react";
815
+ import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
816
+ var statusStyles = {
817
+ idle: "bg-muted-foreground",
818
+ working: "bg-[hsl(var(--blue))] animate-pulse",
819
+ error: "bg-[hsl(var(--orange))]",
820
+ ready: "bg-[hsl(var(--purple))]",
821
+ live: "bg-[hsl(var(--purple))] animate-pulse"
822
+ };
823
+ var StatusBar = forwardRef18(
824
+ ({ className, status = "idle", label, children, ...props }, ref) => {
825
+ return /* @__PURE__ */ jsxs9(
826
+ "div",
827
+ {
828
+ ref,
829
+ role: "status",
830
+ className: cn(
831
+ "inline-flex items-center gap-2 rounded-full border border-border bg-card px-3 py-1",
832
+ className
833
+ ),
834
+ ...props,
835
+ children: [
836
+ /* @__PURE__ */ jsx18(
837
+ "span",
838
+ {
839
+ className: cn("h-2 w-2 rounded-full", statusStyles[status]),
840
+ "aria-hidden": "true"
841
+ }
842
+ ),
843
+ /* @__PURE__ */ jsx18("span", { className: "text-xs font-semibold uppercase tracking-wider", children: label || status }),
844
+ children && /* @__PURE__ */ jsx18("span", { className: "text-xs text-muted-foreground border-l border-border pl-2", children })
845
+ ]
846
+ }
847
+ );
848
+ }
849
+ );
850
+ StatusBar.displayName = "StatusBar";
851
+
852
+ // src/components/extended/WeekViewCalendar.tsx
853
+ import { forwardRef as forwardRef19 } from "react";
854
+ import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
855
+ var WeekViewCalendar = forwardRef19(({ className, events = [], startHour = 8, endHour = 18, ...props }, ref) => {
856
+ const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
857
+ const hours = Array.from(
858
+ { length: endHour - startHour },
859
+ (_, i) => i + startHour
860
+ );
861
+ return /* @__PURE__ */ jsxs10(
862
+ "div",
863
+ {
864
+ ref,
865
+ className: cn(
866
+ "flex flex-col rounded-lg border border-border overflow-hidden bg-card",
867
+ className
868
+ ),
869
+ ...props,
870
+ children: [
871
+ /* @__PURE__ */ jsxs10("div", { className: "grid grid-cols-8 border-b border-border bg-muted/30", children: [
872
+ /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center border-r border-border p-2 text-xs font-medium text-muted-foreground w-16", children: "Time" }),
873
+ days.map((day, i) => /* @__PURE__ */ jsx19(
874
+ "div",
875
+ {
876
+ className: cn(
877
+ "p-2 text-center text-sm font-semibold",
878
+ i < 6 && "border-r border-border"
879
+ ),
880
+ children: day
881
+ },
882
+ day
883
+ ))
884
+ ] }),
885
+ /* @__PURE__ */ jsxs10("div", { className: "relative overflow-y-auto max-h-[500px] custom-scrollbar", children: [
886
+ hours.map((hour, hIndex) => /* @__PURE__ */ jsxs10(
887
+ "div",
888
+ {
889
+ className: cn(
890
+ "grid grid-cols-8",
891
+ hIndex < hours.length - 1 && "border-b border-border/50"
892
+ ),
893
+ children: [
894
+ /* @__PURE__ */ jsx19("div", { className: "flex items-start justify-center border-r border-border p-2 text-xs text-muted-foreground w-16 sticky left-0 bg-card", children: `${hour === 0 ? 12 : hour > 12 ? hour - 12 : hour} ${hour >= 12 ? "PM" : "AM"}` }),
895
+ days.map((_, dIndex) => /* @__PURE__ */ jsx19(
896
+ "div",
897
+ {
898
+ className: cn(
899
+ "h-16 relative",
900
+ dIndex < 6 && "border-r border-border/50"
901
+ )
902
+ },
903
+ dIndex
904
+ ))
905
+ ]
906
+ },
907
+ hour
908
+ )),
909
+ /* @__PURE__ */ jsx19(
910
+ "div",
911
+ {
912
+ className: "absolute inset-0 z-10 pointer-events-none",
913
+ style: { paddingLeft: "4rem" },
914
+ children: /* @__PURE__ */ jsx19("div", { className: "relative w-full h-full", children: events.map((event) => {
915
+ if (event.startHour < startHour || event.startHour >= endHour)
916
+ return null;
917
+ const top = (event.startHour - startHour) / (endHour - startHour) * 100;
918
+ const height = event.durationHours / (endHour - startHour) * 100;
919
+ const left = event.dayIndex / 7 * 100;
920
+ const width = 100 / 7;
921
+ return /* @__PURE__ */ jsx19(
922
+ "div",
923
+ {
924
+ className: "absolute p-0.5 pointer-events-auto",
925
+ style: {
926
+ top: `${top}%`,
927
+ left: `${left}%`,
928
+ height: `${height}%`,
929
+ width: `${width}%`
930
+ },
931
+ children: /* @__PURE__ */ jsx19(
932
+ "div",
933
+ {
934
+ className: "h-full w-full rounded-md border border-white/10 p-1.5 text-xs font-semibold text-white overflow-hidden shadow-sm transition-transform hover:scale-[1.02] hover:shadow-md cursor-pointer",
935
+ style: {
936
+ backgroundColor: event.color || "hsl(var(--primary))"
937
+ },
938
+ title: event.title,
939
+ children: event.title
940
+ }
941
+ )
942
+ },
943
+ event.id
944
+ );
945
+ }) })
946
+ }
947
+ )
948
+ ] })
949
+ ]
950
+ }
951
+ );
952
+ });
953
+ WeekViewCalendar.displayName = "WeekViewCalendar";
954
+ export {
955
+ ArrowButton,
956
+ Badge,
957
+ Button,
958
+ Card,
959
+ CardContent,
960
+ CardDescription,
961
+ CardFooter,
962
+ CardHeader,
963
+ CardTitle,
964
+ Checkbox,
965
+ ChooseList,
966
+ Counter,
967
+ HighlightText,
968
+ Input,
969
+ Popup,
970
+ ProgressBar,
971
+ Separator,
972
+ StatusBar,
973
+ Switch,
974
+ Table,
975
+ TableBody,
976
+ TableCell,
977
+ TableHead,
978
+ TableHeader,
979
+ TableRow,
980
+ Tabs,
981
+ TabsContent,
982
+ TabsList,
983
+ TabsTrigger,
984
+ ThemeToggle,
985
+ Tooltip,
986
+ WeekViewCalendar,
987
+ cn
988
+ };