@classytic/fluid 0.4.1 → 0.5.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 (51) hide show
  1. package/README.md +21 -1
  2. package/dist/client/calendar.d.mts +1 -2
  3. package/dist/client/calendar.mjs +4 -4
  4. package/dist/client/color-picker.d.mts +94 -0
  5. package/dist/client/color-picker.mjs +392 -0
  6. package/dist/client/core.d.mts +243 -557
  7. package/dist/client/core.mjs +351 -1462
  8. package/dist/client/error.d.mts +41 -41
  9. package/dist/client/error.mjs +35 -35
  10. package/dist/client/gallery.d.mts +175 -0
  11. package/dist/client/gallery.mjs +546 -0
  12. package/dist/client/hooks.d.mts +57 -39
  13. package/dist/client/hooks.mjs +29 -7
  14. package/dist/client/spreadsheet.d.mts +30 -27
  15. package/dist/client/spreadsheet.mjs +80 -80
  16. package/dist/client/table.d.mts +66 -33
  17. package/dist/client/table.mjs +87 -54
  18. package/dist/client/theme.mjs +1 -1
  19. package/dist/command.d.mts +6 -4
  20. package/dist/command.mjs +3 -3
  21. package/dist/compact.d.mts +97 -95
  22. package/dist/compact.mjs +336 -322
  23. package/dist/dashboard.d.mts +614 -422
  24. package/dist/dashboard.mjs +1051 -762
  25. package/dist/{dropdown-wrapper-B86u9Fri.mjs → dropdown-wrapper-B9nRDUlz.mjs} +25 -35
  26. package/dist/forms.d.mts +1037 -972
  27. package/dist/forms.mjs +2849 -2721
  28. package/dist/index.d.mts +218 -152
  29. package/dist/index.mjs +357 -264
  30. package/dist/layouts.d.mts +94 -94
  31. package/dist/layouts.mjs +115 -110
  32. package/dist/phone-input-B9_XPNvv.mjs +429 -0
  33. package/dist/phone-input-CLH_UjQZ.d.mts +31 -0
  34. package/dist/{search-context-DR7DBs7S.mjs → search-context-1g3ZmOvx.mjs} +1 -1
  35. package/dist/search.d.mts +168 -164
  36. package/dist/search.mjs +305 -301
  37. package/dist/{sheet-wrapper-C13Y-Q6w.mjs → sheet-wrapper-B2uxookb.mjs} +1 -1
  38. package/dist/timeline-Bgu1mIe9.d.mts +373 -0
  39. package/dist/timeline-HJtWf4Op.mjs +804 -0
  40. package/dist/{use-base-search-BGgWnWaF.d.mts → use-base-search-DFC4QKYU.d.mts} +1 -1
  41. package/dist/{use-media-query-BnVNIKT4.mjs → use-media-query-ChLfFChU.mjs} +6 -7
  42. package/package.json +10 -2
  43. /package/dist/{api-pagination-CJ0vR_w6.d.mts → api-pagination-C30ser2L.d.mts} +0 -0
  44. /package/dist/{filter-utils-DqMmy_v-.mjs → filter-utils-BGIvtq1R.mjs} +0 -0
  45. /package/dist/{filter-utils-IZ0GtuPo.d.mts → filter-utils-DOFTBWm1.d.mts} +0 -0
  46. /package/dist/{use-debounce-xmZucz5e.mjs → use-debounce-BNoNiEon.mjs} +0 -0
  47. /package/dist/{use-keyboard-shortcut-Bl6YM5Q7.mjs → use-keyboard-shortcut-C_Vk-36P.mjs} +0 -0
  48. /package/dist/{use-keyboard-shortcut-_mRCh3QO.d.mts → use-keyboard-shortcut-Q4CSPzSI.d.mts} +0 -0
  49. /package/dist/{use-mobile-BX3SQVo2.mjs → use-mobile-CnEmFiQx.mjs} +0 -0
  50. /package/dist/{use-scroll-detection-CsgsQYvy.mjs → use-scroll-detection-BKfqkmEC.mjs} +0 -0
  51. /package/dist/{utils-CDue7cEt.d.mts → utils-rqvYP1by.d.mts} +0 -0
@@ -0,0 +1,804 @@
1
+ import { t as cn } from "./utils-DQ5SCVoW.mjs";
2
+ import * as React$1 from "react";
3
+ import { memo, useState } from "react";
4
+ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
7
+ import { AlertTriangle, Check, ChevronDownIcon, ChevronUpIcon, Circle, Copy, MinusIcon, X } from "lucide-react";
8
+ import { Button } from "@/components/ui/button";
9
+ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
10
+ import { Badge } from "@/components/ui/badge";
11
+
12
+ //#region src/components/accordion-wrapper.tsx
13
+ /**
14
+ * AccordionSection - Single collapsible section with smooth animation
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * <AccordionSection title="Settings" icon={<Settings className="h-4 w-4" />}>
19
+ * <div>Content here</div>
20
+ * </AccordionSection>
21
+ * ```
22
+ */
23
+ const AccordionSection = memo(function AccordionSection({ title, icon, children, defaultOpen = false, className, badge }) {
24
+ return /* @__PURE__ */ jsx(Accordion, {
25
+ defaultValue: defaultOpen ? ["section"] : [],
26
+ className,
27
+ children: /* @__PURE__ */ jsxs(AccordionItem, {
28
+ value: "section",
29
+ className: "border-0",
30
+ children: [/* @__PURE__ */ jsx(AccordionTrigger, {
31
+ className: "py-3 hover:no-underline",
32
+ children: /* @__PURE__ */ jsxs("div", {
33
+ className: "flex items-center gap-2",
34
+ children: [
35
+ icon && /* @__PURE__ */ jsx("span", {
36
+ className: "text-muted-foreground",
37
+ children: icon
38
+ }),
39
+ /* @__PURE__ */ jsx("span", {
40
+ className: "font-medium",
41
+ children: title
42
+ }),
43
+ badge
44
+ ]
45
+ })
46
+ }), /* @__PURE__ */ jsx(AccordionContent, { children: /* @__PURE__ */ jsx("div", {
47
+ className: "pt-2",
48
+ children
49
+ }) })]
50
+ })
51
+ });
52
+ });
53
+ /**
54
+ * FaqAccordion - FAQ-style accordion where only one item can be open by default
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * <FaqAccordion
59
+ * items={[
60
+ * { id: "1", question: "What is this?", answer: "A FAQ accordion" },
61
+ * { id: "2", question: "How does it work?", answer: "Click to expand" },
62
+ * ]}
63
+ * />
64
+ * ```
65
+ */
66
+ const FaqAccordion = memo(function FaqAccordion({ items, defaultOpen, className, multiple = false }) {
67
+ return /* @__PURE__ */ jsx(Accordion, {
68
+ defaultValue: defaultOpen ? [defaultOpen] : [],
69
+ multiple,
70
+ className: cn("w-full", className),
71
+ children: items.map((item) => /* @__PURE__ */ jsxs(AccordionItem, {
72
+ value: item.id,
73
+ children: [/* @__PURE__ */ jsx(AccordionTrigger, {
74
+ className: "text-left",
75
+ children: item.question
76
+ }), /* @__PURE__ */ jsx(AccordionContent, { children: item.answer })]
77
+ }, item.id))
78
+ });
79
+ });
80
+
81
+ //#endregion
82
+ //#region src/components/card-wrapper.tsx
83
+ const CARD_VARIANTS = {
84
+ default: "",
85
+ outline: "border-2",
86
+ ghost: "border-0 shadow-none bg-transparent",
87
+ elevated: "shadow-lg border-0",
88
+ primary: "border-primary/20 bg-primary/5",
89
+ secondary: "border-secondary/20 bg-secondary/5",
90
+ destructive: "border-destructive/20 bg-destructive/5",
91
+ success: "border-green-500/20 bg-green-500/5",
92
+ warning: "border-yellow-500/20 bg-yellow-500/5"
93
+ };
94
+ const CARD_SIZES = {
95
+ sm: "p-3",
96
+ default: "p-6",
97
+ lg: "p-8",
98
+ xl: "p-10"
99
+ };
100
+ const CARD_CONTENT_SIZES = {
101
+ sm: "pt-3",
102
+ default: "pt-6",
103
+ lg: "pt-8",
104
+ xl: "pt-10"
105
+ };
106
+ function CardWrapper({ title, description, headerRight, children, footer, className, headerClassName, contentClassName, footerClassName, variant = "default", size = "default", hideHeader = false }) {
107
+ return /* @__PURE__ */ jsxs(Card, {
108
+ className: cn(CARD_VARIANTS[variant], className),
109
+ children: [
110
+ !hideHeader && (title || description || headerRight) && /* @__PURE__ */ jsx(CardHeader, {
111
+ className: cn(CARD_SIZES[size], "pb-4", headerClassName),
112
+ children: /* @__PURE__ */ jsxs("div", {
113
+ className: cn("flex items-start justify-between gap-4", !headerRight && "flex-col"),
114
+ children: [/* @__PURE__ */ jsxs("div", {
115
+ className: headerRight ? "" : "space-y-1.5",
116
+ children: [title && /* @__PURE__ */ jsx(CardTitle, {
117
+ className: "text-lg font-semibold",
118
+ children: title
119
+ }), description && /* @__PURE__ */ jsx(CardDescription, { children: description })]
120
+ }), headerRight && /* @__PURE__ */ jsx("div", {
121
+ className: "shrink-0",
122
+ children: headerRight
123
+ })]
124
+ })
125
+ }),
126
+ /* @__PURE__ */ jsx(CardContent, {
127
+ className: cn(hideHeader ? CARD_SIZES[size] : CARD_CONTENT_SIZES[size], contentClassName),
128
+ children
129
+ }),
130
+ footer && /* @__PURE__ */ jsx(CardFooter, {
131
+ className: cn(CARD_SIZES[size], "pt-4 border-t", footerClassName),
132
+ children: /* @__PURE__ */ jsx("div", {
133
+ className: "w-full",
134
+ children: footer
135
+ })
136
+ })
137
+ ]
138
+ });
139
+ }
140
+ const DATA_CARD_COLS = {
141
+ 1: "grid-cols-1",
142
+ 2: "grid-cols-2",
143
+ 3: "grid-cols-2 md:grid-cols-3",
144
+ 4: "grid-cols-2 md:grid-cols-4"
145
+ };
146
+ function DataCard({ title, data, cols = 3, className, ...props }) {
147
+ return /* @__PURE__ */ jsx(CardWrapper, {
148
+ title,
149
+ className: cn("space-y-4", className),
150
+ ...props,
151
+ children: /* @__PURE__ */ jsx("div", {
152
+ className: cn("grid gap-4", DATA_CARD_COLS[cols]),
153
+ children: data.map((item, index) => /* @__PURE__ */ jsxs("div", {
154
+ className: "space-y-1",
155
+ children: [/* @__PURE__ */ jsx("p", {
156
+ className: "text-sm text-muted-foreground",
157
+ children: item.label
158
+ }), /* @__PURE__ */ jsx("p", {
159
+ className: cn("text-lg font-semibold", item.color),
160
+ children: item.value
161
+ })]
162
+ }, index))
163
+ })
164
+ });
165
+ }
166
+ function LoadingCard({ title, description, className, ...props }) {
167
+ return /* @__PURE__ */ jsx(CardWrapper, {
168
+ title,
169
+ description,
170
+ className,
171
+ ...props,
172
+ children: /* @__PURE__ */ jsxs("div", {
173
+ className: "flex items-center justify-center py-8",
174
+ children: [/* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-primary" }), /* @__PURE__ */ jsx("span", {
175
+ className: "ml-2",
176
+ children: "Loading..."
177
+ })]
178
+ })
179
+ });
180
+ }
181
+ const STATS_CARD_VARIANTS = {
182
+ default: "",
183
+ success: "bg-green-50 border-green-200 dark:bg-green-950/30 dark:border-green-900",
184
+ warning: "bg-yellow-50 border-yellow-200 dark:bg-yellow-950/30 dark:border-yellow-900",
185
+ danger: "bg-red-50 border-red-200 dark:bg-red-950/30 dark:border-red-900",
186
+ info: "bg-blue-50 border-blue-200 dark:bg-blue-950/30 dark:border-blue-900"
187
+ };
188
+ const STATS_ICON_VARIANTS = {
189
+ default: "text-muted-foreground",
190
+ success: "text-green-600 dark:text-green-400",
191
+ warning: "text-yellow-600 dark:text-yellow-400",
192
+ danger: "text-red-600 dark:text-red-400",
193
+ info: "text-blue-600 dark:text-blue-400"
194
+ };
195
+ const STATS_ICON_WRAPPER_VARIANTS = {
196
+ default: "bg-muted border border-border",
197
+ success: "bg-green-100/50 dark:bg-green-900/30",
198
+ warning: "bg-yellow-100/50 dark:bg-yellow-900/30",
199
+ danger: "bg-red-100/50 dark:bg-red-900/30",
200
+ info: "bg-blue-100/50 dark:bg-blue-900/30",
201
+ purple: "bg-purple-100/50 dark:bg-purple-900/30",
202
+ orange: "bg-orange-100/50 dark:bg-orange-900/30"
203
+ };
204
+ const ICON_COLOR_TEXT = {
205
+ default: "text-muted-foreground",
206
+ success: "text-green-600 dark:text-green-400",
207
+ warning: "text-yellow-600 dark:text-yellow-400",
208
+ danger: "text-red-600 dark:text-red-400",
209
+ info: "text-blue-600 dark:text-blue-400",
210
+ purple: "text-purple-600 dark:text-purple-400",
211
+ orange: "text-orange-600 dark:text-orange-400"
212
+ };
213
+ function StatsCard({ title, value, description, icon, trend, className, statsVariant = "default", iconColor, iconClassName, ...props }) {
214
+ const effectiveIconWrapperClass = iconColor ? STATS_ICON_WRAPPER_VARIANTS[iconColor] ?? STATS_ICON_WRAPPER_VARIANTS.default : STATS_ICON_WRAPPER_VARIANTS[statsVariant];
215
+ const effectiveIconTextClass = iconColor ? ICON_COLOR_TEXT[iconColor] ?? ICON_COLOR_TEXT.default : STATS_ICON_VARIANTS[statsVariant];
216
+ return /* @__PURE__ */ jsxs(CardWrapper, {
217
+ className: cn("relative overflow-hidden", iconColor ? "" : STATS_CARD_VARIANTS[statsVariant], className),
218
+ size: "sm",
219
+ hideHeader: true,
220
+ ...props,
221
+ children: [/* @__PURE__ */ jsxs("div", {
222
+ className: "flex items-center justify-between",
223
+ children: [/* @__PURE__ */ jsxs("div", {
224
+ className: "space-y-1",
225
+ children: [
226
+ /* @__PURE__ */ jsx("p", {
227
+ className: "text-sm font-medium text-muted-foreground",
228
+ children: title
229
+ }),
230
+ /* @__PURE__ */ jsx("p", {
231
+ className: "text-2xl font-bold",
232
+ children: value
233
+ }),
234
+ description && /* @__PURE__ */ jsx("p", {
235
+ className: "text-xs text-muted-foreground",
236
+ children: description
237
+ })
238
+ ]
239
+ }), icon && /* @__PURE__ */ jsx("div", {
240
+ className: cn("p-2 rounded-md", effectiveIconWrapperClass, effectiveIconTextClass, iconClassName),
241
+ children: icon
242
+ })]
243
+ }), trend && /* @__PURE__ */ jsx("div", {
244
+ className: cn("absolute top-2 right-2 text-xs px-2 py-1 rounded-full", trend.type === "up" && "bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300", trend.type === "down" && "bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300", trend.type === "neutral" && "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300"),
245
+ children: trend.value
246
+ })]
247
+ });
248
+ }
249
+ function DraggableCard({ title, subtitle, badges, actions, details, dragHandleProps, className, isDragging, isHidden, children, ...props }) {
250
+ return /* @__PURE__ */ jsx(CardWrapper, {
251
+ hideHeader: true,
252
+ className: cn("transition-all", isDragging && "shadow-lg rotate-2", isHidden && "opacity-50", className),
253
+ contentClassName: "!pt-4",
254
+ ...props,
255
+ children: /* @__PURE__ */ jsxs("div", {
256
+ className: "flex items-start gap-3",
257
+ children: [
258
+ dragHandleProps && /* @__PURE__ */ jsx("div", {
259
+ ...dragHandleProps,
260
+ className: "mt-1 cursor-grab hover:text-foreground",
261
+ children: dragHandleProps.icon || /* @__PURE__ */ jsxs("svg", {
262
+ xmlns: "http://www.w3.org/2000/svg",
263
+ width: "16",
264
+ height: "16",
265
+ viewBox: "0 0 24 24",
266
+ fill: "none",
267
+ stroke: "currentColor",
268
+ strokeWidth: "2",
269
+ strokeLinecap: "round",
270
+ strokeLinejoin: "round",
271
+ className: "text-muted-foreground",
272
+ children: [
273
+ /* @__PURE__ */ jsx("circle", {
274
+ cx: "9",
275
+ cy: "12",
276
+ r: "1"
277
+ }),
278
+ /* @__PURE__ */ jsx("circle", {
279
+ cx: "9",
280
+ cy: "5",
281
+ r: "1"
282
+ }),
283
+ /* @__PURE__ */ jsx("circle", {
284
+ cx: "9",
285
+ cy: "19",
286
+ r: "1"
287
+ }),
288
+ /* @__PURE__ */ jsx("circle", {
289
+ cx: "15",
290
+ cy: "12",
291
+ r: "1"
292
+ }),
293
+ /* @__PURE__ */ jsx("circle", {
294
+ cx: "15",
295
+ cy: "5",
296
+ r: "1"
297
+ }),
298
+ /* @__PURE__ */ jsx("circle", {
299
+ cx: "15",
300
+ cy: "19",
301
+ r: "1"
302
+ })
303
+ ]
304
+ })
305
+ }),
306
+ /* @__PURE__ */ jsxs("div", {
307
+ className: "flex-1 min-w-0 space-y-3",
308
+ children: [
309
+ /* @__PURE__ */ jsxs("div", {
310
+ className: "flex flex-wrap items-center gap-2",
311
+ children: [title && /* @__PURE__ */ jsx("h4", {
312
+ className: "font-medium",
313
+ children: title
314
+ }), badges && /* @__PURE__ */ jsx("div", {
315
+ className: "flex flex-wrap gap-1",
316
+ children: badges
317
+ })]
318
+ }),
319
+ subtitle && /* @__PURE__ */ jsx("p", {
320
+ className: "text-xs text-muted-foreground break-words",
321
+ children: subtitle
322
+ }),
323
+ details,
324
+ children
325
+ ]
326
+ }),
327
+ actions && /* @__PURE__ */ jsx("div", {
328
+ className: "flex items-center gap-2 flex-shrink-0",
329
+ children: actions
330
+ })
331
+ ]
332
+ })
333
+ });
334
+ }
335
+
336
+ //#endregion
337
+ //#region src/components/detail-view.tsx
338
+ const COLUMN_CLASSES = {
339
+ 1: "grid-cols-1",
340
+ 2: "grid-cols-1 sm:grid-cols-2",
341
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"
342
+ };
343
+ const SIZE_LABEL = {
344
+ sm: "text-xs",
345
+ default: "text-sm",
346
+ lg: "text-sm"
347
+ };
348
+ const SIZE_VALUE = {
349
+ sm: "text-sm",
350
+ default: "text-sm",
351
+ lg: "text-base"
352
+ };
353
+ function DetailView({ items, columns = 1, layout = "stacked", size = "default", dividers = false, striped = false, bordered = false, title, description, className, children }) {
354
+ const visibleItems = items?.filter((item) => !item.hidden) || [];
355
+ return /* @__PURE__ */ jsxs("div", {
356
+ className: cn(bordered && "border rounded-lg overflow-hidden", className),
357
+ children: [(title || description) && /* @__PURE__ */ jsxs("div", {
358
+ className: cn("space-y-1", bordered ? "px-4 py-3 border-b bg-muted/30" : "mb-4"),
359
+ children: [title && /* @__PURE__ */ jsx("h3", {
360
+ className: "text-base font-semibold",
361
+ children: title
362
+ }), description && /* @__PURE__ */ jsx("p", {
363
+ className: "text-sm text-muted-foreground",
364
+ children: description
365
+ })]
366
+ }), children ? /* @__PURE__ */ jsx("div", {
367
+ className: cn("grid", COLUMN_CLASSES[columns], bordered && "p-4"),
368
+ children
369
+ }) : layout === "horizontal" ? /* @__PURE__ */ jsx(HorizontalLayout, {
370
+ items: visibleItems,
371
+ size,
372
+ dividers,
373
+ striped,
374
+ bordered
375
+ }) : layout === "inline" ? /* @__PURE__ */ jsx(InlineLayout, {
376
+ items: visibleItems,
377
+ columns,
378
+ size,
379
+ bordered
380
+ }) : /* @__PURE__ */ jsx(StackedLayout, {
381
+ items: visibleItems,
382
+ columns,
383
+ size,
384
+ dividers,
385
+ bordered
386
+ })]
387
+ });
388
+ }
389
+ function StackedLayout({ items, columns, size, dividers, bordered }) {
390
+ return /* @__PURE__ */ jsx("div", {
391
+ className: cn("grid gap-4", COLUMN_CLASSES[columns], bordered && "p-4"),
392
+ children: items.map((item, index) => /* @__PURE__ */ jsxs("div", {
393
+ className: cn("space-y-1", item.fullWidth && columns > 1 && "col-span-full", dividers && index > 0 && "pt-4 border-t"),
394
+ children: [/* @__PURE__ */ jsx("dt", {
395
+ className: cn("text-muted-foreground font-medium", SIZE_LABEL[size]),
396
+ children: item.label
397
+ }), /* @__PURE__ */ jsx("dd", {
398
+ className: cn("text-foreground", SIZE_VALUE[size], item.className),
399
+ children: item.render ? item.render() : item.value ?? /* @__PURE__ */ jsx("span", {
400
+ className: "text-muted-foreground/50",
401
+ children: "-"
402
+ })
403
+ })]
404
+ }, index))
405
+ });
406
+ }
407
+ function HorizontalLayout({ items, size, dividers, striped, bordered }) {
408
+ return /* @__PURE__ */ jsx("dl", {
409
+ className: cn(bordered && "divide-y"),
410
+ children: items.map((item, index) => /* @__PURE__ */ jsxs("div", {
411
+ className: cn("flex items-start gap-4 py-3", bordered && "px-4", striped && index % 2 === 0 && "bg-muted/30", dividers && !bordered && index > 0 && "border-t"),
412
+ children: [/* @__PURE__ */ jsx("dt", {
413
+ className: cn("text-muted-foreground font-medium w-1/3 shrink-0", SIZE_LABEL[size]),
414
+ children: item.label
415
+ }), /* @__PURE__ */ jsx("dd", {
416
+ className: cn("text-foreground flex-1 min-w-0", SIZE_VALUE[size], item.className),
417
+ children: item.render ? item.render() : item.value ?? /* @__PURE__ */ jsx("span", {
418
+ className: "text-muted-foreground/50",
419
+ children: "-"
420
+ })
421
+ })]
422
+ }, index))
423
+ });
424
+ }
425
+ function InlineLayout({ items, columns, size, bordered }) {
426
+ return /* @__PURE__ */ jsx("div", {
427
+ className: cn("grid gap-x-6 gap-y-2", COLUMN_CLASSES[columns], bordered && "p-4"),
428
+ children: items.map((item, index) => /* @__PURE__ */ jsxs("div", {
429
+ className: cn("flex items-center justify-between gap-2 py-1", item.fullWidth && columns > 1 && "col-span-full"),
430
+ children: [/* @__PURE__ */ jsx("span", {
431
+ className: cn("text-muted-foreground", SIZE_LABEL[size]),
432
+ children: item.label
433
+ }), /* @__PURE__ */ jsx("span", {
434
+ className: cn("text-foreground font-medium text-right", SIZE_VALUE[size], item.className),
435
+ children: item.render ? item.render() : item.value ?? "-"
436
+ })]
437
+ }, index))
438
+ });
439
+ }
440
+ function DetailItem({ label, children, value, className, labelClassName, layout = "stacked" }) {
441
+ const content = children ?? value ?? /* @__PURE__ */ jsx("span", {
442
+ className: "text-muted-foreground/50",
443
+ children: "-"
444
+ });
445
+ if (layout === "horizontal") return /* @__PURE__ */ jsxs("div", {
446
+ className: cn("flex items-start gap-4 py-3", className),
447
+ children: [/* @__PURE__ */ jsx("dt", {
448
+ className: cn("text-sm text-muted-foreground font-medium w-1/3 shrink-0", labelClassName),
449
+ children: label
450
+ }), /* @__PURE__ */ jsx("dd", {
451
+ className: "text-sm text-foreground flex-1 min-w-0",
452
+ children: content
453
+ })]
454
+ });
455
+ if (layout === "inline") return /* @__PURE__ */ jsxs("div", {
456
+ className: cn("flex items-center justify-between gap-2 py-1", className),
457
+ children: [/* @__PURE__ */ jsx("span", {
458
+ className: cn("text-sm text-muted-foreground", labelClassName),
459
+ children: label
460
+ }), /* @__PURE__ */ jsx("span", {
461
+ className: "text-sm text-foreground font-medium text-right",
462
+ children: content
463
+ })]
464
+ });
465
+ return /* @__PURE__ */ jsxs("div", {
466
+ className: cn("space-y-1", className),
467
+ children: [/* @__PURE__ */ jsx("dt", {
468
+ className: cn("text-sm text-muted-foreground font-medium", labelClassName),
469
+ children: label
470
+ }), /* @__PURE__ */ jsx("dd", {
471
+ className: "text-sm text-foreground",
472
+ children: content
473
+ })]
474
+ });
475
+ }
476
+
477
+ //#endregion
478
+ //#region src/components/copy-button.tsx
479
+ async function copyToClipboard(text, options) {
480
+ try {
481
+ await navigator.clipboard.writeText(text);
482
+ return true;
483
+ } catch {
484
+ return false;
485
+ }
486
+ }
487
+ function CopyButton({ value, className, size = "sm", variant = "ghost", showToast = true, toastMessage = "Copied to clipboard", errorMessage = "Failed to copy to clipboard", timeout = 2e3, children, ...props }) {
488
+ const [copied, setCopied] = useState(false);
489
+ const handleCopy = async () => {
490
+ if (!value) return;
491
+ if (await copyToClipboard(value, {
492
+ showToast,
493
+ successMessage: toastMessage,
494
+ errorMessage
495
+ })) {
496
+ setCopied(true);
497
+ setTimeout(() => setCopied(false), timeout);
498
+ }
499
+ };
500
+ return /* @__PURE__ */ jsx(Button, {
501
+ variant,
502
+ size,
503
+ className: cn("h-6 w-6 p-0", className),
504
+ onClick: handleCopy,
505
+ disabled: !value,
506
+ "aria-label": copied ? "Copied to clipboard" : "Copy to clipboard",
507
+ ...props,
508
+ children: children || (copied ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3 text-green-600" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3 w-3" }))
509
+ });
510
+ }
511
+ function CopyText({ value, displayValue, className, textClassName, buttonClassName, maxLength = 30, showButton = true, ...buttonProps }) {
512
+ const truncatedValue = displayValue || (value && value.length > maxLength ? `${value.substring(0, maxLength)}...` : value || "N/A");
513
+ return /* @__PURE__ */ jsxs("div", {
514
+ className: cn("flex items-center gap-2", className),
515
+ children: [/* @__PURE__ */ jsx("span", {
516
+ className: cn("font-medium", textClassName),
517
+ title: value || "N/A",
518
+ children: truncatedValue
519
+ }), showButton && value && /* @__PURE__ */ jsx(CopyButton, {
520
+ value,
521
+ className: buttonClassName,
522
+ ...buttonProps
523
+ })]
524
+ });
525
+ }
526
+ function CopyCodeBlock({ value, className, language, showLineNumbers = false, ...buttonProps }) {
527
+ return /* @__PURE__ */ jsxs("div", {
528
+ className: cn("relative group", className),
529
+ children: [/* @__PURE__ */ jsx("pre", {
530
+ className: "bg-muted p-4 rounded-md overflow-x-auto text-sm",
531
+ children: /* @__PURE__ */ jsx("code", {
532
+ className: language ? `language-${language}` : "",
533
+ children: value
534
+ })
535
+ }), /* @__PURE__ */ jsx("div", {
536
+ className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity",
537
+ children: /* @__PURE__ */ jsx(CopyButton, {
538
+ value,
539
+ variant: "secondary",
540
+ size: "sm",
541
+ ...buttonProps
542
+ })
543
+ })]
544
+ });
545
+ }
546
+
547
+ //#endregion
548
+ //#region src/components/info-row.tsx
549
+ function InfoRow({ label, value, copyable = false, icon: Icon }) {
550
+ if (!value && value !== 0) return null;
551
+ return /* @__PURE__ */ jsxs("div", {
552
+ className: "flex flex-col sm:flex-row sm:justify-between sm:items-center py-3 gap-2 group hover:bg-muted rounded-md px-3 -mx-3 transition-colors",
553
+ children: [/* @__PURE__ */ jsxs("div", {
554
+ className: "flex items-center gap-2 min-w-0",
555
+ children: [Icon && /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 text-muted-foreground flex-shrink-0" }), /* @__PURE__ */ jsx("span", {
556
+ className: "text-sm font-medium text-muted-foreground truncate",
557
+ children: label
558
+ })]
559
+ }), /* @__PURE__ */ jsx("div", {
560
+ className: "sm:text-right min-w-0 flex-shrink-0",
561
+ children: copyable ? /* @__PURE__ */ jsx(CopyText, {
562
+ value: String(value),
563
+ textClassName: "text-foreground font-semibold",
564
+ maxLength: 40,
565
+ className: "justify-start sm:justify-end"
566
+ }) : /* @__PURE__ */ jsx("span", {
567
+ className: "font-semibold text-foreground block truncate max-w-full sm:max-w-[250px]",
568
+ title: value?.toString() || "N/A",
569
+ children: value?.toString() || "N/A"
570
+ })
571
+ })]
572
+ });
573
+ }
574
+
575
+ //#endregion
576
+ //#region src/components/pill.tsx
577
+ function Pill({ variant = "secondary", themed = false, className, ...props }) {
578
+ return /* @__PURE__ */ jsx(Badge, {
579
+ className: cn("gap-2 rounded-full px-3 py-1.5 font-normal", className),
580
+ variant,
581
+ ...props
582
+ });
583
+ }
584
+ function PillAvatar({ fallback, className, src, alt, ...props }) {
585
+ return /* @__PURE__ */ jsxs(Avatar, {
586
+ className: cn("-ml-1 h-4 w-4", className),
587
+ children: [/* @__PURE__ */ jsx(AvatarImage, {
588
+ src,
589
+ alt,
590
+ ...props
591
+ }), /* @__PURE__ */ jsx(AvatarFallback, { children: fallback })]
592
+ });
593
+ }
594
+ function PillButton({ className, ...props }) {
595
+ return /* @__PURE__ */ jsx(Button, {
596
+ className: cn("-my-2 -mr-2 size-6 rounded-full p-0.5 hover:bg-foreground/5", className),
597
+ size: "icon",
598
+ variant: "ghost",
599
+ ...props
600
+ });
601
+ }
602
+ function PillStatus({ children, className, ...props }) {
603
+ return /* @__PURE__ */ jsx("div", {
604
+ className: cn("flex items-center gap-2 border-r pr-2 font-medium", className),
605
+ ...props,
606
+ children
607
+ });
608
+ }
609
+ function PillIndicator({ variant = "success", pulse = false }) {
610
+ return /* @__PURE__ */ jsxs("span", {
611
+ className: "relative flex size-2",
612
+ children: [
613
+ pulse && /* @__PURE__ */ jsx("span", { className: cn("absolute inline-flex h-full w-full animate-ping rounded-full opacity-75", variant === "success" && "bg-emerald-400", variant === "error" && "bg-rose-400", variant === "warning" && "bg-amber-400", variant === "info" && "bg-sky-400") }),
614
+ /* @__PURE__ */ jsx("span", { className: cn("relative inline-flex size-2 rounded-full", variant === "success" && "bg-emerald-500", variant === "error" && "bg-rose-500", variant === "warning" && "bg-amber-500", variant === "info" && "bg-sky-500") }),
615
+ /* @__PURE__ */ jsxs("span", {
616
+ className: "sr-only",
617
+ children: [variant, " status"]
618
+ })
619
+ ]
620
+ });
621
+ }
622
+ function PillDelta({ className, delta }) {
623
+ if (!delta) return /* @__PURE__ */ jsx(MinusIcon, { className: cn("size-3 text-muted-foreground", className) });
624
+ if (delta > 0) return /* @__PURE__ */ jsx(ChevronUpIcon, { className: cn("size-3 text-emerald-500", className) });
625
+ return /* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("size-3 text-rose-500", className) });
626
+ }
627
+ function PillIcon({ icon: Icon, className, ...props }) {
628
+ return /* @__PURE__ */ jsx(Icon, {
629
+ className: cn("size-3 text-muted-foreground", className),
630
+ size: 12,
631
+ ...props
632
+ });
633
+ }
634
+ function PillAvatarGroup({ children, className, ...props }) {
635
+ return /* @__PURE__ */ jsx("div", {
636
+ className: cn("-space-x-1 flex items-center", "[&>*:not(:first-of-type)]:mask-[radix-gradient(circle_9px_at_-4px_50%,transparent_99%,white_100%)]", className),
637
+ ...props,
638
+ children
639
+ });
640
+ }
641
+
642
+ //#endregion
643
+ //#region src/components/timeline.tsx
644
+ const STATUS_CONFIG = {
645
+ default: {
646
+ dotClass: "bg-muted-foreground/20 text-muted-foreground",
647
+ lineClass: "bg-border",
648
+ defaultIcon: Circle
649
+ },
650
+ success: {
651
+ dotClass: "bg-green-500/20 text-green-600 dark:text-green-400",
652
+ lineClass: "bg-green-500/30",
653
+ defaultIcon: Check
654
+ },
655
+ error: {
656
+ dotClass: "bg-red-500/20 text-red-600 dark:text-red-400",
657
+ lineClass: "bg-red-500/30",
658
+ defaultIcon: X
659
+ },
660
+ warning: {
661
+ dotClass: "bg-yellow-500/20 text-yellow-600 dark:text-yellow-400",
662
+ lineClass: "bg-yellow-500/30",
663
+ defaultIcon: AlertTriangle
664
+ },
665
+ pending: {
666
+ dotClass: "bg-muted text-muted-foreground animate-pulse",
667
+ lineClass: "bg-border border-dashed",
668
+ defaultIcon: Circle
669
+ },
670
+ active: {
671
+ dotClass: "bg-primary/20 text-primary ring-2 ring-primary/30",
672
+ lineClass: "bg-primary/30",
673
+ defaultIcon: Circle
674
+ }
675
+ };
676
+ const SIZE_CONFIG = {
677
+ sm: {
678
+ dot: "h-6 w-6",
679
+ icon: "h-3 w-3",
680
+ gap: "gap-3",
681
+ text: "text-xs"
682
+ },
683
+ default: {
684
+ dot: "h-8 w-8",
685
+ icon: "h-4 w-4",
686
+ gap: "gap-4",
687
+ text: "text-sm"
688
+ },
689
+ lg: {
690
+ dot: "h-10 w-10",
691
+ icon: "h-5 w-5",
692
+ gap: "gap-5",
693
+ text: "text-base"
694
+ }
695
+ };
696
+ function Timeline({ items, orientation = "vertical", size = "default", showConnectors = true, reverse = false, className }) {
697
+ const sizeConfig = SIZE_CONFIG[size];
698
+ const orderedItems = reverse ? [...items].reverse() : items;
699
+ if (orientation === "horizontal") return /* @__PURE__ */ jsx("div", {
700
+ className: cn("flex overflow-x-auto", sizeConfig.gap, className),
701
+ children: orderedItems.map((item, index) => /* @__PURE__ */ jsx(HorizontalTimelineItem, {
702
+ item,
703
+ isLast: index === orderedItems.length - 1,
704
+ showConnector: showConnectors,
705
+ size
706
+ }, index))
707
+ });
708
+ return /* @__PURE__ */ jsx("div", {
709
+ className: cn("relative", className),
710
+ children: orderedItems.map((item, index) => /* @__PURE__ */ jsx(VerticalTimelineItem, {
711
+ item,
712
+ isLast: index === orderedItems.length - 1,
713
+ showConnector: showConnectors,
714
+ size
715
+ }, index))
716
+ });
717
+ }
718
+ function VerticalTimelineItem({ item, isLast, showConnector, size }) {
719
+ const config = STATUS_CONFIG[item.status || "default"];
720
+ const sizeConfig = SIZE_CONFIG[size];
721
+ const renderIcon = () => {
722
+ if (React$1.isValidElement(item.icon)) return item.icon;
723
+ return /* @__PURE__ */ jsx(item.icon || config.defaultIcon, { className: sizeConfig.icon });
724
+ };
725
+ return /* @__PURE__ */ jsxs("div", {
726
+ className: cn("flex", sizeConfig.gap, "pb-6 last:pb-0"),
727
+ children: [/* @__PURE__ */ jsxs("div", {
728
+ className: "flex flex-col items-center shrink-0",
729
+ children: [/* @__PURE__ */ jsx("div", {
730
+ className: cn("flex items-center justify-center rounded-full shrink-0", sizeConfig.dot, config.dotClass),
731
+ children: renderIcon()
732
+ }), showConnector && !isLast && /* @__PURE__ */ jsx("div", { className: cn("w-0.5 flex-1 mt-2", config.lineClass) })]
733
+ }), /* @__PURE__ */ jsxs("div", {
734
+ className: "min-w-0 flex-1 pt-0.5 pb-2",
735
+ children: [
736
+ /* @__PURE__ */ jsxs("div", {
737
+ className: "flex items-start justify-between gap-2",
738
+ children: [/* @__PURE__ */ jsxs("div", {
739
+ className: "min-w-0",
740
+ children: [/* @__PURE__ */ jsx("p", {
741
+ className: cn("font-medium leading-tight", sizeConfig.text),
742
+ children: item.title
743
+ }), item.label && /* @__PURE__ */ jsx("p", {
744
+ className: "text-xs text-muted-foreground mt-0.5",
745
+ children: item.label
746
+ })]
747
+ }), item.timestamp && /* @__PURE__ */ jsx("time", {
748
+ className: "text-xs text-muted-foreground whitespace-nowrap shrink-0",
749
+ children: item.timestamp
750
+ })]
751
+ }),
752
+ item.description && /* @__PURE__ */ jsx("div", {
753
+ className: "text-sm text-muted-foreground mt-1",
754
+ children: item.description
755
+ }),
756
+ item.content && /* @__PURE__ */ jsx("div", {
757
+ className: "mt-2",
758
+ children: item.content
759
+ })
760
+ ]
761
+ })]
762
+ });
763
+ }
764
+ function HorizontalTimelineItem({ item, isLast, showConnector, size }) {
765
+ const config = STATUS_CONFIG[item.status || "default"];
766
+ const sizeConfig = SIZE_CONFIG[size];
767
+ const renderIcon = () => {
768
+ if (React$1.isValidElement(item.icon)) return item.icon;
769
+ return /* @__PURE__ */ jsx(item.icon || config.defaultIcon, { className: sizeConfig.icon });
770
+ };
771
+ return /* @__PURE__ */ jsxs("div", {
772
+ className: "flex flex-col items-center min-w-[120px]",
773
+ children: [/* @__PURE__ */ jsxs("div", {
774
+ className: "flex items-center w-full",
775
+ children: [
776
+ /* @__PURE__ */ jsx("div", { className: cn("h-0.5 flex-1", showConnector ? config.lineClass : "bg-transparent") }),
777
+ /* @__PURE__ */ jsx("div", {
778
+ className: cn("flex items-center justify-center rounded-full shrink-0 mx-1", sizeConfig.dot, config.dotClass),
779
+ children: renderIcon()
780
+ }),
781
+ /* @__PURE__ */ jsx("div", { className: cn("h-0.5 flex-1", showConnector && !isLast ? config.lineClass : "bg-transparent") })
782
+ ]
783
+ }), /* @__PURE__ */ jsxs("div", {
784
+ className: "text-center mt-2 px-2",
785
+ children: [
786
+ /* @__PURE__ */ jsx("p", {
787
+ className: cn("font-medium leading-tight", sizeConfig.text),
788
+ children: item.title
789
+ }),
790
+ item.timestamp && /* @__PURE__ */ jsx("time", {
791
+ className: "text-xs text-muted-foreground",
792
+ children: item.timestamp
793
+ }),
794
+ item.description && /* @__PURE__ */ jsx("div", {
795
+ className: "text-xs text-muted-foreground mt-1",
796
+ children: item.description
797
+ })
798
+ ]
799
+ })]
800
+ });
801
+ }
802
+
803
+ //#endregion
804
+ export { FaqAccordion as S, DataCard as _, PillButton as a, StatsCard as b, PillIndicator as c, CopyButton as d, CopyCodeBlock as f, CardWrapper as g, DetailView as h, PillAvatarGroup as i, PillStatus as l, DetailItem as m, Pill as n, PillDelta as o, CopyText as p, PillAvatar as r, PillIcon as s, Timeline as t, InfoRow as u, DraggableCard as v, AccordionSection as x, LoadingCard as y };