@sproutsocial/seeds-react-menu 1.11.0 → 1.11.2

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/v3/index.js CHANGED
@@ -52,6 +52,9 @@ __export(v3_exports, {
52
52
  ComboboxTokenInput: () => ComboboxTokenInput,
53
53
  ComboboxTokenInputGroup: () => ComboboxTokenInputGroup,
54
54
  ComboboxTrigger: () => ComboboxTrigger,
55
+ MultiCombobox: () => MultiCombobox,
56
+ MultiSearchableSelect: () => MultiSearchableSelect,
57
+ MultiSelect: () => MultiSelect,
55
58
  SearchableSelectInput: () => SearchableSelectInput,
56
59
  SearchableSelectList: () => SearchableSelectList,
57
60
  SearchableSelectPlaceholder: () => SearchableSelectPlaceholder,
@@ -60,6 +63,9 @@ __export(v3_exports, {
60
63
  SearchableSelectTokenTrigger: () => SearchableSelectTokenTrigger,
61
64
  SearchableSelectTrigger: () => SearchableSelectTrigger,
62
65
  SearchableSelectTriggerIcon: () => SearchableSelectTriggerIcon,
66
+ SingleCombobox: () => SingleCombobox,
67
+ SingleSearchableSelect: () => SingleSearchableSelect,
68
+ SingleSelect: () => SingleSelect,
63
69
  Token: () => Token,
64
70
  TokenRemove: () => TokenRemove
65
71
  });
@@ -73,6 +79,18 @@ var import_styled_components4 = __toESM(require("styled-components"));
73
79
  // src/v3/SeedsPortal.tsx
74
80
  var React = __toESM(require("react"));
75
81
  var import_seeds_react_portal = require("@sproutsocial/seeds-react-portal");
82
+ function useSeedsPortalContainer() {
83
+ const disablePortalToBody = React.useContext(import_seeds_react_portal.DisablePortalToBodyContext);
84
+ const containerRef = React.useRef(null);
85
+ const [portalContainer, setPortalContainer] = React.useState(void 0);
86
+ React.useEffect(() => {
87
+ if (disablePortalToBody && containerRef.current) {
88
+ const dialogContent = containerRef.current.closest("[role='dialog']");
89
+ setPortalContainer(dialogContent ?? containerRef.current);
90
+ }
91
+ }, [disablePortalToBody]);
92
+ return { containerRef, portalContainer, disablePortalToBody };
93
+ }
76
94
 
77
95
  // src/v3/Common/SelectItem.tsx
78
96
  var React2 = require("react");
@@ -118,6 +136,72 @@ var StyledItemIndicator = (0, import_styled_components.default)(import_select.Se
118
136
  }
119
137
  `;
120
138
  var StyledItemText = (0, import_styled_components.default)(import_select.Select.ItemText)``;
139
+ function CheckIcon() {
140
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_icon.Icon, { name: "check-outline", fixedWidth: true, "aria-hidden": true });
141
+ }
142
+ function SelectItem({
143
+ value,
144
+ label,
145
+ inputType = "icon",
146
+ renderItem,
147
+ hidden
148
+ }) {
149
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
150
+ StyledItem,
151
+ {
152
+ value,
153
+ style: hidden ? { display: "none" } : void 0,
154
+ "data-qa-menu-item": label,
155
+ children: [
156
+ inputType === "radio" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
157
+ StyledItemIndicator,
158
+ {
159
+ keepMounted: true,
160
+ render: (_props, state) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
161
+ import_seeds_react_radio.default,
162
+ {
163
+ checked: state.selected,
164
+ onChange: () => {
165
+ },
166
+ tabIndex: -1,
167
+ id: `radio-${value}`,
168
+ name: "select-item"
169
+ }
170
+ )
171
+ }
172
+ ) : inputType === "checkbox" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
173
+ StyledItemIndicator,
174
+ {
175
+ keepMounted: true,
176
+ render: (_props, state) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
177
+ import_seeds_react_checkbox.default,
178
+ {
179
+ checked: state.selected,
180
+ onChange: () => {
181
+ },
182
+ tabIndex: -1,
183
+ id: `checkbox-${value}`,
184
+ name: "select-item"
185
+ }
186
+ )
187
+ }
188
+ ) : inputType === "icon" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledItemIndicator, { keepMounted: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckIcon, {}) }) : null,
189
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledItemText, { children: renderItem ? renderItem() : label })
190
+ ]
191
+ }
192
+ );
193
+ }
194
+
195
+ // src/v3/Common/groupItems.ts
196
+ function groupItems(data, groupBy) {
197
+ const map = /* @__PURE__ */ new Map();
198
+ for (const item of data) {
199
+ const key = groupBy(item);
200
+ if (!map.has(key)) map.set(key, []);
201
+ map.get(key).push(item);
202
+ }
203
+ return Array.from(map.entries()).map(([value, items]) => ({ value, items }));
204
+ }
121
205
 
122
206
  // src/v3/Common/SelectStyles.tsx
123
207
  var import_select2 = require("@base-ui/react/select");
@@ -163,6 +247,11 @@ var SelectTrigger = (0, import_styled_components2.default)(import_select2.Select
163
247
  &[data-popup-open] [data-chevron] {
164
248
  transform: rotate(-180deg);
165
249
  }
250
+
251
+ &[data-disabled] {
252
+ opacity: 0.4;
253
+ cursor: not-allowed;
254
+ }
166
255
  `;
167
256
  var SelectValue = (0, import_styled_components2.default)(import_select2.Select.Value)`
168
257
  min-width: 0;
@@ -247,7 +336,13 @@ var StyledChevron = import_styled_components3.default.div`
247
336
  transition: transform 0.15s;
248
337
  ${({ $isOpen }) => $isOpen && "transform: rotate(-180deg);"}
249
338
  `;
250
- function CheckIcon() {
339
+ function ChevronIcon() {
340
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true });
341
+ }
342
+ function ClearIcon() {
343
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "circle-x-outline", fixedWidth: true, "aria-hidden": true, size: "mini" });
344
+ }
345
+ function CheckIcon2() {
251
346
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "check-outline", fixedWidth: true, "aria-hidden": true });
252
347
  }
253
348
 
@@ -264,6 +359,116 @@ var StyledValue = (0, import_styled_components4.default)(import_select3.Select.V
264
359
  color: ${({ theme }) => theme.colors.text.subtext};
265
360
  }
266
361
  `;
362
+ function SingleSelect(props) {
363
+ const { id, placeholder, includePlaceholderItem } = props;
364
+ const isChildrenMode = "children" in props && props.children != null;
365
+ const selectedItemId = props.selectedItemId;
366
+ const defaultSelectedItemId = props.defaultSelectedItemId;
367
+ const onSelectedItemIdChange = props.onSelectedItemIdChange;
368
+ const data = isChildrenMode ? [] : props.data;
369
+ const itemToString = isChildrenMode ? () => "" : props.itemToString;
370
+ const renderItem = isChildrenMode ? void 0 : props.renderItem;
371
+ const inputType = isChildrenMode ? "icon" : props.inputType ?? "icon";
372
+ const renderSelection = isChildrenMode ? void 0 : props.renderSelection;
373
+ const groupBy = isChildrenMode ? void 0 : props.groupBy;
374
+ const renderGroupHeading = isChildrenMode ? void 0 : props.renderGroupHeading;
375
+ const children = isChildrenMode ? props.children : void 0;
376
+ const { containerRef, portalContainer } = useSeedsPortalContainer();
377
+ const items = React4.useMemo(() => {
378
+ const dataItems = data.map((item) => ({
379
+ value: String(item.id),
380
+ label: itemToString(item)
381
+ }));
382
+ if (includePlaceholderItem) {
383
+ return [{ value: null, label: placeholder ?? "" }, ...dataItems];
384
+ }
385
+ return dataItems;
386
+ }, [data, itemToString, includePlaceholderItem, placeholder]);
387
+ const dataWithPlaceholder = includePlaceholderItem ? [{ id: null, value: null, label: placeholder ?? "" }, ...data] : data;
388
+ const isControlled = selectedItemId !== void 0;
389
+ const [internalValue, setInternalValue] = React4.useState(
390
+ defaultSelectedItemId != null ? String(defaultSelectedItemId) : null
391
+ );
392
+ const value = isControlled ? selectedItemId != null ? String(selectedItemId) : null : internalValue;
393
+ const selectedItem = React4.useMemo(
394
+ () => value != null ? data.find((d) => String(d.id) === value) ?? null : null,
395
+ [data, value]
396
+ );
397
+ function handleValueChange(newValue) {
398
+ if (!isControlled) {
399
+ setInternalValue(newValue);
400
+ }
401
+ if (onSelectedItemIdChange) {
402
+ if (newValue == null) {
403
+ onSelectedItemIdChange(null);
404
+ } else {
405
+ const item = data.find((d) => String(d.id) === newValue);
406
+ onSelectedItemIdChange(item ? item.id : null);
407
+ }
408
+ }
409
+ }
410
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Field, { children: [
411
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
412
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
413
+ import_select3.Select.Root,
414
+ {
415
+ items,
416
+ value,
417
+ disabled: props.disabled,
418
+ onValueChange: handleValueChange,
419
+ id,
420
+ children: [
421
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(SelectTrigger, { children: [
422
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledValue, { placeholder, children: renderSelection && selectedItem ? renderSelection(selectedItem) : void 0 }),
423
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectIcon, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChevronIcon, {}) }) })
424
+ ] }),
425
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_select3.Select.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectPositioner, { sideOffset: 8, alignItemWithTrigger: false, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(SelectPopup, { children: [
426
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_select3.Select.ScrollUpArrow, {}),
427
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_select3.Select.List, { children: children ? children : groupBy ? groupItems(data, groupBy).map((group, index, arr) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React4.Fragment, { children: [
428
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(SelectGroup, { children: [
429
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
430
+ group.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
431
+ SelectItem,
432
+ {
433
+ value: String(item.id),
434
+ label: itemToString(item),
435
+ inputType,
436
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
437
+ },
438
+ item.id
439
+ ))
440
+ ] }),
441
+ index < arr.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SelectSeparator, {})
442
+ ] }, group.value)) : (
443
+ // TODO: need to add a placeholder item when includePlaceholderItem is true
444
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
445
+ includePlaceholderItem && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
446
+ SelectItem,
447
+ {
448
+ value: null,
449
+ label: placeholder ?? ""
450
+ },
451
+ "placeholder"
452
+ ),
453
+ data.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
454
+ SelectItem,
455
+ {
456
+ value: String(item.id),
457
+ label: itemToString(item),
458
+ inputType,
459
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
460
+ },
461
+ item.id
462
+ ))
463
+ ] })
464
+ ) }),
465
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_select3.Select.ScrollDownArrow, {})
466
+ ] }) }) })
467
+ ]
468
+ }
469
+ )
470
+ ] });
471
+ }
267
472
 
268
473
  // src/v3/MultiSelect.tsx
269
474
  var React5 = __toESM(require("react"));
@@ -284,6 +489,117 @@ var Placeholder = import_styled_components5.default.div`
284
489
  padding-bottom: 2px;
285
490
  margin: 2px 8px 0px 0px;
286
491
  `;
492
+ function MultiSelect(props) {
493
+ const { id, placeholder = "Select..." } = props;
494
+ const isChildrenMode = "children" in props && props.children != null;
495
+ const data = isChildrenMode ? [] : props.data;
496
+ const itemToString = isChildrenMode ? () => "" : props.itemToString;
497
+ const renderItem = isChildrenMode ? void 0 : props.renderItem;
498
+ const customRenderSelections = isChildrenMode ? void 0 : props.customRenderSelections;
499
+ const maxSelections = isChildrenMode ? void 0 : props.maxSelections;
500
+ const renderSelection = isChildrenMode ? void 0 : props.renderSelection;
501
+ const removeSelectedItems = isChildrenMode ? false : props.removeSelectedItems ?? false;
502
+ const inputType = isChildrenMode ? "checkbox" : removeSelectedItems ? "none" : props.inputType ?? "checkbox";
503
+ const selectedItemIds = props.selectedItemIds;
504
+ const defaultSelectedItemIds = props.defaultSelectedItemIds;
505
+ const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
506
+ const groupBy = isChildrenMode ? void 0 : props.groupBy;
507
+ const renderGroupHeading = isChildrenMode ? void 0 : props.renderGroupHeading;
508
+ const children = isChildrenMode ? props.children : void 0;
509
+ const { containerRef, portalContainer } = useSeedsPortalContainer();
510
+ const isControlled = selectedItemIds !== void 0;
511
+ const [internalValue, setInternalValue] = React5.useState(
512
+ () => defaultSelectedItemIds?.map(String) ?? []
513
+ );
514
+ const value = isControlled ? selectedItemIds.map(String) : internalValue;
515
+ const items = React5.useMemo(
516
+ () => data.map((item) => ({
517
+ value: String(item.id),
518
+ label: itemToString(item)
519
+ })),
520
+ [data, itemToString]
521
+ );
522
+ const selectedItems = React5.useMemo(
523
+ () => value.map((v) => data.find((d) => String(d.id) === v)).filter((d) => d != null),
524
+ [data, value]
525
+ );
526
+ function handleValueChange(newValues) {
527
+ if (!isControlled) {
528
+ setInternalValue(newValues);
529
+ }
530
+ if (onSelectedItemIdsChange) {
531
+ const ids = newValues.map((v) => {
532
+ const item = data.find((d) => String(d.id) === v);
533
+ return item ? item.id : v;
534
+ });
535
+ onSelectedItemIdsChange(ids);
536
+ }
537
+ }
538
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Field, { children: [
539
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
540
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
541
+ import_select4.Select.Root,
542
+ {
543
+ multiple: true,
544
+ items,
545
+ value,
546
+ onValueChange: handleValueChange,
547
+ disabled: props.disabled,
548
+ id,
549
+ children: [
550
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectTrigger, { children: [
551
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectValue, { children: () => {
552
+ if (renderSelection) return renderSelection(selectedItems);
553
+ if (selectedItems.length === 0)
554
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Placeholder, { children: placeholder });
555
+ const visibleItems = maxSelections != null ? selectedItems.slice(0, maxSelections) : selectedItems;
556
+ const overflowCount = maxSelections != null && selectedItems.length > maxSelections ? selectedItems.length - maxSelections : 0;
557
+ const text = visibleItems.map(
558
+ (item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
559
+ ).join(", ");
560
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectionText, { children: [
561
+ text,
562
+ overflowCount > 0 ? `, +${overflowCount}` : ""
563
+ ] });
564
+ } }),
565
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectIcon, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChevronIcon, {}) }) })
566
+ ] }),
567
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_select4.Select.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectPositioner, { sideOffset: 8, alignItemWithTrigger: false, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectPopup, { children: [
568
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_select4.Select.ScrollUpArrow, {}),
569
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_select4.Select.List, { children: children ? children : groupBy ? groupItems(data, groupBy).map((group, index, arr) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(React5.Fragment, { children: [
570
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectGroup, { children: [
571
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
572
+ group.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
573
+ SelectItem,
574
+ {
575
+ value: String(item.id),
576
+ label: itemToString(item),
577
+ inputType,
578
+ hidden: removeSelectedItems && value.includes(String(item.id)),
579
+ renderItem: renderItem ? () => renderItem(item) : void 0
580
+ },
581
+ item.id
582
+ ))
583
+ ] }),
584
+ index < arr.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectSeparator, {})
585
+ ] }, group.value)) : data.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
586
+ SelectItem,
587
+ {
588
+ value: String(item.id),
589
+ label: itemToString(item),
590
+ inputType,
591
+ hidden: removeSelectedItems && value.includes(String(item.id)),
592
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
593
+ },
594
+ item.id
595
+ )) }),
596
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_select4.Select.ScrollDownArrow, {})
597
+ ] }) }) })
598
+ ]
599
+ }
600
+ )
601
+ ] });
602
+ }
287
603
 
288
604
  // src/v3/SingleCombobox.tsx
289
605
  var React8 = __toESM(require("react"));
@@ -322,6 +638,11 @@ var ComboboxInputGroup = (0, import_styled_components6.default)(import_combobox.
322
638
  &:focus-within {
323
639
  ${import_seeds_react_mixins2.focusRing}
324
640
  }
641
+
642
+ &[data-disabled] {
643
+ opacity: 0.4;
644
+ cursor: not-allowed;
645
+ }
325
646
  `;
326
647
  var ComboboxInput = (0, import_styled_components6.default)(import_combobox.Combobox.Input)`
327
648
  flex: 1;
@@ -337,6 +658,10 @@ var ComboboxInput = (0, import_styled_components6.default)(import_combobox.Combo
337
658
  &::placeholder {
338
659
  color: ${({ theme }) => theme.colors.text.subtext};
339
660
  }
661
+
662
+ &:disabled {
663
+ cursor: not-allowed;
664
+ }
340
665
  `;
341
666
  var ComboboxTokenInput = (0, import_styled_components6.default)(import_combobox.Combobox.Input)`
342
667
  flex: 1;
@@ -353,6 +678,10 @@ var ComboboxTokenInput = (0, import_styled_components6.default)(import_combobox.
353
678
  &::placeholder {
354
679
  color: ${({ theme }) => theme.colors.text.subtext};
355
680
  }
681
+
682
+ &:disabled {
683
+ cursor: not-allowed;
684
+ }
356
685
  `;
357
686
  var ComboboxActionButtons = import_styled_components6.default.div`
358
687
  display: flex;
@@ -596,6 +925,11 @@ var ComboboxTokenInputGroup = (0, import_styled_components6.default)(import_comb
596
925
  &:focus-within {
597
926
  ${import_seeds_react_mixins2.focusRing}
598
927
  }
928
+
929
+ &[data-disabled] {
930
+ opacity: 0.4;
931
+ cursor: not-allowed;
932
+ }
599
933
  `;
600
934
  var Token = import_styled_components6.default.span`
601
935
  display: inline-flex;
@@ -656,6 +990,11 @@ var SearchableSelectTrigger = (0, import_styled_components6.default)(import_comb
656
990
  &[data-popup-open] [data-chevron] {
657
991
  transform: rotate(-180deg);
658
992
  }
993
+
994
+ &[data-disabled] {
995
+ opacity: 0.4;
996
+ cursor: not-allowed;
997
+ }
659
998
  `;
660
999
  var SearchableSelectTriggerIcon = (0, import_styled_components6.default)(import_combobox.Combobox.Icon)`
661
1000
  display: flex;
@@ -733,6 +1072,11 @@ var SearchableSelectTokenTrigger = (0, import_styled_components6.default)(import
733
1072
  &[data-popup-open] [data-chevron] {
734
1073
  transform: rotate(-180deg);
735
1074
  }
1075
+
1076
+ &[data-disabled] {
1077
+ opacity: 0.4;
1078
+ cursor: not-allowed;
1079
+ }
736
1080
  `;
737
1081
 
738
1082
  // src/v3/Common/ComboboxItem.tsx
@@ -755,6 +1099,7 @@ function ComboboxItemInner({
755
1099
  "data-index": dataIndex,
756
1100
  style,
757
1101
  ref,
1102
+ "data-qa-menu-item": label,
758
1103
  children: [
759
1104
  inputType === "radio" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
760
1105
  ComboboxItemIndicator,
@@ -788,22 +1133,310 @@ function ComboboxItemInner({
788
1133
  }
789
1134
  )
790
1135
  }
791
- ) : inputType === "icon" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ComboboxItemIndicator, { keepMounted: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckIcon, {}) }) : null,
1136
+ ) : inputType === "icon" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ComboboxItemIndicator, { keepMounted: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckIcon2, {}) }) : null,
792
1137
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: renderItem ? renderItem() : label })
793
1138
  ]
794
1139
  }
795
1140
  );
796
1141
  }
797
1142
  var ComboboxItem2 = React6.forwardRef(ComboboxItemInner);
1143
+ var ComboboxItem_default = ComboboxItem2;
798
1144
 
799
1145
  // src/v3/Common/VirtualizedComboboxList.tsx
800
1146
  var React7 = __toESM(require("react"));
801
1147
  var import_combobox2 = require("@base-ui/react/combobox");
802
1148
  var import_react_virtual = require("@tanstack/react-virtual");
803
1149
  var import_jsx_runtime7 = require("react/jsx-runtime");
1150
+ var ITEM_HEIGHT = 32;
1151
+ function isGroupHeaderSentinel(v) {
1152
+ return typeof v === "object" && v !== null && "__groupHeader" in v;
1153
+ }
1154
+ function isSelectAllSentinel(v) {
1155
+ return typeof v === "object" && v !== null && "__selectAll" in v;
1156
+ }
1157
+ function VirtualizedComboboxList({
1158
+ open,
1159
+ virtualizerRef,
1160
+ value,
1161
+ groups,
1162
+ data,
1163
+ itemToString,
1164
+ inputType,
1165
+ renderItem,
1166
+ renderGroupHeading
1167
+ }) {
1168
+ const filteredItems = import_combobox2.Combobox.useFilteredItems();
1169
+ const scrollElementRef = React7.useRef(null);
1170
+ const virtualizer = (0, import_react_virtual.useVirtualizer)({
1171
+ enabled: open,
1172
+ count: filteredItems.length,
1173
+ getScrollElement: () => scrollElementRef.current,
1174
+ estimateSize: () => ITEM_HEIGHT,
1175
+ overscan: 20,
1176
+ paddingStart: 4,
1177
+ paddingEnd: 4,
1178
+ scrollPaddingStart: 4,
1179
+ scrollPaddingEnd: 4
1180
+ });
1181
+ React7.useImperativeHandle(virtualizerRef, () => virtualizer);
1182
+ const handleScrollRef = React7.useCallback(
1183
+ (el) => {
1184
+ scrollElementRef.current = el;
1185
+ if (el) virtualizer.measure();
1186
+ },
1187
+ [virtualizer]
1188
+ );
1189
+ if (!filteredItems.length) return null;
1190
+ const selectedArray = Array.isArray(value) ? value : value != null ? [value] : [];
1191
+ const totalSize = virtualizer.getTotalSize();
1192
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1193
+ "div",
1194
+ {
1195
+ role: "presentation",
1196
+ ref: handleScrollRef,
1197
+ style: {
1198
+ flex: 1,
1199
+ minHeight: 0,
1200
+ overflowY: "auto",
1201
+ overscrollBehavior: "contain"
1202
+ },
1203
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1204
+ "div",
1205
+ {
1206
+ role: "presentation",
1207
+ style: { position: "relative", width: "100%", height: totalSize },
1208
+ children: virtualizer.getVirtualItems().map((virtualItem) => {
1209
+ const row = filteredItems[virtualItem.index];
1210
+ if (!row) return null;
1211
+ const baseStyle = {
1212
+ position: "absolute",
1213
+ top: 0,
1214
+ left: 0,
1215
+ width: "100%",
1216
+ transform: `translateY(${virtualItem.start}px)`,
1217
+ boxSizing: "border-box"
1218
+ };
1219
+ if (isSelectAllSentinel(row)) {
1220
+ const selectedCount = selectedArray.length;
1221
+ const totalCount = data.length;
1222
+ const state = selectedCount === 0 ? "none" : selectedCount === totalCount ? "all" : "partial";
1223
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1224
+ ComboboxSelectAllItem,
1225
+ {
1226
+ index: virtualItem.index,
1227
+ "data-index": virtualItem.index,
1228
+ value: row,
1229
+ style: baseStyle,
1230
+ ref: virtualizer.measureElement,
1231
+ children: [
1232
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComboboxGroupHeaderCheckbox, { $state: state, id: "__selectAll" }),
1233
+ "Select all"
1234
+ ]
1235
+ },
1236
+ virtualItem.key
1237
+ );
1238
+ }
1239
+ if (isGroupHeaderSentinel(row)) {
1240
+ const group = groups?.find((g) => g.value === row.groupName);
1241
+ const groupItems2 = group?.items ?? [];
1242
+ const selectedCount = groupItems2.filter(
1243
+ (item2) => selectedArray.some((s) => s.id === item2.id)
1244
+ ).length;
1245
+ const state = selectedCount === 0 ? "none" : selectedCount === groupItems2.length ? "all" : "partial";
1246
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1247
+ ComboboxGroupHeaderItem,
1248
+ {
1249
+ index: virtualItem.index,
1250
+ "data-index": virtualItem.index,
1251
+ value: row,
1252
+ style: baseStyle,
1253
+ ref: virtualizer.measureElement,
1254
+ children: [
1255
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1256
+ ComboboxGroupHeaderCheckbox,
1257
+ {
1258
+ $state: state,
1259
+ id: `__header-${row.groupName}`
1260
+ }
1261
+ ),
1262
+ renderGroupHeading ? renderGroupHeading(row.groupName) : row.groupName
1263
+ ]
1264
+ },
1265
+ virtualItem.key
1266
+ );
1267
+ }
1268
+ const item = row;
1269
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1270
+ ComboboxItem_default,
1271
+ {
1272
+ index: virtualItem.index,
1273
+ "data-index": virtualItem.index,
1274
+ value: item,
1275
+ itemId: String(item.id),
1276
+ label: itemToString(item),
1277
+ inputType,
1278
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item),
1279
+ style: baseStyle,
1280
+ ref: virtualizer.measureElement
1281
+ },
1282
+ virtualItem.key
1283
+ );
1284
+ })
1285
+ }
1286
+ )
1287
+ }
1288
+ );
1289
+ }
804
1290
 
805
1291
  // src/v3/SingleCombobox.tsx
806
1292
  var import_jsx_runtime8 = require("react/jsx-runtime");
1293
+ function SingleCombobox(props) {
1294
+ const {
1295
+ id,
1296
+ placeholder = "Search...",
1297
+ emptyText = "No results found."
1298
+ } = props;
1299
+ const isChildrenMode = "children" in props && props.children != null;
1300
+ const data = isChildrenMode ? [] : props.data;
1301
+ const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
1302
+ const renderItem = isChildrenMode ? void 0 : props.renderItem;
1303
+ const inputType = isChildrenMode ? "icon" : props.inputType ?? "icon";
1304
+ const isVirtualized = isChildrenMode ? false : props.isVirtualized ?? false;
1305
+ const groupBy = isChildrenMode ? void 0 : isVirtualized ? void 0 : props.groupBy;
1306
+ const renderGroupHeading = isChildrenMode ? void 0 : isVirtualized ? void 0 : props.renderGroupHeading;
1307
+ const children = isChildrenMode ? props.children : void 0;
1308
+ const selectedItemId = props.selectedItemId;
1309
+ const defaultSelectedItemId = props.defaultSelectedItemId;
1310
+ const onSelectedItemIdChange = props.onSelectedItemIdChange;
1311
+ const { containerRef, portalContainer } = useSeedsPortalContainer();
1312
+ const [open, setOpen] = React8.useState(false);
1313
+ const virtualizerRef = React8.useRef(null);
1314
+ const isControlled = selectedItemId !== void 0;
1315
+ const idToItem = React8.useCallback(
1316
+ (id2) => {
1317
+ if (id2 == null) return null;
1318
+ return data.find((d) => String(d.id) === String(id2)) ?? null;
1319
+ },
1320
+ [data]
1321
+ );
1322
+ const [internalValue, setInternalValue] = React8.useState(
1323
+ () => idToItem(defaultSelectedItemId)
1324
+ );
1325
+ const value = isControlled ? idToItem(selectedItemId) : internalValue;
1326
+ function handleValueChange(newItem) {
1327
+ if (!isControlled) {
1328
+ setInternalValue(newItem);
1329
+ }
1330
+ if (onSelectedItemIdChange) {
1331
+ onSelectedItemIdChange(newItem ? newItem.id : null);
1332
+ }
1333
+ }
1334
+ const groups = React8.useMemo(
1335
+ () => groupBy ? groupItems(data, groupBy) : null,
1336
+ [data, groupBy]
1337
+ );
1338
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Field, { children: [
1339
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
1340
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1341
+ import_combobox3.Combobox.Root,
1342
+ {
1343
+ id,
1344
+ value,
1345
+ onValueChange: handleValueChange,
1346
+ itemToStringLabel: itemToString,
1347
+ isItemEqualToValue: (a, b) => a != null && b != null && a.id === b.id,
1348
+ items: isVirtualized ? data : groups ?? (isChildrenMode ? void 0 : data),
1349
+ virtualized: isVirtualized,
1350
+ disabled: props.disabled,
1351
+ open,
1352
+ onOpenChange: setOpen,
1353
+ onItemHighlighted: isVirtualized ? (item, { reason, index }) => {
1354
+ const virt = virtualizerRef.current;
1355
+ if (!item || !virt) return;
1356
+ const isStart = index === 0;
1357
+ const isEnd = index === virt.options.count - 1;
1358
+ if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
1359
+ queueMicrotask(() => {
1360
+ virt.scrollToIndex(index, {
1361
+ align: isEnd ? "start" : "end"
1362
+ });
1363
+ });
1364
+ }
1365
+ } : void 0,
1366
+ children: [
1367
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxInputGroup, { children: [
1368
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxInput, { placeholder, id }),
1369
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxActionButtons, { children: [
1370
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxClear, { "aria-label": "Clear selection", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ClearIcon, {}) }),
1371
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxTrigger, { "aria-label": "Open popup", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StyledChevron, { $isOpen: open, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChevronIcon, {}) }) })
1372
+ ] })
1373
+ ] }),
1374
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_combobox3.Combobox.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1375
+ ComboboxPopup,
1376
+ {
1377
+ style: isVirtualized ? { display: "flex", flexDirection: "column" } : void 0,
1378
+ children: [
1379
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxEmpty, { children: emptyText }),
1380
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1381
+ ComboboxList,
1382
+ {
1383
+ style: isVirtualized ? {
1384
+ padding: 0,
1385
+ flex: 1,
1386
+ minHeight: 0,
1387
+ display: "flex",
1388
+ flexDirection: "column"
1389
+ } : void 0,
1390
+ children: isVirtualized ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1391
+ VirtualizedComboboxList,
1392
+ {
1393
+ open,
1394
+ virtualizerRef,
1395
+ value,
1396
+ groups,
1397
+ data,
1398
+ itemToString,
1399
+ inputType,
1400
+ renderItem,
1401
+ renderGroupHeading
1402
+ }
1403
+ ) : children ? children : groups ? (group, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(React8.Fragment, { children: [
1404
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxGroup, { items: group.items, children: [
1405
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
1406
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_combobox3.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1407
+ ComboboxItem_default,
1408
+ {
1409
+ value: item,
1410
+ itemId: String(item.id),
1411
+ label: itemToString(item),
1412
+ inputType,
1413
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1414
+ },
1415
+ item.id
1416
+ ) })
1417
+ ] }),
1418
+ index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxSeparator, {})
1419
+ ] }, group.value) : (item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1420
+ ComboboxItem_default,
1421
+ {
1422
+ value: item,
1423
+ itemId: String(item.id),
1424
+ label: itemToString(item),
1425
+ inputType,
1426
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1427
+ },
1428
+ item.id
1429
+ )
1430
+ }
1431
+ )
1432
+ ]
1433
+ }
1434
+ ) }) })
1435
+ ]
1436
+ }
1437
+ )
1438
+ ] });
1439
+ }
807
1440
 
808
1441
  // src/v3/MultiCombobox.tsx
809
1442
  var React9 = __toESM(require("react"));
@@ -811,12 +1444,473 @@ var import_combobox4 = require("@base-ui/react/combobox");
811
1444
  var import_react_virtual3 = require("@tanstack/react-virtual");
812
1445
  var import_seeds_react_icon3 = __toESM(require("@sproutsocial/seeds-react-icon"));
813
1446
  var import_jsx_runtime9 = require("react/jsx-runtime");
1447
+ function makeGroupHeaderSentinel(groupName) {
1448
+ return { __groupHeader: true, groupName };
1449
+ }
1450
+ function isGroupHeaderSentinel2(v) {
1451
+ return typeof v === "object" && v !== null && "__groupHeader" in v;
1452
+ }
1453
+ var SELECT_ALL_SENTINEL = { __selectAll: true };
1454
+ function isSelectAllSentinel2(v) {
1455
+ return typeof v === "object" && v !== null && "__selectAll" in v;
1456
+ }
1457
+ function MultiCombobox(props) {
1458
+ const {
1459
+ id,
1460
+ placeholder = "Search...",
1461
+ emptyText = "No results found.",
1462
+ isLoading = false,
1463
+ loadingText = "Loading..."
1464
+ } = props;
1465
+ const isChildrenMode = "children" in props && props.children != null;
1466
+ const data = isChildrenMode ? [] : props.data;
1467
+ const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
1468
+ const renderItem = isChildrenMode ? void 0 : props.renderItem;
1469
+ const renderToken = isChildrenMode ? void 0 : props.renderToken;
1470
+ const renderSelection = isChildrenMode ? void 0 : props.renderSelection;
1471
+ const maxTokens = isChildrenMode ? void 0 : props.maxTokens;
1472
+ const removeSelectedItems = isChildrenMode ? false : props.removeSelectedItems ?? false;
1473
+ const inputType = isChildrenMode ? "checkbox" : removeSelectedItems ? "none" : props.inputType ?? "checkbox";
1474
+ const groupBy = isChildrenMode ? void 0 : props.groupBy;
1475
+ const renderGroupHeading = isChildrenMode ? void 0 : props.renderGroupHeading;
1476
+ const selectHeadings = isChildrenMode ? false : props.selectHeadings ?? false;
1477
+ const selectAll = isChildrenMode ? false : props.selectAll ?? false;
1478
+ const isVirtualized = isChildrenMode ? false : props.isVirtualized ?? false;
1479
+ const children = isChildrenMode ? props.children : void 0;
1480
+ const selectedItemIds = props.selectedItemIds;
1481
+ const defaultSelectedItemIds = props.defaultSelectedItemIds;
1482
+ const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
1483
+ const { containerRef, portalContainer } = useSeedsPortalContainer();
1484
+ const [open, setOpen] = React9.useState(false);
1485
+ const virtualizerRef = React9.useRef(null);
1486
+ const isControlled = selectedItemIds !== void 0;
1487
+ const idsToItems = React9.useCallback(
1488
+ (ids) => ids.map((id2) => data.find((d) => d.id === id2)).filter((d) => d != null),
1489
+ [data]
1490
+ );
1491
+ const [internalValue, setInternalValue] = React9.useState(
1492
+ () => defaultSelectedItemIds ? idsToItems(defaultSelectedItemIds) : []
1493
+ );
1494
+ const value = isControlled ? idsToItems(selectedItemIds) : internalValue;
1495
+ const visibleData = React9.useMemo(
1496
+ () => removeSelectedItems ? data.filter((item) => !value.some((v) => v.id === item.id)) : data,
1497
+ [data, value, removeSelectedItems]
1498
+ );
1499
+ const groups = React9.useMemo(
1500
+ () => groupBy ? groupItems(visibleData, groupBy) : null,
1501
+ [visibleData, groupBy]
1502
+ );
1503
+ const flatItems = React9.useMemo(() => {
1504
+ if (!groups || !selectHeadings && !selectAll) return null;
1505
+ const rows = [];
1506
+ if (selectAll) rows.push(SELECT_ALL_SENTINEL);
1507
+ for (const group of groups) {
1508
+ rows.push(makeGroupHeaderSentinel(group.value));
1509
+ rows.push(...group.items);
1510
+ }
1511
+ return rows;
1512
+ }, [groups, selectHeadings, selectAll]);
1513
+ function setSelectedItems(items) {
1514
+ if (!isControlled) setInternalValue(items);
1515
+ if (onSelectedItemIdsChange)
1516
+ onSelectedItemIdsChange(items.map((item) => item.id));
1517
+ }
1518
+ function handleValueChange(next) {
1519
+ const selectAllClicked = next.filter(isSelectAllSentinel2);
1520
+ const groupSentinels = next.filter(isGroupHeaderSentinel2);
1521
+ const realItems = next.filter(
1522
+ (v) => !isGroupHeaderSentinel2(v) && !isSelectAllSentinel2(v)
1523
+ );
1524
+ if (selectAllClicked.length > 0) {
1525
+ const allSelected = data.every(
1526
+ (d) => realItems.some((s) => s.id === d.id)
1527
+ );
1528
+ setSelectedItems(allSelected ? [] : [...data]);
1529
+ return;
1530
+ }
1531
+ if (groupSentinels.length === 0) {
1532
+ setSelectedItems(realItems);
1533
+ return;
1534
+ }
1535
+ let updated = [...realItems];
1536
+ for (const sentinel of groupSentinels) {
1537
+ const group = groups?.find((g) => g.value === sentinel.groupName);
1538
+ if (!group) continue;
1539
+ const allSelected = group.items.every(
1540
+ (item) => updated.some((s) => s.id === item.id)
1541
+ );
1542
+ if (allSelected) {
1543
+ updated = updated.filter(
1544
+ (s) => !group.items.some((item) => item.id === s.id)
1545
+ );
1546
+ } else {
1547
+ const missing = group.items.filter(
1548
+ (item) => !updated.some((s) => s.id === item.id)
1549
+ );
1550
+ updated = [...updated, ...missing];
1551
+ }
1552
+ }
1553
+ setSelectedItems(updated);
1554
+ }
1555
+ function handleSimpleValueChange(newItems) {
1556
+ setSelectedItems(newItems);
1557
+ }
1558
+ function removeItem(item, e) {
1559
+ e.preventDefault();
1560
+ e.stopPropagation();
1561
+ setSelectedItems(value.filter((v) => v.id !== item.id));
1562
+ }
1563
+ function renderSentinelRow(row) {
1564
+ if (isSelectAllSentinel2(row)) {
1565
+ const totalCount = data.length;
1566
+ const selectedCount = value.length;
1567
+ const state = selectedCount === 0 ? "none" : selectedCount === totalCount ? "all" : "partial";
1568
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxSelectAllItem, { value: row, children: [
1569
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxGroupHeaderCheckbox, { $state: state, id: "__selectAll" }),
1570
+ "Select all"
1571
+ ] }, "__selectAll");
1572
+ }
1573
+ if (isGroupHeaderSentinel2(row)) {
1574
+ const group = groups?.find((g) => g.value === row.groupName);
1575
+ const groupItemsList = group?.items ?? [];
1576
+ const selectedCount = groupItemsList.filter(
1577
+ (item2) => value.some((s) => s.id === item2.id)
1578
+ ).length;
1579
+ const state = selectedCount === 0 ? "none" : selectedCount === groupItemsList.length ? "all" : "partial";
1580
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxGroupHeaderItem, { value: row, children: [
1581
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1582
+ ComboboxGroupHeaderCheckbox,
1583
+ {
1584
+ $state: state,
1585
+ id: `__header-${row.groupName}`
1586
+ }
1587
+ ),
1588
+ renderGroupHeading ? renderGroupHeading(row.groupName) : row.groupName
1589
+ ] }, `__header-${row.groupName}`);
1590
+ }
1591
+ const item = row;
1592
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1593
+ ComboboxItem_default,
1594
+ {
1595
+ value: item,
1596
+ itemId: String(item.id),
1597
+ label: itemToString(item),
1598
+ inputType,
1599
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1600
+ },
1601
+ item.id
1602
+ );
1603
+ }
1604
+ const rootItems = flatItems ?? groups ?? (isChildrenMode ? void 0 : visibleData);
1605
+ const hasSentinels = selectAll || selectHeadings;
1606
+ const rootValue = hasSentinels ? [...value] : value;
1607
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Field, { children: [
1608
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
1609
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1610
+ import_combobox4.Combobox.Root,
1611
+ {
1612
+ multiple: true,
1613
+ id,
1614
+ virtualized: isVirtualized,
1615
+ open,
1616
+ disabled: props.disabled,
1617
+ onOpenChange: setOpen,
1618
+ onItemHighlighted: isVirtualized ? (item, { reason, index }) => {
1619
+ const virt = virtualizerRef.current;
1620
+ if (!item || !virt) return;
1621
+ const isStart = index === 0;
1622
+ const isEnd = index === virt.options.count - 1;
1623
+ if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
1624
+ queueMicrotask(() => {
1625
+ virt.scrollToIndex(index, {
1626
+ align: isEnd ? "start" : "end"
1627
+ });
1628
+ });
1629
+ }
1630
+ } : void 0,
1631
+ value: rootValue,
1632
+ onValueChange: (
1633
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1634
+ hasSentinels ? handleValueChange : handleSimpleValueChange
1635
+ ),
1636
+ itemToStringLabel: (item) => {
1637
+ if (!item || isGroupHeaderSentinel2(item) || isSelectAllSentinel2(item))
1638
+ return "";
1639
+ return itemToString(item);
1640
+ },
1641
+ isItemEqualToValue: (a, b) => {
1642
+ if (isGroupHeaderSentinel2(a) && isGroupHeaderSentinel2(b))
1643
+ return a.groupName === b.groupName;
1644
+ if (isSelectAllSentinel2(a) && isSelectAllSentinel2(b)) return true;
1645
+ if (!isGroupHeaderSentinel2(a) && !isSelectAllSentinel2(a) && !isGroupHeaderSentinel2(b) && !isSelectAllSentinel2(b))
1646
+ return a.id === b.id;
1647
+ return false;
1648
+ },
1649
+ items: rootItems,
1650
+ children: [
1651
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxTokenInputGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxToken, { children: [
1652
+ renderSelection ? renderSelection(value) : (() => {
1653
+ const visibleTokens = maxTokens != null ? value.slice(0, maxTokens) : value;
1654
+ const overflow = maxTokens != null ? value.length - maxTokens : 0;
1655
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1656
+ visibleTokens.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Token, { children: [
1657
+ renderToken ? renderToken(item) : itemToString(item),
1658
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1659
+ TokenRemove,
1660
+ {
1661
+ "aria-label": `Remove ${itemToString(item)}`,
1662
+ onPointerDown: (e) => e.preventDefault(),
1663
+ onClick: (e) => removeItem(item, e),
1664
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_seeds_react_icon3.default, { name: "x-outline", size: "mini" })
1665
+ }
1666
+ )
1667
+ ] }, item.id)),
1668
+ overflow > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Token, { children: [
1669
+ "+",
1670
+ overflow
1671
+ ] }, "__overflow")
1672
+ ] });
1673
+ })(),
1674
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1675
+ ComboboxTokenInput,
1676
+ {
1677
+ id,
1678
+ placeholder: value.length > 0 ? "" : placeholder
1679
+ }
1680
+ ),
1681
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxActionButtons, { children: [
1682
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxClear, { "aria-label": "Clear all", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ClearIcon, {}) }),
1683
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxTrigger, { "aria-label": "Open popup", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StyledChevron, { $isOpen: open, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ChevronIcon, {}) }) })
1684
+ ] })
1685
+ ] }) }),
1686
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_combobox4.Combobox.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1687
+ ComboboxPopup,
1688
+ {
1689
+ "aria-busy": isLoading || void 0,
1690
+ style: isVirtualized ? { display: "flex", flexDirection: "column" } : void 0,
1691
+ children: [
1692
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxStatus, { children: isLoading ? loadingText : null }),
1693
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxEmpty, { children: isLoading ? null : emptyText }),
1694
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1695
+ ComboboxList,
1696
+ {
1697
+ style: isVirtualized ? {
1698
+ padding: 0,
1699
+ flex: 1,
1700
+ minHeight: 0,
1701
+ display: "flex",
1702
+ flexDirection: "column"
1703
+ } : void 0,
1704
+ children: isVirtualized ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1705
+ VirtualizedComboboxList,
1706
+ {
1707
+ open,
1708
+ virtualizerRef,
1709
+ value,
1710
+ groups,
1711
+ data: visibleData,
1712
+ itemToString,
1713
+ inputType,
1714
+ renderItem,
1715
+ renderGroupHeading
1716
+ }
1717
+ ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(React9.Fragment, { children: [
1718
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxGroup, { items: group.items, children: [
1719
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
1720
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_combobox4.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1721
+ ComboboxItem_default,
1722
+ {
1723
+ value: item,
1724
+ itemId: String(item.id),
1725
+ label: itemToString(item),
1726
+ inputType,
1727
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1728
+ },
1729
+ item.id
1730
+ ) })
1731
+ ] }),
1732
+ index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxSeparator, {})
1733
+ ] }, group.value) : (item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1734
+ ComboboxItem_default,
1735
+ {
1736
+ value: item,
1737
+ itemId: String(item.id),
1738
+ label: itemToString(item),
1739
+ inputType,
1740
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1741
+ },
1742
+ item.id
1743
+ )
1744
+ }
1745
+ )
1746
+ ]
1747
+ }
1748
+ ) }) })
1749
+ ]
1750
+ }
1751
+ )
1752
+ ] });
1753
+ }
814
1754
 
815
1755
  // src/v3/SingleSearchableSelect.tsx
816
1756
  var React10 = __toESM(require("react"));
817
1757
  var import_combobox5 = require("@base-ui/react/combobox");
818
1758
  var import_react_virtual4 = require("@tanstack/react-virtual");
819
1759
  var import_jsx_runtime10 = require("react/jsx-runtime");
1760
+ function SingleSearchableSelect(props) {
1761
+ const {
1762
+ id,
1763
+ placeholder = "Select...",
1764
+ searchPlaceholder = "Search...",
1765
+ emptyText = "No results found.",
1766
+ isLoading = false,
1767
+ loadingText = "Loading..."
1768
+ } = props;
1769
+ const isChildrenMode = "children" in props && props.children != null;
1770
+ const data = isChildrenMode ? [] : props.data;
1771
+ const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
1772
+ const renderItem = isChildrenMode ? void 0 : props.renderItem;
1773
+ const renderSelection = isChildrenMode ? void 0 : props.renderSelection;
1774
+ const inputType = isChildrenMode ? "icon" : props.inputType ?? "icon";
1775
+ const isVirtualized = isChildrenMode ? false : props.isVirtualized ?? false;
1776
+ const groupBy = isChildrenMode ? void 0 : isVirtualized ? void 0 : props.groupBy;
1777
+ const renderGroupHeading = isChildrenMode ? void 0 : isVirtualized ? void 0 : props.renderGroupHeading;
1778
+ const children = isChildrenMode ? props.children : void 0;
1779
+ const selectedItemId = props.selectedItemId;
1780
+ const defaultSelectedItemId = props.defaultSelectedItemId;
1781
+ const onSelectedItemIdChange = props.onSelectedItemIdChange;
1782
+ const { containerRef, portalContainer } = useSeedsPortalContainer();
1783
+ const [open, setOpen] = React10.useState(false);
1784
+ const virtualizerRef = React10.useRef(null);
1785
+ const isControlled = selectedItemId !== void 0;
1786
+ const idToItem = React10.useCallback(
1787
+ (id2) => {
1788
+ if (id2 == null) return null;
1789
+ return data.find((d) => String(d.id) === String(id2)) ?? null;
1790
+ },
1791
+ [data]
1792
+ );
1793
+ const [internalValue, setInternalValue] = React10.useState(
1794
+ () => idToItem(defaultSelectedItemId)
1795
+ );
1796
+ const value = isControlled ? idToItem(selectedItemId) : internalValue;
1797
+ function handleValueChange(newItem) {
1798
+ if (!isControlled) setInternalValue(newItem);
1799
+ if (onSelectedItemIdChange) {
1800
+ onSelectedItemIdChange(newItem ? newItem.id : null);
1801
+ }
1802
+ }
1803
+ const groups = React10.useMemo(
1804
+ () => groupBy ? groupItems(data, groupBy) : null,
1805
+ [data, groupBy]
1806
+ );
1807
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Field, { children: [
1808
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
1809
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1810
+ import_combobox5.Combobox.Root,
1811
+ {
1812
+ id,
1813
+ value,
1814
+ disabled: props.disabled,
1815
+ onValueChange: handleValueChange,
1816
+ itemToStringLabel: itemToString,
1817
+ isItemEqualToValue: (a, b) => a != null && b != null && a.id === b.id,
1818
+ items: isVirtualized ? data : groups ?? (isChildrenMode ? void 0 : data),
1819
+ virtualized: isVirtualized,
1820
+ open,
1821
+ onOpenChange: setOpen,
1822
+ onItemHighlighted: isVirtualized ? (item, { reason, index }) => {
1823
+ const virt = virtualizerRef.current;
1824
+ if (!item || !virt) return;
1825
+ const isStart = index === 0;
1826
+ const isEnd = index === virt.options.count - 1;
1827
+ if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
1828
+ queueMicrotask(() => {
1829
+ virt.scrollToIndex(index, {
1830
+ align: isEnd ? "start" : "end"
1831
+ });
1832
+ });
1833
+ }
1834
+ } : void 0,
1835
+ children: [
1836
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SearchableSelectTrigger, { id, children: [
1837
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SearchableSelectPlaceholder, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_combobox5.Combobox.Value, { placeholder, children: value ? renderSelection ? renderSelection(value) : itemToString(value) : null }) }),
1838
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SearchableSelectTriggerIcon, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChevronIcon, {}) }) })
1839
+ ] }),
1840
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_combobox5.Combobox.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1841
+ SearchableSelectPopup,
1842
+ {
1843
+ "aria-busy": isLoading || void 0,
1844
+ style: { display: "flex", flexDirection: "column" },
1845
+ children: [
1846
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SearchableSelectSearchContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1847
+ SearchableSelectInput,
1848
+ {
1849
+ placeholder: searchPlaceholder,
1850
+ autoFocus: true
1851
+ }
1852
+ ) }),
1853
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComboboxStatus, { children: isLoading ? loadingText : null }),
1854
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComboboxEmpty, { children: isLoading ? null : emptyText }),
1855
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1856
+ SearchableSelectList,
1857
+ {
1858
+ style: isVirtualized ? {
1859
+ padding: 0,
1860
+ flex: 1,
1861
+ minHeight: 0,
1862
+ display: "flex",
1863
+ flexDirection: "column"
1864
+ } : void 0,
1865
+ children: isVirtualized ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1866
+ VirtualizedComboboxList,
1867
+ {
1868
+ open,
1869
+ virtualizerRef,
1870
+ value,
1871
+ groups: null,
1872
+ data,
1873
+ itemToString,
1874
+ inputType,
1875
+ renderItem
1876
+ }
1877
+ ) : children ? children : groups ? (group, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(React10.Fragment, { children: [
1878
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ComboboxGroup, { items: group.items, children: [
1879
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
1880
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_combobox5.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1881
+ ComboboxItem_default,
1882
+ {
1883
+ value: item,
1884
+ itemId: String(item.id),
1885
+ label: itemToString(item),
1886
+ inputType,
1887
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1888
+ },
1889
+ item.id
1890
+ ) })
1891
+ ] }),
1892
+ index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComboboxSeparator, {})
1893
+ ] }, group.value) : (item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1894
+ ComboboxItem_default,
1895
+ {
1896
+ value: item,
1897
+ itemId: String(item.id),
1898
+ label: itemToString(item),
1899
+ inputType,
1900
+ renderItem: renderItem ? () => renderItem(item) : void 0
1901
+ },
1902
+ item.id
1903
+ )
1904
+ }
1905
+ )
1906
+ ]
1907
+ }
1908
+ ) }) })
1909
+ ]
1910
+ }
1911
+ )
1912
+ ] });
1913
+ }
820
1914
 
821
1915
  // src/v3/MultiSearchableSelect.tsx
822
1916
  var React11 = __toESM(require("react"));
@@ -830,6 +1924,295 @@ var SelectionText2 = import_styled_components7.default.span`
830
1924
  text-overflow: ellipsis;
831
1925
  white-space: nowrap;
832
1926
  `;
1927
+ function makeGroupHeaderSentinel2(groupName) {
1928
+ return { __groupHeader: true, groupName };
1929
+ }
1930
+ function isGroupHeaderSentinel3(v) {
1931
+ return typeof v === "object" && v !== null && "__groupHeader" in v;
1932
+ }
1933
+ var SELECT_ALL_SENTINEL2 = { __selectAll: true };
1934
+ function isSelectAllSentinel3(v) {
1935
+ return typeof v === "object" && v !== null && "__selectAll" in v;
1936
+ }
1937
+ function MultiSearchableSelect(props) {
1938
+ const {
1939
+ id,
1940
+ placeholder = "Select...",
1941
+ searchPlaceholder = "Search...",
1942
+ emptyText = "No results found.",
1943
+ isLoading = false,
1944
+ loadingText = "Loading..."
1945
+ } = props;
1946
+ const isChildrenMode = "children" in props && props.children != null;
1947
+ const data = isChildrenMode ? [] : props.data;
1948
+ const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
1949
+ const renderItem = isChildrenMode ? void 0 : props.renderItem;
1950
+ const customRenderSelections = isChildrenMode ? void 0 : props.customRenderSelections;
1951
+ const maxSelections = isChildrenMode ? void 0 : props.maxSelections;
1952
+ const renderSelection = isChildrenMode ? void 0 : props.renderSelection;
1953
+ const removeSelectedItems = isChildrenMode ? false : props.removeSelectedItems ?? false;
1954
+ const inputType = isChildrenMode ? "checkbox" : removeSelectedItems ? "none" : props.inputType ?? "checkbox";
1955
+ const groupBy = isChildrenMode ? void 0 : props.groupBy;
1956
+ const renderGroupHeading = isChildrenMode ? void 0 : props.renderGroupHeading;
1957
+ const selectHeadings = isChildrenMode ? false : props.selectHeadings ?? false;
1958
+ const selectAll = isChildrenMode ? false : props.selectAll ?? false;
1959
+ const isVirtualized = isChildrenMode ? false : props.isVirtualized ?? false;
1960
+ const children = isChildrenMode ? props.children : void 0;
1961
+ const selectedItemIds = props.selectedItemIds;
1962
+ const defaultSelectedItemIds = props.defaultSelectedItemIds;
1963
+ const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
1964
+ const { containerRef, portalContainer } = useSeedsPortalContainer();
1965
+ const [open, setOpen] = React11.useState(false);
1966
+ const virtualizerRef = React11.useRef(null);
1967
+ const isControlled = selectedItemIds !== void 0;
1968
+ const idsToItems = React11.useCallback(
1969
+ (ids) => ids.map((id2) => data.find((d) => d.id === id2)).filter((d) => d != null),
1970
+ [data]
1971
+ );
1972
+ const [internalValue, setInternalValue] = React11.useState(
1973
+ () => defaultSelectedItemIds ? idsToItems(defaultSelectedItemIds) : []
1974
+ );
1975
+ const value = isControlled ? idsToItems(selectedItemIds) : internalValue;
1976
+ const visibleData = React11.useMemo(
1977
+ () => removeSelectedItems ? data.filter((item) => !value.some((v) => v.id === item.id)) : data,
1978
+ [data, value, removeSelectedItems]
1979
+ );
1980
+ const groups = React11.useMemo(
1981
+ () => groupBy ? groupItems(visibleData, groupBy) : null,
1982
+ [visibleData, groupBy]
1983
+ );
1984
+ const flatItems = React11.useMemo(() => {
1985
+ if (!groups || !selectHeadings && !selectAll) return null;
1986
+ const rows = [];
1987
+ if (selectAll) rows.push(SELECT_ALL_SENTINEL2);
1988
+ for (const group of groups) {
1989
+ rows.push(makeGroupHeaderSentinel2(group.value));
1990
+ rows.push(...group.items);
1991
+ }
1992
+ return rows;
1993
+ }, [groups, selectHeadings, selectAll]);
1994
+ function setSelectedItems(items) {
1995
+ if (!isControlled) setInternalValue(items);
1996
+ if (onSelectedItemIdsChange)
1997
+ onSelectedItemIdsChange(items.map((item) => item.id));
1998
+ }
1999
+ function handleValueChange(next) {
2000
+ const selectAllClicked = next.filter(isSelectAllSentinel3);
2001
+ const groupSentinels = next.filter(isGroupHeaderSentinel3);
2002
+ const realItems = next.filter(
2003
+ (v) => !isGroupHeaderSentinel3(v) && !isSelectAllSentinel3(v)
2004
+ );
2005
+ if (selectAllClicked.length > 0) {
2006
+ const allSelected = data.every(
2007
+ (d) => realItems.some((s) => s.id === d.id)
2008
+ );
2009
+ setSelectedItems(allSelected ? [] : [...data]);
2010
+ return;
2011
+ }
2012
+ if (groupSentinels.length === 0) {
2013
+ setSelectedItems(realItems);
2014
+ return;
2015
+ }
2016
+ let updated = [...realItems];
2017
+ for (const sentinel of groupSentinels) {
2018
+ const group = groups?.find((g) => g.value === sentinel.groupName);
2019
+ if (!group) continue;
2020
+ const allSelected = group.items.every(
2021
+ (item) => updated.some((s) => s.id === item.id)
2022
+ );
2023
+ if (allSelected) {
2024
+ updated = updated.filter(
2025
+ (s) => !group.items.some((item) => item.id === s.id)
2026
+ );
2027
+ } else {
2028
+ const missing = group.items.filter(
2029
+ (item) => !updated.some((s) => s.id === item.id)
2030
+ );
2031
+ updated = [...updated, ...missing];
2032
+ }
2033
+ }
2034
+ setSelectedItems(updated);
2035
+ }
2036
+ function handleSimpleValueChange(newItems) {
2037
+ setSelectedItems(newItems);
2038
+ }
2039
+ function renderSentinelRow(row) {
2040
+ if (isSelectAllSentinel3(row)) {
2041
+ const totalCount = data.length;
2042
+ const selectedCount = value.length;
2043
+ const state = selectedCount === 0 ? "none" : selectedCount === totalCount ? "all" : "partial";
2044
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ComboboxSelectAllItem, { value: row, children: [
2045
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxGroupHeaderCheckbox, { $state: state, id: "__selectAll" }),
2046
+ "Select all"
2047
+ ] }, "__selectAll");
2048
+ }
2049
+ if (isGroupHeaderSentinel3(row)) {
2050
+ const group = groups?.find((g) => g.value === row.groupName);
2051
+ const groupItemsList = group?.items ?? [];
2052
+ const selectedCount = groupItemsList.filter(
2053
+ (item2) => value.some((s) => s.id === item2.id)
2054
+ ).length;
2055
+ const state = selectedCount === 0 ? "none" : selectedCount === groupItemsList.length ? "all" : "partial";
2056
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ComboboxGroupHeaderItem, { value: row, children: [
2057
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2058
+ ComboboxGroupHeaderCheckbox,
2059
+ {
2060
+ $state: state,
2061
+ id: `__header-${row.groupName}`
2062
+ }
2063
+ ),
2064
+ renderGroupHeading ? renderGroupHeading(row.groupName) : row.groupName
2065
+ ] }, `__header-${row.groupName}`);
2066
+ }
2067
+ const item = row;
2068
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2069
+ ComboboxItem_default,
2070
+ {
2071
+ value: item,
2072
+ itemId: String(item.id),
2073
+ label: itemToString(item),
2074
+ inputType,
2075
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
2076
+ },
2077
+ item.id
2078
+ );
2079
+ }
2080
+ const rootItems = flatItems ?? groups ?? (isChildrenMode ? void 0 : visibleData);
2081
+ const hasSentinels = selectAll || selectHeadings;
2082
+ const rootValue = hasSentinels ? [...value] : value;
2083
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Field, { children: [
2084
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
2085
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2086
+ import_combobox6.Combobox.Root,
2087
+ {
2088
+ multiple: true,
2089
+ id,
2090
+ virtualized: isVirtualized,
2091
+ open,
2092
+ disabled: props.disabled,
2093
+ onOpenChange: setOpen,
2094
+ onItemHighlighted: isVirtualized ? (item, { reason, index }) => {
2095
+ const virt = virtualizerRef.current;
2096
+ if (!item || !virt) return;
2097
+ const isStart = index === 0;
2098
+ const isEnd = index === virt.options.count - 1;
2099
+ if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
2100
+ queueMicrotask(() => {
2101
+ virt.scrollToIndex(index, {
2102
+ align: isEnd ? "start" : "end"
2103
+ });
2104
+ });
2105
+ }
2106
+ } : void 0,
2107
+ value: rootValue,
2108
+ onValueChange: (
2109
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2110
+ hasSentinels ? handleValueChange : handleSimpleValueChange
2111
+ ),
2112
+ itemToStringLabel: (item) => {
2113
+ if (!item || isGroupHeaderSentinel3(item) || isSelectAllSentinel3(item))
2114
+ return "";
2115
+ return itemToString(item);
2116
+ },
2117
+ isItemEqualToValue: (a, b) => {
2118
+ if (isGroupHeaderSentinel3(a) && isGroupHeaderSentinel3(b))
2119
+ return a.groupName === b.groupName;
2120
+ if (isSelectAllSentinel3(a) && isSelectAllSentinel3(b)) return true;
2121
+ if (!isGroupHeaderSentinel3(a) && !isSelectAllSentinel3(a) && !isGroupHeaderSentinel3(b) && !isSelectAllSentinel3(b))
2122
+ return a.id === b.id;
2123
+ return false;
2124
+ },
2125
+ items: rootItems,
2126
+ children: [
2127
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SearchableSelectTokenTrigger, { id, children: [
2128
+ renderSelection ? renderSelection(value) : value.length > 0 ? (() => {
2129
+ const visibleItems = maxSelections != null ? value.slice(0, maxSelections) : value;
2130
+ const overflowCount = maxSelections != null && value.length > maxSelections ? value.length - maxSelections : 0;
2131
+ const text = visibleItems.map(
2132
+ (item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
2133
+ ).join(", ");
2134
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SelectionText2, { children: [
2135
+ text,
2136
+ overflowCount > 0 ? `, +${overflowCount}` : ""
2137
+ ] });
2138
+ })() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SearchableSelectPlaceholder, { children: placeholder }),
2139
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SearchableSelectTriggerIcon, { style: { marginLeft: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChevronIcon, {}) }) })
2140
+ ] }),
2141
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_combobox6.Combobox.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2142
+ SearchableSelectPopup,
2143
+ {
2144
+ "aria-busy": isLoading || void 0,
2145
+ style: { display: "flex", flexDirection: "column" },
2146
+ children: [
2147
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SearchableSelectSearchContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2148
+ SearchableSelectInput,
2149
+ {
2150
+ placeholder: searchPlaceholder,
2151
+ autoFocus: true
2152
+ }
2153
+ ) }),
2154
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxStatus, { children: isLoading ? loadingText : null }),
2155
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxEmpty, { children: isLoading ? null : emptyText }),
2156
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2157
+ SearchableSelectList,
2158
+ {
2159
+ style: isVirtualized ? {
2160
+ padding: 0,
2161
+ flex: 1,
2162
+ minHeight: 0,
2163
+ display: "flex",
2164
+ flexDirection: "column"
2165
+ } : void 0,
2166
+ children: isVirtualized ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2167
+ VirtualizedComboboxList,
2168
+ {
2169
+ open,
2170
+ virtualizerRef,
2171
+ value,
2172
+ groups,
2173
+ data: visibleData,
2174
+ itemToString,
2175
+ inputType,
2176
+ renderItem,
2177
+ renderGroupHeading
2178
+ }
2179
+ ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React11.Fragment, { children: [
2180
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ComboboxGroup, { items: group.items, children: [
2181
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
2182
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_combobox6.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2183
+ ComboboxItem_default,
2184
+ {
2185
+ value: item,
2186
+ itemId: String(item.id),
2187
+ label: itemToString(item),
2188
+ inputType,
2189
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
2190
+ },
2191
+ item.id
2192
+ ) })
2193
+ ] }),
2194
+ index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxSeparator, {})
2195
+ ] }, group.value) : (item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2196
+ ComboboxItem_default,
2197
+ {
2198
+ value: item,
2199
+ itemId: String(item.id),
2200
+ label: itemToString(item),
2201
+ inputType,
2202
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
2203
+ },
2204
+ item.id
2205
+ )
2206
+ }
2207
+ )
2208
+ ]
2209
+ }
2210
+ ) }) })
2211
+ ]
2212
+ }
2213
+ )
2214
+ ] });
2215
+ }
833
2216
  // Annotate the CommonJS export names for ESM import in node:
834
2217
  0 && (module.exports = {
835
2218
  ComboboxActionButtons,
@@ -854,6 +2237,9 @@ var SelectionText2 = import_styled_components7.default.span`
854
2237
  ComboboxTokenInput,
855
2238
  ComboboxTokenInputGroup,
856
2239
  ComboboxTrigger,
2240
+ MultiCombobox,
2241
+ MultiSearchableSelect,
2242
+ MultiSelect,
857
2243
  SearchableSelectInput,
858
2244
  SearchableSelectList,
859
2245
  SearchableSelectPlaceholder,
@@ -862,6 +2248,9 @@ var SelectionText2 = import_styled_components7.default.span`
862
2248
  SearchableSelectTokenTrigger,
863
2249
  SearchableSelectTrigger,
864
2250
  SearchableSelectTriggerIcon,
2251
+ SingleCombobox,
2252
+ SingleSearchableSelect,
2253
+ SingleSelect,
865
2254
  Token,
866
2255
  TokenRemove
867
2256
  });