@thangnqdev/ui 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.
Files changed (253) hide show
  1. package/README.md +196 -0
  2. package/dist/Label-DWOlgSNW.d.cts +14 -0
  3. package/dist/Label-DWOlgSNW.d.ts +14 -0
  4. package/dist/bento/index.cjs +140 -0
  5. package/dist/bento/index.cjs.map +1 -0
  6. package/dist/bento/index.d.cts +4 -0
  7. package/dist/bento/index.d.ts +4 -0
  8. package/dist/bento/index.js +4 -0
  9. package/dist/bento/index.js.map +1 -0
  10. package/dist/bento/styles.css +46 -0
  11. package/dist/buttons/index.cjs +365 -0
  12. package/dist/buttons/index.cjs.map +1 -0
  13. package/dist/buttons/index.d.cts +4 -0
  14. package/dist/buttons/index.d.ts +4 -0
  15. package/dist/buttons/index.js +5 -0
  16. package/dist/buttons/index.js.map +1 -0
  17. package/dist/buttons/styles.css +6 -0
  18. package/dist/chunk-2OXZK6IP.js +514 -0
  19. package/dist/chunk-2OXZK6IP.js.map +1 -0
  20. package/dist/chunk-4S6L5V7X.js +15 -0
  21. package/dist/chunk-4S6L5V7X.js.map +1 -0
  22. package/dist/chunk-5FZ6ZFII.js +728 -0
  23. package/dist/chunk-5FZ6ZFII.js.map +1 -0
  24. package/dist/chunk-66VWUJEI.js +86 -0
  25. package/dist/chunk-66VWUJEI.js.map +1 -0
  26. package/dist/chunk-A7P3O5Z5.js +163 -0
  27. package/dist/chunk-A7P3O5Z5.js.map +1 -0
  28. package/dist/chunk-ATYGDTMK.js +257 -0
  29. package/dist/chunk-ATYGDTMK.js.map +1 -0
  30. package/dist/chunk-C4SUXMI3.js +138 -0
  31. package/dist/chunk-C4SUXMI3.js.map +1 -0
  32. package/dist/chunk-EU2LPUYP.js +25 -0
  33. package/dist/chunk-EU2LPUYP.js.map +1 -0
  34. package/dist/chunk-F5Q7BTMH.js +1991 -0
  35. package/dist/chunk-F5Q7BTMH.js.map +1 -0
  36. package/dist/chunk-GXI2H5XA.js +46 -0
  37. package/dist/chunk-GXI2H5XA.js.map +1 -0
  38. package/dist/chunk-H3LCNPMC.js +101 -0
  39. package/dist/chunk-H3LCNPMC.js.map +1 -0
  40. package/dist/chunk-IABPUCAQ.js +19 -0
  41. package/dist/chunk-IABPUCAQ.js.map +1 -0
  42. package/dist/chunk-KJRBRTQE.js +101 -0
  43. package/dist/chunk-KJRBRTQE.js.map +1 -0
  44. package/dist/chunk-LBUBXUYQ.js +40 -0
  45. package/dist/chunk-LBUBXUYQ.js.map +1 -0
  46. package/dist/chunk-LWFRUJRU.js +537 -0
  47. package/dist/chunk-LWFRUJRU.js.map +1 -0
  48. package/dist/chunk-NFVONJUK.js +882 -0
  49. package/dist/chunk-NFVONJUK.js.map +1 -0
  50. package/dist/chunk-PF4ZHGVW.js +284 -0
  51. package/dist/chunk-PF4ZHGVW.js.map +1 -0
  52. package/dist/chunk-WAFHC4DQ.js +366 -0
  53. package/dist/chunk-WAFHC4DQ.js.map +1 -0
  54. package/dist/chunk-X76KBH4Y.js +71 -0
  55. package/dist/chunk-X76KBH4Y.js.map +1 -0
  56. package/dist/core/index.cjs +103 -0
  57. package/dist/core/index.cjs.map +1 -0
  58. package/dist/core/index.d.cts +3 -0
  59. package/dist/core/index.d.ts +3 -0
  60. package/dist/core/index.js +4 -0
  61. package/dist/core/index.js.map +1 -0
  62. package/dist/core/styles.css +128 -0
  63. package/dist/data-display/index.cjs +1023 -0
  64. package/dist/data-display/index.cjs.map +1 -0
  65. package/dist/data-display/index.d.cts +4 -0
  66. package/dist/data-display/index.d.ts +4 -0
  67. package/dist/data-display/index.js +6 -0
  68. package/dist/data-display/index.js.map +1 -0
  69. package/dist/data-display/styles.css +4 -0
  70. package/dist/feedback/index.cjs +368 -0
  71. package/dist/feedback/index.cjs.map +1 -0
  72. package/dist/feedback/index.d.cts +4 -0
  73. package/dist/feedback/index.d.ts +4 -0
  74. package/dist/feedback/index.js +4 -0
  75. package/dist/feedback/index.js.map +1 -0
  76. package/dist/feedback/styles.css +4 -0
  77. package/dist/forms/index.cjs +2287 -0
  78. package/dist/forms/index.cjs.map +1 -0
  79. package/dist/forms/index.d.cts +5 -0
  80. package/dist/forms/index.d.ts +5 -0
  81. package/dist/forms/index.js +10 -0
  82. package/dist/forms/index.js.map +1 -0
  83. package/dist/forms/styles.css +6 -0
  84. package/dist/glass/index.cjs +165 -0
  85. package/dist/glass/index.cjs.map +1 -0
  86. package/dist/glass/index.d.cts +4 -0
  87. package/dist/glass/index.d.ts +4 -0
  88. package/dist/glass/index.js +4 -0
  89. package/dist/glass/index.js.map +1 -0
  90. package/dist/glass/styles.css +81 -0
  91. package/dist/index-BTvkbCIj.d.cts +146 -0
  92. package/dist/index-BTvkbCIj.d.ts +146 -0
  93. package/dist/index-BkRqGNG1.d.cts +201 -0
  94. package/dist/index-BkRqGNG1.d.ts +201 -0
  95. package/dist/index-BlPcGeW-.d.cts +45 -0
  96. package/dist/index-BlPcGeW-.d.ts +45 -0
  97. package/dist/index-BzOCqvC6.d.cts +32 -0
  98. package/dist/index-BzOCqvC6.d.ts +32 -0
  99. package/dist/index-CCeWYAvn.d.cts +83 -0
  100. package/dist/index-COQ7uwt9.d.cts +44 -0
  101. package/dist/index-COQ7uwt9.d.ts +44 -0
  102. package/dist/index-CenuF_P2.d.cts +221 -0
  103. package/dist/index-CenuF_P2.d.ts +221 -0
  104. package/dist/index-Cle6QzQl.d.ts +371 -0
  105. package/dist/index-D6fE7w-b.d.cts +90 -0
  106. package/dist/index-D6fE7w-b.d.ts +90 -0
  107. package/dist/index-DR8cfJUG.d.ts +83 -0
  108. package/dist/index-DzcWh1Hs.d.cts +131 -0
  109. package/dist/index-DzcWh1Hs.d.ts +131 -0
  110. package/dist/index-TyK-Ldpy.d.cts +371 -0
  111. package/dist/index-ugj5s6a3.d.cts +95 -0
  112. package/dist/index-ugj5s6a3.d.ts +95 -0
  113. package/dist/index.cjs +6400 -0
  114. package/dist/index.cjs.map +1 -0
  115. package/dist/index.d.cts +16 -0
  116. package/dist/index.d.ts +16 -0
  117. package/dist/index.js +21 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/layout/index.cjs +516 -0
  120. package/dist/layout/index.cjs.map +1 -0
  121. package/dist/layout/index.d.cts +4 -0
  122. package/dist/layout/index.d.ts +4 -0
  123. package/dist/layout/index.js +4 -0
  124. package/dist/layout/index.js.map +1 -0
  125. package/dist/layout/styles.css +8 -0
  126. package/dist/navigation/index.cjs +673 -0
  127. package/dist/navigation/index.cjs.map +1 -0
  128. package/dist/navigation/index.d.cts +2 -0
  129. package/dist/navigation/index.d.ts +2 -0
  130. package/dist/navigation/index.js +8 -0
  131. package/dist/navigation/index.js.map +1 -0
  132. package/dist/navigation/styles.css +4 -0
  133. package/dist/overlays/index.cjs +954 -0
  134. package/dist/overlays/index.cjs.map +1 -0
  135. package/dist/overlays/index.d.cts +4 -0
  136. package/dist/overlays/index.d.ts +4 -0
  137. package/dist/overlays/index.js +9 -0
  138. package/dist/overlays/index.js.map +1 -0
  139. package/dist/overlays/styles.css +8 -0
  140. package/dist/styles.css +333 -0
  141. package/dist/typography/index.cjs +311 -0
  142. package/dist/typography/index.cjs.map +1 -0
  143. package/dist/typography/index.d.cts +5 -0
  144. package/dist/typography/index.d.ts +5 -0
  145. package/dist/typography/index.js +6 -0
  146. package/dist/typography/index.js.map +1 -0
  147. package/dist/typography/styles.css +5 -0
  148. package/llms.txt +113 -0
  149. package/package.json +116 -0
  150. package/src/bento/BentoCard.tsx +140 -0
  151. package/src/bento/BentoGrid.tsx +50 -0
  152. package/src/bento/index.ts +2 -0
  153. package/src/bento/tokens.css +46 -0
  154. package/src/buttons/Button.tsx +104 -0
  155. package/src/buttons/ButtonGroup.tsx +43 -0
  156. package/src/buttons/IconButton.tsx +79 -0
  157. package/src/buttons/SplitButton.tsx +86 -0
  158. package/src/buttons/ToggleButton.tsx +157 -0
  159. package/src/buttons/index.ts +5 -0
  160. package/src/buttons/tokens.css +6 -0
  161. package/src/core/ThemeProvider.tsx +123 -0
  162. package/src/core/index.ts +2 -0
  163. package/src/core/tokens.css +128 -0
  164. package/src/data-display/Accordion.tsx +147 -0
  165. package/src/data-display/Avatar.tsx +134 -0
  166. package/src/data-display/Card.tsx +112 -0
  167. package/src/data-display/Carousel.tsx +130 -0
  168. package/src/data-display/Chip.tsx +74 -0
  169. package/src/data-display/DataTablePro.tsx +356 -0
  170. package/src/data-display/StatCard.tsx +60 -0
  171. package/src/data-display/Table.tsx +74 -0
  172. package/src/data-display/Timeline.tsx +62 -0
  173. package/src/data-display/TreeView.tsx +140 -0
  174. package/src/data-display/index.ts +10 -0
  175. package/src/data-display/tokens.css +4 -0
  176. package/src/feedback/Alert.tsx +80 -0
  177. package/src/feedback/EmptyState.tsx +45 -0
  178. package/src/feedback/ProgressBar.tsx +174 -0
  179. package/src/feedback/Skeleton.tsx +66 -0
  180. package/src/feedback/Spinner.tsx +65 -0
  181. package/src/feedback/index.ts +5 -0
  182. package/src/feedback/tokens.css +4 -0
  183. package/src/forms/Checkbox.tsx +69 -0
  184. package/src/forms/CheckboxGroup.tsx +29 -0
  185. package/src/forms/Combobox.tsx +368 -0
  186. package/src/forms/DatePicker.tsx +480 -0
  187. package/src/forms/FileUpload.tsx +222 -0
  188. package/src/forms/FormField.tsx +115 -0
  189. package/src/forms/Input.tsx +151 -0
  190. package/src/forms/MaskedInput.tsx +97 -0
  191. package/src/forms/NumberInput.tsx +248 -0
  192. package/src/forms/PasswordInput.tsx +35 -0
  193. package/src/forms/PinInput.tsx +125 -0
  194. package/src/forms/Radio.tsx +142 -0
  195. package/src/forms/RangeSlider.tsx +111 -0
  196. package/src/forms/SearchInput.tsx +34 -0
  197. package/src/forms/Select.tsx +103 -0
  198. package/src/forms/Slider.tsx +85 -0
  199. package/src/forms/Switch.tsx +95 -0
  200. package/src/forms/Textarea.tsx +114 -0
  201. package/src/forms/index.ts +18 -0
  202. package/src/forms/tokens.css +6 -0
  203. package/src/glass/GlassBadge.tsx +61 -0
  204. package/src/glass/GlassButton.tsx +59 -0
  205. package/src/glass/GlassCard.tsx +71 -0
  206. package/src/glass/index.ts +3 -0
  207. package/src/glass/tokens.css +81 -0
  208. package/src/index.ts +26 -0
  209. package/src/layout/AspectRatio.tsx +39 -0
  210. package/src/layout/Container.tsx +53 -0
  211. package/src/layout/Divider.tsx +61 -0
  212. package/src/layout/Flex.tsx +79 -0
  213. package/src/layout/Grid.tsx +124 -0
  214. package/src/layout/PageLayout.tsx +59 -0
  215. package/src/layout/ScrollArea.tsx +43 -0
  216. package/src/layout/Section.tsx +47 -0
  217. package/src/layout/Spacer.tsx +30 -0
  218. package/src/layout/Stack.tsx +88 -0
  219. package/src/layout/index.ts +10 -0
  220. package/src/layout/tokens.css +8 -0
  221. package/src/navigation/Breadcrumb.tsx +73 -0
  222. package/src/navigation/CommandPalette.tsx +142 -0
  223. package/src/navigation/DropdownMenu.tsx +160 -0
  224. package/src/navigation/Pagination.tsx +114 -0
  225. package/src/navigation/Stepper.tsx +93 -0
  226. package/src/navigation/Tabs.tsx +133 -0
  227. package/src/navigation/index.ts +6 -0
  228. package/src/navigation/tokens.css +4 -0
  229. package/src/overlays/AlertDialog.tsx +54 -0
  230. package/src/overlays/BottomSheet.tsx +123 -0
  231. package/src/overlays/ContextMenu.tsx +119 -0
  232. package/src/overlays/Drawer.tsx +145 -0
  233. package/src/overlays/FocusTrap.tsx +49 -0
  234. package/src/overlays/HoverCard.tsx +72 -0
  235. package/src/overlays/Modal.tsx +219 -0
  236. package/src/overlays/Popover.tsx +126 -0
  237. package/src/overlays/Portal.tsx +23 -0
  238. package/src/overlays/Toast.tsx +137 -0
  239. package/src/overlays/Tooltip.tsx +100 -0
  240. package/src/overlays/index.ts +11 -0
  241. package/src/overlays/tokens.css +8 -0
  242. package/src/styles/tokens.css +2 -0
  243. package/src/typography/Blockquote.tsx +32 -0
  244. package/src/typography/Code.tsx +89 -0
  245. package/src/typography/Heading.tsx +56 -0
  246. package/src/typography/Kbd.tsx +25 -0
  247. package/src/typography/Label.tsx +47 -0
  248. package/src/typography/Link.tsx +56 -0
  249. package/src/typography/Text.tsx +62 -0
  250. package/src/typography/index.ts +7 -0
  251. package/src/typography/tokens.css +5 -0
  252. package/src/utils/cn.ts +6 -0
  253. package/ui-contract.json +62 -0
@@ -0,0 +1,882 @@
1
+ import { chipVariants, Chip } from './chunk-X76KBH4Y.js';
2
+ import { Button } from './chunk-66VWUJEI.js';
3
+ import { __export, cn } from './chunk-4S6L5V7X.js';
4
+ import React9, { forwardRef, useState, createContext, useContext, useMemo, useRef, useEffect } from 'react';
5
+ import { cva } from 'class-variance-authority';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+ import { ChevronDown, ArrowUpRight, ArrowDownRight, Minus, Search, Download, ChevronUp, ChevronsUpDown, ChevronLeft, ChevronRight, FolderOpen, Folder, FileCode, Image, FileText } from 'lucide-react';
8
+
9
+ // src/data-display/index.ts
10
+ var data_display_exports = {};
11
+ __export(data_display_exports, {
12
+ Accordion: () => Accordion,
13
+ AccordionContent: () => AccordionContent,
14
+ AccordionItem: () => AccordionItem,
15
+ AccordionTrigger: () => AccordionTrigger,
16
+ Avatar: () => Avatar,
17
+ AvatarGroup: () => AvatarGroup,
18
+ Card: () => Card,
19
+ CardContent: () => CardContent,
20
+ CardDescription: () => CardDescription,
21
+ CardFooter: () => CardFooter,
22
+ CardHeader: () => CardHeader,
23
+ CardTitle: () => CardTitle,
24
+ Carousel: () => Carousel,
25
+ Chip: () => Chip,
26
+ DataTablePro: () => DataTablePro,
27
+ StatCard: () => StatCard,
28
+ Table: () => Table,
29
+ TableBody: () => TableBody,
30
+ TableCaption: () => TableCaption,
31
+ TableCell: () => TableCell,
32
+ TableFooter: () => TableFooter,
33
+ TableHead: () => TableHead,
34
+ TableHeader: () => TableHeader,
35
+ TableRow: () => TableRow,
36
+ Timeline: () => Timeline,
37
+ TreeView: () => TreeView,
38
+ avatarVariants: () => avatarVariants,
39
+ cardVariants: () => cardVariants,
40
+ chipVariants: () => chipVariants,
41
+ statusVariants: () => statusVariants,
42
+ useAccordion: () => useAccordion
43
+ });
44
+ var cardVariants = cva(
45
+ "relative overflow-hidden rounded-[var(--ui-radius-xl)] transition-all duration-200 border",
46
+ {
47
+ variants: {
48
+ variant: {
49
+ default: "bg-[var(--ui-bg-surface)] backdrop-blur-xl border-[var(--ui-border-default)] shadow-[var(--ui-shadow-md)] text-[var(--ui-text-primary)]",
50
+ bordered: "bg-transparent border-[var(--ui-border-strong)] text-[var(--ui-text-primary)]",
51
+ elevated: "bg-[var(--ui-bg-surface)] backdrop-blur-2xl border-[var(--ui-border-default)] shadow-[var(--ui-shadow-xl)] hover:shadow-2xl text-[var(--ui-text-primary)]",
52
+ interactive: "bg-[var(--ui-bg-surface)] backdrop-blur-xl border-[var(--ui-border-default)] shadow-[var(--ui-shadow-md)] hover:border-[var(--ui-primary)] cursor-pointer hover:-translate-y-1 hover:shadow-[0_12px_32px_rgba(99,102,241,0.15)] text-[var(--ui-text-primary)] active:translate-y-0",
53
+ glow: "bg-[var(--ui-bg-surface)] backdrop-blur-xl border-indigo-500/30 shadow-[0_0_30px_rgba(99,102,241,0.12)] text-[var(--ui-text-primary)]"
54
+ },
55
+ padding: {
56
+ none: "p-0",
57
+ sm: "p-4 sm:p-5",
58
+ md: "p-6 sm:p-7",
59
+ lg: "p-8 sm:p-10"
60
+ },
61
+ specular: {
62
+ true: "before:absolute before:inset-x-0 before:top-0 before:h-px before:bg-gradient-to-r before:from-transparent before:via-white/30 before:to-transparent before:pointer-events-none",
63
+ false: ""
64
+ }
65
+ },
66
+ defaultVariants: {
67
+ variant: "default",
68
+ padding: "md",
69
+ specular: true
70
+ }
71
+ }
72
+ );
73
+ var Card = forwardRef(
74
+ ({ className, variant, padding, specular = true, children, ...props }, ref) => {
75
+ return /* @__PURE__ */ jsx(
76
+ "div",
77
+ {
78
+ ref,
79
+ className: cn(cardVariants({ variant, padding, specular }), className),
80
+ ...props,
81
+ children
82
+ }
83
+ );
84
+ }
85
+ );
86
+ Card.displayName = "Card";
87
+ var CardHeader = forwardRef(
88
+ ({ className, children, ...props }, ref) => {
89
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-1.5 mb-5", className), ...props, children });
90
+ }
91
+ );
92
+ CardHeader.displayName = "CardHeader";
93
+ var CardTitle = forwardRef(
94
+ ({ className, children, ...props }, ref) => {
95
+ return /* @__PURE__ */ jsx("h3", { ref, className: cn("text-lg sm:text-xl font-bold tracking-tight text-[var(--ui-text-primary)]", className), ...props, children });
96
+ }
97
+ );
98
+ CardTitle.displayName = "CardTitle";
99
+ var CardDescription = forwardRef(
100
+ ({ className, children, ...props }, ref) => {
101
+ return /* @__PURE__ */ jsx("p", { ref, className: cn("text-xs sm:text-sm text-[var(--ui-text-muted)] font-normal leading-relaxed", className), ...props, children });
102
+ }
103
+ );
104
+ CardDescription.displayName = "CardDescription";
105
+ var CardContent = forwardRef(
106
+ ({ className, children, ...props }, ref) => {
107
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("pt-0", className), ...props, children });
108
+ }
109
+ );
110
+ CardContent.displayName = "CardContent";
111
+ var CardFooter = forwardRef(
112
+ ({ className, children, ...props }, ref) => {
113
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center pt-4 mt-5 border-t border-[var(--ui-border-subtle)]", className), ...props, children });
114
+ }
115
+ );
116
+ CardFooter.displayName = "CardFooter";
117
+ var Table = forwardRef(
118
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto rounded-[var(--ui-radius-lg)] border border-[var(--ui-border-default)] bg-[var(--ui-bg-surface)]", children: /* @__PURE__ */ jsx("table", { ref, className: cn("w-full caption-bottom text-sm text-left", className), ...props }) })
119
+ );
120
+ Table.displayName = "Table";
121
+ var TableHeader = forwardRef(
122
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("bg-[var(--ui-bg-secondary)] border-b border-[var(--ui-border-default)]", className), ...props })
123
+ );
124
+ TableHeader.displayName = "TableHeader";
125
+ var TableBody = forwardRef(
126
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props })
127
+ );
128
+ TableBody.displayName = "TableBody";
129
+ var TableFooter = forwardRef(
130
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("tfoot", { ref, className: cn("bg-[var(--ui-bg-secondary)] font-medium border-t border-[var(--ui-border-default)]", className), ...props })
131
+ );
132
+ TableFooter.displayName = "TableFooter";
133
+ var TableRow = forwardRef(
134
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
135
+ "tr",
136
+ {
137
+ ref,
138
+ className: cn(
139
+ "border-b border-[var(--ui-border-subtle)] transition-colors hover:bg-[var(--ui-bg-tertiary)]/50 data-[state=selected]:bg-[var(--ui-bg-tertiary)]",
140
+ className
141
+ ),
142
+ ...props
143
+ }
144
+ )
145
+ );
146
+ TableRow.displayName = "TableRow";
147
+ var TableHead = forwardRef(
148
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
149
+ "th",
150
+ {
151
+ ref,
152
+ className: cn(
153
+ "h-11 px-4 text-left align-middle font-semibold text-xs text-[var(--ui-text-muted)] uppercase tracking-wider",
154
+ className
155
+ ),
156
+ ...props
157
+ }
158
+ )
159
+ );
160
+ TableHead.displayName = "TableHead";
161
+ var TableCell = forwardRef(
162
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("td", { ref, className: cn("p-4 align-middle text-sm text-[var(--ui-text-primary)]", className), ...props })
163
+ );
164
+ TableCell.displayName = "TableCell";
165
+ var TableCaption = forwardRef(
166
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("caption", { ref, className: cn("mt-4 text-xs text-[var(--ui-text-muted)]", className), ...props })
167
+ );
168
+ TableCaption.displayName = "TableCaption";
169
+ var avatarVariants = cva(
170
+ "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-[var(--ui-bg-tertiary)] select-none border border-[var(--ui-border-subtle)]",
171
+ {
172
+ variants: {
173
+ size: {
174
+ xs: "h-6 w-6 text-[10px]",
175
+ sm: "h-8 w-8 text-xs",
176
+ md: "h-10 w-10 text-sm font-semibold",
177
+ lg: "h-12 w-12 text-base font-semibold",
178
+ xl: "h-16 w-16 text-lg font-bold"
179
+ }
180
+ },
181
+ defaultVariants: {
182
+ size: "md"
183
+ }
184
+ }
185
+ );
186
+ var statusVariants = cva(
187
+ "absolute bottom-0 right-0 rounded-full ring-2 ring-[var(--ui-bg-surface)]",
188
+ {
189
+ variants: {
190
+ status: {
191
+ online: "bg-[var(--ui-success)]",
192
+ offline: "bg-[var(--ui-text-muted)]",
193
+ busy: "bg-[var(--ui-error)]",
194
+ away: "bg-[var(--ui-warning)]"
195
+ },
196
+ size: {
197
+ xs: "h-1.5 w-1.5",
198
+ sm: "h-2 w-2",
199
+ md: "h-2.5 w-2.5",
200
+ lg: "h-3 w-3",
201
+ xl: "h-4 w-4"
202
+ }
203
+ },
204
+ defaultVariants: {
205
+ status: "online",
206
+ size: "md"
207
+ }
208
+ }
209
+ );
210
+ var Avatar = forwardRef(
211
+ ({ className, size = "md", src, alt, name, status, children, ...props }, ref) => {
212
+ const [hasError, setHasError] = useState(false);
213
+ const getInitials = (n) => {
214
+ if (!n) return "";
215
+ const parts = n.trim().split(" ");
216
+ if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
217
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
218
+ };
219
+ const initials = name ? getInitials(name) : "";
220
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn(avatarVariants({ size }), className), ...props, children: [
221
+ src && !hasError ? /* @__PURE__ */ jsx(
222
+ "img",
223
+ {
224
+ src,
225
+ alt: alt || name || "Avatar",
226
+ onError: () => setHasError(true),
227
+ className: "h-full w-full object-cover"
228
+ }
229
+ ) : initials ? /* @__PURE__ */ jsx("span", { className: "font-semibold text-[var(--ui-text-secondary)]", children: initials }) : children || /* @__PURE__ */ jsx("span", { className: "font-semibold text-[var(--ui-text-muted)]", children: "?" }),
230
+ status && /* @__PURE__ */ jsx(
231
+ "span",
232
+ {
233
+ "aria-label": `Status: ${status}`,
234
+ className: cn(statusVariants({ status, size }))
235
+ }
236
+ )
237
+ ] });
238
+ }
239
+ );
240
+ Avatar.displayName = "Avatar";
241
+ var AvatarGroup = forwardRef(
242
+ ({ className, max = 4, spacing = "tight", children, ...props }, ref) => {
243
+ const childArray = React9.Children.toArray(children);
244
+ const visibleChildren = childArray.slice(0, max);
245
+ const remainingCount = childArray.length - max;
246
+ return /* @__PURE__ */ jsxs(
247
+ "div",
248
+ {
249
+ ref,
250
+ role: "group",
251
+ className: cn(
252
+ "flex items-center",
253
+ spacing === "tight" ? "-space-x-3" : "-space-x-1.5",
254
+ className
255
+ ),
256
+ ...props,
257
+ children: [
258
+ visibleChildren.map((child, i) => /* @__PURE__ */ jsx("div", { className: "ring-2 ring-[var(--ui-bg-surface)] rounded-full", children: child }, i)),
259
+ remainingCount > 0 && /* @__PURE__ */ jsxs("div", { className: "relative inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-[var(--ui-bg-secondary)] border border-[var(--ui-border-default)] ring-2 ring-[var(--ui-bg-surface)] text-xs font-bold text-[var(--ui-text-secondary)] select-none", children: [
260
+ "+",
261
+ remainingCount
262
+ ] })
263
+ ]
264
+ }
265
+ );
266
+ }
267
+ );
268
+ AvatarGroup.displayName = "AvatarGroup";
269
+ var AccordionContext = createContext(null);
270
+ function useAccordion() {
271
+ const context = useContext(AccordionContext);
272
+ if (!context) throw new Error("AccordionItem components must be used within <Accordion />");
273
+ return context;
274
+ }
275
+ var Accordion = forwardRef(
276
+ ({
277
+ className,
278
+ type = "single",
279
+ defaultValue,
280
+ value: controlledValue,
281
+ onValueChange,
282
+ children,
283
+ ...props
284
+ }, ref) => {
285
+ const [internalOpen, setInternalOpen] = useState(() => {
286
+ if (Array.isArray(defaultValue)) return defaultValue;
287
+ if (typeof defaultValue === "string") return [defaultValue];
288
+ return [];
289
+ });
290
+ const openItems = controlledValue !== void 0 ? Array.isArray(controlledValue) ? controlledValue : [controlledValue] : internalOpen;
291
+ const toggleItem = (id) => {
292
+ let next;
293
+ if (type === "single") {
294
+ next = openItems.includes(id) ? [] : [id];
295
+ } else {
296
+ next = openItems.includes(id) ? openItems.filter((i) => i !== id) : [...openItems, id];
297
+ }
298
+ setInternalOpen(next);
299
+ onValueChange?.(type === "single" ? next[0] || "" : next);
300
+ };
301
+ return /* @__PURE__ */ jsx(AccordionContext.Provider, { value: { openItems, toggleItem }, children: /* @__PURE__ */ jsx("div", { ref, className: cn("divide-y divide-[var(--ui-border-subtle)] border-y border-[var(--ui-border-subtle)]", className), ...props, children }) });
302
+ }
303
+ );
304
+ Accordion.displayName = "Accordion";
305
+ var AccordionItemContext = createContext(null);
306
+ var AccordionItem = forwardRef(
307
+ ({ className, value, children, ...props }, ref) => {
308
+ return /* @__PURE__ */ jsx(AccordionItemContext.Provider, { value: { id: value }, children: /* @__PURE__ */ jsx("div", { ref, className: cn("w-full", className), ...props, children }) });
309
+ }
310
+ );
311
+ AccordionItem.displayName = "AccordionItem";
312
+ var AccordionTrigger = forwardRef(
313
+ ({ className, children, ...props }, ref) => {
314
+ const { openItems, toggleItem } = useAccordion();
315
+ const item = useContext(AccordionItemContext);
316
+ const isOpen = item ? openItems.includes(item.id) : false;
317
+ return /* @__PURE__ */ jsxs(
318
+ "button",
319
+ {
320
+ ref,
321
+ type: "button",
322
+ "aria-expanded": isOpen,
323
+ onClick: () => item && toggleItem(item.id),
324
+ className: cn(
325
+ "flex w-full items-center justify-between py-4 text-sm font-semibold text-[var(--ui-text-primary)] transition-all hover:text-[var(--ui-primary)] text-left",
326
+ className
327
+ ),
328
+ ...props,
329
+ children: [
330
+ children,
331
+ /* @__PURE__ */ jsx(
332
+ ChevronDown,
333
+ {
334
+ className: cn(
335
+ "h-4 w-4 shrink-0 text-[var(--ui-text-muted)] transition-transform duration-200",
336
+ isOpen && "rotate-180 text-[var(--ui-primary)]"
337
+ )
338
+ }
339
+ )
340
+ ]
341
+ }
342
+ );
343
+ }
344
+ );
345
+ AccordionTrigger.displayName = "AccordionTrigger";
346
+ var AccordionContent = forwardRef(
347
+ ({ className, children, ...props }, ref) => {
348
+ const { openItems } = useAccordion();
349
+ const item = useContext(AccordionItemContext);
350
+ const isOpen = item ? openItems.includes(item.id) : false;
351
+ if (!isOpen) return null;
352
+ return /* @__PURE__ */ jsx(
353
+ "div",
354
+ {
355
+ ref,
356
+ className: cn("pb-4 pt-0 text-sm text-[var(--ui-text-secondary)] animate-in fade-in duration-200", className),
357
+ ...props,
358
+ children
359
+ }
360
+ );
361
+ }
362
+ );
363
+ AccordionContent.displayName = "AccordionContent";
364
+ var StatCard = forwardRef(
365
+ ({ className, label, value, change, trend, trendLabel, icon, ...props }, ref) => {
366
+ return /* @__PURE__ */ jsxs(Card, { ref, className: cn("p-6", className), ...props, children: [
367
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
368
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wider text-[var(--ui-text-muted)]", children: label }),
369
+ icon && /* @__PURE__ */ jsx("div", { className: "p-2 rounded-[var(--ui-radius-md)] bg-[var(--ui-bg-secondary)] text-[var(--ui-text-secondary)]", children: icon })
370
+ ] }),
371
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-baseline gap-2", children: [
372
+ /* @__PURE__ */ jsx("span", { className: "text-2xl sm:text-3xl font-extrabold tracking-tight text-[var(--ui-text-primary)]", children: value }),
373
+ change !== void 0 && /* @__PURE__ */ jsxs(
374
+ "div",
375
+ {
376
+ className: cn(
377
+ "inline-flex items-center gap-0.5 text-xs font-bold px-1.5 py-0.5 rounded-full",
378
+ trend === "up" && "text-[var(--ui-success)] bg-[var(--ui-success-subtle)]",
379
+ trend === "down" && "text-[var(--ui-error)] bg-[var(--ui-error-subtle)]",
380
+ trend === "neutral" && "text-[var(--ui-text-muted)] bg-[var(--ui-bg-tertiary)]"
381
+ ),
382
+ children: [
383
+ trend === "up" && /* @__PURE__ */ jsx(ArrowUpRight, { className: "w-3.5 h-3.5" }),
384
+ trend === "down" && /* @__PURE__ */ jsx(ArrowDownRight, { className: "w-3.5 h-3.5" }),
385
+ trend === "neutral" && /* @__PURE__ */ jsx(Minus, { className: "w-3.5 h-3.5" }),
386
+ /* @__PURE__ */ jsx("span", { children: change })
387
+ ]
388
+ }
389
+ )
390
+ ] }),
391
+ trendLabel && /* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-[var(--ui-text-muted)]", children: trendLabel })
392
+ ] });
393
+ }
394
+ );
395
+ StatCard.displayName = "StatCard";
396
+ var Timeline = forwardRef(
397
+ ({ className, items, ...props }, ref) => {
398
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("relative pl-6 space-y-6", className), ...props, children: [
399
+ /* @__PURE__ */ jsx("div", { className: "absolute left-[11px] top-2 bottom-2 w-0.5 bg-[var(--ui-border-subtle)]" }),
400
+ items.map((item) => {
401
+ const isCompleted = item.status === "completed";
402
+ const isActive = item.status === "active";
403
+ return /* @__PURE__ */ jsxs("div", { className: "relative flex items-start gap-4", children: [
404
+ /* @__PURE__ */ jsx(
405
+ "div",
406
+ {
407
+ className: cn(
408
+ "absolute -left-6 flex items-center justify-center w-6 h-6 rounded-full ring-4 ring-[var(--ui-bg-surface)] text-xs font-bold transition-all",
409
+ isCompleted && "bg-[var(--ui-primary)] text-[var(--ui-primary-fg)]",
410
+ isActive && "bg-[var(--ui-bg-surface)] border-2 border-[var(--ui-primary)] text-[var(--ui-primary)]",
411
+ (!item.status || item.status === "pending") && "bg-[var(--ui-bg-tertiary)] border border-[var(--ui-border-default)] text-[var(--ui-text-muted)]"
412
+ ),
413
+ children: item.icon || /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-current" })
414
+ }
415
+ ),
416
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-1 pt-0.5", children: [
417
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
418
+ /* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold text-[var(--ui-text-primary)]", children: item.title }),
419
+ item.timestamp && /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--ui-text-muted)] font-mono", children: item.timestamp })
420
+ ] }),
421
+ item.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ui-text-secondary)] leading-relaxed", children: item.description })
422
+ ] })
423
+ ] }, item.id);
424
+ })
425
+ ] });
426
+ }
427
+ );
428
+ Timeline.displayName = "Timeline";
429
+ function DataTablePro({
430
+ data,
431
+ columns,
432
+ keyExtractor,
433
+ searchable = true,
434
+ searchPlaceholder = "Search all records...",
435
+ selectable = true,
436
+ onSelectionChange,
437
+ pageSize: initialPageSize = 10,
438
+ pageSizeOptions = [5, 10, 25, 50],
439
+ title,
440
+ description,
441
+ actions,
442
+ className
443
+ }) {
444
+ const [search, setSearch] = useState("");
445
+ const [sortKey, setSortKey] = useState(null);
446
+ const [sortDirection, setSortDirection] = useState("asc");
447
+ const [currentPage, setCurrentPage] = useState(1);
448
+ const [pageSize, setPageSize] = useState(initialPageSize);
449
+ const [selectedKeys, setSelectedKeys] = useState([]);
450
+ const filteredData = useMemo(() => {
451
+ if (!search.trim()) return data;
452
+ const q = search.toLowerCase();
453
+ return data.filter((row) => {
454
+ return Object.values(row).some((val) => {
455
+ if (val === null || val === void 0) return false;
456
+ return String(val).toLowerCase().includes(q);
457
+ });
458
+ });
459
+ }, [data, search]);
460
+ const sortedData = useMemo(() => {
461
+ if (!sortKey) return filteredData;
462
+ const col = columns.find((c) => c.key === sortKey);
463
+ return [...filteredData].sort((a, b) => {
464
+ const valA = col?.accessor ? col.accessor(a) : a[sortKey];
465
+ const valB = col?.accessor ? col.accessor(b) : b[sortKey];
466
+ if (valA === valB) return 0;
467
+ if (valA === null || valA === void 0) return 1;
468
+ if (valB === null || valB === void 0) return -1;
469
+ const comp = valA < valB ? -1 : 1;
470
+ return sortDirection === "asc" ? comp : -comp;
471
+ });
472
+ }, [filteredData, sortKey, sortDirection, columns]);
473
+ const totalPages = Math.max(1, Math.ceil(sortedData.length / pageSize));
474
+ const paginatedData = useMemo(() => {
475
+ const start = (currentPage - 1) * pageSize;
476
+ return sortedData.slice(start, start + pageSize);
477
+ }, [sortedData, currentPage, pageSize]);
478
+ const handleSort = (key) => {
479
+ if (sortKey === key) {
480
+ if (sortDirection === "asc") {
481
+ setSortDirection("desc");
482
+ } else {
483
+ setSortKey(null);
484
+ setSortDirection("asc");
485
+ }
486
+ } else {
487
+ setSortKey(key);
488
+ setSortDirection("asc");
489
+ }
490
+ };
491
+ const toggleSelectAll = () => {
492
+ if (selectedKeys.length === paginatedData.length) {
493
+ setSelectedKeys([]);
494
+ onSelectionChange?.([]);
495
+ } else {
496
+ const allKeys = paginatedData.map(keyExtractor);
497
+ setSelectedKeys(allKeys);
498
+ onSelectionChange?.(allKeys);
499
+ }
500
+ };
501
+ const toggleSelectRow = (key) => {
502
+ const next = selectedKeys.includes(key) ? selectedKeys.filter((k) => k !== key) : [...selectedKeys, key];
503
+ setSelectedKeys(next);
504
+ onSelectionChange?.(next);
505
+ };
506
+ const exportCSV = () => {
507
+ const headers = columns.map((c) => typeof c.header === "string" ? c.header : c.key);
508
+ const rows = sortedData.map(
509
+ (row) => columns.map((c) => {
510
+ const val = c.accessor ? c.accessor(row) : row[c.key];
511
+ return `"${String(val ?? "").replace(/"/g, '""')}"`;
512
+ }).join(",")
513
+ );
514
+ const csvContent = "data:text/csv;charset=utf-8," + [headers.join(","), ...rows].join("\n");
515
+ const encodedUri = encodeURI(csvContent);
516
+ const link = document.createElement("a");
517
+ link.setAttribute("href", encodedUri);
518
+ link.setAttribute("download", `export_${Date.now()}.csv`);
519
+ document.body.appendChild(link);
520
+ link.click();
521
+ document.body.removeChild(link);
522
+ };
523
+ const isAllSelected = paginatedData.length > 0 && selectedKeys.length === paginatedData.length;
524
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full space-y-4", className), children: [
525
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-4", children: [
526
+ (title || description) && /* @__PURE__ */ jsxs("div", { children: [
527
+ title && /* @__PURE__ */ jsx("h3", { className: "text-base font-bold tracking-tight text-[var(--ui-text-primary)]", children: title }),
528
+ description && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ui-text-muted)]", children: description })
529
+ ] }),
530
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2.5", children: [
531
+ searchable && /* @__PURE__ */ jsxs("div", { className: "relative w-full sm:w-64", children: [
532
+ /* @__PURE__ */ jsx(Search, { className: "absolute left-3 w-3.5 h-3.5 text-[var(--ui-text-muted)] pointer-events-none" }),
533
+ /* @__PURE__ */ jsx(
534
+ "input",
535
+ {
536
+ type: "text",
537
+ placeholder: searchPlaceholder,
538
+ value: search,
539
+ onChange: (e) => {
540
+ setSearch(e.target.value);
541
+ setCurrentPage(1);
542
+ },
543
+ className: "w-full h-8 pl-8 pr-3 text-xs rounded-xl bg-[var(--ui-bg-surface)] border border-[var(--ui-border-default)] hover:border-[var(--ui-border-strong)] focus:outline-none focus:ring-2 focus:ring-[var(--ui-primary)]/40 text-[var(--ui-text-primary)] placeholder:text-[var(--ui-text-muted)] transition-all shadow-inner"
544
+ }
545
+ )
546
+ ] }),
547
+ /* @__PURE__ */ jsx(Button, { size: "xs", variant: "outline", leftIcon: /* @__PURE__ */ jsx(Download, { className: "w-3 h-3" }), onClick: exportCSV, children: "Export CSV" }),
548
+ actions
549
+ ] })
550
+ ] }),
551
+ selectedKeys.length > 0 && /* @__PURE__ */ jsxs("div", { className: "px-4 py-2 rounded-xl bg-[var(--ui-primary)]/15 border border-[var(--ui-primary)]/30 flex items-center justify-between animate-in fade-in duration-200", children: [
552
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 text-xs font-semibold text-[var(--ui-primary)]", children: /* @__PURE__ */ jsxs("span", { children: [
553
+ "Selected ",
554
+ selectedKeys.length,
555
+ " of ",
556
+ sortedData.length,
557
+ " records"
558
+ ] }) }),
559
+ /* @__PURE__ */ jsx(
560
+ Button,
561
+ {
562
+ size: "xs",
563
+ variant: "ghost",
564
+ className: "text-xs text-rose-500 hover:text-rose-600 hover:bg-rose-500/10",
565
+ onClick: () => {
566
+ setSelectedKeys([]);
567
+ onSelectionChange?.([]);
568
+ },
569
+ children: "Clear Selection"
570
+ }
571
+ )
572
+ ] }),
573
+ /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-x-auto rounded-2xl border border-[var(--ui-border-default)] bg-[var(--ui-bg-surface)] shadow-sm", children: /* @__PURE__ */ jsxs(Table, { children: [
574
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
575
+ selectable && /* @__PURE__ */ jsx(TableHead, { className: "w-10 px-4", children: /* @__PURE__ */ jsx(
576
+ "input",
577
+ {
578
+ type: "checkbox",
579
+ checked: isAllSelected,
580
+ onChange: toggleSelectAll,
581
+ className: "rounded border-[var(--ui-border-default)] text-[var(--ui-primary)] focus:ring-[var(--ui-primary)] cursor-pointer"
582
+ }
583
+ ) }),
584
+ columns.map((col) => /* @__PURE__ */ jsx(
585
+ TableHead,
586
+ {
587
+ style: { width: col.width },
588
+ onClick: () => col.sortable !== false && handleSort(col.key),
589
+ className: cn(
590
+ col.sortable !== false && "cursor-pointer select-none hover:text-[var(--ui-text-primary)] transition-colors"
591
+ ),
592
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
593
+ /* @__PURE__ */ jsx("span", { children: col.header }),
594
+ col.sortable !== false && /* @__PURE__ */ jsx("span", { className: "text-[var(--ui-text-muted)]", children: sortKey === col.key ? sortDirection === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "w-3.5 h-3.5 text-[var(--ui-primary)] font-bold" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "w-3.5 h-3.5 text-[var(--ui-primary)] font-bold" }) : /* @__PURE__ */ jsx(ChevronsUpDown, { className: "w-3 h-3 opacity-40" }) })
595
+ ] })
596
+ },
597
+ col.key
598
+ ))
599
+ ] }) }),
600
+ /* @__PURE__ */ jsx(TableBody, { children: paginatedData.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: columns.length + (selectable ? 1 : 0), className: "h-32 text-center text-xs text-[var(--ui-text-muted)]", children: "No matching records found." }) }) : paginatedData.map((row, rowIdx) => {
601
+ const key = keyExtractor(row);
602
+ const isSelected = selectedKeys.includes(key);
603
+ return /* @__PURE__ */ jsxs(
604
+ TableRow,
605
+ {
606
+ "data-state": isSelected ? "selected" : void 0,
607
+ className: cn(isSelected && "bg-[var(--ui-primary)]/10"),
608
+ children: [
609
+ selectable && /* @__PURE__ */ jsx(TableCell, { className: "w-10 px-4", children: /* @__PURE__ */ jsx(
610
+ "input",
611
+ {
612
+ type: "checkbox",
613
+ checked: isSelected,
614
+ onChange: () => toggleSelectRow(key),
615
+ className: "rounded border-[var(--ui-border-default)] text-[var(--ui-primary)] focus:ring-[var(--ui-primary)] cursor-pointer"
616
+ }
617
+ ) }),
618
+ columns.map((col) => {
619
+ const cellContent = col.render ? col.render(row, rowIdx) : col.accessor ? col.accessor(row) : row[col.key];
620
+ return /* @__PURE__ */ jsx(TableCell, { children: cellContent }, col.key);
621
+ })
622
+ ]
623
+ },
624
+ key
625
+ );
626
+ }) })
627
+ ] }) }),
628
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-3 px-1 text-xs text-[var(--ui-text-muted)] font-mono", children: [
629
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
630
+ /* @__PURE__ */ jsx("span", { children: "Rows per page:" }),
631
+ /* @__PURE__ */ jsx(
632
+ "select",
633
+ {
634
+ value: pageSize,
635
+ onChange: (e) => {
636
+ setPageSize(Number(e.target.value));
637
+ setCurrentPage(1);
638
+ },
639
+ className: "px-2 py-1 rounded-lg bg-[var(--ui-bg-surface)] border border-[var(--ui-border-default)] text-[var(--ui-text-primary)] font-mono text-xs focus:outline-none",
640
+ children: pageSizeOptions.map((opt) => /* @__PURE__ */ jsx("option", { value: opt, children: opt }, opt))
641
+ }
642
+ ),
643
+ /* @__PURE__ */ jsxs("span", { className: "text-[var(--ui-text-muted)]", children: [
644
+ "Showing ",
645
+ Math.min((currentPage - 1) * pageSize + 1, sortedData.length),
646
+ "\u2013",
647
+ Math.min(currentPage * pageSize, sortedData.length),
648
+ " of ",
649
+ sortedData.length
650
+ ] })
651
+ ] }),
652
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
653
+ /* @__PURE__ */ jsx(
654
+ Button,
655
+ {
656
+ size: "xs",
657
+ variant: "outline",
658
+ disabled: currentPage === 1,
659
+ onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
660
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "w-3.5 h-3.5" })
661
+ }
662
+ ),
663
+ /* @__PURE__ */ jsxs("span", { className: "px-2 font-bold text-[var(--ui-text-primary)]", children: [
664
+ currentPage,
665
+ " / ",
666
+ totalPages
667
+ ] }),
668
+ /* @__PURE__ */ jsx(
669
+ Button,
670
+ {
671
+ size: "xs",
672
+ variant: "outline",
673
+ disabled: currentPage === totalPages,
674
+ onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
675
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "w-3.5 h-3.5" })
676
+ }
677
+ )
678
+ ] })
679
+ ] })
680
+ ] });
681
+ }
682
+ function TreeNode({ item, level, selectedId, onSelect }) {
683
+ const [isExpanded, setIsExpanded] = useState(Boolean(item.defaultExpanded));
684
+ const hasChildren = Boolean(item.children && item.children.length > 0);
685
+ const isSelected = selectedId === item.id;
686
+ const handleClick = (e) => {
687
+ e.stopPropagation();
688
+ if (hasChildren) {
689
+ setIsExpanded(!isExpanded);
690
+ }
691
+ onSelect?.(item);
692
+ };
693
+ const getIcon = () => {
694
+ if (item.icon) return item.icon;
695
+ if (hasChildren) {
696
+ return isExpanded ? /* @__PURE__ */ jsx(FolderOpen, { className: "w-4 h-4 text-amber-500 shrink-0" }) : /* @__PURE__ */ jsx(Folder, { className: "w-4 h-4 text-amber-500 shrink-0" });
697
+ }
698
+ if (item.label.endsWith(".tsx") || item.label.endsWith(".ts") || item.label.endsWith(".js")) {
699
+ return /* @__PURE__ */ jsx(FileCode, { className: "w-4 h-4 text-blue-500 shrink-0" });
700
+ }
701
+ if (item.label.endsWith(".png") || item.label.endsWith(".jpg") || item.label.endsWith(".svg")) {
702
+ return /* @__PURE__ */ jsx(Image, { className: "w-4 h-4 text-purple-500 shrink-0" });
703
+ }
704
+ return /* @__PURE__ */ jsx(FileText, { className: "w-4 h-4 text-[var(--ui-text-muted)] shrink-0" });
705
+ };
706
+ return /* @__PURE__ */ jsxs("div", { className: "select-none text-xs", children: [
707
+ /* @__PURE__ */ jsxs(
708
+ "div",
709
+ {
710
+ onClick: handleClick,
711
+ style: { paddingLeft: `${level * 16 + 8}px` },
712
+ className: cn(
713
+ "flex items-center justify-between py-1.5 pr-2.5 rounded-xl cursor-pointer transition-colors group",
714
+ isSelected ? "bg-[var(--ui-primary)] text-white font-semibold shadow-xs" : "text-[var(--ui-text-primary)] hover:bg-[var(--ui-bg-tertiary)]"
715
+ ),
716
+ children: [
717
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 truncate", children: [
718
+ hasChildren ? /* @__PURE__ */ jsx("span", { className: cn("p-0.5 rounded transition-transform duration-200", isExpanded && "rotate-90"), children: /* @__PURE__ */ jsx(ChevronRight, { className: cn("w-3 h-3", isSelected ? "text-white" : "text-[var(--ui-text-muted)]") }) }) : /* @__PURE__ */ jsx("span", { className: "w-4" }),
719
+ getIcon(),
720
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
721
+ ] }),
722
+ item.badge !== void 0 && /* @__PURE__ */ jsx(
723
+ "span",
724
+ {
725
+ className: cn(
726
+ "px-1.5 py-0.5 rounded-md text-[10px] font-mono",
727
+ isSelected ? "bg-white/20 text-white" : "bg-[var(--ui-bg-secondary)] text-[var(--ui-text-muted)]"
728
+ ),
729
+ children: item.badge
730
+ }
731
+ )
732
+ ]
733
+ }
734
+ ),
735
+ hasChildren && isExpanded && /* @__PURE__ */ jsxs("div", { className: "relative space-y-0.5 animate-in fade-in duration-150", children: [
736
+ /* @__PURE__ */ jsx(
737
+ "div",
738
+ {
739
+ className: "absolute left-[15px] top-0 bottom-0 w-[1px] bg-[var(--ui-border-subtle)]",
740
+ style: { left: `${level * 16 + 15}px` }
741
+ }
742
+ ),
743
+ item.children.map((child) => /* @__PURE__ */ jsx(
744
+ TreeNode,
745
+ {
746
+ item: child,
747
+ level: level + 1,
748
+ selectedId,
749
+ onSelect
750
+ },
751
+ child.id
752
+ ))
753
+ ] })
754
+ ] });
755
+ }
756
+ var TreeView = forwardRef(
757
+ ({ data, selectedId, onSelect, className }, ref) => {
758
+ return /* @__PURE__ */ jsx(
759
+ "div",
760
+ {
761
+ ref,
762
+ className: cn(
763
+ "w-full p-2 rounded-2xl bg-[var(--ui-bg-surface)] border border-[var(--ui-border-default)] space-y-0.5 shadow-sm overflow-hidden",
764
+ className
765
+ ),
766
+ children: data.map((item) => /* @__PURE__ */ jsx(
767
+ TreeNode,
768
+ {
769
+ item,
770
+ level: 0,
771
+ selectedId,
772
+ onSelect
773
+ },
774
+ item.id
775
+ ))
776
+ }
777
+ );
778
+ }
779
+ );
780
+ TreeView.displayName = "TreeView";
781
+ var Carousel = forwardRef(
782
+ ({
783
+ autoplay = false,
784
+ autoplayInterval = 4e3,
785
+ loop = true,
786
+ showArrows = true,
787
+ showDots = true,
788
+ children,
789
+ className,
790
+ ...props
791
+ }, ref) => {
792
+ const [currentIndex, setCurrentIndex] = useState(0);
793
+ const totalSlides = React9.Children.count(children);
794
+ const timerRef = useRef(null);
795
+ const nextSlide = () => {
796
+ setCurrentIndex((prev) => {
797
+ if (prev === totalSlides - 1) {
798
+ return loop ? 0 : prev;
799
+ }
800
+ return prev + 1;
801
+ });
802
+ };
803
+ const prevSlide = () => {
804
+ setCurrentIndex((prev) => {
805
+ if (prev === 0) {
806
+ return loop ? totalSlides - 1 : prev;
807
+ }
808
+ return prev - 1;
809
+ });
810
+ };
811
+ useEffect(() => {
812
+ if (autoplay && totalSlides > 1) {
813
+ timerRef.current = setInterval(nextSlide, autoplayInterval);
814
+ return () => clearInterval(timerRef.current);
815
+ }
816
+ }, [autoplay, autoplayInterval, totalSlides, currentIndex]);
817
+ return /* @__PURE__ */ jsxs(
818
+ "div",
819
+ {
820
+ ref,
821
+ onMouseEnter: () => autoplay && clearInterval(timerRef.current),
822
+ onMouseLeave: () => {
823
+ if (autoplay && totalSlides > 1) {
824
+ timerRef.current = setInterval(nextSlide, autoplayInterval);
825
+ }
826
+ },
827
+ className: cn("relative w-full overflow-hidden rounded-3xl group", className),
828
+ ...props,
829
+ children: [
830
+ /* @__PURE__ */ jsx(
831
+ "div",
832
+ {
833
+ className: "flex transition-transform duration-500 ease-out",
834
+ style: { transform: `translateX(-${currentIndex * 100}%)` },
835
+ children: React9.Children.map(children, (child, idx) => /* @__PURE__ */ jsx("div", { className: "w-full flex-shrink-0", children: child }, idx))
836
+ }
837
+ ),
838
+ showArrows && totalSlides > 1 && /* @__PURE__ */ jsx(
839
+ "button",
840
+ {
841
+ type: "button",
842
+ onClick: prevSlide,
843
+ disabled: !loop && currentIndex === 0,
844
+ className: "absolute left-3 top-1/2 -translate-y-1/2 w-9 h-9 rounded-full bg-[var(--ui-bg-surface)]/80 hover:bg-[var(--ui-bg-surface)] backdrop-blur-xl border border-[var(--ui-border-default)] shadow-lg flex items-center justify-center text-[var(--ui-text-primary)] opacity-0 group-hover:opacity-100 transition-all disabled:opacity-0 cursor-pointer",
845
+ "aria-label": "Previous Slide",
846
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "w-5 h-5" })
847
+ }
848
+ ),
849
+ showArrows && totalSlides > 1 && /* @__PURE__ */ jsx(
850
+ "button",
851
+ {
852
+ type: "button",
853
+ onClick: nextSlide,
854
+ disabled: !loop && currentIndex === totalSlides - 1,
855
+ className: "absolute right-3 top-1/2 -translate-y-1/2 w-9 h-9 rounded-full bg-[var(--ui-bg-surface)]/80 hover:bg-[var(--ui-bg-surface)] backdrop-blur-xl border border-[var(--ui-border-default)] shadow-lg flex items-center justify-center text-[var(--ui-text-primary)] opacity-0 group-hover:opacity-100 transition-all disabled:opacity-0 cursor-pointer",
856
+ "aria-label": "Next Slide",
857
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "w-5 h-5" })
858
+ }
859
+ ),
860
+ showDots && totalSlides > 1 && /* @__PURE__ */ jsx("div", { className: "absolute bottom-4 inset-x-0 flex items-center justify-center gap-1.5 pointer-events-auto", children: Array.from({ length: totalSlides }).map((_, idx) => /* @__PURE__ */ jsx(
861
+ "button",
862
+ {
863
+ type: "button",
864
+ onClick: () => setCurrentIndex(idx),
865
+ className: cn(
866
+ "h-2 rounded-full transition-all cursor-pointer shadow-xs",
867
+ currentIndex === idx ? "w-6 bg-[var(--ui-primary)]" : "w-2 bg-white/40 dark:bg-white/30 hover:bg-white/60"
868
+ ),
869
+ "aria-label": `Go to slide ${idx + 1}`
870
+ },
871
+ idx
872
+ )) })
873
+ ]
874
+ }
875
+ );
876
+ }
877
+ );
878
+ Carousel.displayName = "Carousel";
879
+
880
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Avatar, AvatarGroup, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, DataTablePro, StatCard, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Timeline, TreeView, avatarVariants, cardVariants, data_display_exports, statusVariants, useAccordion };
881
+ //# sourceMappingURL=chunk-NFVONJUK.js.map
882
+ //# sourceMappingURL=chunk-NFVONJUK.js.map