xertica-ui 2.1.2 → 2.1.4

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 (181) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +1 -1
  3. package/bin/cli.ts +1 -1
  4. package/bin/generate-tokens.ts +13 -7
  5. package/components/assistant/xertica-assistant/index.ts +2 -0
  6. package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +97 -0
  7. package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -0
  8. package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -0
  9. package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +86 -0
  10. package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +77 -0
  11. package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +573 -0
  12. package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +65 -0
  13. package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -0
  14. package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +98 -0
  15. package/components/assistant/xertica-assistant/parts/index.ts +16 -0
  16. package/components/assistant/xertica-assistant/types.ts +139 -0
  17. package/components/assistant/xertica-assistant/use-assistant.ts +559 -0
  18. package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +200 -0
  19. package/components/assistant/xertica-assistant/xertica-assistant.tsx +198 -1460
  20. package/components/brand/theme-toggle/ThemeToggle.tsx +8 -27
  21. package/components/hooks/index.ts +3 -0
  22. package/components/hooks/use-layout-shortcuts.ts +46 -0
  23. package/components/layout/sidebar/index.ts +2 -0
  24. package/components/layout/sidebar/sidebar.stories.tsx +160 -8
  25. package/components/layout/sidebar/sidebar.tsx +606 -497
  26. package/components/layout/sidebar/use-sidebar.ts +104 -0
  27. package/components/media/audio-player/AudioPlayer.tsx +131 -206
  28. package/components/media/audio-player/use-audio-player.ts +298 -0
  29. package/components/pages/home-page/HomePage.tsx +1 -1
  30. package/components/pages/template-content/TemplateContent.tsx +5 -5
  31. package/components/pages/template-page/TemplatePage.tsx +5 -5
  32. package/components/shared/CustomTooltipContent.tsx +52 -0
  33. package/components/shared/layout-constants.ts +1 -1
  34. package/components/ui/chart/chart.stories.tsx +966 -7
  35. package/components/ui/chart/chart.tsx +918 -45
  36. package/components/ui/file-upload/file-upload.stories.tsx +100 -0
  37. package/components/ui/file-upload/file-upload.tsx +14 -74
  38. package/components/ui/file-upload/index.ts +1 -0
  39. package/components/ui/file-upload/use-file-upload.ts +181 -0
  40. package/components/ui/pagination/index.ts +2 -0
  41. package/components/ui/pagination/pagination.stories.tsx +94 -0
  42. package/components/ui/pagination/use-pagination.ts +194 -0
  43. package/components/ui/rich-text-editor/index.ts +2 -0
  44. package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +129 -1
  45. package/components/ui/rich-text-editor/rich-text-editor.tsx +86 -305
  46. package/components/ui/rich-text-editor/use-rich-text-editor.ts +439 -0
  47. package/components/ui/stepper/index.ts +3 -1
  48. package/components/ui/stepper/stepper.stories.tsx +116 -0
  49. package/components/ui/stepper/stepper.tsx +4 -4
  50. package/components/ui/stepper/use-stepper.ts +137 -0
  51. package/components/ui/tree-view/index.ts +4 -1
  52. package/components/ui/tree-view/tree-view.stories.tsx +110 -4
  53. package/components/ui/tree-view/tree-view.tsx +17 -125
  54. package/components/ui/tree-view/use-tree-view.ts +229 -0
  55. package/contexts/AssistenteContext.tsx +17 -54
  56. package/contexts/BrandColorsContext.tsx +6 -17
  57. package/contexts/LayoutContext.tsx +5 -31
  58. package/dist/AssistantChart-BAudAfne.cjs +3591 -0
  59. package/dist/AssistantChart-BP8upjMk.js +3565 -0
  60. package/dist/AudioPlayer-1ypwE2Wh.cjs +936 -0
  61. package/dist/AudioPlayer-DuKXrCfy.js +937 -0
  62. package/dist/CustomTooltipContent-DHjkY0ww.js +40 -0
  63. package/dist/CustomTooltipContent-c_K-DWRr.cjs +56 -0
  64. package/dist/LanguageContext-BwhwC3G2.js +657 -0
  65. package/dist/LanguageContext-DvUt5jBg.cjs +656 -0
  66. package/dist/LayoutContext-BDmcZfMH.cjs +84 -0
  67. package/dist/LayoutContext-dbQvdC4O.js +85 -0
  68. package/dist/ThemeContext-RTy1m2Uq.js +82 -0
  69. package/dist/ThemeContext-bSzuOit2.cjs +81 -0
  70. package/dist/VerifyEmailPage-C_ihbcth.js +2828 -0
  71. package/dist/VerifyEmailPage-Dt7zgA4w.cjs +2827 -0
  72. package/dist/XerticaProvider-CW9hpCdF.cjs +39 -0
  73. package/dist/XerticaProvider-siSt9uG2.js +40 -0
  74. package/dist/XerticaXLogo-D8jf0SNv.cjs +214 -0
  75. package/dist/XerticaXLogo-fAJMy3H4.js +215 -0
  76. package/dist/assistant.cjs.js +2 -1
  77. package/dist/assistant.es.js +3 -2
  78. package/dist/brand.cjs.js +2 -2
  79. package/dist/brand.es.js +2 -2
  80. package/dist/cli.js +14 -8
  81. package/dist/components/assistant/xertica-assistant/index.d.ts +2 -0
  82. package/dist/components/assistant/xertica-assistant/parts/AssistantCollapsedView.d.ts +13 -0
  83. package/dist/components/assistant/xertica-assistant/parts/AssistantConversationList.d.ts +16 -0
  84. package/dist/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.d.ts +17 -0
  85. package/dist/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.d.ts +19 -0
  86. package/dist/components/assistant/xertica-assistant/parts/AssistantHeader.d.ts +11 -0
  87. package/dist/components/assistant/xertica-assistant/parts/AssistantMessageBubble.d.ts +29 -0
  88. package/dist/components/assistant/xertica-assistant/parts/AssistantTabBar.d.ts +13 -0
  89. package/dist/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.d.ts +4 -0
  90. package/dist/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.d.ts +17 -0
  91. package/dist/components/assistant/xertica-assistant/parts/index.d.ts +16 -0
  92. package/dist/components/assistant/xertica-assistant/types.d.ts +106 -0
  93. package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +125 -0
  94. package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +8 -97
  95. package/dist/components/hooks/index.d.ts +3 -0
  96. package/dist/components/hooks/use-layout-shortcuts.d.ts +22 -0
  97. package/dist/components/layout/sidebar/index.d.ts +2 -0
  98. package/dist/components/layout/sidebar/sidebar.d.ts +80 -0
  99. package/dist/components/layout/sidebar/use-sidebar.d.ts +22 -0
  100. package/dist/components/media/audio-player/AudioPlayer.d.ts +4 -1
  101. package/dist/components/media/audio-player/use-audio-player.d.ts +72 -0
  102. package/dist/components/shared/CustomTooltipContent.d.ts +20 -0
  103. package/dist/components/shared/layout-constants.d.ts +1 -1
  104. package/dist/components/ui/alert/alert.d.ts +1 -1
  105. package/dist/components/ui/badge/badge.d.ts +1 -1
  106. package/dist/components/ui/button/button.d.ts +2 -2
  107. package/dist/components/ui/chart/chart.d.ts +162 -5
  108. package/dist/components/ui/file-upload/file-upload.d.ts +2 -0
  109. package/dist/components/ui/file-upload/index.d.ts +1 -0
  110. package/dist/components/ui/file-upload/use-file-upload.d.ts +49 -0
  111. package/dist/components/ui/pagination/index.d.ts +2 -0
  112. package/dist/components/ui/pagination/use-pagination.d.ts +78 -0
  113. package/dist/components/ui/rich-text-editor/index.d.ts +2 -0
  114. package/dist/components/ui/rich-text-editor/use-rich-text-editor.d.ts +107 -0
  115. package/dist/components/ui/stepper/index.d.ts +3 -1
  116. package/dist/components/ui/stepper/stepper.d.ts +2 -2
  117. package/dist/components/ui/stepper/use-stepper.d.ts +60 -0
  118. package/dist/components/ui/tree-view/index.d.ts +4 -1
  119. package/dist/components/ui/tree-view/tree-view.d.ts +4 -6
  120. package/dist/components/ui/tree-view/use-tree-view.d.ts +60 -0
  121. package/dist/contexts/AssistenteContext.d.ts +10 -49
  122. package/dist/hooks.cjs.js +30 -10
  123. package/dist/hooks.es.js +25 -4
  124. package/dist/index.cjs.js +20 -9
  125. package/dist/index.es.js +38 -27
  126. package/dist/layout.cjs.js +82 -1
  127. package/dist/layout.es.js +83 -2
  128. package/dist/media.cjs.js +1 -1
  129. package/dist/media.es.js +1 -1
  130. package/dist/pages.cjs.js +1 -1
  131. package/dist/pages.es.js +1 -1
  132. package/dist/rich-text-editor-BmsjY03B.js +2949 -0
  133. package/dist/rich-text-editor-GS2kpTAK.cjs +2966 -0
  134. package/dist/sidebar-CVUGHOS_.cjs +756 -0
  135. package/dist/sidebar-CmvwjnVb.js +757 -0
  136. package/dist/ui.cjs.js +12 -2
  137. package/dist/ui.es.js +24 -14
  138. package/dist/use-audio-player-Bkh23vQ3.js +177 -0
  139. package/dist/use-audio-player-Dn1NR9xN.cjs +176 -0
  140. package/dist/utils/color-utils.d.ts +51 -0
  141. package/dist/xertica-assistant-BMqdyRVi.js +2082 -0
  142. package/dist/xertica-assistant-Bj3vBCq_.cjs +2081 -0
  143. package/dist/xertica-ui.css +1 -1
  144. package/docs/ai-usage.md +28 -10
  145. package/docs/architecture-improvements.md +463 -0
  146. package/docs/architecture.md +77 -1
  147. package/docs/components/assistant-chart.md +1 -1
  148. package/docs/components/assistant.md +159 -0
  149. package/docs/components/audio-player.md +46 -0
  150. package/docs/components/branding.md +251 -0
  151. package/docs/components/chart.md +354 -39
  152. package/docs/components/code-block.md +108 -0
  153. package/docs/components/file-upload.md +119 -2
  154. package/docs/components/formatted-document.md +113 -0
  155. package/docs/components/hooks.md +430 -0
  156. package/docs/components/image-with-fallback.md +106 -0
  157. package/docs/components/map-layers.md +140 -0
  158. package/docs/components/modern-chat-input.md +163 -0
  159. package/docs/components/pages.md +351 -0
  160. package/docs/components/pagination.md +187 -0
  161. package/docs/components/rich-text-editor.md +164 -0
  162. package/docs/components/sidebar.md +153 -4
  163. package/docs/components/stepper.md +157 -12
  164. package/docs/components/tree-view.md +164 -6
  165. package/docs/doc-audit.md +223 -0
  166. package/docs/getting-started.md +155 -1
  167. package/docs/guidelines.md +14 -8
  168. package/docs/layout.md +2 -2
  169. package/docs/llms.md +29 -9
  170. package/docs/patterns/detail-page.md +276 -0
  171. package/docs/patterns/settings.md +346 -0
  172. package/docs/patterns/wizard.md +217 -0
  173. package/guidelines/Guidelines.md +5 -3
  174. package/llms.txt +1 -1
  175. package/package.json +10 -10
  176. package/styles/xertica/tokens.css +41 -12
  177. package/templates/CLAUDE.md +16 -6
  178. package/templates/guidelines/Guidelines.md +16 -4
  179. package/templates/package.json +3 -3
  180. package/templates/src/styles/xertica/tokens.css +39 -10
  181. package/utils/color-utils.ts +72 -0
@@ -0,0 +1,3565 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
3
+ import { GripVerticalIcon, ChevronDownIcon, MoreHorizontalIcon, ChevronRightIcon, ChevronLeftIcon, MinusIcon, ChevronLeft, ChevronRight, ChevronDown, XIcon, CheckIcon, CircleIcon, SearchIcon, TrendingUp, TrendingDown, Minus, ArrowRight, ArrowLeft, X, Check, Upload, AlertCircle, FileIcon, Star, Search as Search$1 } from "lucide-react";
4
+ import * as React from "react";
5
+ import React__default, { useState, useCallback, useMemo, useRef, useEffect } from "react";
6
+ import { c as cn, b as buttonVariants, B as Button } from "./button-qkz7Icqf.js";
7
+ import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
8
+ import { cva } from "class-variance-authority";
9
+ import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
10
+ import * as TogglePrimitive from "@radix-ui/react-toggle";
11
+ import { OTPInput, OTPInputContext } from "input-otp";
12
+ import { Slot } from "@radix-ui/react-slot";
13
+ import { FormProvider, Controller, useFormContext, useFormState } from "react-hook-form";
14
+ import { L as Label, M as Map$1 } from "./alert-dialog-iDe5VE5o.js";
15
+ import { getDefaultClassNames, DayPicker } from "react-day-picker";
16
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
17
+ import { Drawer as Drawer$1 } from "vaul";
18
+ import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
19
+ import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
20
+ import * as MenubarPrimitive from "@radix-ui/react-menubar";
21
+ import { Command as Command$1 } from "cmdk";
22
+ import { k as Dialog, q as DialogHeader, t as DialogTitle, o as DialogDescription, n as DialogContent, c as ChartContainer, g as ChartTooltip, h as ChartTooltipContent } from "./rich-text-editor-BmsjY03B.js";
23
+ import { C as Card, b as CardContent } from "./card-fi8zAN-I.js";
24
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
25
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
26
+ import useEmblaCarousel from "embla-carousel-react";
27
+ import { u as useGoogleMapsLoader } from "./google-maps-loader-t2IlYBzw.js";
28
+ import { BarChart, CartesianGrid, XAxis, Bar } from "recharts";
29
+ function AspectRatio({
30
+ ...props
31
+ }) {
32
+ return /* @__PURE__ */ jsx(AspectRatioPrimitive.Root, { "data-slot": "aspect-ratio", ...props });
33
+ }
34
+ const ResizableContext = React.createContext(null);
35
+ const ResizablePanelGroup = ({
36
+ children,
37
+ className,
38
+ direction = "horizontal",
39
+ id,
40
+ autoSaveId,
41
+ storage,
42
+ onLayout,
43
+ ...props
44
+ }) => {
45
+ const [panels, setPanels] = React.useState(/* @__PURE__ */ new Map());
46
+ const [handles, setHandles] = React.useState(/* @__PURE__ */ new Map());
47
+ const [sizes, setSizes] = React.useState(/* @__PURE__ */ new Map());
48
+ const [isDragging, setIsDragging] = React.useState(false);
49
+ const containerRef = React.useRef(null);
50
+ const getSortedItems = React.useCallback((items) => {
51
+ if (!containerRef.current) return [];
52
+ return Array.from(items.values()).sort((a, b) => {
53
+ if (!a.ref.current || !b.ref.current) return 0;
54
+ const position = a.ref.current.compareDocumentPosition(b.ref.current);
55
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
56
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;
57
+ return 0;
58
+ });
59
+ }, []);
60
+ React.useEffect(() => {
61
+ const sortedPanels = getSortedItems(panels);
62
+ if (sortedPanels.length === 0) return;
63
+ const uninitialized = sortedPanels.some((p) => !sizes.has(p.id));
64
+ if (uninitialized) {
65
+ const newSizes = new Map(sizes);
66
+ const remainingSpace = 100;
67
+ const defaultSizeCount = sortedPanels.filter((p) => p.defaultSize).length;
68
+ let usedSpace = 0;
69
+ sortedPanels.forEach((p) => {
70
+ if (p.defaultSize) usedSpace += p.defaultSize;
71
+ });
72
+ const spaceForOthers = Math.max(0, remainingSpace - usedSpace);
73
+ const countOthers = sortedPanels.length - defaultSizeCount;
74
+ const sizeForOthers = countOthers > 0 ? spaceForOthers / countOthers : 0;
75
+ sortedPanels.forEach((p) => {
76
+ if (!newSizes.has(p.id)) {
77
+ newSizes.set(p.id, p.defaultSize ?? sizeForOthers);
78
+ }
79
+ });
80
+ setSizes(newSizes);
81
+ }
82
+ }, [panels, sizes, getSortedItems]);
83
+ const registerPanel = React.useCallback((data) => {
84
+ setPanels((prev) => {
85
+ const next = new Map(prev);
86
+ next.set(data.id, data);
87
+ return next;
88
+ });
89
+ }, []);
90
+ const unregisterPanel = React.useCallback((id2) => {
91
+ setPanels((prev) => {
92
+ const next = new Map(prev);
93
+ next.delete(id2);
94
+ return next;
95
+ });
96
+ setSizes((prev) => {
97
+ const next = new Map(prev);
98
+ next.delete(id2);
99
+ return next;
100
+ });
101
+ }, []);
102
+ const registerHandle = React.useCallback((data) => {
103
+ setHandles((prev) => {
104
+ const next = new Map(prev);
105
+ next.set(data.id, data);
106
+ return next;
107
+ });
108
+ }, []);
109
+ const unregisterHandle = React.useCallback((id2) => {
110
+ setHandles((prev) => {
111
+ const next = new Map(prev);
112
+ next.delete(id2);
113
+ return next;
114
+ });
115
+ }, []);
116
+ const startDragging = React.useCallback((handleId, event) => {
117
+ var _a, _b;
118
+ event.preventDefault();
119
+ setIsDragging(true);
120
+ const sortedPanels = getSortedItems(panels);
121
+ const sortedHandles = getSortedItems(handles);
122
+ const handleIndex = sortedHandles.findIndex((h) => h.id === handleId);
123
+ if (handleIndex === -1) return;
124
+ const leftPanel = sortedPanels[handleIndex];
125
+ const rightPanel = sortedPanels[handleIndex + 1];
126
+ if (!leftPanel || !rightPanel) return;
127
+ const startX = "touches" in event ? event.touches[0].clientX : event.clientX;
128
+ const startY = "touches" in event ? event.touches[0].clientY : event.clientY;
129
+ const startSizeLeft = sizes.get(leftPanel.id) || 0;
130
+ const startSizeRight = sizes.get(rightPanel.id) || 0;
131
+ const containerSize = direction === "horizontal" ? ((_a = containerRef.current) == null ? void 0 : _a.offsetWidth) || 1 : ((_b = containerRef.current) == null ? void 0 : _b.offsetHeight) || 1;
132
+ const onMove = (e) => {
133
+ var _a2, _b2;
134
+ const currentX = "touches" in e ? e.touches[0].clientX : e.clientX;
135
+ const currentY = "touches" in e ? e.touches[0].clientY : e.clientY;
136
+ const deltaPixels = direction === "horizontal" ? currentX - startX : currentY - startY;
137
+ const deltaPercent = deltaPixels / containerSize * 100;
138
+ let finalLeft = startSizeLeft + deltaPercent;
139
+ let finalRight = startSizeRight - deltaPercent;
140
+ if (leftPanel.minSize !== void 0 && finalLeft < leftPanel.minSize) {
141
+ const diff = leftPanel.minSize - finalLeft;
142
+ finalLeft = leftPanel.minSize;
143
+ finalRight -= diff;
144
+ }
145
+ if (rightPanel.minSize !== void 0 && finalRight < rightPanel.minSize) {
146
+ const diff = rightPanel.minSize - finalRight;
147
+ finalRight = rightPanel.minSize;
148
+ finalLeft -= diff;
149
+ }
150
+ if (leftPanel.maxSize !== void 0 && finalLeft > leftPanel.maxSize) {
151
+ const diff = finalLeft - leftPanel.maxSize;
152
+ finalLeft = leftPanel.maxSize;
153
+ finalRight += diff;
154
+ }
155
+ if (rightPanel.maxSize !== void 0 && finalRight > rightPanel.maxSize) {
156
+ const diff = finalRight - rightPanel.maxSize;
157
+ finalRight = rightPanel.maxSize;
158
+ finalLeft -= diff;
159
+ }
160
+ finalLeft = Math.max(0, Math.min(100, finalLeft));
161
+ finalRight = Math.max(0, Math.min(100, finalRight));
162
+ setSizes((prev) => {
163
+ const next = new Map(prev);
164
+ next.set(leftPanel.id, finalLeft);
165
+ next.set(rightPanel.id, finalRight);
166
+ return next;
167
+ });
168
+ (_a2 = leftPanel.onResize) == null ? void 0 : _a2.call(leftPanel, finalLeft);
169
+ (_b2 = rightPanel.onResize) == null ? void 0 : _b2.call(rightPanel, finalRight);
170
+ };
171
+ const onUp = () => {
172
+ setIsDragging(false);
173
+ window.removeEventListener("mousemove", onMove);
174
+ window.removeEventListener("mouseup", onUp);
175
+ window.removeEventListener("touchmove", onMove);
176
+ window.removeEventListener("touchend", onUp);
177
+ if (onLayout) {
178
+ onLayout(sortedPanels.map((p) => sizes.get(p.id) || 0));
179
+ }
180
+ };
181
+ window.addEventListener("mousemove", onMove);
182
+ window.addEventListener("mouseup", onUp);
183
+ window.addEventListener("touchmove", onMove);
184
+ window.addEventListener("touchend", onUp);
185
+ }, [panels, handles, sizes, direction, getSortedItems, onLayout]);
186
+ const getPanelStyle = React.useCallback((id2) => {
187
+ const size = sizes.get(id2);
188
+ if (size === void 0) return { flex: "1 1 0%", overflow: "hidden" };
189
+ return { flex: `${size} 1 0%`, overflow: "hidden" };
190
+ }, [sizes]);
191
+ const contextValue = React.useMemo(() => ({
192
+ direction,
193
+ registerPanel,
194
+ unregisterPanel,
195
+ registerHandle,
196
+ unregisterHandle,
197
+ isDragging,
198
+ startDragging,
199
+ getPanelStyle
200
+ }), [direction, registerPanel, unregisterPanel, registerHandle, unregisterHandle, isDragging, startDragging, getPanelStyle]);
201
+ return /* @__PURE__ */ jsx(ResizableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
202
+ "div",
203
+ {
204
+ ref: containerRef,
205
+ "data-slot": "resizable-panel-group",
206
+ "data-panel-group-direction": direction,
207
+ className: cn(
208
+ "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
209
+ className
210
+ ),
211
+ ...props,
212
+ children
213
+ }
214
+ ) });
215
+ };
216
+ const ResizablePanel = ({
217
+ className,
218
+ defaultSize,
219
+ minSize = 0,
220
+ maxSize = 100,
221
+ collapsible,
222
+ collapsedSize,
223
+ onCollapse,
224
+ onExpand,
225
+ onResize,
226
+ order,
227
+ tagName,
228
+ id: propId,
229
+ children,
230
+ ...props
231
+ }) => {
232
+ const context = React.useContext(ResizableContext);
233
+ const ref = React.useRef(null);
234
+ const [generatedId] = React.useState(() => Math.random().toString(36).substr(2, 9));
235
+ const id = propId || generatedId;
236
+ const registerPanel = context == null ? void 0 : context.registerPanel;
237
+ const unregisterPanel = context == null ? void 0 : context.unregisterPanel;
238
+ React.useLayoutEffect(() => {
239
+ if (!registerPanel || !unregisterPanel) return;
240
+ registerPanel({
241
+ id,
242
+ ref,
243
+ defaultSize,
244
+ minSize,
245
+ maxSize,
246
+ collapsible,
247
+ onCollapse,
248
+ onExpand,
249
+ onResize
250
+ });
251
+ return () => unregisterPanel(id);
252
+ }, [registerPanel, unregisterPanel, id, defaultSize, minSize, maxSize, collapsible, onCollapse, onExpand, onResize]);
253
+ if (!context) {
254
+ return /* @__PURE__ */ jsx("div", { className: cn("flex-1", className), ...props, children });
255
+ }
256
+ return /* @__PURE__ */ jsx(
257
+ "div",
258
+ {
259
+ ref,
260
+ "data-slot": "resizable-panel",
261
+ className: cn("relative transition-[flex-grow] duration-0", className),
262
+ style: context.getPanelStyle(id),
263
+ ...props,
264
+ children
265
+ }
266
+ );
267
+ };
268
+ const ResizableHandle = ({
269
+ withHandle,
270
+ className,
271
+ id: propId,
272
+ tagName,
273
+ ...props
274
+ }) => {
275
+ const context = React.useContext(ResizableContext);
276
+ const ref = React.useRef(null);
277
+ const [generatedId] = React.useState(() => Math.random().toString(36).substr(2, 9));
278
+ const id = propId || generatedId;
279
+ const registerHandle = context == null ? void 0 : context.registerHandle;
280
+ const unregisterHandle = context == null ? void 0 : context.unregisterHandle;
281
+ React.useLayoutEffect(() => {
282
+ if (!registerHandle || !unregisterHandle) return;
283
+ registerHandle({ id, ref });
284
+ return () => unregisterHandle(id);
285
+ }, [registerHandle, unregisterHandle, id]);
286
+ const handleMouseDown = (e) => {
287
+ if (context) {
288
+ context.startDragging(id, e);
289
+ }
290
+ };
291
+ if (!context) return null;
292
+ return /* @__PURE__ */ jsx(
293
+ "div",
294
+ {
295
+ ref,
296
+ "data-slot": "resizable-handle",
297
+ className: cn(
298
+ "bg-border relative flex items-center justify-center focus-visible:outline-hidden",
299
+ "touch-none select-none",
300
+ context.direction === "vertical" ? "h-px w-full cursor-row-resize after:left-0 after:h-1 after:w-full after:-translate-y-1/2 hover:after:h-4" : "w-px h-full cursor-col-resize after:top-0 after:w-1 after:h-full after:-translate-x-1/2 hover:after:w-4",
301
+ "after:absolute after:z-10",
302
+ className
303
+ ),
304
+ onMouseDown: handleMouseDown,
305
+ onTouchStart: handleMouseDown,
306
+ ...props,
307
+ children: withHandle && /* @__PURE__ */ jsx("div", { className: "bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border", children: /* @__PURE__ */ jsx(GripVerticalIcon, { className: "size-2.5" }) })
308
+ }
309
+ );
310
+ };
311
+ function NavigationMenu({
312
+ className,
313
+ children,
314
+ viewport = true,
315
+ ...props
316
+ }) {
317
+ return /* @__PURE__ */ jsxs(
318
+ NavigationMenuPrimitive.Root,
319
+ {
320
+ "data-slot": "navigation-menu",
321
+ className: cn(
322
+ "relative z-10 flex w-full flex-1 items-center justify-center",
323
+ className
324
+ ),
325
+ ...props,
326
+ children: [
327
+ children,
328
+ viewport && /* @__PURE__ */ jsx(NavigationMenuViewport, {})
329
+ ]
330
+ }
331
+ );
332
+ }
333
+ function NavigationMenuList({
334
+ className,
335
+ ...props
336
+ }) {
337
+ return /* @__PURE__ */ jsx(
338
+ NavigationMenuPrimitive.List,
339
+ {
340
+ "data-slot": "navigation-menu-list",
341
+ className: cn(
342
+ "group flex flex-1 list-none items-center justify-center gap-1",
343
+ className
344
+ ),
345
+ ...props
346
+ }
347
+ );
348
+ }
349
+ function NavigationMenuItem({
350
+ className,
351
+ ...props
352
+ }) {
353
+ return /* @__PURE__ */ jsx(
354
+ NavigationMenuPrimitive.Item,
355
+ {
356
+ "data-slot": "navigation-menu-item",
357
+ className: cn("relative", className),
358
+ ...props
359
+ }
360
+ );
361
+ }
362
+ const navigationMenuTriggerStyle = cva(
363
+ "group inline-flex h-10 w-max items-center justify-center rounded-[var(--radius)] bg-background px-4 py-2 text-[var(--text-p)] font-[var(--font-weight-medium)] hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:bg-accent/50 outline-none focus-visible:ring-2 focus-visible:ring-ring"
364
+ );
365
+ function NavigationMenuTrigger({
366
+ className,
367
+ children,
368
+ ...props
369
+ }) {
370
+ return /* @__PURE__ */ jsxs(
371
+ NavigationMenuPrimitive.Trigger,
372
+ {
373
+ "data-slot": "navigation-menu-trigger",
374
+ className: cn(navigationMenuTriggerStyle(), "group", className),
375
+ ...props,
376
+ children: [
377
+ children,
378
+ " ",
379
+ /* @__PURE__ */ jsx(
380
+ ChevronDownIcon,
381
+ {
382
+ className: "relative top-[1px] ml-1 size-3 group-data-[state=open]:rotate-180",
383
+ "aria-hidden": "true"
384
+ }
385
+ )
386
+ ]
387
+ }
388
+ );
389
+ }
390
+ function NavigationMenuContent({
391
+ className,
392
+ ...props
393
+ }) {
394
+ return /* @__PURE__ */ jsx(
395
+ NavigationMenuPrimitive.Content,
396
+ {
397
+ "data-slot": "navigation-menu-content",
398
+ className: cn(
399
+ "left-0 top-0 w-full md:w-auto",
400
+ className
401
+ ),
402
+ ...props
403
+ }
404
+ );
405
+ }
406
+ function NavigationMenuViewport({
407
+ className,
408
+ ...props
409
+ }) {
410
+ return /* @__PURE__ */ jsx("div", { className: cn("absolute left-0 top-full flex justify-center w-full"), children: /* @__PURE__ */ jsx(
411
+ NavigationMenuPrimitive.Viewport,
412
+ {
413
+ "data-slot": "navigation-menu-viewport",
414
+ className: cn(
415
+ "origin-top-center relative mt-1.5 overflow-hidden rounded-[var(--radius)] border border-border bg-popover text-popover-foreground shadow-lg",
416
+ className
417
+ ),
418
+ ...props
419
+ }
420
+ ) });
421
+ }
422
+ function NavigationMenuLink({
423
+ className,
424
+ ...props
425
+ }) {
426
+ return /* @__PURE__ */ jsx(
427
+ NavigationMenuPrimitive.Link,
428
+ {
429
+ "data-slot": "navigation-menu-link",
430
+ className: cn(
431
+ "block select-none space-y-1 rounded-[var(--radius)] p-3 leading-none no-underline outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
432
+ className
433
+ ),
434
+ ...props
435
+ }
436
+ );
437
+ }
438
+ function NavigationMenuIndicator({
439
+ className,
440
+ ...props
441
+ }) {
442
+ return /* @__PURE__ */ jsx(
443
+ NavigationMenuPrimitive.Indicator,
444
+ {
445
+ "data-slot": "navigation-menu-indicator",
446
+ className: cn(
447
+ "top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden",
448
+ className
449
+ ),
450
+ ...props,
451
+ children: /* @__PURE__ */ jsx("div", { className: "bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" })
452
+ }
453
+ );
454
+ }
455
+ function Pagination({ className, ...props }) {
456
+ return /* @__PURE__ */ jsx(
457
+ "nav",
458
+ {
459
+ role: "navigation",
460
+ "aria-label": "pagination",
461
+ "data-slot": "pagination",
462
+ className: cn("mx-auto flex w-full justify-center", className),
463
+ ...props
464
+ }
465
+ );
466
+ }
467
+ function PaginationContent({
468
+ className,
469
+ ...props
470
+ }) {
471
+ return /* @__PURE__ */ jsx(
472
+ "ul",
473
+ {
474
+ "data-slot": "pagination-content",
475
+ className: cn("flex flex-row items-center gap-1", className),
476
+ ...props
477
+ }
478
+ );
479
+ }
480
+ function PaginationItem({ ...props }) {
481
+ return /* @__PURE__ */ jsx("li", { "data-slot": "pagination-item", ...props });
482
+ }
483
+ function PaginationLink({
484
+ className,
485
+ isActive,
486
+ size = "icon",
487
+ ...props
488
+ }) {
489
+ return /* @__PURE__ */ jsx(
490
+ "a",
491
+ {
492
+ "aria-current": isActive ? "page" : void 0,
493
+ "data-slot": "pagination-link",
494
+ "data-active": isActive,
495
+ className: cn(
496
+ buttonVariants({
497
+ variant: isActive ? "outline" : "ghost",
498
+ size
499
+ }),
500
+ className
501
+ ),
502
+ ...props
503
+ }
504
+ );
505
+ }
506
+ function PaginationPrevious({
507
+ className,
508
+ ...props
509
+ }) {
510
+ return /* @__PURE__ */ jsxs(
511
+ PaginationLink,
512
+ {
513
+ "aria-label": "Go to previous page",
514
+ size: "default",
515
+ className: cn("gap-1 px-2.5 sm:pl-2.5", className),
516
+ ...props,
517
+ children: [
518
+ /* @__PURE__ */ jsx(ChevronLeftIcon, {}),
519
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:block", children: "Previous" })
520
+ ]
521
+ }
522
+ );
523
+ }
524
+ function PaginationNext({
525
+ className,
526
+ ...props
527
+ }) {
528
+ return /* @__PURE__ */ jsxs(
529
+ PaginationLink,
530
+ {
531
+ "aria-label": "Go to next page",
532
+ size: "default",
533
+ className: cn("gap-1 px-2.5 sm:pr-2.5", className),
534
+ ...props,
535
+ children: [
536
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:block", children: "Next" }),
537
+ /* @__PURE__ */ jsx(ChevronRightIcon, {})
538
+ ]
539
+ }
540
+ );
541
+ }
542
+ function PaginationEllipsis({
543
+ className,
544
+ ...props
545
+ }) {
546
+ return /* @__PURE__ */ jsxs(
547
+ "span",
548
+ {
549
+ "aria-hidden": true,
550
+ "data-slot": "pagination-ellipsis",
551
+ className: cn("flex size-9 items-center justify-center", className),
552
+ ...props,
553
+ children: [
554
+ /* @__PURE__ */ jsx(MoreHorizontalIcon, { className: "size-4" }),
555
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "More pages" })
556
+ ]
557
+ }
558
+ );
559
+ }
560
+ function usePagination({
561
+ totalItems,
562
+ pageSize = 10,
563
+ initialPage = 1,
564
+ page: controlledPage,
565
+ onPageChange,
566
+ siblingCount = 1
567
+ }) {
568
+ const [internalPage, setInternalPage] = useState(initialPage);
569
+ const isControlled = controlledPage !== void 0;
570
+ const currentPage = isControlled ? controlledPage : internalPage;
571
+ const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
572
+ const setPage = useCallback(
573
+ (p) => {
574
+ const clamped = Math.min(Math.max(1, p), totalPages);
575
+ if (!isControlled) setInternalPage(clamped);
576
+ onPageChange == null ? void 0 : onPageChange(clamped);
577
+ },
578
+ [isControlled, onPageChange, totalPages]
579
+ );
580
+ const startIndex = (currentPage - 1) * pageSize;
581
+ const endIndex = Math.min(startIndex + pageSize, totalItems);
582
+ const canGoPrev = currentPage > 1;
583
+ const canGoNext = currentPage < totalPages;
584
+ const isFirstPage = currentPage === 1;
585
+ const isLastPage = currentPage === totalPages;
586
+ const items = useMemo(() => {
587
+ const range = (start, end) => Array.from({ length: end - start + 1 }, (_, i) => start + i);
588
+ const leftSibling = Math.max(currentPage - siblingCount, 1);
589
+ const rightSibling = Math.min(currentPage + siblingCount, totalPages);
590
+ const showLeftEllipsis = leftSibling > 2;
591
+ const showRightEllipsis = rightSibling < totalPages - 1;
592
+ const result = [];
593
+ result.push({ type: "page", page: 1 });
594
+ if (showLeftEllipsis) {
595
+ result.push({ type: "ellipsis", key: "ellipsis-left" });
596
+ } else if (leftSibling === 2) {
597
+ result.push({ type: "page", page: 2 });
598
+ }
599
+ for (const p of range(Math.max(leftSibling, 2), Math.min(rightSibling, totalPages - 1))) {
600
+ result.push({ type: "page", page: p });
601
+ }
602
+ if (showRightEllipsis) {
603
+ result.push({ type: "ellipsis", key: "ellipsis-right" });
604
+ } else if (rightSibling === totalPages - 1) {
605
+ result.push({ type: "page", page: totalPages - 1 });
606
+ }
607
+ if (totalPages > 1) {
608
+ result.push({ type: "page", page: totalPages });
609
+ }
610
+ return result;
611
+ }, [currentPage, siblingCount, totalPages]);
612
+ const goTo = useCallback((p) => setPage(p), [setPage]);
613
+ const next = useCallback(() => setPage(currentPage + 1), [currentPage, setPage]);
614
+ const prev = useCallback(() => setPage(currentPage - 1), [currentPage, setPage]);
615
+ const first = useCallback(() => setPage(1), [setPage]);
616
+ const last = useCallback(() => setPage(totalPages), [setPage, totalPages]);
617
+ return {
618
+ currentPage,
619
+ totalPages,
620
+ startIndex,
621
+ endIndex,
622
+ canGoPrev,
623
+ canGoNext,
624
+ isFirstPage,
625
+ isLastPage,
626
+ items,
627
+ goTo,
628
+ next,
629
+ prev,
630
+ first,
631
+ last
632
+ };
633
+ }
634
+ const toggleVariants = cva(
635
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
636
+ {
637
+ variants: {
638
+ variant: {
639
+ default: "bg-transparent",
640
+ outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground"
641
+ },
642
+ size: {
643
+ default: "h-9 px-2 min-w-9",
644
+ sm: "h-8 px-1.5 min-w-8",
645
+ lg: "h-10 px-2.5 min-w-10"
646
+ }
647
+ },
648
+ defaultVariants: {
649
+ variant: "default",
650
+ size: "default"
651
+ }
652
+ }
653
+ );
654
+ const Toggle = React.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(
655
+ TogglePrimitive.Root,
656
+ {
657
+ ref,
658
+ "data-slot": "toggle",
659
+ className: cn(toggleVariants({ variant, size, className })),
660
+ ...props
661
+ }
662
+ ));
663
+ Toggle.displayName = TogglePrimitive.Root.displayName;
664
+ const ToggleGroupContext = React.createContext({
665
+ size: "default",
666
+ variant: "default"
667
+ });
668
+ const ToggleGroup = React.forwardRef(({ className, variant, size, children, ...props }, ref) => /* @__PURE__ */ jsx(
669
+ ToggleGroupPrimitive.Root,
670
+ {
671
+ ref,
672
+ "data-slot": "toggle-group",
673
+ "data-variant": variant,
674
+ "data-size": size,
675
+ className: cn(
676
+ "group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
677
+ className
678
+ ),
679
+ ...props,
680
+ children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
681
+ }
682
+ ));
683
+ ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
684
+ const ToggleGroupItem = React.forwardRef(({ className, children, variant, size, ...props }, ref) => {
685
+ const context = React.useContext(ToggleGroupContext);
686
+ return /* @__PURE__ */ jsx(
687
+ ToggleGroupPrimitive.Item,
688
+ {
689
+ ref,
690
+ "data-slot": "toggle-group-item",
691
+ "data-variant": context.variant || variant,
692
+ "data-size": context.size || size,
693
+ className: cn(
694
+ toggleVariants({
695
+ variant: context.variant || variant,
696
+ size: context.size || size
697
+ }),
698
+ "min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
699
+ className
700
+ ),
701
+ ...props,
702
+ children
703
+ }
704
+ );
705
+ });
706
+ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
707
+ function InputOTP({
708
+ className,
709
+ containerClassName,
710
+ ...props
711
+ }) {
712
+ return /* @__PURE__ */ jsx(
713
+ OTPInput,
714
+ {
715
+ "data-slot": "input-otp",
716
+ containerClassName: cn(
717
+ "flex items-center gap-2 has-disabled:opacity-50",
718
+ containerClassName
719
+ ),
720
+ className: cn("disabled:cursor-not-allowed", className),
721
+ ...props
722
+ }
723
+ );
724
+ }
725
+ function InputOTPGroup({ className, ...props }) {
726
+ return /* @__PURE__ */ jsx(
727
+ "div",
728
+ {
729
+ "data-slot": "input-otp-group",
730
+ className: cn("flex items-center gap-1", className),
731
+ ...props
732
+ }
733
+ );
734
+ }
735
+ function InputOTPSlot({
736
+ index,
737
+ className,
738
+ size = "md",
739
+ ...props
740
+ }) {
741
+ const inputOTPContext = React.useContext(OTPInputContext);
742
+ const { char, hasFakeCaret, isActive } = (inputOTPContext == null ? void 0 : inputOTPContext.slots[index]) ?? {};
743
+ const sizeClasses = {
744
+ sm: "h-8 w-8 text-sm",
745
+ md: "h-10 w-10 text-base",
746
+ lg: "h-12 w-12 text-lg"
747
+ };
748
+ return /* @__PURE__ */ jsxs(
749
+ "div",
750
+ {
751
+ "data-slot": "input-otp-slot",
752
+ "data-active": isActive,
753
+ className: cn(
754
+ "data-[active=true]:border-primary data-[active=true]:ring-primary/20 data-[active=true]:aria-invalid:ring-destructive/20 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive relative flex items-center justify-center border border-border rounded-[var(--radius)] bg-background transition-all outline-none data-[active=true]:z-10 data-[active=true]:ring-2",
755
+ sizeClasses[size],
756
+ className
757
+ ),
758
+ ...props,
759
+ children: [
760
+ char,
761
+ hasFakeCaret && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "animate-caret-blink bg-foreground h-4 w-px duration-1000" }) })
762
+ ]
763
+ }
764
+ );
765
+ }
766
+ function InputOTPSeparator({ ...props }) {
767
+ return /* @__PURE__ */ jsx("div", { "data-slot": "input-otp-separator", role: "separator", ...props, children: /* @__PURE__ */ jsx(MinusIcon, {}) });
768
+ }
769
+ const Form = FormProvider;
770
+ const FormFieldContext = React.createContext(
771
+ {}
772
+ );
773
+ const FormField = ({
774
+ ...props
775
+ }) => {
776
+ return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
777
+ };
778
+ const useFormField = () => {
779
+ const fieldContext = React.useContext(FormFieldContext);
780
+ const itemContext = React.useContext(FormItemContext);
781
+ const { getFieldState } = useFormContext();
782
+ const formState = useFormState({ name: fieldContext.name });
783
+ const fieldState = getFieldState(
784
+ fieldContext.name,
785
+ formState
786
+ );
787
+ if (!fieldContext) {
788
+ throw new Error(
789
+ "useFormField should be used within <FormField>"
790
+ );
791
+ }
792
+ const { id } = itemContext;
793
+ return {
794
+ id,
795
+ name: fieldContext.name,
796
+ formItemId: `${id}-form-item`,
797
+ formDescriptionId: `${id}-form-item-description`,
798
+ formMessageId: `${id}-form-item-message`,
799
+ ...fieldState
800
+ };
801
+ };
802
+ const FormItemContext = React.createContext(
803
+ {}
804
+ );
805
+ function FormItem({
806
+ className,
807
+ ...props
808
+ }) {
809
+ const id = React.useId();
810
+ return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx(
811
+ "div",
812
+ {
813
+ "data-slot": "form-item",
814
+ className: cn("grid gap-2", className),
815
+ ...props
816
+ }
817
+ ) });
818
+ }
819
+ function FormLabel({
820
+ className,
821
+ ...props
822
+ }) {
823
+ const { error, formItemId } = useFormField();
824
+ return /* @__PURE__ */ jsx(
825
+ Label,
826
+ {
827
+ "data-slot": "form-label",
828
+ "data-error": !!error,
829
+ className: cn(
830
+ "data-[error=true]:text-destructive",
831
+ className
832
+ ),
833
+ htmlFor: formItemId,
834
+ ...props
835
+ }
836
+ );
837
+ }
838
+ function FormControl({
839
+ ...props
840
+ }) {
841
+ const {
842
+ error,
843
+ formItemId,
844
+ formDescriptionId,
845
+ formMessageId
846
+ } = useFormField();
847
+ return /* @__PURE__ */ jsx(
848
+ Slot,
849
+ {
850
+ "data-slot": "form-control",
851
+ id: formItemId,
852
+ "aria-describedby": !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`,
853
+ "aria-invalid": !!error,
854
+ ...props
855
+ }
856
+ );
857
+ }
858
+ function FormDescription({
859
+ className,
860
+ ...props
861
+ }) {
862
+ const { formDescriptionId } = useFormField();
863
+ return /* @__PURE__ */ jsx(
864
+ "p",
865
+ {
866
+ "data-slot": "form-description",
867
+ id: formDescriptionId,
868
+ className: cn("text-muted-foreground text-sm", className),
869
+ ...props
870
+ }
871
+ );
872
+ }
873
+ function FormMessage({
874
+ className,
875
+ ...props
876
+ }) {
877
+ const { error, formMessageId } = useFormField();
878
+ const body = error ? String((error == null ? void 0 : error.message) ?? "") : props.children;
879
+ if (!body) {
880
+ return null;
881
+ }
882
+ return /* @__PURE__ */ jsx(
883
+ "p",
884
+ {
885
+ "data-slot": "form-message",
886
+ id: formMessageId,
887
+ className: cn("text-destructive text-sm", className),
888
+ ...props,
889
+ children: body
890
+ }
891
+ );
892
+ }
893
+ function Calendar({
894
+ className,
895
+ classNames,
896
+ showOutsideDays = true,
897
+ captionLayout = "label",
898
+ buttonVariant = "ghost",
899
+ formatters,
900
+ components,
901
+ ...props
902
+ }) {
903
+ const defaultClassNames = getDefaultClassNames();
904
+ const isDropdownCaption = captionLayout.startsWith("dropdown");
905
+ return /* @__PURE__ */ jsx(
906
+ DayPicker,
907
+ {
908
+ showOutsideDays,
909
+ className: cn(
910
+ "bg-background group/calendar p-4 [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent font-sans",
911
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
912
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
913
+ className
914
+ ),
915
+ captionLayout,
916
+ formatters,
917
+ classNames: {
918
+ root: cn("w-fit", defaultClassNames.root),
919
+ months: cn(
920
+ "flex gap-6 flex-col md:flex-row relative",
921
+ defaultClassNames.months
922
+ ),
923
+ month: cn("flex flex-col w-full gap-5", defaultClassNames.month),
924
+ nav: cn(
925
+ "flex items-center gap-2 w-full absolute top-0 inset-x-0 justify-between",
926
+ defaultClassNames.nav
927
+ ),
928
+ button_previous: cn(
929
+ buttonVariants({ variant: buttonVariant }),
930
+ "size-(--cell-size) aria-disabled:opacity-40 p-0 select-none hover:bg-accent/50 transition-colors duration-200",
931
+ defaultClassNames.button_previous
932
+ ),
933
+ button_next: cn(
934
+ buttonVariants({ variant: buttonVariant }),
935
+ "size-(--cell-size) aria-disabled:opacity-40 p-0 select-none hover:bg-accent/50 transition-colors duration-200",
936
+ defaultClassNames.button_next
937
+ ),
938
+ month_caption: cn(
939
+ "flex items-center justify-center w-full",
940
+ isDropdownCaption ? "h-auto px-0" : "h-(--cell-size) px-(--cell-size)",
941
+ defaultClassNames.month_caption
942
+ ),
943
+ dropdowns: cn(
944
+ "w-full flex items-center justify-center gap-2",
945
+ isDropdownCaption ? "h-auto" : "h-(--cell-size)",
946
+ defaultClassNames.dropdowns
947
+ ),
948
+ dropdown_root: cn(
949
+ isDropdownCaption ? "relative flex min-w-[7rem] items-center rounded-[var(--radius)] border border-border bg-background text-foreground transition-colors outline-none focus-within:ring-2 focus-within:ring-primary focus-within:border-transparent data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 px-2.5 py-1" : "relative rounded-[var(--radius)] hover:bg-accent transition-colors",
950
+ defaultClassNames.dropdown_root
951
+ ),
952
+ dropdown: cn(
953
+ isDropdownCaption ? "absolute inset-0 cursor-pointer opacity-0" : "absolute bg-popover inset-0 opacity-0 cursor-pointer",
954
+ defaultClassNames.dropdown
955
+ ),
956
+ caption_label: cn(
957
+ "select-none font-[family-name:var(--font-family,Roboto)] tracking-tight transition-all duration-200",
958
+ captionLayout === "label" ? "rounded-[var(--radius)] px-2 py-1 text-[length:var(--calendar-caption-size)] font-[number:var(--font-weight-semibold)] hover:bg-accent hover:text-accent-foreground" : "flex h-full w-full items-center justify-between gap-2 rounded-[var(--radius)] text-[length:var(--calendar-caption-size)] font-[number:var(--font-weight-semibold)] [&>svg]:text-muted-foreground [&>svg]:size-4",
959
+ defaultClassNames.caption_label
960
+ ),
961
+ table: "w-full border-collapse mt-1",
962
+ weekdays: cn("flex gap-1", defaultClassNames.weekdays),
963
+ weekday: cn(
964
+ "text-muted-foreground rounded-(--cell-radius) flex-1 select-none text-[length:var(--calendar-weekday-size)] font-[number:var(--font-weight-medium)] uppercase tracking-wider",
965
+ defaultClassNames.weekday
966
+ ),
967
+ week: cn("flex w-full gap-1", defaultClassNames.week),
968
+ week_number_header: cn(
969
+ "select-none w-(--cell-size)",
970
+ defaultClassNames.week_number_header
971
+ ),
972
+ week_number: cn(
973
+ "select-none text-muted-foreground text-[length:var(--calendar-weekday-size)]",
974
+ defaultClassNames.week_number
975
+ ),
976
+ day: cn(
977
+ "relative w-full rounded-(--cell-radius) h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius) group/day aspect-square select-none",
978
+ props.showWeekNumber ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)" : "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)",
979
+ defaultClassNames.day
980
+ ),
981
+ range_start: cn(
982
+ "rounded-l-(--cell-radius) bg-accent/50 relative after:bg-accent/50 after:absolute after:inset-y-0 after:w-2 after:right-0 -z-0 isolate",
983
+ defaultClassNames.range_start
984
+ ),
985
+ range_middle: cn(
986
+ "rounded-none bg-accent/30",
987
+ defaultClassNames.range_middle
988
+ ),
989
+ range_end: cn(
990
+ "rounded-r-(--cell-radius) bg-accent/50 relative after:bg-accent/50 after:absolute after:inset-y-0 after:w-2 after:left-0 -z-0 isolate",
991
+ defaultClassNames.range_end
992
+ ),
993
+ today: cn(
994
+ "bg-accent/60 text-accent-foreground rounded-(--cell-radius) data-[selected=true]:rounded-none font-[number:var(--font-weight-semibold)]",
995
+ defaultClassNames.today
996
+ ),
997
+ outside: cn(
998
+ "text-muted-foreground aria-selected:text-muted-foreground",
999
+ defaultClassNames.outside
1000
+ ),
1001
+ disabled: cn(
1002
+ "text-muted-foreground/30 opacity-40",
1003
+ defaultClassNames.disabled
1004
+ ),
1005
+ hidden: cn("invisible", defaultClassNames.hidden),
1006
+ ...classNames
1007
+ },
1008
+ components: {
1009
+ Root: ({ className: className2, rootRef, ...props2 }) => {
1010
+ return /* @__PURE__ */ jsx(
1011
+ "div",
1012
+ {
1013
+ "data-slot": "calendar",
1014
+ ref: rootRef,
1015
+ className: cn(className2),
1016
+ ...props2
1017
+ }
1018
+ );
1019
+ },
1020
+ Chevron: ({ className: className2, orientation, ...props2 }) => {
1021
+ if (orientation === "left") {
1022
+ return /* @__PURE__ */ jsx(
1023
+ ChevronLeft,
1024
+ {
1025
+ className: cn("size-5 transition-transform group-hover:scale-110", className2),
1026
+ ...props2
1027
+ }
1028
+ );
1029
+ }
1030
+ if (orientation === "right") {
1031
+ return /* @__PURE__ */ jsx(
1032
+ ChevronRight,
1033
+ {
1034
+ className: cn("size-5 transition-transform group-hover:scale-110", className2),
1035
+ ...props2
1036
+ }
1037
+ );
1038
+ }
1039
+ return /* @__PURE__ */ jsx(
1040
+ ChevronDown,
1041
+ {
1042
+ className: cn("size-4", className2),
1043
+ ...props2
1044
+ }
1045
+ );
1046
+ },
1047
+ DayButton: CalendarDayButton,
1048
+ WeekNumber: ({ children, ...props2 }) => {
1049
+ return /* @__PURE__ */ jsx("td", { ...props2, children: /* @__PURE__ */ jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center font-[number:var(--font-weight-medium)]", children }) });
1050
+ },
1051
+ ...components
1052
+ },
1053
+ ...props
1054
+ }
1055
+ );
1056
+ }
1057
+ function CalendarDayButton({
1058
+ className,
1059
+ day,
1060
+ modifiers,
1061
+ ...props
1062
+ }) {
1063
+ const defaultClassNames = getDefaultClassNames();
1064
+ const ref = React.useRef(null);
1065
+ React.useEffect(() => {
1066
+ var _a;
1067
+ if (modifiers.focused) (_a = ref.current) == null ? void 0 : _a.focus();
1068
+ }, [modifiers.focused]);
1069
+ return /* @__PURE__ */ jsx(
1070
+ Button,
1071
+ {
1072
+ ref,
1073
+ variant: "ghost",
1074
+ size: "icon",
1075
+ "data-day": day.date.toLocaleDateString(),
1076
+ "data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
1077
+ "data-range-start": modifiers.range_start,
1078
+ "data-range-end": modifiers.range_end,
1079
+ "data-range-middle": modifiers.range_middle,
1080
+ className: cn(
1081
+ "relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col items-center justify-center gap-1 border-0 leading-none transition-all duration-200 cursor-pointer disabled:cursor-not-allowed",
1082
+ "text-[length:var(--calendar-day-size)] font-[number:var(--font-weight-regular)]",
1083
+ "hover:bg-accent/70 hover:text-accent-foreground hover:scale-105",
1084
+ "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[selected-single=true]:font-[number:var(--font-weight-semibold)] data-[selected-single=true]:shadow-sm",
1085
+ "data-[range-middle=true]:bg-accent/50 data-[range-middle=true]:text-foreground",
1086
+ "data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-start=true]:font-[number:var(--font-weight-semibold)] data-[range-start=true]:shadow-sm",
1087
+ "data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-end=true]:font-[number:var(--font-weight-semibold)] data-[range-end=true]:shadow-sm",
1088
+ "group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 group-data-[focused=true]/day:ring-2 group-data-[focused=true]/day:ring-offset-2 group-data-[focused=true]/day:ring-offset-background",
1089
+ "data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-r-(--cell-radius)",
1090
+ "data-[range-middle=true]:rounded-none",
1091
+ "data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-l-(--cell-radius)",
1092
+ "[&>span]:opacity-80",
1093
+ defaultClassNames.day,
1094
+ className
1095
+ ),
1096
+ ...props,
1097
+ children: day.date.getDate()
1098
+ }
1099
+ );
1100
+ }
1101
+ function Sheet({ ...props }) {
1102
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "sheet", ...props });
1103
+ }
1104
+ function SheetTrigger({
1105
+ ...props
1106
+ }) {
1107
+ return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
1108
+ }
1109
+ function SheetClose({
1110
+ ...props
1111
+ }) {
1112
+ return /* @__PURE__ */ jsx(DialogPrimitive.Close, { "data-slot": "sheet-close", ...props });
1113
+ }
1114
+ function SheetPortal({
1115
+ ...props
1116
+ }) {
1117
+ return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
1118
+ }
1119
+ const SheetOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1120
+ DialogPrimitive.Overlay,
1121
+ {
1122
+ className: cn(
1123
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
1124
+ className
1125
+ ),
1126
+ ...props,
1127
+ ref
1128
+ }
1129
+ ));
1130
+ SheetOverlay.displayName = DialogPrimitive.Overlay.displayName;
1131
+ function SheetContent({
1132
+ className,
1133
+ children,
1134
+ side = "right",
1135
+ ...props
1136
+ }) {
1137
+ return /* @__PURE__ */ jsxs(SheetPortal, { children: [
1138
+ /* @__PURE__ */ jsx(SheetOverlay, {}),
1139
+ /* @__PURE__ */ jsxs(
1140
+ DialogPrimitive.Content,
1141
+ {
1142
+ "data-slot": "sheet-content",
1143
+ className: cn(
1144
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
1145
+ side === "right" && "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
1146
+ side === "left" && "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
1147
+ side === "top" && "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
1148
+ side === "bottom" && "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
1149
+ className
1150
+ ),
1151
+ ...props,
1152
+ children: [
1153
+ children,
1154
+ /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none", children: [
1155
+ /* @__PURE__ */ jsx(XIcon, { className: "size-4" }),
1156
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1157
+ ] })
1158
+ ]
1159
+ }
1160
+ )
1161
+ ] });
1162
+ }
1163
+ function SheetHeader({ className, ...props }) {
1164
+ return /* @__PURE__ */ jsx(
1165
+ "div",
1166
+ {
1167
+ "data-slot": "sheet-header",
1168
+ className: cn("flex flex-col gap-1.5 px-6 pt-6", className),
1169
+ ...props
1170
+ }
1171
+ );
1172
+ }
1173
+ function SheetBody({ className, ...props }) {
1174
+ return /* @__PURE__ */ jsx(
1175
+ "div",
1176
+ {
1177
+ "data-slot": "sheet-body",
1178
+ className: cn("flex-1 overflow-auto px-6", className),
1179
+ ...props
1180
+ }
1181
+ );
1182
+ }
1183
+ function SheetFooter({ className, ...props }) {
1184
+ return /* @__PURE__ */ jsx(
1185
+ "div",
1186
+ {
1187
+ "data-slot": "sheet-footer",
1188
+ className: cn("mt-auto flex flex-col gap-2 px-6 pb-6", className),
1189
+ ...props
1190
+ }
1191
+ );
1192
+ }
1193
+ function SheetTitle({
1194
+ className,
1195
+ ...props
1196
+ }) {
1197
+ return /* @__PURE__ */ jsx(
1198
+ DialogPrimitive.Title,
1199
+ {
1200
+ "data-slot": "sheet-title",
1201
+ className: cn("text-foreground font-semibold", className),
1202
+ ...props
1203
+ }
1204
+ );
1205
+ }
1206
+ function SheetDescription({
1207
+ className,
1208
+ ...props
1209
+ }) {
1210
+ return /* @__PURE__ */ jsx(
1211
+ DialogPrimitive.Description,
1212
+ {
1213
+ "data-slot": "sheet-description",
1214
+ className: cn("text-muted-foreground text-sm", className),
1215
+ ...props
1216
+ }
1217
+ );
1218
+ }
1219
+ function Drawer({
1220
+ ...props
1221
+ }) {
1222
+ return /* @__PURE__ */ jsx(Drawer$1.Root, { "data-slot": "drawer", ...props });
1223
+ }
1224
+ function DrawerTrigger({
1225
+ ...props
1226
+ }) {
1227
+ return /* @__PURE__ */ jsx(Drawer$1.Trigger, { "data-slot": "drawer-trigger", ...props });
1228
+ }
1229
+ function DrawerPortal({
1230
+ ...props
1231
+ }) {
1232
+ return /* @__PURE__ */ jsx(Drawer$1.Portal, { "data-slot": "drawer-portal", ...props });
1233
+ }
1234
+ function DrawerClose({
1235
+ ...props
1236
+ }) {
1237
+ return /* @__PURE__ */ jsx(Drawer$1.Close, { "data-slot": "drawer-close", ...props });
1238
+ }
1239
+ const DrawerOverlay = React.forwardRef(({ className, ...props }, ref) => {
1240
+ return /* @__PURE__ */ jsx(
1241
+ Drawer$1.Overlay,
1242
+ {
1243
+ ref,
1244
+ "data-slot": "drawer-overlay",
1245
+ className: cn(
1246
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
1247
+ className
1248
+ ),
1249
+ ...props
1250
+ }
1251
+ );
1252
+ });
1253
+ DrawerOverlay.displayName = Drawer$1.Overlay.displayName;
1254
+ function DrawerContent({
1255
+ className,
1256
+ children,
1257
+ ...props
1258
+ }) {
1259
+ return /* @__PURE__ */ jsxs(DrawerPortal, { "data-slot": "drawer-portal", children: [
1260
+ /* @__PURE__ */ jsx(DrawerOverlay, {}),
1261
+ /* @__PURE__ */ jsxs(
1262
+ Drawer$1.Content,
1263
+ {
1264
+ "data-slot": "drawer-content",
1265
+ className: cn(
1266
+ "group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
1267
+ "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b",
1268
+ "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t",
1269
+ "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
1270
+ "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
1271
+ className
1272
+ ),
1273
+ ...props,
1274
+ children: [
1275
+ /* @__PURE__ */ jsx("div", { className: "bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }),
1276
+ children
1277
+ ]
1278
+ }
1279
+ )
1280
+ ] });
1281
+ }
1282
+ function DrawerHeader({ className, ...props }) {
1283
+ return /* @__PURE__ */ jsx(
1284
+ "div",
1285
+ {
1286
+ "data-slot": "drawer-header",
1287
+ className: cn("flex flex-col gap-1.5 p-4", className),
1288
+ ...props
1289
+ }
1290
+ );
1291
+ }
1292
+ function DrawerFooter({ className, ...props }) {
1293
+ return /* @__PURE__ */ jsx(
1294
+ "div",
1295
+ {
1296
+ "data-slot": "drawer-footer",
1297
+ className: cn("mt-auto flex flex-col gap-2 p-4", className),
1298
+ ...props
1299
+ }
1300
+ );
1301
+ }
1302
+ function DrawerTitle({
1303
+ className,
1304
+ ...props
1305
+ }) {
1306
+ return /* @__PURE__ */ jsx(
1307
+ Drawer$1.Title,
1308
+ {
1309
+ "data-slot": "drawer-title",
1310
+ className: cn("text-foreground font-semibold", className),
1311
+ ...props
1312
+ }
1313
+ );
1314
+ }
1315
+ function DrawerDescription({
1316
+ className,
1317
+ ...props
1318
+ }) {
1319
+ return /* @__PURE__ */ jsx(
1320
+ Drawer$1.Description,
1321
+ {
1322
+ "data-slot": "drawer-description",
1323
+ className: cn("text-muted-foreground text-sm", className),
1324
+ ...props
1325
+ }
1326
+ );
1327
+ }
1328
+ function DrawerHandle({ className, ...props }) {
1329
+ return /* @__PURE__ */ jsx(
1330
+ "div",
1331
+ {
1332
+ "data-slot": "drawer-handle",
1333
+ className: cn("bg-muted mx-auto mt-4 h-2 w-[100px] shrink-0 rounded-full", className),
1334
+ ...props
1335
+ }
1336
+ );
1337
+ }
1338
+ function HoverCard({
1339
+ ...props
1340
+ }) {
1341
+ return /* @__PURE__ */ jsx(HoverCardPrimitive.Root, { "data-slot": "hover-card", ...props });
1342
+ }
1343
+ function HoverCardTrigger({
1344
+ ...props
1345
+ }) {
1346
+ return /* @__PURE__ */ jsx(HoverCardPrimitive.Trigger, { "data-slot": "hover-card-trigger", ...props });
1347
+ }
1348
+ function HoverCardContent({
1349
+ className,
1350
+ align = "center",
1351
+ sideOffset = 4,
1352
+ ...props
1353
+ }) {
1354
+ return /* @__PURE__ */ jsx(HoverCardPrimitive.Portal, { "data-slot": "hover-card-portal", children: /* @__PURE__ */ jsx(
1355
+ HoverCardPrimitive.Content,
1356
+ {
1357
+ "data-slot": "hover-card-content",
1358
+ align,
1359
+ sideOffset,
1360
+ className: cn(
1361
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
1362
+ className
1363
+ ),
1364
+ ...props
1365
+ }
1366
+ ) });
1367
+ }
1368
+ function ContextMenu({
1369
+ ...props
1370
+ }) {
1371
+ return /* @__PURE__ */ jsx(ContextMenuPrimitive.Root, { "data-slot": "context-menu", ...props });
1372
+ }
1373
+ function ContextMenuTrigger({
1374
+ ...props
1375
+ }) {
1376
+ return /* @__PURE__ */ jsx(ContextMenuPrimitive.Trigger, { "data-slot": "context-menu-trigger", ...props });
1377
+ }
1378
+ function ContextMenuGroup({
1379
+ ...props
1380
+ }) {
1381
+ return /* @__PURE__ */ jsx(ContextMenuPrimitive.Group, { "data-slot": "context-menu-group", ...props });
1382
+ }
1383
+ function ContextMenuPortal({
1384
+ ...props
1385
+ }) {
1386
+ return /* @__PURE__ */ jsx(ContextMenuPrimitive.Portal, { "data-slot": "context-menu-portal", ...props });
1387
+ }
1388
+ function ContextMenuSub({
1389
+ ...props
1390
+ }) {
1391
+ return /* @__PURE__ */ jsx(ContextMenuPrimitive.Sub, { "data-slot": "context-menu-sub", ...props });
1392
+ }
1393
+ function ContextMenuRadioGroup({
1394
+ ...props
1395
+ }) {
1396
+ return /* @__PURE__ */ jsx(
1397
+ ContextMenuPrimitive.RadioGroup,
1398
+ {
1399
+ "data-slot": "context-menu-radio-group",
1400
+ ...props
1401
+ }
1402
+ );
1403
+ }
1404
+ function ContextMenuSubTrigger({
1405
+ className,
1406
+ inset,
1407
+ children,
1408
+ ...props
1409
+ }) {
1410
+ return /* @__PURE__ */ jsxs(
1411
+ ContextMenuPrimitive.SubTrigger,
1412
+ {
1413
+ "data-slot": "context-menu-sub-trigger",
1414
+ "data-inset": inset,
1415
+ className: cn(
1416
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1417
+ className
1418
+ ),
1419
+ ...props,
1420
+ children: [
1421
+ children,
1422
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto" })
1423
+ ]
1424
+ }
1425
+ );
1426
+ }
1427
+ function ContextMenuSubContent({
1428
+ className,
1429
+ ...props
1430
+ }) {
1431
+ return /* @__PURE__ */ jsx(
1432
+ ContextMenuPrimitive.SubContent,
1433
+ {
1434
+ "data-slot": "context-menu-sub-content",
1435
+ className: cn(
1436
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
1437
+ className
1438
+ ),
1439
+ ...props
1440
+ }
1441
+ );
1442
+ }
1443
+ function ContextMenuContent({
1444
+ className,
1445
+ ...props
1446
+ }) {
1447
+ return /* @__PURE__ */ jsx(ContextMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1448
+ ContextMenuPrimitive.Content,
1449
+ {
1450
+ "data-slot": "context-menu-content",
1451
+ className: cn(
1452
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
1453
+ className
1454
+ ),
1455
+ ...props
1456
+ }
1457
+ ) });
1458
+ }
1459
+ function ContextMenuItem({
1460
+ className,
1461
+ inset,
1462
+ variant = "default",
1463
+ ...props
1464
+ }) {
1465
+ return /* @__PURE__ */ jsx(
1466
+ ContextMenuPrimitive.Item,
1467
+ {
1468
+ "data-slot": "context-menu-item",
1469
+ "data-inset": inset,
1470
+ "data-variant": variant,
1471
+ className: cn(
1472
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1473
+ className
1474
+ ),
1475
+ ...props
1476
+ }
1477
+ );
1478
+ }
1479
+ function ContextMenuCheckboxItem({
1480
+ className,
1481
+ children,
1482
+ checked,
1483
+ ...props
1484
+ }) {
1485
+ return /* @__PURE__ */ jsxs(
1486
+ ContextMenuPrimitive.CheckboxItem,
1487
+ {
1488
+ "data-slot": "context-menu-checkbox-item",
1489
+ className: cn(
1490
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1491
+ className
1492
+ ),
1493
+ checked,
1494
+ ...props,
1495
+ children: [
1496
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(ContextMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
1497
+ children
1498
+ ]
1499
+ }
1500
+ );
1501
+ }
1502
+ function ContextMenuRadioItem({
1503
+ className,
1504
+ children,
1505
+ ...props
1506
+ }) {
1507
+ return /* @__PURE__ */ jsxs(
1508
+ ContextMenuPrimitive.RadioItem,
1509
+ {
1510
+ "data-slot": "context-menu-radio-item",
1511
+ className: cn(
1512
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1513
+ className
1514
+ ),
1515
+ ...props,
1516
+ children: [
1517
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(ContextMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) }) }),
1518
+ children
1519
+ ]
1520
+ }
1521
+ );
1522
+ }
1523
+ function ContextMenuLabel({
1524
+ className,
1525
+ inset,
1526
+ ...props
1527
+ }) {
1528
+ return /* @__PURE__ */ jsx(
1529
+ ContextMenuPrimitive.Label,
1530
+ {
1531
+ "data-slot": "context-menu-label",
1532
+ "data-inset": inset,
1533
+ className: cn(
1534
+ "text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
1535
+ className
1536
+ ),
1537
+ ...props
1538
+ }
1539
+ );
1540
+ }
1541
+ function ContextMenuSeparator({
1542
+ className,
1543
+ ...props
1544
+ }) {
1545
+ return /* @__PURE__ */ jsx(
1546
+ ContextMenuPrimitive.Separator,
1547
+ {
1548
+ "data-slot": "context-menu-separator",
1549
+ className: cn("bg-border -mx-1 my-1 h-px", className),
1550
+ ...props
1551
+ }
1552
+ );
1553
+ }
1554
+ function ContextMenuShortcut({
1555
+ className,
1556
+ ...props
1557
+ }) {
1558
+ return /* @__PURE__ */ jsx(
1559
+ "span",
1560
+ {
1561
+ "data-slot": "context-menu-shortcut",
1562
+ className: cn(
1563
+ "text-muted-foreground ml-auto text-xs tracking-widest",
1564
+ className
1565
+ ),
1566
+ ...props
1567
+ }
1568
+ );
1569
+ }
1570
+ function Menubar({
1571
+ className,
1572
+ ...props
1573
+ }) {
1574
+ return /* @__PURE__ */ jsx(
1575
+ MenubarPrimitive.Root,
1576
+ {
1577
+ "data-slot": "menubar",
1578
+ className: cn(
1579
+ "bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs",
1580
+ className
1581
+ ),
1582
+ ...props
1583
+ }
1584
+ );
1585
+ }
1586
+ function MenubarMenu({
1587
+ ...props
1588
+ }) {
1589
+ return /* @__PURE__ */ jsx(MenubarPrimitive.Menu, { "data-slot": "menubar-menu", ...props });
1590
+ }
1591
+ function MenubarGroup({
1592
+ ...props
1593
+ }) {
1594
+ return /* @__PURE__ */ jsx(MenubarPrimitive.Group, { "data-slot": "menubar-group", ...props });
1595
+ }
1596
+ function MenubarPortal({
1597
+ ...props
1598
+ }) {
1599
+ return /* @__PURE__ */ jsx(MenubarPrimitive.Portal, { "data-slot": "menubar-portal", ...props });
1600
+ }
1601
+ function MenubarRadioGroup({
1602
+ ...props
1603
+ }) {
1604
+ return /* @__PURE__ */ jsx(MenubarPrimitive.RadioGroup, { "data-slot": "menubar-radio-group", ...props });
1605
+ }
1606
+ function MenubarTrigger({
1607
+ className,
1608
+ ...props
1609
+ }) {
1610
+ return /* @__PURE__ */ jsx(
1611
+ MenubarPrimitive.Trigger,
1612
+ {
1613
+ "data-slot": "menubar-trigger",
1614
+ className: cn(
1615
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none",
1616
+ className
1617
+ ),
1618
+ ...props
1619
+ }
1620
+ );
1621
+ }
1622
+ function MenubarContent({
1623
+ className,
1624
+ align = "start",
1625
+ alignOffset = -4,
1626
+ sideOffset = 8,
1627
+ ...props
1628
+ }) {
1629
+ return /* @__PURE__ */ jsx(MenubarPortal, { children: /* @__PURE__ */ jsx(
1630
+ MenubarPrimitive.Content,
1631
+ {
1632
+ "data-slot": "menubar-content",
1633
+ align,
1634
+ alignOffset,
1635
+ sideOffset,
1636
+ className: cn(
1637
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-md",
1638
+ className
1639
+ ),
1640
+ ...props
1641
+ }
1642
+ ) });
1643
+ }
1644
+ function MenubarItem({
1645
+ className,
1646
+ inset,
1647
+ variant = "default",
1648
+ ...props
1649
+ }) {
1650
+ return /* @__PURE__ */ jsx(
1651
+ MenubarPrimitive.Item,
1652
+ {
1653
+ "data-slot": "menubar-item",
1654
+ "data-inset": inset,
1655
+ "data-variant": variant,
1656
+ className: cn(
1657
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1658
+ className
1659
+ ),
1660
+ ...props
1661
+ }
1662
+ );
1663
+ }
1664
+ function MenubarCheckboxItem({
1665
+ className,
1666
+ children,
1667
+ checked,
1668
+ ...props
1669
+ }) {
1670
+ return /* @__PURE__ */ jsxs(
1671
+ MenubarPrimitive.CheckboxItem,
1672
+ {
1673
+ "data-slot": "menubar-checkbox-item",
1674
+ className: cn(
1675
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1676
+ className
1677
+ ),
1678
+ checked,
1679
+ ...props,
1680
+ children: [
1681
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(MenubarPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
1682
+ children
1683
+ ]
1684
+ }
1685
+ );
1686
+ }
1687
+ function MenubarRadioItem({
1688
+ className,
1689
+ children,
1690
+ ...props
1691
+ }) {
1692
+ return /* @__PURE__ */ jsxs(
1693
+ MenubarPrimitive.RadioItem,
1694
+ {
1695
+ "data-slot": "menubar-radio-item",
1696
+ className: cn(
1697
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1698
+ className
1699
+ ),
1700
+ ...props,
1701
+ children: [
1702
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(MenubarPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) }) }),
1703
+ children
1704
+ ]
1705
+ }
1706
+ );
1707
+ }
1708
+ function MenubarLabel({
1709
+ className,
1710
+ inset,
1711
+ ...props
1712
+ }) {
1713
+ return /* @__PURE__ */ jsx(
1714
+ MenubarPrimitive.Label,
1715
+ {
1716
+ "data-slot": "menubar-label",
1717
+ "data-inset": inset,
1718
+ className: cn(
1719
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
1720
+ className
1721
+ ),
1722
+ ...props
1723
+ }
1724
+ );
1725
+ }
1726
+ function MenubarSeparator({
1727
+ className,
1728
+ ...props
1729
+ }) {
1730
+ return /* @__PURE__ */ jsx(
1731
+ MenubarPrimitive.Separator,
1732
+ {
1733
+ "data-slot": "menubar-separator",
1734
+ className: cn("bg-border -mx-1 my-1 h-px", className),
1735
+ ...props
1736
+ }
1737
+ );
1738
+ }
1739
+ function MenubarShortcut({
1740
+ className,
1741
+ ...props
1742
+ }) {
1743
+ return /* @__PURE__ */ jsx(
1744
+ "span",
1745
+ {
1746
+ "data-slot": "menubar-shortcut",
1747
+ className: cn(
1748
+ "text-muted-foreground ml-auto text-xs tracking-widest",
1749
+ className
1750
+ ),
1751
+ ...props
1752
+ }
1753
+ );
1754
+ }
1755
+ function MenubarSub({
1756
+ ...props
1757
+ }) {
1758
+ return /* @__PURE__ */ jsx(MenubarPrimitive.Sub, { "data-slot": "menubar-sub", ...props });
1759
+ }
1760
+ function MenubarSubTrigger({
1761
+ className,
1762
+ inset,
1763
+ children,
1764
+ ...props
1765
+ }) {
1766
+ return /* @__PURE__ */ jsxs(
1767
+ MenubarPrimitive.SubTrigger,
1768
+ {
1769
+ "data-slot": "menubar-sub-trigger",
1770
+ "data-inset": inset,
1771
+ className: cn(
1772
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8",
1773
+ className
1774
+ ),
1775
+ ...props,
1776
+ children: [
1777
+ children,
1778
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto h-4 w-4" })
1779
+ ]
1780
+ }
1781
+ );
1782
+ }
1783
+ function MenubarSubContent({
1784
+ className,
1785
+ ...props
1786
+ }) {
1787
+ return /* @__PURE__ */ jsx(
1788
+ MenubarPrimitive.SubContent,
1789
+ {
1790
+ "data-slot": "menubar-sub-content",
1791
+ className: cn(
1792
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
1793
+ className
1794
+ ),
1795
+ ...props
1796
+ }
1797
+ );
1798
+ }
1799
+ function Command({
1800
+ className,
1801
+ ...props
1802
+ }) {
1803
+ return /* @__PURE__ */ jsx(
1804
+ Command$1,
1805
+ {
1806
+ "data-slot": "command",
1807
+ className: cn(
1808
+ "bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
1809
+ className
1810
+ ),
1811
+ ...props
1812
+ }
1813
+ );
1814
+ }
1815
+ function CommandDialog({
1816
+ title = "Command Palette",
1817
+ description = "Search for a command to run...",
1818
+ children,
1819
+ ...props
1820
+ }) {
1821
+ return /* @__PURE__ */ jsxs(Dialog, { ...props, children: [
1822
+ /* @__PURE__ */ jsxs(DialogHeader, { className: "sr-only", children: [
1823
+ /* @__PURE__ */ jsx(DialogTitle, { children: title }),
1824
+ /* @__PURE__ */ jsx(DialogDescription, { children: description })
1825
+ ] }),
1826
+ /* @__PURE__ */ jsx(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx(Command, { className: "[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children }) })
1827
+ ] });
1828
+ }
1829
+ function CommandInput({
1830
+ className,
1831
+ ...props
1832
+ }) {
1833
+ return /* @__PURE__ */ jsxs(
1834
+ "div",
1835
+ {
1836
+ "data-slot": "command-input-wrapper",
1837
+ className: "flex h-9 items-center gap-2 border-b px-3",
1838
+ children: [
1839
+ /* @__PURE__ */ jsx(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
1840
+ /* @__PURE__ */ jsx(
1841
+ Command$1.Input,
1842
+ {
1843
+ "data-slot": "command-input",
1844
+ className: cn(
1845
+ "placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
1846
+ className
1847
+ ),
1848
+ ...props
1849
+ }
1850
+ )
1851
+ ]
1852
+ }
1853
+ );
1854
+ }
1855
+ function CommandList({
1856
+ className,
1857
+ ...props
1858
+ }) {
1859
+ return /* @__PURE__ */ jsx(
1860
+ Command$1.List,
1861
+ {
1862
+ "data-slot": "command-list",
1863
+ role: "listbox",
1864
+ className: cn(
1865
+ "max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
1866
+ className
1867
+ ),
1868
+ ...props
1869
+ }
1870
+ );
1871
+ }
1872
+ function CommandEmpty({
1873
+ ...props
1874
+ }) {
1875
+ return /* @__PURE__ */ jsx(
1876
+ Command$1.Empty,
1877
+ {
1878
+ "data-slot": "command-empty",
1879
+ className: "py-6 text-center text-sm",
1880
+ ...props
1881
+ }
1882
+ );
1883
+ }
1884
+ function CommandGroup({
1885
+ className,
1886
+ ...props
1887
+ }) {
1888
+ return /* @__PURE__ */ jsx(
1889
+ Command$1.Group,
1890
+ {
1891
+ "data-slot": "command-group",
1892
+ className: cn(
1893
+ "text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
1894
+ className
1895
+ ),
1896
+ ...props
1897
+ }
1898
+ );
1899
+ }
1900
+ function CommandSeparator({
1901
+ className,
1902
+ ...props
1903
+ }) {
1904
+ return /* @__PURE__ */ jsx(
1905
+ Command$1.Separator,
1906
+ {
1907
+ "data-slot": "command-separator",
1908
+ className: cn("bg-border -mx-1 h-px", className),
1909
+ ...props
1910
+ }
1911
+ );
1912
+ }
1913
+ function CommandItem({
1914
+ className,
1915
+ ...props
1916
+ }) {
1917
+ return /* @__PURE__ */ jsx(
1918
+ Command$1.Item,
1919
+ {
1920
+ "data-slot": "command-item",
1921
+ role: "option",
1922
+ className: cn(
1923
+ "data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1924
+ className
1925
+ ),
1926
+ ...props
1927
+ }
1928
+ );
1929
+ }
1930
+ function CommandShortcut({
1931
+ className,
1932
+ ...props
1933
+ }) {
1934
+ return /* @__PURE__ */ jsx(
1935
+ "span",
1936
+ {
1937
+ "data-slot": "command-shortcut",
1938
+ className: cn(
1939
+ "text-muted-foreground ml-auto text-xs tracking-widest",
1940
+ className
1941
+ ),
1942
+ ...props
1943
+ }
1944
+ );
1945
+ }
1946
+ const variantStyles = {
1947
+ default: "bg-primary text-primary-foreground",
1948
+ secondary: "bg-secondary text-secondary-foreground",
1949
+ destructive: "bg-destructive text-destructive-foreground",
1950
+ outline: "border-2 border-primary bg-background text-primary",
1951
+ success: "bg-success text-success-foreground",
1952
+ info: "bg-info text-info-foreground",
1953
+ warning: "bg-warning text-warning-foreground"
1954
+ };
1955
+ const NotificationBadge = React.forwardRef(
1956
+ ({
1957
+ className,
1958
+ count = 0,
1959
+ max = 99,
1960
+ showZero = false,
1961
+ dot = false,
1962
+ variant = "destructive",
1963
+ children,
1964
+ ...props
1965
+ }, ref) => {
1966
+ const displayCount = count > max ? `${max}+` : count;
1967
+ const shouldShow = count > 0 || showZero;
1968
+ if (!shouldShow && !dot) {
1969
+ return /* @__PURE__ */ jsx("div", { ref, className, ...props, children });
1970
+ }
1971
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("relative inline-block", className), ...props, children: [
1972
+ children,
1973
+ /* @__PURE__ */ jsx(
1974
+ "span",
1975
+ {
1976
+ className: cn(
1977
+ "absolute -right-1 -top-1 flex items-center justify-center rounded-full",
1978
+ variantStyles[variant],
1979
+ dot ? "h-2 w-2" : "min-w-[1.25rem] h-5 px-1.5"
1980
+ ),
1981
+ children: !dot && shouldShow && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium leading-none", children: displayCount })
1982
+ }
1983
+ )
1984
+ ] });
1985
+ }
1986
+ );
1987
+ NotificationBadge.displayName = "NotificationBadge";
1988
+ const StatsCard = React.forwardRef(
1989
+ ({ className, title, value, description, trend, icon, ...props }, ref) => {
1990
+ const getTrendIcon = () => {
1991
+ if (!trend) return null;
1992
+ if (trend.value > 0) {
1993
+ return /* @__PURE__ */ jsx(TrendingUp, { className: "h-4 w-4 text-success" });
1994
+ } else if (trend.value < 0) {
1995
+ return /* @__PURE__ */ jsx(TrendingDown, { className: "h-4 w-4 text-destructive" });
1996
+ } else {
1997
+ return /* @__PURE__ */ jsx(Minus, { className: "h-4 w-4 text-muted-foreground" });
1998
+ }
1999
+ };
2000
+ const getTrendColor = () => {
2001
+ if (!trend) return "";
2002
+ if (trend.value > 0) {
2003
+ return "text-success";
2004
+ } else if (trend.value < 0) {
2005
+ return "text-destructive";
2006
+ } else {
2007
+ return "text-muted-foreground";
2008
+ }
2009
+ };
2010
+ return /* @__PURE__ */ jsx(Card, { ref, className: cn("", className), ...props, children: /* @__PURE__ */ jsx(CardContent, { className: "p-4 sm:p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
2011
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2012
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mb-1 text-sm", children: title }),
2013
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-2", children: [
2014
+ /* @__PURE__ */ jsx("h3", { className: "text-foreground text-xl sm:text-2xl", children: value }),
2015
+ trend && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-1 text-sm", getTrendColor()), children: [
2016
+ getTrendIcon(),
2017
+ /* @__PURE__ */ jsxs("span", { children: [
2018
+ Math.abs(trend.value),
2019
+ "%"
2020
+ ] })
2021
+ ] })
2022
+ ] }),
2023
+ (description || (trend == null ? void 0 : trend.label)) && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1 text-xs sm:text-sm", children: (trend == null ? void 0 : trend.label) || description })
2024
+ ] }),
2025
+ icon && /* @__PURE__ */ jsx("div", { className: "rounded-[var(--radius)] bg-muted p-2 sm:p-3 text-muted-foreground flex-shrink-0", children: icon })
2026
+ ] }) }) });
2027
+ }
2028
+ );
2029
+ StatsCard.displayName = "StatsCard";
2030
+ const Timeline = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2031
+ "ol",
2032
+ {
2033
+ ref,
2034
+ className: cn("relative border-l border-border", className),
2035
+ ...props
2036
+ }
2037
+ ));
2038
+ Timeline.displayName = "Timeline";
2039
+ const TimelineItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2040
+ "li",
2041
+ {
2042
+ ref,
2043
+ className: cn("mb-10 ml-6", className),
2044
+ ...props
2045
+ }
2046
+ ));
2047
+ TimelineItem.displayName = "TimelineItem";
2048
+ const TimelineDot = React.forwardRef(({ className, variant = "default", icon, children, ...props }, ref) => {
2049
+ const variantStyles2 = {
2050
+ default: "bg-muted border-border",
2051
+ primary: "bg-primary border-primary",
2052
+ success: "bg-success border-success",
2053
+ info: "bg-info border-info",
2054
+ warning: "bg-warning border-warning",
2055
+ destructive: "bg-destructive border-destructive",
2056
+ outline: "bg-background border-border"
2057
+ };
2058
+ const iconColorStyles = {
2059
+ default: "text-muted-foreground",
2060
+ primary: "text-primary-foreground",
2061
+ success: "text-success-foreground",
2062
+ info: "text-info-foreground",
2063
+ warning: "text-warning-foreground",
2064
+ destructive: "text-destructive-foreground",
2065
+ outline: "text-foreground"
2066
+ };
2067
+ if (icon || children) {
2068
+ return /* @__PURE__ */ jsx(
2069
+ "div",
2070
+ {
2071
+ ref,
2072
+ className: cn(
2073
+ "absolute -left-[17px] mt-0.5 h-8 w-8 rounded-full border-2 flex items-center justify-center",
2074
+ variantStyles2[variant],
2075
+ className
2076
+ ),
2077
+ ...props,
2078
+ children: /* @__PURE__ */ jsx("span", { className: cn("h-4 w-4", iconColorStyles[variant]), children: icon || children })
2079
+ }
2080
+ );
2081
+ }
2082
+ return /* @__PURE__ */ jsx(
2083
+ "div",
2084
+ {
2085
+ ref,
2086
+ className: cn(
2087
+ "absolute -left-[9px] mt-1.5 h-4 w-4 rounded-full border-2",
2088
+ variantStyles2[variant],
2089
+ className
2090
+ ),
2091
+ ...props
2092
+ }
2093
+ );
2094
+ });
2095
+ TimelineDot.displayName = "TimelineDot";
2096
+ const TimelineContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2097
+ "div",
2098
+ {
2099
+ ref,
2100
+ className: cn("", className),
2101
+ ...props
2102
+ }
2103
+ ));
2104
+ TimelineContent.displayName = "TimelineContent";
2105
+ const TimelineHeading = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2106
+ "h3",
2107
+ {
2108
+ ref,
2109
+ className: cn("mb-1 text-foreground", className),
2110
+ ...props
2111
+ }
2112
+ ));
2113
+ TimelineHeading.displayName = "TimelineHeading";
2114
+ const TimelineTime = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2115
+ "time",
2116
+ {
2117
+ ref,
2118
+ className: cn("mb-2 block text-muted-foreground", className),
2119
+ ...props
2120
+ }
2121
+ ));
2122
+ TimelineTime.displayName = "TimelineTime";
2123
+ const TimelineDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2124
+ "p",
2125
+ {
2126
+ ref,
2127
+ className: cn("text-muted-foreground", className),
2128
+ ...props
2129
+ }
2130
+ ));
2131
+ TimelineDescription.displayName = "TimelineDescription";
2132
+ function useTreeView({
2133
+ data,
2134
+ defaultExpanded = [],
2135
+ selectedNodeId,
2136
+ onNodeClick,
2137
+ onNodeSelect
2138
+ }) {
2139
+ const [expanded, setExpanded] = useState(new Set(defaultExpanded));
2140
+ const [internalSelectedId, setInternalSelectedId] = useState(void 0);
2141
+ const nodeRefs = useRef(/* @__PURE__ */ new Map());
2142
+ const isControlled = selectedNodeId !== void 0;
2143
+ const effectiveSelectedId = isControlled ? selectedNodeId : internalSelectedId;
2144
+ const getNodeRef = useCallback(
2145
+ (nodeId) => (el) => {
2146
+ if (el) nodeRefs.current.set(nodeId, el);
2147
+ else nodeRefs.current.delete(nodeId);
2148
+ },
2149
+ []
2150
+ );
2151
+ const getVisibleNodes = useCallback(() => {
2152
+ const result = [];
2153
+ const traverse = (nodes) => {
2154
+ var _a;
2155
+ for (const node of nodes) {
2156
+ result.push(node);
2157
+ if (((_a = node.children) == null ? void 0 : _a.length) && expanded.has(node.id)) traverse(node.children);
2158
+ }
2159
+ };
2160
+ traverse(data);
2161
+ return result;
2162
+ }, [data, expanded]);
2163
+ const findParent = useCallback(
2164
+ (nodes, targetId) => {
2165
+ var _a;
2166
+ for (const n of nodes) {
2167
+ if ((_a = n.children) == null ? void 0 : _a.some((c) => c.id === targetId)) return n;
2168
+ if (n.children) {
2169
+ const found = findParent(n.children, targetId);
2170
+ if (found) return found;
2171
+ }
2172
+ }
2173
+ return null;
2174
+ },
2175
+ // findParent is a pure recursive function over `data` — no reactive deps needed
2176
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2177
+ []
2178
+ );
2179
+ const toggleExpand = useCallback((nodeId) => {
2180
+ setExpanded((prev) => {
2181
+ const next = new Set(prev);
2182
+ next.has(nodeId) ? next.delete(nodeId) : next.add(nodeId);
2183
+ return next;
2184
+ });
2185
+ }, []);
2186
+ const handleSelect = useCallback(
2187
+ (node) => {
2188
+ if (!isControlled) setInternalSelectedId(node.id);
2189
+ onNodeSelect == null ? void 0 : onNodeSelect(node);
2190
+ onNodeClick == null ? void 0 : onNodeClick(node);
2191
+ },
2192
+ [isControlled, onNodeClick, onNodeSelect]
2193
+ );
2194
+ const handleKeyDown = useCallback(
2195
+ (e, node) => {
2196
+ var _a, _b;
2197
+ const visibleNodes = getVisibleNodes();
2198
+ const idx = visibleNodes.findIndex((n) => n.id === node.id);
2199
+ const hasChildren = !!((_a = node.children) == null ? void 0 : _a.length);
2200
+ const isExpanded = expanded.has(node.id);
2201
+ const focusNode = (id) => {
2202
+ var _a2;
2203
+ (_a2 = nodeRefs.current.get(id)) == null ? void 0 : _a2.focus();
2204
+ };
2205
+ switch (e.key) {
2206
+ case "ArrowDown": {
2207
+ e.preventDefault();
2208
+ const next = visibleNodes[idx + 1];
2209
+ if (next) focusNode(next.id);
2210
+ break;
2211
+ }
2212
+ case "ArrowUp": {
2213
+ e.preventDefault();
2214
+ const prev = visibleNodes[idx - 1];
2215
+ if (prev) focusNode(prev.id);
2216
+ break;
2217
+ }
2218
+ case "ArrowRight": {
2219
+ e.preventDefault();
2220
+ if (hasChildren && !isExpanded) {
2221
+ toggleExpand(node.id);
2222
+ } else if (hasChildren && isExpanded && ((_b = node.children) == null ? void 0 : _b.length)) {
2223
+ focusNode(node.children[0].id);
2224
+ }
2225
+ break;
2226
+ }
2227
+ case "ArrowLeft": {
2228
+ e.preventDefault();
2229
+ if (hasChildren && isExpanded) {
2230
+ toggleExpand(node.id);
2231
+ } else {
2232
+ const parent = findParent(data, node.id);
2233
+ if (parent) focusNode(parent.id);
2234
+ }
2235
+ break;
2236
+ }
2237
+ case "Home": {
2238
+ e.preventDefault();
2239
+ if (visibleNodes.length > 0) focusNode(visibleNodes[0].id);
2240
+ break;
2241
+ }
2242
+ case "End": {
2243
+ e.preventDefault();
2244
+ const last = visibleNodes[visibleNodes.length - 1];
2245
+ if (last) focusNode(last.id);
2246
+ break;
2247
+ }
2248
+ case "Enter":
2249
+ case " ": {
2250
+ e.preventDefault();
2251
+ if (hasChildren) toggleExpand(node.id);
2252
+ handleSelect(node);
2253
+ break;
2254
+ }
2255
+ }
2256
+ },
2257
+ [data, expanded, findParent, getVisibleNodes, handleSelect, toggleExpand]
2258
+ );
2259
+ return {
2260
+ expanded,
2261
+ effectiveSelectedId,
2262
+ nodeRefs,
2263
+ getNodeRef,
2264
+ toggleExpand,
2265
+ handleSelect,
2266
+ handleKeyDown,
2267
+ getVisibleNodes
2268
+ };
2269
+ }
2270
+ const TreeView = React.forwardRef(
2271
+ ({ className, data, onNodeClick, onNodeSelect, defaultExpanded = [], selectedNodeId, ...props }, ref) => {
2272
+ const {
2273
+ expanded,
2274
+ effectiveSelectedId,
2275
+ getNodeRef,
2276
+ toggleExpand,
2277
+ handleSelect,
2278
+ handleKeyDown
2279
+ } = useTreeView({ data, defaultExpanded, selectedNodeId, onNodeClick, onNodeSelect });
2280
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("w-full", className), role: "tree", ...props, children: data.map((node) => /* @__PURE__ */ jsx(
2281
+ TreeNodeComponent,
2282
+ {
2283
+ node,
2284
+ level: 0,
2285
+ expanded,
2286
+ selectedId: effectiveSelectedId,
2287
+ onToggle: toggleExpand,
2288
+ onSelect: handleSelect,
2289
+ onKeyDown: handleKeyDown,
2290
+ getNodeRef
2291
+ },
2292
+ node.id
2293
+ )) });
2294
+ }
2295
+ );
2296
+ TreeView.displayName = "TreeView";
2297
+ const TreeNodeComponent = ({
2298
+ node,
2299
+ level,
2300
+ expanded,
2301
+ selectedId,
2302
+ onToggle,
2303
+ onSelect,
2304
+ onKeyDown,
2305
+ getNodeRef
2306
+ }) => {
2307
+ var _a;
2308
+ const hasChildren = !!((_a = node.children) == null ? void 0 : _a.length);
2309
+ const isExpanded = expanded.has(node.id);
2310
+ const isSelected = node.id === selectedId;
2311
+ const handleClick = () => {
2312
+ if (hasChildren) onToggle(node.id);
2313
+ onSelect(node);
2314
+ };
2315
+ return /* @__PURE__ */ jsxs("div", { role: "none", children: [
2316
+ /* @__PURE__ */ jsxs(
2317
+ "button",
2318
+ {
2319
+ ref: getNodeRef(node.id),
2320
+ role: "treeitem",
2321
+ "aria-expanded": hasChildren ? isExpanded : void 0,
2322
+ "aria-selected": isSelected,
2323
+ tabIndex: isSelected ? 0 : -1,
2324
+ onClick: handleClick,
2325
+ onKeyDown: (e) => onKeyDown(e, node),
2326
+ className: cn(
2327
+ "flex w-full items-center gap-2 rounded-[var(--radius)] px-2 py-1.5 text-left transition-colors",
2328
+ "hover:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
2329
+ isSelected && "bg-primary/10 text-primary font-medium"
2330
+ ),
2331
+ style: { paddingLeft: `${level * 1.5 + 0.5}rem` },
2332
+ children: [
2333
+ hasChildren ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-muted-foreground", children: isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" }) }) : /* @__PURE__ */ jsx("span", { className: "w-4 flex-shrink-0", "aria-hidden": "true" }),
2334
+ node.icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-muted-foreground", children: node.icon }),
2335
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-foreground", children: node.label })
2336
+ ]
2337
+ }
2338
+ ),
2339
+ hasChildren && isExpanded && /* @__PURE__ */ jsx("div", { role: "group", children: node.children.map((child) => /* @__PURE__ */ jsx(
2340
+ TreeNodeComponent,
2341
+ {
2342
+ node: child,
2343
+ level: level + 1,
2344
+ expanded,
2345
+ selectedId,
2346
+ onToggle,
2347
+ onSelect,
2348
+ onKeyDown,
2349
+ getNodeRef
2350
+ },
2351
+ child.id
2352
+ )) })
2353
+ ] });
2354
+ };
2355
+ function Collapsible({
2356
+ ...props
2357
+ }) {
2358
+ return /* @__PURE__ */ jsx(CollapsiblePrimitive.Root, { "data-slot": "collapsible", ...props });
2359
+ }
2360
+ function CollapsibleTrigger({
2361
+ ...props
2362
+ }) {
2363
+ return /* @__PURE__ */ jsx(
2364
+ CollapsiblePrimitive.CollapsibleTrigger,
2365
+ {
2366
+ "data-slot": "collapsible-trigger",
2367
+ ...props
2368
+ }
2369
+ );
2370
+ }
2371
+ function CollapsibleContent({
2372
+ ...props
2373
+ }) {
2374
+ return /* @__PURE__ */ jsx(
2375
+ CollapsiblePrimitive.CollapsibleContent,
2376
+ {
2377
+ "data-slot": "collapsible-content",
2378
+ ...props
2379
+ }
2380
+ );
2381
+ }
2382
+ function Accordion({
2383
+ ...props
2384
+ }) {
2385
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Root, { "data-slot": "accordion", ...props });
2386
+ }
2387
+ function AccordionItem({
2388
+ className,
2389
+ ...props
2390
+ }) {
2391
+ return /* @__PURE__ */ jsx(
2392
+ AccordionPrimitive.Item,
2393
+ {
2394
+ "data-slot": "accordion-item",
2395
+ className: cn("border-b last:border-b-0", className),
2396
+ ...props
2397
+ }
2398
+ );
2399
+ }
2400
+ function AccordionTrigger({
2401
+ className,
2402
+ children,
2403
+ ...props
2404
+ }) {
2405
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
2406
+ AccordionPrimitive.Trigger,
2407
+ {
2408
+ "data-slot": "accordion-trigger",
2409
+ className: cn(
2410
+ "focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
2411
+ className
2412
+ ),
2413
+ ...props,
2414
+ children: [
2415
+ children,
2416
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" })
2417
+ ]
2418
+ }
2419
+ ) });
2420
+ }
2421
+ function AccordionContent({
2422
+ className,
2423
+ children,
2424
+ ...props
2425
+ }) {
2426
+ return /* @__PURE__ */ jsx(
2427
+ AccordionPrimitive.Content,
2428
+ {
2429
+ "data-slot": "accordion-content",
2430
+ className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
2431
+ ...props,
2432
+ children: /* @__PURE__ */ jsx("div", { className: cn("pt-0 pb-4", className), children })
2433
+ }
2434
+ );
2435
+ }
2436
+ const CarouselContext = React.createContext(null);
2437
+ function useCarousel() {
2438
+ const context = React.useContext(CarouselContext);
2439
+ if (!context) {
2440
+ throw new Error("useCarousel must be used within a <Carousel />");
2441
+ }
2442
+ return context;
2443
+ }
2444
+ function Carousel({
2445
+ orientation = "horizontal",
2446
+ opts,
2447
+ setApi,
2448
+ plugins,
2449
+ className,
2450
+ children,
2451
+ ...props
2452
+ }) {
2453
+ const [carouselRef, api] = useEmblaCarousel(
2454
+ {
2455
+ ...opts,
2456
+ axis: orientation === "horizontal" ? "x" : "y"
2457
+ },
2458
+ plugins
2459
+ );
2460
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false);
2461
+ const [canScrollNext, setCanScrollNext] = React.useState(false);
2462
+ const onSelect = React.useCallback((api2) => {
2463
+ if (!api2) return;
2464
+ setCanScrollPrev(api2.canScrollPrev());
2465
+ setCanScrollNext(api2.canScrollNext());
2466
+ }, []);
2467
+ const scrollPrev = React.useCallback(() => {
2468
+ api == null ? void 0 : api.scrollPrev();
2469
+ }, [api]);
2470
+ const scrollNext = React.useCallback(() => {
2471
+ api == null ? void 0 : api.scrollNext();
2472
+ }, [api]);
2473
+ const handleKeyDown = React.useCallback(
2474
+ (event) => {
2475
+ if (event.key === "ArrowLeft") {
2476
+ event.preventDefault();
2477
+ scrollPrev();
2478
+ } else if (event.key === "ArrowRight") {
2479
+ event.preventDefault();
2480
+ scrollNext();
2481
+ }
2482
+ },
2483
+ [scrollPrev, scrollNext]
2484
+ );
2485
+ React.useEffect(() => {
2486
+ if (!api || !setApi) return;
2487
+ setApi(api);
2488
+ }, [api, setApi]);
2489
+ React.useEffect(() => {
2490
+ if (!api) return;
2491
+ onSelect(api);
2492
+ api.on("reInit", onSelect);
2493
+ api.on("select", onSelect);
2494
+ return () => {
2495
+ api == null ? void 0 : api.off("select", onSelect);
2496
+ };
2497
+ }, [api, onSelect]);
2498
+ return /* @__PURE__ */ jsx(
2499
+ CarouselContext.Provider,
2500
+ {
2501
+ value: {
2502
+ carouselRef,
2503
+ api,
2504
+ opts,
2505
+ orientation: orientation || ((opts == null ? void 0 : opts.axis) === "y" ? "vertical" : "horizontal"),
2506
+ scrollPrev,
2507
+ scrollNext,
2508
+ canScrollPrev,
2509
+ canScrollNext
2510
+ },
2511
+ children: /* @__PURE__ */ jsx(
2512
+ "div",
2513
+ {
2514
+ onKeyDownCapture: handleKeyDown,
2515
+ className: cn("relative", className),
2516
+ role: "region",
2517
+ "aria-roledescription": "carousel",
2518
+ "data-slot": "carousel",
2519
+ ...props,
2520
+ children
2521
+ }
2522
+ )
2523
+ }
2524
+ );
2525
+ }
2526
+ function CarouselContent({ className, ...props }) {
2527
+ const { carouselRef, orientation } = useCarousel();
2528
+ return /* @__PURE__ */ jsx(
2529
+ "div",
2530
+ {
2531
+ ref: carouselRef,
2532
+ className: "overflow-hidden",
2533
+ "data-slot": "carousel-content",
2534
+ children: /* @__PURE__ */ jsx(
2535
+ "div",
2536
+ {
2537
+ className: cn(
2538
+ "flex",
2539
+ orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
2540
+ className
2541
+ ),
2542
+ ...props
2543
+ }
2544
+ )
2545
+ }
2546
+ );
2547
+ }
2548
+ function CarouselItem({ className, ...props }) {
2549
+ const { orientation } = useCarousel();
2550
+ return /* @__PURE__ */ jsx(
2551
+ "div",
2552
+ {
2553
+ role: "group",
2554
+ "aria-roledescription": "slide",
2555
+ "data-slot": "carousel-item",
2556
+ className: cn(
2557
+ "min-w-0 shrink-0 grow-0 basis-full",
2558
+ orientation === "horizontal" ? "pl-4" : "pt-4",
2559
+ className
2560
+ ),
2561
+ ...props
2562
+ }
2563
+ );
2564
+ }
2565
+ function CarouselPrevious({
2566
+ className,
2567
+ variant = "outline",
2568
+ size = "icon",
2569
+ ...props
2570
+ }) {
2571
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel();
2572
+ return /* @__PURE__ */ jsxs(
2573
+ Button,
2574
+ {
2575
+ "data-slot": "carousel-previous",
2576
+ variant,
2577
+ size,
2578
+ className: cn(
2579
+ "absolute size-8 rounded-full",
2580
+ orientation === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
2581
+ className
2582
+ ),
2583
+ disabled: !canScrollPrev,
2584
+ onClick: scrollPrev,
2585
+ ...props,
2586
+ children: [
2587
+ /* @__PURE__ */ jsx(ArrowLeft, {}),
2588
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Previous slide" })
2589
+ ]
2590
+ }
2591
+ );
2592
+ }
2593
+ function CarouselNext({
2594
+ className,
2595
+ variant = "outline",
2596
+ size = "icon",
2597
+ ...props
2598
+ }) {
2599
+ const { orientation, scrollNext, canScrollNext } = useCarousel();
2600
+ return /* @__PURE__ */ jsxs(
2601
+ Button,
2602
+ {
2603
+ "data-slot": "carousel-next",
2604
+ variant,
2605
+ size,
2606
+ className: cn(
2607
+ "absolute size-8 rounded-full",
2608
+ orientation === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
2609
+ className
2610
+ ),
2611
+ disabled: !canScrollNext,
2612
+ onClick: scrollNext,
2613
+ ...props,
2614
+ children: [
2615
+ /* @__PURE__ */ jsx(ArrowRight, {}),
2616
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Next slide" })
2617
+ ]
2618
+ }
2619
+ );
2620
+ }
2621
+ const StepperContext = React.createContext(void 0);
2622
+ const useStepperContext = () => {
2623
+ const context = React.useContext(StepperContext);
2624
+ if (!context) throw new Error("useStepperContext must be used within a Stepper");
2625
+ return context;
2626
+ };
2627
+ const Stepper = React.forwardRef(
2628
+ ({ currentStep, orientation = "horizontal", className, children, ...props }, ref) => {
2629
+ const totalSteps = React.Children.count(children);
2630
+ return /* @__PURE__ */ jsx(StepperContext.Provider, { value: { currentStep, totalSteps, orientation }, children: /* @__PURE__ */ jsx(
2631
+ "div",
2632
+ {
2633
+ ref,
2634
+ className: cn("w-full", className),
2635
+ ...props,
2636
+ children: /* @__PURE__ */ jsx("div", { className: cn(
2637
+ orientation === "horizontal" ? "flex items-start justify-between" : "flex flex-col gap-0"
2638
+ ), children })
2639
+ }
2640
+ ) });
2641
+ }
2642
+ );
2643
+ Stepper.displayName = "Stepper";
2644
+ const Step = React.forwardRef(
2645
+ ({ step, label, description, error = false, className, ...props }, ref) => {
2646
+ const { currentStep, totalSteps, orientation } = useStepperContext();
2647
+ const isActive = step === currentStep;
2648
+ const isCompleted = step < currentStep && !error;
2649
+ const isFirst = step === 1;
2650
+ const isLast = step === totalSteps;
2651
+ const circleClasses = cn(
2652
+ "relative flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full border-2 transition-colors",
2653
+ isActive && !error && "border-primary bg-primary text-primary-foreground",
2654
+ isCompleted && "border-primary bg-primary text-primary-foreground",
2655
+ error && "border-destructive bg-destructive text-destructive-foreground",
2656
+ !isActive && !isCompleted && !error && "border-muted bg-background text-muted-foreground"
2657
+ );
2658
+ const connectorClasses = (filled) => cn("transition-colors", filled ? "bg-primary" : "bg-muted");
2659
+ if (orientation === "vertical") {
2660
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex gap-4", className), ...props, children: [
2661
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
2662
+ /* @__PURE__ */ jsx("div", { className: circleClasses, children: error ? /* @__PURE__ */ jsx(X, { className: "h-5 w-5" }) : isCompleted ? /* @__PURE__ */ jsx(Check, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx("span", { children: step }) }),
2663
+ !isLast && /* @__PURE__ */ jsx("div", { className: cn("w-0.5 flex-1 min-h-[2rem] mt-1", connectorClasses(step < currentStep)) })
2664
+ ] }),
2665
+ /* @__PURE__ */ jsxs("div", { className: cn("pb-6", isLast && "pb-0"), children: [
2666
+ /* @__PURE__ */ jsx("div", { className: cn("transition-colors", isActive || error ? "text-foreground" : "text-muted-foreground"), children: label }),
2667
+ description && /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: description })
2668
+ ] })
2669
+ ] });
2670
+ }
2671
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex flex-1 flex-col items-center", className), ...props, children: [
2672
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-start", children: [
2673
+ step > 1 && /* @__PURE__ */ jsx("div", { className: cn("h-0.5 flex-1 mt-[18px]", connectorClasses(step <= currentStep)) }),
2674
+ /* @__PURE__ */ jsx("div", { className: circleClasses, children: error ? /* @__PURE__ */ jsx(X, { className: "h-5 w-5" }) : isCompleted ? /* @__PURE__ */ jsx(Check, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx("span", { children: step }) }),
2675
+ step < totalSteps && /* @__PURE__ */ jsx("div", { className: cn("h-0.5 flex-1 mt-[18px]", connectorClasses(step < currentStep)) })
2676
+ ] }),
2677
+ /* @__PURE__ */ jsxs("div", { className: cn(
2678
+ "mt-2 px-1",
2679
+ isFirst && "text-left self-start",
2680
+ isLast && "text-right self-end",
2681
+ !isFirst && !isLast && "text-center w-full"
2682
+ ), children: [
2683
+ /* @__PURE__ */ jsx("div", { className: cn("transition-colors", isActive || error ? "text-foreground" : "text-muted-foreground"), children: label }),
2684
+ description && /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: description })
2685
+ ] })
2686
+ ] });
2687
+ }
2688
+ );
2689
+ Step.displayName = "Step";
2690
+ function useStepper({
2691
+ totalSteps,
2692
+ initialStep = 1,
2693
+ step: controlledStep,
2694
+ onStepChange,
2695
+ onBeforeNext
2696
+ }) {
2697
+ const [internalStep, setInternalStep] = useState(initialStep);
2698
+ const isControlled = controlledStep !== void 0;
2699
+ const currentStep = isControlled ? controlledStep : internalStep;
2700
+ const setStep = useCallback(
2701
+ (s) => {
2702
+ const clamped = Math.min(Math.max(1, s), totalSteps);
2703
+ if (!isControlled) setInternalStep(clamped);
2704
+ onStepChange == null ? void 0 : onStepChange(clamped);
2705
+ },
2706
+ [isControlled, onStepChange, totalSteps]
2707
+ );
2708
+ const isFirstStep = currentStep === 1;
2709
+ const isLastStep = currentStep === totalSteps;
2710
+ const canGoPrev = currentStep > 1;
2711
+ const canGoNext = currentStep < totalSteps;
2712
+ const next = useCallback(async () => {
2713
+ if (!canGoNext) return;
2714
+ if (onBeforeNext) {
2715
+ const allowed = await onBeforeNext(currentStep);
2716
+ if (!allowed) return;
2717
+ }
2718
+ setStep(currentStep + 1);
2719
+ }, [canGoNext, currentStep, onBeforeNext, setStep]);
2720
+ const prev = useCallback(() => {
2721
+ if (!canGoPrev) return;
2722
+ setStep(currentStep - 1);
2723
+ }, [canGoPrev, currentStep, setStep]);
2724
+ const goTo = useCallback((s) => setStep(s), [setStep]);
2725
+ const reset = useCallback(() => setStep(1), [setStep]);
2726
+ return {
2727
+ currentStep,
2728
+ totalSteps,
2729
+ isFirstStep,
2730
+ isLastStep,
2731
+ canGoPrev,
2732
+ canGoNext,
2733
+ next,
2734
+ prev,
2735
+ goTo,
2736
+ reset
2737
+ };
2738
+ }
2739
+ function useFileUpload({
2740
+ maxFiles = 1,
2741
+ maxSize = 5 * 1024 * 1024,
2742
+ onFilesChange,
2743
+ onError,
2744
+ disabled = false
2745
+ } = {}) {
2746
+ const [files, setFiles] = useState([]);
2747
+ const [dragActive, setDragActive] = useState(false);
2748
+ const [errorMessage, setErrorMessage] = useState(null);
2749
+ const inputRef = useRef(null);
2750
+ const handleFiles = useCallback(
2751
+ (newFiles) => {
2752
+ if (!newFiles) return;
2753
+ setErrorMessage(null);
2754
+ const filesArray = Array.from(newFiles);
2755
+ const oversized = filesArray.filter((f) => f.size > maxSize);
2756
+ const validFiles = filesArray.filter((f) => f.size <= maxSize);
2757
+ if (oversized.length > 0) {
2758
+ const limitMB = (maxSize / 1024 / 1024).toFixed(0);
2759
+ setErrorMessage(
2760
+ `${oversized.length} file(s) exceed the ${limitMB}MB limit and were not added.`
2761
+ );
2762
+ onError == null ? void 0 : onError(oversized, "size");
2763
+ }
2764
+ const merged = maxFiles === 1 ? validFiles.slice(0, 1) : [...files, ...validFiles].slice(0, maxFiles);
2765
+ const countRejected = maxFiles === 1 ? validFiles.slice(1) : [...files, ...validFiles].slice(maxFiles);
2766
+ if (countRejected.length > 0) {
2767
+ setErrorMessage(
2768
+ `Only ${maxFiles} file(s) allowed. ${countRejected.length} file(s) were not added.`
2769
+ );
2770
+ onError == null ? void 0 : onError(countRejected, "count");
2771
+ }
2772
+ setFiles(merged);
2773
+ onFilesChange == null ? void 0 : onFilesChange(merged);
2774
+ },
2775
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2776
+ [files, maxFiles, maxSize, onError, onFilesChange]
2777
+ );
2778
+ const handleDrag = useCallback((e) => {
2779
+ e.preventDefault();
2780
+ e.stopPropagation();
2781
+ if (e.type === "dragenter" || e.type === "dragover") {
2782
+ setDragActive(true);
2783
+ } else if (e.type === "dragleave") {
2784
+ setDragActive(false);
2785
+ }
2786
+ }, []);
2787
+ const handleDrop = useCallback(
2788
+ (e) => {
2789
+ e.preventDefault();
2790
+ e.stopPropagation();
2791
+ setDragActive(false);
2792
+ if (disabled) return;
2793
+ handleFiles(e.dataTransfer.files);
2794
+ },
2795
+ [disabled, handleFiles]
2796
+ );
2797
+ const handleChange = useCallback(
2798
+ (e) => {
2799
+ e.preventDefault();
2800
+ if (disabled) return;
2801
+ handleFiles(e.target.files);
2802
+ },
2803
+ [disabled, handleFiles]
2804
+ );
2805
+ const removeFile = useCallback(
2806
+ (index) => {
2807
+ setFiles((prev) => {
2808
+ const updated = prev.filter((_, i) => i !== index);
2809
+ onFilesChange == null ? void 0 : onFilesChange(updated);
2810
+ if (updated.length === 0) setErrorMessage(null);
2811
+ return updated;
2812
+ });
2813
+ },
2814
+ [onFilesChange]
2815
+ );
2816
+ const openFileDialog = useCallback(() => {
2817
+ var _a;
2818
+ if (!disabled) {
2819
+ setErrorMessage(null);
2820
+ (_a = inputRef.current) == null ? void 0 : _a.click();
2821
+ }
2822
+ }, [disabled]);
2823
+ return {
2824
+ files,
2825
+ dragActive,
2826
+ errorMessage,
2827
+ inputRef,
2828
+ handleFiles,
2829
+ handleDrag,
2830
+ handleDrop,
2831
+ handleChange,
2832
+ removeFile,
2833
+ openFileDialog
2834
+ };
2835
+ }
2836
+ const FileUpload = React.forwardRef(
2837
+ ({
2838
+ className,
2839
+ onFilesChange,
2840
+ maxFiles = 1,
2841
+ maxSize = 5 * 1024 * 1024,
2842
+ // 5MB default
2843
+ showPreview = true,
2844
+ onError,
2845
+ accept,
2846
+ disabled,
2847
+ ...props
2848
+ }, ref) => {
2849
+ const {
2850
+ files,
2851
+ dragActive,
2852
+ errorMessage,
2853
+ inputRef,
2854
+ handleDrag,
2855
+ handleDrop,
2856
+ handleChange,
2857
+ removeFile,
2858
+ openFileDialog
2859
+ } = useFileUpload({ maxFiles, maxSize, onFilesChange, onError, disabled });
2860
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("w-full", className), children: [
2861
+ /* @__PURE__ */ jsxs(
2862
+ "div",
2863
+ {
2864
+ onDragEnter: handleDrag,
2865
+ onDragLeave: handleDrag,
2866
+ onDragOver: handleDrag,
2867
+ onDrop: handleDrop,
2868
+ onClick: openFileDialog,
2869
+ className: cn(
2870
+ "relative flex cursor-pointer flex-col items-center justify-center rounded-[var(--radius)] border-2 border-dashed border-border bg-background p-8 transition-colors hover:bg-muted/50",
2871
+ dragActive && "border-primary bg-primary/5",
2872
+ errorMessage && "border-destructive/50",
2873
+ disabled && "cursor-not-allowed opacity-50"
2874
+ ),
2875
+ children: [
2876
+ /* @__PURE__ */ jsx(Upload, { className: "mb-4 h-10 w-10 text-muted-foreground" }),
2877
+ /* @__PURE__ */ jsxs("p", { className: "mb-2 text-foreground", children: [
2878
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: "Click to upload" }),
2879
+ " or drag and drop"
2880
+ ] }),
2881
+ /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
2882
+ maxFiles > 1 ? `Up to ${maxFiles} files` : "1 file",
2883
+ " • Max ",
2884
+ (maxSize / 1024 / 1024).toFixed(0),
2885
+ "MB"
2886
+ ] }),
2887
+ /* @__PURE__ */ jsx(
2888
+ "input",
2889
+ {
2890
+ ...props,
2891
+ ref: inputRef,
2892
+ type: "file",
2893
+ className: "hidden",
2894
+ onChange: handleChange,
2895
+ multiple: maxFiles > 1,
2896
+ accept,
2897
+ disabled
2898
+ }
2899
+ )
2900
+ ]
2901
+ }
2902
+ ),
2903
+ errorMessage && /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-2 rounded-[var(--radius)] border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: [
2904
+ /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4 shrink-0" }),
2905
+ /* @__PURE__ */ jsx("span", { children: errorMessage })
2906
+ ] }),
2907
+ showPreview && files.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-4 space-y-2", children: files.map((file, index) => /* @__PURE__ */ jsxs(
2908
+ "div",
2909
+ {
2910
+ className: "flex items-center justify-between rounded-[var(--radius)] border border-border bg-card p-3",
2911
+ children: [
2912
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
2913
+ /* @__PURE__ */ jsx(FileIcon, { className: "h-5 w-5 text-muted-foreground" }),
2914
+ /* @__PURE__ */ jsxs("div", { children: [
2915
+ /* @__PURE__ */ jsx("p", { className: "text-foreground", children: file.name }),
2916
+ /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
2917
+ (file.size / 1024).toFixed(2),
2918
+ " KB"
2919
+ ] })
2920
+ ] })
2921
+ ] }),
2922
+ /* @__PURE__ */ jsx(
2923
+ Button,
2924
+ {
2925
+ type: "button",
2926
+ variant: "ghost",
2927
+ size: "sm",
2928
+ onClick: (e) => {
2929
+ e.stopPropagation();
2930
+ removeFile(index);
2931
+ },
2932
+ disabled,
2933
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
2934
+ }
2935
+ )
2936
+ ]
2937
+ },
2938
+ index
2939
+ )) })
2940
+ ] });
2941
+ }
2942
+ );
2943
+ FileUpload.displayName = "FileUpload";
2944
+ const Rating = React.forwardRef(
2945
+ ({
2946
+ className,
2947
+ value = 0,
2948
+ onChange,
2949
+ max = 5,
2950
+ readonly = false,
2951
+ disabled = false,
2952
+ size = "md",
2953
+ showValue = false,
2954
+ allowHalf = false,
2955
+ getAriaLabel,
2956
+ ...props
2957
+ }, ref) => {
2958
+ const [hoverValue, setHoverValue] = React.useState(null);
2959
+ const isInteractive = !readonly && !disabled;
2960
+ const sizeStyles = {
2961
+ sm: "h-4 w-4",
2962
+ md: "h-5 w-5",
2963
+ lg: "h-6 w-6"
2964
+ };
2965
+ const handleClick = (rating) => {
2966
+ if (isInteractive) onChange == null ? void 0 : onChange(rating);
2967
+ };
2968
+ const handleMouseMove = (e, rating) => {
2969
+ if (!isInteractive) return;
2970
+ if (allowHalf) {
2971
+ const rect = e.currentTarget.getBoundingClientRect();
2972
+ setHoverValue(e.clientX - rect.left < rect.width / 2 ? rating - 0.5 : rating);
2973
+ } else {
2974
+ setHoverValue(rating);
2975
+ }
2976
+ };
2977
+ const handleMouseLeave = () => {
2978
+ if (isInteractive) setHoverValue(null);
2979
+ };
2980
+ const handleClickWithHalf = (e, rating) => {
2981
+ if (!isInteractive) return;
2982
+ if (allowHalf) {
2983
+ const rect = e.currentTarget.getBoundingClientRect();
2984
+ const half = e.clientX - rect.left < rect.width / 2 ? rating - 0.5 : rating;
2985
+ onChange == null ? void 0 : onChange(half);
2986
+ } else {
2987
+ handleClick(rating);
2988
+ }
2989
+ };
2990
+ const displayValue = hoverValue ?? value;
2991
+ return /* @__PURE__ */ jsxs(
2992
+ "div",
2993
+ {
2994
+ ref,
2995
+ className: cn("flex items-center gap-1", disabled && "opacity-50", className),
2996
+ ...props,
2997
+ children: [
2998
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Rating", children: Array.from({ length: max }, (_, index) => {
2999
+ const rating = index + 1;
3000
+ const isFull = rating <= displayValue;
3001
+ const isHalf = allowHalf && !isFull && rating - 0.5 <= displayValue;
3002
+ return /* @__PURE__ */ jsxs(
3003
+ "button",
3004
+ {
3005
+ type: "button",
3006
+ onClick: (e) => handleClickWithHalf(e, rating),
3007
+ onMouseMove: (e) => handleMouseMove(e, rating),
3008
+ onMouseLeave: handleMouseLeave,
3009
+ disabled: readonly || disabled,
3010
+ "aria-label": getAriaLabel ? getAriaLabel(rating, max) : `${rating} / ${max}`,
3011
+ className: cn(
3012
+ "relative transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3013
+ isInteractive && "cursor-pointer hover:scale-110",
3014
+ !isInteractive && "cursor-default"
3015
+ ),
3016
+ children: [
3017
+ /* @__PURE__ */ jsx(Star, { className: cn(sizeStyles[size], "fill-none text-muted-foreground") }),
3018
+ (isFull || isHalf) && /* @__PURE__ */ jsx(
3019
+ "span",
3020
+ {
3021
+ className: cn(
3022
+ "absolute inset-0 overflow-hidden",
3023
+ isHalf ? "w-1/2" : "w-full"
3024
+ ),
3025
+ children: /* @__PURE__ */ jsx(Star, { className: cn(sizeStyles[size], "fill-warning text-warning") })
3026
+ }
3027
+ )
3028
+ ]
3029
+ },
3030
+ index
3031
+ );
3032
+ }) }),
3033
+ showValue && /* @__PURE__ */ jsx("span", { className: "ml-2 text-sm text-muted-foreground", children: value % 1 === 0 ? value.toFixed(0) : value.toFixed(1) })
3034
+ ]
3035
+ }
3036
+ );
3037
+ }
3038
+ );
3039
+ Rating.displayName = "Rating";
3040
+ const Search = React.forwardRef(
3041
+ ({
3042
+ className,
3043
+ containerClassName,
3044
+ onSearch,
3045
+ onClear,
3046
+ onChange,
3047
+ size = "md",
3048
+ searchLabel = "Search",
3049
+ clearLabel = "Clear search",
3050
+ value: controlledValue,
3051
+ defaultValue,
3052
+ ...props
3053
+ }, ref) => {
3054
+ const isControlled = controlledValue !== void 0;
3055
+ const [internalValue, setInternalValue] = React.useState(
3056
+ isControlled ? "" : defaultValue ?? ""
3057
+ );
3058
+ const displayValue = isControlled ? controlledValue : internalValue;
3059
+ const sizeClasses = {
3060
+ sm: "h-8 px-8 py-1 text-sm",
3061
+ md: "h-10 px-10 py-2 text-base",
3062
+ lg: "h-12 px-12 py-3 text-base"
3063
+ };
3064
+ const iconSizeClasses = {
3065
+ sm: "left-2 h-3.5 w-3.5",
3066
+ md: "left-3 h-4 w-4",
3067
+ lg: "left-4 h-5 w-5"
3068
+ };
3069
+ const clearSizeClasses = {
3070
+ sm: "right-2",
3071
+ md: "right-3",
3072
+ lg: "right-4"
3073
+ };
3074
+ const handleChange = (e) => {
3075
+ const newValue = e.target.value;
3076
+ if (!isControlled) setInternalValue(newValue);
3077
+ onChange == null ? void 0 : onChange(e);
3078
+ onSearch == null ? void 0 : onSearch(newValue);
3079
+ };
3080
+ const handleClear = () => {
3081
+ if (!isControlled) setInternalValue("");
3082
+ onClear == null ? void 0 : onClear();
3083
+ onSearch == null ? void 0 : onSearch("");
3084
+ };
3085
+ const handleKeyDown = (e) => {
3086
+ var _a;
3087
+ if (e.key === "Escape") {
3088
+ handleClear();
3089
+ }
3090
+ (_a = props.onKeyDown) == null ? void 0 : _a.call(props, e);
3091
+ };
3092
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative w-full", containerClassName), children: [
3093
+ /* @__PURE__ */ jsx(
3094
+ Search$1,
3095
+ {
3096
+ "aria-hidden": "true",
3097
+ className: cn("absolute top-1/2 -translate-y-1/2 text-muted-foreground", iconSizeClasses[size])
3098
+ }
3099
+ ),
3100
+ /* @__PURE__ */ jsx(
3101
+ "input",
3102
+ {
3103
+ ref,
3104
+ type: "text",
3105
+ value: displayValue,
3106
+ onChange: handleChange,
3107
+ onKeyDown: handleKeyDown,
3108
+ className: cn(
3109
+ "flex w-full rounded-[var(--radius)] border border-border bg-background text-foreground transition-colors outline-none",
3110
+ "placeholder:text-muted-foreground",
3111
+ "focus:ring-2 focus:ring-primary focus:border-transparent",
3112
+ "disabled:cursor-not-allowed disabled:opacity-50",
3113
+ sizeClasses[size],
3114
+ className
3115
+ ),
3116
+ "aria-label": props.placeholder || searchLabel,
3117
+ ...props
3118
+ }
3119
+ ),
3120
+ displayValue && /* @__PURE__ */ jsx(
3121
+ "button",
3122
+ {
3123
+ type: "button",
3124
+ onClick: handleClear,
3125
+ "aria-label": clearLabel,
3126
+ className: cn(
3127
+ "absolute top-1/2 -translate-y-1/2 text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
3128
+ clearSizeClasses[size]
3129
+ ),
3130
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
3131
+ }
3132
+ )
3133
+ ] });
3134
+ }
3135
+ );
3136
+ Search.displayName = "Search";
3137
+ const __vite_import_meta_env__ = { "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SSR": false };
3138
+ const RouteMapContent = React__default.forwardRef(
3139
+ ({ apiKey, ...props }, ref) => {
3140
+ const { isLoaded, loadError, load } = useGoogleMapsLoader();
3141
+ const {
3142
+ origin,
3143
+ destination,
3144
+ waypoints = [],
3145
+ travelMode = "DRIVING",
3146
+ height = "450px",
3147
+ mapContainerClassName,
3148
+ disableDefaultUI = false,
3149
+ zoomControl = true,
3150
+ streetViewControl = false,
3151
+ mapTypeControl = false,
3152
+ fullscreenControl = true,
3153
+ onRouteCalculated,
3154
+ className,
3155
+ ...divProps
3156
+ } = props;
3157
+ const mapRef = useRef(null);
3158
+ const gmpMapRef = useRef(null);
3159
+ const directionsRendererRef = useRef(null);
3160
+ useRef(false);
3161
+ const isCalculatingRef = useRef(false);
3162
+ useEffect(() => {
3163
+ if (!isLoaded && apiKey && !loadError && load) {
3164
+ load(apiKey).catch(console.error);
3165
+ }
3166
+ }, [isLoaded, apiKey, loadError, load]);
3167
+ useEffect(() => {
3168
+ if (!isLoaded || !gmpMapRef.current) return;
3169
+ const setupMap = (map) => {
3170
+ mapRef.current = map;
3171
+ const computedStyle = getComputedStyle(document.documentElement);
3172
+ const primaryColor = computedStyle.getPropertyValue("--primary").trim() || "#4F46E5";
3173
+ if (!directionsRendererRef.current) {
3174
+ directionsRendererRef.current = new google.maps.DirectionsRenderer({
3175
+ map,
3176
+ suppressMarkers: false,
3177
+ polylineOptions: {
3178
+ strokeColor: primaryColor,
3179
+ strokeWeight: 5,
3180
+ strokeOpacity: 0.8
3181
+ }
3182
+ });
3183
+ } else {
3184
+ directionsRendererRef.current.setMap(map);
3185
+ }
3186
+ };
3187
+ const gmpMap = gmpMapRef.current;
3188
+ if (gmpMap.innerMap) {
3189
+ setupMap(gmpMap.innerMap);
3190
+ } else {
3191
+ const interval = setInterval(() => {
3192
+ if (gmpMap.innerMap) {
3193
+ setupMap(gmpMap.innerMap);
3194
+ clearInterval(interval);
3195
+ }
3196
+ }, 100);
3197
+ return () => clearInterval(interval);
3198
+ }
3199
+ return () => {
3200
+ if (directionsRendererRef.current) {
3201
+ directionsRendererRef.current.setMap(null);
3202
+ }
3203
+ mapRef.current = null;
3204
+ };
3205
+ }, [isLoaded]);
3206
+ useEffect(() => {
3207
+ if (gmpMapRef.current && origin) {
3208
+ gmpMapRef.current.center = origin;
3209
+ }
3210
+ }, [origin.lat, origin.lng]);
3211
+ useEffect(() => {
3212
+ if (gmpMapRef.current) {
3213
+ gmpMapRef.current.zoom = 13;
3214
+ }
3215
+ }, []);
3216
+ useEffect(() => {
3217
+ const map = mapRef.current;
3218
+ const renderer = directionsRendererRef.current;
3219
+ if (!map || !renderer || !isLoaded || isCalculatingRef.current) return;
3220
+ if (!origin || !destination) return;
3221
+ isCalculatingRef.current = true;
3222
+ const directionsService = new google.maps.DirectionsService();
3223
+ const request = {
3224
+ origin,
3225
+ destination,
3226
+ waypoints: waypoints.map((wp) => ({
3227
+ location: wp,
3228
+ stopover: true
3229
+ })),
3230
+ travelMode: google.maps.TravelMode[travelMode]
3231
+ };
3232
+ directionsService.route(request, (result, status) => {
3233
+ var _a;
3234
+ isCalculatingRef.current = false;
3235
+ if (status === "OK" && result) {
3236
+ renderer.setDirections(result);
3237
+ const route = result.routes[0];
3238
+ if (((_a = route == null ? void 0 : route.legs) == null ? void 0 : _a.length) > 0 && onRouteCalculated) {
3239
+ let totalDistance = 0;
3240
+ let totalDuration = 0;
3241
+ route.legs.forEach((leg) => {
3242
+ if (leg.distance) totalDistance += leg.distance.value;
3243
+ if (leg.duration) totalDuration += leg.duration.value;
3244
+ });
3245
+ const distanceKm = (totalDistance / 1e3).toFixed(1);
3246
+ const distanceText = `${distanceKm} km`;
3247
+ const hours = Math.floor(totalDuration / 3600);
3248
+ const minutes = Math.floor(totalDuration % 3600 / 60);
3249
+ const durationText = hours > 0 ? `${hours}h ${minutes}min` : `${minutes} min`;
3250
+ onRouteCalculated(distanceText, durationText);
3251
+ }
3252
+ }
3253
+ });
3254
+ }, [isLoaded, origin.lat, origin.lng, destination.lat, destination.lng, travelMode, mapRef.current]);
3255
+ if (loadError) {
3256
+ return /* @__PURE__ */ jsx(
3257
+ "div",
3258
+ {
3259
+ ref,
3260
+ className: cn(
3261
+ "relative rounded-[var(--radius-card)] border border-destructive/50 overflow-hidden bg-destructive/5",
3262
+ className
3263
+ ),
3264
+ style: { height },
3265
+ ...divProps,
3266
+ children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center space-y-2 p-6", children: [
3267
+ /* @__PURE__ */ jsx("div", { className: "text-destructive", children: /* @__PURE__ */ jsx("svg", { className: "w-12 h-12 mx-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }) }),
3268
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Failed to load Google Maps" }),
3269
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Check API key in Settings" })
3270
+ ] }) })
3271
+ }
3272
+ );
3273
+ }
3274
+ if (!isLoaded) {
3275
+ return /* @__PURE__ */ jsx(
3276
+ "div",
3277
+ {
3278
+ ref,
3279
+ className: cn(
3280
+ "relative rounded-[var(--radius-card)] border border-border overflow-hidden bg-muted animate-pulse",
3281
+ className
3282
+ ),
3283
+ style: { height },
3284
+ ...divProps
3285
+ }
3286
+ );
3287
+ }
3288
+ return /* @__PURE__ */ jsx(
3289
+ "div",
3290
+ {
3291
+ ref,
3292
+ className: cn(
3293
+ "relative rounded-[var(--radius-card)] border border-border overflow-hidden",
3294
+ className
3295
+ ),
3296
+ style: { height },
3297
+ ...divProps,
3298
+ children: /* @__PURE__ */ jsx(
3299
+ "gmp-map",
3300
+ {
3301
+ ref: gmpMapRef,
3302
+ style: { height: "100%", width: "100%", display: "block" },
3303
+ "map-id": props.mapId || "xertica-route-map"
3304
+ }
3305
+ )
3306
+ }
3307
+ );
3308
+ }
3309
+ );
3310
+ RouteMapContent.displayName = "RouteMapContent";
3311
+ const RouteMap = React__default.forwardRef(
3312
+ (props, ref) => {
3313
+ const { isLoaded, loadError } = useGoogleMapsLoader();
3314
+ const effectiveApiKey = props.apiKey || typeof import.meta !== "undefined" && __vite_import_meta_env__ && void 0 || "";
3315
+ const isValidKey = effectiveApiKey && effectiveApiKey !== "YOUR_GOOGLE_MAPS_API_KEY_HERE" && effectiveApiKey.startsWith("AIza");
3316
+ if (isLoaded || isValidKey || loadError) {
3317
+ return /* @__PURE__ */ jsx(RouteMapContent, { ref, ...props, apiKey: effectiveApiKey });
3318
+ }
3319
+ const isScriptInjected = typeof document !== "undefined" && !!document.querySelector('script[src*="maps.googleapis.com/maps/api/js"]');
3320
+ if (isScriptInjected) {
3321
+ return /* @__PURE__ */ jsx(RouteMapContent, { ref, ...props, apiKey: effectiveApiKey });
3322
+ }
3323
+ const {
3324
+ origin,
3325
+ destination,
3326
+ waypoints,
3327
+ travelMode,
3328
+ height,
3329
+ apiKey,
3330
+ mapContainerClassName,
3331
+ disableDefaultUI,
3332
+ zoomControl,
3333
+ streetViewControl,
3334
+ mapTypeControl,
3335
+ fullscreenControl,
3336
+ onRouteCalculated,
3337
+ ...divProps
3338
+ } = props;
3339
+ return /* @__PURE__ */ jsx(
3340
+ "div",
3341
+ {
3342
+ ref,
3343
+ className: cn(
3344
+ "relative rounded-[var(--radius-card)] border border-border overflow-hidden bg-muted",
3345
+ props.className
3346
+ ),
3347
+ style: { height: props.height || "450px" },
3348
+ ...divProps,
3349
+ children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-gradient-to-br from-muted/50 to-muted", children: /* @__PURE__ */ jsxs("div", { className: "text-center space-y-3 p-6", children: [
3350
+ /* @__PURE__ */ jsx("div", { className: "w-16 h-16 mx-auto bg-primary/10 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxs("svg", { className: "w-8 h-8 text-primary", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [
3351
+ /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" }),
3352
+ /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 11a3 3 0 11-6 0 3 3 0 016 0z" })
3353
+ ] }) }),
3354
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Configure Google Maps API Key in Settings" })
3355
+ ] }) })
3356
+ }
3357
+ );
3358
+ }
3359
+ );
3360
+ RouteMap.displayName = "RouteMap";
3361
+ const SimpleMap = React__default.forwardRef(
3362
+ ({
3363
+ center,
3364
+ address,
3365
+ markerTitle,
3366
+ markerInfo,
3367
+ showMarker = true,
3368
+ zoom = 15,
3369
+ height = "350px",
3370
+ ...props
3371
+ }, ref) => {
3372
+ const markers = showMarker && center ? [
3373
+ {
3374
+ position: center,
3375
+ title: markerTitle || address || "Location",
3376
+ info: markerInfo || address
3377
+ }
3378
+ ] : [];
3379
+ return /* @__PURE__ */ jsx(
3380
+ Map$1,
3381
+ {
3382
+ ref,
3383
+ center,
3384
+ zoom,
3385
+ height,
3386
+ markers,
3387
+ ...props
3388
+ }
3389
+ );
3390
+ }
3391
+ );
3392
+ SimpleMap.displayName = "SimpleMap";
3393
+ function AssistantChart({
3394
+ data,
3395
+ config,
3396
+ categoryKey = "month",
3397
+ bars,
3398
+ xAxisFormatter,
3399
+ className
3400
+ }) {
3401
+ const resolvedBars = bars ?? Object.keys(config).map((key) => ({ dataKey: key }));
3402
+ const formatTick = xAxisFormatter ?? ((value) => value.slice(0, 3));
3403
+ return /* @__PURE__ */ jsx(ChartContainer, { config, className: cn("min-h-[200px] w-full", className), children: /* @__PURE__ */ jsxs(BarChart, { accessibilityLayer: true, data, children: [
3404
+ /* @__PURE__ */ jsx(CartesianGrid, { vertical: false }),
3405
+ /* @__PURE__ */ jsx(
3406
+ XAxis,
3407
+ {
3408
+ dataKey: categoryKey,
3409
+ tickLine: false,
3410
+ tickMargin: 10,
3411
+ axisLine: false,
3412
+ tickFormatter: formatTick
3413
+ }
3414
+ ),
3415
+ /* @__PURE__ */ jsx(ChartTooltip, { cursor: false, content: /* @__PURE__ */ jsx(ChartTooltipContent, { indicator: "dashed" }) }),
3416
+ resolvedBars.map((bar) => /* @__PURE__ */ jsx(
3417
+ Bar,
3418
+ {
3419
+ dataKey: bar.dataKey,
3420
+ fill: bar.fill ?? `var(--color-${bar.dataKey})`,
3421
+ radius: bar.radius ?? 4
3422
+ },
3423
+ bar.dataKey
3424
+ ))
3425
+ ] }) });
3426
+ }
3427
+ export {
3428
+ FormControl as $,
3429
+ Accordion as A,
3430
+ ContextMenuGroup as B,
3431
+ Calendar as C,
3432
+ ContextMenuItem as D,
3433
+ ContextMenuLabel as E,
3434
+ ContextMenuPortal as F,
3435
+ ContextMenuRadioGroup as G,
3436
+ ContextMenuRadioItem as H,
3437
+ ContextMenuSeparator as I,
3438
+ ContextMenuShortcut as J,
3439
+ ContextMenuSub as K,
3440
+ ContextMenuSubContent as L,
3441
+ ContextMenuSubTrigger as M,
3442
+ ContextMenuTrigger as N,
3443
+ Drawer as O,
3444
+ DrawerClose as P,
3445
+ DrawerContent as Q,
3446
+ DrawerDescription as R,
3447
+ DrawerFooter as S,
3448
+ DrawerHandle as T,
3449
+ DrawerHeader as U,
3450
+ DrawerOverlay as V,
3451
+ DrawerPortal as W,
3452
+ DrawerTitle as X,
3453
+ DrawerTrigger as Y,
3454
+ FileUpload as Z,
3455
+ Form as _,
3456
+ AccordionContent as a,
3457
+ Stepper as a$,
3458
+ FormDescription as a0,
3459
+ FormField as a1,
3460
+ FormItem as a2,
3461
+ FormLabel as a3,
3462
+ FormMessage as a4,
3463
+ HoverCard as a5,
3464
+ HoverCardContent as a6,
3465
+ HoverCardTrigger as a7,
3466
+ InputOTP as a8,
3467
+ InputOTPGroup as a9,
3468
+ NotificationBadge as aA,
3469
+ Pagination as aB,
3470
+ PaginationContent as aC,
3471
+ PaginationEllipsis as aD,
3472
+ PaginationItem as aE,
3473
+ PaginationLink as aF,
3474
+ PaginationNext as aG,
3475
+ PaginationPrevious as aH,
3476
+ Rating as aI,
3477
+ ResizableHandle as aJ,
3478
+ ResizablePanel as aK,
3479
+ ResizablePanelGroup as aL,
3480
+ RouteMap as aM,
3481
+ Search as aN,
3482
+ Sheet as aO,
3483
+ SheetBody as aP,
3484
+ SheetClose as aQ,
3485
+ SheetContent as aR,
3486
+ SheetDescription as aS,
3487
+ SheetFooter as aT,
3488
+ SheetHeader as aU,
3489
+ SheetPortal as aV,
3490
+ SheetTitle as aW,
3491
+ SheetTrigger as aX,
3492
+ SimpleMap as aY,
3493
+ StatsCard as aZ,
3494
+ Step as a_,
3495
+ InputOTPSeparator as aa,
3496
+ InputOTPSlot as ab,
3497
+ Menubar as ac,
3498
+ MenubarCheckboxItem as ad,
3499
+ MenubarContent as ae,
3500
+ MenubarGroup as af,
3501
+ MenubarItem as ag,
3502
+ MenubarLabel as ah,
3503
+ MenubarMenu as ai,
3504
+ MenubarPortal as aj,
3505
+ MenubarRadioGroup as ak,
3506
+ MenubarRadioItem as al,
3507
+ MenubarSeparator as am,
3508
+ MenubarShortcut as an,
3509
+ MenubarSub as ao,
3510
+ MenubarSubContent as ap,
3511
+ MenubarSubTrigger as aq,
3512
+ MenubarTrigger as ar,
3513
+ NavigationMenu as as,
3514
+ NavigationMenuContent as at,
3515
+ NavigationMenuIndicator as au,
3516
+ NavigationMenuItem as av,
3517
+ NavigationMenuLink as aw,
3518
+ NavigationMenuList as ax,
3519
+ NavigationMenuTrigger as ay,
3520
+ NavigationMenuViewport as az,
3521
+ AccordionItem as b,
3522
+ Timeline as b0,
3523
+ TimelineContent as b1,
3524
+ TimelineDescription as b2,
3525
+ TimelineDot as b3,
3526
+ TimelineHeading as b4,
3527
+ TimelineItem as b5,
3528
+ TimelineTime as b6,
3529
+ Toggle as b7,
3530
+ ToggleGroup as b8,
3531
+ ToggleGroupItem as b9,
3532
+ TreeView as ba,
3533
+ navigationMenuTriggerStyle as bb,
3534
+ toggleVariants as bc,
3535
+ useFileUpload as bd,
3536
+ useFormField as be,
3537
+ usePagination as bf,
3538
+ useStepper as bg,
3539
+ useStepperContext as bh,
3540
+ useTreeView as bi,
3541
+ AccordionTrigger as c,
3542
+ AspectRatio as d,
3543
+ AssistantChart as e,
3544
+ CalendarDayButton as f,
3545
+ Carousel as g,
3546
+ CarouselContent as h,
3547
+ CarouselItem as i,
3548
+ CarouselNext as j,
3549
+ CarouselPrevious as k,
3550
+ Collapsible as l,
3551
+ CollapsibleContent as m,
3552
+ CollapsibleTrigger as n,
3553
+ Command as o,
3554
+ CommandDialog as p,
3555
+ CommandEmpty as q,
3556
+ CommandGroup as r,
3557
+ CommandInput as s,
3558
+ CommandItem as t,
3559
+ CommandList as u,
3560
+ CommandSeparator as v,
3561
+ CommandShortcut as w,
3562
+ ContextMenu as x,
3563
+ ContextMenuCheckboxItem as y,
3564
+ ContextMenuContent as z
3565
+ };