@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,719 @@
1
+ import {
2
+ fieldVariants,
3
+ fieldIconClasses
4
+ } from "./components-mhd39z7x.js";
5
+ import {
6
+ opensInPlace,
7
+ inPlaceOffset,
8
+ useMorphOrigin,
9
+ useMorph
10
+ } from "./components-hqeq3w9q.js";
11
+ import {
12
+ cn2
13
+ } from "./components-ezxhrmer.js";
14
+ import {
15
+ FluidHoverHighlight2
16
+ } from "./components-kvr7f9hy.js";
17
+ import {
18
+ useIcon
19
+ } from "./components-zrkzcayz.js";
20
+ import {
21
+ MorphSurface
22
+ } from "./components-0q0sqfh4.js";
23
+ import {
24
+ shapeMap,
25
+ useShape
26
+ } from "./components-cv16mryv.js";
27
+ import {
28
+ useSize2
29
+ } from "./components-0sn7ypjw.js";
30
+ import {
31
+ SURFACE_BG,
32
+ SURFACE_SHADOW,
33
+ useSurface2,
34
+ SurfaceProvider2
35
+ } from "./components-zx6b6yby.js";
36
+ import {
37
+ useFluidHover2,
38
+ useRegisterFluidHoverItem2
39
+ } from "./components-59efxjd9.js";
40
+ import {
41
+ useSelectionRuns,
42
+ useMergeSplitBlocks,
43
+ SelectionBackgrounds
44
+ } from "./components-5xc2j8jz.js";
45
+ import {
46
+ ScrollArea2
47
+ } from "./components-hawvy2qz.js";
48
+ import {
49
+ SizeProvider2
50
+ } from "./components-jjw69c4c.js";
51
+ import {
52
+ popupScrollAreaClass,
53
+ popupViewportClass,
54
+ isDisabledRow
55
+ } from "./components-vynjtrk6.js";
56
+ import {
57
+ spring2
58
+ } from "./components-1v7rxytx.js";
59
+
60
+ // components/inputs/combobox/index.tsx
61
+ import { Combobox as ComboboxPrimitive } from "@base-ui/react/combobox";
62
+ import { AnimatePresence, animate, motion, useMotionValue } from "motion/react";
63
+ import {
64
+ createContext,
65
+ forwardRef,
66
+ useCallback,
67
+ useContext,
68
+ useEffect,
69
+ useImperativeHandle,
70
+ useMemo,
71
+ useRef,
72
+ useState
73
+ } from "react";
74
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
75
+ function itemValue(item) {
76
+ return typeof item === "string" ? item : item.value;
77
+ }
78
+ function itemLabel(item) {
79
+ return typeof item === "string" ? item : item.label;
80
+ }
81
+ var CREATE_VALUE = "\x00create";
82
+ function isCreateItem(item) {
83
+ return itemValue(item) === CREATE_VALUE;
84
+ }
85
+ function defaultCreateLabel(query) {
86
+ return `Create “${query}”`;
87
+ }
88
+ var ComboboxContext = createContext(null);
89
+ var ComboboxHighlightContext = createContext(null);
90
+ function useComboboxContext() {
91
+ const ctx = useContext(ComboboxContext);
92
+ if (!ctx)
93
+ throw new Error("Combobox compound components must be inside <Combobox>");
94
+ return ctx;
95
+ }
96
+ var ComboboxContentContext = createContext(null);
97
+ var ComboboxItemIndexContext = createContext(0);
98
+ function toValues(v) {
99
+ if (v === undefined)
100
+ return [];
101
+ if (Array.isArray(v))
102
+ return v;
103
+ return v === "" ? [] : [v];
104
+ }
105
+ function Combobox2({
106
+ children,
107
+ items,
108
+ multiple,
109
+ value,
110
+ defaultValue,
111
+ onValueChange,
112
+ filter,
113
+ onCreate,
114
+ createLabel = defaultCreateLabel,
115
+ creatable = false,
116
+ hideSelected = false,
117
+ disabled = false,
118
+ name,
119
+ required,
120
+ size
121
+ }) {
122
+ const isMultiple = !!multiple;
123
+ const [internalValues, setInternalValues] = useState(() => toValues(defaultValue));
124
+ const [inputValue, setInputValue] = useState("");
125
+ const [open, setOpen] = useState(false);
126
+ const [highlight, setHighlight] = useState(null);
127
+ const [createdItems, setCreatedItems] = useState([]);
128
+ const { origin, capture } = useMorphOrigin();
129
+ const anchorRef = useRef(null);
130
+ const controlledValues = useMemo(() => toValues(value), [value]);
131
+ const values = value !== undefined ? controlledValues : internalValues;
132
+ const allItems = useMemo(() => {
133
+ const own = createdItems.filter((made) => !items.some((item) => itemValue(item) === itemValue(made)));
134
+ return own.length ? [...items, ...own] : items;
135
+ }, [items, createdItems]);
136
+ const query = inputValue.trim();
137
+ const canCreate = !!onCreate || creatable;
138
+ const createItem = useMemo(() => {
139
+ if (!canCreate || query === "")
140
+ return null;
141
+ const lower = query.toLocaleLowerCase();
142
+ const exists = allItems.some((item) => itemLabel(item).toLocaleLowerCase() === lower);
143
+ return exists ? null : { value: CREATE_VALUE, label: query };
144
+ }, [canCreate, query, allItems]);
145
+ const itemsByValue = useMemo(() => {
146
+ const map = new Map;
147
+ for (const item of allItems)
148
+ map.set(itemValue(item), item);
149
+ if (createItem)
150
+ map.set(CREATE_VALUE, createItem);
151
+ return map;
152
+ }, [allItems, createItem]);
153
+ const selectedItems = useMemo(() => values.map((v) => itemsByValue.get(v)).filter(Boolean), [values, itemsByValue]);
154
+ const hideChecked = hideSelected && isMultiple;
155
+ const listItems = useMemo(() => {
156
+ const visible = hideChecked ? allItems.filter((item) => !values.includes(itemValue(item))) : allItems;
157
+ return createItem ? [...visible, createItem] : visible;
158
+ }, [allItems, hideChecked, values, createItem]);
159
+ const allSelected = hideChecked && query === "" && allItems.length > 0 && listItems.length === 0;
160
+ const onCreateRef = useRef(onCreate);
161
+ onCreateRef.current = onCreate;
162
+ const handleValueChange = useCallback((next) => {
163
+ const picked = Array.isArray(next) ? next : next == null ? [] : [next];
164
+ const created = picked.find(isCreateItem);
165
+ let nextValues = picked.filter((item) => !isCreateItem(item)).map(itemValue);
166
+ if (created) {
167
+ const madeQuery = itemLabel(created);
168
+ const made = onCreateRef.current?.(madeQuery) ?? undefined;
169
+ if (made !== undefined) {
170
+ nextValues = [...nextValues, itemValue(made)];
171
+ } else if (creatable) {
172
+ const own = { value: madeQuery, label: madeQuery };
173
+ setCreatedItems((prev) => prev.some((item) => itemValue(item) === madeQuery) ? prev : [...prev, own]);
174
+ nextValues = [...nextValues, madeQuery];
175
+ } else if (!isMultiple) {
176
+ return;
177
+ }
178
+ }
179
+ if (value === undefined)
180
+ setInternalValues(nextValues);
181
+ onValueChange?.(isMultiple ? nextValues : nextValues[0] ?? "");
182
+ }, [value, onValueChange, isMultiple, creatable]);
183
+ const { contains } = ComboboxPrimitive.useFilter();
184
+ const filterFn = useMemo(() => {
185
+ if (!filter && !createItem)
186
+ return;
187
+ const match = filter ? (item, q) => filter(item, q) : (item, q) => contains(item, q, itemLabel);
188
+ return (item, q) => isCreateItem(item) || match(item, q);
189
+ }, [filter, createItem, contains]);
190
+ const createRow = createItem ? createLabel(query) : null;
191
+ const ctx = useMemo(() => ({
192
+ values,
193
+ multiple: isMultiple,
194
+ inputValue,
195
+ open,
196
+ origin,
197
+ anchorRef,
198
+ disabled,
199
+ itemsByValue,
200
+ createRow,
201
+ allSelected
202
+ }), [values, isMultiple, inputValue, open, origin, disabled, itemsByValue, createRow, allSelected]);
203
+ const root = /* @__PURE__ */ jsx(ComboboxContext.Provider, {
204
+ value: ctx,
205
+ children: /* @__PURE__ */ jsx(ComboboxHighlightContext.Provider, {
206
+ value: highlight,
207
+ children: /* @__PURE__ */ jsx(ComboboxPrimitive.Root, {
208
+ items: listItems,
209
+ multiple: isMultiple,
210
+ value: isMultiple ? selectedItems : selectedItems[0] ?? null,
211
+ onValueChange: handleValueChange,
212
+ isItemEqualToValue: (a, b) => itemValue(a) === itemValue(b),
213
+ itemToStringLabel: itemLabel,
214
+ itemToStringValue: itemValue,
215
+ filter: filterFn,
216
+ open,
217
+ onOpenChange: (next, details) => {
218
+ if (next)
219
+ capture({ event: details.event, trigger: anchorRef.current ?? undefined });
220
+ setOpen(next);
221
+ },
222
+ onInputValueChange: (next) => setInputValue(next),
223
+ autoHighlight: ALWAYS_HIGHLIGHT,
224
+ onItemHighlighted: (item, details) => setHighlight(item === undefined ? null : { index: details.index, keyboard: details.reason !== "pointer" }),
225
+ disabled,
226
+ name,
227
+ required,
228
+ modal: false,
229
+ children
230
+ })
231
+ })
232
+ });
233
+ return size ? /* @__PURE__ */ jsx(SizeProvider2, {
234
+ size,
235
+ children: root
236
+ }) : root;
237
+ }
238
+ Combobox2.displayName = "Combobox";
239
+ var popupShape = shapeMap.rounded;
240
+ var ALWAYS_HIGHLIGHT = "always";
241
+ var fieldButtonClass = "flex shrink-0 items-center justify-center rounded-md text-muted-foreground outline-none transition-colors duration-fast hover:text-foreground focus-visible:ring-1 focus-visible:ring-focus-ring data-[disabled]:pointer-events-none";
242
+ var clearButtonClass = cn2(fieldButtonClass, "hover:bg-hover active:bg-active transition-[color,background-color]");
243
+ var chipRemoveClass = cn2(fieldButtonClass, "rounded hover:bg-active");
244
+ function FieldControls({ clearable, compact, iconSize }) {
245
+ const XIcon = useIcon("x");
246
+ const pill = useShape().variant === "pill";
247
+ return /* @__PURE__ */ jsxs(Fragment, {
248
+ children: [
249
+ clearable && /* @__PURE__ */ jsx("span", {
250
+ className: cn2("flex shrink-0 items-center justify-center", compact ? "size-5" : "size-6"),
251
+ children: /* @__PURE__ */ jsx(ComboboxPrimitive.Clear, {
252
+ "aria-label": "Clear",
253
+ className: cn2(clearButtonClass, pill && "rounded-full", compact ? "size-5" : "size-6"),
254
+ children: /* @__PURE__ */ jsx(XIcon, {
255
+ size: iconSize,
256
+ strokeWidth: 1.5
257
+ })
258
+ })
259
+ }),
260
+ /* @__PURE__ */ jsx(ComboboxPrimitive.Trigger, {
261
+ "aria-label": "Open",
262
+ tabIndex: -1,
263
+ className: cn2(fieldButtonClass, compact ? "size-5" : "size-6"),
264
+ children: /* @__PURE__ */ jsx("svg", {
265
+ width: iconSize,
266
+ height: iconSize,
267
+ viewBox: "0 0 24 24",
268
+ fill: "none",
269
+ stroke: "currentColor",
270
+ strokeWidth: 2,
271
+ strokeLinecap: "round",
272
+ strokeLinejoin: "round",
273
+ className: "transition-colors duration-fast",
274
+ children: /* @__PURE__ */ jsx("path", {
275
+ d: "M6 9l6 6 6-6"
276
+ })
277
+ })
278
+ })
279
+ ]
280
+ });
281
+ }
282
+ var ComboboxInput2 = forwardRef(({ className, variant, icon: Icon, placeholder = "Search…", error, clearable = false, size, ...props }, ref) => {
283
+ const shape = useShape();
284
+ const sizeClasses = useSize2(size);
285
+ const compact = sizeClasses.variant === "compact";
286
+ const { anchorRef } = useComboboxContext();
287
+ return /* @__PURE__ */ jsxs("div", {
288
+ className: "flex flex-col gap-1",
289
+ children: [
290
+ /* @__PURE__ */ jsxs(ComboboxPrimitive.InputGroup, {
291
+ ref: anchorRef,
292
+ "data-invalid": !!error || undefined,
293
+ className: cn2(fieldVariants({ variant: variant ?? "bordered" }), "flex items-center", sizeClasses.control, sizeClasses.gap, compact ? "px-2" : "px-2.5", compact ? "min-w-[128px]" : "min-w-[160px]", shape.input, className),
294
+ children: [
295
+ Icon && /* @__PURE__ */ jsx(Icon, {
296
+ size: sizeClasses.icon,
297
+ strokeWidth: 1.5,
298
+ className: fieldIconClasses
299
+ }),
300
+ /* @__PURE__ */ jsx(ComboboxPrimitive.Input, {
301
+ ref,
302
+ placeholder,
303
+ "aria-invalid": !!error || undefined,
304
+ 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"),
305
+ ...props
306
+ }),
307
+ /* @__PURE__ */ jsx(FieldControls, {
308
+ clearable,
309
+ compact,
310
+ iconSize: sizeClasses.icon
311
+ })
312
+ ]
313
+ }),
314
+ error && /* @__PURE__ */ jsx("span", {
315
+ className: "text-caption text-destructive pl-3",
316
+ children: error
317
+ })
318
+ ]
319
+ });
320
+ });
321
+ ComboboxInput2.displayName = "ComboboxInput";
322
+ function useChipRowHeight(padY) {
323
+ const height = useMotionValue("auto");
324
+ const roRef = useRef(null);
325
+ const padRef = useRef(padY);
326
+ padRef.current = padY;
327
+ const ref = useCallback((el) => {
328
+ roRef.current?.disconnect();
329
+ roRef.current = null;
330
+ if (!el)
331
+ return;
332
+ const measure = () => {
333
+ if (el.offsetHeight <= 0)
334
+ return;
335
+ const target = el.offsetHeight + padRef.current;
336
+ if (height.get() === "auto")
337
+ height.set(target);
338
+ else if (height.get() !== target)
339
+ animate(height, target, spring2.fast);
340
+ };
341
+ measure();
342
+ const ro = new ResizeObserver(measure);
343
+ ro.observe(el);
344
+ roRef.current = ro;
345
+ }, [height]);
346
+ return { ref, height };
347
+ }
348
+ var ComboboxChips2 = forwardRef(({ className, variant, icon: Icon, placeholder = "Search…", error, clearable = false, size, ...props }, ref) => {
349
+ const XIcon = useIcon("x");
350
+ const shape = useShape();
351
+ const sizeClasses = useSize2(size);
352
+ const compact = sizeClasses.variant === "compact";
353
+ const { anchorRef, open, disabled, inputValue, values } = useComboboxContext();
354
+ const rowHeight = useChipRowHeight(compact ? 8 : 12);
355
+ return /* @__PURE__ */ jsxs("div", {
356
+ className: "flex flex-col gap-1",
357
+ children: [
358
+ /* @__PURE__ */ jsxs(ComboboxPrimitive.Chips, {
359
+ ref: anchorRef,
360
+ render: /* @__PURE__ */ jsx(motion.div, {
361
+ style: { height: rowHeight.height }
362
+ }),
363
+ "data-disabled": disabled || undefined,
364
+ "data-invalid": !!error || undefined,
365
+ "data-popup-open": open || undefined,
366
+ className: cn2(fieldVariants({ variant: variant ?? "bordered" }), "flex items-center", "transition-[color,background-color,border-radius,box-shadow,opacity]", "!items-start", compact ? "min-h-7 py-1" : "min-h-9 py-1.5", sizeClasses.gap, compact ? "px-2" : "px-2.5", compact ? "min-w-[128px]" : "min-w-[160px]", shape.input, className),
367
+ children: [
368
+ Icon && /* @__PURE__ */ jsx("span", {
369
+ className: cn2("flex shrink-0 items-center", compact ? "h-5" : "h-6"),
370
+ children: /* @__PURE__ */ jsx(Icon, {
371
+ size: sizeClasses.icon,
372
+ strokeWidth: 1.5,
373
+ className: fieldIconClasses
374
+ })
375
+ }),
376
+ /* @__PURE__ */ jsx("div", {
377
+ ref: rowHeight.ref,
378
+ className: cn2("relative flex min-w-0 flex-1 flex-wrap items-center gap-1", !Icon && values.length > 0 && "-ml-1"),
379
+ children: /* @__PURE__ */ jsx(ComboboxPrimitive.Value, {
380
+ children: (selected) => /* @__PURE__ */ jsxs(Fragment, {
381
+ children: [
382
+ /* @__PURE__ */ jsx(AnimatePresence, {
383
+ initial: false,
384
+ mode: "popLayout",
385
+ children: (selected ?? []).map((item) => {
386
+ const label = itemLabel(item);
387
+ return /* @__PURE__ */ jsx(motion.span, {
388
+ layout: true,
389
+ initial: { opacity: 0, scale: 0.9 },
390
+ animate: { opacity: 1, scale: 1 },
391
+ exit: {
392
+ opacity: 0,
393
+ scale: 0.9,
394
+ pointerEvents: "none",
395
+ transition: spring2.fast.exit
396
+ },
397
+ transition: spring2.fast,
398
+ style: { originX: 0 },
399
+ className: "inline-flex max-w-full shrink-0",
400
+ children: /* @__PURE__ */ jsxs(ComboboxPrimitive.Chip, {
401
+ "aria-label": label,
402
+ className: cn2("inline-flex max-w-full shrink-0 items-center gap-0.5 bg-hover pl-2 pr-0.5 text-foreground outline-none", shape.variant === "pill" ? "rounded-full" : "rounded-md", "focus-visible:ring-1 focus-visible:ring-focus-ring", compact ? "h-5 text-caption-compact" : "h-6 text-caption"),
403
+ children: [
404
+ /* @__PURE__ */ jsx("span", {
405
+ className: "truncate",
406
+ children: label
407
+ }),
408
+ /* @__PURE__ */ jsx(ComboboxPrimitive.ChipRemove, {
409
+ "aria-label": `Remove ${label}`,
410
+ className: cn2(chipRemoveClass, shape.variant === "pill" && "rounded-full", compact ? "size-4" : "size-5"),
411
+ children: /* @__PURE__ */ jsx(XIcon, {
412
+ size: compact ? 10 : 12,
413
+ strokeWidth: 2
414
+ })
415
+ })
416
+ ]
417
+ })
418
+ }, itemValue(item));
419
+ })
420
+ }),
421
+ /* @__PURE__ */ jsx("span", {
422
+ className: "flex min-w-6 flex-auto",
423
+ children: /* @__PURE__ */ jsx(ComboboxPrimitive.Input, {
424
+ ref,
425
+ size: Math.max(1, inputValue.length + 1),
426
+ placeholder: selected?.length ? undefined : placeholder,
427
+ "aria-invalid": !!error || undefined,
428
+ className: cn2("w-full min-w-0 rounded-none bg-transparent text-foreground placeholder:text-muted-foreground outline-none font-[inherit]", compact ? "h-5 leading-5" : "h-6 leading-6", sizeClasses.text),
429
+ ...props
430
+ })
431
+ })
432
+ ]
433
+ })
434
+ })
435
+ }),
436
+ /* @__PURE__ */ jsx(FieldControls, {
437
+ clearable,
438
+ compact,
439
+ iconSize: sizeClasses.icon
440
+ })
441
+ ]
442
+ }),
443
+ error && /* @__PURE__ */ jsx("span", {
444
+ className: "text-caption text-destructive pl-3",
445
+ children: error
446
+ })
447
+ ]
448
+ });
449
+ });
450
+ ComboboxChips2.displayName = "ComboboxChips";
451
+ var ComboboxContent2 = forwardRef(({
452
+ className,
453
+ children,
454
+ side = "bottom",
455
+ align = "start",
456
+ sideOffset = 6,
457
+ from,
458
+ effect,
459
+ hideSource,
460
+ tier = "moderate"
461
+ }, ref) => {
462
+ const { open, origin, anchorRef } = useComboboxContext();
463
+ const morph = useMorph(open, origin, { from, effect, hideSource, tier });
464
+ useImperativeHandle(ref, () => morph.popup, [morph.popup]);
465
+ const level = Math.min(useSurface2() + 2, 8);
466
+ const shape = popupShape;
467
+ return /* @__PURE__ */ jsx(ComboboxPrimitive.Portal, {
468
+ children: /* @__PURE__ */ jsx(ComboboxPrimitive.Positioner, {
469
+ anchor: anchorRef,
470
+ side,
471
+ align,
472
+ sideOffset: opensInPlace({ effect, hideSource }) ? inPlaceOffset : sideOffset,
473
+ className: "z-50 outline-none",
474
+ children: /* @__PURE__ */ jsx(ComboboxPrimitive.Popup, {
475
+ ref: morph.popupRef,
476
+ className: "relative select-none outline-none",
477
+ children: /* @__PURE__ */ jsx(SurfaceProvider2, {
478
+ value: level,
479
+ children: /* @__PURE__ */ jsx(MorphSurface, {
480
+ morph,
481
+ bg: SURFACE_BG[level],
482
+ shadow: SURFACE_SHADOW[3],
483
+ radius: shape.container,
484
+ className: cn2(`flex flex-col min-w-[var(--anchor-width)] max-h-[min(300px,var(--available-height))] overflow-hidden ${shape.container}`, className),
485
+ children
486
+ })
487
+ })
488
+ })
489
+ })
490
+ });
491
+ });
492
+ ComboboxContent2.displayName = "ComboboxContent";
493
+ var ComboboxList2 = forwardRef(({ className, children }, ref) => {
494
+ const { open, values, multiple, inputValue, createRow } = useComboboxContext();
495
+ const highlight = useContext(ComboboxHighlightContext);
496
+ const PlusIcon = useIcon("plus");
497
+ const shape = popupShape;
498
+ const containerRef = useRef(null);
499
+ const hover = useFluidHover2(containerRef, { isItemDisabled: isDisabledRow });
500
+ const { activeIndex, setActiveIndex, itemRects, isMeasured, handlers, registerItem, remeasure } = hover;
501
+ const [checkedIndices, setCheckedIndices] = useState([]);
502
+ useEffect(() => {
503
+ if (!open)
504
+ return;
505
+ remeasure();
506
+ }, [open, remeasure]);
507
+ const reflowRef = useRef(false);
508
+ const prevQueryRef = useRef(inputValue);
509
+ const armedRectsRef = useRef(itemRects);
510
+ if (prevQueryRef.current !== inputValue) {
511
+ prevQueryRef.current = inputValue;
512
+ armedRectsRef.current = itemRects;
513
+ reflowRef.current = true;
514
+ }
515
+ const reflowSnap = reflowRef.current;
516
+ useEffect(() => {
517
+ if (reflowRef.current && itemRects !== armedRectsRef.current)
518
+ reflowRef.current = false;
519
+ });
520
+ useEffect(() => {
521
+ if (!open)
522
+ return;
523
+ let inner;
524
+ const outer = requestAnimationFrame(() => {
525
+ inner = requestAnimationFrame(() => {
526
+ const container = containerRef.current;
527
+ if (container) {
528
+ const rows = Array.from(container.querySelectorAll("[data-fluid-hover-index]"));
529
+ const next = [];
530
+ rows.forEach((el, i) => {
531
+ if (values.includes(el.getAttribute("data-value") ?? ""))
532
+ next.push(i);
533
+ });
534
+ setCheckedIndices(next);
535
+ }
536
+ });
537
+ });
538
+ return () => {
539
+ cancelAnimationFrame(outer);
540
+ cancelAnimationFrame(inner);
541
+ };
542
+ }, [open, values, inputValue]);
543
+ useEffect(() => {
544
+ if (!highlight)
545
+ setActiveIndex(null);
546
+ else if (highlight.keyboard)
547
+ setActiveIndex(highlight.index);
548
+ }, [highlight, setActiveIndex]);
549
+ useEffect(() => {
550
+ if (open)
551
+ return;
552
+ setCheckedIndices([]);
553
+ setActiveIndex(null);
554
+ }, [open, setActiveIndex]);
555
+ const firstChecked = checkedIndices[0];
556
+ const checkedRect = isMeasured && !multiple && firstChecked !== undefined ? itemRects[firstChecked] ?? null : null;
557
+ const runs = useSelectionRuns(multiple ? checkedIndices : []);
558
+ const blocks = useMergeSplitBlocks(runs, isMeasured && open ? itemRects : [], shape.bgRadius);
559
+ const contentCtx = useMemo(() => ({ registerItem, activeIndex }), [registerItem, activeIndex]);
560
+ return /* @__PURE__ */ jsx(ComboboxContentContext.Provider, {
561
+ value: contentCtx,
562
+ children: /* @__PURE__ */ jsx(ScrollArea2, {
563
+ className: popupScrollAreaClass,
564
+ viewportClassName: cn2(popupViewportClass, "scroll-fade"),
565
+ children: /* @__PURE__ */ jsxs(ComboboxPrimitive.List, {
566
+ ref: (node) => {
567
+ containerRef.current = node;
568
+ if (typeof ref === "function")
569
+ ref(node);
570
+ else if (ref)
571
+ ref.current = node;
572
+ },
573
+ onMouseEnter: handlers.onMouseEnter,
574
+ onMouseMove: handlers.onMouseMove,
575
+ onMouseLeave: handlers.onMouseLeave,
576
+ onClick: handlers.onClick,
577
+ className: cn2("relative flex flex-col p-1 outline-none data-[empty]:p-0", className),
578
+ children: [
579
+ open && multiple && /* @__PURE__ */ jsx(SelectionBackgrounds, {
580
+ blocks: reflowSnap ? blocks.map((b) => ({ ...b, instant: true })) : blocks
581
+ }),
582
+ open && !multiple && /* @__PURE__ */ jsx(AnimatePresence, {
583
+ children: checkedRect && /* @__PURE__ */ jsx(motion.div, {
584
+ "aria-hidden": true,
585
+ className: `absolute ${shape.bg} bg-active pointer-events-none`,
586
+ initial: false,
587
+ animate: {
588
+ top: checkedRect.top,
589
+ left: checkedRect.left,
590
+ width: checkedRect.width,
591
+ height: checkedRect.height,
592
+ opacity: 1
593
+ },
594
+ exit: { opacity: 0, transition: spring2.moderate.exit },
595
+ transition: reflowSnap ? { duration: 0 } : { ...spring2.moderate, opacity: { duration: spring2.fast.duration } }
596
+ }, "checked")
597
+ }),
598
+ open && /* @__PURE__ */ jsx(FluidHoverHighlight2, {
599
+ hover,
600
+ className: shape.bg,
601
+ transition: reflowSnap ? false : undefined
602
+ }),
603
+ /* @__PURE__ */ jsx(ComboboxPrimitive.Collection, {
604
+ children: (item, index) => /* @__PURE__ */ jsx(ComboboxItemIndexContext.Provider, {
605
+ value: index,
606
+ children: isCreateItem(item) ? /* @__PURE__ */ jsx(ComboboxItem2, {
607
+ value: CREATE_VALUE,
608
+ icon: PlusIcon,
609
+ children: createRow
610
+ }) : children(item, index)
611
+ }, itemValue(item))
612
+ })
613
+ ]
614
+ })
615
+ })
616
+ });
617
+ });
618
+ ComboboxList2.displayName = "ComboboxList";
619
+ var ComboboxItem2 = forwardRef(({ className, children, icon: Icon, value, disabled = false, ...props }, ref) => {
620
+ const comboboxCtx = useComboboxContext();
621
+ const contentCtx = useContext(ComboboxContentContext);
622
+ const index = useContext(ComboboxItemIndexContext);
623
+ const internalRef = useRef(null);
624
+ const shape = popupShape;
625
+ const sizeClasses = useSize2();
626
+ const compact = sizeClasses.variant === "compact";
627
+ const hasMounted = useRef(false);
628
+ useEffect(() => {
629
+ hasMounted.current = true;
630
+ }, []);
631
+ const registerItem = contentCtx?.registerItem;
632
+ useRegisterFluidHoverItem2(registerItem, index, internalRef);
633
+ const isActive = contentCtx?.activeIndex === index;
634
+ const isChecked = comboboxCtx.values.includes(value);
635
+ const skipAnimation = !hasMounted.current;
636
+ const item = comboboxCtx.itemsByValue.get(value) ?? value;
637
+ return /* @__PURE__ */ jsxs(ComboboxPrimitive.Item, {
638
+ value: item,
639
+ index,
640
+ disabled,
641
+ render: /* @__PURE__ */ jsx("div", {
642
+ ref: (node) => {
643
+ internalRef.current = node;
644
+ if (typeof ref === "function")
645
+ ref(node);
646
+ else if (ref)
647
+ ref.current = node;
648
+ },
649
+ "data-fluid-hover-index": index,
650
+ "data-value": value,
651
+ className: cn2(`relative z-10 flex ${sizeClasses.control} shrink-0 items-center ${sizeClasses.gap} ${shape.item} ${sizeClasses.itemPx} ${sizeClasses.text} cursor-pointer outline-none select-none`, "transition-[color] duration-fast", isActive || isChecked ? "text-foreground" : "text-muted-foreground", disabled && "opacity-50 pointer-events-none", className),
652
+ ...props
653
+ }),
654
+ children: [
655
+ Icon && /* @__PURE__ */ jsx(Icon, {
656
+ size: sizeClasses.icon,
657
+ strokeWidth: isActive || isChecked ? 2 : 1.5,
658
+ className: "shrink-0 transition-[color,stroke-width] duration-fast"
659
+ }),
660
+ /* @__PURE__ */ jsx("span", {
661
+ className: "flex-1 min-w-0 truncate [text-box:trim-both_cap_alphabetic] py-1 -my-1",
662
+ children
663
+ }),
664
+ /* @__PURE__ */ jsx("span", {
665
+ "aria-hidden": true,
666
+ className: cn2("shrink-0", compact ? "w-3.5 h-3.5" : "w-4 h-4"),
667
+ children: /* @__PURE__ */ jsx(AnimatePresence, {
668
+ children: isChecked && /* @__PURE__ */ jsx(motion.svg, {
669
+ width: sizeClasses.icon,
670
+ height: sizeClasses.icon,
671
+ viewBox: "0 0 24 24",
672
+ fill: "none",
673
+ stroke: "currentColor",
674
+ strokeWidth: 2,
675
+ strokeLinecap: "round",
676
+ strokeLinejoin: "round",
677
+ className: "text-foreground",
678
+ initial: { opacity: 1 },
679
+ animate: { opacity: 1 },
680
+ exit: { opacity: 1 },
681
+ children: /* @__PURE__ */ jsx(motion.path, {
682
+ d: "M4 12L9 17L20 6",
683
+ initial: { pathLength: skipAnimation ? 1 : 0 },
684
+ animate: {
685
+ pathLength: 1,
686
+ transition: { duration: spring2.fast.duration, ease: "easeOut" }
687
+ },
688
+ exit: {
689
+ pathLength: 0,
690
+ transition: { duration: 0.04, ease: "easeIn" }
691
+ }
692
+ })
693
+ }, "check")
694
+ })
695
+ })
696
+ ]
697
+ });
698
+ });
699
+ ComboboxItem2.displayName = "ComboboxItem";
700
+ var ComboboxEmpty2 = forwardRef(({ className, children, allSelected, ...props }, ref) => {
701
+ const sizeClasses = useSize2();
702
+ const ctx = useComboboxContext();
703
+ return /* @__PURE__ */ jsx(ComboboxPrimitive.Empty, {
704
+ ref,
705
+ className: cn2("px-3 text-center text-muted-foreground [&:not(:empty)]:py-6", sizeClasses.text, className),
706
+ ...props,
707
+ children: ctx.allSelected && allSelected !== undefined ? allSelected : children
708
+ });
709
+ });
710
+ ComboboxEmpty2.displayName = "ComboboxEmpty";
711
+ Combobox2.Input = ComboboxInput2;
712
+ Combobox2.Chips = ComboboxChips2;
713
+ Combobox2.Content = ComboboxContent2;
714
+ Combobox2.List = ComboboxList2;
715
+ Combobox2.Item = ComboboxItem2;
716
+ Combobox2.Empty = ComboboxEmpty2;
717
+ var combobox_default = Combobox2;
718
+
719
+ export { Combobox2, ComboboxInput2, ComboboxChips2, ComboboxContent2, ComboboxList2, ComboboxItem2, ComboboxEmpty2, combobox_default };