@justanarthur/modo-ui 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) 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 +31 -0
  10. package/dist/components/badge/index.d.ts +59 -0
  11. package/dist/components/badge/index.js +16 -0
  12. package/dist/components/button/index.d.ts +59 -0
  13. package/dist/components/button/index.js +14 -0
  14. package/dist/components/card/index.d.ts +141 -0
  15. package/dist/components/card/index.js +42 -0
  16. package/dist/components/inputs/checkbox-group/index.d.ts +50 -0
  17. package/dist/components/inputs/checkbox-group/index.js +21 -0
  18. package/dist/components/inputs/color-picker/index.d.ts +137 -0
  19. package/dist/components/inputs/color-picker/index.js +35 -0
  20. package/dist/components/inputs/combobox/index.d.ts +161 -0
  21. package/dist/components/inputs/combobox/index.js +38 -0
  22. package/dist/components/inputs/date-time/calendar/index.d.ts +45 -0
  23. package/dist/components/inputs/date-time/calendar/index.js +18 -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 +32 -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 +31 -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 +31 -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 +30 -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 +31 -0
  34. package/dist/components/inputs/input/index.d.ts +84 -0
  35. package/dist/components/inputs/input/index.js +19 -0
  36. package/dist/components/inputs/input-copy/index.d.ts +44 -0
  37. package/dist/components/inputs/input-copy/index.js +16 -0
  38. package/dist/components/inputs/input-message/index.d.ts +125 -0
  39. package/dist/components/inputs/input-message/index.js +25 -0
  40. package/dist/components/inputs/radio-group/index.d.ts +58 -0
  41. package/dist/components/inputs/radio-group/index.js +20 -0
  42. package/dist/components/inputs/search/index.d.ts +83 -0
  43. package/dist/components/inputs/search/index.js +25 -0
  44. package/dist/components/inputs/select/index.d.ts +105 -0
  45. package/dist/components/inputs/select/index.js +34 -0
  46. package/dist/components/inputs/slider/index.d.ts +108 -0
  47. package/dist/components/inputs/slider/index.js +14 -0
  48. package/dist/components/inputs/switch/index.d.ts +43 -0
  49. package/dist/components/inputs/switch/index.js +14 -0
  50. package/dist/components/navigation/accordion/index.d.ts +117 -0
  51. package/dist/components/navigation/accordion/index.js +28 -0
  52. package/dist/components/navigation/sidebar/index.d.ts +388 -0
  53. package/dist/components/navigation/sidebar/index.js +99 -0
  54. package/dist/components/navigation/tabs/index.d.ts +70 -0
  55. package/dist/components/navigation/tabs/index.js +23 -0
  56. package/dist/components/navigation/tabs-subtle/index.d.ts +73 -0
  57. package/dist/components/navigation/tabs-subtle/index.js +21 -0
  58. package/dist/components/overlays/alert-dialog/index.d.ts +67 -0
  59. package/dist/components/overlays/alert-dialog/index.js +22 -0
  60. package/dist/components/overlays/command/index.d.ts +121 -0
  61. package/dist/components/overlays/command/index.js +36 -0
  62. package/dist/components/overlays/context-menu/index.d.ts +97 -0
  63. package/dist/components/overlays/context-menu/index.js +29 -0
  64. package/dist/components/overlays/dialog/index.d.ts +130 -0
  65. package/dist/components/overlays/dialog/index.js +37 -0
  66. package/dist/components/overlays/dropdown/index.d.ts +222 -0
  67. package/dist/components/overlays/dropdown/index.js +44 -0
  68. package/dist/components/overlays/popover/index.d.ts +87 -0
  69. package/dist/components/overlays/popover/index.js +26 -0
  70. package/dist/components/overlays/preview-card/index.d.ts +75 -0
  71. package/dist/components/overlays/preview-card/index.js +19 -0
  72. package/dist/components/overlays/sheet/index.d.ts +67 -0
  73. package/dist/components/overlays/sheet/index.js +24 -0
  74. package/dist/components/overlays/toast/index.d.ts +107 -0
  75. package/dist/components/overlays/toast/index.js +21 -0
  76. package/dist/components/overlays/tooltip/index.d.ts +75 -0
  77. package/dist/components/overlays/tooltip/index.js +17 -0
  78. package/dist/components/table/index.d.ts +44 -0
  79. package/dist/components/table/index.js +26 -0
  80. package/dist/components/thinking-indicator/index.d.ts +32 -0
  81. package/dist/components/thinking-indicator/index.js +13 -0
  82. package/dist/index.d.ts +3926 -0
  83. package/dist/index.js +511 -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 +11 -0
  88. package/dist/primitives/craft/index.d.ts +31 -0
  89. package/dist/primitives/craft/index.js +11 -0
  90. package/dist/primitives/fluid-hover/index.d.ts +233 -0
  91. package/dist/primitives/fluid-hover/index.js +25 -0
  92. package/dist/primitives/morph/index.d.ts +127 -0
  93. package/dist/primitives/morph/index.js +19 -0
  94. package/dist/primitives/motion/index.d.ts +115 -0
  95. package/dist/primitives/motion/index.js +19 -0
  96. package/dist/primitives/scroll-area/index.d.ts +41 -0
  97. package/dist/primitives/scroll-area/index.js +12 -0
  98. package/dist/primitives/sizes/index.d.ts +128 -0
  99. package/dist/primitives/sizes/index.js +21 -0
  100. package/dist/primitives/surface/index.d.ts +69 -0
  101. package/dist/primitives/surface/index.js +17 -0
  102. package/dist/shared/components-0ke6xada.js +123 -0
  103. package/dist/shared/components-0q0sqfh4.js +146 -0
  104. package/dist/shared/components-0sn7ypjw.js +61 -0
  105. package/dist/shared/components-1j9791sn.js +345 -0
  106. package/dist/shared/components-1rfwbyyc.js +361 -0
  107. package/dist/shared/components-1v7rxytx.js +30 -0
  108. package/dist/shared/components-1xekx2hx.js +215 -0
  109. package/dist/shared/components-39jq9va1.js +86 -0
  110. package/dist/shared/components-3gae8nta.js +719 -0
  111. package/dist/shared/components-3k8xpnpq.js +1759 -0
  112. package/dist/shared/components-3ky44908.js +9 -0
  113. package/dist/shared/components-3mkepka5.js +111 -0
  114. package/dist/shared/components-3wk0w46f.js +667 -0
  115. package/dist/shared/components-4cnjmgex.js +124 -0
  116. package/dist/shared/components-59efxjd9.js +298 -0
  117. package/dist/shared/components-5xc2j8jz.js +159 -0
  118. package/dist/shared/components-62ybc7t2.js +496 -0
  119. package/dist/shared/components-66mv71kx.js +262 -0
  120. package/dist/shared/components-7ans7ce5.js +120 -0
  121. package/dist/shared/components-7btqt08d.js +270 -0
  122. package/dist/shared/components-7r3etddy.js +171 -0
  123. package/dist/shared/components-7x9kawxv.js +152 -0
  124. package/dist/shared/components-8fpr3s4p.js +292 -0
  125. package/dist/shared/components-9jvzzvt1.js +198 -0
  126. package/dist/shared/components-apdwtweq.js +484 -0
  127. package/dist/shared/components-asr5pg50.js +191 -0
  128. package/dist/shared/components-b2wyq2cq.js +232 -0
  129. package/dist/shared/components-c6s6b43g.js +15 -0
  130. package/dist/shared/components-ca2c898n.js +1828 -0
  131. package/dist/shared/components-cbxjn9p8.js +141 -0
  132. package/dist/shared/components-chacnk61.js +216 -0
  133. package/dist/shared/components-cv16mryv.js +62 -0
  134. package/dist/shared/components-ez65vtbq.js +110 -0
  135. package/dist/shared/components-ezxhrmer.js +17 -0
  136. package/dist/shared/components-gc5vtq2f.js +149 -0
  137. package/dist/shared/components-gf5s6ap9.js +42 -0
  138. package/dist/shared/components-gvr9w41t.js +193 -0
  139. package/dist/shared/components-h2dpcwgc.js +137 -0
  140. package/dist/shared/components-hawvy2qz.js +105 -0
  141. package/dist/shared/components-hqeq3w9q.js +375 -0
  142. package/dist/shared/components-jjw69c4c.js +28 -0
  143. package/dist/shared/components-jwst3vtj.js +346 -0
  144. package/dist/shared/components-kvr7f9hy.js +45 -0
  145. package/dist/shared/components-men63rwj.js +9 -0
  146. package/dist/shared/components-mhd39z7x.js +22 -0
  147. package/dist/shared/components-n7mjr357.js +26 -0
  148. package/dist/shared/components-ng72k97e.js +128 -0
  149. package/dist/shared/components-nh8tma1n.js +986 -0
  150. package/dist/shared/components-njzgqdwy.js +445 -0
  151. package/dist/shared/components-ny774h8p.js +293 -0
  152. package/dist/shared/components-q4daerx0.js +58 -0
  153. package/dist/shared/components-q5xj5c16.js +79 -0
  154. package/dist/shared/components-rr7a6ja9.js +160 -0
  155. package/dist/shared/components-s2bz1xpk.js +63 -0
  156. package/dist/shared/components-tqvarbfv.js +288 -0
  157. package/dist/shared/components-v6xp325t.js +304 -0
  158. package/dist/shared/components-v7wtz8hk.js +144 -0
  159. package/dist/shared/components-vc7vq5nz.js +32 -0
  160. package/dist/shared/components-vfbhxf5r.js +58 -0
  161. package/dist/shared/components-vynjtrk6.js +19 -0
  162. package/dist/shared/components-wvp1m52g.js +1200 -0
  163. package/dist/shared/components-yh3kwdhr.js +981 -0
  164. package/dist/shared/components-ytb2tefr.js +291 -0
  165. package/dist/shared/components-zfnmn5d4.js +220 -0
  166. package/dist/shared/components-zrkzcayz.js +141 -0
  167. package/dist/shared/components-zx6b6yby.js +42 -0
  168. package/dist/styles.css +1949 -0
  169. package/dist/tailwind.css +219 -0
  170. package/dist/tokens.css +345 -0
  171. package/package.json +103 -4
@@ -0,0 +1,986 @@
1
+ import {
2
+ opensInPlace,
3
+ inPlaceOffset,
4
+ useMorphOrigin,
5
+ useMorph
6
+ } from "./components-hqeq3w9q.js";
7
+ import {
8
+ cn2
9
+ } from "./components-ezxhrmer.js";
10
+ import {
11
+ FluidHoverHighlight2
12
+ } from "./components-kvr7f9hy.js";
13
+ import {
14
+ MorphSurface
15
+ } from "./components-0q0sqfh4.js";
16
+ import {
17
+ shapeMap
18
+ } from "./components-cv16mryv.js";
19
+ import {
20
+ useSize2
21
+ } from "./components-0sn7ypjw.js";
22
+ import {
23
+ SURFACE_BG,
24
+ SURFACE_SHADOW,
25
+ useSurface2,
26
+ SurfaceProvider2
27
+ } from "./components-zx6b6yby.js";
28
+ import {
29
+ useControllableState
30
+ } from "./components-n7mjr357.js";
31
+ import {
32
+ useFluidHover2,
33
+ useRegisterFluidHoverItem2
34
+ } from "./components-59efxjd9.js";
35
+ import {
36
+ useSelectionRuns,
37
+ useMergeSplitBlocks,
38
+ SelectionBackgrounds
39
+ } from "./components-5xc2j8jz.js";
40
+ import {
41
+ ScrollArea2
42
+ } from "./components-hawvy2qz.js";
43
+ import {
44
+ SizeProvider2
45
+ } from "./components-jjw69c4c.js";
46
+ import {
47
+ Elevated2
48
+ } from "./components-vc7vq5nz.js";
49
+ import {
50
+ useIcon
51
+ } from "./components-zrkzcayz.js";
52
+ import {
53
+ popupScrollAreaClass,
54
+ popupViewportClass,
55
+ isDisabledRow
56
+ } from "./components-vynjtrk6.js";
57
+ import {
58
+ spring2
59
+ } from "./components-1v7rxytx.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 DropdownSearch2 = 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 = useSize2();
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 = useSurface2();
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: cn2("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: cn2("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
+ DropdownSearch2.displayName = "DropdownSearch";
272
+ var DropdownEmpty2 = forwardRef(({ className, ...props }, ref) => {
273
+ const sizeClasses = useSize2();
274
+ return /* @__PURE__ */ jsx("div", {
275
+ ref,
276
+ role: "status",
277
+ "aria-live": "polite",
278
+ className: cn2("px-2 py-6 text-center text-muted-foreground", sizeClasses.text, className),
279
+ ...props
280
+ });
281
+ });
282
+ DropdownEmpty2.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 useDropdown2() {
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 useDropdownMaybe2() {
303
+ return useContext2(DropdownContext);
304
+ }
305
+ var MenuItem2 = 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
+ } = useDropdown2();
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
+ useRegisterFluidHoverItem2(registerItem, index, internalRef);
322
+ useEffect2(() => {
323
+ hasMounted.current = true;
324
+ }, []);
325
+ const isActive = activeIndex === index;
326
+ const skipAnimation = !hasMounted.current;
327
+ const sizeClasses = useSize2();
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 = cn2(`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: cn2("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: cn2("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: cn2("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: spring2.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
+ MenuItem2.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 === DropdownSearch2 && 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 === DropdownEmpty2) {
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 Dropdown2 = 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 = useFluidHover2(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(Elevated2, {
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: cn2(`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: spring2.moderate.exit },
652
+ transition: {
653
+ ...spring2.moderate,
654
+ opacity: { duration: spring2.fast.duration }
655
+ }
656
+ })
657
+ }),
658
+ /* @__PURE__ */ jsx3(FluidHoverHighlight2, {
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: spring2.fast.exit },
674
+ transition: {
675
+ ...spring2.fast,
676
+ opacity: { duration: spring2.fast.duration }
677
+ }
678
+ })
679
+ }),
680
+ rows.content
681
+ ]
682
+ })
683
+ })
684
+ });
685
+ return size ? /* @__PURE__ */ jsx3(SizeProvider2, {
686
+ size,
687
+ children: panel
688
+ }) : panel;
689
+ });
690
+ Dropdown2.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 DropdownMenu2({
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(SizeProvider2, {
728
+ size,
729
+ children: root
730
+ }) : root;
731
+ }
732
+ DropdownMenu2.displayName = "DropdownMenu";
733
+ var DropdownTrigger2 = Menu.Trigger;
734
+ var DropdownContent2 = 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(useSurface2() + 2, 8);
755
+ const containerRef = useRef3(null);
756
+ const hover = useFluidHover2(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
816
+ }) => checkbox ? /* @__PURE__ */ jsx3(Menu.CheckboxItem, {
817
+ checked: !!checked,
818
+ disabled,
819
+ label,
820
+ closeOnClick,
821
+ onClick,
822
+ render: element,
823
+ children
824
+ }) : radio ? /* @__PURE__ */ jsx3(Menu.RadioItem, {
825
+ value,
826
+ disabled,
827
+ label,
828
+ closeOnClick,
829
+ onClick,
830
+ render: element,
831
+ children
832
+ }) : /* @__PURE__ */ jsx3(Menu.Item, {
833
+ disabled,
834
+ label,
835
+ closeOnClick,
836
+ onClick,
837
+ render: element,
838
+ children
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(SurfaceProvider2, {
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: cn2(`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(ScrollArea2, {
908
+ className: popupScrollAreaClass,
909
+ viewportClassName: cn2(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: spring2.moderate.exit },
929
+ transition: {
930
+ ...spring2.moderate,
931
+ opacity: { duration: spring2.fast.duration }
932
+ }
933
+ })
934
+ }),
935
+ /* @__PURE__ */ jsx3(FluidHoverHighlight2, {
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
+ DropdownContent2.displayName = "DropdownContent";
958
+ var DropdownLabel2 = forwardRef3(({ className, ...props }, ref) => {
959
+ const compact = useSize2().variant === "compact";
960
+ return /* @__PURE__ */ jsx3("div", {
961
+ ref,
962
+ className: cn2("px-2 py-1.5 shrink-0 text-muted-foreground", compact ? "text-caption-compact" : "text-caption", className),
963
+ ...props
964
+ });
965
+ });
966
+ DropdownLabel2.displayName = "DropdownLabel";
967
+ var DropdownSeparator2 = forwardRef3(({ className, ...props }, ref) => /* @__PURE__ */ jsx3("div", {
968
+ ref,
969
+ role: "separator",
970
+ className: cn2("my-1 -mx-1 h-px shrink-0 bg-border/60", className),
971
+ ...props
972
+ }));
973
+ DropdownSeparator2.displayName = "DropdownSeparator";
974
+ Object.assign(Dropdown2, {
975
+ Menu: DropdownMenu2,
976
+ Trigger: DropdownTrigger2,
977
+ Content: DropdownContent2,
978
+ Item: MenuItem2,
979
+ Label: DropdownLabel2,
980
+ Separator: DropdownSeparator2,
981
+ Search: DropdownSearch2,
982
+ Empty: DropdownEmpty2
983
+ });
984
+ var dropdown_default = Dropdown2;
985
+
986
+ export { DropdownSearch2, DropdownEmpty2, DropdownContext, useDropdown2, useDropdownMaybe2, MenuItem2, Dropdown2, DropdownMenu2, DropdownTrigger2, DropdownContent2, DropdownLabel2, DropdownSeparator2, dropdown_default };