@ug666/ui-react 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/blocks/index.cjs +238 -0
  2. package/dist/blocks/index.cjs.map +1 -0
  3. package/dist/blocks/index.d.cts +86 -0
  4. package/dist/blocks/index.d.ts +86 -0
  5. package/dist/blocks/index.js +153 -0
  6. package/dist/blocks/index.js.map +1 -0
  7. package/dist/button-CaLZig8j.d.cts +22 -0
  8. package/dist/button-CaLZig8j.d.ts +22 -0
  9. package/dist/chunk-2IVRUJKO.js +377 -0
  10. package/dist/chunk-2IVRUJKO.js.map +1 -0
  11. package/dist/chunk-73WQAE3E.js +3003 -0
  12. package/dist/chunk-73WQAE3E.js.map +1 -0
  13. package/dist/chunk-RUDEZA5Q.js +62 -0
  14. package/dist/chunk-RUDEZA5Q.js.map +1 -0
  15. package/dist/chunk-S45GP6IB.js +254 -0
  16. package/dist/chunk-S45GP6IB.js.map +1 -0
  17. package/dist/components/index.cjs +3993 -0
  18. package/dist/components/index.cjs.map +1 -0
  19. package/dist/components/index.d.cts +1097 -0
  20. package/dist/components/index.d.ts +1097 -0
  21. package/dist/components/index.js +330 -0
  22. package/dist/components/index.js.map +1 -0
  23. package/dist/hooks/index.cjs +1 -0
  24. package/dist/hooks/index.cjs.map +1 -1
  25. package/dist/hooks/index.js +1 -0
  26. package/dist/index.cjs +1410 -710
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +274 -1340
  29. package/dist/index.d.ts +274 -1340
  30. package/dist/index.js +385 -3229
  31. package/dist/index.js.map +1 -1
  32. package/dist/labs/index.cjs +34 -0
  33. package/dist/labs/index.cjs.map +1 -0
  34. package/dist/labs/index.d.cts +12 -0
  35. package/dist/labs/index.d.ts +12 -0
  36. package/dist/labs/index.js +9 -0
  37. package/dist/labs/index.js.map +1 -0
  38. package/dist/patterns/index.cjs +758 -0
  39. package/dist/patterns/index.cjs.map +1 -0
  40. package/dist/patterns/index.d.cts +158 -0
  41. package/dist/patterns/index.d.ts +158 -0
  42. package/dist/patterns/index.js +320 -0
  43. package/dist/patterns/index.js.map +1 -0
  44. package/dist/primitives/index.cjs +384 -0
  45. package/dist/primitives/index.cjs.map +1 -0
  46. package/dist/primitives/index.d.cts +137 -0
  47. package/dist/primitives/index.d.ts +137 -0
  48. package/dist/primitives/index.js +56 -0
  49. package/dist/primitives/index.js.map +1 -0
  50. package/dist/sidebar-vl00Z2o-.d.cts +93 -0
  51. package/dist/sidebar-vl00Z2o-.d.ts +93 -0
  52. package/dist/styles.css +2499 -0
  53. package/dist/tokens.css +86 -9
  54. package/package.json +36 -6
@@ -0,0 +1,3993 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/components/index.ts
22
+ var components_exports = {};
23
+ __export(components_exports, {
24
+ Accordion: () => Accordion,
25
+ AccordionContent: () => AccordionContent,
26
+ AccordionItem: () => AccordionItem,
27
+ AccordionTrigger: () => AccordionTrigger,
28
+ Alert: () => Alert,
29
+ AlertDescription: () => AlertDescription,
30
+ AlertTitle: () => AlertTitle,
31
+ Avatar: () => Avatar,
32
+ AvatarFallback: () => AvatarFallback,
33
+ AvatarGroup: () => AvatarGroup,
34
+ AvatarImage: () => AvatarImage,
35
+ Badge: () => Badge,
36
+ Breadcrumb: () => Breadcrumb,
37
+ BreadcrumbItem: () => BreadcrumbItem,
38
+ BreadcrumbLink: () => BreadcrumbLink,
39
+ BreadcrumbSeparator: () => BreadcrumbSeparator,
40
+ Button: () => Button,
41
+ Card: () => Card,
42
+ CardContent: () => CardContent,
43
+ CardDescription: () => CardDescription,
44
+ CardFooter: () => CardFooter,
45
+ CardHeader: () => CardHeader,
46
+ CardTitle: () => CardTitle,
47
+ Checkbox: () => Checkbox,
48
+ ContextMenu: () => ContextMenu,
49
+ ContextMenuContent: () => ContextMenuContent,
50
+ ContextMenuItem: () => ContextMenuItem,
51
+ ContextMenuSeparator: () => ContextMenuSeparator,
52
+ ContextMenuTrigger: () => ContextMenuTrigger,
53
+ Descriptions: () => Descriptions,
54
+ DescriptionsItem: () => DescriptionsItem,
55
+ Dialog: () => Dialog,
56
+ Drawer: () => Drawer,
57
+ DrawerClose: () => DrawerClose,
58
+ DrawerContent: () => DrawerContent,
59
+ DrawerDescription: () => DrawerDescription,
60
+ DrawerFooter: () => DrawerFooter,
61
+ DrawerHeader: () => DrawerHeader,
62
+ DrawerTitle: () => DrawerTitle,
63
+ DropdownContent: () => DropdownContent,
64
+ DropdownItem: () => DropdownItem,
65
+ DropdownMenu: () => DropdownMenu,
66
+ DropdownSeparator: () => DropdownSeparator,
67
+ DropdownTrigger: () => DropdownTrigger,
68
+ EmptyState: () => EmptyState,
69
+ Form: () => Form,
70
+ FormControl: () => FormControl,
71
+ FormDescription: () => FormDescription,
72
+ FormField: () => FormField,
73
+ FormItem: () => FormItem,
74
+ FormLabel: () => FormLabel,
75
+ FormMessage: () => FormMessage,
76
+ Input: () => Input,
77
+ Label: () => Label,
78
+ Modal: () => Modal,
79
+ ModalCloseButton: () => ModalCloseButton,
80
+ ModalContent: () => ModalContent,
81
+ ModalFooter: () => ModalFooter,
82
+ ModalHeader: () => ModalHeader,
83
+ ModalTitle: () => ModalTitle,
84
+ NavigationMenu: () => NavigationMenu,
85
+ NavigationMenuContent: () => NavigationMenuContent,
86
+ NavigationMenuItem: () => NavigationMenuItem,
87
+ NavigationMenuLink: () => NavigationMenuLink,
88
+ NavigationMenuTrigger: () => NavigationMenuTrigger,
89
+ NumberInput: () => NumberInput,
90
+ OTPInput: () => OTPInput,
91
+ Pagination: () => Pagination,
92
+ Popover: () => Popover,
93
+ PopoverContent: () => PopoverContent,
94
+ PopoverTrigger: () => PopoverTrigger,
95
+ Progress: () => Progress,
96
+ Radio: () => Radio,
97
+ RadioGroup: () => RadioGroup,
98
+ Select: () => Select,
99
+ Separator: () => Separator,
100
+ Sheet: () => Sheet,
101
+ Sidebar: () => Sidebar,
102
+ Skeleton: () => Skeleton,
103
+ Slider: () => Slider,
104
+ Spinner: () => Spinner,
105
+ Statistic: () => Statistic,
106
+ Steps: () => Steps,
107
+ Switch: () => Switch,
108
+ Table: () => Table,
109
+ TableBody: () => TableBody,
110
+ TableCell: () => TableCell,
111
+ TableHead: () => TableHead,
112
+ TableHeader: () => TableHeader,
113
+ TableRow: () => TableRow,
114
+ Tabs: () => Tabs,
115
+ TabsContent: () => TabsContent,
116
+ TabsList: () => TabsList,
117
+ TabsTrigger: () => TabsTrigger,
118
+ Tag: () => Tag,
119
+ Textarea: () => Textarea,
120
+ Toaster: () => Toaster,
121
+ Tooltip: () => Tooltip,
122
+ TooltipContent: () => TooltipContent,
123
+ TooltipTrigger: () => TooltipTrigger,
124
+ UGAccordion: () => Accordion,
125
+ UGAccordionContent: () => AccordionContent,
126
+ UGAccordionItem: () => AccordionItem,
127
+ UGAccordionTrigger: () => AccordionTrigger,
128
+ UGAlert: () => Alert,
129
+ UGAlertDescription: () => AlertDescription,
130
+ UGAlertTitle: () => AlertTitle,
131
+ UGAvatar: () => Avatar,
132
+ UGAvatarFallback: () => AvatarFallback,
133
+ UGAvatarGroup: () => AvatarGroup,
134
+ UGAvatarImage: () => AvatarImage,
135
+ UGBadge: () => Badge,
136
+ UGBreadcrumb: () => Breadcrumb,
137
+ UGBreadcrumbItem: () => BreadcrumbItem,
138
+ UGBreadcrumbLink: () => BreadcrumbLink,
139
+ UGBreadcrumbSeparator: () => BreadcrumbSeparator,
140
+ UGButton: () => Button,
141
+ UGCard: () => Card,
142
+ UGCardContent: () => CardContent,
143
+ UGCardDescription: () => CardDescription,
144
+ UGCardFooter: () => CardFooter,
145
+ UGCardHeader: () => CardHeader,
146
+ UGCardTitle: () => CardTitle,
147
+ UGCheckbox: () => Checkbox,
148
+ UGContextMenu: () => ContextMenu,
149
+ UGContextMenuContent: () => ContextMenuContent,
150
+ UGContextMenuItem: () => ContextMenuItem,
151
+ UGContextMenuSeparator: () => ContextMenuSeparator,
152
+ UGContextMenuTrigger: () => ContextMenuTrigger,
153
+ UGDescriptions: () => Descriptions,
154
+ UGDescriptionsItem: () => DescriptionsItem,
155
+ UGDialog: () => Dialog,
156
+ UGDrawer: () => Drawer,
157
+ UGDrawerClose: () => DrawerClose,
158
+ UGDrawerContent: () => DrawerContent,
159
+ UGDrawerDescription: () => DrawerDescription,
160
+ UGDrawerFooter: () => DrawerFooter,
161
+ UGDrawerHeader: () => DrawerHeader,
162
+ UGDrawerTitle: () => DrawerTitle,
163
+ UGDropdown: () => DropdownMenu,
164
+ UGDropdownContent: () => DropdownContent,
165
+ UGDropdownItem: () => DropdownItem,
166
+ UGDropdownMenu: () => DropdownMenu,
167
+ UGDropdownSeparator: () => DropdownSeparator,
168
+ UGDropdownTrigger: () => DropdownTrigger,
169
+ UGEmptyState: () => EmptyState,
170
+ UGForm: () => Form,
171
+ UGFormControl: () => FormControl,
172
+ UGFormDescription: () => FormDescription,
173
+ UGFormField: () => FormField,
174
+ UGFormItem: () => FormItem,
175
+ UGFormLabel: () => FormLabel,
176
+ UGFormMessage: () => FormMessage,
177
+ UGInput: () => Input,
178
+ UGLabel: () => Label,
179
+ UGModal: () => Modal,
180
+ UGModalCloseButton: () => ModalCloseButton,
181
+ UGModalContent: () => ModalContent,
182
+ UGModalFooter: () => ModalFooter,
183
+ UGModalHeader: () => ModalHeader,
184
+ UGModalTitle: () => ModalTitle,
185
+ UGNavigationMenu: () => NavigationMenu,
186
+ UGNavigationMenuContent: () => NavigationMenuContent,
187
+ UGNavigationMenuItem: () => NavigationMenuItem,
188
+ UGNavigationMenuLink: () => NavigationMenuLink,
189
+ UGNavigationMenuTrigger: () => NavigationMenuTrigger,
190
+ UGNumberInput: () => NumberInput,
191
+ UGOTPInput: () => OTPInput,
192
+ UGPagination: () => Pagination,
193
+ UGPopover: () => Popover,
194
+ UGPopoverContent: () => PopoverContent,
195
+ UGPopoverTrigger: () => PopoverTrigger,
196
+ UGProgress: () => Progress,
197
+ UGRadio: () => Radio,
198
+ UGRadioGroup: () => RadioGroup,
199
+ UGSelect: () => Select,
200
+ UGSeparator: () => Separator,
201
+ UGSheet: () => Sheet,
202
+ UGSidebar: () => Sidebar,
203
+ UGSkeleton: () => Skeleton,
204
+ UGSlider: () => Slider,
205
+ UGSpinner: () => Spinner,
206
+ UGStatistic: () => Statistic,
207
+ UGSteps: () => Steps,
208
+ UGSwitch: () => Switch,
209
+ UGTable: () => Table,
210
+ UGTableBody: () => TableBody,
211
+ UGTableCell: () => TableCell,
212
+ UGTableHead: () => TableHead,
213
+ UGTableHeader: () => TableHeader,
214
+ UGTableRow: () => TableRow,
215
+ UGTabs: () => Tabs,
216
+ UGTabsContent: () => TabsContent,
217
+ UGTabsList: () => TabsList,
218
+ UGTabsTrigger: () => TabsTrigger,
219
+ UGTag: () => Tag,
220
+ UGTextarea: () => Textarea,
221
+ UGToaster: () => Toaster,
222
+ UGTooltip: () => Tooltip,
223
+ UGTooltipContent: () => TooltipContent,
224
+ UGTooltipTrigger: () => TooltipTrigger,
225
+ badgeVariants: () => badgeVariants,
226
+ buttonVariants: () => buttonVariants,
227
+ checkboxVariants: () => checkboxVariants,
228
+ numberInputVariants: () => numberInputVariants,
229
+ tagVariants: () => tagVariants,
230
+ toast: () => toast,
231
+ ugBadgeVariants: () => badgeVariants,
232
+ ugButtonVariants: () => buttonVariants,
233
+ ugCheckboxVariants: () => checkboxVariants,
234
+ ugNumberInputVariants: () => numberInputVariants,
235
+ ugTagVariants: () => tagVariants
236
+ });
237
+ module.exports = __toCommonJS(components_exports);
238
+
239
+ // src/components/button.tsx
240
+ var import_react = require("react");
241
+ var import_lucide_react = require("lucide-react");
242
+ var import_class_variance_authority = require("class-variance-authority");
243
+
244
+ // src/internal/cn.ts
245
+ var import_clsx = require("clsx");
246
+ var import_tailwind_merge = require("tailwind-merge");
247
+ function cn(...inputs) {
248
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
249
+ }
250
+
251
+ // src/components/button.tsx
252
+ var import_jsx_runtime = require("react/jsx-runtime");
253
+ var buttonVariants = (0, import_class_variance_authority.cva)(
254
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-[background,border-color,color,box-shadow,transform] duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
255
+ {
256
+ variants: {
257
+ variant: {
258
+ default: "bg-primary text-primary-fg shadow-sm hover:bg-primary-hover hover:shadow-md focus-visible:ring-ring",
259
+ destructive: "bg-danger text-danger-fg shadow-sm hover:bg-danger-hover hover:shadow-md focus-visible:ring-danger",
260
+ outline: "border border-border-strong bg-surface-1 text-text-primary shadow-sm hover:border-primary/55 hover:bg-surface-2 focus-visible:ring-ring/30",
261
+ secondary: "border border-border-base bg-surface-2 text-text-primary shadow-sm hover:bg-surface-3 focus-visible:ring-ring/30",
262
+ ghost: "text-text-primary hover:bg-surface-2 focus-visible:ring-ring/30",
263
+ link: "text-text-primary underline-offset-4 hover:underline focus-visible:ring-ring/30"
264
+ },
265
+ size: {
266
+ default: "h-9 px-4 py-2",
267
+ sm: "h-8 px-3 text-xs",
268
+ lg: "h-11 px-5 text-base",
269
+ icon: "h-9 w-9"
270
+ }
271
+ },
272
+ defaultVariants: {
273
+ variant: "default",
274
+ size: "default"
275
+ }
276
+ }
277
+ );
278
+ var Button = (0, import_react.forwardRef)(
279
+ ({ className, variant, size, loading = false, disabled, children, ...props }, ref) => {
280
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
281
+ "button",
282
+ {
283
+ ref,
284
+ className: cn(buttonVariants({ variant, size }), className),
285
+ disabled: disabled || loading,
286
+ ...props,
287
+ children: [
288
+ loading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "animate-spin", size: 16 }),
289
+ children
290
+ ]
291
+ }
292
+ );
293
+ }
294
+ );
295
+ Button.displayName = "Button";
296
+
297
+ // src/components/input.tsx
298
+ var import_react2 = require("react");
299
+ var import_jsx_runtime2 = require("react/jsx-runtime");
300
+ var Input = (0, import_react2.forwardRef)(
301
+ ({ className, label, error, helperText, id, ...props }, ref) => {
302
+ const generatedId = (0, import_react2.useId)();
303
+ const inputId = id ?? generatedId;
304
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col gap-1", children: [
305
+ label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
306
+ "label",
307
+ {
308
+ htmlFor: inputId,
309
+ className: "text-sm font-medium text-text-primary",
310
+ children: label
311
+ }
312
+ ),
313
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
314
+ "input",
315
+ {
316
+ ref,
317
+ id: inputId,
318
+ className: cn(
319
+ "flex h-9 w-full rounded-md border bg-surface-1 px-3 py-2 text-sm text-text-primary placeholder:text-text-tertiary",
320
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
321
+ "disabled:cursor-not-allowed disabled:opacity-50",
322
+ error ? "border-danger focus-visible:ring-danger" : "border-border-strong focus-visible:ring-ring/30",
323
+ className
324
+ ),
325
+ ...props
326
+ }
327
+ ),
328
+ error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-danger", children: error }),
329
+ !error && helperText && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-text-secondary", children: helperText })
330
+ ] });
331
+ }
332
+ );
333
+ Input.displayName = "Input";
334
+
335
+ // src/components/label.tsx
336
+ var import_react3 = require("react");
337
+ var import_jsx_runtime3 = require("react/jsx-runtime");
338
+ var Label = (0, import_react3.forwardRef)(({ className, required, children, ...props }, ref) => {
339
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
340
+ "label",
341
+ {
342
+ ref,
343
+ className: cn(
344
+ "leading-none text-sm font-medium text-text-primary peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
345
+ className
346
+ ),
347
+ ...props,
348
+ children: [
349
+ children,
350
+ required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "ml-0.5 text-danger", "aria-hidden": "true", children: "*" })
351
+ ]
352
+ }
353
+ );
354
+ });
355
+ Label.displayName = "Label";
356
+
357
+ // src/components/card.tsx
358
+ var import_react4 = require("react");
359
+ var import_jsx_runtime4 = require("react/jsx-runtime");
360
+ var Card = (0, import_react4.forwardRef)(({ className, ...props }, ref) => {
361
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("rounded-lg border border-border-base bg-surface-1 shadow-sm", className), ...props });
362
+ });
363
+ var CardHeader = (0, import_react4.forwardRef)(({ className, ...props }, ref) => {
364
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("flex flex-col gap-1 px-5 py-4 border-b border-border-base", className), ...props });
365
+ });
366
+ var CardTitle = (0, import_react4.forwardRef)(({ className, ...props }, ref) => {
367
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { ref, className: cn("leading-none font-semibold text-text-primary", className), ...props });
368
+ });
369
+ var CardDescription = (0, import_react4.forwardRef)(({ className, ...props }, ref) => {
370
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { ref, className: cn("text-sm text-text-secondary", className), ...props });
371
+ });
372
+ var CardContent = (0, import_react4.forwardRef)(({ className, ...props }, ref) => {
373
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("px-5 py-4", className), ...props });
374
+ });
375
+ var CardFooter = (0, import_react4.forwardRef)(({ className, ...props }, ref) => {
376
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("flex items-center px-5 py-4 border-t border-border-base", className), ...props });
377
+ });
378
+ Card.displayName = "Card";
379
+ CardHeader.displayName = "CardHeader";
380
+ CardTitle.displayName = "CardTitle";
381
+ CardDescription.displayName = "CardDescription";
382
+ CardContent.displayName = "CardContent";
383
+ CardFooter.displayName = "CardFooter";
384
+
385
+ // src/components/badge.tsx
386
+ var import_react5 = require("react");
387
+ var import_class_variance_authority2 = require("class-variance-authority");
388
+ var import_jsx_runtime5 = require("react/jsx-runtime");
389
+ var badgeVariants = (0, import_class_variance_authority2.cva)(
390
+ "inline-flex min-h-6 items-center rounded-md px-2.5 py-0.5 text-xs font-semibold leading-none transition-colors",
391
+ {
392
+ variants: {
393
+ variant: {
394
+ default: "border border-primary/20 bg-primary-soft text-primary-soft-fg",
395
+ secondary: "border border-border-base bg-surface-2 text-text-primary",
396
+ destructive: "border border-danger/20 bg-danger-soft text-danger-soft-fg",
397
+ outline: "border border-border-strong bg-transparent text-text-primary",
398
+ success: "border border-success/20 bg-success-soft text-success-soft-fg",
399
+ warning: "border border-warning/20 bg-warning-soft text-warning-soft-fg"
400
+ }
401
+ },
402
+ defaultVariants: {
403
+ variant: "default"
404
+ }
405
+ }
406
+ );
407
+ var Badge = (0, import_react5.forwardRef)(({ className, variant, ...props }, ref) => {
408
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { ref, className: cn(badgeVariants({ variant }), className), ...props });
409
+ });
410
+ Badge.displayName = "Badge";
411
+
412
+ // src/components/tag.tsx
413
+ var import_react6 = require("react");
414
+ var import_lucide_react2 = require("lucide-react");
415
+ var import_class_variance_authority3 = require("class-variance-authority");
416
+ var import_jsx_runtime6 = require("react/jsx-runtime");
417
+ var tagVariants = (0, import_class_variance_authority3.cva)(
418
+ "inline-flex items-center gap-1.5 rounded-md border font-medium leading-none transition-colors",
419
+ {
420
+ variants: {
421
+ variant: {
422
+ default: "border-border-base bg-surface-2 text-text-primary",
423
+ primary: "border-primary/20 bg-primary-soft text-primary-soft-fg",
424
+ success: "border-success/20 bg-success-soft text-success-soft-fg",
425
+ warning: "border-warning/20 bg-warning-soft text-warning-soft-fg",
426
+ destructive: "border-danger/20 bg-danger-soft text-danger-soft-fg",
427
+ outline: "border-border-strong bg-transparent text-text-primary"
428
+ },
429
+ size: {
430
+ sm: "min-h-6 px-2 text-[11px]",
431
+ default: "min-h-7 px-2.5 text-xs"
432
+ }
433
+ },
434
+ defaultVariants: {
435
+ variant: "default",
436
+ size: "default"
437
+ }
438
+ }
439
+ );
440
+ var Tag = (0, import_react6.forwardRef)(
441
+ ({ variant, size, closable = false, disabled = false, color, onClose, className, children, style, ...props }, ref) => {
442
+ const customStyle = color ? { backgroundColor: color, color: "hsl(var(--primary-fg))", borderColor: color, ...style } : style ?? {};
443
+ function handleClose(event) {
444
+ event.stopPropagation();
445
+ if (!disabled) {
446
+ onClose?.(event);
447
+ }
448
+ }
449
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
450
+ "span",
451
+ {
452
+ ref,
453
+ className: cn(tagVariants({ variant, size }), disabled && "cursor-not-allowed opacity-50", className),
454
+ style: customStyle,
455
+ ...props,
456
+ children: [
457
+ children,
458
+ closable && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
459
+ "button",
460
+ {
461
+ type: "button",
462
+ onClick: handleClose,
463
+ disabled,
464
+ className: "-mr-1 inline-flex h-4 w-4 items-center justify-center rounded-sm opacity-70 transition hover:bg-surface-3 hover:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-current disabled:pointer-events-none",
465
+ "aria-label": "\u5173\u95ED\u6807\u7B7E",
466
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react2.X, { size: 10, strokeWidth: 2.5 })
467
+ }
468
+ )
469
+ ]
470
+ }
471
+ );
472
+ }
473
+ );
474
+ Tag.displayName = "Tag";
475
+
476
+ // src/components/modal.tsx
477
+ var import_react9 = require("react");
478
+ var import_react_dom = require("react-dom");
479
+ var import_lucide_react3 = require("lucide-react");
480
+
481
+ // src/hooks/use-escape-key.ts
482
+ var import_react7 = require("react");
483
+ function useEscapeKey(open, onEscape) {
484
+ const handleEscape = (0, import_react7.useCallback)(
485
+ (e) => {
486
+ if (e.key === "Escape") onEscape();
487
+ },
488
+ [onEscape]
489
+ );
490
+ (0, import_react7.useEffect)(() => {
491
+ if (!open || typeof document === "undefined") return;
492
+ document.addEventListener("keydown", handleEscape);
493
+ document.body.style.overflow = "hidden";
494
+ return () => {
495
+ document.removeEventListener("keydown", handleEscape);
496
+ document.body.style.overflow = "";
497
+ };
498
+ }, [open, handleEscape]);
499
+ }
500
+
501
+ // src/internal/use-portal-container.ts
502
+ var import_react8 = require("react");
503
+ function usePortalContainer() {
504
+ const [container, setContainer] = (0, import_react8.useState)(null);
505
+ (0, import_react8.useEffect)(() => {
506
+ if (typeof document === "undefined") return;
507
+ setContainer(document.body);
508
+ }, []);
509
+ return container;
510
+ }
511
+
512
+ // src/components/modal.tsx
513
+ var import_jsx_runtime7 = require("react/jsx-runtime");
514
+ var Modal = (0, import_react9.forwardRef)(({ open, onClose, children, className }, ref) => {
515
+ useEscapeKey(open, onClose);
516
+ const portalContainer = usePortalContainer();
517
+ if (!open || !portalContainer) return null;
518
+ return (0, import_react_dom.createPortal)(
519
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
520
+ "div",
521
+ {
522
+ ref,
523
+ className: cn(
524
+ "fixed inset-0 z-[80] flex items-center justify-center p-4",
525
+ className
526
+ ),
527
+ role: "dialog",
528
+ "aria-modal": "true",
529
+ children: [
530
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
531
+ "div",
532
+ {
533
+ className: "absolute inset-0 bg-overlay",
534
+ onClick: onClose,
535
+ "aria-hidden": "true"
536
+ }
537
+ ),
538
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "relative z-10", children })
539
+ ]
540
+ }
541
+ ),
542
+ portalContainer
543
+ );
544
+ });
545
+ var ModalContent = (0, import_react9.forwardRef)(({ className, maxWidth = "max-w-lg", children, ...props }, ref) => {
546
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn("flex max-h-[85vh] w-full flex-col rounded-lg border border-border-base bg-surface-1 shadow-xl", maxWidth, className), ...props, children });
547
+ });
548
+ var ModalHeader = (0, import_react9.forwardRef)(({ className, ...props }, ref) => {
549
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn("flex shrink-0 items-center justify-between border-b border-border-base px-6 py-4", className), ...props });
550
+ });
551
+ var ModalTitle = (0, import_react9.forwardRef)(({ className, ...props }, ref) => {
552
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { ref, className: cn("text-lg font-semibold text-text-primary", className), ...props });
553
+ });
554
+ var ModalFooter = (0, import_react9.forwardRef)(({ className, ...props }, ref) => {
555
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref, className: cn("flex shrink-0 items-center justify-end gap-2 border-t border-border-base px-6 py-4", className), ...props });
556
+ });
557
+ var ModalCloseButton = (0, import_react9.forwardRef)(({ onClick, className, type = "button", ...props }, ref) => {
558
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
559
+ "button",
560
+ {
561
+ ref,
562
+ type,
563
+ onClick,
564
+ className: cn(
565
+ "rounded-md p-1 text-text-tertiary transition-colors hover:bg-surface-3 hover:text-text-secondary",
566
+ className
567
+ ),
568
+ "aria-label": "\u5173\u95ED",
569
+ ...props,
570
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react3.X, { size: 18 })
571
+ }
572
+ );
573
+ });
574
+ Modal.displayName = "Modal";
575
+ ModalContent.displayName = "ModalContent";
576
+ ModalHeader.displayName = "ModalHeader";
577
+ ModalTitle.displayName = "ModalTitle";
578
+ ModalFooter.displayName = "ModalFooter";
579
+ ModalCloseButton.displayName = "ModalCloseButton";
580
+
581
+ // src/components/dialog.tsx
582
+ var import_react10 = require("react");
583
+ var import_react_dom2 = require("react-dom");
584
+ var import_jsx_runtime8 = require("react/jsx-runtime");
585
+ var CONFIRM_VARIANT_CLASSES = {
586
+ default: "bg-primary text-primary-fg hover:bg-primary-hover focus-visible:ring-ring",
587
+ destructive: "bg-danger text-danger-fg hover:bg-danger-hover focus-visible:ring-danger"
588
+ };
589
+ var Dialog = (0, import_react10.forwardRef)(
590
+ ({
591
+ open,
592
+ onOpenChange,
593
+ title,
594
+ description,
595
+ variant = "default",
596
+ cancelText = "\u53D6\u6D88",
597
+ confirmText = "\u786E\u8BA4",
598
+ onConfirm,
599
+ onCancel,
600
+ className
601
+ }, ref) => {
602
+ const portalContainer = usePortalContainer();
603
+ const handleClose = (0, import_react10.useCallback)(() => {
604
+ onOpenChange(false);
605
+ }, [onOpenChange]);
606
+ const handleCancel = (0, import_react10.useCallback)(() => {
607
+ onCancel?.();
608
+ handleClose();
609
+ }, [onCancel, handleClose]);
610
+ const handleConfirm = (0, import_react10.useCallback)(() => {
611
+ onConfirm?.();
612
+ handleClose();
613
+ }, [onConfirm, handleClose]);
614
+ useEscapeKey(open, handleCancel);
615
+ if (!open || !portalContainer) return null;
616
+ return (0, import_react_dom2.createPortal)(
617
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
618
+ "div",
619
+ {
620
+ ref,
621
+ className: cn(
622
+ "fixed inset-0 z-[90] flex items-center justify-center p-4",
623
+ className
624
+ ),
625
+ role: "alertdialog",
626
+ "aria-modal": "true",
627
+ "aria-labelledby": "dialog-title",
628
+ "aria-describedby": description ? "dialog-description" : void 0,
629
+ children: [
630
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
631
+ "div",
632
+ {
633
+ className: "absolute inset-0 bg-overlay",
634
+ onClick: handleCancel,
635
+ "aria-hidden": "true"
636
+ }
637
+ ),
638
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "relative z-10 w-full max-w-sm rounded-lg border border-border-base bg-surface-1 shadow-xl", children: [
639
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "px-6 pt-6 pb-4", children: [
640
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
641
+ "h2",
642
+ {
643
+ id: "dialog-title",
644
+ className: "text-base font-bold text-text-primary",
645
+ children: title
646
+ }
647
+ ),
648
+ description && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
649
+ "p",
650
+ {
651
+ id: "dialog-description",
652
+ className: "mt-2 text-sm text-text-secondary",
653
+ children: description
654
+ }
655
+ )
656
+ ] }),
657
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-end gap-2 border-t border-border-subtle px-6 py-4", children: [
658
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
659
+ "button",
660
+ {
661
+ type: "button",
662
+ onClick: handleCancel,
663
+ className: cn(
664
+ "inline-flex h-9 items-center justify-center rounded-md border border-border-strong bg-surface-1 px-4 text-sm font-medium text-text-secondary transition-colors",
665
+ "hover:bg-surface-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-ring/30"
666
+ ),
667
+ children: cancelText
668
+ }
669
+ ),
670
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
671
+ "button",
672
+ {
673
+ type: "button",
674
+ onClick: handleConfirm,
675
+ className: cn(
676
+ "inline-flex h-9 items-center justify-center rounded-md px-4 text-sm font-medium transition-colors",
677
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
678
+ CONFIRM_VARIANT_CLASSES[variant]
679
+ ),
680
+ children: confirmText
681
+ }
682
+ )
683
+ ] })
684
+ ] })
685
+ ]
686
+ }
687
+ ),
688
+ portalContainer
689
+ );
690
+ }
691
+ );
692
+ Dialog.displayName = "Dialog";
693
+
694
+ // src/components/drawer.tsx
695
+ var import_react11 = require("react");
696
+ var import_react_dom3 = require("react-dom");
697
+ var import_lucide_react4 = require("lucide-react");
698
+ var import_jsx_runtime9 = require("react/jsx-runtime");
699
+ var DrawerContext = (0, import_react11.createContext)(null);
700
+ function useDrawerContext() {
701
+ const ctx = (0, import_react11.useContext)(DrawerContext);
702
+ if (!ctx) throw new Error("Drawer \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <Drawer> \u5185\u4F7F\u7528");
703
+ return ctx;
704
+ }
705
+ var SIDE_CLASSES = {
706
+ right: "inset-y-0 right-0 h-full w-80 max-w-full translate-x-0",
707
+ left: "inset-y-0 left-0 h-full w-80 max-w-full translate-x-0",
708
+ top: "inset-x-0 top-0 w-full h-auto max-h-[80vh] translate-y-0",
709
+ bottom: "inset-x-0 bottom-0 w-full h-auto max-h-[80vh] translate-y-0"
710
+ };
711
+ var Drawer = ({ open, onOpenChange, side = "right", children }) => {
712
+ useEscapeKey(open, () => onOpenChange(false));
713
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DrawerContext.Provider, { value: { open, onOpenChange, side }, children });
714
+ };
715
+ Drawer.displayName = "Drawer";
716
+ var DrawerContent = (0, import_react11.forwardRef)(({ className, children, ...props }, ref) => {
717
+ const { open, onOpenChange, side } = useDrawerContext();
718
+ const portalContainer = usePortalContainer();
719
+ if (!open || !portalContainer) return null;
720
+ return (0, import_react_dom3.createPortal)(
721
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "fixed inset-0 z-50", role: "dialog", "aria-modal": "true", children: [
722
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
723
+ "div",
724
+ {
725
+ className: "absolute inset-0 bg-overlay transition-opacity",
726
+ onClick: () => onOpenChange(false),
727
+ "aria-hidden": "true"
728
+ }
729
+ ),
730
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
731
+ "div",
732
+ {
733
+ ref,
734
+ className: cn(
735
+ "absolute flex flex-col bg-surface-1 shadow-xl transition-transform duration-300 ease-in-out",
736
+ SIDE_CLASSES[side],
737
+ className
738
+ ),
739
+ onClick: (e) => e.stopPropagation(),
740
+ ...props,
741
+ children
742
+ }
743
+ )
744
+ ] }),
745
+ portalContainer
746
+ );
747
+ });
748
+ DrawerContent.displayName = "DrawerContent";
749
+ var DrawerHeader = (0, import_react11.forwardRef)(({ className, ...props }, ref) => {
750
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
751
+ "div",
752
+ {
753
+ ref,
754
+ className: cn("flex flex-col gap-1.5 border-b border-border-base px-6 py-4", className),
755
+ ...props
756
+ }
757
+ );
758
+ });
759
+ DrawerHeader.displayName = "DrawerHeader";
760
+ var DrawerTitle = (0, import_react11.forwardRef)(({ className, ...props }, ref) => {
761
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { ref, className: cn("text-lg font-semibold text-text-primary", className), ...props });
762
+ });
763
+ DrawerTitle.displayName = "DrawerTitle";
764
+ var DrawerDescription = (0, import_react11.forwardRef)(({ className, ...props }, ref) => {
765
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { ref, className: cn("text-sm text-text-secondary", className), ...props });
766
+ });
767
+ DrawerDescription.displayName = "DrawerDescription";
768
+ var DrawerFooter = (0, import_react11.forwardRef)(({ className, ...props }, ref) => {
769
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
770
+ "div",
771
+ {
772
+ ref,
773
+ className: cn("mt-auto flex items-center justify-end gap-2 border-t border-border-base px-6 py-4", className),
774
+ ...props
775
+ }
776
+ );
777
+ });
778
+ DrawerFooter.displayName = "DrawerFooter";
779
+ var DrawerClose = (0, import_react11.forwardRef)(({ className, children, type = "button", ...props }, ref) => {
780
+ const { onOpenChange } = useDrawerContext();
781
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
782
+ "button",
783
+ {
784
+ ref,
785
+ type,
786
+ onClick: () => onOpenChange(false),
787
+ className: cn(
788
+ "inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium text-text-secondary transition-colors hover:bg-surface-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30",
789
+ className
790
+ ),
791
+ ...props,
792
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.X, { size: 18 })
793
+ }
794
+ );
795
+ });
796
+ DrawerClose.displayName = "DrawerClose";
797
+
798
+ // src/components/table.tsx
799
+ var import_react12 = require("react");
800
+ var import_jsx_runtime10 = require("react/jsx-runtime");
801
+ var Table = (0, import_react12.forwardRef)(({ className, ...props }, ref) => {
802
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "w-full overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
803
+ "table",
804
+ {
805
+ ref,
806
+ className: cn("w-full caption-bottom text-sm", className),
807
+ ...props
808
+ }
809
+ ) });
810
+ });
811
+ var TableHeader = (0, import_react12.forwardRef)(({ className, ...props }, ref) => {
812
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("thead", { ref, className: cn("[&_tr]:border-b border-border-base", className), ...props });
813
+ });
814
+ var TableBody = (0, import_react12.forwardRef)(({ className, ...props }, ref) => {
815
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props });
816
+ });
817
+ var TableRow = (0, import_react12.forwardRef)(({ className, ...props }, ref) => {
818
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { ref, className: cn("border-b border-border-base transition-colors hover:bg-surface-2", className), ...props });
819
+ });
820
+ var TableHead = (0, import_react12.forwardRef)(({ className, ...props }, ref) => {
821
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("th", { ref, className: cn("h-10 px-4 text-left align-middle font-medium text-text-secondary [&:has([role=checkbox])]:pr-0", className), ...props });
822
+ });
823
+ var TableCell = (0, import_react12.forwardRef)(({ className, ...props }, ref) => {
824
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { ref, className: cn("px-4 py-3 align-middle text-text-primary [&:has([role=checkbox])]:pr-0", className), ...props });
825
+ });
826
+ Table.displayName = "Table";
827
+ TableHeader.displayName = "TableHeader";
828
+ TableBody.displayName = "TableBody";
829
+ TableRow.displayName = "TableRow";
830
+ TableHead.displayName = "TableHead";
831
+ TableCell.displayName = "TableCell";
832
+
833
+ // src/components/toast.tsx
834
+ var import_react13 = require("react");
835
+ var import_react_dom4 = require("react-dom");
836
+ var import_lucide_react5 = require("lucide-react");
837
+ var import_jsx_runtime11 = require("react/jsx-runtime");
838
+ var listeners = /* @__PURE__ */ new Set();
839
+ var toastItems = [];
840
+ var toastTimers = /* @__PURE__ */ new Map();
841
+ function notify() {
842
+ listeners.forEach((fn) => fn([...toastItems]));
843
+ }
844
+ function addToast(message, type) {
845
+ const id = Math.random().toString(36).slice(2);
846
+ toastItems = [...toastItems, { id, message, type }];
847
+ notify();
848
+ const timer = setTimeout(() => removeToast(id), 3e3);
849
+ toastTimers.set(id, timer);
850
+ }
851
+ function removeToast(id) {
852
+ const timer = toastTimers.get(id);
853
+ if (timer) {
854
+ clearTimeout(timer);
855
+ toastTimers.delete(id);
856
+ }
857
+ toastItems = toastItems.filter((t) => t.id !== id);
858
+ notify();
859
+ }
860
+ var toast = {
861
+ success: (message) => addToast(message, "success"),
862
+ error: (message) => addToast(message, "error"),
863
+ info: (message) => addToast(message, "info")
864
+ };
865
+ var typeStyles = {
866
+ success: "bg-success-soft border-success/30 text-success-soft-fg",
867
+ error: "bg-danger-soft border-danger/30 text-danger-soft-fg",
868
+ info: "bg-info-soft border-info/30 text-info-soft-fg"
869
+ };
870
+ var typeLabel = {
871
+ success: "\u6210\u529F",
872
+ error: "\u9519\u8BEF",
873
+ info: "\u63D0\u793A"
874
+ };
875
+ var Toaster = (0, import_react13.forwardRef)(({ className, ...props }, ref) => {
876
+ const [items, setItems] = (0, import_react13.useState)([]);
877
+ const mountedRef = (0, import_react13.useRef)(true);
878
+ const portalContainer = usePortalContainer();
879
+ const handleUpdate = (0, import_react13.useCallback)((next) => {
880
+ if (mountedRef.current) {
881
+ setItems(next);
882
+ }
883
+ }, []);
884
+ (0, import_react13.useEffect)(() => {
885
+ listeners.add(handleUpdate);
886
+ return () => {
887
+ mountedRef.current = false;
888
+ listeners.delete(handleUpdate);
889
+ };
890
+ }, [handleUpdate]);
891
+ if (items.length === 0 || !portalContainer) return null;
892
+ return (0, import_react_dom4.createPortal)(
893
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
894
+ "div",
895
+ {
896
+ ref,
897
+ className: cn("fixed top-4 right-4 z-[9999] flex w-80 flex-col gap-2", className),
898
+ role: "region",
899
+ "aria-label": "\u901A\u77E5",
900
+ ...props,
901
+ children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
902
+ "div",
903
+ {
904
+ className: cn(
905
+ "flex items-start justify-between gap-2 rounded-md border px-4 py-3 text-sm shadow-md",
906
+ typeStyles[item.type]
907
+ ),
908
+ role: "alert",
909
+ children: [
910
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
911
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-semibold", children: [
912
+ typeLabel[item.type],
913
+ "\uFF1A"
914
+ ] }),
915
+ item.message
916
+ ] }),
917
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
918
+ "button",
919
+ {
920
+ type: "button",
921
+ onClick: () => removeToast(item.id),
922
+ className: "mt-0.5 shrink-0 opacity-60 hover:opacity-100 transition-opacity",
923
+ "aria-label": "\u5173\u95ED\u901A\u77E5",
924
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react5.X, { size: 14 })
925
+ }
926
+ )
927
+ ]
928
+ },
929
+ item.id
930
+ ))
931
+ }
932
+ ),
933
+ portalContainer
934
+ );
935
+ });
936
+ Toaster.displayName = "Toaster";
937
+
938
+ // src/components/sidebar.tsx
939
+ var import_react14 = require("react");
940
+ var import_lucide_react6 = require("lucide-react");
941
+ var import_jsx_runtime12 = require("react/jsx-runtime");
942
+ var variantStyles = {
943
+ primary: {
944
+ container: "border-r border-border-base bg-surface-1 text-text-primary shadow-sm",
945
+ active: "bg-primary/10 text-primary shadow-sm ring-1 ring-primary/20 before:absolute before:left-0 before:top-1/2 before:h-6 before:w-[3px] before:-translate-y-1/2 before:rounded-r-full before:bg-primary",
946
+ inactive: "text-text-secondary hover:bg-surface-2 hover:text-text-primary",
947
+ divider: "border-border-base",
948
+ icon: "bg-transparent text-text-tertiary group-hover:bg-surface-3 group-hover:text-primary",
949
+ activeIcon: "bg-primary/15 text-primary"
950
+ },
951
+ dark: {
952
+ container: "border-r border-border-base bg-surface-1 text-text-primary shadow-sm",
953
+ active: "bg-primary/10 text-primary shadow-sm ring-1 ring-primary/20 before:absolute before:left-0 before:top-1/2 before:h-6 before:w-[3px] before:-translate-y-1/2 before:rounded-r-full before:bg-primary",
954
+ inactive: "text-text-secondary hover:bg-surface-2 hover:text-text-primary",
955
+ divider: "border-border-base",
956
+ icon: "bg-transparent text-text-tertiary group-hover:bg-surface-3 group-hover:text-primary",
957
+ activeIcon: "bg-primary/15 text-primary"
958
+ }
959
+ };
960
+ function getItemKey(item, index, parentKey) {
961
+ return item.id ?? item.href ?? `${parentKey}-${index}-${item.label}`;
962
+ }
963
+ function itemHasActiveChild(item) {
964
+ return Boolean(item.children?.some((child) => child.active || itemHasActiveChild(child)));
965
+ }
966
+ function normalizeSearch(value) {
967
+ return value.toLowerCase().replace(/\s+/g, "");
968
+ }
969
+ function filterSidebarItems(items, query) {
970
+ if (!query) return items;
971
+ return items.reduce((result, item) => {
972
+ const children = item.children ? filterSidebarItems(item.children, query) : [];
973
+ const matched = normalizeSearch(item.label).includes(query);
974
+ if (matched || children.length > 0) {
975
+ result.push({ ...item, children });
976
+ }
977
+ return result;
978
+ }, []);
979
+ }
980
+ var Sidebar = (0, import_react14.forwardRef)(
981
+ ({
982
+ items,
983
+ variant = "primary",
984
+ collapsed,
985
+ defaultCollapsed = false,
986
+ onCollapsedChange,
987
+ collapsible = false,
988
+ searchable = false,
989
+ searchPlaceholder = "\u641C\u7D22\u83DC\u5355...",
990
+ responsive = false,
991
+ mobileOpen = false,
992
+ onMobileOpenChange,
993
+ header,
994
+ footer,
995
+ className
996
+ }, ref) => {
997
+ const styles = variantStyles[variant];
998
+ const [internalCollapsed, setInternalCollapsed] = (0, import_react14.useState)(defaultCollapsed);
999
+ const [expandedKeys, setExpandedKeys] = (0, import_react14.useState)(() => /* @__PURE__ */ new Set());
1000
+ const [query, setQuery] = (0, import_react14.useState)("");
1001
+ const effectiveCollapsed = collapsed ?? internalCollapsed;
1002
+ const normalizedQuery = normalizeSearch(query);
1003
+ const visibleItems = (0, import_react14.useMemo)(() => filterSidebarItems(items, normalizedQuery), [items, normalizedQuery]);
1004
+ function setCollapsedState(nextCollapsed) {
1005
+ setInternalCollapsed(nextCollapsed);
1006
+ onCollapsedChange?.(nextCollapsed);
1007
+ }
1008
+ function toggleExpanded(key) {
1009
+ setExpandedKeys((current) => {
1010
+ const next = new Set(current);
1011
+ if (next.has(key)) {
1012
+ next.delete(key);
1013
+ } else {
1014
+ next.add(key);
1015
+ }
1016
+ return next;
1017
+ });
1018
+ }
1019
+ function closeMobile() {
1020
+ onMobileOpenChange?.(false);
1021
+ }
1022
+ function renderItems(list, depth = 0, parentKey = "root") {
1023
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { className: cn("flex flex-col gap-1", depth === 0 ? "px-2.5" : "ml-6 mt-1 border-l border-border-base pl-2"), children: list.map((item, index) => {
1024
+ const key = getItemKey(item, index, parentKey);
1025
+ const hasChildren = Boolean(item.children?.length);
1026
+ const active = Boolean(item.active || itemHasActiveChild(item));
1027
+ const expanded = !effectiveCollapsed && hasChildren && (normalizedQuery.length > 0 || active || expandedKeys.has(key));
1028
+ const itemContent = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1029
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1030
+ "span",
1031
+ {
1032
+ className: cn(
1033
+ "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg transition-colors",
1034
+ active ? styles.activeIcon : styles.icon
1035
+ ),
1036
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(item.icon, { size: 16 })
1037
+ }
1038
+ ),
1039
+ !effectiveCollapsed && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "min-w-0 flex-1 truncate text-left", children: item.label }),
1040
+ !effectiveCollapsed && hasChildren && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1041
+ import_lucide_react6.ChevronDown,
1042
+ {
1043
+ size: 15,
1044
+ className: cn("shrink-0 text-text-tertiary transition-transform", expanded && "rotate-180"),
1045
+ "aria-hidden": "true"
1046
+ }
1047
+ )
1048
+ ] });
1049
+ const itemClassName = cn(
1050
+ "group relative flex min-w-0 items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm font-medium outline-none transition-all duration-150 focus-visible:ring-2 focus-visible:ring-primary/35",
1051
+ effectiveCollapsed && "justify-center px-2",
1052
+ active ? styles.active : styles.inactive
1053
+ );
1054
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("li", { children: [
1055
+ hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1056
+ "button",
1057
+ {
1058
+ type: "button",
1059
+ className: cn("w-full", itemClassName),
1060
+ "aria-expanded": expanded,
1061
+ title: effectiveCollapsed ? item.label : void 0,
1062
+ onClick: () => toggleExpanded(key),
1063
+ children: itemContent
1064
+ }
1065
+ ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1066
+ "a",
1067
+ {
1068
+ href: item.href ?? "#",
1069
+ "aria-current": item.active ? "page" : void 0,
1070
+ className: itemClassName,
1071
+ title: effectiveCollapsed ? item.label : void 0,
1072
+ onClick: closeMobile,
1073
+ children: itemContent
1074
+ }
1075
+ ),
1076
+ expanded && item.children ? renderItems(item.children, depth + 1, key) : null
1077
+ ] }, key);
1078
+ }) });
1079
+ }
1080
+ const sidebar = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1081
+ "aside",
1082
+ {
1083
+ ref,
1084
+ className: cn(
1085
+ "flex flex-col overflow-hidden transition-all duration-300",
1086
+ styles.container,
1087
+ effectiveCollapsed ? "w-[72px]" : "w-64",
1088
+ responsive && [
1089
+ "fixed inset-y-0 left-0 z-50 md:relative md:inset-auto md:z-auto",
1090
+ mobileOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"
1091
+ ],
1092
+ className
1093
+ ),
1094
+ children: [
1095
+ (header || collapsible || responsive && mobileOpen) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1096
+ "div",
1097
+ {
1098
+ className: cn(
1099
+ "flex border-b px-3 py-3",
1100
+ styles.divider,
1101
+ effectiveCollapsed ? "justify-center" : "items-center gap-2"
1102
+ ),
1103
+ children: [
1104
+ !effectiveCollapsed && header ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "min-w-0 flex-1", children: header }) : null,
1105
+ collapsible && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1106
+ "button",
1107
+ {
1108
+ type: "button",
1109
+ className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border-base bg-surface-2 text-text-secondary transition-colors hover:border-primary/40 hover:text-text-primary",
1110
+ "aria-label": effectiveCollapsed ? "\u5C55\u5F00\u4FA7\u8FB9\u680F" : "\u6298\u53E0\u4FA7\u8FB9\u680F",
1111
+ onClick: () => setCollapsedState(!effectiveCollapsed),
1112
+ children: effectiveCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.PanelLeftOpen, { size: 17 }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.PanelLeftClose, { size: 17 })
1113
+ }
1114
+ ),
1115
+ responsive && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1116
+ "button",
1117
+ {
1118
+ type: "button",
1119
+ className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border-base bg-surface-2 text-text-secondary transition-colors hover:border-primary/40 hover:text-text-primary md:hidden",
1120
+ "aria-label": "\u5173\u95ED\u4FA7\u8FB9\u680F",
1121
+ onClick: closeMobile,
1122
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.X, { size: 17 })
1123
+ }
1124
+ )
1125
+ ]
1126
+ }
1127
+ ),
1128
+ searchable && !effectiveCollapsed && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cn("border-b px-3 py-3", styles.divider), children: [
1129
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { className: "sr-only", htmlFor: "ug-sidebar-search", children: "\u641C\u7D22\u83DC\u5355" }),
1130
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative", children: [
1131
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary", "aria-hidden": "true" }),
1132
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1133
+ "input",
1134
+ {
1135
+ id: "ug-sidebar-search",
1136
+ value: query,
1137
+ onChange: (event) => setQuery(event.target.value),
1138
+ placeholder: searchPlaceholder,
1139
+ autoComplete: "off",
1140
+ className: "h-10 w-full rounded-lg border border-border-base bg-surface-0 px-3 pl-9 pr-9 text-sm text-text-primary outline-none transition-colors placeholder:text-text-tertiary focus:border-primary focus:ring-2 focus:ring-primary/20",
1141
+ type: "text",
1142
+ role: "searchbox"
1143
+ }
1144
+ ),
1145
+ query ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1146
+ "button",
1147
+ {
1148
+ type: "button",
1149
+ className: "absolute right-1 top-1/2 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-md text-text-tertiary transition-colors hover:bg-surface-2 hover:text-text-primary",
1150
+ "aria-label": "\u6E05\u7A7A\u641C\u7D22",
1151
+ onClick: () => setQuery(""),
1152
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.X, { size: 14 })
1153
+ }
1154
+ ) : null
1155
+ ] })
1156
+ ] }),
1157
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("nav", { className: "flex-1 overflow-y-auto py-3.5", children: visibleItems.length > 0 ? renderItems(visibleItems) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mx-3 rounded-lg border border-dashed border-border-base bg-surface-0 px-3 py-3 text-sm text-text-tertiary", children: "\u6CA1\u6709\u5339\u914D\u7684\u83DC\u5355" }) }),
1158
+ footer && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1159
+ "div",
1160
+ {
1161
+ className: cn(
1162
+ "border-t px-2.5 py-3",
1163
+ styles.divider,
1164
+ effectiveCollapsed && "flex justify-center"
1165
+ ),
1166
+ children: footer
1167
+ }
1168
+ )
1169
+ ]
1170
+ }
1171
+ );
1172
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1173
+ responsive && mobileOpen ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1174
+ "button",
1175
+ {
1176
+ type: "button",
1177
+ className: "fixed inset-0 z-40 bg-overlay md:hidden",
1178
+ "aria-label": "\u5173\u95ED\u4FA7\u8FB9\u680F\u906E\u7F69",
1179
+ onClick: closeMobile
1180
+ }
1181
+ ) : null,
1182
+ sidebar
1183
+ ] });
1184
+ }
1185
+ );
1186
+ Sidebar.displayName = "Sidebar";
1187
+
1188
+ // src/components/pagination.tsx
1189
+ var import_react15 = require("react");
1190
+ var import_lucide_react7 = require("lucide-react");
1191
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1192
+ function getPageNumbers(page, totalPages) {
1193
+ if (totalPages <= 5) {
1194
+ return Array.from({ length: totalPages }, (_, i) => i + 1);
1195
+ }
1196
+ if (page <= 3) {
1197
+ return [1, 2, 3, "...", totalPages];
1198
+ }
1199
+ if (page >= totalPages - 2) {
1200
+ return [1, "...", totalPages - 2, totalPages - 1, totalPages];
1201
+ }
1202
+ return [1, "...", page, "...", totalPages];
1203
+ }
1204
+ var Pagination = (0, import_react15.forwardRef)(({ page, totalPages, onPageChange, className }, ref) => {
1205
+ const pageNumbers = getPageNumbers(page, totalPages);
1206
+ const btnBase = "inline-flex h-8 min-w-8 shrink-0 items-center justify-center rounded-lg px-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 disabled:pointer-events-none disabled:opacity-40";
1207
+ const btnGhost = "border border-border-strong bg-surface-1 text-text-primary hover:border-primary/60 hover:bg-surface-2";
1208
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { ref, className: cn("flex max-w-full flex-wrap items-center gap-1", className), children: [
1209
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1210
+ "button",
1211
+ {
1212
+ type: "button",
1213
+ className: cn(btnBase, btnGhost),
1214
+ disabled: page <= 1,
1215
+ onClick: () => onPageChange(page - 1),
1216
+ "aria-label": "\u4E0A\u4E00\u9875",
1217
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ChevronLeft, { size: 16 })
1218
+ }
1219
+ ),
1220
+ pageNumbers.map(
1221
+ (p, idx) => p === "..." ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "inline-flex h-8 min-w-6 shrink-0 items-center justify-center text-text-tertiary select-none", children: "\u2026" }, `ellipsis-${idx}`) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1222
+ "button",
1223
+ {
1224
+ type: "button",
1225
+ className: cn(
1226
+ btnBase,
1227
+ p === page ? "bg-primary text-primary-fg shadow-sm" : btnGhost
1228
+ ),
1229
+ onClick: () => onPageChange(p),
1230
+ "aria-current": p === page ? "page" : void 0,
1231
+ children: p
1232
+ },
1233
+ p
1234
+ )
1235
+ ),
1236
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1237
+ "button",
1238
+ {
1239
+ type: "button",
1240
+ className: cn(btnBase, btnGhost),
1241
+ disabled: page >= totalPages,
1242
+ onClick: () => onPageChange(page + 1),
1243
+ "aria-label": "\u4E0B\u4E00\u9875",
1244
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ChevronRight, { size: 16 })
1245
+ }
1246
+ )
1247
+ ] });
1248
+ });
1249
+ Pagination.displayName = "Pagination";
1250
+
1251
+ // src/components/select.tsx
1252
+ var import_react16 = require("react");
1253
+ var import_lucide_react8 = require("lucide-react");
1254
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1255
+ var Select = (0, import_react16.forwardRef)(
1256
+ ({
1257
+ className,
1258
+ label,
1259
+ error,
1260
+ helperText,
1261
+ options,
1262
+ placeholder,
1263
+ id,
1264
+ value,
1265
+ defaultValue,
1266
+ onChange,
1267
+ disabled,
1268
+ name,
1269
+ required,
1270
+ ...props
1271
+ }, ref) => {
1272
+ const generatedId = (0, import_react16.useId)();
1273
+ const selectId = id ?? generatedId;
1274
+ const listboxId = `${selectId}-listbox`;
1275
+ const rootRef = (0, import_react16.useRef)(null);
1276
+ const hiddenSelectRef = (0, import_react16.useRef)(null);
1277
+ const isControlled = value !== void 0;
1278
+ const [open, setOpen] = (0, import_react16.useState)(false);
1279
+ const [internalValue, setInternalValue] = (0, import_react16.useState)(() => String(defaultValue ?? ""));
1280
+ const selectedValue = String(isControlled ? value : internalValue);
1281
+ const selectedOption = (0, import_react16.useMemo)(
1282
+ () => options.find((option) => String(option.value) === selectedValue),
1283
+ [options, selectedValue]
1284
+ );
1285
+ function setSelectRef(node) {
1286
+ hiddenSelectRef.current = node;
1287
+ if (typeof ref === "function") {
1288
+ ref(node);
1289
+ } else if (ref) {
1290
+ ref.current = node;
1291
+ }
1292
+ }
1293
+ function handleSelect(nextValue) {
1294
+ if (disabled) return;
1295
+ if (!isControlled) {
1296
+ setInternalValue(nextValue);
1297
+ }
1298
+ if (hiddenSelectRef.current) {
1299
+ hiddenSelectRef.current.value = nextValue;
1300
+ onChange?.({ target: hiddenSelectRef.current, currentTarget: hiddenSelectRef.current });
1301
+ }
1302
+ setOpen(false);
1303
+ }
1304
+ function toggleOpen() {
1305
+ if (disabled) return;
1306
+ setOpen((current) => !current);
1307
+ }
1308
+ function handleTriggerKeyDown(event) {
1309
+ if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
1310
+ event.preventDefault();
1311
+ setOpen(true);
1312
+ return;
1313
+ }
1314
+ if (event.key === "Escape") {
1315
+ event.preventDefault();
1316
+ setOpen(false);
1317
+ }
1318
+ }
1319
+ (0, import_react16.useEffect)(() => {
1320
+ if (!open) return;
1321
+ function handlePointerDown(event) {
1322
+ if (!rootRef.current?.contains(event.target)) {
1323
+ setOpen(false);
1324
+ }
1325
+ }
1326
+ function handleKeyDown(event) {
1327
+ if (event.key === "Escape") {
1328
+ setOpen(false);
1329
+ }
1330
+ }
1331
+ document.addEventListener("pointerdown", handlePointerDown);
1332
+ document.addEventListener("keydown", handleKeyDown);
1333
+ return () => {
1334
+ document.removeEventListener("pointerdown", handlePointerDown);
1335
+ document.removeEventListener("keydown", handleKeyDown);
1336
+ };
1337
+ }, [open]);
1338
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { ref: rootRef, className: "relative flex flex-col gap-1.5", children: [
1339
+ label && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { htmlFor: selectId, className: "text-sm font-medium text-text-primary", children: label }),
1340
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1341
+ "select",
1342
+ {
1343
+ ref: setSelectRef,
1344
+ id: `${selectId}-native`,
1345
+ name,
1346
+ value: selectedValue,
1347
+ required,
1348
+ disabled,
1349
+ tabIndex: -1,
1350
+ "aria-hidden": "true",
1351
+ className: "sr-only",
1352
+ onChange,
1353
+ ...props,
1354
+ children: [
1355
+ placeholder && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "", children: placeholder }),
1356
+ options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
1357
+ ]
1358
+ }
1359
+ ),
1360
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "relative", children: [
1361
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1362
+ "button",
1363
+ {
1364
+ type: "button",
1365
+ id: selectId,
1366
+ disabled,
1367
+ "aria-haspopup": "listbox",
1368
+ "aria-expanded": open,
1369
+ "aria-controls": listboxId,
1370
+ className: cn(
1371
+ "flex h-10 w-full items-center justify-between rounded-lg border bg-surface-1 px-3 py-2 text-left text-sm leading-5 text-text-primary shadow-sm",
1372
+ "transition-colors hover:border-primary/60",
1373
+ "focus-visible:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/25 focus-visible:ring-offset-1 focus-visible:ring-offset-surface-0",
1374
+ "disabled:cursor-not-allowed disabled:bg-surface-2 disabled:text-text-tertiary disabled:opacity-70",
1375
+ error ? "border-danger focus-visible:ring-danger/25" : "border-border-strong",
1376
+ className
1377
+ ),
1378
+ onClick: toggleOpen,
1379
+ onKeyDown: handleTriggerKeyDown,
1380
+ children: [
1381
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: cn("truncate", !selectedOption && "text-text-tertiary"), children: selectedOption?.label ?? placeholder ?? "\u8BF7\u9009\u62E9" }),
1382
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1383
+ import_lucide_react8.ChevronDown,
1384
+ {
1385
+ "aria-hidden": "true",
1386
+ className: cn("h-4 w-4 shrink-0 text-text-tertiary transition-transform", open && "rotate-180")
1387
+ }
1388
+ )
1389
+ ]
1390
+ }
1391
+ ),
1392
+ open && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1393
+ "div",
1394
+ {
1395
+ id: listboxId,
1396
+ role: "listbox",
1397
+ className: "absolute left-0 right-0 top-full z-[70] mt-1 max-h-60 overflow-auto rounded-lg border border-border-strong bg-surface-1 p-1 shadow-xl",
1398
+ children: [
1399
+ placeholder && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1400
+ "button",
1401
+ {
1402
+ type: "button",
1403
+ role: "option",
1404
+ "aria-selected": selectedValue === "",
1405
+ className: cn(
1406
+ "flex w-full items-center rounded-md px-2.5 py-2 text-left text-sm text-text-tertiary transition-colors hover:bg-surface-2",
1407
+ selectedValue === "" && "bg-surface-2 text-text-primary"
1408
+ ),
1409
+ onClick: () => handleSelect(""),
1410
+ children: placeholder
1411
+ }
1412
+ ),
1413
+ options.map((option) => {
1414
+ const optionValue = String(option.value);
1415
+ const selected = optionValue === selectedValue;
1416
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1417
+ "button",
1418
+ {
1419
+ type: "button",
1420
+ role: "option",
1421
+ "aria-selected": selected,
1422
+ className: cn(
1423
+ "flex w-full items-center rounded-md px-2.5 py-2 text-left text-sm text-text-primary transition-colors hover:bg-surface-2",
1424
+ selected && "bg-primary-soft text-primary-soft-fg"
1425
+ ),
1426
+ onClick: () => handleSelect(optionValue),
1427
+ children: option.label
1428
+ },
1429
+ option.value
1430
+ );
1431
+ })
1432
+ ]
1433
+ }
1434
+ )
1435
+ ] }),
1436
+ error && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-xs text-danger", children: error }),
1437
+ !error && helperText && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-xs text-text-secondary", children: helperText })
1438
+ ] });
1439
+ }
1440
+ );
1441
+ Select.displayName = "Select";
1442
+
1443
+ // src/components/spinner.tsx
1444
+ var import_react17 = require("react");
1445
+ var import_lucide_react9 = require("lucide-react");
1446
+ var import_class_variance_authority4 = require("class-variance-authority");
1447
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1448
+ var spinnerVariants = (0, import_class_variance_authority4.cva)("animate-spin text-text-tertiary", {
1449
+ variants: {
1450
+ size: {
1451
+ sm: "h-4 w-4",
1452
+ md: "h-6 w-6",
1453
+ lg: "h-10 w-10"
1454
+ }
1455
+ },
1456
+ defaultVariants: {
1457
+ size: "md"
1458
+ }
1459
+ });
1460
+ var Spinner = (0, import_react17.forwardRef)(({ className, size, label = "\u52A0\u8F7D\u4E2D", ...props }, ref) => {
1461
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1462
+ import_lucide_react9.Loader2,
1463
+ {
1464
+ ref,
1465
+ className: cn(spinnerVariants({ size }), className),
1466
+ "aria-label": label,
1467
+ role: "status",
1468
+ ...props
1469
+ }
1470
+ );
1471
+ });
1472
+ Spinner.displayName = "Spinner";
1473
+
1474
+ // src/components/checkbox.tsx
1475
+ var import_react18 = require("react");
1476
+ var import_lucide_react10 = require("lucide-react");
1477
+ var import_class_variance_authority5 = require("class-variance-authority");
1478
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1479
+ var checkboxVariants = (0, import_class_variance_authority5.cva)(
1480
+ "peer inline-flex shrink-0 items-center justify-center rounded-md border shadow-sm transition-colors peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring/35 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-surface-0 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
1481
+ {
1482
+ variants: {
1483
+ size: {
1484
+ sm: "h-4 w-4",
1485
+ default: "h-[18px] w-[18px]",
1486
+ lg: "h-5 w-5"
1487
+ },
1488
+ state: {
1489
+ unchecked: "border-border-strong bg-surface-1 text-transparent hover:border-primary/70 hover:bg-surface-2",
1490
+ checked: "border-primary bg-primary text-primary-fg",
1491
+ indeterminate: "border-primary bg-primary text-primary-fg"
1492
+ }
1493
+ },
1494
+ defaultVariants: {
1495
+ size: "default",
1496
+ state: "unchecked"
1497
+ }
1498
+ }
1499
+ );
1500
+ var Checkbox = (0, import_react18.forwardRef)(
1501
+ ({
1502
+ className,
1503
+ size,
1504
+ checked,
1505
+ indeterminate = false,
1506
+ disabled,
1507
+ label,
1508
+ labelClassName,
1509
+ onCheckedChange,
1510
+ id,
1511
+ ...props
1512
+ }, ref) => {
1513
+ const innerRef = (0, import_react18.useRef)(null);
1514
+ const generatedId = (0, import_react18.useId)();
1515
+ const inputId = id ?? generatedId;
1516
+ (0, import_react18.useEffect)(() => {
1517
+ if (innerRef.current) {
1518
+ innerRef.current.indeterminate = indeterminate;
1519
+ }
1520
+ }, [indeterminate]);
1521
+ const state = indeterminate ? "indeterminate" : checked ? "checked" : "unchecked";
1522
+ const iconSize = size === "sm" ? 11 : size === "lg" ? 14 : 12;
1523
+ const control = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "relative inline-flex", children: [
1524
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1525
+ "input",
1526
+ {
1527
+ ref: (node) => {
1528
+ innerRef.current = node;
1529
+ if (typeof ref === "function") ref(node);
1530
+ else if (ref) ref.current = node;
1531
+ },
1532
+ id: inputId,
1533
+ type: "checkbox",
1534
+ className: "peer sr-only",
1535
+ checked: checked ?? false,
1536
+ disabled,
1537
+ onChange: (e) => onCheckedChange?.(e.target.checked),
1538
+ ...props
1539
+ }
1540
+ ),
1541
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1542
+ "span",
1543
+ {
1544
+ "aria-hidden": "true",
1545
+ className: cn(checkboxVariants({ size, state }), className),
1546
+ children: indeterminate ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react10.Minus, { size: iconSize }) : checked ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react10.Check, { size: iconSize }) : null
1547
+ }
1548
+ )
1549
+ ] });
1550
+ if (label === void 0 || label === null) return control;
1551
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1552
+ "label",
1553
+ {
1554
+ htmlFor: inputId,
1555
+ className: cn(
1556
+ "inline-flex min-h-5 cursor-pointer items-center gap-2.5 text-sm leading-5 text-text-primary select-none",
1557
+ disabled && "cursor-not-allowed opacity-60",
1558
+ labelClassName
1559
+ ),
1560
+ children: [
1561
+ control,
1562
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "pt-px", children: label })
1563
+ ]
1564
+ }
1565
+ );
1566
+ }
1567
+ );
1568
+ Checkbox.displayName = "Checkbox";
1569
+
1570
+ // src/components/radio.tsx
1571
+ var import_react19 = require("react");
1572
+ var import_class_variance_authority6 = require("class-variance-authority");
1573
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1574
+ var RadioGroupContext = (0, import_react19.createContext)(null);
1575
+ function useRadioGroupContext() {
1576
+ return (0, import_react19.useContext)(RadioGroupContext);
1577
+ }
1578
+ var radioVariants = (0, import_class_variance_authority6.cva)(
1579
+ "relative inline-flex shrink-0 items-center justify-center rounded-full border shadow-sm transition-colors peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring/35 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-surface-0 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
1580
+ {
1581
+ variants: {
1582
+ size: {
1583
+ sm: "h-4 w-4",
1584
+ default: "h-[18px] w-[18px]",
1585
+ lg: "h-5 w-5"
1586
+ },
1587
+ checked: {
1588
+ true: "border-primary bg-surface-1",
1589
+ false: "border-border-strong bg-surface-1 hover:border-primary/70 hover:bg-surface-2"
1590
+ }
1591
+ },
1592
+ defaultVariants: {
1593
+ size: "default",
1594
+ checked: false
1595
+ }
1596
+ }
1597
+ );
1598
+ var Radio = (0, import_react19.forwardRef)(
1599
+ ({
1600
+ className,
1601
+ size,
1602
+ value,
1603
+ checked: checkedProp,
1604
+ disabled: disabledProp,
1605
+ label,
1606
+ name: nameProp,
1607
+ onChange,
1608
+ id,
1609
+ ...props
1610
+ }, ref) => {
1611
+ const group = useRadioGroupContext();
1612
+ const generatedId = (0, import_react19.useId)();
1613
+ const inputId = id ?? generatedId;
1614
+ const isChecked = group ? group.value === value : checkedProp ?? false;
1615
+ const isDisabled = group ? group.disabled || (disabledProp ?? false) : disabledProp ?? false;
1616
+ const inputName = group ? group.name : nameProp;
1617
+ function handleChange() {
1618
+ if (group) {
1619
+ group.onValueChange(value);
1620
+ } else {
1621
+ onChange?.(value);
1622
+ }
1623
+ }
1624
+ const dotSize = size === "sm" ? "h-1.5 w-1.5" : size === "lg" ? "h-2.5 w-2.5" : "h-2 w-2";
1625
+ const control = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "relative inline-flex", children: [
1626
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1627
+ "input",
1628
+ {
1629
+ ref,
1630
+ id: inputId,
1631
+ type: "radio",
1632
+ className: "peer sr-only",
1633
+ value,
1634
+ checked: isChecked,
1635
+ disabled: isDisabled,
1636
+ name: inputName,
1637
+ onChange: handleChange,
1638
+ ...props
1639
+ }
1640
+ ),
1641
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1642
+ "span",
1643
+ {
1644
+ "aria-hidden": "true",
1645
+ className: cn(radioVariants({ size, checked: isChecked }), className),
1646
+ children: isChecked && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: cn("rounded-full bg-primary", dotSize) })
1647
+ }
1648
+ )
1649
+ ] });
1650
+ if (label === void 0 || label === null) return control;
1651
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1652
+ "label",
1653
+ {
1654
+ htmlFor: inputId,
1655
+ className: cn(
1656
+ "inline-flex min-h-5 cursor-pointer items-center gap-2.5 text-sm leading-5 text-text-primary select-none",
1657
+ isDisabled && "cursor-not-allowed opacity-60"
1658
+ ),
1659
+ children: [
1660
+ control,
1661
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "pt-px", children: label })
1662
+ ]
1663
+ }
1664
+ );
1665
+ }
1666
+ );
1667
+ Radio.displayName = "Radio";
1668
+ var RadioGroup = (0, import_react19.forwardRef)(
1669
+ ({
1670
+ className,
1671
+ value: valueProp,
1672
+ defaultValue,
1673
+ onValueChange,
1674
+ disabled = false,
1675
+ name,
1676
+ orientation = "vertical",
1677
+ children,
1678
+ ...props
1679
+ }, ref) => {
1680
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react19.useState)(defaultValue);
1681
+ const isControlled = valueProp !== void 0;
1682
+ const currentValue = isControlled ? valueProp : uncontrolledValue;
1683
+ function handleValueChange(newValue) {
1684
+ if (!isControlled) {
1685
+ setUncontrolledValue(newValue);
1686
+ }
1687
+ onValueChange?.(newValue);
1688
+ }
1689
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1690
+ RadioGroupContext.Provider,
1691
+ {
1692
+ value: {
1693
+ value: currentValue,
1694
+ onValueChange: handleValueChange,
1695
+ name,
1696
+ disabled
1697
+ },
1698
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1699
+ "div",
1700
+ {
1701
+ ref,
1702
+ role: "radiogroup",
1703
+ className: cn(
1704
+ "flex",
1705
+ orientation === "vertical" ? "flex-col gap-2.5" : "flex-row flex-wrap gap-x-5 gap-y-2.5",
1706
+ className
1707
+ ),
1708
+ ...props,
1709
+ children
1710
+ }
1711
+ )
1712
+ }
1713
+ );
1714
+ }
1715
+ );
1716
+ RadioGroup.displayName = "RadioGroup";
1717
+
1718
+ // src/components/slider.tsx
1719
+ var import_react20 = require("react");
1720
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1721
+ var Slider = (0, import_react20.forwardRef)(
1722
+ ({
1723
+ className,
1724
+ value: valueProp,
1725
+ defaultValue = 0,
1726
+ min = 0,
1727
+ max = 100,
1728
+ step = 1,
1729
+ disabled = false,
1730
+ showValue = false,
1731
+ onValueChange,
1732
+ ...props
1733
+ }, ref) => {
1734
+ const isControlled = valueProp !== void 0;
1735
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react20.useState)(defaultValue);
1736
+ const currentValue = isControlled ? valueProp : uncontrolledValue;
1737
+ const fillPercent = max === min ? 0 : (currentValue - min) / (max - min) * 100;
1738
+ function updateValue(nextValue) {
1739
+ if (!isControlled) {
1740
+ setUncontrolledValue(nextValue);
1741
+ }
1742
+ onValueChange?.(nextValue);
1743
+ }
1744
+ function handleInput(e) {
1745
+ updateValue(Number(e.currentTarget.value));
1746
+ }
1747
+ function handleChange(e) {
1748
+ const newValue = Number(e.target.value);
1749
+ if (newValue === currentValue) {
1750
+ return;
1751
+ }
1752
+ updateValue(newValue);
1753
+ }
1754
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cn("flex flex-col gap-1.5", className), children: [
1755
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "self-start text-xs font-semibold leading-none text-text-primary", children: currentValue }),
1756
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "relative flex h-6 w-full items-center", children: [
1757
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "pointer-events-none absolute h-2 w-full overflow-hidden rounded-full bg-surface-3", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1758
+ "div",
1759
+ {
1760
+ className: "h-full rounded-full bg-primary transition-all",
1761
+ style: { width: `${fillPercent}%` }
1762
+ }
1763
+ ) }),
1764
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1765
+ "input",
1766
+ {
1767
+ ref,
1768
+ type: "range",
1769
+ min,
1770
+ max,
1771
+ step,
1772
+ value: currentValue,
1773
+ disabled,
1774
+ onInput: handleInput,
1775
+ onChange: handleChange,
1776
+ className: cn(
1777
+ "relative h-6 w-full cursor-pointer appearance-none bg-transparent",
1778
+ // thumb 样式
1779
+ "[&::-webkit-slider-thumb]:h-[18px] [&::-webkit-slider-thumb]:w-[18px] [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-surface-1 [&::-webkit-slider-thumb]:shadow-md [&::-webkit-slider-thumb]:transition-transform [&::-webkit-slider-thumb]:hover:scale-110",
1780
+ "[&::-moz-range-thumb]:h-[18px] [&::-moz-range-thumb]:w-[18px] [&::-moz-range-thumb]:appearance-none [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary [&::-moz-range-thumb]:bg-surface-1 [&::-moz-range-thumb]:shadow-md",
1781
+ // track 透明(用自定义 div 代替)
1782
+ "[&::-webkit-slider-runnable-track]:bg-transparent",
1783
+ "[&::-moz-range-track]:bg-transparent",
1784
+ // focus
1785
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0",
1786
+ // disabled
1787
+ "disabled:cursor-not-allowed disabled:opacity-50"
1788
+ ),
1789
+ ...props
1790
+ }
1791
+ )
1792
+ ] })
1793
+ ] });
1794
+ }
1795
+ );
1796
+ Slider.displayName = "Slider";
1797
+
1798
+ // src/components/number-input.tsx
1799
+ var import_react21 = require("react");
1800
+ var import_lucide_react11 = require("lucide-react");
1801
+ var import_class_variance_authority7 = require("class-variance-authority");
1802
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1803
+ var numberInputVariants = (0, import_class_variance_authority7.cva)(
1804
+ "inline-flex items-center overflow-hidden rounded-lg border border-border-strong bg-surface-1 shadow-sm transition-colors focus-within:border-primary focus-within:ring-2 focus-within:ring-ring/25 has-[:disabled]:pointer-events-none has-[:disabled]:opacity-60",
1805
+ {
1806
+ variants: {
1807
+ size: {
1808
+ sm: "h-8 text-xs",
1809
+ default: "h-9 text-sm",
1810
+ lg: "h-11 text-base"
1811
+ }
1812
+ },
1813
+ defaultVariants: {
1814
+ size: "default"
1815
+ }
1816
+ }
1817
+ );
1818
+ var NumberInput = (0, import_react21.forwardRef)(
1819
+ ({
1820
+ className,
1821
+ size,
1822
+ value: valueProp,
1823
+ defaultValue = 0,
1824
+ min,
1825
+ max,
1826
+ step = 1,
1827
+ precision = 0,
1828
+ disabled = false,
1829
+ placeholder,
1830
+ onValueChange,
1831
+ ...props
1832
+ }, ref) => {
1833
+ const isControlled = valueProp !== void 0;
1834
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react21.useState)(defaultValue);
1835
+ const currentValue = isControlled ? valueProp : uncontrolledValue;
1836
+ function clamp(val) {
1837
+ let result = val;
1838
+ if (min !== void 0) result = Math.max(min, result);
1839
+ if (max !== void 0) result = Math.min(max, result);
1840
+ return result;
1841
+ }
1842
+ function format(val) {
1843
+ return val.toFixed(precision);
1844
+ }
1845
+ function commit(newVal) {
1846
+ const clamped = clamp(Number(newVal.toFixed(precision)));
1847
+ if (!isControlled) {
1848
+ setUncontrolledValue(clamped);
1849
+ }
1850
+ onValueChange?.(clamped);
1851
+ }
1852
+ function handleDecrement() {
1853
+ commit(currentValue - step);
1854
+ }
1855
+ function handleIncrement() {
1856
+ commit(currentValue + step);
1857
+ }
1858
+ function handleInputChange(e) {
1859
+ const parsed = parseFloat(e.target.value);
1860
+ if (!Number.isNaN(parsed)) {
1861
+ commit(parsed);
1862
+ }
1863
+ }
1864
+ function handleBlur(e) {
1865
+ const parsed = parseFloat(e.target.value);
1866
+ if (!Number.isNaN(parsed)) {
1867
+ commit(parsed);
1868
+ } else {
1869
+ if (!isControlled) {
1870
+ setUncontrolledValue(uncontrolledValue);
1871
+ }
1872
+ }
1873
+ }
1874
+ const atMin = min !== void 0 && currentValue <= min;
1875
+ const atMax = max !== void 0 && currentValue >= max;
1876
+ const btnBase = "inline-flex shrink-0 items-center justify-center bg-surface-2 text-text-secondary transition-colors hover:bg-surface-3 hover:text-text-primary disabled:pointer-events-none disabled:opacity-40";
1877
+ const btnSizeCls = size === "sm" ? "h-8 w-7" : size === "lg" ? "h-11 w-10" : "h-9 w-9";
1878
+ const iconSize = size === "sm" ? 12 : size === "lg" ? 16 : 14;
1879
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cn(numberInputVariants({ size }), className), children: [
1880
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1881
+ "button",
1882
+ {
1883
+ type: "button",
1884
+ "aria-label": "\u51CF\u5C11\u6570\u503C",
1885
+ disabled: disabled || atMin,
1886
+ onClick: handleDecrement,
1887
+ className: cn(btnBase, btnSizeCls, "border-r border-border-base"),
1888
+ tabIndex: -1,
1889
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react11.Minus, { size: iconSize })
1890
+ }
1891
+ ),
1892
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1893
+ "input",
1894
+ {
1895
+ ref,
1896
+ type: "number",
1897
+ className: cn(
1898
+ "min-w-0 flex-1 bg-transparent px-2 text-center font-medium text-text-primary outline-none",
1899
+ "placeholder:text-text-tertiary",
1900
+ // 隐藏原生 spinner
1901
+ "[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
1902
+ ),
1903
+ value: format(currentValue),
1904
+ disabled,
1905
+ placeholder,
1906
+ min,
1907
+ max,
1908
+ step,
1909
+ onChange: handleInputChange,
1910
+ onBlur: handleBlur,
1911
+ ...props
1912
+ }
1913
+ ),
1914
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1915
+ "button",
1916
+ {
1917
+ type: "button",
1918
+ "aria-label": "\u589E\u52A0\u6570\u503C",
1919
+ disabled: disabled || atMax,
1920
+ onClick: handleIncrement,
1921
+ className: cn(btnBase, btnSizeCls, "border-l border-border-base"),
1922
+ tabIndex: -1,
1923
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react11.Plus, { size: iconSize })
1924
+ }
1925
+ )
1926
+ ] });
1927
+ }
1928
+ );
1929
+ NumberInput.displayName = "NumberInput";
1930
+
1931
+ // src/components/otp-input.tsx
1932
+ var import_react22 = require("react");
1933
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1934
+ var OTPInput = (0, import_react22.forwardRef)(
1935
+ ({
1936
+ value,
1937
+ onValueChange,
1938
+ length = 6,
1939
+ disabled = false,
1940
+ onComplete,
1941
+ className
1942
+ }, ref) => {
1943
+ const inputRefs = (0, import_react22.useRef)([]);
1944
+ const focusAt = (0, import_react22.useCallback)((index) => {
1945
+ const el = inputRefs.current[index];
1946
+ if (el) {
1947
+ el.focus();
1948
+ el.setSelectionRange(el.value.length, el.value.length);
1949
+ }
1950
+ }, []);
1951
+ const updateValueAt = (0, import_react22.useCallback)(
1952
+ (index, char) => {
1953
+ const chars = value.padEnd(length, "").split("").slice(0, length);
1954
+ chars[index] = char;
1955
+ const next = chars.join("");
1956
+ onValueChange(next);
1957
+ if (char && next.replace(/\s/g, "").length === length && !next.includes(" ")) {
1958
+ onComplete?.(next);
1959
+ }
1960
+ },
1961
+ [value, length, onValueChange, onComplete]
1962
+ );
1963
+ const handleChange = (0, import_react22.useCallback)(
1964
+ (index, e) => {
1965
+ const raw = e.target.value;
1966
+ const digit = raw.replace(/\D/g, "").slice(-1);
1967
+ updateValueAt(index, digit);
1968
+ if (digit && index < length - 1) {
1969
+ focusAt(index + 1);
1970
+ }
1971
+ },
1972
+ [length, updateValueAt, focusAt]
1973
+ );
1974
+ const handleKeyDown = (0, import_react22.useCallback)(
1975
+ (index, e) => {
1976
+ if (e.key === "ArrowLeft") {
1977
+ e.preventDefault();
1978
+ if (index > 0) focusAt(index - 1);
1979
+ } else if (e.key === "ArrowRight") {
1980
+ e.preventDefault();
1981
+ if (index < length - 1) focusAt(index + 1);
1982
+ } else if (e.key === "Backspace") {
1983
+ e.preventDefault();
1984
+ const current = value[index] ?? "";
1985
+ if (current) {
1986
+ updateValueAt(index, "");
1987
+ } else if (index > 0) {
1988
+ updateValueAt(index - 1, "");
1989
+ focusAt(index - 1);
1990
+ }
1991
+ }
1992
+ },
1993
+ [value, length, focusAt, updateValueAt]
1994
+ );
1995
+ const handlePaste = (0, import_react22.useCallback)(
1996
+ (e) => {
1997
+ e.preventDefault();
1998
+ const pasted = e.clipboardData.getData("text").replace(/\D/g, "").slice(0, length);
1999
+ if (!pasted) return;
2000
+ const chars = pasted.padEnd(length, "").split("").slice(0, length);
2001
+ const next = chars.join("");
2002
+ onValueChange(next);
2003
+ const nextFocus = Math.min(pasted.length, length - 1);
2004
+ focusAt(nextFocus);
2005
+ if (pasted.length === length) {
2006
+ onComplete?.(next);
2007
+ }
2008
+ },
2009
+ [length, onValueChange, onComplete, focusAt]
2010
+ );
2011
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2012
+ "div",
2013
+ {
2014
+ ref,
2015
+ className: cn("flex items-center gap-2", className),
2016
+ role: "group",
2017
+ "aria-label": "\u9A8C\u8BC1\u7801\u8F93\u5165",
2018
+ children: Array.from({ length }, (_, i) => {
2019
+ const char = value[i] ?? "";
2020
+ const isFocused = false;
2021
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2022
+ "input",
2023
+ {
2024
+ ref: (el) => {
2025
+ inputRefs.current[i] = el;
2026
+ },
2027
+ type: "text",
2028
+ inputMode: "numeric",
2029
+ pattern: "[0-9]",
2030
+ maxLength: 1,
2031
+ value: char,
2032
+ disabled,
2033
+ "aria-label": `\u9A8C\u8BC1\u7801\u7B2C ${i + 1} \u4F4D`,
2034
+ className: cn(
2035
+ "h-10 w-10 rounded-md border text-center text-sm font-medium text-text-primary transition-colors",
2036
+ "outline-none focus:border-primary focus:ring-2 focus:ring-ring/20",
2037
+ "disabled:cursor-not-allowed disabled:opacity-50",
2038
+ char ? "border-border-strong" : "border-border-base"
2039
+ ),
2040
+ onChange: (e) => handleChange(i, e),
2041
+ onKeyDown: (e) => handleKeyDown(i, e),
2042
+ onPaste: handlePaste,
2043
+ onClick: (e) => e.target.select()
2044
+ },
2045
+ i
2046
+ );
2047
+ })
2048
+ }
2049
+ );
2050
+ }
2051
+ );
2052
+ OTPInput.displayName = "OTPInput";
2053
+
2054
+ // src/components/form.tsx
2055
+ var import_react23 = require("react");
2056
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2057
+ var FormFieldContext = (0, import_react23.createContext)(null);
2058
+ function useFormFieldContext() {
2059
+ const ctx = (0, import_react23.useContext)(FormFieldContext);
2060
+ if (!ctx) {
2061
+ throw new Error("FormField \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <FormField> \u5185\u4F7F\u7528");
2062
+ }
2063
+ return ctx;
2064
+ }
2065
+ var Form = (0, import_react23.forwardRef)(
2066
+ ({ className, onSubmit, children, ...props }, ref) => {
2067
+ function handleSubmit(event) {
2068
+ event.preventDefault();
2069
+ onSubmit?.(event);
2070
+ }
2071
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2072
+ "form",
2073
+ {
2074
+ ref,
2075
+ className: cn(className),
2076
+ onSubmit: handleSubmit,
2077
+ ...props,
2078
+ children
2079
+ }
2080
+ );
2081
+ }
2082
+ );
2083
+ Form.displayName = "Form";
2084
+ var FormField = (0, import_react23.forwardRef)(
2085
+ ({ name, error, className, children, ...props }, ref) => {
2086
+ const generatedId = (0, import_react23.useId)();
2087
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(FormFieldContext.Provider, { value: { name, error, id: generatedId }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref, className: cn(className), ...props, children }) });
2088
+ }
2089
+ );
2090
+ FormField.displayName = "FormField";
2091
+ var FormItem = (0, import_react23.forwardRef)(
2092
+ ({ className, children, ...props }, ref) => {
2093
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2094
+ "div",
2095
+ {
2096
+ ref,
2097
+ className: cn("flex flex-col gap-1.5", className),
2098
+ ...props,
2099
+ children
2100
+ }
2101
+ );
2102
+ }
2103
+ );
2104
+ FormItem.displayName = "FormItem";
2105
+ var FormLabel = (0, import_react23.forwardRef)(
2106
+ ({ className, required, children, htmlFor, ...props }, ref) => {
2107
+ const ctx = useFormFieldContext();
2108
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2109
+ Label,
2110
+ {
2111
+ ref,
2112
+ htmlFor: htmlFor ?? ctx.id,
2113
+ required,
2114
+ className: cn(className),
2115
+ ...props,
2116
+ children
2117
+ }
2118
+ );
2119
+ }
2120
+ );
2121
+ FormLabel.displayName = "FormLabel";
2122
+ function FormControl({ children }) {
2123
+ const ctx = useFormFieldContext();
2124
+ const descriptionId = `${ctx.id}-description`;
2125
+ const messageId = `${ctx.id}-message`;
2126
+ return (0, import_react23.cloneElement)(children, {
2127
+ id: ctx.id,
2128
+ "aria-describedby": ctx.error ? `${descriptionId} ${messageId}` : descriptionId,
2129
+ "aria-invalid": ctx.error ? true : void 0
2130
+ });
2131
+ }
2132
+ FormControl.displayName = "FormControl";
2133
+ var FormDescription = (0, import_react23.forwardRef)(
2134
+ ({ className, children, ...props }, ref) => {
2135
+ const ctx = useFormFieldContext();
2136
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2137
+ "p",
2138
+ {
2139
+ ref,
2140
+ id: `${ctx.id}-description`,
2141
+ className: cn("text-xs text-text-secondary", className),
2142
+ ...props,
2143
+ children
2144
+ }
2145
+ );
2146
+ }
2147
+ );
2148
+ FormDescription.displayName = "FormDescription";
2149
+ var FormMessage = (0, import_react23.forwardRef)(
2150
+ ({ className, children, ...props }, ref) => {
2151
+ const ctx = useFormFieldContext();
2152
+ const message = ctx.error ?? (typeof children === "string" ? children : void 0);
2153
+ if (!message) return null;
2154
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2155
+ "p",
2156
+ {
2157
+ ref,
2158
+ id: `${ctx.id}-message`,
2159
+ className: cn("text-xs text-danger-soft-fg", className),
2160
+ role: "alert",
2161
+ ...props,
2162
+ children: message
2163
+ }
2164
+ );
2165
+ }
2166
+ );
2167
+ FormMessage.displayName = "FormMessage";
2168
+
2169
+ // src/components/tabs.tsx
2170
+ var import_react24 = require("react");
2171
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2172
+ var TabsContext = (0, import_react24.createContext)(null);
2173
+ function useTabsContext() {
2174
+ const ctx = (0, import_react24.useContext)(TabsContext);
2175
+ if (!ctx) throw new Error("Tabs \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <Tabs> \u5185\u4F7F\u7528");
2176
+ return ctx;
2177
+ }
2178
+ var Tabs = (0, import_react24.forwardRef)(({ value, onValueChange, children, className }, ref) => {
2179
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContext.Provider, { value: { value, onValueChange }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { ref, className: cn("w-full", className), children }) });
2180
+ });
2181
+ var TabsList = (0, import_react24.forwardRef)(({ className, children, ...props }, ref) => {
2182
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2183
+ "div",
2184
+ {
2185
+ ref,
2186
+ role: "tablist",
2187
+ className: cn("inline-flex w-full items-center gap-0 border-b border-border-base", className),
2188
+ ...props,
2189
+ children
2190
+ }
2191
+ );
2192
+ });
2193
+ var TabsTrigger = (0, import_react24.forwardRef)(({ value, className, children, ...props }, ref) => {
2194
+ const { value: activeValue, onValueChange } = useTabsContext();
2195
+ const isActive = activeValue === value;
2196
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2197
+ "button",
2198
+ {
2199
+ ref,
2200
+ type: "button",
2201
+ role: "tab",
2202
+ "aria-selected": isActive,
2203
+ tabIndex: isActive ? 0 : -1,
2204
+ onClick: () => onValueChange(value),
2205
+ className: cn(
2206
+ "relative px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-1",
2207
+ "after:absolute after:bottom-0 after:left-0 after:h-0.5 after:w-full after:transition-colors",
2208
+ isActive ? "text-text-primary after:bg-primary" : "text-text-secondary hover:text-text-primary after:bg-transparent",
2209
+ className
2210
+ ),
2211
+ ...props,
2212
+ children
2213
+ }
2214
+ );
2215
+ });
2216
+ var TabsContent = (0, import_react24.forwardRef)(({ value, className, children, ...props }, ref) => {
2217
+ const { value: activeValue } = useTabsContext();
2218
+ if (activeValue !== value) return null;
2219
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2220
+ "div",
2221
+ {
2222
+ ref,
2223
+ role: "tabpanel",
2224
+ tabIndex: 0,
2225
+ className: cn("mt-4 focus-visible:outline-none", className),
2226
+ ...props,
2227
+ children
2228
+ }
2229
+ );
2230
+ });
2231
+ Tabs.displayName = "Tabs";
2232
+ TabsList.displayName = "TabsList";
2233
+ TabsTrigger.displayName = "TabsTrigger";
2234
+ TabsContent.displayName = "TabsContent";
2235
+
2236
+ // src/components/accordion.tsx
2237
+ var import_react25 = require("react");
2238
+ var import_lucide_react12 = require("lucide-react");
2239
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2240
+ var AccordionContext = (0, import_react25.createContext)(null);
2241
+ var AccordionItemContext = (0, import_react25.createContext)(null);
2242
+ function useAccordionContext() {
2243
+ const ctx = (0, import_react25.useContext)(AccordionContext);
2244
+ if (!ctx) throw new Error("Accordion \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <Accordion> \u5185\u4F7F\u7528");
2245
+ return ctx;
2246
+ }
2247
+ function useAccordionItemContext() {
2248
+ const ctx = (0, import_react25.useContext)(AccordionItemContext);
2249
+ if (!ctx) throw new Error("AccordionTrigger/AccordionContent \u5FC5\u987B\u5728 <AccordionItem> \u5185\u4F7F\u7528");
2250
+ return ctx;
2251
+ }
2252
+ var Accordion = (0, import_react25.forwardRef)(
2253
+ (props, ref) => {
2254
+ const { type, children, className, ...rest } = props;
2255
+ const isSingle = type === "single";
2256
+ const singleProps = isSingle ? props : null;
2257
+ const multiProps = !isSingle ? props : null;
2258
+ const [internalSingle, setInternalSingle] = (0, import_react25.useState)(singleProps?.defaultValue ?? "");
2259
+ const [internalMulti, setInternalMulti] = (0, import_react25.useState)(multiProps?.defaultValue ?? []);
2260
+ const isControlledSingle = isSingle && singleProps?.value !== void 0;
2261
+ const isControlledMulti = !isSingle && multiProps?.value !== void 0;
2262
+ const value = isSingle ? isControlledSingle ? singleProps.value ?? "" : internalSingle : isControlledMulti ? multiProps.value ?? [] : internalMulti;
2263
+ const collapsible = isSingle ? singleProps?.collapsible ?? false : false;
2264
+ function handleValueChange(itemValue) {
2265
+ if (isSingle) {
2266
+ const current = value;
2267
+ const next = current === itemValue && collapsible ? "" : itemValue;
2268
+ if (!isControlledSingle) setInternalSingle(next);
2269
+ singleProps?.onValueChange?.(next);
2270
+ } else {
2271
+ const current = value;
2272
+ const next = current.includes(itemValue) ? current.filter((v) => v !== itemValue) : [...current, itemValue];
2273
+ if (!isControlledMulti) setInternalMulti(next);
2274
+ multiProps?.onValueChange?.(next);
2275
+ }
2276
+ }
2277
+ const { defaultValue: _dv, onValueChange: _ov, collapsible: _col, ...domRest } = rest;
2278
+ void _dv;
2279
+ void _ov;
2280
+ void _col;
2281
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AccordionContext.Provider, { value: { type, value, onValueChange: handleValueChange, collapsible }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref, className: cn("w-full divide-y divide-border-base rounded-md border border-border-base", className), ...domRest, children }) });
2282
+ }
2283
+ );
2284
+ Accordion.displayName = "Accordion";
2285
+ var AccordionItem = (0, import_react25.forwardRef)(({ value, className, children, ...props }, ref) => {
2286
+ const { value: activeValue, type } = useAccordionContext();
2287
+ const isOpen = type === "single" ? activeValue === value : activeValue.includes(value);
2288
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AccordionItemContext.Provider, { value: { value, isOpen }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref, className: cn("", className), ...props, children }) });
2289
+ });
2290
+ AccordionItem.displayName = "AccordionItem";
2291
+ var AccordionTrigger = (0, import_react25.forwardRef)(({ className, children, ...props }, ref) => {
2292
+ const { onValueChange } = useAccordionContext();
2293
+ const { value, isOpen } = useAccordionItemContext();
2294
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2295
+ "button",
2296
+ {
2297
+ ref,
2298
+ type: "button",
2299
+ "aria-expanded": isOpen,
2300
+ onClick: () => onValueChange(value),
2301
+ className: cn(
2302
+ "flex w-full items-center justify-between px-4 py-3 text-left text-sm font-medium text-text-primary transition-colors hover:bg-surface-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-inset",
2303
+ className
2304
+ ),
2305
+ ...props,
2306
+ children: [
2307
+ children,
2308
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2309
+ import_lucide_react12.ChevronDown,
2310
+ {
2311
+ size: 16,
2312
+ className: cn("shrink-0 text-text-secondary transition-transform duration-200", isOpen && "rotate-180")
2313
+ }
2314
+ )
2315
+ ]
2316
+ }
2317
+ );
2318
+ });
2319
+ AccordionTrigger.displayName = "AccordionTrigger";
2320
+ var AccordionContent = (0, import_react25.forwardRef)(({ className, children, ...props }, ref) => {
2321
+ const { isOpen } = useAccordionItemContext();
2322
+ if (!isOpen) return null;
2323
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2324
+ "div",
2325
+ {
2326
+ ref,
2327
+ className: cn("px-4 pb-4 pt-1 text-sm text-text-secondary", className),
2328
+ ...props,
2329
+ children
2330
+ }
2331
+ );
2332
+ });
2333
+ AccordionContent.displayName = "AccordionContent";
2334
+
2335
+ // src/components/steps.tsx
2336
+ var import_react26 = require("react");
2337
+ var import_lucide_react13 = require("lucide-react");
2338
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2339
+ var Steps = (0, import_react26.forwardRef)(
2340
+ ({ current, items, direction = "horizontal", status = "process", className, ...props }, ref) => {
2341
+ const isHorizontal = direction === "horizontal";
2342
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2343
+ "div",
2344
+ {
2345
+ ref,
2346
+ className: cn(
2347
+ isHorizontal ? "flex items-start" : "flex flex-col gap-1",
2348
+ className
2349
+ ),
2350
+ ...props,
2351
+ children: items.map((item, index) => {
2352
+ const isFinished = index < current || index === current && status === "finish";
2353
+ const isCurrent = index === current && status !== "finish";
2354
+ const isError = index === current && status === "error";
2355
+ const isLast = index === items.length - 1;
2356
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2357
+ "div",
2358
+ {
2359
+ className: cn(
2360
+ isHorizontal ? "flex flex-1 items-start" : "flex items-start"
2361
+ ),
2362
+ children: [
2363
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cn("flex", isHorizontal ? "flex-col items-center" : "items-start"), children: [
2364
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2365
+ "div",
2366
+ {
2367
+ className: cn(
2368
+ "flex h-9 w-9 shrink-0 items-center justify-center rounded-full border-2 text-sm font-semibold shadow-sm transition-colors",
2369
+ isFinished && "border-primary bg-primary text-primary-fg shadow-primary/20",
2370
+ isCurrent && !isError && "border-primary bg-primary-soft text-primary-soft-fg shadow-primary/10",
2371
+ isError && "border-danger bg-danger-soft text-danger-soft-fg shadow-danger/10",
2372
+ !isFinished && !isCurrent && !isError && "border-border-strong bg-surface-1 text-text-tertiary"
2373
+ ),
2374
+ children: isFinished ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Check, { size: 16, strokeWidth: 2.5 }) : item.icon ?? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: index + 1 })
2375
+ }
2376
+ ),
2377
+ !isLast && !isHorizontal && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2378
+ "div",
2379
+ {
2380
+ className: cn(
2381
+ "ml-[17px] mt-1 w-0.5 flex-1 self-stretch rounded-full",
2382
+ isFinished ? "bg-primary" : "bg-border-strong"
2383
+ ),
2384
+ style: { minHeight: "26px" }
2385
+ }
2386
+ )
2387
+ ] }),
2388
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2389
+ "div",
2390
+ {
2391
+ className: cn(
2392
+ isHorizontal ? "mt-2 text-center" : "ml-3.5 pb-5",
2393
+ isLast && !isHorizontal && "pb-0"
2394
+ ),
2395
+ children: [
2396
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2397
+ "p",
2398
+ {
2399
+ className: cn(
2400
+ "text-sm font-semibold leading-5",
2401
+ isFinished && "text-text-primary",
2402
+ isCurrent && !isError && "text-primary",
2403
+ isError && "text-danger",
2404
+ !isFinished && !isCurrent && !isError && "text-text-tertiary"
2405
+ ),
2406
+ children: item.title
2407
+ }
2408
+ ),
2409
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2410
+ "p",
2411
+ {
2412
+ className: cn(
2413
+ "mt-0.5 text-xs leading-5",
2414
+ isError ? "text-danger" : "text-text-secondary"
2415
+ ),
2416
+ children: item.description
2417
+ }
2418
+ )
2419
+ ]
2420
+ }
2421
+ ),
2422
+ !isLast && isHorizontal && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2423
+ "div",
2424
+ {
2425
+ className: cn(
2426
+ "mx-2 mt-4 h-0.5 flex-1",
2427
+ isFinished ? "bg-primary" : "bg-border-base"
2428
+ )
2429
+ }
2430
+ )
2431
+ ]
2432
+ },
2433
+ index
2434
+ );
2435
+ })
2436
+ }
2437
+ );
2438
+ }
2439
+ );
2440
+ Steps.displayName = "Steps";
2441
+
2442
+ // src/components/dropdown.tsx
2443
+ var import_react27 = require("react");
2444
+ var import_react_dom5 = require("react-dom");
2445
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2446
+ var DropdownContext = (0, import_react27.createContext)(null);
2447
+ function assignRef(ref, value) {
2448
+ if (typeof ref === "function") {
2449
+ ref(value);
2450
+ return;
2451
+ }
2452
+ if (ref) {
2453
+ ref.current = value;
2454
+ }
2455
+ }
2456
+ function useDropdownContext() {
2457
+ const ctx = (0, import_react27.useContext)(DropdownContext);
2458
+ if (!ctx) throw new Error("Dropdown \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <DropdownMenu> \u5185\u4F7F\u7528");
2459
+ return ctx;
2460
+ }
2461
+ var DropdownMenu = (0, import_react27.forwardRef)(({ children, className }, ref) => {
2462
+ const [open, setOpen] = (0, import_react27.useState)(false);
2463
+ const triggerRef = (0, import_react27.useRef)(null);
2464
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DropdownContext.Provider, { value: { open, setOpen, triggerRef }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref, className: cn("relative inline-block", className), children }) });
2465
+ });
2466
+ var DropdownTrigger = (0, import_react27.forwardRef)(({ children, className }, ref) => {
2467
+ const { setOpen, open, triggerRef } = useDropdownContext();
2468
+ const handleRef = (0, import_react27.useCallback)(
2469
+ (node) => {
2470
+ triggerRef.current = node;
2471
+ assignRef(ref, node);
2472
+ },
2473
+ [ref, triggerRef]
2474
+ );
2475
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2476
+ "div",
2477
+ {
2478
+ ref: handleRef,
2479
+ className: cn("inline-flex cursor-pointer", className),
2480
+ onClick: () => setOpen(!open),
2481
+ children
2482
+ }
2483
+ );
2484
+ });
2485
+ var DropdownContent = (0, import_react27.forwardRef)(({ children, className, align = "start" }, ref) => {
2486
+ const { open, setOpen, triggerRef } = useDropdownContext();
2487
+ const contentRef = (0, import_react27.useRef)(null);
2488
+ const portalContainer = usePortalContainer();
2489
+ const [position, setPosition] = (0, import_react27.useState)({ top: 0, left: 0 });
2490
+ const handleRef = (0, import_react27.useCallback)(
2491
+ (node) => {
2492
+ contentRef.current = node;
2493
+ assignRef(ref, node);
2494
+ },
2495
+ [ref]
2496
+ );
2497
+ const updatePosition = (0, import_react27.useCallback)(() => {
2498
+ if (!triggerRef.current) return;
2499
+ const rect = triggerRef.current.getBoundingClientRect();
2500
+ const top = rect.bottom + window.scrollY + 4;
2501
+ const left = align === "end" ? rect.right + window.scrollX - (contentRef.current?.offsetWidth ?? 0) : rect.left + window.scrollX;
2502
+ setPosition({ top, left });
2503
+ }, [align, triggerRef]);
2504
+ (0, import_react27.useEffect)(() => {
2505
+ if (!open) return;
2506
+ updatePosition();
2507
+ }, [open, updatePosition]);
2508
+ (0, import_react27.useEffect)(() => {
2509
+ if (!open) return;
2510
+ function handleClickOutside(e) {
2511
+ if (contentRef.current && !contentRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
2512
+ setOpen(false);
2513
+ }
2514
+ }
2515
+ document.addEventListener("mousedown", handleClickOutside);
2516
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2517
+ }, [open, setOpen, triggerRef]);
2518
+ if (!open || !portalContainer) return null;
2519
+ return (0, import_react_dom5.createPortal)(
2520
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2521
+ "div",
2522
+ {
2523
+ ref: handleRef,
2524
+ style: { top: position.top, left: position.left },
2525
+ className: cn(
2526
+ "absolute z-50 min-w-44 overflow-hidden rounded-lg border border-border-base bg-surface-1 p-1 text-text-primary shadow-xl",
2527
+ className
2528
+ ),
2529
+ children
2530
+ }
2531
+ ),
2532
+ portalContainer
2533
+ );
2534
+ });
2535
+ var DropdownItem = (0, import_react27.forwardRef)(({ children, className, destructive = false, onClick, ...props }, ref) => {
2536
+ const { setOpen } = useDropdownContext();
2537
+ function handleClick(e) {
2538
+ setOpen(false);
2539
+ onClick?.(e);
2540
+ }
2541
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2542
+ "button",
2543
+ {
2544
+ ref,
2545
+ type: "button",
2546
+ className: cn(
2547
+ "flex min-h-8 w-full items-center gap-2 rounded-md px-2.5 py-2 text-left text-sm leading-none transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50",
2548
+ destructive ? "text-danger hover:bg-danger-soft focus-visible:bg-danger-soft" : "text-text-primary hover:bg-surface-2 focus-visible:bg-surface-2",
2549
+ className
2550
+ ),
2551
+ onClick: handleClick,
2552
+ ...props,
2553
+ children
2554
+ }
2555
+ );
2556
+ });
2557
+ var DropdownSeparator = (0, import_react27.forwardRef)(({ className, ...props }, ref) => {
2558
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref, className: cn("-mx-1 my-1 h-px bg-border-base", className), ...props });
2559
+ });
2560
+ DropdownMenu.displayName = "DropdownMenu";
2561
+ DropdownTrigger.displayName = "DropdownTrigger";
2562
+ DropdownContent.displayName = "DropdownContent";
2563
+ DropdownItem.displayName = "DropdownItem";
2564
+ DropdownSeparator.displayName = "DropdownSeparator";
2565
+
2566
+ // src/components/popover.tsx
2567
+ var import_react28 = require("react");
2568
+ var import_react_dom6 = require("react-dom");
2569
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2570
+ var PopoverContext = (0, import_react28.createContext)(null);
2571
+ function usePopoverContext() {
2572
+ const ctx = (0, import_react28.useContext)(PopoverContext);
2573
+ if (!ctx) throw new Error("Popover \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <Popover> \u5185\u4F7F\u7528");
2574
+ return ctx;
2575
+ }
2576
+ function assignRef2(ref, value) {
2577
+ if (typeof ref === "function") {
2578
+ ref(value);
2579
+ return;
2580
+ }
2581
+ if (ref) {
2582
+ ref.current = value;
2583
+ }
2584
+ }
2585
+ var Popover = ({ open: controlledOpen, defaultOpen = false, onOpenChange, children }) => {
2586
+ const [internalOpen, setInternalOpen] = (0, import_react28.useState)(defaultOpen);
2587
+ const triggerRef = (0, import_react28.useRef)(null);
2588
+ const isControlled = controlledOpen !== void 0;
2589
+ const open = isControlled ? controlledOpen : internalOpen;
2590
+ const setOpen = (0, import_react28.useCallback)(
2591
+ (value) => {
2592
+ if (!isControlled) setInternalOpen(value);
2593
+ onOpenChange?.(value);
2594
+ },
2595
+ [isControlled, onOpenChange]
2596
+ );
2597
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PopoverContext.Provider, { value: { open, setOpen, triggerRef }, children });
2598
+ };
2599
+ Popover.displayName = "Popover";
2600
+ var PopoverTrigger = (0, import_react28.forwardRef)(({ children, className }, ref) => {
2601
+ const { setOpen, open, triggerRef } = usePopoverContext();
2602
+ const handleRef = (0, import_react28.useCallback)(
2603
+ (node) => {
2604
+ triggerRef.current = node;
2605
+ assignRef2(ref, node);
2606
+ },
2607
+ [ref, triggerRef]
2608
+ );
2609
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2610
+ "div",
2611
+ {
2612
+ ref: handleRef,
2613
+ className: cn("inline-flex", className),
2614
+ onClick: () => setOpen(!open),
2615
+ children
2616
+ }
2617
+ );
2618
+ });
2619
+ PopoverTrigger.displayName = "PopoverTrigger";
2620
+ function calcPosition(triggerRect, contentEl, side, align, sideOffset) {
2621
+ const cw = contentEl.offsetWidth;
2622
+ const ch = contentEl.offsetHeight;
2623
+ let top = 0;
2624
+ let left = 0;
2625
+ if (side === "bottom") {
2626
+ top = triggerRect.bottom + window.scrollY + sideOffset;
2627
+ } else if (side === "top") {
2628
+ top = triggerRect.top + window.scrollY - ch - sideOffset;
2629
+ } else if (side === "left") {
2630
+ top = triggerRect.top + window.scrollY + triggerRect.height / 2 - ch / 2;
2631
+ left = triggerRect.left + window.scrollX - cw - sideOffset;
2632
+ return { top, left };
2633
+ } else {
2634
+ top = triggerRect.top + window.scrollY + triggerRect.height / 2 - ch / 2;
2635
+ left = triggerRect.right + window.scrollX + sideOffset;
2636
+ return { top, left };
2637
+ }
2638
+ if (align === "start") {
2639
+ left = triggerRect.left + window.scrollX;
2640
+ } else if (align === "end") {
2641
+ left = triggerRect.right + window.scrollX - cw;
2642
+ } else {
2643
+ left = triggerRect.left + window.scrollX + triggerRect.width / 2 - cw / 2;
2644
+ }
2645
+ return { top, left };
2646
+ }
2647
+ var PopoverContent = (0, import_react28.forwardRef)(
2648
+ ({ children, className, side = "bottom", align = "center", sideOffset = 4, ...props }, ref) => {
2649
+ const { open, setOpen, triggerRef } = usePopoverContext();
2650
+ const contentRef = (0, import_react28.useRef)(null);
2651
+ const portalContainer = usePortalContainer();
2652
+ const [pos, setPos] = (0, import_react28.useState)({ top: 0, left: 0 });
2653
+ const handleRef = (0, import_react28.useCallback)(
2654
+ (node) => {
2655
+ contentRef.current = node;
2656
+ assignRef2(ref, node);
2657
+ },
2658
+ [ref]
2659
+ );
2660
+ const updatePos = (0, import_react28.useCallback)(() => {
2661
+ if (!triggerRef.current || !contentRef.current) return;
2662
+ const rect = triggerRef.current.getBoundingClientRect();
2663
+ setPos(calcPosition(rect, contentRef.current, side, align, sideOffset));
2664
+ }, [side, align, sideOffset, triggerRef]);
2665
+ (0, import_react28.useEffect)(() => {
2666
+ if (open) updatePos();
2667
+ }, [open, updatePos]);
2668
+ (0, import_react28.useEffect)(() => {
2669
+ if (!open) return;
2670
+ function handleMouseDown(e) {
2671
+ if (contentRef.current && !contentRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
2672
+ setOpen(false);
2673
+ }
2674
+ }
2675
+ document.addEventListener("mousedown", handleMouseDown);
2676
+ return () => document.removeEventListener("mousedown", handleMouseDown);
2677
+ }, [open, setOpen, triggerRef]);
2678
+ if (!open || !portalContainer) return null;
2679
+ return (0, import_react_dom6.createPortal)(
2680
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2681
+ "div",
2682
+ {
2683
+ ref: handleRef,
2684
+ style: { top: pos.top, left: pos.left },
2685
+ className: cn(
2686
+ "absolute z-50 min-w-40 rounded-md border border-border-base bg-surface-1 p-3 shadow-lg",
2687
+ className
2688
+ ),
2689
+ ...props,
2690
+ children
2691
+ }
2692
+ ),
2693
+ portalContainer
2694
+ );
2695
+ }
2696
+ );
2697
+ PopoverContent.displayName = "PopoverContent";
2698
+
2699
+ // src/components/context-menu.tsx
2700
+ var import_react29 = require("react");
2701
+ var import_react_dom7 = require("react-dom");
2702
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2703
+ var ContextMenuContext = (0, import_react29.createContext)(null);
2704
+ function useContextMenuContext() {
2705
+ const ctx = (0, import_react29.useContext)(ContextMenuContext);
2706
+ if (!ctx) throw new Error("ContextMenu \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <ContextMenu> \u5185\u4F7F\u7528");
2707
+ return ctx;
2708
+ }
2709
+ function assignRef3(ref, value) {
2710
+ if (typeof ref === "function") {
2711
+ ref(value);
2712
+ return;
2713
+ }
2714
+ if (ref) {
2715
+ ref.current = value;
2716
+ }
2717
+ }
2718
+ var ContextMenu = (0, import_react29.forwardRef)(
2719
+ ({ children, className }, ref) => {
2720
+ const [open, setOpen] = (0, import_react29.useState)(false);
2721
+ const [position, setPosition] = (0, import_react29.useState)({ x: 0, y: 0 });
2722
+ const openAt = (0, import_react29.useCallback)((pos) => {
2723
+ setPosition(pos);
2724
+ setOpen(true);
2725
+ }, []);
2726
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ContextMenuContext.Provider, { value: { open, position, setOpen, openAt }, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { ref, className: cn("relative", className), children }) });
2727
+ }
2728
+ );
2729
+ var ContextMenuTrigger = (0, import_react29.forwardRef)(
2730
+ ({ children, className, ...props }, ref) => {
2731
+ const { openAt } = useContextMenuContext();
2732
+ function handleContextMenu(e) {
2733
+ e.preventDefault();
2734
+ openAt({ x: e.clientX, y: e.clientY });
2735
+ }
2736
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2737
+ "div",
2738
+ {
2739
+ ref,
2740
+ className: cn(className),
2741
+ onContextMenu: handleContextMenu,
2742
+ ...props,
2743
+ children
2744
+ }
2745
+ );
2746
+ }
2747
+ );
2748
+ var ContextMenuContent = (0, import_react29.forwardRef)(
2749
+ ({ children, className, ...props }, ref) => {
2750
+ const { open, position, setOpen } = useContextMenuContext();
2751
+ const contentRef = (0, import_react29.useRef)(null);
2752
+ const portalContainer = usePortalContainer();
2753
+ const handleRef = (0, import_react29.useCallback)(
2754
+ (node) => {
2755
+ contentRef.current = node;
2756
+ assignRef3(ref, node);
2757
+ },
2758
+ [ref]
2759
+ );
2760
+ (0, import_react29.useEffect)(() => {
2761
+ if (!open) return;
2762
+ function handleMouseDown(e) {
2763
+ if (contentRef.current && !contentRef.current.contains(e.target)) {
2764
+ setOpen(false);
2765
+ }
2766
+ }
2767
+ function handleKeyDown(e) {
2768
+ if (e.key === "Escape") {
2769
+ setOpen(false);
2770
+ }
2771
+ }
2772
+ document.addEventListener("mousedown", handleMouseDown);
2773
+ document.addEventListener("keydown", handleKeyDown);
2774
+ return () => {
2775
+ document.removeEventListener("mousedown", handleMouseDown);
2776
+ document.removeEventListener("keydown", handleKeyDown);
2777
+ };
2778
+ }, [open, setOpen]);
2779
+ if (!open || !portalContainer) return null;
2780
+ return (0, import_react_dom7.createPortal)(
2781
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2782
+ "div",
2783
+ {
2784
+ ref: handleRef,
2785
+ style: { top: position.y, left: position.x },
2786
+ className: cn(
2787
+ "fixed z-50 min-w-40 rounded-md border border-border-base bg-surface-1 py-1 shadow-lg",
2788
+ className
2789
+ ),
2790
+ ...props,
2791
+ children
2792
+ }
2793
+ ),
2794
+ portalContainer
2795
+ );
2796
+ }
2797
+ );
2798
+ var ContextMenuItem = (0, import_react29.forwardRef)(
2799
+ ({ children, className, destructive = false, onClick, ...props }, ref) => {
2800
+ const { setOpen } = useContextMenuContext();
2801
+ function handleClick(e) {
2802
+ setOpen(false);
2803
+ onClick?.(e);
2804
+ }
2805
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2806
+ "button",
2807
+ {
2808
+ ref,
2809
+ type: "button",
2810
+ className: cn(
2811
+ "w-full px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:bg-surface-3",
2812
+ destructive ? "text-danger hover:bg-danger-soft/10" : "text-text-primary hover:bg-surface-3",
2813
+ className
2814
+ ),
2815
+ onClick: handleClick,
2816
+ ...props,
2817
+ children
2818
+ }
2819
+ );
2820
+ }
2821
+ );
2822
+ var ContextMenuSeparator = (0, import_react29.forwardRef)(
2823
+ ({ className, ...props }, ref) => {
2824
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { ref, className: cn("my-1 h-px bg-border-base", className), ...props });
2825
+ }
2826
+ );
2827
+ ContextMenu.displayName = "ContextMenu";
2828
+ ContextMenuTrigger.displayName = "ContextMenuTrigger";
2829
+ ContextMenuContent.displayName = "ContextMenuContent";
2830
+ ContextMenuItem.displayName = "ContextMenuItem";
2831
+ ContextMenuSeparator.displayName = "ContextMenuSeparator";
2832
+
2833
+ // src/components/navigation-menu.tsx
2834
+ var import_react30 = require("react");
2835
+ var import_lucide_react14 = require("lucide-react");
2836
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2837
+ var NavigationMenuContext = (0, import_react30.createContext)(null);
2838
+ function useNavigationMenuContext() {
2839
+ const ctx = (0, import_react30.useContext)(NavigationMenuContext);
2840
+ if (!ctx) throw new Error("NavigationMenu \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <NavigationMenu> \u5185\u4F7F\u7528");
2841
+ return ctx;
2842
+ }
2843
+ var NavigationMenuItemContext = (0, import_react30.createContext)(null);
2844
+ function useNavigationMenuItemContext() {
2845
+ const ctx = (0, import_react30.useContext)(NavigationMenuItemContext);
2846
+ if (!ctx) throw new Error("NavigationMenuTrigger/Content \u5FC5\u987B\u5728 <NavigationMenuItem> \u5185\u4F7F\u7528");
2847
+ return ctx;
2848
+ }
2849
+ var _idCounter = 0;
2850
+ var NavigationMenu = (0, import_react30.forwardRef)(
2851
+ ({ className, children, ...props }, ref) => {
2852
+ const [activeItem, setActiveItem] = (0, import_react30.useState)(null);
2853
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(NavigationMenuContext.Provider, { value: { activeItem, setActiveItem }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2854
+ "nav",
2855
+ {
2856
+ ref,
2857
+ className: cn("relative flex items-center gap-1", className),
2858
+ ...props,
2859
+ children
2860
+ }
2861
+ ) });
2862
+ }
2863
+ );
2864
+ var NavigationMenuItem = (0, import_react30.forwardRef)(
2865
+ ({ className, children, ...props }, ref) => {
2866
+ const itemIdRef = (0, import_react30.useRef)(`nav-item-${++_idCounter}`);
2867
+ const { activeItem, setActiveItem } = useNavigationMenuContext();
2868
+ const isOpen = activeItem === itemIdRef.current;
2869
+ const handleMouseEnter = (0, import_react30.useCallback)(() => {
2870
+ setActiveItem(itemIdRef.current);
2871
+ }, [setActiveItem]);
2872
+ const handleMouseLeave = (0, import_react30.useCallback)(() => {
2873
+ setActiveItem(null);
2874
+ }, [setActiveItem]);
2875
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(NavigationMenuItemContext.Provider, { value: { itemId: itemIdRef.current }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2876
+ "div",
2877
+ {
2878
+ ref,
2879
+ className: cn("relative", className),
2880
+ onMouseEnter: handleMouseEnter,
2881
+ onMouseLeave: handleMouseLeave,
2882
+ "data-state": isOpen ? "open" : "closed",
2883
+ ...props,
2884
+ children
2885
+ }
2886
+ ) });
2887
+ }
2888
+ );
2889
+ var NavigationMenuLink = (0, import_react30.forwardRef)(
2890
+ ({ className, active = false, children, ...props }, ref) => {
2891
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2892
+ "a",
2893
+ {
2894
+ ref,
2895
+ className: cn(
2896
+ "inline-flex items-center rounded-md px-3 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-1",
2897
+ active ? "bg-surface-3 text-text-primary" : "text-text-secondary hover:bg-surface-3 hover:text-text-primary",
2898
+ className
2899
+ ),
2900
+ ...props,
2901
+ children
2902
+ }
2903
+ );
2904
+ }
2905
+ );
2906
+ var NavigationMenuTrigger = (0, import_react30.forwardRef)(
2907
+ ({ className, children, ...props }, ref) => {
2908
+ const { activeItem } = useNavigationMenuContext();
2909
+ const { itemId } = useNavigationMenuItemContext();
2910
+ const isOpen = activeItem === itemId;
2911
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
2912
+ "button",
2913
+ {
2914
+ ref,
2915
+ type: "button",
2916
+ "aria-expanded": isOpen,
2917
+ className: cn(
2918
+ "inline-flex items-center gap-1 rounded-md px-3 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-1",
2919
+ isOpen ? "bg-surface-3 text-text-primary" : "text-text-secondary hover:bg-surface-3 hover:text-text-primary",
2920
+ className
2921
+ ),
2922
+ ...props,
2923
+ children: [
2924
+ children,
2925
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2926
+ import_lucide_react14.ChevronDown,
2927
+ {
2928
+ size: 14,
2929
+ className: cn("transition-transform duration-200", isOpen && "rotate-180")
2930
+ }
2931
+ )
2932
+ ]
2933
+ }
2934
+ );
2935
+ }
2936
+ );
2937
+ var NavigationMenuContent = (0, import_react30.forwardRef)(
2938
+ ({ className, children, ...props }, ref) => {
2939
+ const { activeItem } = useNavigationMenuContext();
2940
+ const { itemId } = useNavigationMenuItemContext();
2941
+ const isOpen = activeItem === itemId;
2942
+ if (!isOpen) return null;
2943
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2944
+ "div",
2945
+ {
2946
+ ref,
2947
+ className: cn(
2948
+ "absolute left-0 top-full z-50 mt-1 min-w-40 rounded-md border border-border-base bg-surface-1 py-1 shadow-lg",
2949
+ className
2950
+ ),
2951
+ ...props,
2952
+ children
2953
+ }
2954
+ );
2955
+ }
2956
+ );
2957
+ NavigationMenu.displayName = "NavigationMenu";
2958
+ NavigationMenuItem.displayName = "NavigationMenuItem";
2959
+ NavigationMenuLink.displayName = "NavigationMenuLink";
2960
+ NavigationMenuTrigger.displayName = "NavigationMenuTrigger";
2961
+ NavigationMenuContent.displayName = "NavigationMenuContent";
2962
+
2963
+ // src/components/avatar.tsx
2964
+ var import_react31 = require("react");
2965
+ var import_lucide_react15 = require("lucide-react");
2966
+ var import_class_variance_authority8 = require("class-variance-authority");
2967
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2968
+ var AvatarContext = (0, import_react31.createContext)(null);
2969
+ function useAvatarContext(componentName) {
2970
+ const ctx = (0, import_react31.useContext)(AvatarContext);
2971
+ if (!ctx) {
2972
+ throw new Error(`<${componentName}> \u5FC5\u987B\u5728 <Avatar> \u5185\u4F7F\u7528`);
2973
+ }
2974
+ return ctx;
2975
+ }
2976
+ var avatarVariants = (0, import_class_variance_authority8.cva)(
2977
+ "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-surface-3",
2978
+ {
2979
+ variants: {
2980
+ size: {
2981
+ sm: "h-8 w-8 text-xs",
2982
+ md: "h-10 w-10 text-sm",
2983
+ lg: "h-14 w-14 text-base",
2984
+ xl: "h-20 w-20 text-xl"
2985
+ }
2986
+ },
2987
+ defaultVariants: { size: "md" }
2988
+ }
2989
+ );
2990
+ var Avatar = (0, import_react31.forwardRef)(
2991
+ ({ size, className, children, ...props }, ref) => {
2992
+ const [imageLoadingStatus, setImageLoadingStatus] = (0, import_react31.useState)("idle");
2993
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(AvatarContext.Provider, { value: { imageLoadingStatus, setImageLoadingStatus }, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { ref, className: cn(avatarVariants({ size }), className), ...props, children }) });
2994
+ }
2995
+ );
2996
+ var AvatarImage = (0, import_react31.forwardRef)(
2997
+ ({ src, alt = "", className, onLoad, onError, ...props }, ref) => {
2998
+ const { imageLoadingStatus, setImageLoadingStatus } = useAvatarContext("AvatarImage");
2999
+ (0, import_react31.useEffect)(() => {
3000
+ if (!src) {
3001
+ setImageLoadingStatus("error");
3002
+ return;
3003
+ }
3004
+ setImageLoadingStatus("loading");
3005
+ }, [src, setImageLoadingStatus]);
3006
+ if (imageLoadingStatus !== "loaded" && imageLoadingStatus !== "loading") {
3007
+ return null;
3008
+ }
3009
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
3010
+ "img",
3011
+ {
3012
+ ref,
3013
+ src,
3014
+ alt,
3015
+ onLoad: (event) => {
3016
+ setImageLoadingStatus("loaded");
3017
+ onLoad?.(event);
3018
+ },
3019
+ onError: (event) => {
3020
+ setImageLoadingStatus("error");
3021
+ onError?.(event);
3022
+ },
3023
+ className: cn(
3024
+ "h-full w-full object-cover",
3025
+ imageLoadingStatus === "loading" && "invisible",
3026
+ className
3027
+ ),
3028
+ ...props
3029
+ }
3030
+ );
3031
+ }
3032
+ );
3033
+ var AvatarFallback = (0, import_react31.forwardRef)(
3034
+ ({ className, children, ...props }, ref) => {
3035
+ const { imageLoadingStatus } = useAvatarContext("AvatarFallback");
3036
+ if (imageLoadingStatus === "loaded") return null;
3037
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
3038
+ "span",
3039
+ {
3040
+ ref,
3041
+ className: cn(
3042
+ "absolute inset-0 flex items-center justify-center font-medium text-text-secondary",
3043
+ className
3044
+ ),
3045
+ ...props,
3046
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react15.User, { size: 16 })
3047
+ }
3048
+ );
3049
+ }
3050
+ );
3051
+ Avatar.displayName = "Avatar";
3052
+ AvatarImage.displayName = "AvatarImage";
3053
+ AvatarFallback.displayName = "AvatarFallback";
3054
+
3055
+ // src/components/avatar-group.tsx
3056
+ var import_react32 = require("react");
3057
+ var import_jsx_runtime30 = require("react/jsx-runtime");
3058
+ var SIZE_CLASSES = {
3059
+ sm: "h-8 w-8 text-xs",
3060
+ default: "h-10 w-10 text-sm",
3061
+ lg: "h-14 w-14 text-base"
3062
+ };
3063
+ var RING_SIZE_CLASSES = {
3064
+ sm: "ring-2",
3065
+ default: "ring-2",
3066
+ lg: "ring-[3px]"
3067
+ };
3068
+ var OVERLAP_CLASSES = {
3069
+ sm: "-ml-1.5",
3070
+ default: "-ml-2",
3071
+ lg: "-ml-3"
3072
+ };
3073
+ var AvatarGroup = (0, import_react32.forwardRef)(
3074
+ ({ max = 5, size = "default", className, children, ...props }, ref) => {
3075
+ const allItems = import_react32.Children.toArray(children).filter(import_react32.isValidElement);
3076
+ const visibleItems = allItems.slice(0, max);
3077
+ const overflowCount = allItems.length - max;
3078
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
3079
+ "div",
3080
+ {
3081
+ ref,
3082
+ className: cn("flex max-w-full items-center overflow-hidden py-0.5", className),
3083
+ ...props,
3084
+ children: [
3085
+ visibleItems.map((child, idx) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3086
+ "span",
3087
+ {
3088
+ className: cn(
3089
+ "relative inline-flex shrink-0 overflow-hidden rounded-full border border-border-base bg-surface-2 ring-surface-1",
3090
+ SIZE_CLASSES[size],
3091
+ RING_SIZE_CLASSES[size],
3092
+ idx > 0 && OVERLAP_CLASSES[size]
3093
+ ),
3094
+ children: child
3095
+ },
3096
+ idx
3097
+ )),
3098
+ overflowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
3099
+ "span",
3100
+ {
3101
+ className: cn(
3102
+ "relative inline-flex shrink-0 items-center justify-center rounded-full border border-border-base bg-surface-2 font-medium text-text-secondary ring-surface-1",
3103
+ SIZE_CLASSES[size],
3104
+ RING_SIZE_CLASSES[size],
3105
+ OVERLAP_CLASSES[size]
3106
+ ),
3107
+ "aria-label": `\u8FD8\u6709 ${overflowCount} \u4EBA`,
3108
+ children: [
3109
+ "+",
3110
+ overflowCount
3111
+ ]
3112
+ }
3113
+ )
3114
+ ]
3115
+ }
3116
+ );
3117
+ }
3118
+ );
3119
+ AvatarGroup.displayName = "AvatarGroup";
3120
+
3121
+ // src/components/tooltip.tsx
3122
+ var import_react33 = require("react");
3123
+ var import_react_dom8 = require("react-dom");
3124
+ var import_jsx_runtime31 = require("react/jsx-runtime");
3125
+ var TooltipContext = (0, import_react33.createContext)(null);
3126
+ function assignRef4(ref, value) {
3127
+ if (typeof ref === "function") {
3128
+ ref(value);
3129
+ return;
3130
+ }
3131
+ if (ref) {
3132
+ ref.current = value;
3133
+ }
3134
+ }
3135
+ function useTooltipContext() {
3136
+ const ctx = (0, import_react33.useContext)(TooltipContext);
3137
+ if (!ctx) throw new Error("Tooltip \u5B50\u7EC4\u4EF6\u5FC5\u987B\u5728 <Tooltip> \u5185\u4F7F\u7528");
3138
+ return ctx;
3139
+ }
3140
+ var Tooltip = (0, import_react33.forwardRef)(({ children, className }, ref) => {
3141
+ const [open, setOpen] = (0, import_react33.useState)(false);
3142
+ const triggerRef = (0, import_react33.useRef)(null);
3143
+ const delayRef = (0, import_react33.useRef)(null);
3144
+ (0, import_react33.useEffect)(() => {
3145
+ return () => {
3146
+ if (delayRef.current) {
3147
+ clearTimeout(delayRef.current);
3148
+ }
3149
+ };
3150
+ }, []);
3151
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TooltipContext.Provider, { value: { open, setOpen, triggerRef, delayRef }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { ref, className: cn("relative inline-flex", className), children }) });
3152
+ });
3153
+ var TooltipTrigger = (0, import_react33.forwardRef)(({ children, className }, ref) => {
3154
+ const { setOpen, triggerRef, delayRef } = useTooltipContext();
3155
+ const handleRef = (0, import_react33.useCallback)(
3156
+ (node) => {
3157
+ triggerRef.current = node;
3158
+ assignRef4(ref, node);
3159
+ },
3160
+ [ref, triggerRef]
3161
+ );
3162
+ function handleMouseEnter() {
3163
+ delayRef.current = setTimeout(() => setOpen(true), 200);
3164
+ }
3165
+ function handleMouseLeave() {
3166
+ if (delayRef.current) clearTimeout(delayRef.current);
3167
+ setOpen(false);
3168
+ }
3169
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3170
+ "span",
3171
+ {
3172
+ ref: handleRef,
3173
+ className: cn("inline-flex", className),
3174
+ onMouseEnter: handleMouseEnter,
3175
+ onMouseLeave: handleMouseLeave,
3176
+ children
3177
+ }
3178
+ );
3179
+ });
3180
+ var arrowPositionClasses = {
3181
+ top: "after:absolute after:top-full after:left-1/2 after:-translate-x-1/2 after:border-4 after:border-transparent after:border-t-text-primary",
3182
+ bottom: "after:absolute after:bottom-full after:left-1/2 after:-translate-x-1/2 after:border-4 after:border-transparent after:border-b-text-primary",
3183
+ left: "after:absolute after:left-full after:top-1/2 after:-translate-y-1/2 after:border-4 after:border-transparent after:border-l-text-primary",
3184
+ right: "after:absolute after:right-full after:top-1/2 after:-translate-y-1/2 after:border-4 after:border-transparent after:border-r-text-primary"
3185
+ };
3186
+ var TooltipContent = (0, import_react33.forwardRef)(({ children, side = "top", className }, ref) => {
3187
+ const { open, triggerRef } = useTooltipContext();
3188
+ const contentRef = (0, import_react33.useRef)(null);
3189
+ const portalContainer = usePortalContainer();
3190
+ const [pos, setPos] = (0, import_react33.useState)({ top: 0, left: 0 });
3191
+ const handleRef = (0, import_react33.useCallback)(
3192
+ (node) => {
3193
+ contentRef.current = node;
3194
+ assignRef4(ref, node);
3195
+ },
3196
+ [ref]
3197
+ );
3198
+ const updatePos = (0, import_react33.useCallback)(() => {
3199
+ if (!triggerRef.current || !contentRef.current) return;
3200
+ const rect = triggerRef.current.getBoundingClientRect();
3201
+ const cw = contentRef.current.offsetWidth;
3202
+ const ch = contentRef.current.offsetHeight;
3203
+ const gap = 8;
3204
+ let top = 0;
3205
+ let left = 0;
3206
+ if (side === "top") {
3207
+ top = rect.top + window.scrollY - ch - gap;
3208
+ left = rect.left + window.scrollX + rect.width / 2 - cw / 2;
3209
+ } else if (side === "bottom") {
3210
+ top = rect.bottom + window.scrollY + gap;
3211
+ left = rect.left + window.scrollX + rect.width / 2 - cw / 2;
3212
+ } else if (side === "left") {
3213
+ top = rect.top + window.scrollY + rect.height / 2 - ch / 2;
3214
+ left = rect.left + window.scrollX - cw - gap;
3215
+ } else {
3216
+ top = rect.top + window.scrollY + rect.height / 2 - ch / 2;
3217
+ left = rect.right + window.scrollX + gap;
3218
+ }
3219
+ setPos({ top, left });
3220
+ }, [side, triggerRef]);
3221
+ (0, import_react33.useEffect)(() => {
3222
+ if (open) updatePos();
3223
+ }, [open, updatePos]);
3224
+ if (!open || !portalContainer) return null;
3225
+ return (0, import_react_dom8.createPortal)(
3226
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3227
+ "div",
3228
+ {
3229
+ ref: handleRef,
3230
+ style: { top: pos.top, left: pos.left },
3231
+ className: cn(
3232
+ "absolute z-50 rounded-md bg-text-primary px-2.5 py-1.5 text-xs text-surface-1 shadow-md",
3233
+ arrowPositionClasses[side],
3234
+ className
3235
+ ),
3236
+ children
3237
+ }
3238
+ ),
3239
+ portalContainer
3240
+ );
3241
+ });
3242
+ Tooltip.displayName = "Tooltip";
3243
+ TooltipTrigger.displayName = "TooltipTrigger";
3244
+ TooltipContent.displayName = "TooltipContent";
3245
+
3246
+ // src/components/alert.tsx
3247
+ var import_react34 = require("react");
3248
+ var import_lucide_react16 = require("lucide-react");
3249
+ var import_class_variance_authority9 = require("class-variance-authority");
3250
+ var import_jsx_runtime32 = require("react/jsx-runtime");
3251
+ var alertVariants = (0, import_class_variance_authority9.cva)(
3252
+ "relative flex gap-3 rounded-md border-l-4 p-4",
3253
+ {
3254
+ variants: {
3255
+ variant: {
3256
+ default: "border-l-primary bg-info-soft text-info-soft-fg",
3257
+ info: "border-l-info bg-info-soft text-info-soft-fg",
3258
+ success: "border-l-success bg-success-soft text-success-soft-fg",
3259
+ warning: "border-l-warning bg-warning-soft text-warning-soft-fg",
3260
+ destructive: "border-l-danger bg-danger-soft text-danger-soft-fg"
3261
+ }
3262
+ },
3263
+ defaultVariants: { variant: "default" }
3264
+ }
3265
+ );
3266
+ var iconMap = {
3267
+ default: import_lucide_react16.AlertCircle,
3268
+ info: import_lucide_react16.Info,
3269
+ success: import_lucide_react16.CheckCircle,
3270
+ warning: import_lucide_react16.AlertTriangle,
3271
+ destructive: import_lucide_react16.AlertCircle
3272
+ };
3273
+ var iconColorMap = {
3274
+ default: "text-info",
3275
+ info: "text-info",
3276
+ success: "text-success",
3277
+ warning: "text-warning",
3278
+ destructive: "text-danger"
3279
+ };
3280
+ var Alert = (0, import_react34.forwardRef)(
3281
+ ({ variant = "default", className, children, ...props }, ref) => {
3282
+ const Icon = iconMap[variant ?? "default"];
3283
+ const iconColor = iconColorMap[variant ?? "default"];
3284
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
3285
+ "div",
3286
+ {
3287
+ ref,
3288
+ role: "alert",
3289
+ className: cn(alertVariants({ variant }), className),
3290
+ ...props,
3291
+ children: [
3292
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { size: 18, className: cn("mt-0.5 shrink-0", iconColor) }),
3293
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex flex-col gap-0.5", children })
3294
+ ]
3295
+ }
3296
+ );
3297
+ }
3298
+ );
3299
+ var AlertTitle = (0, import_react34.forwardRef)(({ className, ...props }, ref) => {
3300
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { ref, className: cn("text-sm font-semibold leading-5", className), ...props });
3301
+ });
3302
+ var AlertDescription = (0, import_react34.forwardRef)(({ className, ...props }, ref) => {
3303
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { ref, className: cn("text-sm leading-5 opacity-90", className), ...props });
3304
+ });
3305
+ Alert.displayName = "Alert";
3306
+ AlertTitle.displayName = "AlertTitle";
3307
+ AlertDescription.displayName = "AlertDescription";
3308
+
3309
+ // src/components/breadcrumb.tsx
3310
+ var import_react35 = require("react");
3311
+ var import_lucide_react17 = require("lucide-react");
3312
+ var import_jsx_runtime33 = require("react/jsx-runtime");
3313
+ var Breadcrumb = (0, import_react35.forwardRef)(({ className, children, ...props }, ref) => {
3314
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("nav", { ref, "aria-label": "\u9762\u5305\u5C51\u5BFC\u822A", className: cn(className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("ol", { className: "flex flex-wrap items-center gap-0 text-sm text-text-secondary", children }) });
3315
+ });
3316
+ var BreadcrumbItem = (0, import_react35.forwardRef)(({ className, ...props }, ref) => {
3317
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("li", { ref, className: cn("flex items-center gap-1", className), ...props });
3318
+ });
3319
+ var BreadcrumbLink = (0, import_react35.forwardRef)(
3320
+ ({ current = false, className, children, href, ...props }, ref) => {
3321
+ if (current) {
3322
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { "aria-current": "page", className: cn("font-medium text-text-primary", className), children });
3323
+ }
3324
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3325
+ "a",
3326
+ {
3327
+ ref,
3328
+ href,
3329
+ className: cn("transition-colors hover:text-text-primary", className),
3330
+ ...props,
3331
+ children
3332
+ }
3333
+ );
3334
+ }
3335
+ );
3336
+ var BreadcrumbSeparator = (0, import_react35.forwardRef)(
3337
+ ({ className, children, ...props }, ref) => {
3338
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3339
+ "li",
3340
+ {
3341
+ ref,
3342
+ role: "presentation",
3343
+ "aria-hidden": "true",
3344
+ className: cn("text-text-tertiary", className),
3345
+ ...props,
3346
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.ChevronRight, { size: 14 })
3347
+ }
3348
+ );
3349
+ }
3350
+ );
3351
+ Breadcrumb.displayName = "Breadcrumb";
3352
+ BreadcrumbItem.displayName = "BreadcrumbItem";
3353
+ BreadcrumbLink.displayName = "BreadcrumbLink";
3354
+ BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
3355
+
3356
+ // src/components/switch.tsx
3357
+ var import_react36 = require("react");
3358
+ var import_jsx_runtime34 = require("react/jsx-runtime");
3359
+ var Switch = (0, import_react36.forwardRef)(
3360
+ ({
3361
+ checked,
3362
+ onCheckedChange,
3363
+ disabled = false,
3364
+ label,
3365
+ labelPlacement = "right",
3366
+ className,
3367
+ id,
3368
+ ...props
3369
+ }, ref) => {
3370
+ const generatedId = (0, import_react36.useId)();
3371
+ const switchId = id ?? generatedId;
3372
+ const track = /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3373
+ "button",
3374
+ {
3375
+ ref,
3376
+ id: switchId,
3377
+ type: "button",
3378
+ role: "switch",
3379
+ "aria-checked": checked,
3380
+ disabled,
3381
+ onClick: () => !disabled && onCheckedChange(!checked),
3382
+ className: cn(
3383
+ "relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border border-transparent p-0.5 shadow-sm transition-colors duration-200",
3384
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/35 focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0",
3385
+ "disabled:cursor-not-allowed disabled:opacity-50",
3386
+ checked ? "bg-primary hover:bg-primary-hover" : "bg-surface-3 hover:bg-border-strong",
3387
+ className
3388
+ ),
3389
+ ...props,
3390
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3391
+ "span",
3392
+ {
3393
+ className: cn(
3394
+ "pointer-events-none block h-5 w-5 rounded-full bg-primary-fg shadow-md ring-0 transition-transform duration-200",
3395
+ checked ? "translate-x-5" : "translate-x-0"
3396
+ )
3397
+ }
3398
+ )
3399
+ }
3400
+ );
3401
+ if (!label) return track;
3402
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
3403
+ "label",
3404
+ {
3405
+ htmlFor: switchId,
3406
+ className: cn(
3407
+ "inline-flex cursor-pointer items-center gap-2.5 text-sm font-medium leading-5 text-text-primary",
3408
+ disabled && "cursor-not-allowed opacity-50"
3409
+ ),
3410
+ children: [
3411
+ labelPlacement === "left" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: label }),
3412
+ track,
3413
+ labelPlacement === "right" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: label })
3414
+ ]
3415
+ }
3416
+ );
3417
+ }
3418
+ );
3419
+ Switch.displayName = "Switch";
3420
+
3421
+ // src/components/textarea.tsx
3422
+ var import_react37 = require("react");
3423
+ var import_jsx_runtime35 = require("react/jsx-runtime");
3424
+ var Textarea = (0, import_react37.forwardRef)(
3425
+ ({ className, label, error, helperText, id, rows = 3, ...props }, ref) => {
3426
+ const generatedId = (0, import_react37.useId)();
3427
+ const textareaId = id ?? generatedId;
3428
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex flex-col gap-1", children: [
3429
+ label && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("label", { htmlFor: textareaId, className: "text-sm font-medium text-text-primary", children: label }),
3430
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3431
+ "textarea",
3432
+ {
3433
+ ref,
3434
+ id: textareaId,
3435
+ rows,
3436
+ className: cn(
3437
+ "w-full rounded-md border bg-surface-1 px-3 py-2 text-sm text-text-primary placeholder:text-text-tertiary",
3438
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
3439
+ "disabled:cursor-not-allowed disabled:opacity-50",
3440
+ "resize-y",
3441
+ error ? "border-danger focus-visible:ring-danger" : "border-border-strong focus-visible:ring-ring/30",
3442
+ className
3443
+ ),
3444
+ ...props
3445
+ }
3446
+ ),
3447
+ error && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "text-xs text-danger", children: error }),
3448
+ !error && helperText && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "text-xs text-text-secondary", children: helperText })
3449
+ ] });
3450
+ }
3451
+ );
3452
+ Textarea.displayName = "Textarea";
3453
+
3454
+ // src/components/skeleton.tsx
3455
+ var import_react38 = require("react");
3456
+ var import_class_variance_authority10 = require("class-variance-authority");
3457
+ var import_jsx_runtime36 = require("react/jsx-runtime");
3458
+ var skeletonVariants = (0, import_class_variance_authority10.cva)(
3459
+ "animate-pulse bg-surface-3",
3460
+ {
3461
+ variants: {
3462
+ variant: {
3463
+ text: "h-4 w-full rounded",
3464
+ circle: "rounded-full",
3465
+ rect: "rounded-md"
3466
+ }
3467
+ },
3468
+ defaultVariants: { variant: "rect" }
3469
+ }
3470
+ );
3471
+ var Skeleton = (0, import_react38.forwardRef)(({ variant, className, ...props }, ref) => {
3472
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { ref, className: cn(skeletonVariants({ variant }), className), "aria-hidden": "true", ...props });
3473
+ });
3474
+ Skeleton.displayName = "Skeleton";
3475
+
3476
+ // src/components/progress.tsx
3477
+ var import_react39 = require("react");
3478
+ var import_jsx_runtime37 = require("react/jsx-runtime");
3479
+ var progressColorClasses = {
3480
+ primary: "bg-primary",
3481
+ success: "bg-success",
3482
+ warning: "bg-warning",
3483
+ danger: "bg-danger",
3484
+ info: "bg-info"
3485
+ };
3486
+ var Progress = (0, import_react39.forwardRef)(({
3487
+ value,
3488
+ max = 100,
3489
+ showLabel = false,
3490
+ color = "primary",
3491
+ className,
3492
+ ...props
3493
+ }, ref) => {
3494
+ const clamped = Math.min(Math.max(value, 0), max);
3495
+ const percent = Math.round(clamped / max * 100);
3496
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { ref, className: cn("flex items-center gap-3", className), ...props, children: [
3497
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3498
+ "div",
3499
+ {
3500
+ role: "progressbar",
3501
+ "aria-valuenow": clamped,
3502
+ "aria-valuemin": 0,
3503
+ "aria-valuemax": max,
3504
+ className: "h-2 w-full overflow-hidden rounded-full bg-surface-2",
3505
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3506
+ "div",
3507
+ {
3508
+ className: cn("h-full rounded-full transition-all duration-500 ease-out", progressColorClasses[color]),
3509
+ style: { width: `${percent}%` }
3510
+ }
3511
+ )
3512
+ }
3513
+ ),
3514
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "shrink-0 text-xs font-medium text-text-secondary tabular-nums w-9 text-right", children: [
3515
+ percent,
3516
+ "%"
3517
+ ] })
3518
+ ] });
3519
+ });
3520
+ Progress.displayName = "Progress";
3521
+
3522
+ // src/components/sheet.tsx
3523
+ var import_react40 = require("react");
3524
+ var import_react_dom9 = require("react-dom");
3525
+ var import_lucide_react18 = require("lucide-react");
3526
+ var import_jsx_runtime38 = require("react/jsx-runtime");
3527
+ var Sheet = (0, import_react40.forwardRef)(({ open, onClose, side = "right", title, children, className }, ref) => {
3528
+ useEscapeKey(open, onClose);
3529
+ const portalContainer = usePortalContainer();
3530
+ if (!open || !portalContainer) return null;
3531
+ return (0, import_react_dom9.createPortal)(
3532
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "fixed inset-0 z-50 flex", role: "dialog", "aria-modal": "true", children: [
3533
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3534
+ "div",
3535
+ {
3536
+ className: "absolute inset-0 bg-overlay transition-opacity",
3537
+ onClick: onClose,
3538
+ "aria-hidden": "true"
3539
+ }
3540
+ ),
3541
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
3542
+ "div",
3543
+ {
3544
+ ref,
3545
+ className: cn(
3546
+ "relative flex h-full w-80 max-w-full flex-col bg-surface-1 shadow-xl",
3547
+ "transition-transform duration-300 ease-in-out",
3548
+ side === "right" ? "ml-auto translate-x-0" : "mr-auto translate-x-0",
3549
+ className
3550
+ ),
3551
+ children: [
3552
+ title && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between border-b border-border-base px-5 py-4", children: [
3553
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h2", { className: "text-base font-semibold text-text-primary", children: title }),
3554
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3555
+ "button",
3556
+ {
3557
+ type: "button",
3558
+ onClick: onClose,
3559
+ className: "rounded-md p-1 text-text-tertiary hover:bg-surface-3 hover:text-text-secondary transition-colors",
3560
+ "aria-label": "\u5173\u95ED",
3561
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react18.X, { size: 18 })
3562
+ }
3563
+ )
3564
+ ] }),
3565
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "flex-1 overflow-y-auto px-5 py-4", children })
3566
+ ]
3567
+ }
3568
+ )
3569
+ ] }),
3570
+ portalContainer
3571
+ );
3572
+ });
3573
+ Sheet.displayName = "Sheet";
3574
+
3575
+ // src/components/empty-state.tsx
3576
+ var import_react41 = require("react");
3577
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3578
+ var EmptyState = (0, import_react41.forwardRef)(
3579
+ ({ icon: Icon, title, description, action, className, ...props }, ref) => {
3580
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
3581
+ "div",
3582
+ {
3583
+ ref,
3584
+ className: cn(
3585
+ "flex flex-col items-center justify-center gap-3 py-16 text-center",
3586
+ className
3587
+ ),
3588
+ ...props,
3589
+ children: [
3590
+ Icon && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex h-14 w-14 items-center justify-center rounded-full bg-surface-2", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { size: 28, className: "text-text-tertiary" }) }),
3591
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-col gap-1", children: [
3592
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-base font-semibold text-text-primary", children: title }),
3593
+ description && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "max-w-xs text-sm text-text-secondary", children: description })
3594
+ ] }),
3595
+ action && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "mt-1", children: action })
3596
+ ]
3597
+ }
3598
+ );
3599
+ }
3600
+ );
3601
+ EmptyState.displayName = "EmptyState";
3602
+
3603
+ // src/components/separator.tsx
3604
+ var import_react42 = require("react");
3605
+ var import_jsx_runtime40 = require("react/jsx-runtime");
3606
+ var ORIENTATION_CLASSES = {
3607
+ horizontal: "h-px w-full bg-border-base",
3608
+ vertical: "w-px h-full bg-border-base"
3609
+ };
3610
+ var Separator = (0, import_react42.forwardRef)(
3611
+ ({ orientation = "horizontal", className, ...props }, ref) => {
3612
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
3613
+ "div",
3614
+ {
3615
+ ref,
3616
+ role: "separator",
3617
+ "aria-orientation": orientation,
3618
+ className: cn(ORIENTATION_CLASSES[orientation], className),
3619
+ ...props
3620
+ }
3621
+ );
3622
+ }
3623
+ );
3624
+ Separator.displayName = "Separator";
3625
+
3626
+ // src/components/descriptions.tsx
3627
+ var import_react43 = require("react");
3628
+ var import_jsx_runtime41 = require("react/jsx-runtime");
3629
+ var SIZE_LABEL_CLASSES = {
3630
+ sm: "px-3 py-2 text-xs",
3631
+ default: "px-3.5 py-2.5 text-sm",
3632
+ lg: "px-4 py-3 text-base"
3633
+ };
3634
+ var SIZE_VALUE_CLASSES = {
3635
+ sm: "px-3 py-2 text-xs",
3636
+ default: "px-3.5 py-2.5 text-sm",
3637
+ lg: "px-4 py-3 text-base"
3638
+ };
3639
+ var DescriptionsItem = (0, import_react43.forwardRef)(
3640
+ ({ label, children, className, span: _span, ...props }, ref) => {
3641
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { ref, className, ...props, children: [
3642
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-text-secondary", children: label }),
3643
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-text-primary", children })
3644
+ ] });
3645
+ }
3646
+ );
3647
+ DescriptionsItem.displayName = "DescriptionsItem";
3648
+ var Descriptions = (0, import_react43.forwardRef)(
3649
+ ({ column = 2, bordered = false, size = "default", title, className, children, ...props }, ref) => {
3650
+ const items = import_react43.Children.toArray(children).filter(
3651
+ (child) => (0, import_react43.isValidElement)(child) && child.type.displayName === "DescriptionsItem"
3652
+ );
3653
+ if (bordered) {
3654
+ const rows = [];
3655
+ let currentRow = [];
3656
+ let currentColCount = 0;
3657
+ for (const item of items) {
3658
+ const span = item.props.span ?? 1;
3659
+ if (currentColCount + span > column) {
3660
+ rows.push(currentRow);
3661
+ currentRow = [];
3662
+ currentColCount = 0;
3663
+ }
3664
+ currentRow.push({ label: item.props.label, value: item.props.children, span });
3665
+ currentColCount += span;
3666
+ }
3667
+ if (currentRow.length > 0) rows.push(currentRow);
3668
+ const labelColumnWidth = column === 1 ? "34%" : `${Math.max(12, 100 / (column * 2))}%`;
3669
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { ref, className: cn("w-full", className), ...props, children: [
3670
+ title && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "mb-3 text-base font-semibold text-text-primary", children: title }),
3671
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "overflow-hidden rounded-lg border border-border-base bg-surface-1", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("table", { className: "w-full table-fixed border-separate border-spacing-0", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("tbody", { children: rows.map((row, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("tr", { children: row.map((cell, cellIdx) => {
3672
+ const hasRowDivider = rowIdx < rows.length - 1;
3673
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react43.Fragment, { children: [
3674
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3675
+ "td",
3676
+ {
3677
+ className: cn(
3678
+ "border-r border-border-base bg-surface-2/80 font-medium text-text-secondary",
3679
+ hasRowDivider && "border-b",
3680
+ SIZE_LABEL_CLASSES[size]
3681
+ ),
3682
+ style: { width: labelColumnWidth },
3683
+ children: cell.label
3684
+ }
3685
+ ),
3686
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3687
+ "td",
3688
+ {
3689
+ className: cn(
3690
+ "break-words font-medium text-text-primary",
3691
+ hasRowDivider && "border-b border-border-base",
3692
+ SIZE_VALUE_CLASSES[size]
3693
+ ),
3694
+ colSpan: cell.span > 1 ? cell.span * 2 - 1 : 1,
3695
+ children: cell.value
3696
+ }
3697
+ )
3698
+ ] }, `${rowIdx}-${cellIdx}`);
3699
+ }) }, rowIdx)) }) }) })
3700
+ ] });
3701
+ }
3702
+ const GRID_COLS = {
3703
+ 1: "grid-cols-1",
3704
+ 2: "grid-cols-2",
3705
+ 3: "grid-cols-3",
3706
+ 4: "grid-cols-4"
3707
+ };
3708
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { ref, className: cn("w-full", className), ...props, children: [
3709
+ title && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "mb-3 text-base font-semibold text-text-primary", children: title }),
3710
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("grid gap-x-6 gap-y-4", GRID_COLS[column]), children: items.map((item, idx) => {
3711
+ const span = item.props.span ?? 1;
3712
+ const colSpanClass = span === 2 ? "col-span-2" : span === 3 ? "col-span-3" : span === 4 ? "col-span-4" : "";
3713
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex flex-col gap-0.5", colSpanClass, item.props.className), children: [
3714
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: cn("font-medium text-text-secondary", size === "sm" ? "text-xs" : size === "lg" ? "text-sm" : "text-xs"), children: item.props.label }),
3715
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: cn("text-text-primary", size === "sm" ? "text-sm" : size === "lg" ? "text-base" : "text-sm"), children: item.props.children })
3716
+ ] }, idx);
3717
+ }) })
3718
+ ] });
3719
+ }
3720
+ );
3721
+ Descriptions.displayName = "Descriptions";
3722
+
3723
+ // src/components/statistic.tsx
3724
+ var import_react44 = require("react");
3725
+ var import_lucide_react19 = require("lucide-react");
3726
+ var import_jsx_runtime42 = require("react/jsx-runtime");
3727
+ var SIZE_TITLE_CLASSES = {
3728
+ sm: "text-xs",
3729
+ default: "text-sm",
3730
+ lg: "text-base"
3731
+ };
3732
+ var SIZE_VALUE_CLASSES2 = {
3733
+ sm: "text-2xl",
3734
+ default: "text-3xl",
3735
+ lg: "text-4xl"
3736
+ };
3737
+ var SIZE_SUFFIX_CLASSES = {
3738
+ sm: "text-xs",
3739
+ default: "text-sm",
3740
+ lg: "text-base"
3741
+ };
3742
+ var TREND_ICON_COLOR = {
3743
+ up: "text-success",
3744
+ down: "text-danger",
3745
+ flat: "text-text-secondary"
3746
+ };
3747
+ var TREND_TEXT_COLOR = {
3748
+ up: "text-success",
3749
+ down: "text-danger",
3750
+ flat: "text-text-secondary"
3751
+ };
3752
+ function formatValue(value, precision) {
3753
+ if (typeof value === "string") return value;
3754
+ return new Intl.NumberFormat("zh-CN", {
3755
+ minimumFractionDigits: precision ?? 0,
3756
+ maximumFractionDigits: precision ?? 0
3757
+ }).format(value);
3758
+ }
3759
+ var Statistic = (0, import_react44.forwardRef)(
3760
+ ({ title, value, precision, prefix, suffix, trend, change, size = "default", className, ...props }, ref) => {
3761
+ const TrendIcon = trend === "up" ? import_lucide_react19.TrendingUp : trend === "down" ? import_lucide_react19.TrendingDown : trend === "flat" ? import_lucide_react19.Minus : null;
3762
+ const iconSize = size === "sm" ? 14 : size === "lg" ? 18 : 16;
3763
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { ref, className: cn("flex flex-col gap-1", className), ...props, children: [
3764
+ title && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn("font-medium text-text-secondary", SIZE_TITLE_CLASSES[size]), children: title }),
3765
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-baseline gap-1", children: [
3766
+ prefix && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn("text-text-primary", SIZE_SUFFIX_CLASSES[size]), children: prefix }),
3767
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn("font-bold tabular-nums text-text-primary", SIZE_VALUE_CLASSES2[size]), children: formatValue(value, precision) }),
3768
+ suffix && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn("text-text-secondary", SIZE_SUFFIX_CLASSES[size]), children: suffix })
3769
+ ] }),
3770
+ (trend || change) && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-1", children: [
3771
+ TrendIcon && trend && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(TrendIcon, { size: iconSize, className: TREND_ICON_COLOR[trend] }),
3772
+ change && trend && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn("text-xs font-medium", TREND_TEXT_COLOR[trend]), children: change })
3773
+ ] })
3774
+ ] });
3775
+ }
3776
+ );
3777
+ Statistic.displayName = "Statistic";
3778
+ // Annotate the CommonJS export names for ESM import in node:
3779
+ 0 && (module.exports = {
3780
+ Accordion,
3781
+ AccordionContent,
3782
+ AccordionItem,
3783
+ AccordionTrigger,
3784
+ Alert,
3785
+ AlertDescription,
3786
+ AlertTitle,
3787
+ Avatar,
3788
+ AvatarFallback,
3789
+ AvatarGroup,
3790
+ AvatarImage,
3791
+ Badge,
3792
+ Breadcrumb,
3793
+ BreadcrumbItem,
3794
+ BreadcrumbLink,
3795
+ BreadcrumbSeparator,
3796
+ Button,
3797
+ Card,
3798
+ CardContent,
3799
+ CardDescription,
3800
+ CardFooter,
3801
+ CardHeader,
3802
+ CardTitle,
3803
+ Checkbox,
3804
+ ContextMenu,
3805
+ ContextMenuContent,
3806
+ ContextMenuItem,
3807
+ ContextMenuSeparator,
3808
+ ContextMenuTrigger,
3809
+ Descriptions,
3810
+ DescriptionsItem,
3811
+ Dialog,
3812
+ Drawer,
3813
+ DrawerClose,
3814
+ DrawerContent,
3815
+ DrawerDescription,
3816
+ DrawerFooter,
3817
+ DrawerHeader,
3818
+ DrawerTitle,
3819
+ DropdownContent,
3820
+ DropdownItem,
3821
+ DropdownMenu,
3822
+ DropdownSeparator,
3823
+ DropdownTrigger,
3824
+ EmptyState,
3825
+ Form,
3826
+ FormControl,
3827
+ FormDescription,
3828
+ FormField,
3829
+ FormItem,
3830
+ FormLabel,
3831
+ FormMessage,
3832
+ Input,
3833
+ Label,
3834
+ Modal,
3835
+ ModalCloseButton,
3836
+ ModalContent,
3837
+ ModalFooter,
3838
+ ModalHeader,
3839
+ ModalTitle,
3840
+ NavigationMenu,
3841
+ NavigationMenuContent,
3842
+ NavigationMenuItem,
3843
+ NavigationMenuLink,
3844
+ NavigationMenuTrigger,
3845
+ NumberInput,
3846
+ OTPInput,
3847
+ Pagination,
3848
+ Popover,
3849
+ PopoverContent,
3850
+ PopoverTrigger,
3851
+ Progress,
3852
+ Radio,
3853
+ RadioGroup,
3854
+ Select,
3855
+ Separator,
3856
+ Sheet,
3857
+ Sidebar,
3858
+ Skeleton,
3859
+ Slider,
3860
+ Spinner,
3861
+ Statistic,
3862
+ Steps,
3863
+ Switch,
3864
+ Table,
3865
+ TableBody,
3866
+ TableCell,
3867
+ TableHead,
3868
+ TableHeader,
3869
+ TableRow,
3870
+ Tabs,
3871
+ TabsContent,
3872
+ TabsList,
3873
+ TabsTrigger,
3874
+ Tag,
3875
+ Textarea,
3876
+ Toaster,
3877
+ Tooltip,
3878
+ TooltipContent,
3879
+ TooltipTrigger,
3880
+ UGAccordion,
3881
+ UGAccordionContent,
3882
+ UGAccordionItem,
3883
+ UGAccordionTrigger,
3884
+ UGAlert,
3885
+ UGAlertDescription,
3886
+ UGAlertTitle,
3887
+ UGAvatar,
3888
+ UGAvatarFallback,
3889
+ UGAvatarGroup,
3890
+ UGAvatarImage,
3891
+ UGBadge,
3892
+ UGBreadcrumb,
3893
+ UGBreadcrumbItem,
3894
+ UGBreadcrumbLink,
3895
+ UGBreadcrumbSeparator,
3896
+ UGButton,
3897
+ UGCard,
3898
+ UGCardContent,
3899
+ UGCardDescription,
3900
+ UGCardFooter,
3901
+ UGCardHeader,
3902
+ UGCardTitle,
3903
+ UGCheckbox,
3904
+ UGContextMenu,
3905
+ UGContextMenuContent,
3906
+ UGContextMenuItem,
3907
+ UGContextMenuSeparator,
3908
+ UGContextMenuTrigger,
3909
+ UGDescriptions,
3910
+ UGDescriptionsItem,
3911
+ UGDialog,
3912
+ UGDrawer,
3913
+ UGDrawerClose,
3914
+ UGDrawerContent,
3915
+ UGDrawerDescription,
3916
+ UGDrawerFooter,
3917
+ UGDrawerHeader,
3918
+ UGDrawerTitle,
3919
+ UGDropdown,
3920
+ UGDropdownContent,
3921
+ UGDropdownItem,
3922
+ UGDropdownMenu,
3923
+ UGDropdownSeparator,
3924
+ UGDropdownTrigger,
3925
+ UGEmptyState,
3926
+ UGForm,
3927
+ UGFormControl,
3928
+ UGFormDescription,
3929
+ UGFormField,
3930
+ UGFormItem,
3931
+ UGFormLabel,
3932
+ UGFormMessage,
3933
+ UGInput,
3934
+ UGLabel,
3935
+ UGModal,
3936
+ UGModalCloseButton,
3937
+ UGModalContent,
3938
+ UGModalFooter,
3939
+ UGModalHeader,
3940
+ UGModalTitle,
3941
+ UGNavigationMenu,
3942
+ UGNavigationMenuContent,
3943
+ UGNavigationMenuItem,
3944
+ UGNavigationMenuLink,
3945
+ UGNavigationMenuTrigger,
3946
+ UGNumberInput,
3947
+ UGOTPInput,
3948
+ UGPagination,
3949
+ UGPopover,
3950
+ UGPopoverContent,
3951
+ UGPopoverTrigger,
3952
+ UGProgress,
3953
+ UGRadio,
3954
+ UGRadioGroup,
3955
+ UGSelect,
3956
+ UGSeparator,
3957
+ UGSheet,
3958
+ UGSidebar,
3959
+ UGSkeleton,
3960
+ UGSlider,
3961
+ UGSpinner,
3962
+ UGStatistic,
3963
+ UGSteps,
3964
+ UGSwitch,
3965
+ UGTable,
3966
+ UGTableBody,
3967
+ UGTableCell,
3968
+ UGTableHead,
3969
+ UGTableHeader,
3970
+ UGTableRow,
3971
+ UGTabs,
3972
+ UGTabsContent,
3973
+ UGTabsList,
3974
+ UGTabsTrigger,
3975
+ UGTag,
3976
+ UGTextarea,
3977
+ UGToaster,
3978
+ UGTooltip,
3979
+ UGTooltipContent,
3980
+ UGTooltipTrigger,
3981
+ badgeVariants,
3982
+ buttonVariants,
3983
+ checkboxVariants,
3984
+ numberInputVariants,
3985
+ tagVariants,
3986
+ toast,
3987
+ ugBadgeVariants,
3988
+ ugButtonVariants,
3989
+ ugCheckboxVariants,
3990
+ ugNumberInputVariants,
3991
+ ugTagVariants
3992
+ });
3993
+ //# sourceMappingURL=index.cjs.map