@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,719 @@
1
+ import {
2
+ fieldIconClasses,
3
+ fieldVariants
4
+ } from "./components-de8xsm9y.js";
5
+ import {
6
+ SelectionBackgrounds,
7
+ useMergeSplitBlocks,
8
+ useSelectionRuns
9
+ } from "./components-rc63qsy6.js";
10
+ import {
11
+ SizeProvider
12
+ } from "./components-vb033rns.js";
13
+ import {
14
+ useIcon
15
+ } from "./components-m5br529r.js";
16
+ import {
17
+ isDisabledRow,
18
+ popupScrollAreaClass,
19
+ popupViewportClass
20
+ } from "./components-jw16snbn.js";
21
+ import {
22
+ ScrollArea
23
+ } from "./components-ed7cmssr.js";
24
+ import {
25
+ SURFACE_BG,
26
+ SURFACE_SHADOW,
27
+ SurfaceProvider,
28
+ useSurface
29
+ } from "./components-csxz9f52.js";
30
+ import {
31
+ MorphSurface
32
+ } from "./components-jxgznftn.js";
33
+ import {
34
+ FluidHoverHighlight
35
+ } from "./components-r22vtgqc.js";
36
+ import {
37
+ useFluidHover,
38
+ useRegisterFluidHoverItem
39
+ } from "./components-e46kf6cp.js";
40
+ import {
41
+ shapeMap,
42
+ useShape
43
+ } from "./components-7zp99w5d.js";
44
+ import {
45
+ inPlaceOffset,
46
+ opensInPlace,
47
+ useMorph,
48
+ useMorphOrigin
49
+ } from "./components-7nww01w4.js";
50
+ import {
51
+ spring
52
+ } from "./components-vc1k7yv2.js";
53
+ import {
54
+ useSize
55
+ } from "./components-x3rz4cyn.js";
56
+ import {
57
+ cn
58
+ } from "./components-0f0as45n.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 Combobox({
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(SizeProvider, {
234
+ size,
235
+ children: root
236
+ }) : root;
237
+ }
238
+ Combobox.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 = cn(fieldButtonClass, "hover:bg-hover active:bg-active transition-[color,background-color]");
243
+ var chipRemoveClass = cn(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: cn("flex shrink-0 items-center justify-center", compact ? "size-5" : "size-6"),
251
+ children: /* @__PURE__ */ jsx(ComboboxPrimitive.Clear, {
252
+ "aria-label": "Clear",
253
+ className: cn(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: cn(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 ComboboxInput = forwardRef(({ className, variant, icon: Icon, placeholder = "Search…", error, clearable = false, size, ...props }, ref) => {
283
+ const shape = useShape();
284
+ const sizeClasses = useSize(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: cn(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: 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"),
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
+ ComboboxInput.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, spring.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 ComboboxChips = 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 = useSize(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: cn(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: cn("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: cn("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: spring.fast.exit
396
+ },
397
+ transition: spring.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: cn("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: cn(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: cn("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
+ ComboboxChips.displayName = "ComboboxChips";
451
+ var ComboboxContent = 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(useSurface() + 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(SurfaceProvider, {
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: cn(`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
+ ComboboxContent.displayName = "ComboboxContent";
493
+ var ComboboxList = 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 = useFluidHover(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(ScrollArea, {
563
+ className: popupScrollAreaClass,
564
+ viewportClassName: cn(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: cn("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: spring.moderate.exit },
595
+ transition: reflowSnap ? { duration: 0 } : { ...spring.moderate, opacity: { duration: spring.fast.duration } }
596
+ }, "checked")
597
+ }),
598
+ open && /* @__PURE__ */ jsx(FluidHoverHighlight, {
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(ComboboxItem, {
607
+ value: CREATE_VALUE,
608
+ icon: PlusIcon,
609
+ children: createRow
610
+ }) : children(item, index)
611
+ }, itemValue(item))
612
+ })
613
+ ]
614
+ })
615
+ })
616
+ });
617
+ });
618
+ ComboboxList.displayName = "ComboboxList";
619
+ var ComboboxItem = 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 = useSize();
626
+ const compact = sizeClasses.variant === "compact";
627
+ const hasMounted = useRef(false);
628
+ useEffect(() => {
629
+ hasMounted.current = true;
630
+ }, []);
631
+ const registerItem = contentCtx?.registerItem;
632
+ useRegisterFluidHoverItem(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: cn(`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: cn("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: spring.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
+ ComboboxItem.displayName = "ComboboxItem";
700
+ var ComboboxEmpty = forwardRef(({ className, children, allSelected, ...props }, ref) => {
701
+ const sizeClasses = useSize();
702
+ const ctx = useComboboxContext();
703
+ return /* @__PURE__ */ jsx(ComboboxPrimitive.Empty, {
704
+ ref,
705
+ className: cn("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
+ ComboboxEmpty.displayName = "ComboboxEmpty";
711
+ Combobox.Input = ComboboxInput;
712
+ Combobox.Chips = ComboboxChips;
713
+ Combobox.Content = ComboboxContent;
714
+ Combobox.List = ComboboxList;
715
+ Combobox.Item = ComboboxItem;
716
+ Combobox.Empty = ComboboxEmpty;
717
+ var combobox_default = Combobox;
718
+
719
+ export { Combobox, ComboboxInput, ComboboxChips, ComboboxContent, ComboboxList, ComboboxItem, ComboboxEmpty, combobox_default };