@strapi/ui-primitives 2.0.1 → 2.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.
package/dist/index.js CHANGED
@@ -1,2315 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const jsxRuntime = require("react/jsx-runtime");
4
- const React = require("react");
5
- const reactComposeRefs = require("@radix-ui/react-compose-refs");
6
- const reactContext = require("@radix-ui/react-context");
7
- const reactSlot = require("@radix-ui/react-slot");
8
- const primitive = require("@radix-ui/primitive");
9
- const reactDismissableLayer = require("@radix-ui/react-dismissable-layer");
10
- const reactFocusGuards = require("@radix-ui/react-focus-guards");
11
- const reactFocusScope = require("@radix-ui/react-focus-scope");
12
- const reactId = require("@radix-ui/react-id");
13
- const PopperPrimitive = require("@radix-ui/react-popper");
14
- const reactPortal = require("@radix-ui/react-portal");
15
- const reactPrimitive = require("@radix-ui/react-primitive");
16
- const reactUseControllableState = require("@radix-ui/react-use-controllable-state");
17
- const reactUseLayoutEffect = require("@radix-ui/react-use-layout-effect");
18
- const ariaHidden = require("aria-hidden");
19
- const ReactDOM = require("react-dom");
20
- const reactRemoveScroll = require("react-remove-scroll");
21
- const reactVirtual = require("@tanstack/react-virtual");
22
- const number = require("@radix-ui/number");
23
- const reactCollection = require("@radix-ui/react-collection");
24
- const reactDirection = require("@radix-ui/react-direction");
25
- const reactUsePrevious = require("@radix-ui/react-use-previous");
26
- const reactVisuallyHidden = require("@radix-ui/react-visually-hidden");
27
- function _interopNamespace(e) {
28
- if (e && e.__esModule)
29
- return e;
30
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
31
- if (e) {
32
- for (const k in e) {
33
- if (k !== "default") {
34
- const d = Object.getOwnPropertyDescriptor(e, k);
35
- Object.defineProperty(n, k, d.get ? d : {
36
- enumerable: true,
37
- get: () => e[k]
38
- });
39
- }
40
- }
41
- }
42
- n.default = e;
43
- return Object.freeze(n);
44
- }
45
- const React__namespace = /* @__PURE__ */ _interopNamespace(React);
46
- const PopperPrimitive__namespace = /* @__PURE__ */ _interopNamespace(PopperPrimitive);
47
- const ReactDOM__namespace = /* @__PURE__ */ _interopNamespace(ReactDOM);
48
- function createCollection(name) {
49
- const PROVIDER_NAME = `${name}CollectionProvider`;
50
- const [createCollectionContext, createCollectionScope2] = reactContext.createContextScope(PROVIDER_NAME);
51
- const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(PROVIDER_NAME, {
52
- collectionRef: { current: null },
53
- itemMap: /* @__PURE__ */ new Map(),
54
- listeners: /* @__PURE__ */ new Set()
55
- });
56
- const CollectionProvider = (props) => {
57
- const { scope, children } = props;
58
- const ref = React__namespace.useRef(null);
59
- const itemMap = React__namespace.useRef(/* @__PURE__ */ new Map()).current;
60
- const listeners = React__namespace.useRef(/* @__PURE__ */ new Set()).current;
61
- return /* @__PURE__ */ jsxRuntime.jsx(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, listeners, children });
62
- };
63
- CollectionProvider.displayName = PROVIDER_NAME;
64
- const COLLECTION_SLOT_NAME = `${name}CollectionSlot`;
65
- const CollectionSlot = React__namespace.forwardRef((props, forwardedRef) => {
66
- const { scope, children } = props;
67
- const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
68
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, context.collectionRef);
69
- return /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slot, { ref: composedRefs, children });
70
- });
71
- CollectionSlot.displayName = COLLECTION_SLOT_NAME;
72
- const ITEM_SLOT_NAME = `${name}CollectionItemSlot`;
73
- const ITEM_DATA_ATTR = "data-radix-collection-item";
74
- const CollectionItemSlot = React__namespace.forwardRef((props, forwardedRef) => {
75
- const { scope, children, ...itemData } = props;
76
- const ref = React__namespace.useRef(null);
77
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, ref);
78
- const context = useCollectionContext(ITEM_SLOT_NAME, scope);
79
- React__namespace.useEffect(() => {
80
- const previousMap = Array.from(context.itemMap.values());
81
- context.itemMap.set(ref, { ref, ...itemData });
82
- context.listeners.forEach((listener) => listener(Array.from(context.itemMap.values()), previousMap));
83
- return () => {
84
- const previousMap2 = Array.from(context.itemMap.values());
85
- context.itemMap.delete(ref);
86
- context.listeners.forEach((listener) => listener(Array.from(context.itemMap.values()), previousMap2));
87
- };
88
- });
89
- return /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slot, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
90
- });
91
- CollectionItemSlot.displayName = ITEM_SLOT_NAME;
92
- function useCollection2(scope) {
93
- const context = useCollectionContext(`${name}CollectionConsumer`, scope);
94
- const getItems = React__namespace.useCallback(() => {
95
- const collectionNode = context.collectionRef.current;
96
- if (!collectionNode)
97
- return [];
98
- const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
99
- const items = Array.from(context.itemMap.values());
100
- const orderedItems = items.sort(
101
- (a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
102
- );
103
- return orderedItems;
104
- }, [context.collectionRef, context.itemMap]);
105
- const subscribe = React__namespace.useCallback(
106
- (listener) => {
107
- context.listeners.add(listener);
108
- return () => context.listeners.delete(listener);
109
- },
110
- [context.listeners]
111
- );
112
- return { getItems, subscribe };
113
- }
114
- return [
115
- { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
116
- useCollection2,
117
- createCollectionScope2
118
- ];
119
- }
120
- const cache = /* @__PURE__ */ new Map();
121
- function useCollator(locale, options) {
122
- const cacheKey = locale + (options ? Object.entries(options).sort((a, b) => a[0] < b[0] ? -1 : 1).join() : "");
123
- if (cache.has(cacheKey)) {
124
- return cache.get(cacheKey);
125
- }
126
- const formatter = new Intl.Collator(locale, options);
127
- cache.set(cacheKey, formatter);
128
- return formatter;
129
- }
130
- function useFilter(locale, options) {
131
- const collator = useCollator(locale, {
132
- usage: "search",
133
- ...options
134
- });
135
- return {
136
- startsWith(string, substring) {
137
- if (substring.length === 0) {
138
- return true;
139
- }
140
- string = string.normalize("NFC");
141
- substring = substring.normalize("NFC");
142
- return collator.compare(string.slice(0, substring.length), substring) === 0;
143
- },
144
- endsWith(string, substring) {
145
- if (substring.length === 0) {
146
- return true;
147
- }
148
- string = string.normalize("NFC");
149
- substring = substring.normalize("NFC");
150
- return collator.compare(string.slice(-substring.length), substring) === 0;
151
- },
152
- contains(string, substring) {
153
- if (substring.length === 0) {
154
- return true;
155
- }
156
- string = string.normalize("NFC");
157
- substring = substring.normalize("NFC");
158
- let scan = 0;
159
- const sliceLen = substring.length;
160
- for (; scan + sliceLen <= string.length; scan++) {
161
- const slice = string.slice(scan, scan + sliceLen);
162
- if (collator.compare(substring, slice) === 0) {
163
- return true;
164
- }
165
- }
166
- return false;
167
- }
168
- };
169
- }
170
- const usePrev = (value) => {
171
- const ref = React__namespace.useRef();
172
- React__namespace.useEffect(() => {
173
- ref.current = value;
174
- });
175
- return ref.current;
176
- };
177
- const VirtualizedViewport = React__namespace.forwardRef(
178
- ({ children, estimatedItemSize = 40, overscan = 5, getItemCount, onViewportChange, ...props }, forwardedRef) => {
179
- const parentRef = React__namespace.useRef(null);
180
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, parentRef, onViewportChange);
181
- const childArray = React__namespace.useMemo(() => React__namespace.Children.toArray(children), [children]);
182
- const virtualizer = reactVirtual.useVirtualizer({
183
- count: getItemCount(),
184
- getScrollElement: () => parentRef.current,
185
- estimateSize: () => estimatedItemSize,
186
- overscan
187
- });
188
- const virtualItems = virtualizer.getVirtualItems();
189
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
190
- /* @__PURE__ */ jsxRuntime.jsx(
191
- "style",
192
- {
193
- dangerouslySetInnerHTML: {
194
- __html: `[data-radix-combobox-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-combobox-viewport]::-webkit-scrollbar{display:none}`
195
- }
196
- }
197
- ),
198
- /* @__PURE__ */ jsxRuntime.jsx(
199
- reactPrimitive.Primitive.div,
200
- {
201
- "data-radix-combobox-viewport": "",
202
- role: "presentation",
203
- ...props,
204
- ref: composedRefs,
205
- style: {
206
- position: "relative",
207
- flex: 1,
208
- overflow: "auto",
209
- ...props.style
210
- },
211
- children: /* @__PURE__ */ jsxRuntime.jsx(
212
- "div",
213
- {
214
- style: {
215
- height: `${virtualizer.getTotalSize()}px`,
216
- width: "100%",
217
- position: "relative"
218
- },
219
- children: virtualItems.map((virtualItem) => {
220
- const child = childArray[virtualItem.index];
221
- return /* @__PURE__ */ jsxRuntime.jsx(
222
- "div",
223
- {
224
- "data-index": virtualItem.index,
225
- ref: virtualizer.measureElement,
226
- style: {
227
- position: "absolute",
228
- top: 0,
229
- left: 0,
230
- width: "100%",
231
- transform: `translateY(${virtualItem.start}px)`
232
- },
233
- children: child
234
- },
235
- virtualItem.key
236
- );
237
- })
238
- }
239
- )
240
- }
241
- )
242
- ] });
243
- }
244
- );
245
- VirtualizedViewport.displayName = "VirtualizedViewport";
246
- const OPEN_KEYS$1 = [" ", "Enter", "ArrowUp", "ArrowDown"];
247
- const SELECTION_KEYS$1 = ["Enter"];
248
- const defaultIsPrintableCharacter = (str) => {
249
- return Boolean(str.length === 1 && str.match(/\S| /));
250
- };
251
- const COMBOBOX_NAME = "Combobox";
252
- const [Collection$1, useCollection$1] = createCollection(COMBOBOX_NAME);
253
- const [ComboboxProvider, useComboboxContext] = reactContext.createContext(COMBOBOX_NAME);
254
- const ComboboxProviders = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx(PopperPrimitive__namespace.Root, { children: /* @__PURE__ */ jsxRuntime.jsx(Collection$1.Provider, { scope: void 0, children }) });
255
- const formatAutocomplete = (autocomplete) => {
256
- if (typeof autocomplete === "string") {
257
- if (autocomplete === "none") {
258
- return {
259
- type: autocomplete,
260
- filter: void 0
261
- };
262
- }
263
- return {
264
- type: autocomplete,
265
- filter: "startsWith"
266
- };
267
- }
268
- return autocomplete;
269
- };
270
- const Combobox = (props) => {
271
- const {
272
- allowCustomValue = false,
273
- autocomplete = "none",
274
- children,
275
- open: openProp,
276
- defaultOpen,
277
- onOpenChange,
278
- value: valueProp,
279
- defaultValue,
280
- onValueChange,
281
- disabled,
282
- required = false,
283
- locale = "en-EN",
284
- onTextValueChange,
285
- textValue: textValueProp,
286
- defaultTextValue,
287
- filterValue: filterValueProp,
288
- defaultFilterValue,
289
- onFilterValueChange,
290
- isPrintableCharacter = defaultIsPrintableCharacter,
291
- visible = false,
292
- virtualized = "auto",
293
- estimatedItemSize = 40,
294
- overscan = 5
295
- } = props;
296
- const [trigger, setTrigger] = React__namespace.useState(null);
297
- const [viewport, setViewport] = React__namespace.useState(null);
298
- const [content, setContent] = React__namespace.useState(null);
299
- const [visuallyFocussedItem, setVisuallyFocussedItem] = React__namespace.useState(null);
300
- const [open = false, setOpen] = reactUseControllableState.useControllableState({
301
- prop: openProp,
302
- defaultProp: defaultOpen,
303
- onChange: onOpenChange
304
- });
305
- const [value, setValue] = reactUseControllableState.useControllableState({
306
- prop: valueProp,
307
- defaultProp: defaultValue,
308
- onChange: onValueChange
309
- });
310
- const [textValue, setTextValue] = reactUseControllableState.useControllableState({
311
- prop: textValueProp,
312
- defaultProp: allowCustomValue && !defaultTextValue ? valueProp : defaultTextValue,
313
- onChange: onTextValueChange
314
- });
315
- const [filterValue, setFilterValue] = reactUseControllableState.useControllableState({
316
- prop: filterValueProp,
317
- defaultProp: defaultFilterValue,
318
- onChange: onFilterValueChange
319
- });
320
- const id = reactId.useId();
321
- const focusFirst = React__namespace.useCallback(
322
- (candidates, items) => {
323
- const allItems = items.map((item) => item.ref.current);
324
- const [firstItem, ...restItems] = allItems;
325
- const [lastItem] = restItems.slice(-1);
326
- const PREVIOUSLY_FOCUSED_ELEMENT = visuallyFocussedItem ?? items.find((item) => item.value === value)?.ref.current;
327
- for (const candidate of candidates) {
328
- if (candidate === PREVIOUSLY_FOCUSED_ELEMENT)
329
- return;
330
- candidate?.scrollIntoView({ block: "nearest" });
331
- if (candidate === firstItem && viewport)
332
- viewport.scrollTop = 0;
333
- if (candidate === lastItem && viewport)
334
- viewport.scrollTop = viewport.scrollHeight;
335
- setVisuallyFocussedItem(candidate);
336
- if (autocomplete === "both") {
337
- const item = items.find((item2) => item2.ref.current === candidate);
338
- if (item) {
339
- setTextValue(item.textValue);
340
- }
341
- }
342
- if (candidate !== PREVIOUSLY_FOCUSED_ELEMENT)
343
- return;
344
- }
345
- },
346
- [autocomplete, setTextValue, viewport, visuallyFocussedItem, value]
347
- );
348
- const autocompleteObject = formatAutocomplete(autocomplete);
349
- React__namespace.useEffect(() => {
350
- if (autocomplete !== "both") {
351
- setVisuallyFocussedItem(null);
352
- }
353
- }, [textValue, autocomplete]);
354
- React__namespace.useEffect(() => {
355
- if (content && trigger)
356
- return ariaHidden.hideOthers([content, trigger]);
357
- }, [content, trigger]);
358
- return /* @__PURE__ */ jsxRuntime.jsx(ComboboxProviders, { children: /* @__PURE__ */ jsxRuntime.jsx(
359
- ComboboxProvider,
360
- {
361
- allowCustomValue,
362
- autocomplete: autocompleteObject,
363
- required,
364
- trigger,
365
- onTriggerChange: setTrigger,
366
- contentId: id,
367
- value,
368
- onValueChange: setValue,
369
- open,
370
- onOpenChange: setOpen,
371
- disabled,
372
- locale,
373
- focusFirst,
374
- textValue,
375
- onTextValueChange: setTextValue,
376
- onViewportChange: setViewport,
377
- onContentChange: setContent,
378
- visuallyFocussedItem,
379
- filterValue,
380
- onFilterValueChange: setFilterValue,
381
- onVisuallyFocussedItemChange: setVisuallyFocussedItem,
382
- isPrintableCharacter,
383
- visible,
384
- virtualized,
385
- estimatedItemSize,
386
- overscan,
387
- children
388
- }
389
- ) });
390
- };
391
- const TRIGGER_NAME$1 = "ComboboxTrigger";
392
- const ComboboxTrigger = React__namespace.forwardRef((props, forwardedRef) => {
393
- const { ...triggerProps } = props;
394
- const context = useComboboxContext(TRIGGER_NAME$1);
395
- const handleOpen = () => {
396
- if (!context.disabled) {
397
- context.onOpenChange(true);
398
- }
399
- };
400
- return /* @__PURE__ */ jsxRuntime.jsx(PopperPrimitive__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
401
- reactFocusScope.FocusScope,
402
- {
403
- asChild: true,
404
- trapped: context.open,
405
- onMountAutoFocus: (event) => {
406
- event.preventDefault();
407
- },
408
- onUnmountAutoFocus: (event) => {
409
- context.trigger?.focus({ preventScroll: true });
410
- document.getSelection()?.empty();
411
- event.preventDefault();
412
- },
413
- children: /* @__PURE__ */ jsxRuntime.jsx(
414
- "div",
415
- {
416
- ref: forwardedRef,
417
- "data-disabled": context.disabled ? "" : void 0,
418
- ...triggerProps,
419
- onClick: primitive.composeEventHandlers(triggerProps.onClick, (event) => {
420
- if (context.disabled) {
421
- event.preventDefault();
422
- return;
423
- }
424
- context.trigger?.focus();
425
- }),
426
- onPointerDown: primitive.composeEventHandlers(triggerProps.onPointerDown, (event) => {
427
- if (context.disabled) {
428
- event.preventDefault();
429
- return;
430
- }
431
- const target = event.target;
432
- if (target.hasPointerCapture(event.pointerId)) {
433
- target.releasePointerCapture(event.pointerId);
434
- }
435
- const buttonTarg = target.closest("button") ?? target.closest("div");
436
- if (buttonTarg !== event.currentTarget) {
437
- return;
438
- }
439
- if (event.button === 0 && event.ctrlKey === false) {
440
- handleOpen();
441
- context.trigger?.focus();
442
- }
443
- })
444
- }
445
- )
446
- }
447
- ) });
448
- });
449
- ComboboxTrigger.displayName = TRIGGER_NAME$1;
450
- const INPUT_NAME = "ComboboxInput";
451
- const ComboxboxTextInput = React__namespace.forwardRef((props, forwardedRef) => {
452
- const context = useComboboxContext(INPUT_NAME);
453
- const inputRef = React__namespace.useRef(null);
454
- const { getItems } = useCollection$1(void 0);
455
- const { startsWith } = useFilter(context.locale, { sensitivity: "base" });
456
- const isDisabled = context.disabled;
457
- const composedRefs = reactComposeRefs.useComposedRefs(inputRef, forwardedRef, context.onTriggerChange);
458
- const handleOpen = () => {
459
- if (!isDisabled) {
460
- context.onOpenChange(true);
461
- }
462
- };
463
- const previousFilter = usePrev(context.filterValue);
464
- reactUseLayoutEffect.useLayoutEffect(() => {
465
- const timeout = setTimeout(() => {
466
- if (context.textValue === "" || context.textValue === void 0 || context.filterValue === "" || context.filterValue === void 0)
467
- return;
468
- const firstItem = getItems().find(
469
- (item) => item.type === "option" && startsWith(item.textValue, context.textValue)
470
- );
471
- const characterChangedAtIndex = findChangedIndex(previousFilter ?? "", context.filterValue);
472
- if (firstItem && !context.visuallyFocussedItem && characterChangedAtIndex === context.filterValue.length) {
473
- inputRef.current?.setSelectionRange(context.filterValue.length, context.textValue.length);
474
- }
475
- });
476
- return () => clearTimeout(timeout);
477
- }, [context.textValue, context.filterValue, startsWith, context.visuallyFocussedItem, getItems, previousFilter]);
478
- return /* @__PURE__ */ jsxRuntime.jsx(
479
- "input",
480
- {
481
- type: "text",
482
- role: "combobox",
483
- "aria-controls": context.contentId,
484
- "aria-expanded": context.open,
485
- "aria-required": context.required,
486
- "aria-autocomplete": context.autocomplete.type,
487
- "data-state": context.open ? "open" : "closed",
488
- "aria-disabled": isDisabled,
489
- "aria-activedescendant": context.visuallyFocussedItem?.id,
490
- disabled: isDisabled,
491
- "data-disabled": isDisabled ? "" : void 0,
492
- "data-placeholder": context.textValue === void 0 ? "" : void 0,
493
- value: context.textValue ?? "",
494
- ...props,
495
- ref: composedRefs,
496
- onKeyDown: primitive.composeEventHandlers(props.onKeyDown, (event) => {
497
- if (["ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
498
- if (!context.open) {
499
- handleOpen();
500
- }
501
- setTimeout(() => {
502
- const items = getItems().filter((item) => !item.disabled && item.isVisible);
503
- let candidateNodes = items.map((item) => item.ref.current);
504
- if (["ArrowUp", "End"].includes(event.key)) {
505
- candidateNodes = candidateNodes.slice().reverse();
506
- }
507
- if (["ArrowUp", "ArrowDown"].includes(event.key)) {
508
- const currentElement = context.visuallyFocussedItem ?? getItems().find((item) => item.value === context.value)?.ref.current;
509
- if (currentElement) {
510
- let currentIndex = candidateNodes.indexOf(currentElement);
511
- if (currentIndex === candidateNodes.length - 1) {
512
- currentIndex = -1;
513
- }
514
- candidateNodes = candidateNodes.slice(currentIndex + 1);
515
- }
516
- }
517
- if (["ArrowDown"].includes(event.key) && context.autocomplete.type === "both" && candidateNodes.length > 1) {
518
- const [firstItem, ...restItems] = candidateNodes;
519
- const firstItemText = getItems().find((item) => item.ref.current === firstItem).textValue;
520
- if (context.textValue === firstItemText) {
521
- candidateNodes = restItems;
522
- }
523
- }
524
- context.focusFirst(candidateNodes, getItems());
525
- });
526
- event.preventDefault();
527
- } else if (["Tab"].includes(event.key) && context.open) {
528
- event.preventDefault();
529
- } else if (["Escape"].includes(event.key)) {
530
- if (context.open) {
531
- context.onOpenChange(false);
532
- } else {
533
- context.onValueChange(void 0);
534
- context.onTextValueChange("");
535
- }
536
- event.preventDefault();
537
- } else if (SELECTION_KEYS$1.includes(event.key)) {
538
- if (context.visuallyFocussedItem) {
539
- const focussedItem = getItems().find((item) => item.ref.current === context.visuallyFocussedItem);
540
- if (focussedItem) {
541
- context.onValueChange(focussedItem.value);
542
- context.onTextValueChange(focussedItem.textValue);
543
- if (context.autocomplete.type === "both") {
544
- context.onFilterValueChange(focussedItem.textValue);
545
- }
546
- focussedItem.ref.current?.click();
547
- }
548
- } else {
549
- const matchedItem = getItems().find(
550
- (item) => item.type === "option" && !item.disabled && item.textValue === context.textValue
551
- );
552
- if (matchedItem) {
553
- context.onValueChange(matchedItem.value);
554
- context.onTextValueChange(matchedItem.textValue);
555
- if (context.autocomplete.type === "both") {
556
- context.onFilterValueChange(matchedItem.textValue);
557
- }
558
- matchedItem.ref.current?.click();
559
- }
560
- }
561
- context.onOpenChange(false);
562
- event.preventDefault();
563
- } else {
564
- context.onVisuallyFocussedItemChange(null);
565
- }
566
- }),
567
- onChange: primitive.composeEventHandlers(props.onChange, (event) => {
568
- context.onTextValueChange(event.currentTarget.value);
569
- if (context.autocomplete.type === "both") {
570
- context.onFilterValueChange(event.currentTarget.value);
571
- }
572
- }),
573
- onKeyUp: primitive.composeEventHandlers(props.onKeyUp, (event) => {
574
- if (!context.open && (context.isPrintableCharacter(event.key) || ["Backspace"].includes(event.key))) {
575
- handleOpen();
576
- }
577
- setTimeout(() => {
578
- if (context.autocomplete.type === "both" && context.isPrintableCharacter(event.key) && context.filterValue !== void 0) {
579
- const value = context.filterValue;
580
- const firstItem = getItems().find((item) => startsWith(item.textValue, value));
581
- if (firstItem) {
582
- context.onTextValueChange(firstItem.textValue);
583
- }
584
- }
585
- });
586
- if (context.autocomplete.type === "none" && context.isPrintableCharacter(event.key)) {
587
- const value = context.textValue ?? "";
588
- const nextItem = getItems().find((item) => startsWith(item.textValue, value));
589
- if (nextItem) {
590
- context.onVisuallyFocussedItemChange(nextItem.ref.current);
591
- nextItem.ref.current?.scrollIntoView();
592
- }
593
- }
594
- }),
595
- onBlur: primitive.composeEventHandlers(props.onBlur, () => {
596
- if (context.open) {
597
- return;
598
- }
599
- context.onVisuallyFocussedItemChange(null);
600
- const [activeItem] = getItems().filter(
601
- (item) => item.textValue === context.textValue && item.type === "option"
602
- );
603
- if (activeItem) {
604
- context.onValueChange(activeItem.value);
605
- if (context.autocomplete.type === "both") {
606
- context.onFilterValueChange(activeItem.textValue);
607
- }
608
- return;
609
- }
610
- if (context.allowCustomValue) {
611
- context.onValueChange(context.textValue);
612
- if (context.autocomplete.type === "both") {
613
- context.onFilterValueChange(context.textValue);
614
- }
615
- return;
616
- }
617
- const [previousItem] = getItems().filter((item) => item.value === context.value && item.type === "option");
618
- if (previousItem && context.textValue !== "") {
619
- context.onTextValueChange(previousItem.textValue);
620
- if (context.autocomplete.type === "both") {
621
- context.onFilterValueChange(previousItem.textValue);
622
- }
623
- } else {
624
- context.onValueChange(void 0);
625
- context.onTextValueChange("");
626
- }
627
- })
628
- }
629
- );
630
- });
631
- ComboxboxTextInput.displayName = "ComboboxTextInput";
632
- const ComboboxIcon = React__namespace.forwardRef((props, forwardedRef) => {
633
- const { children, ...iconProps } = props;
634
- const context = useComboboxContext(INPUT_NAME);
635
- const isDisabled = context.disabled;
636
- const handleOpen = () => {
637
- if (!isDisabled) {
638
- context.onOpenChange(true);
639
- context.trigger?.focus();
640
- }
641
- };
642
- return /* @__PURE__ */ jsxRuntime.jsx(
643
- reactPrimitive.Primitive.button,
644
- {
645
- "aria-hidden": true,
646
- type: "button",
647
- "aria-disabled": isDisabled,
648
- "aria-controls": context.contentId,
649
- "aria-expanded": context.open,
650
- disabled: isDisabled,
651
- "data-disabled": isDisabled ? "" : void 0,
652
- ...iconProps,
653
- tabIndex: -1,
654
- ref: forwardedRef,
655
- onClick: primitive.composeEventHandlers(iconProps.onClick, () => {
656
- context.trigger?.focus();
657
- }),
658
- onPointerDown: primitive.composeEventHandlers(iconProps.onPointerDown, (event) => {
659
- if (event.button === 0 && event.ctrlKey === false) {
660
- handleOpen();
661
- event.preventDefault();
662
- }
663
- }),
664
- onKeyDown: primitive.composeEventHandlers(iconProps.onKeyDown, (event) => {
665
- if (OPEN_KEYS$1.includes(event.key)) {
666
- handleOpen();
667
- event.preventDefault();
668
- }
669
- }),
670
- children: children || "▼"
671
- }
672
- );
673
- });
674
- ComboboxIcon.displayName = "ComboboxIcon";
675
- const PORTAL_NAME$1 = "ComboboxPortal";
676
- const ComboboxPortal = (props) => {
677
- return /* @__PURE__ */ jsxRuntime.jsx(reactPortal.Portal, { asChild: true, ...props });
678
- };
679
- ComboboxPortal.displayName = PORTAL_NAME$1;
680
- const CONTENT_NAME$1 = "ComboboxContent";
681
- const ComboboxContent = React__namespace.forwardRef((props, forwardedRef) => {
682
- const context = useComboboxContext(CONTENT_NAME$1);
683
- const { getItems } = useCollection$1(void 0);
684
- const [fragment, setFragment] = React__namespace.useState();
685
- reactUseLayoutEffect.useLayoutEffect(() => {
686
- setFragment(new DocumentFragment());
687
- }, []);
688
- reactUseLayoutEffect.useLayoutEffect(() => {
689
- if (context.open && context.autocomplete.type === "none") {
690
- setTimeout(() => {
691
- const activeItem = getItems().find((item) => item.value === context.value);
692
- activeItem?.ref.current?.scrollIntoView({ block: "nearest" });
693
- });
694
- }
695
- }, [getItems, context.autocomplete, context.value, context.open]);
696
- if (!context.open) {
697
- const frag = fragment;
698
- return frag ? ReactDOM__namespace.createPortal(
699
- /* @__PURE__ */ jsxRuntime.jsx(Collection$1.Slot, { scope: void 0, children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: props.children }) }),
700
- frag
701
- ) : null;
702
- }
703
- return /* @__PURE__ */ jsxRuntime.jsx(ComboboxContentImpl, { ...props, ref: forwardedRef });
704
- });
705
- ComboboxContent.displayName = CONTENT_NAME$1;
706
- const CONTENT_MARGIN$1 = 10;
707
- const ComboboxContentImpl = React__namespace.forwardRef(
708
- (props, forwardedRef) => {
709
- const { onEscapeKeyDown, onPointerDownOutside, ...contentProps } = props;
710
- const context = useComboboxContext(CONTENT_NAME$1);
711
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, (node) => context.onContentChange(node));
712
- const { onOpenChange } = context;
713
- reactFocusGuards.useFocusGuards();
714
- React__namespace.useEffect(() => {
715
- const close = () => {
716
- onOpenChange(false);
717
- };
718
- window.addEventListener("blur", close);
719
- window.addEventListener("resize", close);
720
- return () => {
721
- window.removeEventListener("blur", close);
722
- window.removeEventListener("resize", close);
723
- };
724
- }, [onOpenChange]);
725
- return /* @__PURE__ */ jsxRuntime.jsx(reactRemoveScroll.RemoveScroll, { allowPinchZoom: true, children: /* @__PURE__ */ jsxRuntime.jsx(
726
- reactDismissableLayer.DismissableLayer,
727
- {
728
- asChild: true,
729
- onEscapeKeyDown,
730
- onPointerDownOutside,
731
- onFocusOutside: (event) => {
732
- event.preventDefault();
733
- },
734
- onDismiss: () => {
735
- context.onOpenChange(false);
736
- context.trigger?.focus({ preventScroll: true });
737
- },
738
- children: /* @__PURE__ */ jsxRuntime.jsx(
739
- ComboboxPopperPosition,
740
- {
741
- role: "listbox",
742
- id: context.contentId,
743
- "data-state": context.open ? "open" : "closed",
744
- onContextMenu: (event) => event.preventDefault(),
745
- ...contentProps,
746
- ref: composedRefs,
747
- style: {
748
- // flex layout so we can place the scroll buttons properly
749
- display: "flex",
750
- flexDirection: "column",
751
- // reset the outline by default as the content MAY get focused
752
- outline: "none",
753
- ...contentProps.style
754
- }
755
- }
756
- )
757
- }
758
- ) });
759
- }
760
- );
761
- ComboboxContentImpl.displayName = "ComboboxContentImpl";
762
- const ComboboxPopperPosition = React__namespace.forwardRef(
763
- (props, forwardedRef) => {
764
- const { align = "start", collisionPadding = CONTENT_MARGIN$1, ...popperProps } = props;
765
- return /* @__PURE__ */ jsxRuntime.jsx(
766
- PopperPrimitive__namespace.Content,
767
- {
768
- ...popperProps,
769
- ref: forwardedRef,
770
- align,
771
- collisionPadding,
772
- style: {
773
- // Ensure border-box for floating-ui calculations
774
- boxSizing: "border-box",
775
- ...popperProps.style,
776
- // re-namespace exposed content custom properties
777
- ...{
778
- "--radix-combobox-content-transform-origin": "var(--radix-popper-transform-origin)",
779
- "--radix-combobox-content-available-width": "var(--radix-popper-available-width)",
780
- "--radix-combobox-content-available-height": "var(--radix-popper-available-height)",
781
- "--radix-combobox-trigger-width": "var(--radix-popper-anchor-width)",
782
- "--radix-combobox-trigger-height": "var(--radix-popper-anchor-height)"
783
- }
784
- }
785
- }
786
- );
787
- }
788
- );
789
- ComboboxPopperPosition.displayName = "ComboboxPopperPosition";
790
- const VIEWPORT_NAME$1 = "ComboboxViewport";
791
- const ComboboxViewport = React__namespace.forwardRef((props, forwardedRef) => {
792
- const comboboxContext = useComboboxContext(VIEWPORT_NAME$1);
793
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, comboboxContext.onViewportChange);
794
- const childArray = React__namespace.useMemo(() => React__namespace.Children.toArray(props.children), [props.children]);
795
- const itemCount = childArray.length;
796
- const shouldVirtualize = comboboxContext.virtualized === true || comboboxContext.virtualized === "auto" && itemCount > 100;
797
- if (shouldVirtualize) {
798
- return /* @__PURE__ */ jsxRuntime.jsx(Collection$1.Slot, { scope: void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
799
- VirtualizedViewport,
800
- {
801
- ...props,
802
- ref: composedRefs,
803
- getItemCount: () => itemCount,
804
- estimatedItemSize: comboboxContext.estimatedItemSize,
805
- overscan: comboboxContext.overscan,
806
- onViewportChange: comboboxContext.onViewportChange
807
- }
808
- ) });
809
- }
810
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
811
- /* @__PURE__ */ jsxRuntime.jsx(
812
- "style",
813
- {
814
- dangerouslySetInnerHTML: {
815
- __html: `[data-radix-combobox-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-combobox-viewport]::-webkit-scrollbar{display:none}`
816
- }
817
- }
818
- ),
819
- /* @__PURE__ */ jsxRuntime.jsx(Collection$1.Slot, { scope: void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
820
- reactPrimitive.Primitive.div,
821
- {
822
- "data-radix-combobox-viewport": "",
823
- role: "presentation",
824
- ...props,
825
- ref: composedRefs,
826
- style: {
827
- // we use position: 'relative' here on the `viewport` so that when we call
828
- // `selectedItem.offsetTop` in calculations, the offset is relative to the viewport
829
- // (independent of the scrollUpButton).
830
- position: "relative",
831
- flex: 1,
832
- overflow: "auto",
833
- ...props.style
834
- }
835
- }
836
- ) })
837
- ] });
838
- });
839
- ComboboxViewport.displayName = VIEWPORT_NAME$1;
840
- const ITEM_NAME$1 = "ComboboxItem";
841
- const [ComboboxItemProvider, useComboboxItemContext] = reactContext.createContext(ITEM_NAME$1);
842
- const ComboboxItem = React__namespace.forwardRef((props, forwardedRef) => {
843
- const { value, disabled = false, textValue: textValueProp, ...restProps } = props;
844
- const [fragment, setFragment] = React__namespace.useState();
845
- reactUseLayoutEffect.useLayoutEffect(() => {
846
- setFragment(new DocumentFragment());
847
- }, []);
848
- const { onTextValueChange, textValue: contextTextValue, ...context } = useComboboxContext(ITEM_NAME$1);
849
- const textId = reactId.useId();
850
- const [textValue, setTextValue] = React__namespace.useState(textValueProp ?? "");
851
- const isSelected = context.value === value;
852
- const { startsWith, contains } = useFilter(context.locale, { sensitivity: "base" });
853
- const handleTextValueChange = React__namespace.useCallback((node) => {
854
- setTextValue((prevTextValue) => {
855
- return prevTextValue || (node?.textContent ?? "").trim();
856
- });
857
- }, []);
858
- React__namespace.useEffect(() => {
859
- if (isSelected && contextTextValue === void 0 && textValue !== "") {
860
- onTextValueChange(textValue);
861
- }
862
- }, [textValue, isSelected, contextTextValue, onTextValueChange]);
863
- if (context.autocomplete.type === "both" && textValue && context.filterValue && !startsWith(textValue, context.filterValue) || context.autocomplete.type === "list" && context.autocomplete.filter === "startsWith" && textValue && contextTextValue && !startsWith(textValue, contextTextValue) || context.autocomplete.type === "list" && context.autocomplete.filter === "contains" && textValue && contextTextValue && !contains(textValue, contextTextValue)) {
864
- return fragment ? ReactDOM__namespace.createPortal(
865
- /* @__PURE__ */ jsxRuntime.jsx(
866
- ComboboxItemProvider,
867
- {
868
- textId,
869
- onTextValueChange: handleTextValueChange,
870
- isSelected,
871
- textValue,
872
- children: /* @__PURE__ */ jsxRuntime.jsx(
873
- Collection$1.ItemSlot,
874
- {
875
- scope: void 0,
876
- value,
877
- textValue,
878
- disabled,
879
- type: "option",
880
- isVisible: false,
881
- children: /* @__PURE__ */ jsxRuntime.jsx(ComboboxItemImpl, { ref: forwardedRef, value, disabled, ...restProps })
882
- }
883
- )
884
- }
885
- ),
886
- fragment
887
- ) : null;
888
- }
889
- return /* @__PURE__ */ jsxRuntime.jsx(
890
- ComboboxItemProvider,
891
- {
892
- textId,
893
- onTextValueChange: handleTextValueChange,
894
- isSelected,
895
- textValue,
896
- children: /* @__PURE__ */ jsxRuntime.jsx(
897
- Collection$1.ItemSlot,
898
- {
899
- scope: void 0,
900
- value,
901
- textValue,
902
- disabled,
903
- type: "option",
904
- isVisible: true,
905
- children: /* @__PURE__ */ jsxRuntime.jsx(ComboboxItemImpl, { ref: forwardedRef, value, disabled, ...restProps })
906
- }
907
- )
908
- }
909
- );
910
- });
911
- ComboboxItem.displayName = ITEM_NAME$1;
912
- const ITEM_IMPL_NAME = "ComboboxItemImpl";
913
- const ComboboxItemImpl = React__namespace.forwardRef((props, forwardedRef) => {
914
- const { value, disabled = false, ...restProps } = props;
915
- const itemRef = React__namespace.useRef(null);
916
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, itemRef);
917
- const { getItems } = useCollection$1(void 0);
918
- const { onTextValueChange, visuallyFocussedItem, ...context } = useComboboxContext(ITEM_NAME$1);
919
- const { isSelected, textValue, textId } = useComboboxItemContext(ITEM_IMPL_NAME);
920
- const handleSelect = () => {
921
- if (!disabled) {
922
- context.onValueChange(value);
923
- onTextValueChange(textValue);
924
- context.onOpenChange(false);
925
- if (context.autocomplete.type === "both") {
926
- context.onFilterValueChange(textValue);
927
- }
928
- context.trigger?.focus({ preventScroll: true });
929
- }
930
- };
931
- const isFocused = React__namespace.useMemo(() => {
932
- return visuallyFocussedItem === getItems().find((item) => item.ref.current === itemRef.current)?.ref.current;
933
- }, [getItems, visuallyFocussedItem]);
934
- const id = reactId.useId();
935
- return /* @__PURE__ */ jsxRuntime.jsx(
936
- reactPrimitive.Primitive.div,
937
- {
938
- role: "option",
939
- "aria-labelledby": textId,
940
- "data-highlighted": isFocused ? "" : void 0,
941
- "aria-selected": isSelected && isFocused,
942
- "data-state": isSelected ? "checked" : "unchecked",
943
- "aria-disabled": disabled || void 0,
944
- "data-disabled": disabled ? "" : void 0,
945
- tabIndex: disabled ? void 0 : -1,
946
- ...restProps,
947
- id,
948
- ref: composedRefs,
949
- onPointerUp: primitive.composeEventHandlers(restProps.onPointerUp, handleSelect)
950
- }
951
- );
952
- });
953
- ComboboxItemImpl.displayName = ITEM_IMPL_NAME;
954
- const ITEM_TEXT_NAME$1 = "ComboboxItemText";
955
- const ComboboxItemText = React__namespace.forwardRef((props, forwardedRef) => {
956
- const { className: _unusedClassName, style: _unusedStyle, ...itemTextProps } = props;
957
- const itemContext = useComboboxItemContext(ITEM_TEXT_NAME$1);
958
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, itemContext.onTextValueChange);
959
- return /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.span, { id: itemContext.textId, ...itemTextProps, ref: composedRefs });
960
- });
961
- ComboboxItemText.displayName = ITEM_TEXT_NAME$1;
962
- const ITEM_INDICATOR_NAME$1 = "ComboboxItemIndicator";
963
- const ComboboxItemIndicator = React__namespace.forwardRef((props, forwardedRef) => {
964
- const { isSelected } = useComboboxItemContext(ITEM_INDICATOR_NAME$1);
965
- return isSelected ? /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.span, { "aria-hidden": true, ...props, ref: forwardedRef }) : null;
966
- });
967
- ComboboxItemIndicator.displayName = ITEM_INDICATOR_NAME$1;
968
- const NO_VALUE_FOUND_NAME = "ComboboxNoValueFound";
969
- const ComboboxNoValueFound = React__namespace.forwardRef((props, ref) => {
970
- const {
971
- textValue = "",
972
- filterValue = "",
973
- visible = false,
974
- locale,
975
- autocomplete
976
- } = useComboboxContext(NO_VALUE_FOUND_NAME);
977
- const [items, setItems] = React__namespace.useState([]);
978
- const { subscribe } = useCollection$1(void 0);
979
- const { startsWith, contains } = useFilter(locale, { sensitivity: "base" });
980
- React__namespace.useEffect(() => {
981
- const unsub = subscribe((state) => {
982
- if (visible) {
983
- const filteredItems = state.filter((item) => item.type !== "create");
984
- setItems(filteredItems);
985
- } else {
986
- setItems(state);
987
- }
988
- });
989
- return () => {
990
- unsub();
991
- };
992
- }, [visible, subscribe]);
993
- if (autocomplete.type === "none" && items.length > 0)
994
- return null;
995
- if (autocomplete.type === "list" && autocomplete.filter === "startsWith" && items.some((item) => startsWith(item.textValue, textValue))) {
996
- return null;
997
- }
998
- if (autocomplete.type === "both" && items.some((item) => startsWith(item.textValue, filterValue))) {
999
- return null;
1000
- }
1001
- if (autocomplete.type === "list" && autocomplete.filter === "contains" && items.some((item) => contains(item.textValue, textValue))) {
1002
- return null;
1003
- }
1004
- return /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.div, { ...props, ref });
1005
- });
1006
- ComboboxNoValueFound.displayName = NO_VALUE_FOUND_NAME;
1007
- const ComboboxCreateItem = React__namespace.forwardRef((props, ref) => {
1008
- const { disabled = false, ...restProps } = props;
1009
- const context = useComboboxContext(NO_VALUE_FOUND_NAME);
1010
- const { textValue, visuallyFocussedItem } = context;
1011
- const { getItems, subscribe } = useCollection$1(void 0);
1012
- const itemRef = React__namespace.useRef(null);
1013
- const [show, setShow] = React__namespace.useState(false);
1014
- const composedRefs = reactComposeRefs.useComposedRefs(ref, itemRef);
1015
- const isFocused = React__namespace.useMemo(() => {
1016
- return visuallyFocussedItem === getItems().find((item) => item.ref.current === itemRef.current)?.ref.current;
1017
- }, [getItems, visuallyFocussedItem]);
1018
- const id = reactId.useId();
1019
- const handleSelect = () => {
1020
- if (!disabled && textValue) {
1021
- context.onValueChange(textValue);
1022
- context.onTextValueChange(textValue);
1023
- context.onOpenChange(false);
1024
- if (context.autocomplete.type === "both") {
1025
- context.onFilterValueChange(textValue);
1026
- }
1027
- context.trigger?.focus({ preventScroll: true });
1028
- }
1029
- };
1030
- reactUseLayoutEffect.useLayoutEffect(() => {
1031
- const unsub = subscribe((state) => {
1032
- setShow(!state.some((item) => item.textValue === textValue && item.type !== "create"));
1033
- });
1034
- if (getItems().length === 0) {
1035
- setShow(true);
1036
- }
1037
- return () => {
1038
- unsub();
1039
- };
1040
- }, [textValue, subscribe, getItems]);
1041
- if ((!textValue || !show) && !context.visible) {
1042
- return null;
1043
- }
1044
- return /* @__PURE__ */ jsxRuntime.jsx(
1045
- Collection$1.ItemSlot,
1046
- {
1047
- scope: void 0,
1048
- value: textValue ?? "",
1049
- textValue: textValue ?? "",
1050
- disabled,
1051
- isVisible: true,
1052
- type: "create",
1053
- children: /* @__PURE__ */ jsxRuntime.jsx(
1054
- reactPrimitive.Primitive.div,
1055
- {
1056
- role: "option",
1057
- tabIndex: disabled ? void 0 : -1,
1058
- "aria-disabled": disabled || void 0,
1059
- "data-disabled": disabled ? "" : void 0,
1060
- "data-highlighted": isFocused ? "" : void 0,
1061
- ...restProps,
1062
- id,
1063
- ref: composedRefs,
1064
- onPointerUp: primitive.composeEventHandlers(restProps.onPointerUp, handleSelect)
1065
- }
1066
- )
1067
- }
1068
- );
1069
- });
1070
- ComboboxCreateItem.displayName = "ComboboxCreateItem";
1071
- const Root$1 = Combobox;
1072
- const Trigger$1 = ComboboxTrigger;
1073
- const TextInput = ComboxboxTextInput;
1074
- const Icon$1 = ComboboxIcon;
1075
- const Portal$1 = ComboboxPortal;
1076
- const Content$1 = ComboboxContent;
1077
- const Viewport$1 = ComboboxViewport;
1078
- const Item$1 = ComboboxItem;
1079
- const ItemText$1 = ComboboxItemText;
1080
- const ItemIndicator$1 = ComboboxItemIndicator;
1081
- const NoValueFound = ComboboxNoValueFound;
1082
- const CreateItem = ComboboxCreateItem;
1083
- function findChangedIndex(a, b) {
1084
- const length = Math.min(a.length, b.length);
1085
- for (let i = 0; i < length; i++) {
1086
- if (a[i] !== b[i]) {
1087
- return i;
1088
- }
1089
- }
1090
- return length;
1091
- }
1092
- const Combobox$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1093
- __proto__: null,
1094
- ComboboxItem,
1095
- Content: Content$1,
1096
- CreateItem,
1097
- Icon: Icon$1,
1098
- Item: Item$1,
1099
- ItemIndicator: ItemIndicator$1,
1100
- ItemText: ItemText$1,
1101
- NoValueFound,
1102
- Portal: Portal$1,
1103
- Root: Root$1,
1104
- TextInput,
1105
- Trigger: Trigger$1,
1106
- Viewport: Viewport$1
1107
- }, Symbol.toStringTag, { value: "Module" }));
1108
- function useCallbackRef(callback) {
1109
- const callbackRef = React__namespace.useRef(callback);
1110
- React__namespace.useEffect(() => {
1111
- callbackRef.current = callback;
1112
- });
1113
- return React__namespace.useMemo(() => (...args) => callbackRef.current?.(...args), []);
1114
- }
1115
- const OPEN_KEYS = [" ", "Enter", "ArrowUp", "ArrowDown"];
1116
- const SELECTION_KEYS = [" ", "Enter"];
1117
- const SELECT_NAME = "Select";
1118
- const [Collection, useCollection, createCollectionScope] = reactCollection.createCollection(SELECT_NAME);
1119
- const [createSelectContext, createSelectScope] = reactContext.createContextScope(SELECT_NAME, [
1120
- createCollectionScope,
1121
- PopperPrimitive.createPopperScope
1122
- ]);
1123
- const usePopperScope = PopperPrimitive.createPopperScope();
1124
- const [SelectProvider, useSelectContext] = createSelectContext(SELECT_NAME);
1125
- const [SelectNativeOptionsProvider, useSelectNativeOptionsContext] = createSelectContext(SELECT_NAME);
1126
- const Select = (props) => {
1127
- const {
1128
- __scopeSelect,
1129
- children,
1130
- open: openProp,
1131
- defaultOpen,
1132
- onOpenChange,
1133
- value: valueProp,
1134
- defaultValue,
1135
- onValueChange,
1136
- dir,
1137
- // name,
1138
- // autoComplete,
1139
- disabled,
1140
- required,
1141
- multi = false
1142
- } = props;
1143
- const popperScope = usePopperScope(__scopeSelect);
1144
- const [trigger, setTrigger] = React__namespace.useState(null);
1145
- const [valueNode, setValueNode] = React__namespace.useState(null);
1146
- const [valueNodeHasChildren, setValueNodeHasChildren] = React__namespace.useState(false);
1147
- const direction = reactDirection.useDirection(dir);
1148
- const [open = false, setOpen] = reactUseControllableState.useControllableState({
1149
- prop: openProp,
1150
- defaultProp: defaultOpen,
1151
- onChange: onOpenChange
1152
- });
1153
- const [value, setValue] = reactUseControllableState.useControllableState({
1154
- prop: valueProp,
1155
- defaultProp: defaultValue,
1156
- onChange(value2) {
1157
- if (onValueChange) {
1158
- if (Array.isArray(value2)) {
1159
- onValueChange(value2);
1160
- } else {
1161
- onValueChange(value2);
1162
- }
1163
- }
1164
- }
1165
- });
1166
- const triggerPointerDownPosRef = React__namespace.useRef(null);
1167
- const [_nativeOptionsSet, setNativeOptionsSet] = React__namespace.useState(/* @__PURE__ */ new Set());
1168
- return /* @__PURE__ */ jsxRuntime.jsx(PopperPrimitive__namespace.Root, { ...popperScope, children: /* @__PURE__ */ jsxRuntime.jsx(
1169
- SelectProvider,
1170
- {
1171
- required,
1172
- scope: __scopeSelect,
1173
- trigger,
1174
- onTriggerChange: setTrigger,
1175
- valueNode,
1176
- onValueNodeChange: setValueNode,
1177
- valueNodeHasChildren,
1178
- onValueNodeHasChildrenChange: setValueNodeHasChildren,
1179
- contentId: reactId.useId(),
1180
- value,
1181
- onValueChange: setValue,
1182
- open,
1183
- onOpenChange: setOpen,
1184
- dir: direction,
1185
- triggerPointerDownPosRef,
1186
- disabled,
1187
- multi,
1188
- children: /* @__PURE__ */ jsxRuntime.jsx(Collection.Provider, { scope: __scopeSelect, children: /* @__PURE__ */ jsxRuntime.jsx(
1189
- SelectNativeOptionsProvider,
1190
- {
1191
- scope: props.__scopeSelect,
1192
- onNativeOptionAdd: React__namespace.useCallback((option) => {
1193
- setNativeOptionsSet((prev) => new Set(prev).add(option));
1194
- }, []),
1195
- onNativeOptionRemove: React__namespace.useCallback((option) => {
1196
- setNativeOptionsSet((prev) => {
1197
- const optionsSet = new Set(prev);
1198
- optionsSet.delete(option);
1199
- return optionsSet;
1200
- });
1201
- }, []),
1202
- children
1203
- }
1204
- ) })
1205
- }
1206
- ) });
1207
- };
1208
- Select.displayName = SELECT_NAME;
1209
- const TRIGGER_NAME = "SelectTrigger";
1210
- const SelectTrigger = React__namespace.forwardRef(
1211
- (props, forwardedRef) => {
1212
- const { __scopeSelect, ...triggerProps } = props;
1213
- const popperScope = usePopperScope(__scopeSelect);
1214
- const context = useSelectContext(TRIGGER_NAME, __scopeSelect);
1215
- const isDisabled = context.disabled;
1216
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, context.onTriggerChange);
1217
- const getItems = useCollection(__scopeSelect);
1218
- const [searchRef, handleTypeaheadSearch, resetTypeahead] = useTypeaheadSearch((search) => {
1219
- const enabledItems = getItems().filter((item) => !item.disabled);
1220
- const currentItem = enabledItems.find((item) => item.value === context.value);
1221
- const nextItem = findNextItem(enabledItems, search, currentItem);
1222
- if (nextItem !== void 0 && !Array.isArray(nextItem.value)) {
1223
- const newValue = context.multi ? [nextItem.value] : nextItem.value;
1224
- context.onValueChange(newValue);
1225
- }
1226
- });
1227
- const handleOpen = () => {
1228
- if (!isDisabled) {
1229
- context.onOpenChange(true);
1230
- resetTypeahead();
1231
- }
1232
- };
1233
- return /* @__PURE__ */ jsxRuntime.jsx(PopperPrimitive__namespace.Anchor, { asChild: true, ...popperScope, children: /* @__PURE__ */ jsxRuntime.jsx(
1234
- reactPrimitive.Primitive.div,
1235
- {
1236
- role: "combobox",
1237
- "aria-controls": context.contentId,
1238
- "aria-expanded": context.open,
1239
- "aria-required": context.required,
1240
- "aria-autocomplete": "none",
1241
- dir: context.dir,
1242
- "data-state": context.open ? "open" : "closed",
1243
- "data-disabled": isDisabled ? "" : void 0,
1244
- "data-placeholder": context.value === void 0 ? "" : void 0,
1245
- tabIndex: isDisabled ? void 0 : 0,
1246
- ...triggerProps,
1247
- ref: composedRefs,
1248
- onClick: primitive.composeEventHandlers(triggerProps.onClick, (event) => {
1249
- event.currentTarget.focus();
1250
- }),
1251
- onPointerDown: primitive.composeEventHandlers(triggerProps.onPointerDown, (event) => {
1252
- const target = event.target;
1253
- if (target.hasPointerCapture(event.pointerId)) {
1254
- target.releasePointerCapture(event.pointerId);
1255
- }
1256
- const buttonTarg = target.closest("button") ?? target.closest("div");
1257
- if (buttonTarg !== event.currentTarget) {
1258
- return;
1259
- }
1260
- if (event.button === 0 && event.ctrlKey === false) {
1261
- handleOpen();
1262
- context.triggerPointerDownPosRef.current = {
1263
- x: Math.round(event.pageX),
1264
- y: Math.round(event.pageY)
1265
- };
1266
- event.preventDefault();
1267
- }
1268
- }),
1269
- onKeyDown: primitive.composeEventHandlers(triggerProps.onKeyDown, (event) => {
1270
- const isTypingAhead = searchRef.current !== "";
1271
- const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
1272
- const target = event.target;
1273
- const buttonTarg = target.closest("button") ?? target.closest("div");
1274
- if (buttonTarg !== event.currentTarget) {
1275
- return;
1276
- }
1277
- if (!isModifierKey && event.key.length === 1)
1278
- handleTypeaheadSearch(event.key);
1279
- if (isTypingAhead && event.key === " ")
1280
- return;
1281
- if (OPEN_KEYS.includes(event.key)) {
1282
- handleOpen();
1283
- event.preventDefault();
1284
- }
1285
- })
1286
- }
1287
- ) });
1288
- }
1289
- );
1290
- SelectTrigger.displayName = TRIGGER_NAME;
1291
- const VALUE_NAME = "SelectValue";
1292
- const SelectValue = React__namespace.forwardRef(
1293
- (props, forwardedRef) => {
1294
- const { __scopeSelect, children, placeholder, ...valueProps } = props;
1295
- const context = useSelectContext(VALUE_NAME, __scopeSelect);
1296
- const { onValueNodeHasChildrenChange } = context;
1297
- const hasChildren = children !== void 0;
1298
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, context.onValueNodeChange);
1299
- const [valuedItems, setValuedItems] = React__namespace.useState([]);
1300
- const getItems = useCollection(__scopeSelect);
1301
- reactUseLayoutEffect.useLayoutEffect(() => {
1302
- onValueNodeHasChildrenChange(hasChildren);
1303
- }, [onValueNodeHasChildrenChange, hasChildren]);
1304
- React__namespace.useLayoutEffect(() => {
1305
- if (Array.isArray(context.value) && valuedItems.length !== context.value.length) {
1306
- const timeout = setTimeout(() => {
1307
- const valuedItems2 = getItems().filter(
1308
- (item) => !Array.isArray(item.value) ? context.value?.includes(item.value) : false
1309
- );
1310
- setValuedItems(valuedItems2);
1311
- });
1312
- return () => {
1313
- clearTimeout(timeout);
1314
- };
1315
- }
1316
- }, [context.value, getItems, valuedItems]);
1317
- let renderValue;
1318
- if ((context.value === void 0 || context.value.length === 0) && placeholder !== void 0) {
1319
- renderValue = /* @__PURE__ */ jsxRuntime.jsx("span", { children: placeholder });
1320
- } else if (typeof children === "function") {
1321
- if (Array.isArray(context.value)) {
1322
- const childrenArray = context.value.map((value) => {
1323
- const valueItem = valuedItems.find((item) => item.value === value);
1324
- if (!valueItem) {
1325
- return null;
1326
- }
1327
- return children({ value, textValue: valueItem?.textValue });
1328
- });
1329
- renderValue = childrenArray.every((child) => child === null) ? placeholder : childrenArray;
1330
- } else {
1331
- renderValue = children(context.value);
1332
- }
1333
- } else {
1334
- renderValue = children;
1335
- }
1336
- return /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.span, { ...valueProps, ref: composedRefs, children: renderValue || null });
1337
- }
1338
- );
1339
- SelectValue.displayName = VALUE_NAME;
1340
- const ICON_NAME = "SelectIcon";
1341
- const SelectIcon = React__namespace.forwardRef(
1342
- (props, forwardedRef) => {
1343
- const { __scopeSelect, children, ...iconProps } = props;
1344
- return /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.span, { "aria-hidden": true, ...iconProps, ref: forwardedRef, children: children || "▼" });
1345
- }
1346
- );
1347
- SelectIcon.displayName = ICON_NAME;
1348
- const PORTAL_NAME = "SelectPortal";
1349
- const SelectPortal = (props) => {
1350
- return /* @__PURE__ */ jsxRuntime.jsx(reactPortal.Portal, { asChild: true, ...props });
1351
- };
1352
- SelectPortal.displayName = PORTAL_NAME;
1353
- const CONTENT_NAME = "SelectContent";
1354
- const SelectContent = React__namespace.forwardRef(
1355
- (props, forwardedRef) => {
1356
- const context = useSelectContext(CONTENT_NAME, props.__scopeSelect);
1357
- const [fragment, setFragment] = React__namespace.useState();
1358
- reactUseLayoutEffect.useLayoutEffect(() => {
1359
- setFragment(new DocumentFragment());
1360
- }, []);
1361
- if (!context.open) {
1362
- const frag = fragment;
1363
- return frag ? ReactDOM__namespace.createPortal(
1364
- /* @__PURE__ */ jsxRuntime.jsx(SelectContentProvider, { scope: props.__scopeSelect, children: /* @__PURE__ */ jsxRuntime.jsx(Collection.Slot, { scope: props.__scopeSelect, children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: props.children }) }) }),
1365
- frag
1366
- ) : null;
1367
- }
1368
- return /* @__PURE__ */ jsxRuntime.jsx(SelectContentImpl, { ...props, ref: forwardedRef });
1369
- }
1370
- );
1371
- SelectContent.displayName = CONTENT_NAME;
1372
- const CONTENT_MARGIN = 10;
1373
- const [SelectContentProvider, useSelectContentContext] = createSelectContext(CONTENT_NAME);
1374
- const CONTENT_IMPL_NAME = "SelectContentImpl";
1375
- const SelectContentImpl = React__namespace.forwardRef(
1376
- (props, forwardedRef) => {
1377
- const {
1378
- __scopeSelect,
1379
- position = "item-aligned",
1380
- onCloseAutoFocus,
1381
- onEscapeKeyDown,
1382
- onPointerDownOutside,
1383
- //
1384
- // PopperContent props
1385
- side,
1386
- sideOffset,
1387
- align,
1388
- alignOffset,
1389
- arrowPadding,
1390
- collisionBoundary,
1391
- collisionPadding,
1392
- sticky,
1393
- hideWhenDetached,
1394
- avoidCollisions,
1395
- //
1396
- ...contentProps
1397
- } = props;
1398
- const context = useSelectContext(CONTENT_NAME, __scopeSelect);
1399
- const [content, setContent] = React__namespace.useState(null);
1400
- const [viewport, setViewport] = React__namespace.useState(null);
1401
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, (node) => setContent(node));
1402
- const [selectedItem, setSelectedItem] = React__namespace.useState(null);
1403
- const [selectedItemText, setSelectedItemText] = React__namespace.useState(null);
1404
- const getItems = useCollection(__scopeSelect);
1405
- const [isPositioned, setIsPositioned] = React__namespace.useState(false);
1406
- const firstValidItemFoundRef = React__namespace.useRef(false);
1407
- React__namespace.useEffect(() => {
1408
- if (content)
1409
- return ariaHidden.hideOthers(content);
1410
- }, [content]);
1411
- reactFocusGuards.useFocusGuards();
1412
- const focusFirst = React__namespace.useCallback(
1413
- (candidates) => {
1414
- const [firstItem, ...restItems] = getItems().map((item) => item.ref.current);
1415
- const [lastItem] = restItems.slice(-1);
1416
- const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
1417
- for (const candidate of candidates) {
1418
- if (candidate === PREVIOUSLY_FOCUSED_ELEMENT)
1419
- return;
1420
- candidate?.scrollIntoView({ block: "nearest" });
1421
- if (candidate === firstItem && viewport)
1422
- viewport.scrollTop = 0;
1423
- if (candidate === lastItem && viewport)
1424
- viewport.scrollTop = viewport.scrollHeight;
1425
- candidate?.focus();
1426
- if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT)
1427
- return;
1428
- }
1429
- },
1430
- [getItems, viewport]
1431
- );
1432
- const focusSelectedItem = React__namespace.useCallback(
1433
- () => focusFirst([selectedItem, content]),
1434
- [focusFirst, selectedItem, content]
1435
- );
1436
- React__namespace.useEffect(() => {
1437
- if (isPositioned) {
1438
- focusSelectedItem();
1439
- }
1440
- }, [isPositioned, focusSelectedItem]);
1441
- const { onOpenChange, triggerPointerDownPosRef } = context;
1442
- React__namespace.useEffect(() => {
1443
- if (content) {
1444
- let pointerMoveDelta = { x: 0, y: 0 };
1445
- const handlePointerMove = (event) => {
1446
- pointerMoveDelta = {
1447
- x: Math.abs(Math.round(event.pageX) - (triggerPointerDownPosRef.current?.x ?? 0)),
1448
- y: Math.abs(Math.round(event.pageY) - (triggerPointerDownPosRef.current?.y ?? 0))
1449
- };
1450
- };
1451
- const handlePointerUp = (event) => {
1452
- if (pointerMoveDelta.x <= 10 && pointerMoveDelta.y <= 10) {
1453
- event.preventDefault();
1454
- } else if (!content.contains(event.target)) {
1455
- onOpenChange(false);
1456
- }
1457
- document.removeEventListener("pointermove", handlePointerMove);
1458
- triggerPointerDownPosRef.current = null;
1459
- };
1460
- if (triggerPointerDownPosRef.current !== null) {
1461
- document.addEventListener("pointermove", handlePointerMove);
1462
- document.addEventListener("pointerup", handlePointerUp, { capture: true, once: true });
1463
- }
1464
- return () => {
1465
- document.removeEventListener("pointermove", handlePointerMove);
1466
- document.removeEventListener("pointerup", handlePointerUp, { capture: true });
1467
- };
1468
- }
1469
- }, [content, onOpenChange, triggerPointerDownPosRef]);
1470
- React__namespace.useEffect(() => {
1471
- const close = () => onOpenChange(false);
1472
- window.addEventListener("blur", close);
1473
- window.addEventListener("resize", close);
1474
- return () => {
1475
- window.removeEventListener("blur", close);
1476
- window.removeEventListener("resize", close);
1477
- };
1478
- }, [onOpenChange]);
1479
- const [searchRef, handleTypeaheadSearch] = useTypeaheadSearch((search) => {
1480
- const enabledItems = getItems().filter((item) => !item.disabled);
1481
- const currentItem = enabledItems.find((item) => item.ref.current === document.activeElement);
1482
- const nextItem = findNextItem(enabledItems, search, currentItem);
1483
- if (nextItem) {
1484
- setTimeout(() => nextItem.ref.current.focus());
1485
- }
1486
- });
1487
- const itemRefCallback = React__namespace.useCallback(
1488
- (node, value, disabled) => {
1489
- const isFirstValidItem = !firstValidItemFoundRef.current && !disabled;
1490
- const isSelectedItem = context.value !== void 0 && context.value === value;
1491
- if (isSelectedItem || isFirstValidItem) {
1492
- setSelectedItem(node);
1493
- if (isFirstValidItem)
1494
- firstValidItemFoundRef.current = true;
1495
- }
1496
- },
1497
- [context.value]
1498
- );
1499
- const handleItemLeave = React__namespace.useCallback(() => content?.focus(), [content]);
1500
- const itemTextRefCallback = React__namespace.useCallback(
1501
- (node, value, disabled) => {
1502
- const isFirstValidItem = !firstValidItemFoundRef.current && !disabled;
1503
- const isSelectedItem = context.value !== void 0 && (Array.isArray(value) ? value.every((v) => context.value?.includes(v)) : context.value === value);
1504
- if (isSelectedItem || isFirstValidItem) {
1505
- setSelectedItemText(node);
1506
- }
1507
- },
1508
- [context.value]
1509
- );
1510
- const SelectPosition = position === "popper" ? SelectPopperPosition : SelectItemAlignedPosition;
1511
- const popperContentProps = SelectPosition === SelectPopperPosition ? {
1512
- side,
1513
- sideOffset,
1514
- align,
1515
- alignOffset,
1516
- arrowPadding,
1517
- collisionBoundary,
1518
- collisionPadding,
1519
- sticky,
1520
- hideWhenDetached,
1521
- avoidCollisions
1522
- } : {};
1523
- return /* @__PURE__ */ jsxRuntime.jsx(
1524
- SelectContentProvider,
1525
- {
1526
- scope: __scopeSelect,
1527
- content,
1528
- viewport,
1529
- onViewportChange: setViewport,
1530
- itemRefCallback,
1531
- selectedItem,
1532
- onItemLeave: handleItemLeave,
1533
- itemTextRefCallback,
1534
- focusSelectedItem,
1535
- selectedItemText,
1536
- position,
1537
- isPositioned,
1538
- searchRef,
1539
- children: /* @__PURE__ */ jsxRuntime.jsx(reactRemoveScroll.RemoveScroll, { as: reactSlot.Slot, allowPinchZoom: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1540
- reactFocusScope.FocusScope,
1541
- {
1542
- asChild: true,
1543
- trapped: context.open,
1544
- onMountAutoFocus: (event) => {
1545
- event.preventDefault();
1546
- },
1547
- onUnmountAutoFocus: primitive.composeEventHandlers(onCloseAutoFocus, (event) => {
1548
- context.trigger?.focus({ preventScroll: true });
1549
- document.getSelection()?.empty();
1550
- event.preventDefault();
1551
- }),
1552
- children: /* @__PURE__ */ jsxRuntime.jsx(
1553
- reactDismissableLayer.DismissableLayer,
1554
- {
1555
- asChild: true,
1556
- disableOutsidePointerEvents: true,
1557
- onEscapeKeyDown,
1558
- onPointerDownOutside,
1559
- onFocusOutside: (event) => event.preventDefault(),
1560
- onDismiss: () => context.onOpenChange(false),
1561
- children: /* @__PURE__ */ jsxRuntime.jsx(
1562
- SelectPosition,
1563
- {
1564
- role: "listbox",
1565
- id: context.contentId,
1566
- "data-state": context.open ? "open" : "closed",
1567
- "aria-multiselectable": context.multi ? "true" : void 0,
1568
- dir: context.dir,
1569
- onContextMenu: (event) => event.preventDefault(),
1570
- ...contentProps,
1571
- ...popperContentProps,
1572
- onPlaced: () => setIsPositioned(true),
1573
- ref: composedRefs,
1574
- style: {
1575
- // flex layout so we can place the scroll buttons properly
1576
- display: "flex",
1577
- flexDirection: "column",
1578
- // reset the outline by default as the content MAY get focused
1579
- outline: "none",
1580
- ...contentProps.style
1581
- },
1582
- onKeyDown: primitive.composeEventHandlers(contentProps.onKeyDown, (event) => {
1583
- const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
1584
- if (event.key === "Tab")
1585
- event.preventDefault();
1586
- if (!isModifierKey && event.key.length === 1)
1587
- handleTypeaheadSearch(event.key);
1588
- if (["ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
1589
- const items = getItems().filter((item) => !item.disabled);
1590
- let candidateNodes = items.map((item) => item.ref.current);
1591
- if (["ArrowUp", "End"].includes(event.key)) {
1592
- candidateNodes = candidateNodes.slice().reverse();
1593
- }
1594
- if (["ArrowUp", "ArrowDown"].includes(event.key)) {
1595
- const currentElement = event.target;
1596
- const currentIndex = candidateNodes.indexOf(currentElement);
1597
- candidateNodes = candidateNodes.slice(currentIndex + 1);
1598
- }
1599
- setTimeout(() => focusFirst(candidateNodes));
1600
- event.preventDefault();
1601
- }
1602
- })
1603
- }
1604
- )
1605
- }
1606
- )
1607
- }
1608
- ) })
1609
- }
1610
- );
1611
- }
1612
- );
1613
- SelectContentImpl.displayName = CONTENT_IMPL_NAME;
1614
- const ITEM_ALIGNED_POSITION_NAME = "SelectItemAlignedPosition";
1615
- const SelectItemAlignedPosition = React__namespace.forwardRef(
1616
- (props, forwardedRef) => {
1617
- const { __scopeSelect, onPlaced, ...popperProps } = props;
1618
- const context = useSelectContext(CONTENT_NAME, __scopeSelect);
1619
- const contentContext = useSelectContentContext(CONTENT_NAME, __scopeSelect);
1620
- const [contentWrapper, setContentWrapper] = React__namespace.useState(null);
1621
- const [content, setContent] = React__namespace.useState(null);
1622
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, (node) => setContent(node));
1623
- const getItems = useCollection(__scopeSelect);
1624
- const shouldExpandOnScrollRef = React__namespace.useRef(false);
1625
- const shouldRepositionRef = React__namespace.useRef(true);
1626
- const { viewport, selectedItem, selectedItemText, focusSelectedItem } = contentContext;
1627
- const position = React__namespace.useCallback(() => {
1628
- if (context.trigger && context.valueNode && contentWrapper && content && viewport && selectedItem && selectedItemText) {
1629
- const triggerRect = context.trigger.getBoundingClientRect();
1630
- const contentRect = content.getBoundingClientRect();
1631
- const valueNodeRect = context.valueNode.getBoundingClientRect();
1632
- const itemTextRect = selectedItemText.getBoundingClientRect();
1633
- if (context.dir !== "rtl") {
1634
- const itemTextOffset = itemTextRect.left - contentRect.left;
1635
- const left = valueNodeRect.left - itemTextOffset;
1636
- const leftDelta = triggerRect.left - left;
1637
- const minContentWidth = triggerRect.width + leftDelta;
1638
- const contentWidth = Math.max(minContentWidth, contentRect.width);
1639
- const rightEdge = window.innerWidth - CONTENT_MARGIN;
1640
- const clampedLeft = number.clamp(left, [CONTENT_MARGIN, rightEdge - contentWidth]);
1641
- contentWrapper.style.minWidth = `${minContentWidth}px`;
1642
- contentWrapper.style.left = `${clampedLeft}px`;
1643
- } else {
1644
- const itemTextOffset = contentRect.right - itemTextRect.right;
1645
- const right = window.innerWidth - valueNodeRect.right - itemTextOffset;
1646
- const rightDelta = window.innerWidth - triggerRect.right - right;
1647
- const minContentWidth = triggerRect.width + rightDelta;
1648
- const contentWidth = Math.max(minContentWidth, contentRect.width);
1649
- const leftEdge = window.innerWidth - CONTENT_MARGIN;
1650
- const clampedRight = number.clamp(right, [CONTENT_MARGIN, leftEdge - contentWidth]);
1651
- contentWrapper.style.minWidth = `${minContentWidth}px`;
1652
- contentWrapper.style.right = `${clampedRight}px`;
1653
- }
1654
- const items = getItems();
1655
- const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
1656
- const itemsHeight = viewport.scrollHeight;
1657
- const contentStyles = window.getComputedStyle(content);
1658
- const contentBorderTopWidth = parseInt(contentStyles.borderTopWidth, 10);
1659
- const contentPaddingTop = parseInt(contentStyles.paddingTop, 10);
1660
- const contentBorderBottomWidth = parseInt(contentStyles.borderBottomWidth, 10);
1661
- const contentPaddingBottom = parseInt(contentStyles.paddingBottom, 10);
1662
- const fullContentHeight = contentBorderTopWidth + contentPaddingTop + itemsHeight + contentPaddingBottom + contentBorderBottomWidth;
1663
- const minContentHeight = Math.min(selectedItem.offsetHeight * 5, fullContentHeight);
1664
- const viewportStyles = window.getComputedStyle(viewport);
1665
- const viewportPaddingTop = parseInt(viewportStyles.paddingTop, 10);
1666
- const viewportPaddingBottom = parseInt(viewportStyles.paddingBottom, 10);
1667
- const topEdgeToTriggerMiddle = triggerRect.top + triggerRect.height / 2 - CONTENT_MARGIN;
1668
- const triggerMiddleToBottomEdge = availableHeight - topEdgeToTriggerMiddle;
1669
- const selectedItemHalfHeight = selectedItem.offsetHeight / 2;
1670
- const itemOffsetMiddle = selectedItem.offsetTop + selectedItemHalfHeight;
1671
- const contentTopToItemMiddle = contentBorderTopWidth + contentPaddingTop + itemOffsetMiddle;
1672
- const itemMiddleToContentBottom = fullContentHeight - contentTopToItemMiddle;
1673
- const willAlignWithoutTopOverflow = contentTopToItemMiddle <= topEdgeToTriggerMiddle;
1674
- if (willAlignWithoutTopOverflow) {
1675
- const isLastItem = selectedItem === items[items.length - 1].ref.current;
1676
- contentWrapper.style.bottom = `${0}px`;
1677
- const viewportOffsetBottom = content.clientHeight - viewport.offsetTop - viewport.offsetHeight;
1678
- const clampedTriggerMiddleToBottomEdge = Math.max(
1679
- triggerMiddleToBottomEdge,
1680
- selectedItemHalfHeight + // viewport might have padding bottom, include it to avoid a scrollable viewport
1681
- (isLastItem ? viewportPaddingBottom : 0) + viewportOffsetBottom + contentBorderBottomWidth
1682
- );
1683
- const height = contentTopToItemMiddle + clampedTriggerMiddleToBottomEdge;
1684
- contentWrapper.style.height = `${height}px`;
1685
- } else {
1686
- const isFirstItem = selectedItem === items[0].ref.current;
1687
- contentWrapper.style.top = `${0}px`;
1688
- const clampedTopEdgeToTriggerMiddle = Math.max(
1689
- topEdgeToTriggerMiddle,
1690
- contentBorderTopWidth + viewport.offsetTop + // viewport might have padding top, include it to avoid a scrollable viewport
1691
- (isFirstItem ? viewportPaddingTop : 0) + selectedItemHalfHeight
1692
- );
1693
- const height = clampedTopEdgeToTriggerMiddle + itemMiddleToContentBottom;
1694
- contentWrapper.style.height = `${height}px`;
1695
- viewport.scrollTop = contentTopToItemMiddle - topEdgeToTriggerMiddle + viewport.offsetTop;
1696
- }
1697
- contentWrapper.style.margin = `${CONTENT_MARGIN}px 0`;
1698
- contentWrapper.style.minHeight = `${minContentHeight}px`;
1699
- contentWrapper.style.maxHeight = `${availableHeight}px`;
1700
- onPlaced?.();
1701
- requestAnimationFrame(() => shouldExpandOnScrollRef.current = true);
1702
- }
1703
- }, [
1704
- getItems,
1705
- context.trigger,
1706
- context.valueNode,
1707
- contentWrapper,
1708
- content,
1709
- viewport,
1710
- selectedItem,
1711
- selectedItemText,
1712
- context.dir,
1713
- onPlaced
1714
- ]);
1715
- reactUseLayoutEffect.useLayoutEffect(() => position(), [position]);
1716
- const [contentZIndex, setContentZIndex] = React__namespace.useState();
1717
- reactUseLayoutEffect.useLayoutEffect(() => {
1718
- if (content)
1719
- setContentZIndex(window.getComputedStyle(content).zIndex);
1720
- }, [content]);
1721
- const handleScrollButtonChange = React__namespace.useCallback(
1722
- (node) => {
1723
- if (node && shouldRepositionRef.current === true) {
1724
- position();
1725
- focusSelectedItem?.();
1726
- shouldRepositionRef.current = false;
1727
- }
1728
- },
1729
- [position, focusSelectedItem]
1730
- );
1731
- return /* @__PURE__ */ jsxRuntime.jsx(
1732
- SelectViewportProvider,
1733
- {
1734
- scope: __scopeSelect,
1735
- contentWrapper,
1736
- shouldExpandOnScrollRef,
1737
- onScrollButtonChange: handleScrollButtonChange,
1738
- children: /* @__PURE__ */ jsxRuntime.jsx(
1739
- "div",
1740
- {
1741
- ref: setContentWrapper,
1742
- style: {
1743
- display: "flex",
1744
- flexDirection: "column",
1745
- position: "fixed",
1746
- zIndex: contentZIndex
1747
- },
1748
- children: /* @__PURE__ */ jsxRuntime.jsx(
1749
- reactPrimitive.Primitive.div,
1750
- {
1751
- ...popperProps,
1752
- ref: composedRefs,
1753
- style: {
1754
- // When we get the height of the content, it includes borders. If we were to set
1755
- // the height without having `boxSizing: 'border-box'` it would be too big.
1756
- boxSizing: "border-box",
1757
- // We need to ensure the content doesn't get taller than the wrapper
1758
- maxHeight: "100%",
1759
- ...popperProps.style
1760
- }
1761
- }
1762
- )
1763
- }
1764
- )
1765
- }
1766
- );
1767
- }
1768
- );
1769
- SelectItemAlignedPosition.displayName = ITEM_ALIGNED_POSITION_NAME;
1770
- const POPPER_POSITION_NAME = "SelectPopperPosition";
1771
- const SelectPopperPosition = React__namespace.forwardRef(
1772
- (props, forwardedRef) => {
1773
- const { __scopeSelect, align = "start", collisionPadding = CONTENT_MARGIN, ...popperProps } = props;
1774
- const popperScope = usePopperScope(__scopeSelect);
1775
- return /* @__PURE__ */ jsxRuntime.jsx(
1776
- PopperPrimitive__namespace.Content,
1777
- {
1778
- ...popperScope,
1779
- ...popperProps,
1780
- ref: forwardedRef,
1781
- align,
1782
- collisionPadding,
1783
- style: {
1784
- // Ensure border-box for floating-ui calculations
1785
- boxSizing: "border-box",
1786
- ...popperProps.style,
1787
- // re-namespace exposed content custom properties
1788
- ...{
1789
- "--radix-select-content-transform-origin": "var(--radix-popper-transform-origin)",
1790
- "--radix-select-content-available-width": "var(--radix-popper-available-width)",
1791
- "--radix-select-content-available-height": "var(--radix-popper-available-height)",
1792
- "--radix-select-trigger-width": "var(--radix-popper-anchor-width)",
1793
- "--radix-select-trigger-height": "var(--radix-popper-anchor-height)"
1794
- }
1795
- }
1796
- }
1797
- );
1798
- }
1799
- );
1800
- SelectPopperPosition.displayName = POPPER_POSITION_NAME;
1801
- const [SelectViewportProvider, useSelectViewportContext] = createSelectContext(
1802
- CONTENT_NAME,
1803
- {}
1804
- );
1805
- const VIEWPORT_NAME = "SelectViewport";
1806
- const SelectViewport = React__namespace.forwardRef(
1807
- (props, forwardedRef) => {
1808
- const { __scopeSelect, ...viewportProps } = props;
1809
- const contentContext = useSelectContentContext(VIEWPORT_NAME, __scopeSelect);
1810
- const viewportContext = useSelectViewportContext(VIEWPORT_NAME, __scopeSelect);
1811
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, contentContext.onViewportChange);
1812
- const prevScrollTopRef = React__namespace.useRef(0);
1813
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1814
- /* @__PURE__ */ jsxRuntime.jsx(
1815
- "style",
1816
- {
1817
- dangerouslySetInnerHTML: {
1818
- __html: `[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}`
1819
- }
1820
- }
1821
- ),
1822
- /* @__PURE__ */ jsxRuntime.jsx(Collection.Slot, { scope: __scopeSelect, children: /* @__PURE__ */ jsxRuntime.jsx(
1823
- reactPrimitive.Primitive.div,
1824
- {
1825
- "data-radix-select-viewport": "",
1826
- role: "presentation",
1827
- ...viewportProps,
1828
- ref: composedRefs,
1829
- style: {
1830
- // we use position: 'relative' here on the `viewport` so that when we call
1831
- // `selectedItem.offsetTop` in calculations, the offset is relative to the viewport
1832
- // (independent of the scrollUpButton).
1833
- position: "relative",
1834
- flex: 1,
1835
- overflow: "auto",
1836
- ...viewportProps.style
1837
- },
1838
- onScroll: primitive.composeEventHandlers(viewportProps.onScroll, (event) => {
1839
- const viewport = event.currentTarget;
1840
- const { contentWrapper, shouldExpandOnScrollRef } = viewportContext;
1841
- if (shouldExpandOnScrollRef?.current && contentWrapper) {
1842
- const scrolledBy = Math.abs(prevScrollTopRef.current - viewport.scrollTop);
1843
- if (scrolledBy > 0) {
1844
- const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
1845
- const cssMinHeight = parseFloat(contentWrapper.style.minHeight);
1846
- const cssHeight = parseFloat(contentWrapper.style.height);
1847
- const prevHeight = Math.max(cssMinHeight, cssHeight);
1848
- if (prevHeight < availableHeight) {
1849
- const nextHeight = prevHeight + scrolledBy;
1850
- const clampedNextHeight = Math.min(availableHeight, nextHeight);
1851
- const heightDiff = nextHeight - clampedNextHeight;
1852
- contentWrapper.style.height = `${clampedNextHeight}px`;
1853
- if (contentWrapper.style.bottom === "0px") {
1854
- viewport.scrollTop = heightDiff > 0 ? heightDiff : 0;
1855
- contentWrapper.style.justifyContent = "flex-end";
1856
- }
1857
- }
1858
- }
1859
- }
1860
- prevScrollTopRef.current = viewport.scrollTop;
1861
- })
1862
- }
1863
- ) })
1864
- ] });
1865
- }
1866
- );
1867
- SelectViewport.displayName = VIEWPORT_NAME;
1868
- const GROUP_NAME = "SelectGroup";
1869
- const [SelectGroupContextProvider, useSelectGroupContext] = createSelectContext(GROUP_NAME);
1870
- const SelectGroup = React__namespace.forwardRef(
1871
- (props, forwardedRef) => {
1872
- const { __scopeSelect, ...groupProps } = props;
1873
- const groupId = reactId.useId();
1874
- return /* @__PURE__ */ jsxRuntime.jsx(SelectGroupContextProvider, { scope: __scopeSelect, id: groupId, children: /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.div, { role: "group", "aria-labelledby": groupId, ...groupProps, ref: forwardedRef }) });
1875
- }
1876
- );
1877
- SelectGroup.displayName = GROUP_NAME;
1878
- const LABEL_NAME = "SelectLabel";
1879
- const SelectLabel = React__namespace.forwardRef(
1880
- (props, forwardedRef) => {
1881
- const { __scopeSelect, ...labelProps } = props;
1882
- const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
1883
- return /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.div, { id: groupContext.id, ...labelProps, ref: forwardedRef });
1884
- }
1885
- );
1886
- SelectLabel.displayName = LABEL_NAME;
1887
- const ITEM_NAME = "SelectItem";
1888
- const [SelectItemContextProvider, useSelectItemContext] = createSelectContext(ITEM_NAME);
1889
- const SelectItem = React__namespace.forwardRef(
1890
- (props, forwardedRef) => {
1891
- const { __scopeSelect, value, disabled = false, textValue: textValueProp, ...itemProps } = props;
1892
- const context = useSelectContext(ITEM_NAME, __scopeSelect);
1893
- const contentContext = useSelectContentContext(ITEM_NAME, __scopeSelect);
1894
- const isSelected = typeof value === "string" ? Array.isArray(context.value) ? context.value.includes(value) : context.value === value : value.every((v) => context.value?.includes(v));
1895
- const isIntermediate = Array.isArray(context.value) && Array.isArray(value) && value.some((v) => context.value?.includes(v));
1896
- const [textValue, setTextValue] = React__namespace.useState(textValueProp ?? "");
1897
- const [isFocused, setIsFocused] = React__namespace.useState(false);
1898
- const composedRefs = reactComposeRefs.useComposedRefs(
1899
- forwardedRef,
1900
- (node) => contentContext.itemRefCallback?.(node, value, disabled)
1901
- );
1902
- const textId = reactId.useId();
1903
- const handleSelect = () => {
1904
- if (!disabled) {
1905
- let newValue = context.multi && typeof value === "string" ? [value] : value;
1906
- if (isIntermediate && !isSelected) {
1907
- context.onValueChange(newValue);
1908
- } else if (Array.isArray(context.value)) {
1909
- newValue = toggleArrayValue(value, context.value);
1910
- }
1911
- context.onValueChange(newValue);
1912
- if (!context.multi) {
1913
- context.onOpenChange(false);
1914
- }
1915
- }
1916
- };
1917
- if (!context.multi && Array.isArray(value)) {
1918
- throw new Error("You can only pass an array of values in multi selects");
1919
- }
1920
- return /* @__PURE__ */ jsxRuntime.jsx(
1921
- SelectItemContextProvider,
1922
- {
1923
- scope: __scopeSelect,
1924
- value,
1925
- disabled,
1926
- textId,
1927
- isSelected,
1928
- isIntermediate,
1929
- onItemTextChange: React__namespace.useCallback((node) => {
1930
- setTextValue((prevTextValue) => prevTextValue || (node?.textContent ?? "").trim());
1931
- }, []),
1932
- children: /* @__PURE__ */ jsxRuntime.jsx(Collection.ItemSlot, { scope: __scopeSelect, value, disabled, textValue, children: /* @__PURE__ */ jsxRuntime.jsx(
1933
- reactPrimitive.Primitive.div,
1934
- {
1935
- role: "option",
1936
- "aria-labelledby": textId,
1937
- "data-highlighted": isFocused ? "" : void 0,
1938
- "aria-selected": !context.multi ? isSelected && isFocused : void 0,
1939
- "aria-checked": context.multi ? isSelected : void 0,
1940
- "data-state": isSelected ? "checked" : "unchecked",
1941
- "aria-disabled": disabled || void 0,
1942
- "data-disabled": disabled ? "" : void 0,
1943
- tabIndex: disabled ? void 0 : -1,
1944
- ...itemProps,
1945
- ref: composedRefs,
1946
- onFocus: primitive.composeEventHandlers(itemProps.onFocus, () => setIsFocused(true)),
1947
- onBlur: primitive.composeEventHandlers(itemProps.onBlur, () => setIsFocused(false)),
1948
- onPointerUp: primitive.composeEventHandlers(itemProps.onPointerUp, handleSelect),
1949
- onPointerMove: primitive.composeEventHandlers(itemProps.onPointerMove, (event) => {
1950
- if (disabled) {
1951
- contentContext.onItemLeave?.();
1952
- } else {
1953
- event.currentTarget.focus({ preventScroll: true });
1954
- }
1955
- }),
1956
- onPointerLeave: primitive.composeEventHandlers(itemProps.onPointerLeave, (event) => {
1957
- if (event.currentTarget === document.activeElement) {
1958
- contentContext.onItemLeave?.();
1959
- }
1960
- }),
1961
- onKeyDown: primitive.composeEventHandlers(itemProps.onKeyDown, (event) => {
1962
- const isTypingAhead = contentContext.searchRef?.current !== "";
1963
- if (isTypingAhead && event.key === " ")
1964
- return;
1965
- if (SELECTION_KEYS.includes(event.key))
1966
- handleSelect();
1967
- if (event.key === " ")
1968
- event.preventDefault();
1969
- })
1970
- }
1971
- ) })
1972
- }
1973
- );
1974
- }
1975
- );
1976
- SelectItem.displayName = ITEM_NAME;
1977
- const ITEM_TEXT_NAME = "SelectItemText";
1978
- const SelectItemText = React__namespace.forwardRef(
1979
- (props, forwardedRef) => {
1980
- const { __scopeSelect, className: _className, style: _style, ...itemTextProps } = props;
1981
- const context = useSelectContext(ITEM_TEXT_NAME, __scopeSelect);
1982
- const contentContext = useSelectContentContext(ITEM_TEXT_NAME, __scopeSelect);
1983
- const itemContext = useSelectItemContext(ITEM_TEXT_NAME, __scopeSelect);
1984
- const nativeOptionsContext = useSelectNativeOptionsContext(ITEM_TEXT_NAME, __scopeSelect);
1985
- const [itemTextNode, setItemTextNode] = React__namespace.useState(null);
1986
- const composedRefs = reactComposeRefs.useComposedRefs(
1987
- forwardedRef,
1988
- (node) => setItemTextNode(node),
1989
- itemContext.onItemTextChange,
1990
- (node) => contentContext.itemTextRefCallback?.(node, itemContext.value, itemContext.disabled)
1991
- );
1992
- const textContent = itemTextNode?.textContent;
1993
- const nativeOption = React__namespace.useMemo(
1994
- () => /* @__PURE__ */ jsxRuntime.jsx(
1995
- "option",
1996
- {
1997
- value: itemContext.value,
1998
- disabled: itemContext.disabled,
1999
- children: textContent
2000
- },
2001
- Array.isArray(itemContext.value) ? itemContext.value.join(";") : itemContext.value
2002
- ),
2003
- [itemContext.disabled, itemContext.value, textContent]
2004
- );
2005
- const { onNativeOptionAdd, onNativeOptionRemove } = nativeOptionsContext;
2006
- reactUseLayoutEffect.useLayoutEffect(() => {
2007
- onNativeOptionAdd(nativeOption);
2008
- return () => onNativeOptionRemove(nativeOption);
2009
- }, [onNativeOptionAdd, onNativeOptionRemove, nativeOption]);
2010
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2011
- /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.span, { id: itemContext.textId, ...itemTextProps, ref: composedRefs }),
2012
- itemContext.isSelected && context.valueNode && !context.valueNodeHasChildren ? ReactDOM__namespace.createPortal(itemTextProps.children, context.valueNode) : null
2013
- ] });
2014
- }
2015
- );
2016
- SelectItemText.displayName = ITEM_TEXT_NAME;
2017
- const ITEM_INDICATOR_NAME = "SelectItemIndicator";
2018
- const SelectItemIndicator = React__namespace.forwardRef(
2019
- (props, forwardedRef) => {
2020
- const { __scopeSelect, children, ...itemIndicatorProps } = props;
2021
- const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME, __scopeSelect);
2022
- if (typeof children === "function") {
2023
- return /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.span, { "aria-hidden": true, ...itemIndicatorProps, ref: forwardedRef, children: children({
2024
- isSelected: itemContext.isSelected,
2025
- isIntermediate: itemContext.isIntermediate
2026
- }) });
2027
- }
2028
- return itemContext.isSelected ? /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.span, { "aria-hidden": true, ...itemIndicatorProps, ref: forwardedRef, children }) : null;
2029
- }
2030
- );
2031
- SelectItemIndicator.displayName = ITEM_INDICATOR_NAME;
2032
- const SCROLL_UP_BUTTON_NAME = "SelectScrollUpButton";
2033
- const SelectScrollUpButton = React__namespace.forwardRef(
2034
- (props, forwardedRef) => {
2035
- const contentContext = useSelectContentContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
2036
- const viewportContext = useSelectViewportContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
2037
- const [canScrollUp, setCanScrollUp] = React__namespace.useState(false);
2038
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, viewportContext.onScrollButtonChange);
2039
- reactUseLayoutEffect.useLayoutEffect(() => {
2040
- if (contentContext.viewport && contentContext.isPositioned) {
2041
- const viewport = contentContext.viewport;
2042
- const handleScroll = () => {
2043
- const canScrollUp2 = viewport.scrollTop > 0;
2044
- setCanScrollUp(canScrollUp2);
2045
- };
2046
- handleScroll();
2047
- viewport.addEventListener("scroll", handleScroll);
2048
- return () => viewport.removeEventListener("scroll", handleScroll);
2049
- }
2050
- }, [contentContext.viewport, contentContext.isPositioned]);
2051
- return canScrollUp ? /* @__PURE__ */ jsxRuntime.jsx(
2052
- SelectScrollButtonImpl,
2053
- {
2054
- ...props,
2055
- ref: composedRefs,
2056
- onAutoScroll: () => {
2057
- const { viewport, selectedItem } = contentContext;
2058
- if (viewport && selectedItem) {
2059
- viewport.scrollTop -= selectedItem.offsetHeight;
2060
- }
2061
- }
2062
- }
2063
- ) : null;
2064
- }
2065
- );
2066
- SelectScrollUpButton.displayName = SCROLL_UP_BUTTON_NAME;
2067
- const SCROLL_DOWN_BUTTON_NAME = "SelectScrollDownButton";
2068
- const SelectScrollDownButton = React__namespace.forwardRef(
2069
- (props, forwardedRef) => {
2070
- const contentContext = useSelectContentContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
2071
- const viewportContext = useSelectViewportContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
2072
- const [canScrollDown, setCanScrollDown] = React__namespace.useState(false);
2073
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, viewportContext.onScrollButtonChange);
2074
- reactUseLayoutEffect.useLayoutEffect(() => {
2075
- if (contentContext.viewport && contentContext.isPositioned) {
2076
- const viewport = contentContext.viewport;
2077
- const handleScroll = () => {
2078
- const maxScroll = viewport.scrollHeight - viewport.clientHeight;
2079
- const canScrollDown2 = Math.ceil(viewport.scrollTop) < maxScroll;
2080
- setCanScrollDown(canScrollDown2);
2081
- };
2082
- handleScroll();
2083
- viewport.addEventListener("scroll", handleScroll);
2084
- return () => viewport.removeEventListener("scroll", handleScroll);
2085
- }
2086
- }, [contentContext.viewport, contentContext.isPositioned]);
2087
- return canScrollDown ? /* @__PURE__ */ jsxRuntime.jsx(
2088
- SelectScrollButtonImpl,
2089
- {
2090
- ...props,
2091
- ref: composedRefs,
2092
- onAutoScroll: () => {
2093
- const { viewport, selectedItem } = contentContext;
2094
- if (viewport && selectedItem) {
2095
- viewport.scrollTop += selectedItem.offsetHeight;
2096
- }
2097
- }
2098
- }
2099
- ) : null;
2100
- }
2101
- );
2102
- SelectScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
2103
- const SelectScrollButtonImpl = React__namespace.forwardRef(
2104
- (props, forwardedRef) => {
2105
- const { __scopeSelect, onAutoScroll, ...scrollIndicatorProps } = props;
2106
- const contentContext = useSelectContentContext("SelectScrollButton", __scopeSelect);
2107
- const autoScrollTimerRef = React__namespace.useRef(null);
2108
- const getItems = useCollection(__scopeSelect);
2109
- const clearAutoScrollTimer = React__namespace.useCallback(() => {
2110
- if (autoScrollTimerRef.current !== null) {
2111
- window.clearInterval(autoScrollTimerRef.current);
2112
- autoScrollTimerRef.current = null;
2113
- }
2114
- }, []);
2115
- React__namespace.useEffect(() => {
2116
- return () => clearAutoScrollTimer();
2117
- }, [clearAutoScrollTimer]);
2118
- reactUseLayoutEffect.useLayoutEffect(() => {
2119
- const activeItem = getItems().find((item) => item.ref.current === document.activeElement);
2120
- activeItem?.ref.current?.scrollIntoView({ block: "nearest" });
2121
- }, [getItems]);
2122
- return /* @__PURE__ */ jsxRuntime.jsx(
2123
- reactPrimitive.Primitive.div,
2124
- {
2125
- "aria-hidden": true,
2126
- ...scrollIndicatorProps,
2127
- ref: forwardedRef,
2128
- style: { flexShrink: 0, ...scrollIndicatorProps.style },
2129
- onPointerMove: primitive.composeEventHandlers(scrollIndicatorProps.onPointerMove, () => {
2130
- contentContext.onItemLeave?.();
2131
- if (autoScrollTimerRef.current === null) {
2132
- autoScrollTimerRef.current = window.setInterval(onAutoScroll, 50);
2133
- }
2134
- }),
2135
- onPointerLeave: primitive.composeEventHandlers(scrollIndicatorProps.onPointerLeave, () => {
2136
- clearAutoScrollTimer();
2137
- })
2138
- }
2139
- );
2140
- }
2141
- );
2142
- SelectScrollButtonImpl.displayName = "SelectScrollButtonImpl";
2143
- const SEPARATOR_NAME = "SelectSeparator";
2144
- const SelectSeparator = React__namespace.forwardRef(
2145
- (props, forwardedRef) => {
2146
- const { __scopeSelect, ...separatorProps } = props;
2147
- return /* @__PURE__ */ jsxRuntime.jsx(reactPrimitive.Primitive.div, { "aria-hidden": true, ...separatorProps, ref: forwardedRef });
2148
- }
2149
- );
2150
- SelectSeparator.displayName = SEPARATOR_NAME;
2151
- const ARROW_NAME = "SelectArrow";
2152
- const SelectArrow = React__namespace.forwardRef(
2153
- (props, forwardedRef) => {
2154
- const { __scopeSelect, ...arrowProps } = props;
2155
- const popperScope = usePopperScope(__scopeSelect);
2156
- const context = useSelectContext(ARROW_NAME, __scopeSelect);
2157
- const contentContext = useSelectContentContext(ARROW_NAME, __scopeSelect);
2158
- return context.open && contentContext.position === "popper" ? /* @__PURE__ */ jsxRuntime.jsx(PopperPrimitive__namespace.Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef }) : null;
2159
- }
2160
- );
2161
- SelectArrow.displayName = ARROW_NAME;
2162
- const BUBBLE_SELECT_NAME = "BubbleSelect";
2163
- const BubbleSelect = React__namespace.forwardRef(
2164
- (props, forwardedRef) => {
2165
- const { value, ...selectProps } = props;
2166
- const ref = React__namespace.useRef(null);
2167
- const composedRefs = reactComposeRefs.useComposedRefs(forwardedRef, ref);
2168
- const prevValue = reactUsePrevious.usePrevious(value);
2169
- const context = useSelectContext(BUBBLE_SELECT_NAME, void 0);
2170
- React__namespace.useEffect(() => {
2171
- const select = ref.current;
2172
- const selectProto = window.HTMLSelectElement.prototype;
2173
- const descriptor = Object.getOwnPropertyDescriptor(selectProto, "value");
2174
- const setValue = descriptor.set;
2175
- if (prevValue !== value && setValue) {
2176
- const event = new Event("change", { bubbles: true });
2177
- setValue.call(select, value);
2178
- select.dispatchEvent(event);
2179
- }
2180
- }, [prevValue, value]);
2181
- let defaultValue = value;
2182
- if (context.multi && !Array.isArray(value)) {
2183
- defaultValue = [];
2184
- }
2185
- return /* @__PURE__ */ jsxRuntime.jsx(reactVisuallyHidden.VisuallyHidden, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2186
- "select",
2187
- {
2188
- ...selectProps,
2189
- multiple: context.multi ? true : void 0,
2190
- ref: composedRefs,
2191
- defaultValue
2192
- }
2193
- ) });
2194
- }
2195
- );
2196
- BubbleSelect.displayName = "BubbleSelect";
2197
- function useTypeaheadSearch(onSearchChange) {
2198
- const handleSearchChange = useCallbackRef(onSearchChange);
2199
- const searchRef = React__namespace.useRef("");
2200
- const timerRef = React__namespace.useRef(0);
2201
- const handleTypeaheadSearch = React__namespace.useCallback(
2202
- (key) => {
2203
- const search = searchRef.current + key;
2204
- handleSearchChange(search);
2205
- (function updateSearch(value) {
2206
- searchRef.current = value;
2207
- window.clearTimeout(timerRef.current);
2208
- if (value !== "")
2209
- timerRef.current = window.setTimeout(() => updateSearch(""), 1e3);
2210
- })(search);
2211
- },
2212
- [handleSearchChange]
2213
- );
2214
- const resetTypeahead = React__namespace.useCallback(() => {
2215
- searchRef.current = "";
2216
- window.clearTimeout(timerRef.current);
2217
- }, []);
2218
- React__namespace.useEffect(() => {
2219
- return () => window.clearTimeout(timerRef.current);
2220
- }, []);
2221
- return [searchRef, handleTypeaheadSearch, resetTypeahead];
2222
- }
2223
- function findNextItem(items, search, currentItem) {
2224
- const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
2225
- const normalizedSearch = isRepeated ? search[0] : search;
2226
- const currentItemIndex = currentItem ? items.indexOf(currentItem) : -1;
2227
- let wrappedItems = wrapArray(items, Math.max(currentItemIndex, 0));
2228
- const excludeCurrentItem = normalizedSearch.length === 1;
2229
- if (excludeCurrentItem)
2230
- wrappedItems = wrappedItems.filter((v) => v !== currentItem);
2231
- const nextItem = wrappedItems.find((item) => item.textValue.toLowerCase().startsWith(normalizedSearch.toLowerCase()));
2232
- return nextItem !== currentItem ? nextItem : void 0;
2233
- }
2234
- function wrapArray(array, startIndex) {
2235
- return array.map((_, index) => array[(startIndex + index) % array.length]);
2236
- }
2237
- const toggleArrayValue = (value, array = []) => {
2238
- if (Array.isArray(value)) {
2239
- return value.reduce((acc, val) => toggleArrayValue(val, acc), array);
2240
- }
2241
- const index = array.indexOf(value);
2242
- if (index === -1) {
2243
- return [...array, value];
2244
- }
2245
- return [...array.slice(0, index), ...array.slice(index + 1)];
2246
- };
2247
- const Root = Select;
2248
- const Trigger = SelectTrigger;
2249
- const Value = SelectValue;
2250
- const Icon = SelectIcon;
2251
- const Portal = SelectPortal;
2252
- const Content = SelectContent;
2253
- const Viewport = SelectViewport;
2254
- const Group = SelectGroup;
2255
- const Label = SelectLabel;
2256
- const Item = SelectItem;
2257
- const ItemText = SelectItemText;
2258
- const ItemIndicator = SelectItemIndicator;
2259
- const ScrollUpButton = SelectScrollUpButton;
2260
- const ScrollDownButton = SelectScrollDownButton;
2261
- const Separator = SelectSeparator;
2262
- const Arrow = SelectArrow;
2263
- const Select$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2264
- __proto__: null,
2265
- Arrow,
2266
- Content,
2267
- Group,
2268
- Icon,
2269
- Item,
2270
- ItemIndicator,
2271
- ItemText,
2272
- Label,
2273
- Portal,
2274
- Root,
2275
- ScrollDownButton,
2276
- ScrollUpButton,
2277
- Select,
2278
- SelectArrow,
2279
- SelectContent,
2280
- SelectGroup,
2281
- SelectIcon,
2282
- SelectItem,
2283
- SelectItemIndicator,
2284
- SelectItemText,
2285
- SelectLabel,
2286
- SelectPortal,
2287
- SelectScrollDownButton,
2288
- SelectScrollUpButton,
2289
- SelectSeparator,
2290
- SelectTrigger,
2291
- SelectValue,
2292
- SelectViewport,
2293
- Separator,
2294
- Trigger,
2295
- Value,
2296
- Viewport,
2297
- createSelectScope
2298
- }, Symbol.toStringTag, { value: "Module" }));
2299
- function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
2300
- return function handleEvent(event) {
2301
- originalEventHandler?.(event);
2302
- if (checkForDefaultPrevented === false || !event.defaultPrevented) {
2303
- return ourEventHandler?.(event);
2304
- }
2305
- };
2306
- }
2307
- exports.Combobox = Combobox$1;
2308
- exports.Select = Select$1;
2309
- exports.composeEventHandlers = composeEventHandlers;
2310
- exports.createCollection = createCollection;
2311
- exports.useCallbackRef = useCallbackRef;
2312
- exports.useCollator = useCollator;
2313
- exports.useFilter = useFilter;
2314
- exports.usePrev = usePrev;
2315
- //# sourceMappingURL=index.js.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react/jsx-runtime"),Yt=require("react"),_=require("@radix-ui/react-compose-refs"),ye=require("@radix-ui/react-context"),Ee=require("@radix-ui/react-slot"),V=require("@radix-ui/primitive"),it=require("@radix-ui/react-dismissable-layer"),ct=require("@radix-ui/react-focus-guards"),at=require("@radix-ui/react-focus-scope"),le=require("@radix-ui/react-id"),je=require("@radix-ui/react-popper"),ut=require("@radix-ui/react-portal"),R=require("@radix-ui/react-primitive"),de=require("@radix-ui/react-use-controllable-state"),H=require("@radix-ui/react-use-layout-effect"),dt=require("aria-hidden"),Xt=require("react-dom"),pt=require("react-remove-scroll"),Zt=require("@tanstack/react-virtual"),st=require("@radix-ui/number"),Jt=require("@radix-ui/react-collection"),Qt=require("@radix-ui/react-direction"),eo=require("@radix-ui/react-use-previous"),to=require("@radix-ui/react-visually-hidden");function De(o){const i=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(o){for(const e in o)if(e!=="default"){const t=Object.getOwnPropertyDescriptor(o,e);Object.defineProperty(i,e,t.get?t:{enumerable:!0,get:()=>o[e]})}}return i.default=o,Object.freeze(i)}const l=De(Yt),ie=De(je),Se=De(Xt);function ft(o){const i=`${o}CollectionProvider`,[e,t]=ye.createContextScope(i),[n,r]=e(i,{collectionRef:{current:null},itemMap:new Map,listeners:new Set}),c=d=>{const{scope:f,children:h}=d,b=l.useRef(null),g=l.useRef(new Map).current,p=l.useRef(new Set).current;return u.jsx(n,{scope:f,itemMap:g,collectionRef:b,listeners:p,children:h})};c.displayName=i;const s=`${o}CollectionSlot`,a=l.forwardRef((d,f)=>{const{scope:h,children:b}=d,g=r(s,h),p=_.useComposedRefs(f,g.collectionRef);return u.jsx(Ee.Slot,{ref:p,children:b})});a.displayName=s;const m=`${o}CollectionItemSlot`,v="data-radix-collection-item",C=l.forwardRef((d,f)=>{const{scope:h,children:b,...g}=d,p=l.useRef(null),y=_.useComposedRefs(f,p),E=r(m,h);return l.useEffect(()=>{const O=Array.from(E.itemMap.values());return E.itemMap.set(p,{ref:p,...g}),E.listeners.forEach(L=>L(Array.from(E.itemMap.values()),O)),()=>{const L=Array.from(E.itemMap.values());E.itemMap.delete(p),E.listeners.forEach(A=>A(Array.from(E.itemMap.values()),L))}}),u.jsx(Ee.Slot,{[v]:"",ref:y,children:b})});C.displayName=m;function x(d){const f=r(`${o}CollectionConsumer`,d),h=l.useCallback(()=>{const g=f.collectionRef.current;if(!g)return[];const p=Array.from(g.querySelectorAll(`[${v}]`));return Array.from(f.itemMap.values()).sort((O,L)=>p.indexOf(O.ref.current)-p.indexOf(L.ref.current))},[f.collectionRef,f.itemMap]),b=l.useCallback(g=>(f.listeners.add(g),()=>f.listeners.delete(g)),[f.listeners]);return{getItems:h,subscribe:b}}return[{Provider:c,Slot:a,ItemSlot:C},x,t]}const Ve=new Map;function mt(o,i){const e=o+(i?Object.entries(i).sort((n,r)=>n[0]<r[0]?-1:1).join():"");if(Ve.has(e))return Ve.get(e);const t=new Intl.Collator(o,i);return Ve.set(e,t),t}function we(o,i){const e=mt(o,{usage:"search",...i});return{startsWith(t,n){return n.length===0?!0:(t=t.normalize("NFC"),n=n.normalize("NFC"),e.compare(t.slice(0,n.length),n)===0)},endsWith(t,n){return n.length===0?!0:(t=t.normalize("NFC"),n=n.normalize("NFC"),e.compare(t.slice(-n.length),n)===0)},contains(t,n){if(n.length===0)return!0;t=t.normalize("NFC"),n=n.normalize("NFC");let r=0;const c=n.length;for(;r+c<=t.length;r++){const s=t.slice(r,r+c);if(e.compare(n,s)===0)return!0}return!1}}}const ht=o=>{const i=l.useRef();return l.useEffect(()=>{i.current=o}),i.current},xt=l.forwardRef(({children:o,estimatedItemSize:i=40,overscan:e=5,getItemCount:t,onViewportChange:n,...r},c)=>{const s=l.useRef(null),a=_.useComposedRefs(c,s,n),m=l.useMemo(()=>l.Children.toArray(o),[o]),v=Zt.useVirtualizer({count:t(),getScrollElement:()=>s.current,estimateSize:()=>i,overscan:e}),C=v.getVirtualItems();return u.jsxs(u.Fragment,{children:[u.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-combobox-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-combobox-viewport]::-webkit-scrollbar{display:none}"}}),u.jsx(R.Primitive.div,{"data-radix-combobox-viewport":"",role:"presentation",...r,ref:a,style:{position:"relative",flex:1,overflow:"auto",...r.style},children:u.jsx("div",{style:{height:`${v.getTotalSize()}px`,width:"100%",position:"relative"},children:C.map(x=>{const d=m[x.index];return u.jsx("div",{"data-index":x.index,ref:v.measureElement,style:{position:"absolute",top:0,left:0,width:"100%",transform:`translateY(${x.start}px)`},children:d},x.key)})})})]})});xt.displayName="VirtualizedViewport";const oo=[" ","Enter","ArrowUp","ArrowDown"],no=["Enter"],ro=o=>!!(o.length===1&&o.match(/\S| /)),gt="Combobox",[re,ge]=ft(gt),[so,G]=ye.createContext(gt),lo=({children:o})=>u.jsx(ie.Root,{children:u.jsx(re.Provider,{scope:void 0,children:o})}),io=o=>typeof o=="string"?o==="none"?{type:o,filter:void 0}:{type:o,filter:"startsWith"}:o,co=o=>{const{allowCustomValue:i=!1,autocomplete:e="none",children:t,open:n,defaultOpen:r,onOpenChange:c,value:s,defaultValue:a,onValueChange:m,disabled:v,required:C=!1,locale:x="en-EN",onTextValueChange:d,textValue:f,defaultTextValue:h,filterValue:b,defaultFilterValue:g,onFilterValueChange:p,isPrintableCharacter:y=ro,visible:E=!1,virtualized:O="auto",estimatedItemSize:L=40,overscan:A=5}=o,[D,Z]=l.useState(null),[B,z]=l.useState(null),[N,$]=l.useState(null),[F,U]=l.useState(null),[J=!1,Q]=de.useControllableState({prop:n,defaultProp:r,onChange:c}),[W,q]=de.useControllableState({prop:s,defaultProp:a,onChange:m}),[ce,ee]=de.useControllableState({prop:f,defaultProp:i&&!h?s:h,onChange:d}),[fe,me]=de.useControllableState({prop:b,defaultProp:g,onChange:p}),te=le.useId(),ae=l.useCallback((S,I)=>{var K;const M=I.map(j=>j.ref.current),[P,...T]=M,[w]=T.slice(-1),k=F??((K=I.find(j=>j.value===W))==null?void 0:K.ref.current);for(const j of S){if(j===k)return;if(j==null||j.scrollIntoView({block:"nearest"}),j===P&&B&&(B.scrollTop=0),j===w&&B&&(B.scrollTop=B.scrollHeight),U(j),e==="both"){const ue=I.find(he=>he.ref.current===j);ue&&ee(ue.textValue)}if(j!==k)return}},[e,ee,B,F,W]),ne=io(e);return l.useEffect(()=>{e!=="both"&&U(null)},[ce,e]),l.useEffect(()=>{if(N&&D)return dt.hideOthers([N,D])},[N,D]),u.jsx(lo,{children:u.jsx(so,{allowCustomValue:i,autocomplete:ne,required:C,trigger:D,onTriggerChange:Z,contentId:te,value:W,onValueChange:q,open:J,onOpenChange:Q,disabled:v,locale:x,focusFirst:ae,textValue:ce,onTextValueChange:ee,onViewportChange:z,onContentChange:$,visuallyFocussedItem:F,filterValue:fe,onFilterValueChange:me,onVisuallyFocussedItemChange:U,isPrintableCharacter:y,visible:E,virtualized:O,estimatedItemSize:L,overscan:A,children:t})})},vt="ComboboxTrigger",Ct=l.forwardRef((o,i)=>{const{...e}=o,t=G(vt),n=()=>{t.disabled||t.onOpenChange(!0)};return u.jsx(ie.Anchor,{asChild:!0,children:u.jsx(at.FocusScope,{asChild:!0,trapped:t.open,onMountAutoFocus:r=>{r.preventDefault()},onUnmountAutoFocus:r=>{var c,s;(c=t.trigger)==null||c.focus({preventScroll:!0}),(s=document.getSelection())==null||s.empty(),r.preventDefault()},children:u.jsx("div",{ref:i,"data-disabled":t.disabled?"":void 0,...e,onClick:V.composeEventHandlers(e.onClick,r=>{var c;if(t.disabled){r.preventDefault();return}(c=t.trigger)==null||c.focus()}),onPointerDown:V.composeEventHandlers(e.onPointerDown,r=>{var a;if(t.disabled){r.preventDefault();return}const c=r.target;c.hasPointerCapture(r.pointerId)&&c.releasePointerCapture(r.pointerId),(c.closest("button")??c.closest("div"))===r.currentTarget&&r.button===0&&r.ctrlKey===!1&&(n(),(a=t.trigger)==null||a.focus())})})})})});Ct.displayName=vt;const bt="ComboboxInput",yt=l.forwardRef((o,i)=>{var v;const e=G(bt),t=l.useRef(null),{getItems:n}=ge(void 0),{startsWith:r}=we(e.locale,{sensitivity:"base"}),c=e.disabled,s=_.useComposedRefs(t,i,e.onTriggerChange),a=()=>{c||e.onOpenChange(!0)},m=ht(e.filterValue);return H.useLayoutEffect(()=>{const C=setTimeout(()=>{var f;if(e.textValue===""||e.textValue===void 0||e.filterValue===""||e.filterValue===void 0)return;const x=n().find(h=>h.type==="option"&&r(h.textValue,e.textValue)),d=Io(m??"",e.filterValue);x&&!e.visuallyFocussedItem&&d===e.filterValue.length&&((f=t.current)==null||f.setSelectionRange(e.filterValue.length,e.textValue.length))});return()=>clearTimeout(C)},[e.textValue,e.filterValue,r,e.visuallyFocussedItem,n,m]),u.jsx("input",{type:"text",role:"combobox","aria-controls":e.contentId,"aria-expanded":e.open,"aria-required":e.required,"aria-autocomplete":e.autocomplete.type,"data-state":e.open?"open":"closed","aria-disabled":c,"aria-activedescendant":(v=e.visuallyFocussedItem)==null?void 0:v.id,disabled:c,"data-disabled":c?"":void 0,"data-placeholder":e.textValue===void 0?"":void 0,value:e.textValue??"",...o,ref:s,onKeyDown:V.composeEventHandlers(o.onKeyDown,C=>{var x,d;if(["ArrowUp","ArrowDown","Home","End"].includes(C.key))e.open||a(),setTimeout(()=>{var b;let h=n().filter(g=>!g.disabled&&g.isVisible).map(g=>g.ref.current);if(["ArrowUp","End"].includes(C.key)&&(h=h.slice().reverse()),["ArrowUp","ArrowDown"].includes(C.key)){const g=e.visuallyFocussedItem??((b=n().find(p=>p.value===e.value))==null?void 0:b.ref.current);if(g){let p=h.indexOf(g);p===h.length-1&&(p=-1),h=h.slice(p+1)}}if(["ArrowDown"].includes(C.key)&&e.autocomplete.type==="both"&&h.length>1){const[g,...p]=h,y=n().find(E=>E.ref.current===g).textValue;e.textValue===y&&(h=p)}e.focusFirst(h,n())}),C.preventDefault();else if(["Tab"].includes(C.key)&&e.open)C.preventDefault();else if(["Escape"].includes(C.key))e.open?e.onOpenChange(!1):(e.onValueChange(void 0),e.onTextValueChange("")),C.preventDefault();else if(no.includes(C.key)){if(e.visuallyFocussedItem){const f=n().find(h=>h.ref.current===e.visuallyFocussedItem);f&&(e.onValueChange(f.value),e.onTextValueChange(f.textValue),e.autocomplete.type==="both"&&e.onFilterValueChange(f.textValue),(x=f.ref.current)==null||x.click())}else{const f=n().find(h=>h.type==="option"&&!h.disabled&&h.textValue===e.textValue);f&&(e.onValueChange(f.value),e.onTextValueChange(f.textValue),e.autocomplete.type==="both"&&e.onFilterValueChange(f.textValue),(d=f.ref.current)==null||d.click())}e.onOpenChange(!1),C.preventDefault()}else e.onVisuallyFocussedItemChange(null)}),onChange:V.composeEventHandlers(o.onChange,C=>{e.onTextValueChange(C.currentTarget.value),e.autocomplete.type==="both"&&e.onFilterValueChange(C.currentTarget.value)}),onKeyUp:V.composeEventHandlers(o.onKeyUp,C=>{var x;if(!e.open&&(e.isPrintableCharacter(C.key)||["Backspace"].includes(C.key))&&a(),setTimeout(()=>{if(e.autocomplete.type==="both"&&e.isPrintableCharacter(C.key)&&e.filterValue!==void 0){const d=e.filterValue,f=n().find(h=>r(h.textValue,d));f&&e.onTextValueChange(f.textValue)}}),e.autocomplete.type==="none"&&e.isPrintableCharacter(C.key)){const d=e.textValue??"",f=n().find(h=>r(h.textValue,d));f&&(e.onVisuallyFocussedItemChange(f.ref.current),(x=f.ref.current)==null||x.scrollIntoView())}}),onBlur:V.composeEventHandlers(o.onBlur,()=>{if(e.open)return;e.onVisuallyFocussedItemChange(null);const[C]=n().filter(d=>d.textValue===e.textValue&&d.type==="option");if(C){e.onValueChange(C.value),e.autocomplete.type==="both"&&e.onFilterValueChange(C.textValue);return}if(e.allowCustomValue){e.onValueChange(e.textValue),e.autocomplete.type==="both"&&e.onFilterValueChange(e.textValue);return}const[x]=n().filter(d=>d.value===e.value&&d.type==="option");x&&e.textValue!==""?(e.onTextValueChange(x.textValue),e.autocomplete.type==="both"&&e.onFilterValueChange(x.textValue)):(e.onValueChange(void 0),e.onTextValueChange(""))})})});yt.displayName="ComboboxTextInput";const St=l.forwardRef((o,i)=>{const{children:e,...t}=o,n=G(bt),r=n.disabled,c=()=>{var s;r||(n.onOpenChange(!0),(s=n.trigger)==null||s.focus())};return u.jsx(R.Primitive.button,{"aria-hidden":!0,type:"button","aria-disabled":r,"aria-controls":n.contentId,"aria-expanded":n.open,disabled:r,"data-disabled":r?"":void 0,...t,tabIndex:-1,ref:i,onClick:V.composeEventHandlers(t.onClick,()=>{var s;(s=n.trigger)==null||s.focus()}),onPointerDown:V.composeEventHandlers(t.onPointerDown,s=>{s.button===0&&s.ctrlKey===!1&&(c(),s.preventDefault())}),onKeyDown:V.composeEventHandlers(t.onKeyDown,s=>{oo.includes(s.key)&&(c(),s.preventDefault())}),children:e||"▼"})});St.displayName="ComboboxIcon";const ao="ComboboxPortal",wt=o=>u.jsx(ut.Portal,{asChild:!0,...o});wt.displayName=ao;const Le="ComboboxContent",It=l.forwardRef((o,i)=>{const e=G(Le),{getItems:t}=ge(void 0),[n,r]=l.useState();if(H.useLayoutEffect(()=>{r(new DocumentFragment)},[]),H.useLayoutEffect(()=>{e.open&&e.autocomplete.type==="none"&&setTimeout(()=>{var s;const c=t().find(a=>a.value===e.value);(s=c==null?void 0:c.ref.current)==null||s.scrollIntoView({block:"nearest"})})},[t,e.autocomplete,e.value,e.open]),!e.open){const c=n;return c?Se.createPortal(u.jsx(re.Slot,{scope:void 0,children:u.jsx("div",{children:o.children})}),c):null}return u.jsx(Tt,{...o,ref:i})});It.displayName=Le;const uo=10,Tt=l.forwardRef((o,i)=>{const{onEscapeKeyDown:e,onPointerDownOutside:t,...n}=o,r=G(Le),c=_.useComposedRefs(i,a=>r.onContentChange(a)),{onOpenChange:s}=r;return ct.useFocusGuards(),l.useEffect(()=>{const a=()=>{s(!1)};return window.addEventListener("blur",a),window.addEventListener("resize",a),()=>{window.removeEventListener("blur",a),window.removeEventListener("resize",a)}},[s]),u.jsx(pt.RemoveScroll,{allowPinchZoom:!0,children:u.jsx(it.DismissableLayer,{asChild:!0,onEscapeKeyDown:e,onPointerDownOutside:t,onFocusOutside:a=>{a.preventDefault()},onDismiss:()=>{var a;r.onOpenChange(!1),(a=r.trigger)==null||a.focus({preventScroll:!0})},children:u.jsx(Pt,{role:"listbox",id:r.contentId,"data-state":r.open?"open":"closed",onContextMenu:a=>a.preventDefault(),...n,ref:c,style:{display:"flex",flexDirection:"column",outline:"none",...n.style}})})})});Tt.displayName="ComboboxContentImpl";const Pt=l.forwardRef((o,i)=>{const{align:e="start",collisionPadding:t=uo,...n}=o;return u.jsx(ie.Content,{...n,ref:i,align:e,collisionPadding:t,style:{boxSizing:"border-box",...n.style,"--radix-combobox-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-combobox-content-available-width":"var(--radix-popper-available-width)","--radix-combobox-content-available-height":"var(--radix-popper-available-height)","--radix-combobox-trigger-width":"var(--radix-popper-anchor-width)","--radix-combobox-trigger-height":"var(--radix-popper-anchor-height)"}})});Pt.displayName="ComboboxPopperPosition";const Vt="ComboboxViewport",Et=l.forwardRef((o,i)=>{const e=G(Vt),t=_.useComposedRefs(i,e.onViewportChange),r=l.useMemo(()=>l.Children.toArray(o.children),[o.children]).length;return e.virtualized===!0||e.virtualized==="auto"&&r>100?u.jsx(re.Slot,{scope:void 0,children:u.jsx(xt,{...o,ref:t,getItemCount:()=>r,estimatedItemSize:e.estimatedItemSize,overscan:e.overscan,onViewportChange:e.onViewportChange})}):u.jsxs(u.Fragment,{children:[u.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-combobox-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-combobox-viewport]::-webkit-scrollbar{display:none}"}}),u.jsx(re.Slot,{scope:void 0,children:u.jsx(R.Primitive.div,{"data-radix-combobox-viewport":"",role:"presentation",...o,ref:t,style:{position:"relative",flex:1,overflow:"auto",...o.style}})})]})});Et.displayName=Vt;const Ie="ComboboxItem",[lt,Fe]=ye.createContext(Ie),ke=l.forwardRef((o,i)=>{const{value:e,disabled:t=!1,textValue:n,...r}=o,[c,s]=l.useState();H.useLayoutEffect(()=>{s(new DocumentFragment)},[]);const{onTextValueChange:a,textValue:m,...v}=G(Ie),C=le.useId(),[x,d]=l.useState(n??""),f=v.value===e,{startsWith:h,contains:b}=we(v.locale,{sensitivity:"base"}),g=l.useCallback(p=>{d(y=>y||((p==null?void 0:p.textContent)??"").trim())},[]);return l.useEffect(()=>{f&&m===void 0&&x!==""&&a(x)},[x,f,m,a]),v.autocomplete.type==="both"&&x&&v.filterValue&&!h(x,v.filterValue)||v.autocomplete.type==="list"&&v.autocomplete.filter==="startsWith"&&x&&m&&!h(x,m)||v.autocomplete.type==="list"&&v.autocomplete.filter==="contains"&&x&&m&&!b(x,m)?c?Se.createPortal(u.jsx(lt,{textId:C,onTextValueChange:g,isSelected:f,textValue:x,children:u.jsx(re.ItemSlot,{scope:void 0,value:e,textValue:x,disabled:t,type:"option",isVisible:!1,children:u.jsx(Re,{ref:i,value:e,disabled:t,...r})})}),c):null:u.jsx(lt,{textId:C,onTextValueChange:g,isSelected:f,textValue:x,children:u.jsx(re.ItemSlot,{scope:void 0,value:e,textValue:x,disabled:t,type:"option",isVisible:!0,children:u.jsx(Re,{ref:i,value:e,disabled:t,...r})})})});ke.displayName=Ie;const Rt="ComboboxItemImpl",Re=l.forwardRef((o,i)=>{const{value:e,disabled:t=!1,...n}=o,r=l.useRef(null),c=_.useComposedRefs(i,r),{getItems:s}=ge(void 0),{onTextValueChange:a,visuallyFocussedItem:m,...v}=G(Ie),{isSelected:C,textValue:x,textId:d}=Fe(Rt),f=()=>{var g;t||(v.onValueChange(e),a(x),v.onOpenChange(!1),v.autocomplete.type==="both"&&v.onFilterValueChange(x),(g=v.trigger)==null||g.focus({preventScroll:!0}))},h=l.useMemo(()=>{var g;return m===((g=s().find(p=>p.ref.current===r.current))==null?void 0:g.ref.current)},[s,m]),b=le.useId();return u.jsx(R.Primitive.div,{role:"option","aria-labelledby":d,"data-highlighted":h?"":void 0,"aria-selected":C&&h,"data-state":C?"checked":"unchecked","aria-disabled":t||void 0,"data-disabled":t?"":void 0,tabIndex:t?void 0:-1,...n,id:b,ref:c,onPointerUp:V.composeEventHandlers(n.onPointerUp,f)})});Re.displayName=Rt;const Nt="ComboboxItemText",_t=l.forwardRef((o,i)=>{const{className:e,style:t,...n}=o,r=Fe(Nt),c=_.useComposedRefs(i,r.onTextValueChange);return u.jsx(R.Primitive.span,{id:r.textId,...n,ref:c})});_t.displayName=Nt;const At="ComboboxItemIndicator",Mt=l.forwardRef((o,i)=>{const{isSelected:e}=Fe(At);return e?u.jsx(R.Primitive.span,{"aria-hidden":!0,...o,ref:i}):null});Mt.displayName=At;const He="ComboboxNoValueFound",Ot=l.forwardRef((o,i)=>{const{textValue:e="",filterValue:t="",visible:n=!1,locale:r,autocomplete:c}=G(He),[s,a]=l.useState([]),{subscribe:m}=ge(void 0),{startsWith:v,contains:C}=we(r,{sensitivity:"base"});return l.useEffect(()=>{const x=m(d=>{if(n){const f=d.filter(h=>h.type!=="create");a(f)}else a(d)});return()=>{x()}},[n,m]),c.type==="none"&&s.length>0||c.type==="list"&&c.filter==="startsWith"&&s.some(x=>v(x.textValue,e))||c.type==="both"&&s.some(x=>v(x.textValue,t))||c.type==="list"&&c.filter==="contains"&&s.some(x=>C(x.textValue,e))?null:u.jsx(R.Primitive.div,{...o,ref:i})});Ot.displayName=He;const jt=l.forwardRef((o,i)=>{const{disabled:e=!1,...t}=o,n=G(He),{textValue:r,visuallyFocussedItem:c}=n,{getItems:s,subscribe:a}=ge(void 0),m=l.useRef(null),[v,C]=l.useState(!1),x=_.useComposedRefs(i,m),d=l.useMemo(()=>{var b;return c===((b=s().find(g=>g.ref.current===m.current))==null?void 0:b.ref.current)},[s,c]),f=le.useId(),h=()=>{var b;!e&&r&&(n.onValueChange(r),n.onTextValueChange(r),n.onOpenChange(!1),n.autocomplete.type==="both"&&n.onFilterValueChange(r),(b=n.trigger)==null||b.focus({preventScroll:!0}))};return H.useLayoutEffect(()=>{const b=a(g=>{C(!g.some(p=>p.textValue===r&&p.type!=="create"))});return s().length===0&&C(!0),()=>{b()}},[r,a,s]),(!r||!v)&&!n.visible?null:u.jsx(re.ItemSlot,{scope:void 0,value:r??"",textValue:r??"",disabled:e,isVisible:!0,type:"create",children:u.jsx(R.Primitive.div,{role:"option",tabIndex:e?void 0:-1,"aria-disabled":e||void 0,"data-disabled":e?"":void 0,"data-highlighted":d?"":void 0,...t,id:f,ref:x,onPointerUp:V.composeEventHandlers(t.onPointerUp,h)})})});jt.displayName="ComboboxCreateItem";const po=co,fo=Ct,mo=yt,ho=St,xo=wt,go=It,vo=Et,Co=ke,bo=_t,yo=Mt,So=Ot,wo=jt;function Io(o,i){const e=Math.min(o.length,i.length);for(let t=0;t<e;t++)if(o[t]!==i[t])return t;return e}const To=Object.freeze(Object.defineProperty({__proto__:null,ComboboxItem:ke,Content:go,CreateItem:wo,Icon:ho,Item:Co,ItemIndicator:yo,ItemText:bo,NoValueFound:So,Portal:xo,Root:po,TextInput:mo,Trigger:fo,Viewport:vo},Symbol.toStringTag,{value:"Module"}));function Dt(o){const i=l.useRef(o);return l.useEffect(()=>{i.current=o}),l.useMemo(()=>(...e)=>{var t;return(t=i.current)==null?void 0:t.call(i,...e)},[])}const Po=[" ","Enter","ArrowUp","ArrowDown"],Vo=[" ","Enter"],ve="Select",[Te,Ce,Eo]=Jt.createCollection(ve),[pe,Ro]=ye.createContextScope(ve,[Eo,je.createPopperScope]),Pe=je.createPopperScope(),[No,X]=pe(ve),[_o,Ao]=pe(ve),Be=o=>{const{__scopeSelect:i,children:e,open:t,defaultOpen:n,onOpenChange:r,value:c,defaultValue:s,onValueChange:a,dir:m,disabled:v,required:C,multi:x=!1}=o,d=Pe(i),[f,h]=l.useState(null),[b,g]=l.useState(null),[p,y]=l.useState(!1),E=Qt.useDirection(m),[O=!1,L]=de.useControllableState({prop:t,defaultProp:n,onChange:r}),[A,D]=de.useControllableState({prop:c,defaultProp:s,onChange(N){a&&(Array.isArray(N),a(N))}}),Z=l.useRef(null),[B,z]=l.useState(new Set);return u.jsx(ie.Root,{...d,children:u.jsx(No,{required:C,scope:i,trigger:f,onTriggerChange:h,valueNode:b,onValueNodeChange:g,valueNodeHasChildren:p,onValueNodeHasChildrenChange:y,contentId:le.useId(),value:A,onValueChange:D,open:O,onOpenChange:L,dir:E,triggerPointerDownPosRef:Z,disabled:v,multi:x,children:u.jsx(Te.Provider,{scope:i,children:u.jsx(_o,{scope:o.__scopeSelect,onNativeOptionAdd:l.useCallback(N=>{z($=>new Set($).add(N))},[]),onNativeOptionRemove:l.useCallback(N=>{z($=>{const F=new Set($);return F.delete(N),F})},[]),children:e})})})})};Be.displayName=ve;const Lt="SelectTrigger",$e=l.forwardRef((o,i)=>{const{__scopeSelect:e,...t}=o,n=Pe(e),r=X(Lt,e),c=r.disabled,s=_.useComposedRefs(i,r.onTriggerChange),a=Ce(e),[m,v,C]=qt(d=>{const f=a().filter(g=>!g.disabled),h=f.find(g=>g.value===r.value),b=Kt(f,d,h);if(b!==void 0&&!Array.isArray(b.value)){const g=r.multi?[b.value]:b.value;r.onValueChange(g)}}),x=()=>{c||(r.onOpenChange(!0),C())};return u.jsx(ie.Anchor,{asChild:!0,...n,children:u.jsx(R.Primitive.div,{role:"combobox","aria-controls":r.contentId,"aria-expanded":r.open,"aria-required":r.required,"aria-autocomplete":"none",dir:r.dir,"data-state":r.open?"open":"closed","data-disabled":c?"":void 0,"data-placeholder":r.value===void 0?"":void 0,tabIndex:c?void 0:0,...t,ref:s,onClick:V.composeEventHandlers(t.onClick,d=>{d.currentTarget.focus()}),onPointerDown:V.composeEventHandlers(t.onPointerDown,d=>{const f=d.target;f.hasPointerCapture(d.pointerId)&&f.releasePointerCapture(d.pointerId),(f.closest("button")??f.closest("div"))===d.currentTarget&&d.button===0&&d.ctrlKey===!1&&(x(),r.triggerPointerDownPosRef.current={x:Math.round(d.pageX),y:Math.round(d.pageY)},d.preventDefault())}),onKeyDown:V.composeEventHandlers(t.onKeyDown,d=>{const f=m.current!=="",h=d.ctrlKey||d.altKey||d.metaKey,b=d.target;(b.closest("button")??b.closest("div"))===d.currentTarget&&(!h&&d.key.length===1&&v(d.key),!(f&&d.key===" ")&&Po.includes(d.key)&&(x(),d.preventDefault()))})})})});$e.displayName=Lt;const Ft="SelectValue",Ue=l.forwardRef((o,i)=>{const{__scopeSelect:e,children:t,placeholder:n,...r}=o,c=X(Ft,e),{onValueNodeHasChildrenChange:s}=c,a=t!==void 0,m=_.useComposedRefs(i,c.onValueNodeChange),[v,C]=l.useState([]),x=Ce(e);H.useLayoutEffect(()=>{s(a)},[s,a]),l.useLayoutEffect(()=>{if(Array.isArray(c.value)&&v.length!==c.value.length){const f=setTimeout(()=>{const h=x().filter(b=>{var g;return Array.isArray(b.value)?!1:(g=c.value)==null?void 0:g.includes(b.value)});C(h)});return()=>{clearTimeout(f)}}},[c.value,x,v]);let d;if((c.value===void 0||c.value.length===0)&&n!==void 0)d=u.jsx("span",{children:n});else if(typeof t=="function")if(Array.isArray(c.value)){const f=c.value.map(h=>{const b=v.find(g=>g.value===h);return b?t({value:h,textValue:b==null?void 0:b.textValue}):null});d=f.every(h=>h===null)?n:f}else d=t(c.value);else d=t;return u.jsx(R.Primitive.span,{...r,ref:m,children:d||null})});Ue.displayName=Ft;const Mo="SelectIcon",ze=l.forwardRef((o,i)=>{const{__scopeSelect:e,children:t,...n}=o;return u.jsx(R.Primitive.span,{"aria-hidden":!0,...n,ref:i,children:t||"▼"})});ze.displayName=Mo;const Oo="SelectPortal",We=o=>u.jsx(ut.Portal,{asChild:!0,...o});We.displayName=Oo;const se="SelectContent",qe=l.forwardRef((o,i)=>{const e=X(se,o.__scopeSelect),[t,n]=l.useState();if(H.useLayoutEffect(()=>{n(new DocumentFragment)},[]),!e.open){const r=t;return r?Se.createPortal(u.jsx(kt,{scope:o.__scopeSelect,children:u.jsx(Te.Slot,{scope:o.__scopeSelect,children:u.jsx("div",{children:o.children})})}),r):null}return u.jsx(Ht,{...o,ref:i})});qe.displayName=se;const Y=10,[kt,oe]=pe(se),jo="SelectContentImpl",Ht=l.forwardRef((o,i)=>{const{__scopeSelect:e,position:t="item-aligned",onCloseAutoFocus:n,onEscapeKeyDown:r,onPointerDownOutside:c,side:s,sideOffset:a,align:m,alignOffset:v,arrowPadding:C,collisionBoundary:x,collisionPadding:d,sticky:f,hideWhenDetached:h,avoidCollisions:b,...g}=o,p=X(se,e),[y,E]=l.useState(null),[O,L]=l.useState(null),A=_.useComposedRefs(i,S=>E(S)),[D,Z]=l.useState(null),[B,z]=l.useState(null),N=Ce(e),[$,F]=l.useState(!1),U=l.useRef(!1);l.useEffect(()=>{if(y)return dt.hideOthers(y)},[y]),ct.useFocusGuards();const J=l.useCallback(S=>{const[I,...M]=N().map(w=>w.ref.current),[P]=M.slice(-1),T=document.activeElement;for(const w of S)if(w===T||(w==null||w.scrollIntoView({block:"nearest"}),w===I&&O&&(O.scrollTop=0),w===P&&O&&(O.scrollTop=O.scrollHeight),w==null||w.focus(),document.activeElement!==T))return},[N,O]),Q=l.useCallback(()=>J([D,y]),[J,D,y]);l.useEffect(()=>{$&&Q()},[$,Q]);const{onOpenChange:W,triggerPointerDownPosRef:q}=p;l.useEffect(()=>{if(y){let S={x:0,y:0};const I=P=>{var T,w;S={x:Math.abs(Math.round(P.pageX)-(((T=q.current)==null?void 0:T.x)??0)),y:Math.abs(Math.round(P.pageY)-(((w=q.current)==null?void 0:w.y)??0))}},M=P=>{S.x<=10&&S.y<=10?P.preventDefault():y.contains(P.target)||W(!1),document.removeEventListener("pointermove",I),q.current=null};return q.current!==null&&(document.addEventListener("pointermove",I),document.addEventListener("pointerup",M,{capture:!0,once:!0})),()=>{document.removeEventListener("pointermove",I),document.removeEventListener("pointerup",M,{capture:!0})}}},[y,W,q]),l.useEffect(()=>{const S=()=>W(!1);return window.addEventListener("blur",S),window.addEventListener("resize",S),()=>{window.removeEventListener("blur",S),window.removeEventListener("resize",S)}},[W]);const[ce,ee]=qt(S=>{const I=N().filter(T=>!T.disabled),M=I.find(T=>T.ref.current===document.activeElement),P=Kt(I,S,M);P&&setTimeout(()=>P.ref.current.focus())}),fe=l.useCallback((S,I,M)=>{const P=!U.current&&!M;(p.value!==void 0&&p.value===I||P)&&(Z(S),P&&(U.current=!0))},[p.value]),me=l.useCallback(()=>y==null?void 0:y.focus(),[y]),te=l.useCallback((S,I,M)=>{const P=!U.current&&!M;(p.value!==void 0&&(Array.isArray(I)?I.every(w=>{var k;return(k=p.value)==null?void 0:k.includes(w)}):p.value===I)||P)&&z(S)},[p.value]),ae=t==="popper"?Ne:Bt,ne=ae===Ne?{side:s,sideOffset:a,align:m,alignOffset:v,arrowPadding:C,collisionBoundary:x,collisionPadding:d,sticky:f,hideWhenDetached:h,avoidCollisions:b}:{};return u.jsx(kt,{scope:e,content:y,viewport:O,onViewportChange:L,itemRefCallback:fe,selectedItem:D,onItemLeave:me,itemTextRefCallback:te,focusSelectedItem:Q,selectedItemText:B,position:t,isPositioned:$,searchRef:ce,children:u.jsx(pt.RemoveScroll,{as:Ee.Slot,allowPinchZoom:!0,children:u.jsx(at.FocusScope,{asChild:!0,trapped:p.open,onMountAutoFocus:S=>{S.preventDefault()},onUnmountAutoFocus:V.composeEventHandlers(n,S=>{var I,M;(I=p.trigger)==null||I.focus({preventScroll:!0}),(M=document.getSelection())==null||M.empty(),S.preventDefault()}),children:u.jsx(it.DismissableLayer,{asChild:!0,disableOutsidePointerEvents:!0,onEscapeKeyDown:r,onPointerDownOutside:c,onFocusOutside:S=>S.preventDefault(),onDismiss:()=>p.onOpenChange(!1),children:u.jsx(ae,{role:"listbox",id:p.contentId,"data-state":p.open?"open":"closed","aria-multiselectable":p.multi?"true":void 0,dir:p.dir,onContextMenu:S=>S.preventDefault(),...g,...ne,onPlaced:()=>F(!0),ref:A,style:{display:"flex",flexDirection:"column",outline:"none",...g.style},onKeyDown:V.composeEventHandlers(g.onKeyDown,S=>{const I=S.ctrlKey||S.altKey||S.metaKey;if(S.key==="Tab"&&S.preventDefault(),!I&&S.key.length===1&&ee(S.key),["ArrowUp","ArrowDown","Home","End"].includes(S.key)){let P=N().filter(T=>!T.disabled).map(T=>T.ref.current);if(["ArrowUp","End"].includes(S.key)&&(P=P.slice().reverse()),["ArrowUp","ArrowDown"].includes(S.key)){const T=S.target,w=P.indexOf(T);P=P.slice(w+1)}setTimeout(()=>J(P)),S.preventDefault()}})})})})})})});Ht.displayName=jo;const Do="SelectItemAlignedPosition",Bt=l.forwardRef((o,i)=>{const{__scopeSelect:e,onPlaced:t,...n}=o,r=X(se,e),c=oe(se,e),[s,a]=l.useState(null),[m,v]=l.useState(null),C=_.useComposedRefs(i,A=>v(A)),x=Ce(e),d=l.useRef(!1),f=l.useRef(!0),{viewport:h,selectedItem:b,selectedItemText:g,focusSelectedItem:p}=c,y=l.useCallback(()=>{if(r.trigger&&r.valueNode&&s&&m&&h&&b&&g){const A=r.trigger.getBoundingClientRect(),D=m.getBoundingClientRect(),Z=r.valueNode.getBoundingClientRect(),B=g.getBoundingClientRect();if(r.dir!=="rtl"){const T=B.left-D.left,w=Z.left-T,k=A.left-w,K=A.width+k,j=Math.max(K,D.width),ue=window.innerWidth-Y,he=st.clamp(w,[Y,ue-j]);s.style.minWidth=`${K}px`,s.style.left=`${he}px`}else{const T=D.right-B.right,w=window.innerWidth-Z.right-T,k=window.innerWidth-A.right-w,K=A.width+k,j=Math.max(K,D.width),ue=window.innerWidth-Y,he=st.clamp(w,[Y,ue-j]);s.style.minWidth=`${K}px`,s.style.right=`${he}px`}const z=x(),N=window.innerHeight-Y*2,$=h.scrollHeight,F=window.getComputedStyle(m),U=parseInt(F.borderTopWidth,10),J=parseInt(F.paddingTop,10),Q=parseInt(F.borderBottomWidth,10),W=parseInt(F.paddingBottom,10),q=U+J+$+W+Q,ce=Math.min(b.offsetHeight*5,q),ee=window.getComputedStyle(h),fe=parseInt(ee.paddingTop,10),me=parseInt(ee.paddingBottom,10),te=A.top+A.height/2-Y,ae=N-te,ne=b.offsetHeight/2,S=b.offsetTop+ne,I=U+J+S,M=q-I;if(I<=te){const T=b===z[z.length-1].ref.current;s.style.bottom="0px";const w=m.clientHeight-h.offsetTop-h.offsetHeight,k=Math.max(ae,ne+(T?me:0)+w+Q),K=I+k;s.style.height=`${K}px`}else{const T=b===z[0].ref.current;s.style.top="0px";const k=Math.max(te,U+h.offsetTop+(T?fe:0)+ne)+M;s.style.height=`${k}px`,h.scrollTop=I-te+h.offsetTop}s.style.margin=`${Y}px 0`,s.style.minHeight=`${ce}px`,s.style.maxHeight=`${N}px`,t==null||t(),requestAnimationFrame(()=>d.current=!0)}},[x,r.trigger,r.valueNode,s,m,h,b,g,r.dir,t]);H.useLayoutEffect(()=>y(),[y]);const[E,O]=l.useState();H.useLayoutEffect(()=>{m&&O(window.getComputedStyle(m).zIndex)},[m]);const L=l.useCallback(A=>{A&&f.current===!0&&(y(),p==null||p(),f.current=!1)},[y,p]);return u.jsx(Fo,{scope:e,contentWrapper:s,shouldExpandOnScrollRef:d,onScrollButtonChange:L,children:u.jsx("div",{ref:a,style:{display:"flex",flexDirection:"column",position:"fixed",zIndex:E},children:u.jsx(R.Primitive.div,{...n,ref:C,style:{boxSizing:"border-box",maxHeight:"100%",...n.style}})})})});Bt.displayName=Do;const Lo="SelectPopperPosition",Ne=l.forwardRef((o,i)=>{const{__scopeSelect:e,align:t="start",collisionPadding:n=Y,...r}=o,c=Pe(e);return u.jsx(ie.Content,{...c,...r,ref:i,align:t,collisionPadding:n,style:{boxSizing:"border-box",...r.style,"--radix-select-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-select-content-available-width":"var(--radix-popper-available-width)","--radix-select-content-available-height":"var(--radix-popper-available-height)","--radix-select-trigger-width":"var(--radix-popper-anchor-width)","--radix-select-trigger-height":"var(--radix-popper-anchor-height)"}})});Ne.displayName=Lo;const[Fo,Ke]=pe(se,{}),_e="SelectViewport",Ge=l.forwardRef((o,i)=>{const{__scopeSelect:e,...t}=o,n=oe(_e,e),r=Ke(_e,e),c=_.useComposedRefs(i,n.onViewportChange),s=l.useRef(0);return u.jsxs(u.Fragment,{children:[u.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}"}}),u.jsx(Te.Slot,{scope:e,children:u.jsx(R.Primitive.div,{"data-radix-select-viewport":"",role:"presentation",...t,ref:c,style:{position:"relative",flex:1,overflow:"auto",...t.style},onScroll:V.composeEventHandlers(t.onScroll,a=>{const m=a.currentTarget,{contentWrapper:v,shouldExpandOnScrollRef:C}=r;if(C!=null&&C.current&&v){const x=Math.abs(s.current-m.scrollTop);if(x>0){const d=window.innerHeight-Y*2,f=parseFloat(v.style.minHeight),h=parseFloat(v.style.height),b=Math.max(f,h);if(b<d){const g=b+x,p=Math.min(d,g),y=g-p;v.style.height=`${p}px`,v.style.bottom==="0px"&&(m.scrollTop=y>0?y:0,v.style.justifyContent="flex-end")}}}s.current=m.scrollTop})})})]})});Ge.displayName=_e;const $t="SelectGroup",[ko,Ho]=pe($t),Ye=l.forwardRef((o,i)=>{const{__scopeSelect:e,...t}=o,n=le.useId();return u.jsx(ko,{scope:e,id:n,children:u.jsx(R.Primitive.div,{role:"group","aria-labelledby":n,...t,ref:i})})});Ye.displayName=$t;const Ut="SelectLabel",Xe=l.forwardRef((o,i)=>{const{__scopeSelect:e,...t}=o,n=Ho(Ut,e);return u.jsx(R.Primitive.div,{id:n.id,...t,ref:i})});Xe.displayName=Ut;const be="SelectItem",[Bo,zt]=pe(be),Ze=l.forwardRef((o,i)=>{const{__scopeSelect:e,value:t,disabled:n=!1,textValue:r,...c}=o,s=X(be,e),a=oe(be,e),m=typeof t=="string"?Array.isArray(s.value)?s.value.includes(t):s.value===t:t.every(p=>{var y;return(y=s.value)==null?void 0:y.includes(p)}),v=Array.isArray(s.value)&&Array.isArray(t)&&t.some(p=>{var y;return(y=s.value)==null?void 0:y.includes(p)}),[C,x]=l.useState(r??""),[d,f]=l.useState(!1),h=_.useComposedRefs(i,p=>{var y;return(y=a.itemRefCallback)==null?void 0:y.call(a,p,t,n)}),b=le.useId(),g=()=>{if(!n){let p=s.multi&&typeof t=="string"?[t]:t;v&&!m?s.onValueChange(p):Array.isArray(s.value)&&(p=Gt(t,s.value)),s.onValueChange(p),s.multi||s.onOpenChange(!1)}};if(!s.multi&&Array.isArray(t))throw new Error("You can only pass an array of values in multi selects");return u.jsx(Bo,{scope:e,value:t,disabled:n,textId:b,isSelected:m,isIntermediate:v,onItemTextChange:l.useCallback(p=>{x(y=>y||((p==null?void 0:p.textContent)??"").trim())},[]),children:u.jsx(Te.ItemSlot,{scope:e,value:t,disabled:n,textValue:C,children:u.jsx(R.Primitive.div,{role:"option","aria-labelledby":b,"data-highlighted":d?"":void 0,"aria-selected":s.multi?void 0:m&&d,"aria-checked":s.multi?m:void 0,"data-state":m?"checked":"unchecked","aria-disabled":n||void 0,"data-disabled":n?"":void 0,tabIndex:n?void 0:-1,...c,ref:h,onFocus:V.composeEventHandlers(c.onFocus,()=>f(!0)),onBlur:V.composeEventHandlers(c.onBlur,()=>f(!1)),onPointerUp:V.composeEventHandlers(c.onPointerUp,g),onPointerMove:V.composeEventHandlers(c.onPointerMove,p=>{var y;n?(y=a.onItemLeave)==null||y.call(a):p.currentTarget.focus({preventScroll:!0})}),onPointerLeave:V.composeEventHandlers(c.onPointerLeave,p=>{var y;p.currentTarget===document.activeElement&&((y=a.onItemLeave)==null||y.call(a))}),onKeyDown:V.composeEventHandlers(c.onKeyDown,p=>{var E;((E=a.searchRef)==null?void 0:E.current)!==""&&p.key===" "||(Vo.includes(p.key)&&g(),p.key===" "&&p.preventDefault())})})})})});Ze.displayName=be;const xe="SelectItemText",Je=l.forwardRef((o,i)=>{const{__scopeSelect:e,className:t,style:n,...r}=o,c=X(xe,e),s=oe(xe,e),a=zt(xe,e),m=Ao(xe,e),[v,C]=l.useState(null),x=_.useComposedRefs(i,g=>C(g),a.onItemTextChange,g=>{var p;return(p=s.itemTextRefCallback)==null?void 0:p.call(s,g,a.value,a.disabled)}),d=v==null?void 0:v.textContent,f=l.useMemo(()=>u.jsx("option",{value:a.value,disabled:a.disabled,children:d},Array.isArray(a.value)?a.value.join(";"):a.value),[a.disabled,a.value,d]),{onNativeOptionAdd:h,onNativeOptionRemove:b}=m;return H.useLayoutEffect(()=>(h(f),()=>b(f)),[h,b,f]),u.jsxs(u.Fragment,{children:[u.jsx(R.Primitive.span,{id:a.textId,...r,ref:x}),a.isSelected&&c.valueNode&&!c.valueNodeHasChildren?Se.createPortal(r.children,c.valueNode):null]})});Je.displayName=xe;const Wt="SelectItemIndicator",Qe=l.forwardRef((o,i)=>{const{__scopeSelect:e,children:t,...n}=o,r=zt(Wt,e);return typeof t=="function"?u.jsx(R.Primitive.span,{"aria-hidden":!0,...n,ref:i,children:t({isSelected:r.isSelected,isIntermediate:r.isIntermediate})}):r.isSelected?u.jsx(R.Primitive.span,{"aria-hidden":!0,...n,ref:i,children:t}):null});Qe.displayName=Wt;const Ae="SelectScrollUpButton",et=l.forwardRef((o,i)=>{const e=oe(Ae,o.__scopeSelect),t=Ke(Ae,o.__scopeSelect),[n,r]=l.useState(!1),c=_.useComposedRefs(i,t.onScrollButtonChange);return H.useLayoutEffect(()=>{if(e.viewport&&e.isPositioned){const s=e.viewport,a=()=>{const m=s.scrollTop>0;r(m)};return a(),s.addEventListener("scroll",a),()=>s.removeEventListener("scroll",a)}},[e.viewport,e.isPositioned]),n?u.jsx(ot,{...o,ref:c,onAutoScroll:()=>{const{viewport:s,selectedItem:a}=e;s&&a&&(s.scrollTop-=a.offsetHeight)}}):null});et.displayName=Ae;const Me="SelectScrollDownButton",tt=l.forwardRef((o,i)=>{const e=oe(Me,o.__scopeSelect),t=Ke(Me,o.__scopeSelect),[n,r]=l.useState(!1),c=_.useComposedRefs(i,t.onScrollButtonChange);return H.useLayoutEffect(()=>{if(e.viewport&&e.isPositioned){const s=e.viewport,a=()=>{const m=s.scrollHeight-s.clientHeight,v=Math.ceil(s.scrollTop)<m;r(v)};return a(),s.addEventListener("scroll",a),()=>s.removeEventListener("scroll",a)}},[e.viewport,e.isPositioned]),n?u.jsx(ot,{...o,ref:c,onAutoScroll:()=>{const{viewport:s,selectedItem:a}=e;s&&a&&(s.scrollTop+=a.offsetHeight)}}):null});tt.displayName=Me;const ot=l.forwardRef((o,i)=>{const{__scopeSelect:e,onAutoScroll:t,...n}=o,r=oe("SelectScrollButton",e),c=l.useRef(null),s=Ce(e),a=l.useCallback(()=>{c.current!==null&&(window.clearInterval(c.current),c.current=null)},[]);return l.useEffect(()=>()=>a(),[a]),H.useLayoutEffect(()=>{var v;const m=s().find(C=>C.ref.current===document.activeElement);(v=m==null?void 0:m.ref.current)==null||v.scrollIntoView({block:"nearest"})},[s]),u.jsx(R.Primitive.div,{"aria-hidden":!0,...n,ref:i,style:{flexShrink:0,...n.style},onPointerMove:V.composeEventHandlers(n.onPointerMove,()=>{var m;(m=r.onItemLeave)==null||m.call(r),c.current===null&&(c.current=window.setInterval(t,50))}),onPointerLeave:V.composeEventHandlers(n.onPointerLeave,()=>{a()})})});ot.displayName="SelectScrollButtonImpl";const $o="SelectSeparator",nt=l.forwardRef((o,i)=>{const{__scopeSelect:e,...t}=o;return u.jsx(R.Primitive.div,{"aria-hidden":!0,...t,ref:i})});nt.displayName=$o;const Oe="SelectArrow",rt=l.forwardRef((o,i)=>{const{__scopeSelect:e,...t}=o,n=Pe(e),r=X(Oe,e),c=oe(Oe,e);return r.open&&c.position==="popper"?u.jsx(ie.Arrow,{...n,...t,ref:i}):null});rt.displayName=Oe;const Uo="BubbleSelect",zo=l.forwardRef((o,i)=>{const{value:e,...t}=o,n=l.useRef(null),r=_.useComposedRefs(i,n),c=eo.usePrevious(e),s=X(Uo,void 0);l.useEffect(()=>{const m=n.current,v=window.HTMLSelectElement.prototype,x=Object.getOwnPropertyDescriptor(v,"value").set;if(c!==e&&x){const d=new Event("change",{bubbles:!0});x.call(m,e),m.dispatchEvent(d)}},[c,e]);let a=e;return s.multi&&!Array.isArray(e)&&(a=[]),u.jsx(to.VisuallyHidden,{asChild:!0,children:u.jsx("select",{...t,multiple:s.multi?!0:void 0,ref:r,defaultValue:a})})});zo.displayName="BubbleSelect";function qt(o){const i=Dt(o),e=l.useRef(""),t=l.useRef(0),n=l.useCallback(c=>{const s=e.current+c;i(s),function a(m){e.current=m,window.clearTimeout(t.current),m!==""&&(t.current=window.setTimeout(()=>a(""),1e3))}(s)},[i]),r=l.useCallback(()=>{e.current="",window.clearTimeout(t.current)},[]);return l.useEffect(()=>()=>window.clearTimeout(t.current),[]),[e,n,r]}function Kt(o,i,e){const n=i.length>1&&Array.from(i).every(m=>m===i[0])?i[0]:i,r=e?o.indexOf(e):-1;let c=Wo(o,Math.max(r,0));n.length===1&&(c=c.filter(m=>m!==e));const a=c.find(m=>m.textValue.toLowerCase().startsWith(n.toLowerCase()));return a!==e?a:void 0}function Wo(o,i){return o.map((e,t)=>o[(i+t)%o.length])}const Gt=(o,i=[])=>{if(Array.isArray(o))return o.reduce((t,n)=>Gt(n,t),i);const e=i.indexOf(o);return e===-1?[...i,o]:[...i.slice(0,e),...i.slice(e+1)]},qo=Be,Ko=$e,Go=Ue,Yo=ze,Xo=We,Zo=qe,Jo=Ge,Qo=Ye,en=Xe,tn=Ze,on=Je,nn=Qe,rn=et,sn=tt,ln=nt,cn=rt,an=Object.freeze(Object.defineProperty({__proto__:null,Arrow:cn,Content:Zo,Group:Qo,Icon:Yo,Item:tn,ItemIndicator:nn,ItemText:on,Label:en,Portal:Xo,Root:qo,ScrollDownButton:sn,ScrollUpButton:rn,Select:Be,SelectArrow:rt,SelectContent:qe,SelectGroup:Ye,SelectIcon:ze,SelectItem:Ze,SelectItemIndicator:Qe,SelectItemText:Je,SelectLabel:Xe,SelectPortal:We,SelectScrollDownButton:tt,SelectScrollUpButton:et,SelectSeparator:nt,SelectTrigger:$e,SelectValue:Ue,SelectViewport:Ge,Separator:ln,Trigger:Ko,Value:Go,Viewport:Jo,createSelectScope:Ro},Symbol.toStringTag,{value:"Module"}));function un(o,i,{checkForDefaultPrevented:e=!0}={}){return function(n){if(o==null||o(n),e===!1||!n.defaultPrevented)return i==null?void 0:i(n)}}exports.Combobox=To;exports.Select=an;exports.composeEventHandlers=un;exports.createCollection=ft;exports.useCallbackRef=Dt;exports.useCollator=mt;exports.useFilter=we;exports.usePrev=ht;