@justanarthur/modo-ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSE.beui +21 -0
  3. package/LICENSE.fluid-functionalism +21 -0
  4. package/LICENSE.motion-primitives +21 -0
  5. package/LICENSE.sileo +21 -0
  6. package/README.md +608 -2
  7. package/dist/base.css +994 -0
  8. package/dist/blocks/sidebar-app/index.d.ts +34 -0
  9. package/dist/blocks/sidebar-app/index.js +34 -0
  10. package/dist/components/badge/index.d.ts +59 -0
  11. package/dist/components/badge/index.js +18 -0
  12. package/dist/components/button/index.d.ts +59 -0
  13. package/dist/components/button/index.js +16 -0
  14. package/dist/components/card/index.d.ts +141 -0
  15. package/dist/components/card/index.js +44 -0
  16. package/dist/components/inputs/checkbox-group/index.d.ts +50 -0
  17. package/dist/components/inputs/checkbox-group/index.js +23 -0
  18. package/dist/components/inputs/color-picker/index.d.ts +137 -0
  19. package/dist/components/inputs/color-picker/index.js +37 -0
  20. package/dist/components/inputs/combobox/index.d.ts +161 -0
  21. package/dist/components/inputs/combobox/index.js +41 -0
  22. package/dist/components/inputs/date-time/calendar/index.d.ts +45 -0
  23. package/dist/components/inputs/date-time/calendar/index.js +20 -0
  24. package/dist/components/inputs/date-time/date-picker/index.d.ts +82 -0
  25. package/dist/components/inputs/date-time/date-picker/index.js +34 -0
  26. package/dist/components/inputs/date-time/date-range-picker/index.d.ts +64 -0
  27. package/dist/components/inputs/date-time/date-range-picker/index.js +33 -0
  28. package/dist/components/inputs/date-time/duration-picker/index.d.ts +57 -0
  29. package/dist/components/inputs/date-time/duration-picker/index.js +33 -0
  30. package/dist/components/inputs/date-time/month-picker/index.d.ts +57 -0
  31. package/dist/components/inputs/date-time/month-picker/index.js +32 -0
  32. package/dist/components/inputs/date-time/time-picker/index.d.ts +59 -0
  33. package/dist/components/inputs/date-time/time-picker/index.js +33 -0
  34. package/dist/components/inputs/input/index.d.ts +84 -0
  35. package/dist/components/inputs/input/index.js +20 -0
  36. package/dist/components/inputs/input-copy/index.d.ts +44 -0
  37. package/dist/components/inputs/input-copy/index.js +18 -0
  38. package/dist/components/inputs/input-message/index.d.ts +125 -0
  39. package/dist/components/inputs/input-message/index.js +27 -0
  40. package/dist/components/inputs/radio-group/index.d.ts +58 -0
  41. package/dist/components/inputs/radio-group/index.js +22 -0
  42. package/dist/components/inputs/search/index.d.ts +83 -0
  43. package/dist/components/inputs/search/index.js +28 -0
  44. package/dist/components/inputs/select/index.d.ts +105 -0
  45. package/dist/components/inputs/select/index.js +37 -0
  46. package/dist/components/inputs/slider/index.d.ts +108 -0
  47. package/dist/components/inputs/slider/index.js +16 -0
  48. package/dist/components/inputs/switch/index.d.ts +43 -0
  49. package/dist/components/inputs/switch/index.js +16 -0
  50. package/dist/components/navigation/accordion/index.d.ts +117 -0
  51. package/dist/components/navigation/accordion/index.js +30 -0
  52. package/dist/components/navigation/sidebar/index.d.ts +388 -0
  53. package/dist/components/navigation/sidebar/index.js +101 -0
  54. package/dist/components/navigation/tabs/index.d.ts +70 -0
  55. package/dist/components/navigation/tabs/index.js +25 -0
  56. package/dist/components/navigation/tabs-subtle/index.d.ts +73 -0
  57. package/dist/components/navigation/tabs-subtle/index.js +23 -0
  58. package/dist/components/overlays/alert-dialog/index.d.ts +67 -0
  59. package/dist/components/overlays/alert-dialog/index.js +24 -0
  60. package/dist/components/overlays/command/index.d.ts +121 -0
  61. package/dist/components/overlays/command/index.js +39 -0
  62. package/dist/components/overlays/context-menu/index.d.ts +97 -0
  63. package/dist/components/overlays/context-menu/index.js +32 -0
  64. package/dist/components/overlays/dialog/index.d.ts +130 -0
  65. package/dist/components/overlays/dialog/index.js +39 -0
  66. package/dist/components/overlays/dropdown/index.d.ts +222 -0
  67. package/dist/components/overlays/dropdown/index.js +47 -0
  68. package/dist/components/overlays/popover/index.d.ts +87 -0
  69. package/dist/components/overlays/popover/index.js +28 -0
  70. package/dist/components/overlays/preview-card/index.d.ts +75 -0
  71. package/dist/components/overlays/preview-card/index.js +21 -0
  72. package/dist/components/overlays/sheet/index.d.ts +67 -0
  73. package/dist/components/overlays/sheet/index.js +26 -0
  74. package/dist/components/overlays/toast/index.d.ts +107 -0
  75. package/dist/components/overlays/toast/index.js +23 -0
  76. package/dist/components/overlays/tooltip/index.d.ts +75 -0
  77. package/dist/components/overlays/tooltip/index.js +19 -0
  78. package/dist/components/table/index.d.ts +44 -0
  79. package/dist/components/table/index.js +28 -0
  80. package/dist/components/thinking-indicator/index.d.ts +32 -0
  81. package/dist/components/thinking-indicator/index.js +15 -0
  82. package/dist/index.d.ts +3926 -0
  83. package/dist/index.js +513 -0
  84. package/dist/preset.d.ts +104 -0
  85. package/dist/preset.js +124 -0
  86. package/dist/primitives/code/index.d.ts +23 -0
  87. package/dist/primitives/code/index.js +12 -0
  88. package/dist/primitives/craft/index.d.ts +31 -0
  89. package/dist/primitives/craft/index.js +13 -0
  90. package/dist/primitives/fluid-hover/index.d.ts +233 -0
  91. package/dist/primitives/fluid-hover/index.js +27 -0
  92. package/dist/primitives/morph/index.d.ts +127 -0
  93. package/dist/primitives/morph/index.js +21 -0
  94. package/dist/primitives/motion/index.d.ts +115 -0
  95. package/dist/primitives/motion/index.js +20 -0
  96. package/dist/primitives/scroll-area/index.d.ts +41 -0
  97. package/dist/primitives/scroll-area/index.js +13 -0
  98. package/dist/primitives/sizes/index.d.ts +128 -0
  99. package/dist/primitives/sizes/index.js +22 -0
  100. package/dist/primitives/surface/index.d.ts +69 -0
  101. package/dist/primitives/surface/index.js +18 -0
  102. package/dist/shared/components-0f0as45n.js +17 -0
  103. package/dist/shared/components-40j34hdb.js +986 -0
  104. package/dist/shared/components-4hh0gm0v.js +292 -0
  105. package/dist/shared/components-4xxddc44.js +15 -0
  106. package/dist/shared/components-4xxtggzp.js +110 -0
  107. package/dist/shared/components-54nf2x99.js +293 -0
  108. package/dist/shared/components-5pkcfprd.js +232 -0
  109. package/dist/shared/components-5vxtcp88.js +9 -0
  110. package/dist/shared/components-5zry9te1.js +152 -0
  111. package/dist/shared/components-61ckf42z.js +220 -0
  112. package/dist/shared/components-6hzwfmfd.js +58 -0
  113. package/dist/shared/components-6phwsry6.js +361 -0
  114. package/dist/shared/components-6t6nr33r.js +86 -0
  115. package/dist/shared/components-6y1th6k4.js +111 -0
  116. package/dist/shared/components-74c20v2f.js +32 -0
  117. package/dist/shared/components-7cqq1sqy.js +193 -0
  118. package/dist/shared/components-7gv95yfy.js +496 -0
  119. package/dist/shared/components-7nww01w4.js +375 -0
  120. package/dist/shared/components-7zp99w5d.js +62 -0
  121. package/dist/shared/components-8hk9ve3r.js +1200 -0
  122. package/dist/shared/components-8hzbsfbd.js +123 -0
  123. package/dist/shared/components-9p8s8n5q.js +171 -0
  124. package/dist/shared/components-aaq3yk4f.js +304 -0
  125. package/dist/shared/components-bf2d9k02.js +484 -0
  126. package/dist/shared/components-bkvb6nem.js +63 -0
  127. package/dist/shared/components-brnzrp2t.js +262 -0
  128. package/dist/shared/components-csxz9f52.js +42 -0
  129. package/dist/shared/components-de8xsm9y.js +22 -0
  130. package/dist/shared/components-dg0w8g5p.js +26 -0
  131. package/dist/shared/components-dphg9gjr.js +42 -0
  132. package/dist/shared/components-e46kf6cp.js +298 -0
  133. package/dist/shared/components-ed7cmssr.js +105 -0
  134. package/dist/shared/components-ess3ch6w.js +137 -0
  135. package/dist/shared/components-gjfrycb5.js +984 -0
  136. package/dist/shared/components-gndm6am4.js +128 -0
  137. package/dist/shared/components-hjkrv00c.js +191 -0
  138. package/dist/shared/components-hzfp4tjb.js +270 -0
  139. package/dist/shared/components-j65qt1mq.js +719 -0
  140. package/dist/shared/components-jw16snbn.js +19 -0
  141. package/dist/shared/components-jxgznftn.js +146 -0
  142. package/dist/shared/components-kf2ehztc.js +216 -0
  143. package/dist/shared/components-kpbcms10.js +9 -0
  144. package/dist/shared/components-m5br529r.js +141 -0
  145. package/dist/shared/components-nn6xezy2.js +1828 -0
  146. package/dist/shared/components-nnnd2xef.js +9 -0
  147. package/dist/shared/components-p2vmyfe1.js +345 -0
  148. package/dist/shared/components-peg09pzs.js +79 -0
  149. package/dist/shared/components-r22vtgqc.js +45 -0
  150. package/dist/shared/components-r2gke5p6.js +1759 -0
  151. package/dist/shared/components-r43mqnd6.js +160 -0
  152. package/dist/shared/components-r4jt6hgd.js +58 -0
  153. package/dist/shared/components-rc63qsy6.js +159 -0
  154. package/dist/shared/components-s3yfvfkr.js +149 -0
  155. package/dist/shared/components-s5pkbjx1.js +445 -0
  156. package/dist/shared/components-tad5h7ta.js +346 -0
  157. package/dist/shared/components-taxmgbnh.js +120 -0
  158. package/dist/shared/components-tm88ghva.js +215 -0
  159. package/dist/shared/components-v7es8aan.js +144 -0
  160. package/dist/shared/components-vb033rns.js +28 -0
  161. package/dist/shared/components-vc1k7yv2.js +30 -0
  162. package/dist/shared/components-vktws5r6.js +667 -0
  163. package/dist/shared/components-x2xyckd5.js +198 -0
  164. package/dist/shared/components-x3rz4cyn.js +61 -0
  165. package/dist/shared/components-xszag63d.js +141 -0
  166. package/dist/shared/components-y3cqdrgy.js +291 -0
  167. package/dist/shared/components-zvb11ker.js +288 -0
  168. package/dist/shared/components-zx2hr57f.js +124 -0
  169. package/dist/styles.css +1949 -0
  170. package/dist/tailwind.css +219 -0
  171. package/dist/tokens.css +345 -0
  172. package/package.json +102 -3
@@ -0,0 +1,986 @@
1
+ import {
2
+ Elevated
3
+ } from "./components-74c20v2f.js";
4
+ import {
5
+ SelectionBackgrounds,
6
+ useMergeSplitBlocks,
7
+ useSelectionRuns
8
+ } from "./components-rc63qsy6.js";
9
+ import {
10
+ SizeProvider
11
+ } from "./components-vb033rns.js";
12
+ import {
13
+ useIcon
14
+ } from "./components-m5br529r.js";
15
+ import {
16
+ isDisabledRow,
17
+ popupScrollAreaClass,
18
+ popupViewportClass
19
+ } from "./components-jw16snbn.js";
20
+ import {
21
+ ScrollArea
22
+ } from "./components-ed7cmssr.js";
23
+ import {
24
+ SURFACE_BG,
25
+ SURFACE_SHADOW,
26
+ SurfaceProvider,
27
+ useSurface
28
+ } from "./components-csxz9f52.js";
29
+ import {
30
+ MorphSurface
31
+ } from "./components-jxgznftn.js";
32
+ import {
33
+ FluidHoverHighlight
34
+ } from "./components-r22vtgqc.js";
35
+ import {
36
+ useFluidHover,
37
+ useRegisterFluidHoverItem
38
+ } from "./components-e46kf6cp.js";
39
+ import {
40
+ shapeMap
41
+ } from "./components-7zp99w5d.js";
42
+ import {
43
+ useControllableState
44
+ } from "./components-dg0w8g5p.js";
45
+ import {
46
+ inPlaceOffset,
47
+ opensInPlace,
48
+ useMorph,
49
+ useMorphOrigin
50
+ } from "./components-7nww01w4.js";
51
+ import {
52
+ spring
53
+ } from "./components-vc1k7yv2.js";
54
+ import {
55
+ useSize
56
+ } from "./components-x3rz4cyn.js";
57
+ import {
58
+ cn
59
+ } from "./components-0f0as45n.js";
60
+
61
+ // components/overlays/dropdown/index.tsx
62
+ import { Menu } from "@base-ui/react/menu";
63
+ import { AnimatePresence as AnimatePresence2, motion as motion2 } from "motion/react";
64
+ import {
65
+ Children,
66
+ cloneElement,
67
+ createContext as createContext3,
68
+ forwardRef as forwardRef3,
69
+ isValidElement,
70
+ useCallback as useCallback2,
71
+ useContext as useContext3,
72
+ useEffect as useEffect3,
73
+ useImperativeHandle,
74
+ useMemo as useMemo2,
75
+ useRef as useRef3,
76
+ useState as useState2
77
+ } from "react";
78
+
79
+ // components/overlays/dropdown/dropdown-search.tsx
80
+ import {
81
+ createContext,
82
+ forwardRef,
83
+ useCallback,
84
+ useContext,
85
+ useEffect,
86
+ useMemo,
87
+ useRef,
88
+ useState
89
+ } from "react";
90
+ import { jsx, jsxs } from "react/jsx-runtime";
91
+ var DropdownSearchHostContext = createContext(null);
92
+ var DropdownFilterContext = createContext(null);
93
+ var ROW_SELECTOR = [
94
+ '[role="menuitem"]:not([aria-disabled="true"])',
95
+ '[role="menuitemradio"]:not([aria-disabled="true"])',
96
+ '[role="menuitemcheckbox"]:not([aria-disabled="true"])'
97
+ ].join(", ");
98
+ function menuRows(from) {
99
+ const menu = from?.closest('[role="menu"]');
100
+ return menu ? Array.from(menu.querySelectorAll(ROW_SELECTOR)) : [];
101
+ }
102
+ function useDropdownSearchHost(open, { containerRef, setActiveIndex }) {
103
+ const handleRef = useRef(null);
104
+ const [searchMounted, setSearchMounted] = useState(false);
105
+ const register = useCallback((handle) => {
106
+ handleRef.current = handle;
107
+ setSearchMounted(true);
108
+ return () => {
109
+ if (handleRef.current === handle) {
110
+ handleRef.current = null;
111
+ setSearchMounted(false);
112
+ }
113
+ };
114
+ }, []);
115
+ const highlightFirst = useCallback(() => {
116
+ const first = containerRef.current?.querySelector(ROW_SELECTOR);
117
+ const index = first?.getAttribute("data-fluid-hover-index");
118
+ setActiveIndex(index != null ? Number(index) : null);
119
+ }, [containerRef, setActiveIndex]);
120
+ const isSearchField = useCallback((target) => target !== null && target === handleRef.current?.input, []);
121
+ const host = useMemo(() => ({ register, open, highlightFirst }), [register, open, highlightFirst]);
122
+ const onKeyDownCapture = useCallback((e) => {
123
+ const handle = handleRef.current;
124
+ if (!handle?.input)
125
+ return;
126
+ if (e.target === handle.input)
127
+ return;
128
+ if (e.metaKey || e.ctrlKey || e.altKey)
129
+ return;
130
+ if (e.key.length === 1 && e.key !== " ") {
131
+ e.preventDefault();
132
+ e.stopPropagation();
133
+ handle.input.focus();
134
+ handle.append(e.key);
135
+ } else if (e.key === "Backspace") {
136
+ e.preventDefault();
137
+ e.stopPropagation();
138
+ handle.input.focus();
139
+ handle.deleteBackward();
140
+ }
141
+ }, []);
142
+ const hasSearch = useCallback(() => handleRef.current !== null, []);
143
+ return {
144
+ host,
145
+ hasSearch,
146
+ searchMounted,
147
+ onKeyDownCapture,
148
+ isSearchField,
149
+ highlightFirst
150
+ };
151
+ }
152
+ var DropdownSearch = forwardRef(({
153
+ value,
154
+ onValueChange,
155
+ filter = false,
156
+ placeholder = "Search…",
157
+ clearOnClose = true,
158
+ autoFocus = true,
159
+ className,
160
+ onKeyDown,
161
+ ...props
162
+ }, ref) => {
163
+ const SearchIcon = useIcon("search");
164
+ const sizeClasses = useSize();
165
+ const compact = sizeClasses.variant === "compact";
166
+ const host = useContext(DropdownSearchHostContext);
167
+ const open = host?.open ?? true;
168
+ const panel = useContext(DropdownFilterContext);
169
+ const managed = filter ? panel : null;
170
+ const query = managed ? managed.query : value ?? "";
171
+ const setQuery = useCallback((next) => {
172
+ managed?.setQuery(next);
173
+ onValueChange?.(next);
174
+ }, [managed, onValueChange]);
175
+ const surface = useSurface();
176
+ const inputRef = useRef(null);
177
+ const valueRef = useRef(query);
178
+ valueRef.current = query;
179
+ const onValueChangeRef = useRef(setQuery);
180
+ onValueChangeRef.current = setQuery;
181
+ const clearOnCloseRef = useRef(clearOnClose);
182
+ clearOnCloseRef.current = clearOnClose;
183
+ useEffect(() => {
184
+ if (!host)
185
+ return;
186
+ return host.register({
187
+ get input() {
188
+ return inputRef.current;
189
+ },
190
+ append: (text) => onValueChangeRef.current(valueRef.current + text),
191
+ deleteBackward: () => onValueChangeRef.current(valueRef.current.slice(0, -1))
192
+ });
193
+ }, [host]);
194
+ useEffect(() => {
195
+ if (!open)
196
+ return;
197
+ if (clearOnCloseRef.current && valueRef.current !== "") {
198
+ onValueChangeRef.current("");
199
+ }
200
+ if (!autoFocus)
201
+ return;
202
+ let inner;
203
+ const outer = requestAnimationFrame(() => {
204
+ inner = requestAnimationFrame(() => inputRef.current?.focus());
205
+ });
206
+ return () => {
207
+ cancelAnimationFrame(outer);
208
+ if (inner !== undefined)
209
+ cancelAnimationFrame(inner);
210
+ };
211
+ }, [open, autoFocus]);
212
+ useEffect(() => {
213
+ if (!host || document.activeElement !== inputRef.current)
214
+ return;
215
+ host.highlightFirst();
216
+ }, [host, query]);
217
+ useEffect(() => () => {
218
+ if (clearOnCloseRef.current && valueRef.current !== "") {
219
+ onValueChangeRef.current("");
220
+ }
221
+ }, []);
222
+ const handleKeyDown = (e) => {
223
+ onKeyDown?.(e);
224
+ if (e.defaultPrevented)
225
+ return;
226
+ if (e.key === "Escape" || e.key === "Tab")
227
+ return;
228
+ e.stopPropagation();
229
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
230
+ const rows = menuRows(e.currentTarget);
231
+ if (rows.length === 0)
232
+ return;
233
+ e.preventDefault();
234
+ (e.key === "ArrowDown" ? rows[0] : rows[rows.length - 1])?.focus();
235
+ } else if (e.key === "Enter") {
236
+ e.preventDefault();
237
+ menuRows(e.currentTarget)[0]?.click();
238
+ }
239
+ };
240
+ return /* @__PURE__ */ jsxs("div", {
241
+ className: cn("group/search sticky top-0 z-20 -mx-1 -mt-1 mb-0.5 flex shrink-0 items-center border-b border-border/60", SURFACE_BG[surface], sizeClasses.control, sizeClasses.gap, compact ? "px-2.5" : "px-3", className),
242
+ children: [
243
+ /* @__PURE__ */ jsx(SearchIcon, {
244
+ size: sizeClasses.icon,
245
+ strokeWidth: 1.5,
246
+ className: "shrink-0 text-muted-foreground transition-[color,stroke-width] duration-fast group-focus-within/search:text-foreground group-focus-within/search:stroke-[2]"
247
+ }),
248
+ /* @__PURE__ */ jsx("input", {
249
+ ref: (node) => {
250
+ inputRef.current = node;
251
+ if (typeof ref === "function")
252
+ ref(node);
253
+ else if (ref)
254
+ ref.current = node;
255
+ },
256
+ type: "text",
257
+ role: "searchbox",
258
+ autoComplete: "off",
259
+ autoCorrect: "off",
260
+ spellCheck: false,
261
+ value: query,
262
+ onChange: (e) => setQuery(e.target.value),
263
+ onKeyDown: handleKeyDown,
264
+ placeholder,
265
+ className: cn("min-w-0 flex-1 rounded-none bg-transparent text-foreground placeholder:text-muted-foreground outline-none font-[inherit]", sizeClasses.text, compact ? "leading-5" : "leading-6"),
266
+ ...props
267
+ })
268
+ ]
269
+ });
270
+ });
271
+ DropdownSearch.displayName = "DropdownSearch";
272
+ var DropdownEmpty = forwardRef(({ className, ...props }, ref) => {
273
+ const sizeClasses = useSize();
274
+ return /* @__PURE__ */ jsx("div", {
275
+ ref,
276
+ role: "status",
277
+ "aria-live": "polite",
278
+ className: cn("px-2 py-6 text-center text-muted-foreground", sizeClasses.text, className),
279
+ ...props
280
+ });
281
+ });
282
+ DropdownEmpty.displayName = "DropdownEmpty";
283
+
284
+ // components/overlays/dropdown/menu-item.tsx
285
+ import { AnimatePresence, motion } from "motion/react";
286
+ import {
287
+ createContext as createContext2,
288
+ forwardRef as forwardRef2,
289
+ useContext as useContext2,
290
+ useEffect as useEffect2,
291
+ useRef as useRef2
292
+ } from "react";
293
+ import { jsx as jsx2, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
294
+ var shape = shapeMap.rounded;
295
+ var DropdownContext = createContext2(null);
296
+ function useDropdown() {
297
+ const ctx = useContext2(DropdownContext);
298
+ if (!ctx)
299
+ throw new Error("useDropdown must be used within a Dropdown");
300
+ return ctx;
301
+ }
302
+ function useDropdownMaybe() {
303
+ return useContext2(DropdownContext);
304
+ }
305
+ var MenuItem = forwardRef2(({ icon: Icon, label, index, checked, onSelect, disabled, closeOnClick, sourceIndex, className, onClick, ...props }, ref) => {
306
+ const internalRef = useRef2(null);
307
+ const hasMounted = useRef2(false);
308
+ const {
309
+ registerItem,
310
+ activeIndex,
311
+ checkedIndex,
312
+ multiple,
313
+ checkedIndices,
314
+ renderMenuItem,
315
+ selfManaged,
316
+ toggleIndex
317
+ } = useDropdown();
318
+ const panelChecked = multiple ? checkedIndices?.includes(index) ?? false : checkedIndex === index;
319
+ const isChecked = checked ?? (selfManaged ? panelChecked : undefined);
320
+ const isCheckbox = !!multiple && typeof isChecked === "boolean";
321
+ useRegisterFluidHoverItem(registerItem, index, internalRef);
322
+ useEffect2(() => {
323
+ hasMounted.current = true;
324
+ }, []);
325
+ const isActive = activeIndex === index;
326
+ const skipAnimation = !hasMounted.current;
327
+ const sizeClasses = useSize();
328
+ const mergeRef = (node) => {
329
+ internalRef.current = node;
330
+ if (typeof ref === "function")
331
+ ref(node);
332
+ else if (ref)
333
+ ref.current = node;
334
+ };
335
+ const activate = () => {
336
+ onSelect?.();
337
+ if (selfManaged)
338
+ toggleIndex?.(sourceIndex ?? index);
339
+ };
340
+ const handleActivate = disabled ? undefined : (e) => {
341
+ onClick?.(e);
342
+ activate();
343
+ };
344
+ const itemClassName = cn(`relative z-10 flex ${sizeClasses.control} shrink-0 items-center ${sizeClasses.gap} ${shape.item} ${sizeClasses.itemPx} cursor-pointer outline-none`, disabled && "opacity-50 pointer-events-none", className);
345
+ const content = /* @__PURE__ */ jsxs2(Fragment, {
346
+ children: [
347
+ Icon && /* @__PURE__ */ jsxs2("span", {
348
+ className: "inline-grid",
349
+ children: [
350
+ /* @__PURE__ */ jsx2("span", {
351
+ className: "col-start-1 row-start-1 invisible",
352
+ children: /* @__PURE__ */ jsx2(Icon, {
353
+ size: sizeClasses.icon,
354
+ strokeWidth: 2
355
+ })
356
+ }),
357
+ /* @__PURE__ */ jsx2(Icon, {
358
+ size: sizeClasses.icon,
359
+ strokeWidth: isActive || isChecked ? 2 : 1.5,
360
+ className: cn("col-start-1 row-start-1 transition-[color,stroke-width] duration-fast", isActive || isChecked ? "text-foreground" : "text-muted-foreground")
361
+ })
362
+ ]
363
+ }),
364
+ /* @__PURE__ */ jsxs2("span", {
365
+ className: cn("inline-grid flex-1", sizeClasses.text),
366
+ children: [
367
+ /* @__PURE__ */ jsx2("span", {
368
+ className: "col-start-1 row-start-1 invisible [text-box:trim-both_cap_alphabetic] weight-semibold",
369
+ "aria-hidden": "true",
370
+ children: label
371
+ }),
372
+ /* @__PURE__ */ jsx2("span", {
373
+ className: cn("col-start-1 row-start-1 transition-[color,font-variation-settings] duration-fast [text-box:trim-both_cap_alphabetic]", isActive || isChecked ? "text-foreground" : "text-muted-foreground", isChecked ? "weight-semibold" : "weight-normal"),
374
+ children: label
375
+ })
376
+ ]
377
+ }),
378
+ /* @__PURE__ */ jsx2(AnimatePresence, {
379
+ children: isChecked && /* @__PURE__ */ jsx2(motion.svg, {
380
+ width: sizeClasses.icon,
381
+ height: sizeClasses.icon,
382
+ viewBox: "0 0 24 24",
383
+ fill: "none",
384
+ stroke: "currentColor",
385
+ strokeWidth: 2,
386
+ strokeLinecap: "round",
387
+ strokeLinejoin: "round",
388
+ className: "text-foreground shrink-0",
389
+ initial: { opacity: 1 },
390
+ animate: { opacity: 1 },
391
+ exit: { opacity: 1 },
392
+ children: /* @__PURE__ */ jsx2(motion.path, {
393
+ d: "M4 12L9 17L20 6",
394
+ initial: { pathLength: skipAnimation ? 1 : 0 },
395
+ animate: {
396
+ pathLength: 1,
397
+ transition: { duration: spring.fast.duration, ease: "easeOut" }
398
+ },
399
+ exit: {
400
+ pathLength: 0,
401
+ transition: { duration: 0.04, ease: "easeIn" }
402
+ }
403
+ })
404
+ }, "check")
405
+ })
406
+ ]
407
+ });
408
+ if (renderMenuItem) {
409
+ return renderMenuItem({
410
+ radio: !isCheckbox && typeof isChecked === "boolean",
411
+ checkbox: isCheckbox,
412
+ checked: isChecked,
413
+ value: index,
414
+ disabled,
415
+ label,
416
+ closeOnClick: closeOnClick ?? !multiple,
417
+ onClick: handleActivate,
418
+ element: /* @__PURE__ */ jsx2("div", {
419
+ ref: mergeRef,
420
+ "data-fluid-hover-index": index,
421
+ "aria-label": label,
422
+ className: itemClassName,
423
+ ...props
424
+ }),
425
+ children: content
426
+ });
427
+ }
428
+ return /* @__PURE__ */ jsx2("div", {
429
+ ref: mergeRef,
430
+ "data-fluid-hover-index": index,
431
+ tabIndex: !disabled && index === (checkedIndex ?? checkedIndices?.[0] ?? 0) ? 0 : -1,
432
+ role: isCheckbox ? "menuitemcheckbox" : typeof isChecked === "boolean" ? "menuitemradio" : "menuitem",
433
+ "aria-checked": typeof isChecked === "boolean" ? isChecked : undefined,
434
+ "aria-disabled": disabled || undefined,
435
+ "aria-label": label,
436
+ onClick: handleActivate,
437
+ onKeyDown: (e) => {
438
+ if (disabled)
439
+ return;
440
+ if (e.key === " " || e.key === "Enter") {
441
+ e.preventDefault();
442
+ activate();
443
+ }
444
+ },
445
+ className: itemClassName,
446
+ ...props,
447
+ children: content
448
+ });
449
+ });
450
+ MenuItem.displayName = "MenuItem";
451
+
452
+ // components/overlays/dropdown/index.tsx
453
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
454
+ var shape2 = shapeMap.rounded;
455
+ var NONE = -1;
456
+ var NO_INDICES = [];
457
+ var NO_RECTS = [];
458
+ function usePanelSelection({
459
+ checkedIndex,
460
+ defaultCheckedIndex,
461
+ onCheckedIndexChange,
462
+ checkedIndices,
463
+ defaultCheckedIndices,
464
+ onCheckedIndicesChange
465
+ }, sourceOf, filtering) {
466
+ const [single, setSingle] = useControllableState(defaultCheckedIndex === undefined ? checkedIndex ?? NONE : undefined, defaultCheckedIndex ?? NONE, (index) => onCheckedIndexChange?.(index === NONE ? undefined : index));
467
+ const [many, setMany] = useControllableState(defaultCheckedIndices === undefined ? checkedIndices ?? NO_INDICES : undefined, defaultCheckedIndices ?? NO_INDICES, (indices) => onCheckedIndicesChange?.(indices));
468
+ const multiple = checkedIndices != null || defaultCheckedIndices != null;
469
+ const selfManaged = defaultCheckedIndex !== undefined || defaultCheckedIndices !== undefined;
470
+ const toggleIndex = useCallback2((source) => {
471
+ if (multiple) {
472
+ setMany((prev) => prev.includes(source) ? prev.filter((i) => i !== source) : [...prev, source].sort((a, b) => a - b));
473
+ return;
474
+ }
475
+ setSingle(source);
476
+ }, [multiple, setMany, setSingle]);
477
+ const renderedIndex = useMemo2(() => {
478
+ if (single === NONE)
479
+ return;
480
+ const i = filtering ? sourceOf.indexOf(single) : single;
481
+ return i === -1 ? undefined : i;
482
+ }, [single, filtering, sourceOf]);
483
+ const renderedIndices = useMemo2(() => {
484
+ if (!multiple)
485
+ return;
486
+ if (!filtering)
487
+ return many;
488
+ return many.map((s) => sourceOf.indexOf(s)).filter((i) => i !== -1);
489
+ }, [multiple, many, filtering, sourceOf]);
490
+ return {
491
+ checkedIndex: renderedIndex,
492
+ checkedIndices: renderedIndices,
493
+ multiple,
494
+ selfManaged,
495
+ toggleIndex
496
+ };
497
+ }
498
+ function usePanelRows(children) {
499
+ const [query, setQuery] = useState2("");
500
+ const filtering = useMemo2(() => Children.toArray(children).some((child) => isValidElement(child) && child.type === DropdownSearch && child.props.filter), [children]);
501
+ const filterCtx = useMemo2(() => ({ query, setQuery }), [query]);
502
+ const { content, sourceOf } = useMemo2(() => {
503
+ if (!filtering)
504
+ return { content: children, sourceOf: NO_INDICES };
505
+ const needle = query.trim().toLowerCase();
506
+ const rendered = [];
507
+ const empties = [];
508
+ const sources = [];
509
+ for (const child of Children.toArray(children)) {
510
+ if (!isValidElement(child)) {
511
+ rendered.push(child);
512
+ continue;
513
+ }
514
+ if (child.type === DropdownEmpty) {
515
+ empties.push(child);
516
+ continue;
517
+ }
518
+ const rowProps = child.props;
519
+ if (typeof rowProps.label !== "string" || typeof rowProps.index !== "number") {
520
+ rendered.push(child);
521
+ continue;
522
+ }
523
+ if (needle && !rowProps.label.toLowerCase().includes(needle))
524
+ continue;
525
+ rendered.push(cloneElement(child, {
526
+ index: sources.length,
527
+ sourceIndex: rowProps.index
528
+ }));
529
+ sources.push(rowProps.index);
530
+ }
531
+ if (sources.length === 0)
532
+ rendered.push(...empties);
533
+ return { content: rendered, sourceOf: sources };
534
+ }, [children, filtering, query]);
535
+ return { content, sourceOf, filtering, filterCtx: filtering ? filterCtx : null };
536
+ }
537
+ var Dropdown = forwardRef3(({
538
+ children,
539
+ checkedIndex,
540
+ defaultCheckedIndex,
541
+ onCheckedIndexChange,
542
+ checkedIndices,
543
+ defaultCheckedIndices,
544
+ onCheckedIndicesChange,
545
+ size,
546
+ className,
547
+ ...props
548
+ }, ref) => {
549
+ const containerRef = useRef3(null);
550
+ const hover = useFluidHover(containerRef, { isItemDisabled: isDisabledRow });
551
+ const { activeIndex, setActiveIndex, itemRects, handlers, registerItem } = hover;
552
+ const [focusedIndex, setFocusedIndex] = useState2(null);
553
+ const rows = usePanelRows(children);
554
+ const selection = usePanelSelection({
555
+ checkedIndex,
556
+ defaultCheckedIndex,
557
+ onCheckedIndexChange,
558
+ checkedIndices,
559
+ defaultCheckedIndices,
560
+ onCheckedIndicesChange
561
+ }, rows.sourceOf, rows.filtering);
562
+ const multiple = selection.multiple;
563
+ const checkedRect = !multiple && selection.checkedIndex != null ? itemRects[selection.checkedIndex] : null;
564
+ const focusRect = focusedIndex !== null ? itemRects[focusedIndex] : null;
565
+ const runs = useSelectionRuns(selection.checkedIndices ?? NO_INDICES);
566
+ const blocks = useMergeSplitBlocks(runs, itemRects, shape2.bgRadius);
567
+ const panelCtx = useMemo2(() => ({
568
+ registerItem,
569
+ activeIndex,
570
+ checkedIndex: selection.checkedIndex,
571
+ multiple,
572
+ checkedIndices: selection.checkedIndices,
573
+ selfManaged: selection.selfManaged,
574
+ toggleIndex: selection.toggleIndex
575
+ }), [
576
+ registerItem,
577
+ activeIndex,
578
+ selection.checkedIndex,
579
+ multiple,
580
+ selection.checkedIndices,
581
+ selection.selfManaged,
582
+ selection.toggleIndex
583
+ ]);
584
+ const panel = /* @__PURE__ */ jsx3(DropdownContext.Provider, {
585
+ value: panelCtx,
586
+ children: /* @__PURE__ */ jsx3(DropdownFilterContext.Provider, {
587
+ value: rows.filterCtx,
588
+ children: /* @__PURE__ */ jsxs3(Elevated, {
589
+ offset: 2,
590
+ shadowLevel: 3,
591
+ ref: (node) => {
592
+ containerRef.current = node;
593
+ if (typeof ref === "function")
594
+ ref(node);
595
+ else if (ref)
596
+ ref.current = node;
597
+ },
598
+ onMouseEnter: handlers.onMouseEnter,
599
+ onMouseMove: handlers.onMouseMove,
600
+ onMouseLeave: handlers.onMouseLeave,
601
+ onClick: handlers.onClick,
602
+ onFocus: (e) => {
603
+ const indexAttr = e.target.closest("[data-fluid-hover-index]")?.getAttribute("data-fluid-hover-index");
604
+ if (indexAttr != null) {
605
+ const idx = Number(indexAttr);
606
+ setActiveIndex(idx);
607
+ setFocusedIndex(e.target.matches(":focus-visible") ? idx : null);
608
+ }
609
+ },
610
+ onBlur: (e) => {
611
+ if (containerRef.current?.contains(e.relatedTarget))
612
+ return;
613
+ setFocusedIndex(null);
614
+ setActiveIndex(null);
615
+ },
616
+ onKeyDown: (e) => {
617
+ const items = Array.from(containerRef.current?.querySelectorAll('[role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]') ?? []);
618
+ const currentIdx = items.indexOf(e.target);
619
+ if (currentIdx === -1)
620
+ return;
621
+ if (["ArrowDown", "ArrowUp", "ArrowRight", "ArrowLeft"].includes(e.key)) {
622
+ e.preventDefault();
623
+ const next = ["ArrowDown", "ArrowRight"].includes(e.key) ? (currentIdx + 1) % items.length : (currentIdx - 1 + items.length) % items.length;
624
+ items[next]?.focus();
625
+ } else if (e.key === "Home") {
626
+ e.preventDefault();
627
+ items[0]?.focus();
628
+ } else if (e.key === "End") {
629
+ e.preventDefault();
630
+ items[items.length - 1]?.focus();
631
+ }
632
+ },
633
+ role: "group",
634
+ className: cn(`relative flex flex-col w-72 max-w-full p-1 select-none`, className),
635
+ ...props,
636
+ children: [
637
+ multiple && /* @__PURE__ */ jsx3(SelectionBackgrounds, {
638
+ blocks
639
+ }),
640
+ /* @__PURE__ */ jsx3(AnimatePresence2, {
641
+ children: checkedRect && /* @__PURE__ */ jsx3(motion2.div, {
642
+ className: `absolute ${shape2.bg} bg-active pointer-events-none`,
643
+ initial: false,
644
+ animate: {
645
+ top: checkedRect.top,
646
+ left: checkedRect.left,
647
+ width: checkedRect.width,
648
+ height: checkedRect.height,
649
+ opacity: 1
650
+ },
651
+ exit: { opacity: 0, transition: spring.moderate.exit },
652
+ transition: {
653
+ ...spring.moderate,
654
+ opacity: { duration: spring.fast.duration }
655
+ }
656
+ })
657
+ }),
658
+ /* @__PURE__ */ jsx3(FluidHoverHighlight, {
659
+ hover,
660
+ from: checkedRect,
661
+ className: shape2.bg
662
+ }),
663
+ /* @__PURE__ */ jsx3(AnimatePresence2, {
664
+ children: focusRect && /* @__PURE__ */ jsx3(motion2.div, {
665
+ className: `absolute ${shape2.focusRing} pointer-events-none z-20 border border-focus-ring`,
666
+ initial: false,
667
+ animate: {
668
+ left: focusRect.left - 2,
669
+ top: focusRect.top - 2,
670
+ width: focusRect.width + 4,
671
+ height: focusRect.height + 4
672
+ },
673
+ exit: { opacity: 0, transition: spring.fast.exit },
674
+ transition: {
675
+ ...spring.fast,
676
+ opacity: { duration: spring.fast.duration }
677
+ }
678
+ })
679
+ }),
680
+ rows.content
681
+ ]
682
+ })
683
+ })
684
+ });
685
+ return size ? /* @__PURE__ */ jsx3(SizeProvider, {
686
+ size,
687
+ children: panel
688
+ }) : panel;
689
+ });
690
+ Dropdown.displayName = "Dropdown";
691
+ var DropdownMenuContext = createContext3(null);
692
+ function useDropdownMenuContext() {
693
+ const ctx = useContext3(DropdownMenuContext);
694
+ if (!ctx)
695
+ throw new Error("DropdownMenu compound components must be inside <DropdownMenu>");
696
+ return ctx;
697
+ }
698
+ function DropdownMenu({
699
+ children,
700
+ open: openProp,
701
+ defaultOpen = false,
702
+ onOpenChange,
703
+ disabled = false,
704
+ size
705
+ }) {
706
+ const [internalOpen, setInternalOpen] = useState2(defaultOpen);
707
+ const open = openProp !== undefined ? openProp : internalOpen;
708
+ const { origin, capture } = useMorphOrigin();
709
+ const handleOpenChange = useCallback2((next, details) => {
710
+ if (next)
711
+ capture(details);
712
+ if (openProp === undefined)
713
+ setInternalOpen(next);
714
+ onOpenChange?.(next);
715
+ }, [openProp, onOpenChange, capture]);
716
+ const ctx = useMemo2(() => ({ open, origin }), [open, origin]);
717
+ const root = /* @__PURE__ */ jsx3(DropdownMenuContext.Provider, {
718
+ value: ctx,
719
+ children: /* @__PURE__ */ jsx3(Menu.Root, {
720
+ open,
721
+ onOpenChange: handleOpenChange,
722
+ disabled,
723
+ modal: false,
724
+ children
725
+ })
726
+ });
727
+ return size ? /* @__PURE__ */ jsx3(SizeProvider, {
728
+ size,
729
+ children: root
730
+ }) : root;
731
+ }
732
+ DropdownMenu.displayName = "DropdownMenu";
733
+ var DropdownTrigger = Menu.Trigger;
734
+ var DropdownContent = forwardRef3(({
735
+ className,
736
+ children,
737
+ checkedIndex,
738
+ defaultCheckedIndex,
739
+ onCheckedIndexChange,
740
+ checkedIndices,
741
+ defaultCheckedIndices,
742
+ onCheckedIndicesChange,
743
+ side = "bottom",
744
+ align = "start",
745
+ sideOffset = 6,
746
+ from,
747
+ effect,
748
+ hideSource,
749
+ tier = "moderate"
750
+ }, ref) => {
751
+ const { open, origin } = useDropdownMenuContext();
752
+ const morph = useMorph(open, origin, { from, effect, hideSource, tier });
753
+ useImperativeHandle(ref, () => morph.popup, [morph.popup]);
754
+ const level = Math.min(useSurface() + 2, 8);
755
+ const containerRef = useRef3(null);
756
+ const hover = useFluidHover(containerRef, { isItemDisabled: isDisabledRow });
757
+ const { activeIndex, setActiveIndex, itemRects, handlers, registerItem, remeasure } = hover;
758
+ const rows = usePanelRows(children);
759
+ const selection = usePanelSelection({
760
+ checkedIndex,
761
+ defaultCheckedIndex,
762
+ onCheckedIndexChange,
763
+ checkedIndices,
764
+ defaultCheckedIndices,
765
+ onCheckedIndicesChange
766
+ }, rows.sourceOf, rows.filtering);
767
+ const {
768
+ host: searchHost,
769
+ hasSearch,
770
+ searchMounted,
771
+ onKeyDownCapture: redirectTypingToSearch,
772
+ isSearchField,
773
+ highlightFirst
774
+ } = useDropdownSearchHost(open, { containerRef, setActiveIndex });
775
+ useEffect3(() => {
776
+ if (!open)
777
+ return;
778
+ let inner;
779
+ const outer = requestAnimationFrame(() => {
780
+ inner = requestAnimationFrame(() => {
781
+ if (hasSearch())
782
+ return;
783
+ const container = containerRef.current;
784
+ if (!container || container.contains(document.activeElement) && document.activeElement !== container)
785
+ return;
786
+ const first = container.querySelector('[role="menuitem"]:not([aria-disabled="true"]), [role="menuitemradio"]:not([aria-disabled="true"]), [role="menuitemcheckbox"]:not([aria-disabled="true"])');
787
+ first?.focus();
788
+ });
789
+ });
790
+ return () => {
791
+ cancelAnimationFrame(outer);
792
+ if (inner !== undefined)
793
+ cancelAnimationFrame(inner);
794
+ };
795
+ }, [open, hasSearch]);
796
+ useEffect3(() => {
797
+ if (!open)
798
+ return;
799
+ remeasure();
800
+ }, [open, remeasure]);
801
+ const multiple = selection.multiple;
802
+ const checkedRect = !multiple && selection.checkedIndex != null ? itemRects[selection.checkedIndex] : null;
803
+ const runs = useSelectionRuns(selection.checkedIndices ?? NO_INDICES);
804
+ const blocks = useMergeSplitBlocks(runs, open ? itemRects : NO_RECTS, shape2.bgRadius);
805
+ const renderMenuItem = useCallback2(({
806
+ radio,
807
+ checkbox,
808
+ checked,
809
+ value,
810
+ disabled,
811
+ label,
812
+ closeOnClick,
813
+ onClick,
814
+ element,
815
+ children: children2
816
+ }) => checkbox ? /* @__PURE__ */ jsx3(Menu.CheckboxItem, {
817
+ checked: !!checked,
818
+ disabled,
819
+ label,
820
+ closeOnClick,
821
+ onClick,
822
+ render: element,
823
+ children: children2
824
+ }) : radio ? /* @__PURE__ */ jsx3(Menu.RadioItem, {
825
+ value,
826
+ disabled,
827
+ label,
828
+ closeOnClick,
829
+ onClick,
830
+ render: element,
831
+ children: children2
832
+ }) : /* @__PURE__ */ jsx3(Menu.Item, {
833
+ disabled,
834
+ label,
835
+ closeOnClick,
836
+ onClick,
837
+ render: element,
838
+ children: children2
839
+ }), []);
840
+ const contentCtx = useMemo2(() => ({
841
+ registerItem,
842
+ activeIndex,
843
+ checkedIndex: selection.checkedIndex,
844
+ multiple,
845
+ checkedIndices: selection.checkedIndices,
846
+ inMenu: true,
847
+ renderMenuItem,
848
+ selfManaged: selection.selfManaged,
849
+ toggleIndex: selection.toggleIndex
850
+ }), [
851
+ registerItem,
852
+ activeIndex,
853
+ selection.checkedIndex,
854
+ multiple,
855
+ selection.checkedIndices,
856
+ selection.selfManaged,
857
+ selection.toggleIndex,
858
+ renderMenuItem
859
+ ]);
860
+ return /* @__PURE__ */ jsx3(Menu.Portal, {
861
+ children: /* @__PURE__ */ jsx3(Menu.Positioner, {
862
+ side,
863
+ align,
864
+ sideOffset: opensInPlace({ effect, hideSource }) ? inPlaceOffset : sideOffset,
865
+ className: "z-50 outline-none",
866
+ children: /* @__PURE__ */ jsx3(DropdownContext.Provider, {
867
+ value: contentCtx,
868
+ children: /* @__PURE__ */ jsx3(DropdownFilterContext.Provider, {
869
+ value: rows.filterCtx,
870
+ children: /* @__PURE__ */ jsx3(DropdownSearchHostContext.Provider, {
871
+ value: searchHost,
872
+ children: /* @__PURE__ */ jsx3(Menu.Popup, {
873
+ ref: morph.popupRef,
874
+ onKeyDownCapture: redirectTypingToSearch,
875
+ onMouseEnter: handlers.onMouseEnter,
876
+ onMouseMove: handlers.onMouseMove,
877
+ onClick: handlers.onClick,
878
+ onMouseLeave: () => {
879
+ handlers.onMouseLeave();
880
+ if (isSearchField(document.activeElement))
881
+ highlightFirst();
882
+ },
883
+ onFocus: (e) => {
884
+ const indexAttr = e.target.closest("[data-fluid-hover-index]")?.getAttribute("data-fluid-hover-index");
885
+ if (indexAttr != null) {
886
+ setActiveIndex(Number(indexAttr));
887
+ } else if (isSearchField(e.target)) {
888
+ highlightFirst();
889
+ } else if (e.target !== e.currentTarget) {
890
+ setActiveIndex(null);
891
+ }
892
+ },
893
+ onBlur: (e) => {
894
+ if (e.currentTarget.contains(e.relatedTarget))
895
+ return;
896
+ setActiveIndex(null);
897
+ },
898
+ className: "relative select-none outline-none",
899
+ children: /* @__PURE__ */ jsx3(SurfaceProvider, {
900
+ value: level,
901
+ children: /* @__PURE__ */ jsx3(MorphSurface, {
902
+ morph,
903
+ bg: SURFACE_BG[level],
904
+ shadow: SURFACE_SHADOW[3],
905
+ radius: shape2.container,
906
+ className: cn(`flex flex-col w-72 max-w-full min-w-[var(--anchor-width)] max-h-[min(480px,var(--available-height))] overflow-hidden ${shape2.container}`, className),
907
+ children: /* @__PURE__ */ jsx3(ScrollArea, {
908
+ className: popupScrollAreaClass,
909
+ viewportClassName: cn(popupViewportClass, !searchMounted && "scroll-fade"),
910
+ children: /* @__PURE__ */ jsxs3("div", {
911
+ ref: containerRef,
912
+ className: "relative flex flex-col p-1",
913
+ children: [
914
+ multiple && /* @__PURE__ */ jsx3(SelectionBackgrounds, {
915
+ blocks
916
+ }),
917
+ /* @__PURE__ */ jsx3(AnimatePresence2, {
918
+ children: checkedRect && /* @__PURE__ */ jsx3(motion2.div, {
919
+ className: `absolute ${shape2.bg} bg-active pointer-events-none`,
920
+ initial: false,
921
+ animate: {
922
+ top: checkedRect.top,
923
+ left: checkedRect.left,
924
+ width: checkedRect.width,
925
+ height: checkedRect.height,
926
+ opacity: 1
927
+ },
928
+ exit: { opacity: 0, transition: spring.moderate.exit },
929
+ transition: {
930
+ ...spring.moderate,
931
+ opacity: { duration: spring.fast.duration }
932
+ }
933
+ })
934
+ }),
935
+ /* @__PURE__ */ jsx3(FluidHoverHighlight, {
936
+ hover,
937
+ from: checkedRect,
938
+ className: shape2.bg
939
+ }),
940
+ /* @__PURE__ */ jsx3(Menu.RadioGroup, {
941
+ value: selection.checkedIndex ?? null,
942
+ className: "contents",
943
+ children: rows.content
944
+ })
945
+ ]
946
+ })
947
+ })
948
+ })
949
+ })
950
+ })
951
+ })
952
+ })
953
+ })
954
+ })
955
+ });
956
+ });
957
+ DropdownContent.displayName = "DropdownContent";
958
+ var DropdownLabel = forwardRef3(({ className, ...props }, ref) => {
959
+ const compact = useSize().variant === "compact";
960
+ return /* @__PURE__ */ jsx3("div", {
961
+ ref,
962
+ className: cn("px-2 py-1.5 shrink-0 text-muted-foreground", compact ? "text-caption-compact" : "text-caption", className),
963
+ ...props
964
+ });
965
+ });
966
+ DropdownLabel.displayName = "DropdownLabel";
967
+ var DropdownSeparator = forwardRef3(({ className, ...props }, ref) => /* @__PURE__ */ jsx3("div", {
968
+ ref,
969
+ role: "separator",
970
+ className: cn("my-1 -mx-1 h-px shrink-0 bg-border/60", className),
971
+ ...props
972
+ }));
973
+ DropdownSeparator.displayName = "DropdownSeparator";
974
+ Object.assign(Dropdown, {
975
+ Menu: DropdownMenu,
976
+ Trigger: DropdownTrigger,
977
+ Content: DropdownContent,
978
+ Item: MenuItem,
979
+ Label: DropdownLabel,
980
+ Separator: DropdownSeparator,
981
+ Search: DropdownSearch,
982
+ Empty: DropdownEmpty
983
+ });
984
+ var dropdown_default = Dropdown;
985
+
986
+ export { DropdownSearch, DropdownEmpty, DropdownContext, useDropdown, useDropdownMaybe, MenuItem, Dropdown, DropdownMenu, DropdownTrigger, DropdownContent, DropdownLabel, DropdownSeparator, dropdown_default };