@mdigital_ui/ui 0.4.4 → 0.4.6

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 (128) hide show
  1. package/README.md +258 -662
  2. package/dist/anchor/index.js +4 -0
  3. package/dist/anchor/index.js.map +1 -0
  4. package/dist/autocomplete/index.js +6 -0
  5. package/dist/autocomplete/index.js.map +1 -0
  6. package/dist/breadcrumbs/index.js +3 -3
  7. package/dist/calendar/index.js +4 -0
  8. package/dist/calendar/index.js.map +1 -0
  9. package/dist/chunk-3Z7RLVWD.js +258 -0
  10. package/dist/chunk-3Z7RLVWD.js.map +1 -0
  11. package/dist/chunk-5YEC6FDN.js +263 -0
  12. package/dist/chunk-5YEC6FDN.js.map +1 -0
  13. package/dist/{chunk-GOBUFGGJ.js → chunk-6NXZWLSM.js} +3 -3
  14. package/dist/{chunk-GOBUFGGJ.js.map → chunk-6NXZWLSM.js.map} +1 -1
  15. package/dist/{chunk-FU5Q4WVX.js → chunk-6ROGWFQ2.js} +3 -3
  16. package/dist/{chunk-FU5Q4WVX.js.map → chunk-6ROGWFQ2.js.map} +1 -1
  17. package/dist/{chunk-LJOQ2C5W.js → chunk-6RZEJRTC.js} +3 -3
  18. package/dist/{chunk-LJOQ2C5W.js.map → chunk-6RZEJRTC.js.map} +1 -1
  19. package/dist/chunk-74AF6PO2.js +374 -0
  20. package/dist/chunk-74AF6PO2.js.map +1 -0
  21. package/dist/chunk-75N6T3IS.js +77 -0
  22. package/dist/chunk-75N6T3IS.js.map +1 -0
  23. package/dist/{chunk-BKLJDEUX.js → chunk-DBPLQZJ2.js} +38 -14
  24. package/dist/chunk-DBPLQZJ2.js.map +1 -0
  25. package/dist/chunk-ED4CQZ72.js +343 -0
  26. package/dist/chunk-ED4CQZ72.js.map +1 -0
  27. package/dist/{chunk-4ZXHLPRS.js → chunk-FY2TZ2NT.js} +4 -4
  28. package/dist/{chunk-4ZXHLPRS.js.map → chunk-FY2TZ2NT.js.map} +1 -1
  29. package/dist/{chunk-I5AD247M.js → chunk-HKQOAEFY.js} +13 -3
  30. package/dist/chunk-HKQOAEFY.js.map +1 -0
  31. package/dist/chunk-JWYBDNC6.js +307 -0
  32. package/dist/chunk-JWYBDNC6.js.map +1 -0
  33. package/dist/{chunk-W5VLFE4U.js → chunk-LHZJ2GJU.js} +32 -6
  34. package/dist/chunk-LHZJ2GJU.js.map +1 -0
  35. package/dist/{chunk-253JZOYG.js → chunk-NB66D6A5.js} +3 -2
  36. package/dist/chunk-NB66D6A5.js.map +1 -0
  37. package/dist/{chunk-BGMYX7L5.js → chunk-NF6JUJBE.js} +9 -7
  38. package/dist/chunk-NF6JUJBE.js.map +1 -0
  39. package/dist/chunk-NPK4ESMA.js +281 -0
  40. package/dist/chunk-NPK4ESMA.js.map +1 -0
  41. package/dist/{chunk-X7MF3TIF.js → chunk-PD3O6ZH4.js} +12 -5
  42. package/dist/chunk-PD3O6ZH4.js.map +1 -0
  43. package/dist/{chunk-XOEEAMMY.js → chunk-Q46WXJVW.js} +21 -21
  44. package/dist/chunk-Q46WXJVW.js.map +1 -0
  45. package/dist/chunk-QEYNOLRC.js +157 -0
  46. package/dist/chunk-QEYNOLRC.js.map +1 -0
  47. package/dist/chunk-RNG7HR6U.js +174 -0
  48. package/dist/chunk-RNG7HR6U.js.map +1 -0
  49. package/dist/{chunk-HJITFPBT.js → chunk-SZMIHNCZ.js} +13 -7
  50. package/dist/chunk-SZMIHNCZ.js.map +1 -0
  51. package/dist/chunk-TDPJYCNI.js +96 -0
  52. package/dist/chunk-TDPJYCNI.js.map +1 -0
  53. package/dist/chunk-UFYG3HKL.js +374 -0
  54. package/dist/chunk-UFYG3HKL.js.map +1 -0
  55. package/dist/chunk-VNH6R5EU.js +211 -0
  56. package/dist/chunk-VNH6R5EU.js.map +1 -0
  57. package/dist/{chunk-SFP77VS3.js → chunk-X7JN7WPF.js} +5 -2
  58. package/dist/chunk-X7JN7WPF.js.map +1 -0
  59. package/dist/chunk-YRSHBAUQ.js +201 -0
  60. package/dist/chunk-YRSHBAUQ.js.map +1 -0
  61. package/dist/chunk-YUACN5GJ.js +303 -0
  62. package/dist/chunk-YUACN5GJ.js.map +1 -0
  63. package/dist/{chunk-HVHQA34X.js → chunk-ZNGKUG2N.js} +11 -6
  64. package/dist/chunk-ZNGKUG2N.js.map +1 -0
  65. package/dist/color-picker/index.js +6 -0
  66. package/dist/color-picker/index.js.map +1 -0
  67. package/dist/date-picker/RangePicker.d.ts.map +1 -1
  68. package/dist/date-picker/index.d.ts.map +1 -1
  69. package/dist/date-picker/index.js +1 -1
  70. package/dist/date-picker/shared.d.ts +5 -0
  71. package/dist/date-picker/shared.d.ts.map +1 -1
  72. package/dist/dropdown/index.js +2 -2
  73. package/dist/float-button/index.js +5 -0
  74. package/dist/float-button/index.js.map +1 -0
  75. package/dist/index.js +51 -2996
  76. package/dist/index.js.map +1 -1
  77. package/dist/input/index.d.ts.map +1 -1
  78. package/dist/input/index.js +1 -1
  79. package/dist/input-password/index.js +2 -2
  80. package/dist/mentions/index.js +4 -0
  81. package/dist/mentions/index.js.map +1 -0
  82. package/dist/menubar/index.d.ts +3 -3
  83. package/dist/menubar/index.d.ts.map +1 -1
  84. package/dist/menubar/index.js +1 -1
  85. package/dist/multi-select/index.d.ts.map +1 -1
  86. package/dist/multi-select/index.js +3 -3
  87. package/dist/number-input/index.d.ts.map +1 -1
  88. package/dist/number-input/index.js +1 -1
  89. package/dist/qr-code/index.js +5 -0
  90. package/dist/qr-code/index.js.map +1 -0
  91. package/dist/resizable/index.js +4 -0
  92. package/dist/resizable/index.js.map +1 -0
  93. package/dist/result/index.js +4 -0
  94. package/dist/result/index.js.map +1 -0
  95. package/dist/select/index.d.ts.map +1 -1
  96. package/dist/select/index.js +3 -3
  97. package/dist/shared/useSelectBase.d.ts.map +1 -1
  98. package/dist/skeleton/index.d.ts.map +1 -1
  99. package/dist/skeleton/index.js +1 -1
  100. package/dist/table/index.js +4 -4
  101. package/dist/tabs/index.d.ts.map +1 -1
  102. package/dist/tabs/index.js +1 -1
  103. package/dist/tags-input/index.js +5 -0
  104. package/dist/tags-input/index.js.map +1 -0
  105. package/dist/toast/index.d.ts.map +1 -1
  106. package/dist/toast/index.js +1 -1
  107. package/dist/tooltip/index.d.ts.map +1 -1
  108. package/dist/tooltip/index.js +1 -1
  109. package/dist/tour/index.js +5 -0
  110. package/dist/tour/index.js.map +1 -0
  111. package/dist/typography/index.js +4 -0
  112. package/dist/typography/index.js.map +1 -0
  113. package/dist/watermark/index.js +4 -0
  114. package/dist/watermark/index.js.map +1 -0
  115. package/package.json +59 -11
  116. package/styles/global.css +498 -6016
  117. package/dist/chunk-253JZOYG.js.map +0 -1
  118. package/dist/chunk-BGMYX7L5.js.map +0 -1
  119. package/dist/chunk-BKLJDEUX.js.map +0 -1
  120. package/dist/chunk-BS4PZPY6.js +0 -322
  121. package/dist/chunk-BS4PZPY6.js.map +0 -1
  122. package/dist/chunk-HJITFPBT.js.map +0 -1
  123. package/dist/chunk-HVHQA34X.js.map +0 -1
  124. package/dist/chunk-I5AD247M.js.map +0 -1
  125. package/dist/chunk-SFP77VS3.js.map +0 -1
  126. package/dist/chunk-W5VLFE4U.js.map +0 -1
  127. package/dist/chunk-X7MF3TIF.js.map +0 -1
  128. package/dist/chunk-XOEEAMMY.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,3035 +1,90 @@
1
- export { upload_default as Upload } from './chunk-CUXQZRDI.js';
2
- export { ToastProvider, useToast } from './chunk-BGMYX7L5.js';
3
- export { toggle_default as Toggle } from './chunk-I7HJBHQU.js';
4
- export { timeline_default as Timeline } from './chunk-JIXINKUJ.js';
5
- export { tooltip_default as Tooltip, TooltipProvider } from './chunk-253JZOYG.js';
6
1
  export { Transfer } from './chunk-3XOHSE3X.js';
7
2
  export { tree_select_default as TreeSelect } from './chunk-TBKPQOXF.js';
8
3
  export { tree_default as Tree } from './chunk-LXHFGQOI.js';
4
+ export { Paragraph, Text, Title } from './chunk-VNH6R5EU.js';
5
+ export { upload_default as Upload } from './chunk-CUXQZRDI.js';
6
+ export { watermark_default as Watermark } from './chunk-QEYNOLRC.js';
7
+ export { textarea_default as Textarea } from './chunk-7RT65ZGV.js';
8
+ export { ThemeProvider, themeScript, useTheme } from './chunk-XCK62GVU.js';
9
+ export { timeline_default as Timeline } from './chunk-JIXINKUJ.js';
10
+ export { ToastProvider, useToast } from './chunk-NF6JUJBE.js';
11
+ export { toggle_default as Toggle } from './chunk-I7HJBHQU.js';
12
+ export { tooltip_default as Tooltip, TooltipProvider } from './chunk-NB66D6A5.js';
13
+ export { tour_default as Tour } from './chunk-YUACN5GJ.js';
14
+ export { slider_default as Slider } from './chunk-HR5TGNOF.js';
9
15
  export { stepper_default as Stepper } from './chunk-3D77IPKB.js';
10
16
  export { switch_default as Switch } from './chunk-5MBKTMDW.js';
11
- export { EditableCell, table_default as Table, TableActions, TableCell, TableHeaderCell, TableRow, TableSkeleton } from './chunk-4ZXHLPRS.js';
17
+ export { EditableCell, table_default as Table, TableActions, TableCell, TableHeaderCell, TableRow, TableSkeleton } from './chunk-FY2TZ2NT.js';
12
18
  export { toggle_group_default as ToggleGroup } from './chunk-XAM5EKOS.js';
13
- export { tabs_default as Tabs } from './chunk-I5AD247M.js';
19
+ export { tabs_default as Tabs } from './chunk-HKQOAEFY.js';
14
20
  export { tag_default as Tag } from './chunk-NMP4HY6M.js';
15
- export { textarea_default as Textarea } from './chunk-7RT65ZGV.js';
16
- export { ThemeProvider, themeScript, useTheme } from './chunk-XCK62GVU.js';
17
- export { progress_default as Progress } from './chunk-NTCAZ2LF.js';
21
+ export { tags_input_default as TagsInput } from './chunk-NPK4ESMA.js';
18
22
  export { radio_default as Radio } from './chunk-UFC3RGIN.js';
19
23
  export { radio_group_default as RadioGroup } from './chunk-STAYOHDI.js';
20
24
  export { rating_default as Rating } from './chunk-TQEMGWZ2.js';
25
+ export { ResizableHandle, ResizablePanel, ResizablePanelGroup } from './chunk-75N6T3IS.js';
26
+ export { result_default as Result } from './chunk-TDPJYCNI.js';
21
27
  export { scroll_area_default as ScrollArea } from './chunk-WQT24BGG.js';
22
- export { select_default as Select } from './chunk-HVHQA34X.js';
23
- export { skeleton_default as Skeleton } from './chunk-SFP77VS3.js';
24
- export { slider_default as Slider } from './chunk-HR5TGNOF.js';
25
- export { menubar_default as Menubar } from './chunk-BS4PZPY6.js';
26
- export { multi_select_default as MultiSelect } from './chunk-XOEEAMMY.js';
27
- import './chunk-HJITFPBT.js';
28
+ export { select_default as Select } from './chunk-ZNGKUG2N.js';
29
+ export { skeleton_default as Skeleton } from './chunk-X7JN7WPF.js';
30
+ export { multi_select_default as MultiSelect } from './chunk-Q46WXJVW.js';
31
+ import './chunk-SZMIHNCZ.js';
28
32
  export { NavigationMenu } from './chunk-S6HO7HUY.js';
29
33
  export { notification_default as Notification } from './chunk-U4JPTWK6.js';
30
- export { number_input_default as NumberInput } from './chunk-X7MF3TIF.js';
34
+ export { number_input_default as NumberInput } from './chunk-PD3O6ZH4.js';
31
35
  export { pagination_default as Pagination } from './chunk-PB5VGXS5.js';
32
- export { grid_default as Grid } from './chunk-BNHRUHI4.js';
33
- export { image_default as Image } from './chunk-HRVOTFU4.js';
36
+ export { progress_default as Progress } from './chunk-NTCAZ2LF.js';
37
+ export { qr_code_default as QRCode } from './chunk-74AF6PO2.js';
34
38
  export { input_group_default as InputGroup, InputGroupAddon, InputGroupInput } from './chunk-3YP7HY3Y.js';
35
39
  export { input_otp_default as InputOTP } from './chunk-ADZWWBAX.js';
36
- export { input_password_default as InputPassword } from './chunk-LJOQ2C5W.js';
37
- export { input_default as Input } from './chunk-W5VLFE4U.js';
40
+ export { input_password_default as InputPassword } from './chunk-6RZEJRTC.js';
38
41
  export { kbd_default as Kbd } from './chunk-5SEVPU6C.js';
39
42
  export { link_default as Link } from './chunk-XMBZBXXS.js';
40
- export { context_menu_default as ContextMenu, ContextMenuContent } from './chunk-Z3DIBMBQ.js';
41
- export { DatePicker, RangePickerComponent as RangePicker, TimePickerComponent as TimePicker } from './chunk-BKLJDEUX.js';
42
- export { descriptions_default as Descriptions } from './chunk-PRDJLQLB.js';
43
- export { divider_default as Divider } from './chunk-JFTSWOGE.js';
43
+ export { mentions_default as Mentions } from './chunk-3Z7RLVWD.js';
44
+ export { menubar_default as Menubar } from './chunk-ED4CQZ72.js';
44
45
  export { Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger } from './chunk-DDZCRCTQ.js';
45
46
  export { fetching_overlay_default as FetchingOverlay } from './chunk-XBXPY7U3.js';
47
+ export { BackTop, FloatButton, FloatButtonGroup } from './chunk-YRSHBAUQ.js';
46
48
  export { float_input_default as FloatInput } from './chunk-TDNPACQD.js';
49
+ export { grid_default as Grid } from './chunk-BNHRUHI4.js';
50
+ export { image_default as Image } from './chunk-HRVOTFU4.js';
51
+ export { input_default as Input } from './chunk-LHZJ2GJU.js';
52
+ export { clipboard_default as Clipboard } from './chunk-J2WIZULN.js';
53
+ export { collapse_default as Collapse } from './chunk-OJAHIPPP.js';
54
+ export { useControllable } from './chunk-PQOIW5CM.js';
55
+ export { ColorInput, ColorPicker } from './chunk-UFYG3HKL.js';
56
+ export { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandModal, CommandSeparator, CommandShortcut } from './chunk-WG5AYAC6.js';
57
+ export { modal_default as Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, Modal as ModalRoot, ModalTitle, ModalTrigger } from './chunk-AFW2ORFT.js';
58
+ export { context_menu_default as ContextMenu, ContextMenuContent } from './chunk-Z3DIBMBQ.js';
59
+ export { DatePicker, RangePickerComponent as RangePicker, TimePickerComponent as TimePicker } from './chunk-DBPLQZJ2.js';
60
+ export { descriptions_default as Descriptions } from './chunk-PRDJLQLB.js';
61
+ export { divider_default as Divider } from './chunk-JFTSWOGE.js';
62
+ export { button_default as Button } from './chunk-SJLH5ZDW.js';
63
+ export { spinner_default as Spinner } from './chunk-RRPMZYVN.js';
64
+ export { button_group_default as ButtonGroup } from './chunk-L5BU2QTI.js';
65
+ export { calendar_default as Calendar } from './chunk-5YEC6FDN.js';
47
66
  export { card_default as Card } from './chunk-OGB5QPNZ.js';
48
67
  export { carousel_default as Carousel } from './chunk-QEAALOJC.js';
49
68
  export { cascader_default as Cascader } from './chunk-LWYZCSX4.js';
50
69
  export { checkbox_default as Checkbox } from './chunk-A4MYCEGM.js';
51
70
  export { checkbox_group_default as CheckboxGroup } from './chunk-ON76IMMI.js';
52
- export { collapse_default as Collapse } from './chunk-OJAHIPPP.js';
53
- export { useControllable } from './chunk-PQOIW5CM.js';
54
- export { clipboard_default as Clipboard } from './chunk-J2WIZULN.js';
55
- export { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandModal, CommandSeparator, CommandShortcut } from './chunk-WG5AYAC6.js';
56
- export { modal_default as Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, Modal as ModalRoot, ModalTitle, ModalTrigger } from './chunk-AFW2ORFT.js';
57
71
  export { accordion_default as Accordion } from './chunk-4HKPDSA6.js';
58
72
  export { alert_default as Alert } from './chunk-C65SCJD6.js';
73
+ export { anchor_default as Anchor } from './chunk-RNG7HR6U.js';
59
74
  export { Avatar, AvatarGroup } from './chunk-HSMO2BR4.js';
75
+ export { autocomplete_default as Autocomplete } from './chunk-JWYBDNC6.js';
60
76
  export { badge_default as Badge } from './chunk-C32HL4XU.js';
61
- export { breadcrumbs_default as Breadcrumbs } from './chunk-FU5Q4WVX.js';
62
- export { dropdown_default as Dropdown } from './chunk-GOBUFGGJ.js';
77
+ export { breadcrumbs_default as Breadcrumbs } from './chunk-6ROGWFQ2.js';
78
+ export { dropdown_default as Dropdown } from './chunk-6NXZWLSM.js';
63
79
  export { useMenuNavigation } from './chunk-NZHKNUGE.js';
64
- import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from './chunk-ROQGBDET.js';
65
- export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from './chunk-ROQGBDET.js';
66
- export { button_default as Button } from './chunk-SJLH5ZDW.js';
67
- export { spinner_default as Spinner } from './chunk-RRPMZYVN.js';
68
80
  export { RippleContainer, useRipple } from './chunk-4TEZWGX7.js';
69
- import { colorVars } from './chunk-G6QIIWKU.js';
81
+ export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from './chunk-ROQGBDET.js';
70
82
  export { buttonColorVars, colorVars } from './chunk-G6QIIWKU.js';
71
- export { button_group_default as ButtonGroup } from './chunk-L5BU2QTI.js';
72
- import { cn, iconSizes, statusMessageVariants } from './chunk-RAS6HUEI.js';
73
83
  export { cn, getValidationStatus, iconSizes, statusMessageVariants } from './chunk-RAS6HUEI.js';
74
- import React4, { useState, useRef, useCallback, useEffect, useMemo } from 'react';
75
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
76
- import { cva } from 'class-variance-authority';
77
- import { Loader2, X, ChevronDown, ChevronLeft, ChevronRight, ArrowUp, Plus, MoreVertical } from 'lucide-react';
78
- import { Group, Panel, Separator } from 'react-resizable-panels';
84
+ import { useState, useEffect, useRef } from 'react';
79
85
 
80
86
  // src/styles/themes/presets/index.ts
81
87
  var themePresets = ["corporate", "vibrant", "minimal"];
82
- var sizeClasses = {
83
- xs: { link: "text-xs py-0.5 pl-3", indicator: "w-0.5" },
84
- sm: { link: "text-sm py-0.5 pl-3", indicator: "w-0.5" },
85
- md: { link: "text-sm py-1 pl-4", indicator: "w-0.5" },
86
- lg: { link: "text-base py-1 pl-5", indicator: "w-1" }
87
- };
88
- function flattenIds(list) {
89
- return list.flatMap((item) => [item.id, ...item.children ? flattenIds(item.children) : []]);
90
- }
91
- function getScrollContainer(getContainer) {
92
- if (getContainer) return getContainer();
93
- return typeof window !== "undefined" ? window : null;
94
- }
95
- function getContainerRect(container) {
96
- if (!container || container === window || container instanceof Window) return { top: 0 };
97
- return container.getBoundingClientRect();
98
- }
99
- function scrollTo(container, top) {
100
- container.scrollTo({ top, behavior: "smooth" });
101
- }
102
- var Anchor = React4.memo(
103
- ({
104
- items,
105
- offset = 0,
106
- targetOffset = 0,
107
- size = "md",
108
- affix = false,
109
- affixTop = 0,
110
- getContainer,
111
- className,
112
- classNames,
113
- onChange
114
- }) => {
115
- const [activeId, setActiveId] = useState("");
116
- const [indicatorTop, setIndicatorTop] = useState(0);
117
- const [indicatorHeight, setIndicatorHeight] = useState(0);
118
- const navRef = useRef(null);
119
- const linkRefs = useRef(/* @__PURE__ */ new Map());
120
- const isScrolling = useRef(false);
121
- const allIds = flattenIds(items);
122
- const updateActive = useCallback(() => {
123
- if (isScrolling.current) return;
124
- if (typeof window === "undefined") return;
125
- const container = getScrollContainer(getContainer);
126
- const containerTop = getContainerRect(container).top;
127
- let current = "";
128
- for (const id of allIds) {
129
- const el = document.getElementById(id);
130
- if (el) {
131
- const rect = el.getBoundingClientRect();
132
- const relativeTop = rect.top - containerTop;
133
- if (relativeTop <= offset + 10) current = id;
134
- }
135
- }
136
- if (current && current !== activeId) {
137
- setActiveId(current);
138
- onChange?.(current);
139
- }
140
- }, [allIds, offset, activeId, onChange, getContainer]);
141
- useEffect(() => {
142
- if (typeof window === "undefined") return;
143
- const container = getScrollContainer(getContainer);
144
- const target = container instanceof Window ? window : container;
145
- target.addEventListener("scroll", updateActive, { passive: true });
146
- updateActive();
147
- return () => target.removeEventListener("scroll", updateActive);
148
- }, [updateActive, getContainer]);
149
- useEffect(() => {
150
- if (!activeId || !navRef.current) return;
151
- const linkEl = linkRefs.current.get(activeId);
152
- if (linkEl) {
153
- const navRect = navRef.current.getBoundingClientRect();
154
- const linkRect = linkEl.getBoundingClientRect();
155
- setIndicatorTop(linkRect.top - navRect.top);
156
- setIndicatorHeight(linkRect.height);
157
- }
158
- }, [activeId]);
159
- const handleClick = useCallback(
160
- (e, id) => {
161
- e.preventDefault();
162
- const el = document.getElementById(id);
163
- if (!el) return;
164
- const container = getScrollContainer(getContainer);
165
- isScrolling.current = true;
166
- setActiveId(id);
167
- onChange?.(id);
168
- if (container instanceof Window) {
169
- const y = el.getBoundingClientRect().top + window.scrollY - targetOffset;
170
- scrollTo(container, y);
171
- } else {
172
- const y = el.offsetTop - targetOffset;
173
- scrollTo(container, y);
174
- }
175
- setTimeout(() => {
176
- isScrolling.current = false;
177
- }, 800);
178
- },
179
- [targetOffset, onChange, getContainer]
180
- );
181
- const s = sizeClasses[size];
182
- const depthPadding = { 0: "", 1: "pl-6", 2: "pl-10", 3: "pl-14" };
183
- const renderLink = (item, depth = 0) => /* @__PURE__ */ jsxs(React4.Fragment, { children: [
184
- /* @__PURE__ */ jsx(
185
- "a",
186
- {
187
- ref: (el) => {
188
- if (el) linkRefs.current.set(item.id, el);
189
- },
190
- href: `#${item.id}`,
191
- onClick: (e) => handleClick(e, item.id),
192
- "data-slot": "link",
193
- className: cn(
194
- "anchor_link",
195
- "block text-text-secondary hover:text-text-primary transition-colors truncate",
196
- s.link,
197
- depth > 0 && (depthPadding[depth] || "pl-14"),
198
- activeId === item.id && "text-primary font-medium",
199
- activeId === item.id && classNames?.activeLink,
200
- classNames?.link
201
- ),
202
- children: item.label
203
- }
204
- ),
205
- item.children?.map((child) => renderLink(child, depth + 1))
206
- ] }, item.id);
207
- return /* @__PURE__ */ jsxs(
208
- "nav",
209
- {
210
- ref: navRef,
211
- "data-slot": "root",
212
- className: cn(
213
- "anchor_root",
214
- "relative",
215
- affix && "sticky",
216
- classNames?.root,
217
- className
218
- ),
219
- style: affix ? { top: affixTop } : void 0,
220
- "aria-label": "Table of contents",
221
- children: [
222
- /* @__PURE__ */ jsx(
223
- "div",
224
- {
225
- "data-slot": "indicator",
226
- className: cn(
227
- "anchor_indicator",
228
- "absolute left-0 rounded-full bg-primary transition-all duration-200",
229
- s.indicator,
230
- classNames?.indicator
231
- ),
232
- style: {
233
- top: indicatorTop,
234
- height: indicatorHeight,
235
- opacity: activeId ? 1 : 0
236
- }
237
- }
238
- ),
239
- /* @__PURE__ */ jsx("div", { className: "absolute left-0 top-0 bottom-0 w-px bg-border" }),
240
- items.map((item) => renderLink(item))
241
- ]
242
- }
243
- );
244
- }
245
- );
246
- Anchor.displayName = "Anchor";
247
- var anchor_default = Anchor;
248
- var inputVariants = cva(
249
- "w-full flex items-center rounded-md bg-background text-text-primary border outline-none transition-colors",
250
- {
251
- variants: {
252
- status: {
253
- default: "border-border focus-within:border-slot hover:border-slot-50",
254
- primary: "border-slot",
255
- secondary: "border-slot",
256
- accent: "border-slot",
257
- success: "border-slot",
258
- error: "border-slot",
259
- warning: "border-slot",
260
- info: "border-slot"
261
- },
262
- size: {
263
- xs: "h-(--input-height-xs) px-2 text-xs gap-1.5",
264
- sm: "h-(--input-height-sm) px-2.5 text-sm gap-2",
265
- md: "h-(--input-height-md) px-3 text-base gap-2",
266
- lg: "h-(--input-height-lg) px-3.5 text-lg gap-2.5"
267
- },
268
- fullWidth: {
269
- true: "w-full",
270
- false: ""
271
- },
272
- disabled: {
273
- true: "opacity-50 cursor-not-allowed",
274
- false: ""
275
- }
276
- },
277
- defaultVariants: {
278
- status: "default",
279
- size: "md",
280
- fullWidth: true,
281
- disabled: false
282
- }
283
- }
284
- );
285
- function normalizeOption(opt) {
286
- return typeof opt === "string" ? { label: opt, value: opt } : opt;
287
- }
288
- var defaultFilter = (query, option) => option.label.toLowerCase().includes(query.toLowerCase());
289
- var Autocomplete = React4.memo(
290
- ({
291
- value,
292
- defaultValue = "",
293
- onChange,
294
- onSelect,
295
- options: rawOptions,
296
- placeholder,
297
- label,
298
- helperText,
299
- error,
300
- size = "md",
301
- status: statusProp,
302
- disabled = false,
303
- loading = false,
304
- clearable = false,
305
- filter = defaultFilter,
306
- limit = 10,
307
- emptyMessage = "No results",
308
- fullWidth = true,
309
- className,
310
- classNames
311
- }) => {
312
- const [internalValue, setInternalValue] = React4.useState(defaultValue);
313
- const [isOpen, setIsOpen] = React4.useState(false);
314
- const [highlightIdx, setHighlightIdx] = React4.useState(-1);
315
- const inputRef = React4.useRef(null);
316
- const listRef = React4.useRef(null);
317
- const labelId = React4.useId();
318
- const selectingRef = React4.useRef(false);
319
- const currentValue = value !== void 0 ? value : internalValue;
320
- const status = error ? "error" : statusProp || "default";
321
- const options = React4.useMemo(
322
- () => rawOptions.map(normalizeOption),
323
- [rawOptions]
324
- );
325
- const filtered = React4.useMemo(() => {
326
- if (!currentValue) return options.slice(0, limit);
327
- return options.filter((o) => filter(currentValue, o)).slice(0, limit);
328
- }, [currentValue, options, filter, limit]);
329
- React4.useEffect(() => {
330
- setHighlightIdx(-1);
331
- }, [filtered.length]);
332
- const updateValue = (v) => {
333
- if (value === void 0) setInternalValue(v);
334
- onChange?.(v);
335
- };
336
- const open = () => {
337
- if (!disabled) setIsOpen(true);
338
- };
339
- const close = () => {
340
- setIsOpen(false);
341
- setHighlightIdx(-1);
342
- };
343
- const handleInputChange = (e) => {
344
- updateValue(e.target.value);
345
- open();
346
- };
347
- const handleSelect = (option) => {
348
- if (option.disabled) return;
349
- updateValue(option.label);
350
- onSelect?.(option);
351
- close();
352
- requestAnimationFrame(() => inputRef.current?.focus());
353
- };
354
- const handleClear = () => {
355
- updateValue("");
356
- inputRef.current?.focus();
357
- };
358
- const handleKeyDown = (e) => {
359
- if (e.key === "ArrowDown") {
360
- e.preventDefault();
361
- if (!isOpen) {
362
- open();
363
- return;
364
- }
365
- setHighlightIdx((i) => Math.min(i + 1, filtered.length - 1));
366
- } else if (e.key === "ArrowUp") {
367
- e.preventDefault();
368
- if (!isOpen) {
369
- open();
370
- return;
371
- }
372
- setHighlightIdx((i) => Math.max(i - 1, 0));
373
- } else if (e.key === "Enter" && highlightIdx >= 0 && isOpen) {
374
- e.preventDefault();
375
- handleSelect(filtered[highlightIdx]);
376
- } else if (e.key === "Escape") {
377
- close();
378
- } else if (e.key === "Tab") {
379
- close();
380
- }
381
- };
382
- const handleFocus = () => {
383
- open();
384
- };
385
- const handleBlur = () => {
386
- setTimeout(() => {
387
- if (!selectingRef.current) close();
388
- selectingRef.current = false;
389
- }, 150);
390
- };
391
- React4.useEffect(() => {
392
- if (highlightIdx >= 0 && listRef.current) {
393
- const el = listRef.current.children[highlightIdx];
394
- el?.scrollIntoView?.({ block: "nearest" });
395
- }
396
- }, [highlightIdx]);
397
- return /* @__PURE__ */ jsxs(
398
- "div",
399
- {
400
- "data-slot": "root",
401
- className: cn(
402
- "autocomplete_root",
403
- "flex flex-col gap-1.5",
404
- colorVars[status === "default" ? "primary" : status],
405
- fullWidth ? "w-full" : "inline-flex",
406
- classNames?.root,
407
- className
408
- ),
409
- children: [
410
- label && /* @__PURE__ */ jsx(
411
- "label",
412
- {
413
- id: labelId,
414
- className: "text-sm font-medium text-text-primary",
415
- children: label
416
- }
417
- ),
418
- /* @__PURE__ */ jsxs(Popover, { open: isOpen && !disabled, onOpenChange: (v) => {
419
- if (!v) close();
420
- }, children: [
421
- /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs(
422
- "div",
423
- {
424
- className: inputVariants({ status, size, fullWidth, disabled }),
425
- onClick: () => {
426
- if (!isOpen) open();
427
- inputRef.current?.focus();
428
- },
429
- children: [
430
- /* @__PURE__ */ jsx(
431
- "input",
432
- {
433
- ref: inputRef,
434
- type: "text",
435
- role: "combobox",
436
- "aria-expanded": isOpen,
437
- "aria-autocomplete": "list",
438
- "aria-labelledby": label ? labelId : void 0,
439
- className: "flex-1 min-w-0 bg-transparent outline-none placeholder:text-text-secondary/50",
440
- placeholder,
441
- value: currentValue,
442
- onChange: handleInputChange,
443
- onFocus: handleFocus,
444
- onBlur: handleBlur,
445
- onKeyDown: handleKeyDown,
446
- disabled
447
- }
448
- ),
449
- loading && /* @__PURE__ */ jsx(Loader2, { className: cn("animate-spin text-text-secondary", iconSizes[size]) }),
450
- clearable && currentValue && !disabled && !loading && /* @__PURE__ */ jsx(
451
- "button",
452
- {
453
- type: "button",
454
- onMouseDown: (e) => e.preventDefault(),
455
- onClick: (e) => {
456
- e.stopPropagation();
457
- handleClear();
458
- },
459
- className: "text-text-secondary hover:text-text-primary transition-colors cursor-pointer",
460
- tabIndex: -1,
461
- "aria-label": "Clear",
462
- children: /* @__PURE__ */ jsx(X, { className: iconSizes[size] })
463
- }
464
- ),
465
- !loading && !clearable && /* @__PURE__ */ jsx(
466
- ChevronDown,
467
- {
468
- className: cn(
469
- "text-text-secondary transition-transform duration-200",
470
- iconSizes[size],
471
- isOpen && "rotate-180"
472
- )
473
- }
474
- )
475
- ]
476
- }
477
- ) }),
478
- /* @__PURE__ */ jsx(
479
- PopoverContent,
480
- {
481
- className: cn(
482
- "autocomplete_dropdown",
483
- "p-1 w-[var(--radix-popover-trigger-width)] max-h-60 overflow-y-auto",
484
- classNames?.dropdown
485
- ),
486
- align: "start",
487
- onOpenAutoFocus: (e) => e.preventDefault(),
488
- onCloseAutoFocus: (e) => e.preventDefault(),
489
- onInteractOutside: (e) => {
490
- const target = e.target;
491
- if (inputRef.current?.contains(target)) {
492
- e.preventDefault();
493
- }
494
- },
495
- children: /* @__PURE__ */ jsx("div", { ref: listRef, role: "listbox", children: filtered.length === 0 ? /* @__PURE__ */ jsx(
496
- "div",
497
- {
498
- className: cn(
499
- "autocomplete_empty",
500
- "px-3 py-2 text-sm text-text-secondary text-center",
501
- classNames?.empty
502
- ),
503
- children: emptyMessage
504
- }
505
- ) : filtered.map((option, idx) => /* @__PURE__ */ jsx(
506
- "div",
507
- {
508
- role: "option",
509
- "aria-selected": idx === highlightIdx,
510
- "aria-disabled": option.disabled,
511
- onMouseDown: (e) => {
512
- e.preventDefault();
513
- selectingRef.current = true;
514
- },
515
- onClick: () => handleSelect(option),
516
- onMouseEnter: () => setHighlightIdx(idx),
517
- className: cn(
518
- "autocomplete_option",
519
- "px-3 py-2 text-sm rounded-md cursor-pointer transition-colors",
520
- idx === highlightIdx && "bg-surface",
521
- option.disabled && "opacity-50 cursor-not-allowed",
522
- !option.disabled && "hover:bg-surface",
523
- classNames?.option
524
- ),
525
- children: option.label
526
- },
527
- option.value
528
- )) })
529
- }
530
- )
531
- ] }),
532
- (error || helperText) && /* @__PURE__ */ jsx("p", { className: cn(
533
- "text-xs",
534
- error ? statusMessageVariants({ status: "error" }) : "text-text-secondary"
535
- ), children: error || helperText })
536
- ]
537
- }
538
- );
539
- }
540
- );
541
- Autocomplete.displayName = "Autocomplete";
542
- var autocomplete_default = Autocomplete;
543
- var calendarVariants = cva("inline-flex flex-col select-none", {
544
- variants: {
545
- size: {
546
- xs: "text-xs gap-1",
547
- sm: "text-sm gap-1.5",
548
- md: "text-sm gap-2",
549
- lg: "text-base gap-2.5"
550
- }
551
- },
552
- defaultVariants: { size: "md" }
553
- });
554
- var cellVariants = cva(
555
- "flex items-center justify-center rounded-md transition-colors cursor-pointer font-normal",
556
- {
557
- variants: {
558
- size: {
559
- xs: "w-7 h-7 text-xs",
560
- sm: "w-8 h-8 text-sm",
561
- md: "w-9 h-9 text-sm",
562
- lg: "w-10 h-10 text-base"
563
- }
564
- },
565
- defaultVariants: { size: "md" }
566
- }
567
- );
568
- var navBtnClass = "inline-flex items-center justify-center rounded-md w-7 h-7 hover:bg-surface transition-colors cursor-pointer text-text-secondary hover:text-text-primary";
569
- function isSameDay(a, b) {
570
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
571
- }
572
- function getDaysInMonth(year, month) {
573
- return new Date(year, month + 1, 0).getDate();
574
- }
575
- function getMonthGrid(year, month, weekStartsOn, showOutside) {
576
- const firstDay = new Date(year, month, 1).getDay();
577
- const daysInMonth = getDaysInMonth(year, month);
578
- const daysInPrevMonth = getDaysInMonth(year, month - 1);
579
- const offset = (firstDay - weekStartsOn + 7) % 7;
580
- const weeks = [];
581
- let week = [];
582
- for (let i = 0; i < offset; i++) {
583
- const day = daysInPrevMonth - offset + 1 + i;
584
- week.push({ date: new Date(year, month - 1, day), outside: true });
585
- }
586
- for (let day = 1; day <= daysInMonth; day++) {
587
- week.push({ date: new Date(year, month, day), outside: false });
588
- if (week.length === 7) {
589
- weeks.push(week);
590
- week = [];
591
- }
592
- }
593
- if (week.length > 0) {
594
- let nextDay = 1;
595
- while (week.length < 7) {
596
- week.push({ date: new Date(year, month + 1, nextDay++), outside: true });
597
- }
598
- weeks.push(week);
599
- }
600
- if (!showOutside) {
601
- return weeks.map(
602
- (w) => w.map((d) => d.outside ? { ...d, date: d.date } : d)
603
- );
604
- }
605
- return weeks;
606
- }
607
- var DAY_NAMES_SHORT = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
608
- var MONTH_NAMES = [
609
- "January",
610
- "February",
611
- "March",
612
- "April",
613
- "May",
614
- "June",
615
- "July",
616
- "August",
617
- "September",
618
- "October",
619
- "November",
620
- "December"
621
- ];
622
- var Calendar = React4.memo(
623
- ({
624
- value,
625
- defaultValue,
626
- onChange,
627
- month: controlledMonth,
628
- defaultMonth,
629
- onMonthChange,
630
- minDate,
631
- maxDate,
632
- disabledDates,
633
- size = "md",
634
- weekStartsOn = 0,
635
- showOutsideDays = true,
636
- className,
637
- classNames
638
- }) => {
639
- const today = /* @__PURE__ */ new Date();
640
- const [internalValue, setInternalValue] = React4.useState(
641
- defaultValue ?? null
642
- );
643
- const [internalMonth, setInternalMonth] = React4.useState(
644
- defaultMonth ?? defaultValue ?? today
645
- );
646
- const selected = value !== void 0 ? value : internalValue;
647
- const currentMonth = controlledMonth ?? internalMonth;
648
- const year = currentMonth.getFullYear();
649
- const monthIdx = currentMonth.getMonth();
650
- const weeks = React4.useMemo(
651
- () => getMonthGrid(year, monthIdx, weekStartsOn, showOutsideDays),
652
- [year, monthIdx, weekStartsOn, showOutsideDays]
653
- );
654
- const dayNames = React4.useMemo(() => {
655
- const names = [];
656
- for (let i = 0; i < 7; i++) {
657
- names.push(DAY_NAMES_SHORT[(weekStartsOn + i) % 7]);
658
- }
659
- return names;
660
- }, [weekStartsOn]);
661
- const navigate = (offset) => {
662
- const next = new Date(year, monthIdx + offset, 1);
663
- if (controlledMonth === void 0) setInternalMonth(next);
664
- onMonthChange?.(next);
665
- };
666
- const isDisabled = (date) => {
667
- if (minDate && date < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()))
668
- return true;
669
- if (maxDate && date > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()))
670
- return true;
671
- return disabledDates?.(date) ?? false;
672
- };
673
- const handleSelect = (date) => {
674
- if (isDisabled(date)) return;
675
- if (value === void 0) setInternalValue(date);
676
- onChange?.(date);
677
- if (date.getMonth() !== monthIdx) {
678
- navigate(date.getMonth() - monthIdx);
679
- }
680
- };
681
- return /* @__PURE__ */ jsxs(
682
- "div",
683
- {
684
- "data-slot": "root",
685
- className: cn(
686
- "calendar_root",
687
- calendarVariants({ size }),
688
- classNames?.root,
689
- className
690
- ),
691
- children: [
692
- /* @__PURE__ */ jsxs(
693
- "div",
694
- {
695
- "data-slot": "header",
696
- className: cn(
697
- "calendar_header",
698
- "flex items-center justify-between px-1",
699
- classNames?.header
700
- ),
701
- children: [
702
- /* @__PURE__ */ jsx(
703
- "button",
704
- {
705
- type: "button",
706
- onClick: () => navigate(-1),
707
- className: navBtnClass,
708
- "aria-label": "Previous month",
709
- children: /* @__PURE__ */ jsx(ChevronLeft, { className: "w-4 h-4" })
710
- }
711
- ),
712
- /* @__PURE__ */ jsxs("span", { className: "font-semibold text-text-primary", children: [
713
- MONTH_NAMES[monthIdx],
714
- " ",
715
- year
716
- ] }),
717
- /* @__PURE__ */ jsx(
718
- "button",
719
- {
720
- type: "button",
721
- onClick: () => navigate(1),
722
- className: navBtnClass,
723
- "aria-label": "Next month",
724
- children: /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4" })
725
- }
726
- )
727
- ]
728
- }
729
- ),
730
- /* @__PURE__ */ jsxs(
731
- "div",
732
- {
733
- "data-slot": "grid",
734
- className: cn("calendar_grid", "grid grid-cols-7", classNames?.grid),
735
- role: "grid",
736
- children: [
737
- dayNames.map((name) => /* @__PURE__ */ jsx(
738
- "div",
739
- {
740
- role: "columnheader",
741
- className: cn(
742
- "calendar_dayName",
743
- cellVariants({ size }),
744
- "font-medium text-text-secondary cursor-default",
745
- classNames?.dayName
746
- ),
747
- children: name
748
- },
749
- name
750
- )),
751
- weeks.map(
752
- (week, wi) => week.map(({ date, outside }) => {
753
- const disabled = isDisabled(date);
754
- const isToday = isSameDay(date, today);
755
- const isSelected = selected ? isSameDay(date, selected) : false;
756
- return /* @__PURE__ */ jsx(
757
- "button",
758
- {
759
- type: "button",
760
- role: "gridcell",
761
- disabled,
762
- onClick: () => handleSelect(date),
763
- "aria-selected": isSelected,
764
- "aria-current": isToday ? "date" : void 0,
765
- className: cn(
766
- "calendar_day",
767
- cellVariants({ size }),
768
- outside && "text-text-secondary/40",
769
- outside && !showOutsideDays && "invisible",
770
- disabled && "opacity-30 cursor-not-allowed",
771
- !disabled && !isSelected && "hover:bg-surface",
772
- isToday && !isSelected && "border border-primary text-primary",
773
- isSelected && "bg-primary text-primary-foreground",
774
- classNames?.day,
775
- isToday && classNames?.today,
776
- isSelected && classNames?.selected,
777
- outside && classNames?.outside,
778
- disabled && classNames?.disabled
779
- ),
780
- children: date.getDate()
781
- },
782
- `${wi}-${date.toISOString()}`
783
- );
784
- })
785
- )
786
- ]
787
- }
788
- )
789
- ]
790
- }
791
- );
792
- }
793
- );
794
- Calendar.displayName = "Calendar";
795
- var calendar_default = Calendar;
796
- function hexToHsv(hex) {
797
- const r = parseInt(hex.slice(1, 3), 16) / 255;
798
- const g = parseInt(hex.slice(3, 5), 16) / 255;
799
- const b = parseInt(hex.slice(5, 7), 16) / 255;
800
- const max = Math.max(r, g, b), min = Math.min(r, g, b);
801
- const d = max - min;
802
- let h = 0;
803
- if (d !== 0) {
804
- if (max === r) h = ((g - b) / d + 6) % 6;
805
- else if (max === g) h = (b - r) / d + 2;
806
- else h = (r - g) / d + 4;
807
- h *= 60;
808
- }
809
- const s = max === 0 ? 0 : d / max;
810
- return [h, s, max];
811
- }
812
- function hsvToHex(h, s, v) {
813
- const c = v * s;
814
- const x = c * (1 - Math.abs(h / 60 % 2 - 1));
815
- const m = v - c;
816
- let r = 0, g = 0, b = 0;
817
- if (h < 60) {
818
- r = c;
819
- g = x;
820
- } else if (h < 120) {
821
- r = x;
822
- g = c;
823
- } else if (h < 180) {
824
- g = c;
825
- b = x;
826
- } else if (h < 240) {
827
- g = x;
828
- b = c;
829
- } else if (h < 300) {
830
- r = x;
831
- b = c;
832
- } else {
833
- r = c;
834
- b = x;
835
- }
836
- const toHex = (n) => Math.round((n + m) * 255).toString(16).padStart(2, "0");
837
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
838
- }
839
- function isValidHex(v) {
840
- return /^#[0-9a-fA-F]{6}$/.test(v);
841
- }
842
- function normalizeHex(v) {
843
- if (!v) return "#000000";
844
- const clean = v.startsWith("#") ? v : `#${v}`;
845
- return isValidHex(clean) ? clean.toLowerCase() : "#000000";
846
- }
847
- var sizeMap = {
848
- xs: { area: "w-40 h-28", hue: "h-2", swatch: "w-4 h-4" },
849
- sm: { area: "w-48 h-32", hue: "h-2.5", swatch: "w-5 h-5" },
850
- md: { area: "w-56 h-36", hue: "h-3", swatch: "w-6 h-6" },
851
- lg: { area: "w-64 h-44", hue: "h-3.5", swatch: "w-7 h-7" }
852
- };
853
- var inputVariants2 = cva(
854
- "flex items-center rounded-md border border-border bg-background text-text-primary transition-colors focus-within:border-primary",
855
- {
856
- variants: {
857
- size: {
858
- xs: "h-7 px-2 text-xs gap-1.5",
859
- sm: "h-8 px-2.5 text-sm gap-2",
860
- md: "h-9 px-3 text-sm gap-2",
861
- lg: "h-10 px-3.5 text-base gap-2.5"
862
- }
863
- },
864
- defaultVariants: { size: "md" }
865
- }
866
- );
867
- function SaturationArea({
868
- hue,
869
- sat,
870
- val,
871
- onChangeSV,
872
- areaClass,
873
- disabled
874
- }) {
875
- const ref = React4.useRef(null);
876
- const update = React4.useCallback(
877
- (clientX, clientY) => {
878
- if (!ref.current || disabled) return;
879
- const rect = ref.current.getBoundingClientRect();
880
- const s = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
881
- const v = Math.max(0, Math.min(1, 1 - (clientY - rect.top) / rect.height));
882
- onChangeSV(s, v);
883
- },
884
- [onChangeSV, disabled]
885
- );
886
- const handlePointerDown = (e) => {
887
- if (disabled) return;
888
- e.currentTarget.setPointerCapture(e.pointerId);
889
- update(e.clientX, e.clientY);
890
- };
891
- const handlePointerMove = (e) => {
892
- if (e.currentTarget.hasPointerCapture(e.pointerId)) {
893
- update(e.clientX, e.clientY);
894
- }
895
- };
896
- return /* @__PURE__ */ jsxs(
897
- "div",
898
- {
899
- ref,
900
- className: cn("colorPicker_saturation", "relative rounded-md cursor-crosshair", areaClass),
901
- style: { background: `hsl(${hue}, 100%, 50%)` },
902
- onPointerDown: handlePointerDown,
903
- onPointerMove: handlePointerMove,
904
- children: [
905
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-md", style: { background: "linear-gradient(to right, white, transparent)" } }),
906
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-md", style: { background: "linear-gradient(to top, black, transparent)" } }),
907
- /* @__PURE__ */ jsx(
908
- "div",
909
- {
910
- className: "absolute w-3.5 h-3.5 rounded-full border-2 border-white shadow-md -translate-x-1/2 -translate-y-1/2 pointer-events-none",
911
- style: { left: `${sat * 100}%`, top: `${(1 - val) * 100}%` }
912
- }
913
- )
914
- ]
915
- }
916
- );
917
- }
918
- function HueSlider({
919
- hue,
920
- onChange,
921
- hueClass,
922
- disabled
923
- }) {
924
- const ref = React4.useRef(null);
925
- const update = React4.useCallback(
926
- (clientX) => {
927
- if (!ref.current || disabled) return;
928
- const rect = ref.current.getBoundingClientRect();
929
- const h = Math.max(0, Math.min(360, (clientX - rect.left) / rect.width * 360));
930
- onChange(h);
931
- },
932
- [onChange, disabled]
933
- );
934
- const handlePointerDown = (e) => {
935
- if (disabled) return;
936
- e.currentTarget.setPointerCapture(e.pointerId);
937
- update(e.clientX);
938
- };
939
- const handlePointerMove = (e) => {
940
- if (e.currentTarget.hasPointerCapture(e.pointerId)) update(e.clientX);
941
- };
942
- return /* @__PURE__ */ jsx(
943
- "div",
944
- {
945
- ref,
946
- className: cn("colorPicker_hue", "relative rounded-full cursor-pointer", hueClass),
947
- style: { background: "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)" },
948
- onPointerDown: handlePointerDown,
949
- onPointerMove: handlePointerMove,
950
- children: /* @__PURE__ */ jsx(
951
- "div",
952
- {
953
- className: "absolute w-3.5 h-3.5 rounded-full border-2 border-white shadow-md -translate-x-1/2 top-1/2 -translate-y-1/2 pointer-events-none",
954
- style: { left: `${hue / 360 * 100}%` }
955
- }
956
- )
957
- }
958
- );
959
- }
960
- var ColorPicker = React4.memo(
961
- ({
962
- value,
963
- defaultValue = "#3b82f6",
964
- onChange,
965
- swatches,
966
- size = "md",
967
- disabled = false,
968
- label,
969
- className,
970
- classNames
971
- }) => {
972
- const [internalValue, setInternalValue] = React4.useState(normalizeHex(defaultValue));
973
- const currentValue = value !== void 0 ? normalizeHex(value) : internalValue;
974
- const [h, s, v] = React4.useMemo(() => hexToHsv(currentValue), [currentValue]);
975
- const [hue, setHue] = React4.useState(h);
976
- React4.useEffect(() => {
977
- if (s > 0.01 || v > 0.01) setHue(h);
978
- }, [h, s, v]);
979
- const [inputText, setInputText] = React4.useState(currentValue);
980
- React4.useEffect(() => setInputText(currentValue), [currentValue]);
981
- const update = (hex) => {
982
- const valid = normalizeHex(hex);
983
- if (value === void 0) setInternalValue(valid);
984
- onChange?.(valid);
985
- };
986
- const handleSVChange = (ns, nv) => {
987
- update(hsvToHex(hue, ns, nv));
988
- };
989
- const handleHueChange = (nh) => {
990
- setHue(nh);
991
- update(hsvToHex(nh, s, v));
992
- };
993
- const handleInputBlur = () => {
994
- if (isValidHex(inputText) || isValidHex(`#${inputText}`)) {
995
- update(inputText.startsWith("#") ? inputText : `#${inputText}`);
996
- } else {
997
- setInputText(currentValue);
998
- }
999
- };
1000
- const sizes = sizeMap[size];
1001
- return /* @__PURE__ */ jsxs(
1002
- "div",
1003
- {
1004
- "data-slot": "root",
1005
- className: cn(
1006
- "colorPicker_root",
1007
- "inline-flex flex-col gap-2",
1008
- disabled && "opacity-50 pointer-events-none",
1009
- classNames?.root,
1010
- className
1011
- ),
1012
- children: [
1013
- label && /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-text-primary", children: label }),
1014
- /* @__PURE__ */ jsx(
1015
- SaturationArea,
1016
- {
1017
- hue,
1018
- sat: s,
1019
- val: v,
1020
- onChangeSV: handleSVChange,
1021
- areaClass: cn(sizes.area, classNames?.saturation),
1022
- disabled
1023
- }
1024
- ),
1025
- /* @__PURE__ */ jsx(
1026
- HueSlider,
1027
- {
1028
- hue,
1029
- onChange: handleHueChange,
1030
- hueClass: cn(sizes.hue, classNames?.hueSlider),
1031
- disabled
1032
- }
1033
- ),
1034
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1035
- /* @__PURE__ */ jsx(
1036
- "div",
1037
- {
1038
- "data-slot": "preview",
1039
- className: cn(
1040
- "colorPicker_preview",
1041
- "w-8 h-8 rounded-md border border-border shrink-0",
1042
- classNames?.preview
1043
- ),
1044
- style: { backgroundColor: currentValue }
1045
- }
1046
- ),
1047
- /* @__PURE__ */ jsx(
1048
- "input",
1049
- {
1050
- type: "text",
1051
- value: inputText,
1052
- onChange: (e) => setInputText(e.target.value),
1053
- onBlur: handleInputBlur,
1054
- onKeyDown: (e) => e.key === "Enter" && handleInputBlur(),
1055
- className: cn(
1056
- "colorPicker_input",
1057
- "flex-1 min-w-0 bg-transparent border border-border rounded-md px-2 py-1 text-sm text-text-primary outline-none focus:border-primary font-mono",
1058
- classNames?.input
1059
- ),
1060
- disabled
1061
- }
1062
- )
1063
- ] }),
1064
- swatches && swatches.length > 0 && /* @__PURE__ */ jsx(
1065
- "div",
1066
- {
1067
- "data-slot": "swatches",
1068
- className: cn(
1069
- "colorPicker_swatches",
1070
- "flex flex-wrap gap-1",
1071
- classNames?.swatches
1072
- ),
1073
- children: swatches.map((swatch) => /* @__PURE__ */ jsx(
1074
- "button",
1075
- {
1076
- type: "button",
1077
- onClick: () => update(swatch),
1078
- className: cn(
1079
- "colorPicker_swatch",
1080
- sizes.swatch,
1081
- "rounded-md border border-border cursor-pointer transition-transform hover:scale-110",
1082
- currentValue === normalizeHex(swatch) && "ring-2 ring-primary ring-offset-1 ring-offset-background",
1083
- classNames?.swatch
1084
- ),
1085
- style: { backgroundColor: swatch },
1086
- "aria-label": `Select color ${swatch}`
1087
- },
1088
- swatch
1089
- ))
1090
- }
1091
- )
1092
- ]
1093
- }
1094
- );
1095
- }
1096
- );
1097
- ColorPicker.displayName = "ColorPicker";
1098
- var ColorInput = React4.memo(
1099
- ({
1100
- value,
1101
- defaultValue = "#3b82f6",
1102
- onChange,
1103
- swatches,
1104
- size = "md",
1105
- disabled = false,
1106
- label,
1107
- fullWidth = true,
1108
- className,
1109
- classNames
1110
- }) => {
1111
- const [internalValue, setInternalValue] = React4.useState(normalizeHex(defaultValue));
1112
- const currentValue = value !== void 0 ? normalizeHex(value) : internalValue;
1113
- const update = (hex) => {
1114
- const valid = normalizeHex(hex);
1115
- if (value === void 0) setInternalValue(valid);
1116
- onChange?.(valid);
1117
- };
1118
- return /* @__PURE__ */ jsxs(
1119
- "div",
1120
- {
1121
- "data-slot": "root",
1122
- className: cn(
1123
- "colorInput_root",
1124
- "flex flex-col gap-1.5",
1125
- fullWidth ? "w-full" : "inline-flex",
1126
- className
1127
- ),
1128
- children: [
1129
- label && /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-text-primary", children: label }),
1130
- /* @__PURE__ */ jsxs(Popover, { children: [
1131
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: cn(inputVariants2({ size }), disabled && "opacity-50 cursor-not-allowed", fullWidth && "w-full"), children: [
1132
- /* @__PURE__ */ jsx(
1133
- "div",
1134
- {
1135
- className: "w-5 h-5 rounded border border-border shrink-0",
1136
- style: { backgroundColor: currentValue }
1137
- }
1138
- ),
1139
- /* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-text-primary font-mono", children: currentValue })
1140
- ] }) }),
1141
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-3", align: "start", children: /* @__PURE__ */ jsx(
1142
- ColorPicker,
1143
- {
1144
- value: currentValue,
1145
- onChange: update,
1146
- swatches,
1147
- size,
1148
- disabled,
1149
- classNames
1150
- }
1151
- ) })
1152
- ] })
1153
- ]
1154
- }
1155
- );
1156
- }
1157
- );
1158
- ColorInput.displayName = "ColorInput";
1159
- var buttonVariants = cva(
1160
- "inline-flex items-center justify-center shadow-lg transition-all hover:scale-105 active:scale-95 disabled:opacity-50 disabled:pointer-events-none cursor-pointer",
1161
- {
1162
- variants: {
1163
- size: {
1164
- xs: "w-8 h-8 text-sm",
1165
- sm: "w-10 h-10 text-base",
1166
- md: "w-12 h-12 text-lg",
1167
- lg: "w-14 h-14 text-xl"
1168
- },
1169
- shape: {
1170
- circle: "rounded-full",
1171
- square: "rounded-lg"
1172
- },
1173
- variant: {
1174
- default: "bg-background border border-border text-text-primary hover:bg-surface",
1175
- colored: "bg-slot text-slot-fg hover:bg-slot-90"
1176
- }
1177
- },
1178
- defaultVariants: { size: "md", shape: "circle", variant: "default" }
1179
- }
1180
- );
1181
- var FloatButton = React4.memo(
1182
- ({
1183
- icon,
1184
- label,
1185
- tooltip,
1186
- badge,
1187
- onClick,
1188
- href,
1189
- target,
1190
- color = "default",
1191
- size = "md",
1192
- shape = "circle",
1193
- disabled = false,
1194
- className,
1195
- classNames,
1196
- style
1197
- }) => {
1198
- const variant = color === "default" ? "default" : "colored";
1199
- const Component = href ? "a" : "button";
1200
- const content = /* @__PURE__ */ jsxs(
1201
- Component,
1202
- {
1203
- ...href ? { href, target } : { type: "button", onClick, disabled },
1204
- "data-slot": "button",
1205
- title: tooltip,
1206
- className: cn(
1207
- "floatButton_button",
1208
- buttonVariants({ size, shape, variant }),
1209
- color !== "default" && colorVars[color],
1210
- "relative",
1211
- classNames?.button,
1212
- className
1213
- ),
1214
- style,
1215
- children: [
1216
- icon,
1217
- label && !icon && /* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: label }),
1218
- badge !== void 0 && /* @__PURE__ */ jsx(
1219
- "span",
1220
- {
1221
- "data-slot": "badge",
1222
- className: cn(
1223
- "floatButton_badge",
1224
- "absolute -top-1 -right-1 min-w-[18px] h-[18px] px-1 rounded-full bg-error text-error-foreground text-[10px] font-medium flex items-center justify-center",
1225
- classNames?.badge
1226
- ),
1227
- children: badge
1228
- }
1229
- )
1230
- ]
1231
- }
1232
- );
1233
- return content;
1234
- }
1235
- );
1236
- FloatButton.displayName = "FloatButton";
1237
- var FloatButtonGroup = React4.memo(
1238
- ({
1239
- children,
1240
- trigger = "click",
1241
- icon,
1242
- closeIcon,
1243
- open: controlledOpen,
1244
- onOpenChange,
1245
- shape = "circle",
1246
- color = "primary",
1247
- size = "md",
1248
- placement = "top",
1249
- className,
1250
- classNames,
1251
- style
1252
- }) => {
1253
- const [internalOpen, setInternalOpen] = useState(false);
1254
- const isOpen = controlledOpen !== void 0 ? controlledOpen : internalOpen;
1255
- const setOpen = useCallback(
1256
- (v) => {
1257
- if (controlledOpen === void 0) setInternalOpen(v);
1258
- onOpenChange?.(v);
1259
- },
1260
- [controlledOpen, onOpenChange]
1261
- );
1262
- const placementClasses = {
1263
- top: "flex-col-reverse gap-3 bottom-0",
1264
- bottom: "flex-col gap-3 top-0",
1265
- left: "flex-row-reverse gap-3 right-0",
1266
- right: "flex-row gap-3 left-0"
1267
- };
1268
- const openIcon = icon ?? /* @__PURE__ */ jsx(Plus, { className: "w-5 h-5" });
1269
- const closedIcon = closeIcon ?? /* @__PURE__ */ jsx(X, { className: "w-5 h-5" });
1270
- return /* @__PURE__ */ jsxs(
1271
- "div",
1272
- {
1273
- "data-slot": "group",
1274
- className: cn("floatButton_group", "relative inline-flex", classNames?.group, className),
1275
- style,
1276
- onMouseEnter: trigger === "hover" ? () => setOpen(true) : void 0,
1277
- onMouseLeave: trigger === "hover" ? () => setOpen(false) : void 0,
1278
- children: [
1279
- /* @__PURE__ */ jsx(
1280
- FloatButton,
1281
- {
1282
- icon: /* @__PURE__ */ jsx("span", { className: cn("transition-transform duration-200", isOpen && "rotate-45"), children: isOpen ? closedIcon : openIcon }),
1283
- color,
1284
- size,
1285
- shape,
1286
- onClick: trigger === "click" ? () => setOpen(!isOpen) : void 0
1287
- }
1288
- ),
1289
- isOpen && /* @__PURE__ */ jsx("div", { className: cn("absolute flex items-center", placementClasses[placement]), children: React4.Children.map(children, (child, idx) => {
1290
- if (!React4.isValidElement(child)) return child;
1291
- return /* @__PURE__ */ jsx(
1292
- "div",
1293
- {
1294
- className: "animate-in fade-in zoom-in-75",
1295
- style: { animationDelay: `${idx * 50}ms`, animationFillMode: "both", animationDuration: "150ms" },
1296
- children: React4.cloneElement(child, {
1297
- size: child.props.size || size,
1298
- shape: child.props.shape || shape
1299
- })
1300
- },
1301
- idx
1302
- );
1303
- }) })
1304
- ]
1305
- }
1306
- );
1307
- }
1308
- );
1309
- FloatButtonGroup.displayName = "FloatButtonGroup";
1310
- var BackTop = React4.memo(
1311
- ({
1312
- visibilityHeight = 400,
1313
- onClick,
1314
- icon,
1315
- size = "md",
1316
- shape = "circle",
1317
- color = "default",
1318
- ...props
1319
- }) => {
1320
- const [visible, setVisible] = useState(false);
1321
- useEffect(() => {
1322
- if (typeof window === "undefined") return;
1323
- const handleScroll = () => setVisible(window.scrollY >= visibilityHeight);
1324
- handleScroll();
1325
- window.addEventListener("scroll", handleScroll, { passive: true });
1326
- return () => window.removeEventListener("scroll", handleScroll);
1327
- }, [visibilityHeight]);
1328
- const handleClick = useCallback(() => {
1329
- window.scrollTo({ top: 0, behavior: "smooth" });
1330
- onClick?.();
1331
- }, [onClick]);
1332
- if (!visible) return null;
1333
- return /* @__PURE__ */ jsx(
1334
- FloatButton,
1335
- {
1336
- icon: icon ?? /* @__PURE__ */ jsx(ArrowUp, { className: "w-5 h-5" }),
1337
- tooltip: "Back to top",
1338
- onClick: handleClick,
1339
- size,
1340
- shape,
1341
- color,
1342
- ...props
1343
- }
1344
- );
1345
- }
1346
- );
1347
- BackTop.displayName = "BackTop";
1348
- var textareaVariants = cva(
1349
- "w-full rounded-md border bg-background text-text-primary placeholder:text-text-secondary/50 outline-none transition-colors disabled:opacity-50 disabled:cursor-not-allowed read-only:bg-surface read-only:cursor-default",
1350
- {
1351
- variants: {
1352
- size: {
1353
- xs: "px-(--input-padding-x-xs) py-1.5 text-xs",
1354
- sm: "px-(--input-padding-x-sm) py-2 text-sm",
1355
- md: "px-(--input-padding-x-md) py-2 text-sm",
1356
- lg: "px-(--input-padding-x-lg) py-2.5 text-base"
1357
- },
1358
- status: {
1359
- default: "border-border focus:border-primary",
1360
- error: "border-error focus:border-error"
1361
- }
1362
- },
1363
- defaultVariants: { size: "md", status: "default" }
1364
- }
1365
- );
1366
- function getCaretCoordinates(element, position) {
1367
- const div = document.createElement("div");
1368
- const style = getComputedStyle(element);
1369
- const props = [
1370
- "fontFamily",
1371
- "fontSize",
1372
- "fontWeight",
1373
- "letterSpacing",
1374
- "lineHeight",
1375
- "paddingTop",
1376
- "paddingRight",
1377
- "paddingBottom",
1378
- "paddingLeft",
1379
- "borderTopWidth",
1380
- "borderRightWidth",
1381
- "borderBottomWidth",
1382
- "borderLeftWidth",
1383
- "wordWrap",
1384
- "whiteSpace",
1385
- "overflowWrap"
1386
- ];
1387
- div.style.position = "absolute";
1388
- div.style.visibility = "hidden";
1389
- div.style.whiteSpace = "pre-wrap";
1390
- div.style.wordWrap = "break-word";
1391
- div.style.width = `${element.offsetWidth}px`;
1392
- for (const prop of props) div.style[prop] = style.getPropertyValue(prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`));
1393
- div.textContent = element.value.substring(0, position);
1394
- const span = document.createElement("span");
1395
- span.textContent = element.value.substring(position) || ".";
1396
- div.appendChild(span);
1397
- document.body.appendChild(div);
1398
- const top = span.offsetTop - element.scrollTop;
1399
- const left = span.offsetLeft - element.scrollLeft;
1400
- document.body.removeChild(div);
1401
- return { top, left };
1402
- }
1403
- var Mentions = React4.memo(
1404
- ({
1405
- value,
1406
- defaultValue = "",
1407
- onChange,
1408
- onSelect,
1409
- options = [],
1410
- triggers = ["@"],
1411
- loading = false,
1412
- size = "md",
1413
- disabled = false,
1414
- readOnly = false,
1415
- placeholder,
1416
- rows = 3,
1417
- label,
1418
- error,
1419
- helperText,
1420
- fullWidth = true,
1421
- className,
1422
- classNames
1423
- }) => {
1424
- const [internalValue, setInternalValue] = useState(defaultValue);
1425
- const currentValue = value !== void 0 ? value : internalValue;
1426
- const [showDropdown, setShowDropdown] = useState(false);
1427
- const [query, setQuery] = useState("");
1428
- const [activeTrigger, setActiveTrigger] = useState("");
1429
- const [triggerStart, setTriggerStart] = useState(-1);
1430
- const [highlightedIdx, setHighlightedIdx] = useState(0);
1431
- const [dropdownPos, setDropdownPos] = useState({ top: 0, left: 0 });
1432
- const textareaRef = useRef(null);
1433
- const update = useCallback(
1434
- (v) => {
1435
- if (value === void 0) setInternalValue(v);
1436
- onChange?.(v);
1437
- },
1438
- [value, onChange]
1439
- );
1440
- const filteredOptions = useMemo(() => {
1441
- if (!query) return options;
1442
- const q = query.toLowerCase();
1443
- return options.filter(
1444
- (o) => o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q)
1445
- );
1446
- }, [options, query]);
1447
- const insertMention = useCallback(
1448
- (option) => {
1449
- const before = currentValue.substring(0, triggerStart);
1450
- const after = currentValue.substring(textareaRef.current?.selectionStart ?? triggerStart);
1451
- const mention = `${activeTrigger}${option.value} `;
1452
- const next = before + mention + after;
1453
- update(next);
1454
- onSelect?.(option, activeTrigger);
1455
- setShowDropdown(false);
1456
- setQuery("");
1457
- requestAnimationFrame(() => {
1458
- if (textareaRef.current) {
1459
- const pos = before.length + mention.length;
1460
- textareaRef.current.selectionStart = pos;
1461
- textareaRef.current.selectionEnd = pos;
1462
- textareaRef.current.focus();
1463
- }
1464
- });
1465
- },
1466
- [currentValue, triggerStart, activeTrigger, update, onSelect]
1467
- );
1468
- const handleChange = (e) => {
1469
- const v = e.target.value;
1470
- update(v);
1471
- const cursor = e.target.selectionStart;
1472
- const textBefore = v.substring(0, cursor);
1473
- let found = false;
1474
- for (const trigger of triggers) {
1475
- const lastTrigger = textBefore.lastIndexOf(trigger);
1476
- if (lastTrigger >= 0) {
1477
- const between = textBefore.substring(lastTrigger + trigger.length);
1478
- const charBefore = lastTrigger > 0 ? textBefore[lastTrigger - 1] : " ";
1479
- if (/\s/.test(charBefore) || lastTrigger === 0) {
1480
- if (!/\s/.test(between)) {
1481
- setActiveTrigger(trigger);
1482
- setTriggerStart(lastTrigger);
1483
- setQuery(between);
1484
- setShowDropdown(true);
1485
- setHighlightedIdx(0);
1486
- found = true;
1487
- if (typeof window !== "undefined" && textareaRef.current) {
1488
- const coords = getCaretCoordinates(textareaRef.current, lastTrigger);
1489
- setDropdownPos({ top: coords.top + 24, left: coords.left });
1490
- }
1491
- break;
1492
- }
1493
- }
1494
- }
1495
- }
1496
- if (!found) setShowDropdown(false);
1497
- };
1498
- const handleKeyDown = (e) => {
1499
- if (!showDropdown || filteredOptions.length === 0) return;
1500
- if (e.key === "ArrowDown") {
1501
- e.preventDefault();
1502
- setHighlightedIdx((p) => Math.min(p + 1, filteredOptions.length - 1));
1503
- } else if (e.key === "ArrowUp") {
1504
- e.preventDefault();
1505
- setHighlightedIdx((p) => Math.max(p - 1, 0));
1506
- } else if (e.key === "Enter" || e.key === "Tab") {
1507
- e.preventDefault();
1508
- if (filteredOptions[highlightedIdx]) insertMention(filteredOptions[highlightedIdx]);
1509
- } else if (e.key === "Escape") {
1510
- setShowDropdown(false);
1511
- }
1512
- };
1513
- useEffect(() => {
1514
- if (highlightedIdx >= filteredOptions.length) setHighlightedIdx(Math.max(0, filteredOptions.length - 1));
1515
- }, [filteredOptions.length, highlightedIdx]);
1516
- return /* @__PURE__ */ jsxs(
1517
- "div",
1518
- {
1519
- "data-slot": "root",
1520
- className: cn(
1521
- "mentions_root",
1522
- "flex flex-col gap-1.5",
1523
- fullWidth ? "w-full" : "inline-flex",
1524
- classNames?.root,
1525
- className
1526
- ),
1527
- children: [
1528
- label && /* @__PURE__ */ jsx("label", { "data-slot": "label", className: "text-sm font-medium text-text-primary", children: label }),
1529
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1530
- /* @__PURE__ */ jsx(
1531
- "textarea",
1532
- {
1533
- ref: textareaRef,
1534
- value: currentValue,
1535
- onChange: handleChange,
1536
- onKeyDown: handleKeyDown,
1537
- onBlur: () => setTimeout(() => setShowDropdown(false), 150),
1538
- placeholder,
1539
- rows,
1540
- disabled,
1541
- readOnly,
1542
- "data-slot": "textarea",
1543
- className: cn(
1544
- "mentions_textarea",
1545
- textareaVariants({ size, status: error ? "error" : "default" }),
1546
- "resize-y",
1547
- classNames?.textarea
1548
- )
1549
- }
1550
- ),
1551
- showDropdown && filteredOptions.length > 0 && /* @__PURE__ */ jsx(
1552
- "div",
1553
- {
1554
- "data-slot": "dropdown",
1555
- className: cn(
1556
- "mentions_dropdown",
1557
- "absolute z-[var(--z-popover)] rounded-md border border-border bg-background shadow-md max-h-[200px] overflow-auto min-w-[180px]",
1558
- classNames?.dropdown
1559
- ),
1560
- style: { top: dropdownPos.top, left: Math.min(dropdownPos.left, 200) },
1561
- children: loading ? /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-sm text-text-secondary", children: "Loading..." }) : filteredOptions.map((option, idx) => /* @__PURE__ */ jsxs(
1562
- "div",
1563
- {
1564
- onMouseDown: (e) => {
1565
- e.preventDefault();
1566
- insertMention(option);
1567
- },
1568
- onMouseEnter: () => setHighlightedIdx(idx),
1569
- "data-slot": "option",
1570
- className: cn(
1571
- "mentions_option",
1572
- "flex items-center gap-2 px-3 py-1.5 text-sm cursor-pointer transition-colors",
1573
- idx === highlightedIdx ? "bg-surface text-text-primary" : "text-text-primary hover:bg-surface",
1574
- classNames?.option
1575
- ),
1576
- children: [
1577
- option.icon && /* @__PURE__ */ jsx("span", { className: "shrink-0 w-5 h-5", children: option.icon }),
1578
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
1579
- /* @__PURE__ */ jsx("div", { className: "font-medium truncate", children: option.label }),
1580
- option.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-text-secondary truncate", children: option.description })
1581
- ] })
1582
- ]
1583
- },
1584
- option.value
1585
- ))
1586
- }
1587
- )
1588
- ] }),
1589
- (error || helperText) && /* @__PURE__ */ jsx("p", { "data-slot": "message", className: cn("text-xs", error ? statusMessageVariants({ status: "error" }) : "text-text-secondary"), children: error || helperText })
1590
- ]
1591
- }
1592
- );
1593
- }
1594
- );
1595
- Mentions.displayName = "Mentions";
1596
- var mentions_default = Mentions;
1597
- var _createFn = null;
1598
- async function loadQRLib() {
1599
- if (_createFn) return true;
1600
- try {
1601
- const mod = await import('qrcode');
1602
- _createFn = mod.create || mod.default?.create || null;
1603
- return !!_createFn;
1604
- } catch {
1605
- return false;
1606
- }
1607
- }
1608
- function createQRMatrixSync(text, errorLevel) {
1609
- if (!_createFn) return null;
1610
- try {
1611
- const result = _createFn(text, { errorCorrectionLevel: errorLevel });
1612
- return result.modules;
1613
- } catch {
1614
- return null;
1615
- }
1616
- }
1617
- function resolveColor(el, varName) {
1618
- if (typeof window === "undefined") return null;
1619
- try {
1620
- const raw = getComputedStyle(el).getPropertyValue(varName).trim();
1621
- if (!raw) return null;
1622
- const probe = document.createElement("div");
1623
- probe.style.color = raw;
1624
- document.body.appendChild(probe);
1625
- const computed = getComputedStyle(probe).color;
1626
- document.body.removeChild(probe);
1627
- return computed || null;
1628
- } catch {
1629
- return null;
1630
- }
1631
- }
1632
- function useSlotColor(rootRef, explicitColor, slotVar, fallback) {
1633
- const [resolved, setResolved] = useState(explicitColor || fallback);
1634
- useEffect(() => {
1635
- if (explicitColor) {
1636
- setResolved(explicitColor);
1637
- return;
1638
- }
1639
- const update = () => {
1640
- const el = rootRef.current;
1641
- if (!el) return;
1642
- const computed = resolveColor(el, slotVar);
1643
- setResolved(computed || fallback);
1644
- };
1645
- update();
1646
- const raf = requestAnimationFrame(update);
1647
- const observer = new MutationObserver(update);
1648
- observer.observe(document.documentElement, {
1649
- attributes: true,
1650
- attributeFilter: ["class", "data-theme", "data-mode"]
1651
- });
1652
- return () => {
1653
- cancelAnimationFrame(raf);
1654
- observer.disconnect();
1655
- };
1656
- }, [explicitColor, slotVar, fallback, rootRef]);
1657
- return resolved;
1658
- }
1659
- function isFinderModule(row, col, size) {
1660
- if (row < 7 && col < 7) return true;
1661
- if (row < 7 && col >= size - 7) return true;
1662
- if (row >= size - 7 && col < 7) return true;
1663
- return false;
1664
- }
1665
- function drawCanvasQR(canvas, matrix, pixelSize, color, bgColor, moduleStyle, finderStyle, iconArea) {
1666
- const ctx = canvas.getContext("2d");
1667
- if (!ctx) return;
1668
- const ratio = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
1669
- canvas.width = pixelSize * ratio;
1670
- canvas.height = pixelSize * ratio;
1671
- canvas.style.width = `${pixelSize}px`;
1672
- canvas.style.height = `${pixelSize}px`;
1673
- ctx.scale(ratio, ratio);
1674
- const moduleCount = matrix.size;
1675
- const cellSize = pixelSize / moduleCount;
1676
- ctx.fillStyle = bgColor;
1677
- ctx.fillRect(0, 0, pixelSize, pixelSize);
1678
- ctx.fillStyle = color;
1679
- for (let row = 0; row < moduleCount; row++) {
1680
- for (let col = 0; col < moduleCount; col++) {
1681
- if (!matrix.get(row, col)) continue;
1682
- const x = col * cellSize;
1683
- const y = row * cellSize;
1684
- if (iconArea && x + cellSize > iconArea.x && x < iconArea.x + iconArea.w && y + cellSize > iconArea.y && y < iconArea.y + iconArea.h) {
1685
- continue;
1686
- }
1687
- const isFinder = isFinderModule(row, col, moduleCount);
1688
- if (isFinder) {
1689
- drawFinderModule(ctx, x, y, cellSize, finderStyle);
1690
- } else {
1691
- drawDataModule(ctx, x, y, cellSize, moduleStyle);
1692
- }
1693
- }
1694
- }
1695
- }
1696
- function drawDataModule(ctx, x, y, size, style) {
1697
- const gap = size * 0.1;
1698
- switch (style) {
1699
- case "dots": {
1700
- const radius = (size - gap * 2) / 2;
1701
- ctx.beginPath();
1702
- ctx.arc(x + size / 2, y + size / 2, radius, 0, Math.PI * 2);
1703
- ctx.fill();
1704
- break;
1705
- }
1706
- case "rounded": {
1707
- const r = size * 0.3;
1708
- const s = size - gap;
1709
- const ox = x + gap / 2;
1710
- const oy = y + gap / 2;
1711
- ctx.beginPath();
1712
- ctx.moveTo(ox + r, oy);
1713
- ctx.arcTo(ox + s, oy, ox + s, oy + s, r);
1714
- ctx.arcTo(ox + s, oy + s, ox, oy + s, r);
1715
- ctx.arcTo(ox, oy + s, ox, oy, r);
1716
- ctx.arcTo(ox, oy, ox + s, oy, r);
1717
- ctx.closePath();
1718
- ctx.fill();
1719
- break;
1720
- }
1721
- case "squares":
1722
- default: {
1723
- ctx.fillRect(x + gap / 2, y + gap / 2, size - gap, size - gap);
1724
- break;
1725
- }
1726
- }
1727
- }
1728
- function drawFinderModule(ctx, x, y, size, style) {
1729
- switch (style) {
1730
- case "dot": {
1731
- const r = size / 2;
1732
- ctx.beginPath();
1733
- ctx.arc(x + r, y + r, r * 0.9, 0, Math.PI * 2);
1734
- ctx.fill();
1735
- break;
1736
- }
1737
- case "rounded": {
1738
- const radius = size * 0.3;
1739
- ctx.beginPath();
1740
- ctx.moveTo(x + radius, y);
1741
- ctx.arcTo(x + size, y, x + size, y + size, radius);
1742
- ctx.arcTo(x + size, y + size, x, y + size, radius);
1743
- ctx.arcTo(x, y + size, x, y, radius);
1744
- ctx.arcTo(x, y, x + size, y, radius);
1745
- ctx.closePath();
1746
- ctx.fill();
1747
- break;
1748
- }
1749
- case "square":
1750
- default:
1751
- ctx.fillRect(x, y, size, size);
1752
- break;
1753
- }
1754
- }
1755
- function buildSVGPaths(matrix, cellSize, moduleStyle, finderStyle, iconArea) {
1756
- const paths = [];
1757
- const moduleCount = matrix.size;
1758
- for (let row = 0; row < moduleCount; row++) {
1759
- for (let col = 0; col < moduleCount; col++) {
1760
- if (!matrix.get(row, col)) continue;
1761
- const x = col * cellSize;
1762
- const y = row * cellSize;
1763
- if (iconArea && x + cellSize > iconArea.x && x < iconArea.x + iconArea.w && y + cellSize > iconArea.y && y < iconArea.y + iconArea.h) {
1764
- continue;
1765
- }
1766
- const isFinder = isFinderModule(row, col, moduleCount);
1767
- const style = isFinder ? finderStyle : moduleStyle;
1768
- const gap = cellSize * 0.1;
1769
- if (style === "dots" || style === "dot") {
1770
- const r = (cellSize - (isFinder ? 0 : gap * 2)) / 2;
1771
- const cx = x + cellSize / 2;
1772
- const cy = y + cellSize / 2;
1773
- paths.push(`M${cx - r},${cy}a${r},${r} 0 1,0 ${r * 2},0a${r},${r} 0 1,0 ${-r * 2},0`);
1774
- } else if (style === "rounded") {
1775
- const r = cellSize * 0.3;
1776
- const s = cellSize - (isFinder ? 0 : gap);
1777
- const ox = x + (isFinder ? 0 : gap / 2);
1778
- const oy = y + (isFinder ? 0 : gap / 2);
1779
- paths.push(
1780
- `M${ox + r},${oy}H${ox + s - r}Q${ox + s},${oy} ${ox + s},${oy + r}V${oy + s - r}Q${ox + s},${oy + s} ${ox + s - r},${oy + s}H${ox + r}Q${ox},${oy + s} ${ox},${oy + s - r}V${oy + r}Q${ox},${oy} ${ox + r},${oy}Z`
1781
- );
1782
- } else {
1783
- const g = isFinder ? 0 : gap / 2;
1784
- paths.push(`M${x + g},${y + g}h${cellSize - g * 2}v${cellSize - g * 2}h${-(cellSize - g * 2)}Z`);
1785
- }
1786
- }
1787
- }
1788
- return paths.join("");
1789
- }
1790
- var QRCode = React4.memo(
1791
- ({
1792
- value,
1793
- size = 128,
1794
- color = "default",
1795
- fgColor,
1796
- bgColor: bgColorProp,
1797
- errorLevel = "M",
1798
- type = "canvas",
1799
- moduleStyle = "squares",
1800
- finderStyle = "square",
1801
- icon,
1802
- iconSize = 40,
1803
- iconBorderRadius = 4,
1804
- bordered = true,
1805
- status = "active",
1806
- onRefresh,
1807
- refreshText = "Refresh",
1808
- expiredText = "QR code expired",
1809
- className,
1810
- classNames
1811
- }) => {
1812
- const canvasRef = useRef(null);
1813
- const rootRef = useRef(null);
1814
- const [libLoaded, setLibLoaded] = useState(!!_createFn);
1815
- const resolvedFg = useSlotColor(rootRef, fgColor, "--_c", "#000000");
1816
- const resolvedBg = useSlotColor(rootRef, bgColorProp, "--color-background", "#ffffff");
1817
- useEffect(() => {
1818
- if (_createFn) {
1819
- setLibLoaded(true);
1820
- return;
1821
- }
1822
- loadQRLib().then((ok) => setLibLoaded(ok));
1823
- }, []);
1824
- const matrix = useMemo(() => {
1825
- if (!value || !libLoaded) return null;
1826
- return createQRMatrixSync(value, errorLevel);
1827
- }, [value, errorLevel, libLoaded]);
1828
- const iconArea = useMemo(() => {
1829
- if (!icon || !matrix) return void 0;
1830
- const moduleCount = matrix.size;
1831
- const cellSize = size / moduleCount;
1832
- const centerX = (size - iconSize) / 2;
1833
- const centerY = (size - iconSize) / 2;
1834
- const pad = cellSize * 2;
1835
- return { x: centerX - pad, y: centerY - pad, w: iconSize + pad * 2, h: iconSize + pad * 2 };
1836
- }, [icon, matrix, size, iconSize]);
1837
- const renderCanvas = useCallback(() => {
1838
- if (!canvasRef.current || !matrix || typeof window === "undefined") return;
1839
- drawCanvasQR(canvasRef.current, matrix, size, resolvedFg, resolvedBg, moduleStyle, finderStyle, iconArea);
1840
- }, [matrix, size, resolvedFg, resolvedBg, moduleStyle, finderStyle, iconArea]);
1841
- useEffect(() => {
1842
- if (type === "canvas") renderCanvas();
1843
- }, [type, renderCanvas]);
1844
- const svgContent = useMemo(() => {
1845
- if (type !== "svg" || !matrix) return null;
1846
- const cellSize = size / matrix.size;
1847
- const d = buildSVGPaths(matrix, cellSize, moduleStyle, finderStyle, iconArea);
1848
- return d;
1849
- }, [type, matrix, size, moduleStyle, finderStyle, iconArea]);
1850
- return /* @__PURE__ */ jsxs(
1851
- "div",
1852
- {
1853
- ref: rootRef,
1854
- "data-slot": "root",
1855
- className: cn(
1856
- "qrCode_root",
1857
- "relative inline-flex flex-col items-center",
1858
- colorVars[color],
1859
- bordered && "p-3 rounded-lg border border-slot bg-background",
1860
- classNames?.root,
1861
- className
1862
- ),
1863
- children: [
1864
- type === "canvas" ? /* @__PURE__ */ jsx(
1865
- "canvas",
1866
- {
1867
- ref: canvasRef,
1868
- "data-slot": "canvas",
1869
- className: cn("qrCode_canvas", classNames?.canvas),
1870
- style: { width: size, height: size }
1871
- }
1872
- ) : /* @__PURE__ */ jsxs(
1873
- "svg",
1874
- {
1875
- "data-slot": "svg",
1876
- width: size,
1877
- height: size,
1878
- viewBox: `0 0 ${size} ${size}`,
1879
- className: cn("qrCode_svg", classNames?.svg),
1880
- children: [
1881
- /* @__PURE__ */ jsx("rect", { width: size, height: size, fill: resolvedBg }),
1882
- svgContent && /* @__PURE__ */ jsx("path", { d: svgContent, fill: resolvedFg })
1883
- ]
1884
- }
1885
- ),
1886
- icon && status === "active" && /* @__PURE__ */ jsx(
1887
- "div",
1888
- {
1889
- "data-slot": "icon",
1890
- className: cn("qrCode_icon", "absolute", classNames?.icon),
1891
- style: {
1892
- width: iconSize,
1893
- height: iconSize,
1894
- top: `calc(50% - ${iconSize / 2}px)`,
1895
- left: `calc(50% - ${iconSize / 2}px)`,
1896
- backgroundColor: resolvedBg,
1897
- borderRadius: iconBorderRadius,
1898
- padding: 3,
1899
- display: "flex",
1900
- alignItems: "center",
1901
- justifyContent: "center"
1902
- },
1903
- children: /* @__PURE__ */ jsx(
1904
- "img",
1905
- {
1906
- src: icon,
1907
- alt: "",
1908
- style: {
1909
- width: "100%",
1910
- height: "100%",
1911
- objectFit: "contain",
1912
- borderRadius: Math.max(0, iconBorderRadius - 2)
1913
- }
1914
- }
1915
- )
1916
- }
1917
- ),
1918
- status === "loading" && /* @__PURE__ */ jsx(
1919
- "div",
1920
- {
1921
- "data-slot": "overlay",
1922
- className: cn(
1923
- "qrCode_overlay",
1924
- "absolute inset-0 flex items-center justify-center bg-background/80 rounded-lg",
1925
- bordered && "m-3",
1926
- classNames?.overlay
1927
- ),
1928
- children: /* @__PURE__ */ jsx("div", { className: "w-6 h-6 border-2 border-slot border-t-transparent rounded-full animate-spin" })
1929
- }
1930
- ),
1931
- status === "expired" && /* @__PURE__ */ jsxs(
1932
- "div",
1933
- {
1934
- "data-slot": "overlay",
1935
- className: cn(
1936
- "qrCode_overlay",
1937
- "absolute inset-0 flex flex-col items-center justify-center bg-background/90 rounded-lg gap-2",
1938
- bordered && "m-3",
1939
- classNames?.overlay
1940
- ),
1941
- children: [
1942
- /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary", children: expiredText }),
1943
- onRefresh && /* @__PURE__ */ jsx(
1944
- "button",
1945
- {
1946
- type: "button",
1947
- onClick: onRefresh,
1948
- className: "text-sm text-slot hover:opacity-80 font-medium cursor-pointer",
1949
- children: refreshText
1950
- }
1951
- )
1952
- ]
1953
- }
1954
- )
1955
- ]
1956
- }
1957
- );
1958
- }
1959
- );
1960
- QRCode.displayName = "QRCode";
1961
- var qr_code_default = QRCode;
1962
- function ResizablePanelGroup({
1963
- className,
1964
- ...props
1965
- }) {
1966
- return /* @__PURE__ */ jsx(
1967
- Group,
1968
- {
1969
- "data-slot": "resizable-group",
1970
- className: cn(
1971
- "resizable_group",
1972
- "flex h-full w-full",
1973
- className
1974
- ),
1975
- ...props
1976
- }
1977
- );
1978
- }
1979
- function ResizablePanel({ className, ...props }) {
1980
- return /* @__PURE__ */ jsx(
1981
- Panel,
1982
- {
1983
- "data-slot": "resizable-panel",
1984
- className: cn("resizable_panel", className),
1985
- ...props
1986
- }
1987
- );
1988
- }
1989
- function ResizableHandle({
1990
- withHandle = false,
1991
- className,
1992
- ...props
1993
- }) {
1994
- const elRef = React4.useRef(null);
1995
- const [isVertical, setIsVertical] = React4.useState(false);
1996
- React4.useEffect(() => {
1997
- const el = elRef.current;
1998
- if (!el) return;
1999
- const parent = el.parentElement;
2000
- if (!parent) return;
2001
- const dir = getComputedStyle(parent).flexDirection;
2002
- setIsVertical(dir === "column");
2003
- }, []);
2004
- return /* @__PURE__ */ jsx(
2005
- Separator,
2006
- {
2007
- elementRef: elRef,
2008
- "data-slot": "resizable-handle",
2009
- className: cn(
2010
- "resizable_handle",
2011
- "group relative flex items-center justify-center",
2012
- "bg-border",
2013
- "focus-visible:outline-none",
2014
- isVertical ? "h-px" : "w-px",
2015
- className
2016
- ),
2017
- ...props,
2018
- children: withHandle && /* @__PURE__ */ jsx("div", { className: cn(
2019
- "z-10 flex items-center justify-center rounded-sm border border-border bg-background",
2020
- "opacity-0 transition-opacity group-hover:opacity-100",
2021
- isVertical ? "w-4 h-3" : "h-4 w-3"
2022
- ), children: /* @__PURE__ */ jsx(MoreVertical, { className: cn(
2023
- "w-2.5 h-2.5 text-text-secondary",
2024
- isVertical && "rotate-90"
2025
- ) }) })
2026
- }
2027
- );
2028
- }
2029
- var statusConfig = {
2030
- success: { color: "text-success", defaultTitle: "Successfully Done" },
2031
- error: { color: "text-error", defaultTitle: "Something Went Wrong" },
2032
- info: { color: "text-info", defaultTitle: "Information" },
2033
- warning: { color: "text-warning", defaultTitle: "Warning" },
2034
- "403": { color: "text-warning", defaultTitle: "403 \u2014 Access Denied" },
2035
- "404": { color: "text-info", defaultTitle: "404 \u2014 Page Not Found" },
2036
- "500": { color: "text-error", defaultTitle: "500 \u2014 Server Error" }
2037
- };
2038
- var sizeMap2 = {
2039
- xs: { icon: "w-10 h-10", title: "text-base font-semibold", subtitle: "text-xs", padding: "py-6 px-4", maxW: "max-w-xs" },
2040
- sm: { icon: "w-12 h-12", title: "text-lg font-semibold", subtitle: "text-sm", padding: "py-8 px-4", maxW: "max-w-sm" },
2041
- md: { icon: "w-16 h-16", title: "text-xl font-semibold", subtitle: "text-sm", padding: "py-12 px-6", maxW: "max-w-md" },
2042
- lg: { icon: "w-20 h-20", title: "text-2xl font-bold", subtitle: "text-base", padding: "py-16 px-8", maxW: "max-w-lg" }
2043
- };
2044
- function StatusIcon({ status, sizeClass }) {
2045
- const className = cn(sizeClass, statusConfig[status].color);
2046
- if (status === "success") {
2047
- return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2048
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
2049
- /* @__PURE__ */ jsx("path", { d: "M9 12l2 2 4-4" })
2050
- ] });
2051
- }
2052
- if (status === "error" || status === "500") {
2053
- return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2054
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
2055
- /* @__PURE__ */ jsx("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
2056
- /* @__PURE__ */ jsx("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
2057
- ] });
2058
- }
2059
- if (status === "warning" || status === "403") {
2060
- return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2061
- /* @__PURE__ */ jsx("path", { d: "M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" }),
2062
- /* @__PURE__ */ jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
2063
- /* @__PURE__ */ jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
2064
- ] });
2065
- }
2066
- if (status === "404") {
2067
- return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2068
- /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
2069
- /* @__PURE__ */ jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" }),
2070
- /* @__PURE__ */ jsx("line", { x1: "8", y1: "11", x2: "14", y2: "11" })
2071
- ] });
2072
- }
2073
- return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2074
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
2075
- /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
2076
- /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
2077
- ] });
2078
- }
2079
- var Result = React4.memo(
2080
- ({
2081
- status = "info",
2082
- icon,
2083
- title,
2084
- subtitle,
2085
- extra,
2086
- children,
2087
- size = "md",
2088
- className,
2089
- classNames
2090
- }) => {
2091
- const config = statusConfig[status];
2092
- const s = sizeMap2[size];
2093
- return /* @__PURE__ */ jsxs(
2094
- "div",
2095
- {
2096
- "data-slot": "root",
2097
- className: cn(
2098
- "result_root",
2099
- "flex flex-col items-center text-center",
2100
- s.padding,
2101
- classNames?.root,
2102
- className
2103
- ),
2104
- children: [
2105
- /* @__PURE__ */ jsx("div", { "data-slot": "icon", className: cn("result_icon", "mb-6", classNames?.icon), children: icon ?? /* @__PURE__ */ jsx(StatusIcon, { status, sizeClass: s.icon }) }),
2106
- /* @__PURE__ */ jsx("h3", { "data-slot": "title", className: cn("result_title", s.title, "text-text-primary mb-2", classNames?.title), children: title ?? config.defaultTitle }),
2107
- subtitle && /* @__PURE__ */ jsx("p", { "data-slot": "subtitle", className: cn("result_subtitle", s.subtitle, "text-text-secondary", s.maxW, "mb-6", classNames?.subtitle), children: subtitle }),
2108
- extra && /* @__PURE__ */ jsx("div", { "data-slot": "extra", className: cn("result_extra", "flex items-center gap-3 mb-6", classNames?.extra), children: extra }),
2109
- children && /* @__PURE__ */ jsx("div", { "data-slot": "content", className: cn("result_content", "w-full", s.maxW, classNames?.content), children })
2110
- ]
2111
- }
2112
- );
2113
- }
2114
- );
2115
- Result.displayName = "Result";
2116
- var result_default = Result;
2117
- var wrapperVariants = cva(
2118
- "flex flex-wrap items-center gap-1 rounded-md border bg-background text-text-primary transition-colors cursor-text",
2119
- {
2120
- variants: {
2121
- size: {
2122
- xs: "min-h-(--input-height-xs) px-(--input-padding-x-xs) py-0.5 text-xs",
2123
- sm: "min-h-(--input-height-sm) px-(--input-padding-x-sm) py-1 text-sm",
2124
- md: "min-h-(--input-height-md) px-(--input-padding-x-md) py-1 text-sm",
2125
- lg: "min-h-(--input-height-lg) px-(--input-padding-x-lg) py-1.5 text-base"
2126
- },
2127
- status: {
2128
- default: "border-border focus-within:border-primary",
2129
- error: "border-error focus-within:border-error"
2130
- }
2131
- },
2132
- defaultVariants: { size: "md", status: "default" }
2133
- }
2134
- );
2135
- var tagVariants = cva(
2136
- "inline-flex items-center gap-0.5 rounded-md font-medium transition-colors bg-slot-10 text-slot",
2137
- {
2138
- variants: {
2139
- size: {
2140
- xs: "h-4 px-1 text-[10px]",
2141
- sm: "h-5 px-1.5 text-xs",
2142
- md: "h-6 px-2 text-xs",
2143
- lg: "h-7 px-2.5 text-sm"
2144
- }
2145
- },
2146
- defaultVariants: { size: "md" }
2147
- }
2148
- );
2149
- var TagsInput = React4.memo(
2150
- ({
2151
- value,
2152
- defaultValue = [],
2153
- onChange,
2154
- suggestions,
2155
- placeholder = "Add tag...",
2156
- maxTags,
2157
- allowDuplicates = false,
2158
- separator = ",",
2159
- addOnBlur = true,
2160
- addOnPaste = true,
2161
- validate,
2162
- onTagAdd,
2163
- onTagRemove,
2164
- size = "md",
2165
- color = "primary",
2166
- disabled = false,
2167
- readOnly = false,
2168
- label,
2169
- error,
2170
- helperText,
2171
- clearable = false,
2172
- fullWidth = true,
2173
- className,
2174
- classNames
2175
- }) => {
2176
- const [internalValue, setInternalValue] = useState(defaultValue);
2177
- const tags = value !== void 0 ? value : internalValue;
2178
- const [inputValue, setInputValue] = useState("");
2179
- const [showSuggestions, setShowSuggestions] = useState(false);
2180
- const [highlightedIdx, setHighlightedIdx] = useState(-1);
2181
- const inputRef = useRef(null);
2182
- const separators = useMemo(
2183
- () => Array.isArray(separator) ? separator : [separator],
2184
- [separator]
2185
- );
2186
- const update = useCallback(
2187
- (next) => {
2188
- if (value === void 0) setInternalValue(next);
2189
- onChange?.(next);
2190
- },
2191
- [value, onChange]
2192
- );
2193
- const addTag = useCallback(
2194
- (raw) => {
2195
- const tag = raw.trim();
2196
- if (!tag) return false;
2197
- if (maxTags && tags.length >= maxTags) return false;
2198
- if (!allowDuplicates && tags.includes(tag)) return false;
2199
- if (validate && !validate(tag)) return false;
2200
- update([...tags, tag]);
2201
- onTagAdd?.(tag);
2202
- return true;
2203
- },
2204
- [tags, maxTags, allowDuplicates, validate, update, onTagAdd]
2205
- );
2206
- const removeTag = useCallback(
2207
- (idx) => {
2208
- const tag = tags[idx];
2209
- const next = tags.filter((_, i) => i !== idx);
2210
- update(next);
2211
- if (tag) onTagRemove?.(tag);
2212
- },
2213
- [tags, update, onTagRemove]
2214
- );
2215
- const handleKeyDown = (e) => {
2216
- if (e.key === "Enter" || separators.includes(e.key)) {
2217
- e.preventDefault();
2218
- if (showSuggestions && highlightedIdx >= 0 && filteredSuggestions[highlightedIdx]) {
2219
- addTag(filteredSuggestions[highlightedIdx]);
2220
- setInputValue("");
2221
- setShowSuggestions(false);
2222
- setHighlightedIdx(-1);
2223
- } else if (addTag(inputValue)) {
2224
- setInputValue("");
2225
- setShowSuggestions(false);
2226
- }
2227
- } else if (e.key === "Backspace" && !inputValue && tags.length > 0) {
2228
- removeTag(tags.length - 1);
2229
- } else if (e.key === "Escape") {
2230
- setShowSuggestions(false);
2231
- } else if (e.key === "ArrowDown" && showSuggestions) {
2232
- e.preventDefault();
2233
- setHighlightedIdx((p) => Math.min(p + 1, filteredSuggestions.length - 1));
2234
- } else if (e.key === "ArrowUp" && showSuggestions) {
2235
- e.preventDefault();
2236
- setHighlightedIdx((p) => Math.max(p - 1, 0));
2237
- }
2238
- };
2239
- const handlePaste = (e) => {
2240
- if (!addOnPaste) return;
2241
- e.preventDefault();
2242
- const text = e.clipboardData.getData("text");
2243
- const parts = text.split(new RegExp(`[${separators.map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("")}]`));
2244
- let added = false;
2245
- for (const part of parts) {
2246
- if (addTag(part)) added = true;
2247
- }
2248
- if (added) setInputValue("");
2249
- };
2250
- const handleBlur = () => {
2251
- setShowSuggestions(false);
2252
- if (addOnBlur && inputValue.trim()) {
2253
- if (addTag(inputValue)) setInputValue("");
2254
- }
2255
- };
2256
- const filteredSuggestions = useMemo(() => {
2257
- if (!suggestions || !inputValue.trim()) return [];
2258
- const q = inputValue.toLowerCase();
2259
- return suggestions.filter(
2260
- (s) => s.toLowerCase().includes(q) && (allowDuplicates || !tags.includes(s))
2261
- );
2262
- }, [suggestions, inputValue, tags, allowDuplicates]);
2263
- const handleInputChange = (e) => {
2264
- setInputValue(e.target.value);
2265
- setShowSuggestions(!!e.target.value.trim() && !!suggestions?.length);
2266
- setHighlightedIdx(-1);
2267
- };
2268
- const atMax = !!maxTags && tags.length >= maxTags;
2269
- return /* @__PURE__ */ jsxs(
2270
- "div",
2271
- {
2272
- "data-slot": "root",
2273
- className: cn(
2274
- "tagsInput_root",
2275
- "flex flex-col gap-1.5",
2276
- fullWidth ? "w-full" : "inline-flex",
2277
- colorVars[color],
2278
- classNames?.root,
2279
- className
2280
- ),
2281
- children: [
2282
- label && /* @__PURE__ */ jsx("label", { "data-slot": "label", className: "text-sm font-medium text-text-primary", children: label }),
2283
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
2284
- /* @__PURE__ */ jsxs(
2285
- "div",
2286
- {
2287
- "data-slot": "wrapper",
2288
- className: cn(
2289
- "tagsInput_wrapper",
2290
- wrapperVariants({ size, status: error ? "error" : "default" }),
2291
- disabled && "opacity-50 cursor-not-allowed",
2292
- classNames?.wrapper
2293
- ),
2294
- onClick: () => !disabled && !readOnly && inputRef.current?.focus(),
2295
- children: [
2296
- tags.map((tag, idx) => /* @__PURE__ */ jsxs(
2297
- "span",
2298
- {
2299
- "data-slot": "tag",
2300
- className: cn("tagsInput_tag", tagVariants({ size }), classNames?.tag),
2301
- children: [
2302
- /* @__PURE__ */ jsx("span", { className: cn("tagsInput_tagLabel truncate max-w-[150px]", classNames?.tagLabel), children: tag }),
2303
- !readOnly && !disabled && /* @__PURE__ */ jsx(
2304
- "button",
2305
- {
2306
- type: "button",
2307
- onClick: (e) => {
2308
- e.stopPropagation();
2309
- removeTag(idx);
2310
- },
2311
- className: cn("tagsInput_tagClose shrink-0 hover:text-slot-80 cursor-pointer", classNames?.tagClose),
2312
- "aria-label": `Remove ${tag}`,
2313
- tabIndex: -1,
2314
- children: /* @__PURE__ */ jsx(X, { className: "w-3 h-3" })
2315
- }
2316
- )
2317
- ]
2318
- },
2319
- `${tag}-${idx}`
2320
- )),
2321
- !atMax && !readOnly && !disabled && /* @__PURE__ */ jsx(
2322
- "input",
2323
- {
2324
- ref: inputRef,
2325
- type: "text",
2326
- value: inputValue,
2327
- onChange: handleInputChange,
2328
- onKeyDown: handleKeyDown,
2329
- onPaste: handlePaste,
2330
- onBlur: handleBlur,
2331
- onFocus: () => inputValue.trim() && suggestions?.length && setShowSuggestions(true),
2332
- placeholder: tags.length === 0 ? placeholder : "",
2333
- disabled,
2334
- readOnly,
2335
- "data-slot": "input",
2336
- className: cn(
2337
- "tagsInput_input",
2338
- "flex-1 min-w-[60px] bg-transparent outline-none placeholder:text-text-secondary/50",
2339
- classNames?.input
2340
- )
2341
- }
2342
- ),
2343
- clearable && tags.length > 0 && !disabled && !readOnly && /* @__PURE__ */ jsx(
2344
- "button",
2345
- {
2346
- type: "button",
2347
- onClick: (e) => {
2348
- e.stopPropagation();
2349
- update([]);
2350
- },
2351
- className: "shrink-0 text-text-secondary hover:text-text-primary",
2352
- "aria-label": "Clear all tags",
2353
- tabIndex: -1,
2354
- children: /* @__PURE__ */ jsx(X, { className: "w-3.5 h-3.5" })
2355
- }
2356
- )
2357
- ]
2358
- }
2359
- ),
2360
- showSuggestions && filteredSuggestions.length > 0 && /* @__PURE__ */ jsx("div", { className: "absolute z-[var(--z-popover)] mt-1 w-full rounded-md border border-border bg-background shadow-md max-h-[200px] overflow-auto", children: filteredSuggestions.map((s, idx) => /* @__PURE__ */ jsx(
2361
- "div",
2362
- {
2363
- onMouseDown: (e) => {
2364
- e.preventDefault();
2365
- addTag(s);
2366
- setInputValue("");
2367
- setShowSuggestions(false);
2368
- },
2369
- onMouseEnter: () => setHighlightedIdx(idx),
2370
- className: cn(
2371
- "px-3 py-1.5 text-sm cursor-pointer transition-colors",
2372
- idx === highlightedIdx ? "bg-surface text-text-primary" : "text-text-primary hover:bg-surface"
2373
- ),
2374
- children: s
2375
- },
2376
- s
2377
- )) })
2378
- ] }),
2379
- (error || helperText) && /* @__PURE__ */ jsx("p", { "data-slot": "message", className: cn("text-xs", error ? statusMessageVariants({ status: "error" }) : "text-text-secondary"), children: error || helperText })
2380
- ]
2381
- }
2382
- );
2383
- }
2384
- );
2385
- TagsInput.displayName = "TagsInput";
2386
- var tags_input_default = TagsInput;
2387
- function getTargetElement(target) {
2388
- if (typeof target === "function") return target();
2389
- return document.querySelector(target);
2390
- }
2391
- function getTargetBorderRadius(el) {
2392
- if (typeof window === "undefined") return "0px";
2393
- return getComputedStyle(el).borderRadius || "0px";
2394
- }
2395
- function computePopoverPosition(rect, placement, gap) {
2396
- const base = placement.split("-")[0];
2397
- const align = placement.split("-")[1];
2398
- let top = 0;
2399
- let left = 0;
2400
- const cx = rect.left + rect.width / 2;
2401
- const cy = rect.top + rect.height / 2;
2402
- if (base === "bottom") {
2403
- top = rect.bottom + gap;
2404
- left = align === "start" ? rect.left : align === "end" ? rect.right : cx;
2405
- } else if (base === "top") {
2406
- top = rect.top - gap;
2407
- left = align === "start" ? rect.left : align === "end" ? rect.right : cx;
2408
- } else if (base === "left") {
2409
- top = align === "start" ? rect.top : align === "end" ? rect.bottom : cy;
2410
- left = rect.left - gap;
2411
- } else {
2412
- top = align === "start" ? rect.top : align === "end" ? rect.bottom : cy;
2413
- left = rect.right + gap;
2414
- }
2415
- return { top, left };
2416
- }
2417
- function getPopoverStyle(rect, placement, gap) {
2418
- const base = placement.split("-")[0];
2419
- const align = placement.split("-")[1];
2420
- const pos = computePopoverPosition(rect, placement, gap);
2421
- const style = {
2422
- position: "fixed",
2423
- top: pos.top,
2424
- left: pos.left
2425
- };
2426
- if (base === "bottom") {
2427
- if (!align) style.transform = "translateX(-50%)";
2428
- else if (align === "end") style.transform = "translateX(-100%)";
2429
- } else if (base === "top") {
2430
- if (!align) style.transform = "translate(-50%, -100%)";
2431
- else if (align === "start") style.transform = "translateY(-100%)";
2432
- else style.transform = "translate(-100%, -100%)";
2433
- } else if (base === "left") {
2434
- if (!align) style.transform = "translate(-100%, -50%)";
2435
- else if (align === "start") style.transform = "translateX(-100%)";
2436
- else style.transform = "translate(-100%, -100%)";
2437
- } else {
2438
- if (!align) style.transform = "translateY(-50%)";
2439
- else if (align === "end") style.transform = "translateY(-100%)";
2440
- }
2441
- return style;
2442
- }
2443
- var sizeMap3 = {
2444
- xs: { padding: 4, gap: 8, popover: "p-3 max-w-[260px]", title: "text-sm font-semibold", desc: "text-xs", btn: "h-6 px-2.5 text-xs" },
2445
- sm: { padding: 6, gap: 10, popover: "p-3.5 max-w-[300px]", title: "text-sm font-semibold", desc: "text-sm", btn: "h-7 px-3 text-xs" },
2446
- md: { padding: 8, gap: 12, popover: "p-4 max-w-[340px]", title: "text-base font-semibold", desc: "text-sm", btn: "h-8 px-3 text-sm" },
2447
- lg: { padding: 10, gap: 14, popover: "p-5 max-w-[400px]", title: "text-lg font-semibold", desc: "text-base", btn: "h-9 px-4 text-sm" }
2448
- };
2449
- var EASE = "cubic-bezier(0.4, 0, 0.2, 1)";
2450
- var DURATION = "350ms";
2451
- var Tour = React4.memo(
2452
- ({
2453
- steps,
2454
- open: controlledOpen,
2455
- onOpenChange,
2456
- current: controlledCurrent,
2457
- onCurrentChange,
2458
- color = "primary",
2459
- size = "md",
2460
- showProgress = true,
2461
- showSkip = true,
2462
- skipText = "Skip",
2463
- finishText = "Finish",
2464
- nextText = "Next",
2465
- prevText = "Back",
2466
- onFinish,
2467
- onSkip,
2468
- overlayClickable = false,
2469
- className,
2470
- classNames
2471
- }) => {
2472
- const [internalOpen, setInternalOpen] = useState(false);
2473
- const [internalCurrent, setInternalCurrent] = useState(0);
2474
- const isOpen = controlledOpen !== void 0 ? controlledOpen : internalOpen;
2475
- const current = controlledCurrent !== void 0 ? controlledCurrent : internalCurrent;
2476
- const [targetRect, setTargetRect] = useState(null);
2477
- const [targetRadius, setTargetRadius] = useState("0px");
2478
- const [entering, setEntering] = useState(false);
2479
- const [contentFading, setContentFading] = useState(false);
2480
- const popoverRef = useRef(null);
2481
- const setOpen = useCallback(
2482
- (v) => {
2483
- if (controlledOpen === void 0) setInternalOpen(v);
2484
- onOpenChange?.(v);
2485
- },
2486
- [controlledOpen, onOpenChange]
2487
- );
2488
- const setCurrent = useCallback(
2489
- (v) => {
2490
- setContentFading(true);
2491
- setTimeout(() => {
2492
- if (controlledCurrent === void 0) setInternalCurrent(v);
2493
- onCurrentChange?.(v);
2494
- setContentFading(false);
2495
- }, 150);
2496
- },
2497
- [controlledCurrent, onCurrentChange]
2498
- );
2499
- const step = steps[current];
2500
- const s = sizeMap3[size];
2501
- useEffect(() => {
2502
- if (isOpen) {
2503
- setEntering(true);
2504
- const t = setTimeout(() => setEntering(false), 400);
2505
- return () => clearTimeout(t);
2506
- }
2507
- }, [isOpen]);
2508
- useEffect(() => {
2509
- if (!isOpen || !step) {
2510
- setTargetRect(null);
2511
- return;
2512
- }
2513
- const el = getTargetElement(step.target);
2514
- if (!el) {
2515
- setTargetRect(null);
2516
- return;
2517
- }
2518
- const updateRect = () => {
2519
- setTargetRect(el.getBoundingClientRect());
2520
- setTargetRadius(getTargetBorderRadius(el));
2521
- };
2522
- updateRect();
2523
- el.scrollIntoView({ behavior: "smooth", block: "center" });
2524
- const ro = new ResizeObserver(updateRect);
2525
- ro.observe(el);
2526
- window.addEventListener("scroll", updateRect, { passive: true });
2527
- window.addEventListener("resize", updateRect, { passive: true });
2528
- return () => {
2529
- ro.disconnect();
2530
- window.removeEventListener("scroll", updateRect);
2531
- window.removeEventListener("resize", updateRect);
2532
- };
2533
- }, [isOpen, current, step]);
2534
- const handleNext = () => {
2535
- step?.onNext?.();
2536
- if (current < steps.length - 1) setCurrent(current + 1);
2537
- else {
2538
- setOpen(false);
2539
- onFinish?.();
2540
- }
2541
- };
2542
- const handlePrev = () => {
2543
- step?.onPrev?.();
2544
- if (current > 0) setCurrent(current - 1);
2545
- };
2546
- const handleSkip = () => {
2547
- setOpen(false);
2548
- if (controlledCurrent === void 0) setInternalCurrent(0);
2549
- onSkip?.();
2550
- };
2551
- useEffect(() => {
2552
- if (!isOpen) return;
2553
- const handleEsc = (e) => {
2554
- if (e.key === "Escape") handleSkip();
2555
- };
2556
- document.addEventListener("keydown", handleEsc);
2557
- return () => document.removeEventListener("keydown", handleEsc);
2558
- }, [isOpen]);
2559
- if (!isOpen || !step) return null;
2560
- const placement = step.placement || "bottom";
2561
- const isLast = current === steps.length - 1;
2562
- const spotlightStyle = targetRect ? {
2563
- position: "fixed",
2564
- top: targetRect.top - s.padding,
2565
- left: targetRect.left - s.padding,
2566
- width: targetRect.width + s.padding * 2,
2567
- height: targetRect.height + s.padding * 2,
2568
- borderRadius: targetRadius,
2569
- boxShadow: "0 0 0 9999px rgba(0, 0, 0, 0.5)",
2570
- transition: entering ? "none" : `top ${DURATION} ${EASE}, left ${DURATION} ${EASE}, width ${DURATION} ${EASE}, height ${DURATION} ${EASE}, border-radius ${DURATION} ${EASE}`,
2571
- pointerEvents: "none",
2572
- opacity: entering ? 0 : 1,
2573
- animation: entering ? "none" : void 0
2574
- } : {
2575
- position: "fixed",
2576
- inset: 0,
2577
- background: "rgba(0,0,0,0.5)"
2578
- };
2579
- const popoverStyle = targetRect ? {
2580
- ...getPopoverStyle(targetRect, placement, s.gap),
2581
- transition: entering ? "none" : `top ${DURATION} ${EASE}, left ${DURATION} ${EASE}, bottom ${DURATION} ${EASE}, right ${DURATION} ${EASE}, opacity 150ms ease`,
2582
- opacity: contentFading ? 0 : 1
2583
- } : { position: "fixed", opacity: 0 };
2584
- return /* @__PURE__ */ jsxs(
2585
- "div",
2586
- {
2587
- "data-slot": "root",
2588
- className: cn("tour_root", colorVars[color], classNames?.root, className),
2589
- style: { opacity: entering ? 0 : 1, transition: `opacity 300ms ${EASE}` },
2590
- ref: (el) => {
2591
- if (el && entering) requestAnimationFrame(() => setEntering(false));
2592
- },
2593
- children: [
2594
- /* @__PURE__ */ jsx(
2595
- "div",
2596
- {
2597
- "data-slot": "overlay",
2598
- className: cn("tour_overlay", "z-[var(--z-overlay)]", classNames?.overlay),
2599
- onClick: overlayClickable ? handleSkip : void 0,
2600
- style: spotlightStyle
2601
- }
2602
- ),
2603
- targetRect && /* @__PURE__ */ jsx(
2604
- "div",
2605
- {
2606
- "data-slot": "highlight",
2607
- className: "fixed z-[var(--z-overlay)] pointer-events-none",
2608
- style: {
2609
- top: targetRect.top - s.padding,
2610
- left: targetRect.left - s.padding,
2611
- width: targetRect.width + s.padding * 2,
2612
- height: targetRect.height + s.padding * 2,
2613
- borderRadius: targetRadius,
2614
- boxShadow: "0 0 0 2px var(--color-slot, #3b82f6), 0 0 12px 2px color-mix(in srgb, var(--color-slot, #3b82f6) 30%, transparent)",
2615
- transition: `top ${DURATION} ${EASE}, left ${DURATION} ${EASE}, width ${DURATION} ${EASE}, height ${DURATION} ${EASE}, border-radius ${DURATION} ${EASE}`
2616
- }
2617
- }
2618
- ),
2619
- /* @__PURE__ */ jsxs(
2620
- "div",
2621
- {
2622
- ref: popoverRef,
2623
- "data-slot": "popover",
2624
- className: cn(
2625
- "tour_popover",
2626
- "z-[calc(var(--z-overlay)+1)] rounded-lg border border-border bg-background shadow-lg",
2627
- s.popover,
2628
- classNames?.popover
2629
- ),
2630
- style: popoverStyle,
2631
- children: [
2632
- step.cover && /* @__PURE__ */ jsx("div", { "data-slot": "cover", className: cn("tour_cover", "mb-3 rounded-md overflow-hidden", classNames?.cover), children: step.cover }),
2633
- /* @__PURE__ */ jsx("div", { "data-slot": "title", className: cn("tour_title", s.title, "text-text-primary", classNames?.title), children: step.title }),
2634
- step.description && /* @__PURE__ */ jsx("div", { "data-slot": "description", className: cn("tour_description", s.desc, "text-text-secondary mt-1", classNames?.description), children: step.description }),
2635
- /* @__PURE__ */ jsxs("div", { "data-slot": "footer", className: cn("tour_footer", "flex items-center justify-between mt-3 gap-2", classNames?.footer), children: [
2636
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: showProgress && /* @__PURE__ */ jsxs("span", { "data-slot": "indicator", className: cn("tour_indicator", "text-xs text-text-secondary", classNames?.indicator), children: [
2637
- current + 1,
2638
- " / ",
2639
- steps.length
2640
- ] }) }),
2641
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2642
- showSkip && !isLast && /* @__PURE__ */ jsx(
2643
- "button",
2644
- {
2645
- type: "button",
2646
- onClick: handleSkip,
2647
- className: cn("inline-flex items-center justify-center rounded-md text-text-secondary hover:text-text-primary transition-colors font-medium cursor-pointer", s.btn),
2648
- children: skipText
2649
- }
2650
- ),
2651
- current > 0 && /* @__PURE__ */ jsx(
2652
- "button",
2653
- {
2654
- type: "button",
2655
- onClick: handlePrev,
2656
- className: cn("inline-flex items-center justify-center rounded-md border border-border bg-background text-text-primary hover:bg-surface transition-colors font-medium cursor-pointer", s.btn),
2657
- children: step.prevText || prevText
2658
- }
2659
- ),
2660
- /* @__PURE__ */ jsx(
2661
- "button",
2662
- {
2663
- type: "button",
2664
- onClick: handleNext,
2665
- className: cn("inline-flex items-center justify-center rounded-md bg-slot text-slot-fg hover:bg-slot-90 transition-colors font-medium cursor-pointer", s.btn),
2666
- children: isLast ? finishText : step.nextText || nextText
2667
- }
2668
- )
2669
- ] })
2670
- ] })
2671
- ]
2672
- }
2673
- )
2674
- ]
2675
- }
2676
- );
2677
- }
2678
- );
2679
- Tour.displayName = "Tour";
2680
- var tour_default = Tour;
2681
- var levelElements = {
2682
- h1: "h1",
2683
- h2: "h2",
2684
- h3: "h3",
2685
- h4: "h4",
2686
- h5: "h5",
2687
- h6: "h6"
2688
- };
2689
- var levelClasses = {
2690
- h1: "text-4xl font-bold tracking-tight",
2691
- h2: "text-3xl font-semibold tracking-tight",
2692
- h3: "text-2xl font-semibold",
2693
- h4: "text-xl font-semibold",
2694
- h5: "text-lg font-medium",
2695
- h6: "text-base font-medium"
2696
- };
2697
- var sizeClasses2 = {
2698
- xs: "text-xs",
2699
- sm: "text-sm",
2700
- md: "text-base",
2701
- lg: "text-lg",
2702
- xl: "text-xl",
2703
- "2xl": "text-2xl"
2704
- };
2705
- var weightClasses = {
2706
- light: "font-light",
2707
- normal: "font-normal",
2708
- medium: "font-medium",
2709
- semibold: "font-semibold",
2710
- bold: "font-bold"
2711
- };
2712
- var textColorClasses = {
2713
- default: "text-text-primary",
2714
- primary: "text-primary",
2715
- secondary: "text-text-secondary",
2716
- tertiary: "text-text-secondary/60",
2717
- accent: "text-accent",
2718
- success: "text-success",
2719
- error: "text-error",
2720
- warning: "text-warning",
2721
- info: "text-info",
2722
- inherit: ""
2723
- };
2724
- function CopyButton({ text }) {
2725
- const [copied, setCopied] = useState(false);
2726
- const handleCopy = useCallback(async () => {
2727
- try {
2728
- await navigator.clipboard.writeText(text);
2729
- setCopied(true);
2730
- setTimeout(() => setCopied(false), 2e3);
2731
- } catch {
2732
- }
2733
- }, [text]);
2734
- return /* @__PURE__ */ jsx(
2735
- "button",
2736
- {
2737
- type: "button",
2738
- onClick: handleCopy,
2739
- className: "inline-flex items-center ml-1 text-text-secondary hover:text-text-primary transition-colors cursor-pointer",
2740
- "aria-label": "Copy to clipboard",
2741
- children: copied ? /* @__PURE__ */ jsx("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) }) : /* @__PURE__ */ jsxs("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2742
- /* @__PURE__ */ jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
2743
- /* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" })
2744
- ] })
2745
- }
2746
- );
2747
- }
2748
- function useTruncation(truncate, ref) {
2749
- const [expanded, setExpanded] = useState(false);
2750
- const [isTruncated, setIsTruncated] = useState(false);
2751
- useEffect(() => {
2752
- if (!truncate || expanded || !ref.current) return;
2753
- const el = ref.current;
2754
- setIsTruncated(el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth);
2755
- }, [truncate, expanded, ref]);
2756
- return { expanded, setExpanded, isTruncated };
2757
- }
2758
- var Title = React4.memo(
2759
- ({ level = "h1", color = "default", copyable = false, className, children, ...props }) => {
2760
- const Tag = levelElements[level];
2761
- const textContent = typeof children === "string" ? children : "";
2762
- return React4.createElement(
2763
- Tag,
2764
- {
2765
- "data-slot": "title",
2766
- className: cn("typography_title", levelClasses[level], textColorClasses[color] || "", className),
2767
- ...props
2768
- },
2769
- /* @__PURE__ */ jsxs(Fragment, { children: [
2770
- children,
2771
- copyable && textContent && /* @__PURE__ */ jsx(CopyButton, { text: textContent })
2772
- ] })
2773
- );
2774
- }
2775
- );
2776
- Title.displayName = "Title";
2777
- var Text = React4.memo(
2778
- ({
2779
- size = "md",
2780
- weight,
2781
- color = "default",
2782
- truncate,
2783
- copyable = false,
2784
- code = false,
2785
- mark = false,
2786
- del: deleted = false,
2787
- underline = false,
2788
- strong = false,
2789
- italic = false,
2790
- as: Component = "span",
2791
- className,
2792
- children,
2793
- ...props
2794
- }) => {
2795
- const ref = useRef(null);
2796
- const { expanded, setExpanded, isTruncated } = useTruncation(truncate, ref);
2797
- const textContent = typeof children === "string" ? children : "";
2798
- const truncateClass = !expanded && truncate ? typeof truncate === "number" ? `line-clamp-${truncate}` : "truncate" : "";
2799
- let content = children;
2800
- if (code) content = /* @__PURE__ */ jsx("code", { className: "px-1 py-0.5 rounded bg-surface text-sm font-mono", children: content });
2801
- if (mark) content = /* @__PURE__ */ jsx("mark", { className: "bg-warning/20 px-0.5 rounded-sm", children: content });
2802
- if (deleted) content = /* @__PURE__ */ jsx("del", { children: content });
2803
- if (underline) content = /* @__PURE__ */ jsx("u", { children: content });
2804
- if (strong) content = /* @__PURE__ */ jsx("strong", { children: content });
2805
- if (italic) content = /* @__PURE__ */ jsx("em", { children: content });
2806
- return React4.createElement(
2807
- Component,
2808
- {
2809
- ref,
2810
- "data-slot": "text",
2811
- className: cn(
2812
- "typography_text",
2813
- sizeClasses2[size],
2814
- weight && weightClasses[weight],
2815
- textColorClasses[color] || "",
2816
- truncateClass,
2817
- className
2818
- ),
2819
- ...props
2820
- },
2821
- /* @__PURE__ */ jsxs(Fragment, { children: [
2822
- content,
2823
- copyable && textContent && /* @__PURE__ */ jsx(CopyButton, { text: textContent }),
2824
- isTruncated && !expanded && /* @__PURE__ */ jsx(
2825
- "button",
2826
- {
2827
- type: "button",
2828
- onClick: () => setExpanded(true),
2829
- className: "text-primary hover:text-primary/80 ml-1 text-inherit cursor-pointer",
2830
- children: "more"
2831
- }
2832
- )
2833
- ] })
2834
- );
2835
- }
2836
- );
2837
- Text.displayName = "Text";
2838
- var Paragraph = React4.memo(
2839
- ({
2840
- size = "md",
2841
- color = "default",
2842
- truncate,
2843
- copyable = false,
2844
- className,
2845
- children,
2846
- ...props
2847
- }) => {
2848
- const ref = useRef(null);
2849
- const { expanded, setExpanded, isTruncated } = useTruncation(truncate, ref);
2850
- const textContent = typeof children === "string" ? children : "";
2851
- const truncateClass = !expanded && truncate ? typeof truncate === "number" ? `line-clamp-${truncate}` : "truncate" : "";
2852
- return /* @__PURE__ */ jsxs(
2853
- "p",
2854
- {
2855
- ref,
2856
- "data-slot": "paragraph",
2857
- className: cn(
2858
- "typography_paragraph",
2859
- sizeClasses2[size],
2860
- textColorClasses[color] || "",
2861
- truncateClass,
2862
- "leading-relaxed",
2863
- className
2864
- ),
2865
- ...props,
2866
- children: [
2867
- children,
2868
- copyable && textContent && /* @__PURE__ */ jsx(CopyButton, { text: textContent }),
2869
- isTruncated && !expanded && /* @__PURE__ */ jsx(
2870
- "button",
2871
- {
2872
- type: "button",
2873
- onClick: () => setExpanded(true),
2874
- className: "text-primary hover:text-primary/80 ml-1 text-inherit cursor-pointer",
2875
- children: "more"
2876
- }
2877
- )
2878
- ]
2879
- }
2880
- );
2881
- }
2882
- );
2883
- Paragraph.displayName = "Paragraph";
2884
- function generateWatermark({
2885
- text,
2886
- image,
2887
- width = 120,
2888
- height = 64,
2889
- rotate = -22,
2890
- gap = [100, 100],
2891
- offset = [0, 0],
2892
- fontSize = 14,
2893
- fontFamily = "sans-serif",
2894
- fontWeight = "normal",
2895
- fontColor = "rgba(0,0,0,0.15)",
2896
- opacity = 1
2897
- }) {
2898
- return new Promise((resolve) => {
2899
- const canvas = document.createElement("canvas");
2900
- const ctx = canvas.getContext("2d");
2901
- const ratio = window.devicePixelRatio || 1;
2902
- const cellWidth = width + gap[0];
2903
- const cellHeight = height + gap[1];
2904
- canvas.width = cellWidth * ratio;
2905
- canvas.height = cellHeight * ratio;
2906
- ctx.scale(ratio, ratio);
2907
- ctx.globalAlpha = opacity;
2908
- ctx.translate(cellWidth / 2 + offset[0], cellHeight / 2 + offset[1]);
2909
- ctx.rotate(rotate * Math.PI / 180);
2910
- if (image) {
2911
- const img = new Image();
2912
- img.crossOrigin = "anonymous";
2913
- img.onload = () => {
2914
- ctx.drawImage(img, -width / 2, -height / 2, width, height);
2915
- resolve(canvas.toDataURL());
2916
- };
2917
- img.onerror = () => resolve("");
2918
- img.src = image;
2919
- } else if (text) {
2920
- ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
2921
- ctx.fillStyle = fontColor;
2922
- ctx.textAlign = "center";
2923
- ctx.textBaseline = "middle";
2924
- const lines = Array.isArray(text) ? text : [text];
2925
- const lineHeight = fontSize * 1.5;
2926
- const startY = -((lines.length - 1) * lineHeight) / 2;
2927
- lines.forEach((line, i) => {
2928
- ctx.fillText(line, 0, startY + i * lineHeight);
2929
- });
2930
- resolve(canvas.toDataURL());
2931
- } else {
2932
- resolve("");
2933
- }
2934
- });
2935
- }
2936
- var Watermark = React4.memo(
2937
- ({
2938
- children,
2939
- text,
2940
- image,
2941
- width = 120,
2942
- height = 64,
2943
- rotate = -22,
2944
- gap = [100, 100],
2945
- offset = [0, 0],
2946
- fontSize = 14,
2947
- fontFamily = "sans-serif",
2948
- fontWeight = "normal",
2949
- fontColor = "rgba(0,0,0,0.15)",
2950
- opacity = 1,
2951
- zIndex = 10,
2952
- className,
2953
- classNames
2954
- }) => {
2955
- const [bgImage, setBgImage] = useState("");
2956
- const containerRef = useRef(null);
2957
- const watermarkRef = useRef(null);
2958
- const observerRef = useRef(null);
2959
- const render = useCallback(async () => {
2960
- if (typeof window === "undefined") return;
2961
- const dataUrl = await generateWatermark({
2962
- text,
2963
- image,
2964
- width,
2965
- height,
2966
- rotate,
2967
- gap,
2968
- offset,
2969
- fontSize,
2970
- fontFamily,
2971
- fontWeight,
2972
- fontColor,
2973
- opacity
2974
- });
2975
- setBgImage(dataUrl);
2976
- }, [text, image, width, height, rotate, gap, offset, fontSize, fontFamily, fontWeight, fontColor, opacity]);
2977
- useEffect(() => {
2978
- render();
2979
- }, [render]);
2980
- useEffect(() => {
2981
- if (!watermarkRef.current || !containerRef.current) return;
2982
- observerRef.current = new MutationObserver((mutations) => {
2983
- for (const m of mutations) {
2984
- if (m.type === "childList") {
2985
- const removed = Array.from(m.removedNodes);
2986
- if (removed.includes(watermarkRef.current)) {
2987
- render();
2988
- return;
2989
- }
2990
- }
2991
- if (m.type === "attributes" && m.target === watermarkRef.current) {
2992
- render();
2993
- return;
2994
- }
2995
- }
2996
- });
2997
- observerRef.current.observe(containerRef.current, {
2998
- childList: true,
2999
- subtree: true,
3000
- attributes: true,
3001
- attributeFilter: ["style", "class"]
3002
- });
3003
- return () => observerRef.current?.disconnect();
3004
- }, [render]);
3005
- return /* @__PURE__ */ jsxs(
3006
- "div",
3007
- {
3008
- ref: containerRef,
3009
- "data-slot": "root",
3010
- className: cn("watermark_root", "relative", classNames?.root, className),
3011
- children: [
3012
- /* @__PURE__ */ jsx("div", { "data-slot": "content", className: cn("watermark_content", "relative", classNames?.content), children }),
3013
- bgImage && /* @__PURE__ */ jsx(
3014
- "div",
3015
- {
3016
- ref: watermarkRef,
3017
- "data-slot": "watermark",
3018
- className: cn("watermark_layer", "absolute inset-0 pointer-events-none", classNames?.watermark),
3019
- style: {
3020
- backgroundImage: `url(${bgImage})`,
3021
- backgroundRepeat: "repeat",
3022
- zIndex
3023
- }
3024
- }
3025
- )
3026
- ]
3027
- }
3028
- );
3029
- }
3030
- );
3031
- Watermark.displayName = "Watermark";
3032
- var watermark_default = Watermark;
3033
88
  function useDebounce(value, delay) {
3034
89
  const [debouncedValue, setDebouncedValue] = useState(value);
3035
90
  useEffect(() => {
@@ -3068,6 +123,6 @@ function useMediaQuery(query) {
3068
123
  return matches;
3069
124
  }
3070
125
 
3071
- export { anchor_default as Anchor, autocomplete_default as Autocomplete, BackTop, calendar_default as Calendar, ColorInput, ColorPicker, FloatButton, FloatButtonGroup, mentions_default as Mentions, Paragraph, qr_code_default as QRCode, ResizableHandle, ResizablePanel, ResizablePanelGroup, result_default as Result, tags_input_default as TagsInput, Text, Title, tour_default as Tour, watermark_default as Watermark, themePresets, useDebounce, useMediaQuery, useThrottle };
126
+ export { themePresets, useDebounce, useMediaQuery, useThrottle };
3072
127
  //# sourceMappingURL=index.js.map
3073
128
  //# sourceMappingURL=index.js.map