@sproutsocial/seeds-react-menu 1.13.0 → 1.16.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/v3/index.js CHANGED
@@ -53,6 +53,7 @@ __export(v3_exports, {
53
53
  ComboboxTokenInput: () => ComboboxTokenInput,
54
54
  ComboboxTokenInputGroup: () => ComboboxTokenInputGroup,
55
55
  ComboboxTrigger: () => ComboboxTrigger,
56
+ MenuButton: () => MenuButton,
56
57
  MenuGroup: () => MenuGroup,
57
58
  MenuItem: () => MenuItem,
58
59
  MenuRadioGroup: () => MenuRadioGroup,
@@ -213,20 +214,50 @@ function groupItems(data, groupBy) {
213
214
 
214
215
  // src/v3/Common/SelectStyles.tsx
215
216
  var import_select2 = require("@base-ui/react/select");
216
- var import_styled_components2 = __toESM(require("styled-components"));
217
+ var import_styled_components3 = __toESM(require("styled-components"));
217
218
  var import_seeds_react_mixins = require("@sproutsocial/seeds-react-mixins");
218
- var Field = import_styled_components2.default.div`
219
+
220
+ // src/v3/Common/SelectIcons.tsx
221
+ var React3 = require("react");
222
+ var import_styled_components2 = __toESM(require("styled-components"));
223
+ var import_seeds_react_icon2 = require("@sproutsocial/seeds-react-icon");
224
+ var import_jsx_runtime2 = require("react/jsx-runtime");
225
+ var StyledChevron = import_styled_components2.default.div`
226
+ display: flex;
227
+ align-items: center;
228
+ transition: transform 0.15s;
229
+ ${({ $isOpen }) => $isOpen && "transform: rotate(-180deg);"}
230
+ `;
231
+ function ChevronIcon() {
232
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true });
233
+ }
234
+ function ClearIcon() {
235
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "circle-x-outline", fixedWidth: true, "aria-hidden": true, size: "mini" });
236
+ }
237
+ function CheckIcon2() {
238
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "check-outline", fixedWidth: true, "aria-hidden": true });
239
+ }
240
+
241
+ // src/v3/Common/SelectStyles.tsx
242
+ var invalidStyles = import_styled_components3.css`
243
+ border-color: ${({ theme }) => theme.colors.form.border.error};
244
+
245
+ ${StyledChevron} {
246
+ color: ${({ theme }) => theme.colors.icon.error};
247
+ }
248
+ `;
249
+ var Field = import_styled_components3.default.div`
219
250
  display: ${({ $fullWidth }) => $fullWidth === false ? "inline-flex" : "flex"};
220
251
  flex-direction: column;
221
252
  gap: ${({ theme }) => theme.space[200]};
222
253
  ${({ $fullWidth }) => $fullWidth !== false && "width: 100%;"}
223
254
  `;
224
- var SelectLabel = (0, import_styled_components2.default)(import_select2.Select.Label)`
255
+ var SelectLabel = (0, import_styled_components3.default)(import_select2.Select.Label)`
225
256
  font-size: ${({ theme }) => theme.typography[200].fontSize};
226
257
  font-weight: ${({ theme }) => theme.fontWeights.semibold};
227
258
  color: ${({ theme }) => theme.colors.text.body};
228
259
  `;
229
- var SelectTrigger = (0, import_styled_components2.default)(import_select2.Select.Trigger)`
260
+ var SelectTrigger = (0, import_styled_components3.default)(import_select2.Select.Trigger)`
230
261
  display: flex;
231
262
  align-items: center;
232
263
  justify-content: space-between;
@@ -261,21 +292,23 @@ var SelectTrigger = (0, import_styled_components2.default)(import_select2.Select
261
292
  opacity: 0.4;
262
293
  cursor: not-allowed;
263
294
  }
295
+
296
+ ${({ $isInvalid }) => $isInvalid && invalidStyles}
264
297
  `;
265
- var SelectValue = (0, import_styled_components2.default)(import_select2.Select.Value)`
298
+ var SelectValue = (0, import_styled_components3.default)(import_select2.Select.Value)`
266
299
  min-width: 0;
267
300
  overflow: hidden;
268
301
  `;
269
- var SelectIcon = (0, import_styled_components2.default)(import_select2.Select.Icon)`
302
+ var SelectIcon = (0, import_styled_components3.default)(import_select2.Select.Icon)`
270
303
  display: flex;
271
304
  align-items: center;
272
305
  color: ${({ theme }) => theme.colors.icon.base};
273
306
  flex-shrink: 0;
274
307
  `;
275
- var SelectGroup = (0, import_styled_components2.default)(import_select2.Select.Group)`
308
+ var SelectGroup = (0, import_styled_components3.default)(import_select2.Select.Group)`
276
309
  display: block;
277
310
  `;
278
- var SelectGroupLabel = (0, import_styled_components2.default)(import_select2.Select.GroupLabel)`
311
+ var SelectGroupLabel = (0, import_styled_components3.default)(import_select2.Select.GroupLabel)`
279
312
  padding: ${({ theme }) => `${theme.space[300]} ${theme.space[300]} ${theme.space[200]}`};
280
313
  font-size: ${({ theme }) => theme.typography[100].fontSize};
281
314
  font-weight: ${({ theme }) => theme.fontWeights.semibold};
@@ -283,23 +316,23 @@ var SelectGroupLabel = (0, import_styled_components2.default)(import_select2.Sel
283
316
  letter-spacing: 0.05em;
284
317
  color: ${({ theme }) => theme.colors.text.subtext};
285
318
  `;
286
- var SelectSeparator = (0, import_styled_components2.default)(import_select2.Select.Separator)`
319
+ var SelectSeparator = (0, import_styled_components3.default)(import_select2.Select.Separator)`
287
320
  height: 1px;
288
321
  margin: ${({ theme }) => `${theme.space[200]} ${theme.space[300]}`};
289
322
  background: ${({ theme }) => theme.colors.container.border.base};
290
323
  `;
291
- var SelectPositioner = (0, import_styled_components2.default)(import_select2.Select.Positioner)`
324
+ var SelectPositioner = (0, import_styled_components3.default)(import_select2.Select.Positioner)`
292
325
  width: var(--anchor-width);
293
326
  z-index: 7;
294
327
  `;
295
- var SelectPopup = (0, import_styled_components2.default)(import_select2.Select.Popup)`
328
+ var SelectPopup = (0, import_styled_components3.default)(import_select2.Select.Popup)`
296
329
  font-family: ${({ theme }) => theme.fontFamily};
297
330
  background: ${({ theme }) => theme.colors.container.background.base};
298
331
  border: 1px solid ${({ theme }) => theme.colors.container.border.base};
299
332
  border-radius: ${({ theme }) => theme.radii[500]};
300
333
  box-shadow: ${({ theme }) => theme.shadows.low};
301
334
  outline: none;
302
- max-height: min(var(--base-ui-available-height, 400px), 400px);
335
+ max-height: min(var(--available-height, 400px), 400px);
303
336
  overflow-y: auto;
304
337
  padding: ${({ theme }) => theme.space[200]};
305
338
 
@@ -334,27 +367,6 @@ var SelectPopup = (0, import_styled_components2.default)(import_select2.Select.P
334
367
  }
335
368
  `;
336
369
 
337
- // src/v3/Common/SelectIcons.tsx
338
- var React3 = require("react");
339
- var import_styled_components3 = __toESM(require("styled-components"));
340
- var import_seeds_react_icon2 = require("@sproutsocial/seeds-react-icon");
341
- var import_jsx_runtime2 = require("react/jsx-runtime");
342
- var StyledChevron = import_styled_components3.default.div`
343
- display: flex;
344
- align-items: center;
345
- transition: transform 0.15s;
346
- ${({ $isOpen }) => $isOpen && "transform: rotate(-180deg);"}
347
- `;
348
- function ChevronIcon() {
349
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true });
350
- }
351
- function ClearIcon() {
352
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "circle-x-outline", fixedWidth: true, "aria-hidden": true, size: "mini" });
353
- }
354
- function CheckIcon2() {
355
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "check-outline", fixedWidth: true, "aria-hidden": true });
356
- }
357
-
358
370
  // src/v3/SingleSelect.tsx
359
371
  var import_jsx_runtime3 = require("react/jsx-runtime");
360
372
  var StyledValue = (0, import_styled_components4.default)(import_select3.Select.Value)`
@@ -371,6 +383,7 @@ var StyledValue = (0, import_styled_components4.default)(import_select3.Select.V
371
383
  function SingleSelect(props) {
372
384
  const { id, placeholder, includePlaceholderItem, fullWidth = true } = props;
373
385
  const ariaDescribedBy = props["aria-describedby"];
386
+ const isInvalid = props.isInvalid;
374
387
  const isChildrenMode = "children" in props && props.children != null;
375
388
  const selectedItemId = props.selectedItemId;
376
389
  const defaultSelectedItemId = props.defaultSelectedItemId;
@@ -428,10 +441,19 @@ function SingleSelect(props) {
428
441
  onValueChange: handleValueChange,
429
442
  id,
430
443
  children: [
431
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(SelectTrigger, { "aria-describedby": ariaDescribedBy, children: [
432
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledValue, { placeholder, children: renderSelection && selectedItem ? renderSelection(selectedItem) : void 0 }),
433
- /* @__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, {}) }) })
434
- ] }),
444
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
445
+ SelectTrigger,
446
+ {
447
+ "aria-describedby": ariaDescribedBy,
448
+ "aria-invalid": isInvalid || void 0,
449
+ "aria-required": props.required || void 0,
450
+ $isInvalid: isInvalid,
451
+ children: [
452
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledValue, { placeholder, children: renderSelection && selectedItem ? renderSelection(selectedItem) : void 0 }),
453
+ /* @__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, {}) }) })
454
+ ]
455
+ }
456
+ ),
435
457
  /* @__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: [
436
458
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_select3.Select.ScrollUpArrow, {}),
437
459
  /* @__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: [
@@ -501,6 +523,7 @@ var Placeholder = import_styled_components5.default.div`
501
523
  function MultiSelect(props) {
502
524
  const { id, placeholder = "Select...", fullWidth = true } = props;
503
525
  const ariaDescribedBy = props["aria-describedby"];
526
+ const isInvalid = props.isInvalid;
504
527
  const isChildrenMode = "children" in props && props.children != null;
505
528
  const data = isChildrenMode ? [] : props.data;
506
529
  const itemToString = isChildrenMode ? () => "" : props.itemToString;
@@ -557,23 +580,32 @@ function MultiSelect(props) {
557
580
  disabled: props.disabled,
558
581
  id,
559
582
  children: [
560
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectTrigger, { "aria-describedby": ariaDescribedBy, children: [
561
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectValue, { children: () => {
562
- if (renderSelection) return renderSelection(selectedItems);
563
- if (selectedItems.length === 0)
564
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Placeholder, { children: placeholder });
565
- const visibleItems = maxSelections != null ? selectedItems.slice(0, maxSelections) : selectedItems;
566
- const overflowCount = maxSelections != null && selectedItems.length > maxSelections ? selectedItems.length - maxSelections : 0;
567
- const text = visibleItems.map(
568
- (item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
569
- ).join(", ");
570
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectionText, { children: [
571
- text,
572
- overflowCount > 0 ? `, +${overflowCount}` : ""
573
- ] });
574
- } }),
575
- /* @__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, {}) }) })
576
- ] }),
583
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
584
+ SelectTrigger,
585
+ {
586
+ "aria-describedby": ariaDescribedBy,
587
+ "aria-invalid": isInvalid || void 0,
588
+ "aria-required": props.required || void 0,
589
+ $isInvalid: isInvalid,
590
+ children: [
591
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectValue, { children: () => {
592
+ if (renderSelection) return renderSelection(selectedItems);
593
+ if (selectedItems.length === 0)
594
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Placeholder, { children: placeholder });
595
+ const visibleItems = maxSelections != null ? selectedItems.slice(0, maxSelections) : selectedItems;
596
+ const overflowCount = maxSelections != null && selectedItems.length > maxSelections ? selectedItems.length - maxSelections : 0;
597
+ const text = visibleItems.map(
598
+ (item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
599
+ ).join(", ");
600
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectionText, { children: [
601
+ text,
602
+ overflowCount > 0 ? `, +${overflowCount}` : ""
603
+ ] });
604
+ } }),
605
+ /* @__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, {}) }) })
606
+ ]
607
+ }
608
+ ),
577
609
  /* @__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: [
578
610
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_select4.Select.ScrollUpArrow, {}),
579
611
  /* @__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: [
@@ -614,12 +646,25 @@ function MultiSelect(props) {
614
646
  }
615
647
 
616
648
  // src/v3/SingleCombobox.tsx
617
- var React8 = __toESM(require("react"));
649
+ var React9 = __toESM(require("react"));
618
650
  var import_combobox3 = require("@base-ui/react/combobox");
619
651
  var import_react_virtual2 = require("@tanstack/react-virtual");
620
652
 
621
- // src/v3/Common/ComboboxItem.tsx
653
+ // src/v3/Common/useSuppressEscapeClear.ts
622
654
  var React6 = __toESM(require("react"));
655
+ function useSuppressEscapeClear(open) {
656
+ return React6.useCallback(
657
+ (event) => {
658
+ if (event.key === "Escape" && !open) {
659
+ event.stopPropagation();
660
+ }
661
+ },
662
+ [open]
663
+ );
664
+ }
665
+
666
+ // src/v3/Common/ComboboxItem.tsx
667
+ var React7 = __toESM(require("react"));
623
668
  var import_seeds_react_radio2 = __toESM(require("@sproutsocial/seeds-react-radio"));
624
669
  var import_seeds_react_checkbox3 = __toESM(require("@sproutsocial/seeds-react-checkbox"));
625
670
 
@@ -629,6 +674,13 @@ var import_styled_components6 = __toESM(require("styled-components"));
629
674
  var import_seeds_react_mixins2 = require("@sproutsocial/seeds-react-mixins");
630
675
  var import_seeds_react_checkbox2 = __toESM(require("@sproutsocial/seeds-react-checkbox"));
631
676
  var import_jsx_runtime5 = require("react/jsx-runtime");
677
+ var invalidStyles2 = import_styled_components6.css`
678
+ border-color: ${({ theme }) => theme.colors.form.border.error};
679
+
680
+ ${StyledChevron} {
681
+ color: ${({ theme }) => theme.colors.icon.error};
682
+ }
683
+ `;
632
684
  var ComboboxLabel = import_styled_components6.default.label`
633
685
  font-size: ${({ theme }) => theme.typography[200].fontSize};
634
686
  font-weight: ${({ theme }) => theme.fontWeights.semibold};
@@ -655,6 +707,8 @@ var ComboboxInputGroup = (0, import_styled_components6.default)(import_combobox.
655
707
  opacity: 0.4;
656
708
  cursor: not-allowed;
657
709
  }
710
+
711
+ ${({ $isInvalid }) => $isInvalid && invalidStyles2}
658
712
  `;
659
713
  var ComboboxInput = (0, import_styled_components6.default)(import_combobox.Combobox.Input)`
660
714
  flex: 1;
@@ -702,7 +756,7 @@ var ComboboxActionButtons = import_styled_components6.default.div`
702
756
  margin-left: auto;
703
757
  gap: ${({ theme }) => theme.space[100]};
704
758
  `;
705
- var ComboboxClear = (0, import_styled_components6.default)(import_combobox.Combobox.Clear)`
759
+ var ComboboxClear = (0, import_styled_components6.default)(import_combobox.Combobox.Clear).attrs({ tabIndex: 0 })`
706
760
  display: flex;
707
761
  align-items: center;
708
762
  justify-content: center;
@@ -719,6 +773,10 @@ var ComboboxClear = (0, import_styled_components6.default)(import_combobox.Combo
719
773
  color: ${({ theme }) => theme.colors.text.body};
720
774
  }
721
775
 
776
+ &:focus-visible {
777
+ ${import_seeds_react_mixins2.focusRing}
778
+ }
779
+
722
780
  &[data-empty] {
723
781
  display: none;
724
782
  }
@@ -751,7 +809,7 @@ var ComboboxPopup = (0, import_styled_components6.default)(import_combobox.Combo
751
809
  box-shadow: ${({ theme }) => theme.shadows.medium};
752
810
  outline: none;
753
811
  width: 100%;
754
- max-height: min(var(--base-ui-available-height, 400px), 400px);
812
+ max-height: min(var(--available-height, 400px), 400px);
755
813
  overflow-y: auto;
756
814
  padding: 0;
757
815
 
@@ -879,6 +937,12 @@ var ComboboxGroupHeaderItem = (0, import_styled_components6.default)(import_comb
879
937
  background: ${({ theme }) => theme.colors.listItem.background.hover};
880
938
  color: ${({ theme }) => theme.colors.text.body};
881
939
  }
940
+
941
+ &[data-disabled] {
942
+ opacity: 0.4;
943
+ cursor: not-allowed;
944
+ pointer-events: none;
945
+ }
882
946
  `;
883
947
  var ComboboxSelectAllItem = (0, import_styled_components6.default)(import_combobox.Combobox.Item)`
884
948
  display: flex;
@@ -918,6 +982,7 @@ var ComboboxToken = (0, import_styled_components6.default)(import_combobox.Combo
918
982
  display: flex;
919
983
  width: 100%;
920
984
  flex-wrap: wrap;
985
+ gap: ${({ theme }) => theme.space[200]};
921
986
  `;
922
987
  var ComboboxTokenInputGroup = (0, import_styled_components6.default)(import_combobox.Combobox.InputGroup)`
923
988
  display: flex;
@@ -942,6 +1007,8 @@ var ComboboxTokenInputGroup = (0, import_styled_components6.default)(import_comb
942
1007
  opacity: 0.4;
943
1008
  cursor: not-allowed;
944
1009
  }
1010
+
1011
+ ${({ $isInvalid }) => $isInvalid && invalidStyles2}
945
1012
  `;
946
1013
  var Token = import_styled_components6.default.span`
947
1014
  display: inline-flex;
@@ -974,6 +1041,10 @@ var TokenRemove = import_styled_components6.default.button`
974
1041
  cursor: pointer;
975
1042
  padding: 0;
976
1043
  line-height: 1;
1044
+
1045
+ &:focus-visible {
1046
+ ${import_seeds_react_mixins2.focusRing}
1047
+ }
977
1048
  `;
978
1049
  var SearchableSelectTrigger = (0, import_styled_components6.default)(import_combobox.Combobox.Trigger)`
979
1050
  display: flex;
@@ -1007,6 +1078,8 @@ var SearchableSelectTrigger = (0, import_styled_components6.default)(import_comb
1007
1078
  opacity: 0.4;
1008
1079
  cursor: not-allowed;
1009
1080
  }
1081
+
1082
+ ${({ $isInvalid }) => $isInvalid && invalidStyles2}
1010
1083
  `;
1011
1084
  var SearchableSelectTriggerIcon = (0, import_styled_components6.default)(import_combobox.Combobox.Icon)`
1012
1085
  display: flex;
@@ -1089,6 +1162,8 @@ var SearchableSelectTokenTrigger = (0, import_styled_components6.default)(import
1089
1162
  opacity: 0.4;
1090
1163
  cursor: not-allowed;
1091
1164
  }
1165
+
1166
+ ${({ $isInvalid }) => $isInvalid && invalidStyles2}
1092
1167
  `;
1093
1168
 
1094
1169
  // src/v3/Common/ComboboxItem.tsx
@@ -1153,11 +1228,11 @@ function ComboboxItemInner({
1153
1228
  }
1154
1229
  );
1155
1230
  }
1156
- var ComboboxItem2 = React6.forwardRef(ComboboxItemInner);
1231
+ var ComboboxItem2 = React7.forwardRef(ComboboxItemInner);
1157
1232
  var ComboboxItem_default = ComboboxItem2;
1158
1233
 
1159
1234
  // src/v3/Common/VirtualizedComboboxList.tsx
1160
- var React7 = __toESM(require("react"));
1235
+ var React8 = __toESM(require("react"));
1161
1236
  var import_combobox2 = require("@base-ui/react/combobox");
1162
1237
  var import_react_virtual = require("@tanstack/react-virtual");
1163
1238
 
@@ -1194,10 +1269,11 @@ function VirtualizedComboboxList({
1194
1269
  inputType,
1195
1270
  renderItem,
1196
1271
  renderGroupHeading,
1272
+ isGroupHeaderDisabled,
1197
1273
  renderCreatableItem
1198
1274
  }) {
1199
1275
  const filteredItems = import_combobox2.Combobox.useFilteredItems();
1200
- const scrollElementRef = React7.useRef(null);
1276
+ const scrollElementRef = React8.useRef(null);
1201
1277
  const virtualizer = (0, import_react_virtual.useVirtualizer)({
1202
1278
  enabled: open,
1203
1279
  count: filteredItems.length,
@@ -1209,8 +1285,8 @@ function VirtualizedComboboxList({
1209
1285
  scrollPaddingStart: 4,
1210
1286
  scrollPaddingEnd: 4
1211
1287
  });
1212
- React7.useImperativeHandle(virtualizerRef, () => virtualizer);
1213
- const handleScrollRef = React7.useCallback(
1288
+ React8.useImperativeHandle(virtualizerRef, () => virtualizer);
1289
+ const handleScrollRef = React8.useCallback(
1214
1290
  (el) => {
1215
1291
  scrollElementRef.current = el;
1216
1292
  if (el) requestAnimationFrame(() => virtualizer.measure());
@@ -1296,6 +1372,7 @@ function VirtualizedComboboxList({
1296
1372
  index: virtualItem.index,
1297
1373
  "data-index": virtualItem.index,
1298
1374
  value: row,
1375
+ disabled: isGroupHeaderDisabled?.(row.groupName),
1299
1376
  style: baseStyle,
1300
1377
  ref: virtualizer.measureElement,
1301
1378
  children: [
@@ -1358,6 +1435,7 @@ function SingleCombobox(props) {
1358
1435
  fullWidth = true
1359
1436
  } = props;
1360
1437
  const ariaDescribedBy = props["aria-describedby"];
1438
+ const isInvalid = props.isInvalid;
1361
1439
  const isChildrenMode = "children" in props && props.children != null;
1362
1440
  const data = isChildrenMode ? [] : props.data;
1363
1441
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1371,17 +1449,18 @@ function SingleCombobox(props) {
1371
1449
  const defaultSelectedItemId = props.defaultSelectedItemId;
1372
1450
  const onSelectedItemIdChange = props.onSelectedItemIdChange;
1373
1451
  const { containerRef, portalContainer } = useSeedsPortalContainer();
1374
- const [open, setOpen] = React8.useState(false);
1375
- const virtualizerRef = React8.useRef(null);
1452
+ const [open, setOpen] = React9.useState(false);
1453
+ const virtualizerRef = React9.useRef(null);
1454
+ const onInputKeyDownCapture = useSuppressEscapeClear(open);
1376
1455
  const isControlled = selectedItemId !== void 0;
1377
- const idToItem = React8.useCallback(
1456
+ const idToItem = React9.useCallback(
1378
1457
  (id2) => {
1379
1458
  if (id2 == null) return null;
1380
1459
  return data.find((d) => String(d.id) === String(id2)) ?? null;
1381
1460
  },
1382
1461
  [data]
1383
1462
  );
1384
- const [internalValue, setInternalValue] = React8.useState(
1463
+ const [internalValue, setInternalValue] = React9.useState(
1385
1464
  () => idToItem(defaultSelectedItemId)
1386
1465
  );
1387
1466
  const value = isControlled ? idToItem(selectedItemId) : internalValue;
@@ -1393,7 +1472,7 @@ function SingleCombobox(props) {
1393
1472
  onSelectedItemIdChange(newItem ? newItem.id : null);
1394
1473
  }
1395
1474
  }
1396
- const groups = React8.useMemo(
1475
+ const groups = React9.useMemo(
1397
1476
  () => groupBy ? groupItems(data, groupBy) : null,
1398
1477
  [data, groupBy]
1399
1478
  );
@@ -1418,29 +1497,38 @@ function SingleCombobox(props) {
1418
1497
  if (!item || !virt) return;
1419
1498
  const isStart = index === 0;
1420
1499
  const isEnd = index === virt.options.count - 1;
1421
- if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
1500
+ if (reason === "keyboard" && (isStart || isEnd)) {
1422
1501
  queueMicrotask(() => {
1423
1502
  virt.scrollToIndex(index, {
1424
- align: isEnd ? "start" : "end"
1503
+ align: isStart ? "start" : "end"
1425
1504
  });
1426
1505
  });
1427
1506
  }
1428
1507
  } : void 0,
1429
1508
  children: [
1430
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxInputGroup, { children: [
1431
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1432
- ComboboxInput,
1433
- {
1434
- placeholder,
1435
- id,
1436
- "aria-describedby": ariaDescribedBy
1437
- }
1438
- ),
1439
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxActionButtons, { children: [
1440
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxClear, { "aria-label": "Clear selection", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ClearIcon, {}) }),
1441
- /* @__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, {}) }) })
1442
- ] })
1443
- ] }),
1509
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1510
+ ComboboxInputGroup,
1511
+ {
1512
+ $isInvalid: isInvalid,
1513
+ onKeyDownCapture: onInputKeyDownCapture,
1514
+ children: [
1515
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1516
+ ComboboxInput,
1517
+ {
1518
+ placeholder,
1519
+ id,
1520
+ "aria-describedby": ariaDescribedBy,
1521
+ "aria-invalid": isInvalid || void 0,
1522
+ "aria-required": props.required || void 0
1523
+ }
1524
+ ),
1525
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxActionButtons, { children: [
1526
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxClear, { "aria-label": "Clear selection", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ClearIcon, {}) }),
1527
+ /* @__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, {}) }) })
1528
+ ] })
1529
+ ]
1530
+ }
1531
+ ),
1444
1532
  /* @__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)(
1445
1533
  ComboboxPopup,
1446
1534
  {
@@ -1470,7 +1558,7 @@ function SingleCombobox(props) {
1470
1558
  renderItem,
1471
1559
  renderGroupHeading
1472
1560
  }
1473
- ) : children ? children : groups ? (group, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(React8.Fragment, { children: [
1561
+ ) : children ? children : groups ? ((group, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(React9.Fragment, { children: [
1474
1562
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxGroup, { items: group.items, children: [
1475
1563
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
1476
1564
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_combobox3.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
@@ -1487,7 +1575,7 @@ function SingleCombobox(props) {
1487
1575
  ) })
1488
1576
  ] }),
1489
1577
  index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxSeparator, {})
1490
- ] }, group.value) : (item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1578
+ ] }, group.value)) : ((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1491
1579
  ComboboxItem_default,
1492
1580
  {
1493
1581
  value: item,
@@ -1498,7 +1586,7 @@ function SingleCombobox(props) {
1498
1586
  renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1499
1587
  },
1500
1588
  item.id
1501
- )
1589
+ ))
1502
1590
  }
1503
1591
  )
1504
1592
  ]
@@ -1511,7 +1599,7 @@ function SingleCombobox(props) {
1511
1599
  }
1512
1600
 
1513
1601
  // src/v3/MultiCombobox.tsx
1514
- var React9 = __toESM(require("react"));
1602
+ var React10 = __toESM(require("react"));
1515
1603
  var import_combobox4 = require("@base-ui/react/combobox");
1516
1604
  var import_react_virtual3 = require("@tanstack/react-virtual");
1517
1605
  var import_seeds_react_icon3 = __toESM(require("@sproutsocial/seeds-react-icon"));
@@ -1539,6 +1627,7 @@ function MultiCombobox(props) {
1539
1627
  fullWidth = true
1540
1628
  } = props;
1541
1629
  const ariaDescribedBy = props["aria-describedby"];
1630
+ const isInvalid = props.isInvalid;
1542
1631
  const isChildrenMode = "children" in props && props.children != null;
1543
1632
  const data = isChildrenMode ? [] : props.data;
1544
1633
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1550,6 +1639,7 @@ function MultiCombobox(props) {
1550
1639
  const inputType = isChildrenMode ? "checkbox" : removeSelectedItems ? "none" : props.inputType ?? "checkbox";
1551
1640
  const groupBy = isChildrenMode ? void 0 : props.groupBy;
1552
1641
  const renderGroupHeading = isChildrenMode ? void 0 : props.renderGroupHeading;
1642
+ const isGroupHeaderDisabled = isChildrenMode ? void 0 : props.isGroupHeaderDisabled;
1553
1643
  const selectHeadings = isChildrenMode ? false : props.selectHeadings ?? false;
1554
1644
  const selectAllProp = isChildrenMode ? false : props.selectAll ?? false;
1555
1645
  const selectAll = Boolean(selectAllProp);
@@ -1562,29 +1652,31 @@ function MultiCombobox(props) {
1562
1652
  const defaultSelectedItemIds = props.defaultSelectedItemIds;
1563
1653
  const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
1564
1654
  const { containerRef, portalContainer } = useSeedsPortalContainer();
1565
- const [open, setOpen] = React9.useState(false);
1566
- const [internalInputValue, setInternalInputValue] = React9.useState("");
1567
- const skipNextInputChangeRef = React9.useRef(false);
1568
- const virtualizerRef = React9.useRef(null);
1655
+ const [open, setOpen] = React10.useState(false);
1656
+ const [internalInputValue, setInternalInputValue] = React10.useState("");
1657
+ const skipNextInputChangeRef = React10.useRef(false);
1658
+ const virtualizerRef = React10.useRef(null);
1659
+ const inputRef = React10.useRef(null);
1660
+ const onInputKeyDownCapture = useSuppressEscapeClear(open);
1569
1661
  const isControlled = selectedItemIds !== void 0;
1570
- const idsToItems = React9.useCallback(
1662
+ const idsToItems = React10.useCallback(
1571
1663
  (ids) => ids.map((id2) => data.find((d) => d.id === id2)).filter((d) => d != null),
1572
1664
  [data]
1573
1665
  );
1574
- const [internalValue, setInternalValue] = React9.useState(
1666
+ const [internalValue, setInternalValue] = React10.useState(
1575
1667
  () => defaultSelectedItemIds ? idsToItems(defaultSelectedItemIds) : []
1576
1668
  );
1577
1669
  const value = isControlled ? idsToItems(selectedItemIds) : internalValue;
1578
- const visibleData = React9.useMemo(
1670
+ const visibleData = React10.useMemo(
1579
1671
  () => removeSelectedItems ? data.filter((item) => !value.some((v) => v.id === item.id)) : data,
1580
1672
  [data, value, removeSelectedItems]
1581
1673
  );
1582
- const groups = React9.useMemo(
1674
+ const groups = React10.useMemo(
1583
1675
  () => groupBy ? groupItems(visibleData, groupBy) : null,
1584
1676
  [visibleData, groupBy]
1585
1677
  );
1586
1678
  const currentInputValue = inputValue ?? internalInputValue;
1587
- const creatableSentinel = React9.useMemo(() => {
1679
+ const creatableSentinel = React10.useMemo(() => {
1588
1680
  if (!creatableProp) return null;
1589
1681
  const trimmed = currentInputValue.trim();
1590
1682
  if (!trimmed) return null;
@@ -1595,7 +1687,7 @@ function MultiCombobox(props) {
1595
1687
  if (exactExists) return null;
1596
1688
  return makeCreatableSentinel(trimmed);
1597
1689
  }, [creatableProp, currentInputValue, data, itemToString]);
1598
- const flatItems = React9.useMemo(() => {
1690
+ const flatItems = React10.useMemo(() => {
1599
1691
  if (!selectHeadings && !selectAll) return null;
1600
1692
  if (!groups && !selectAll) return null;
1601
1693
  const rows = [];
@@ -1646,6 +1738,7 @@ function MultiCombobox(props) {
1646
1738
  }
1647
1739
  let updated = [...realItems];
1648
1740
  for (const sentinel of groupSentinels) {
1741
+ if (isGroupHeaderDisabled?.(sentinel.groupName)) continue;
1649
1742
  const group = groups?.find((g) => g.value === sentinel.groupName);
1650
1743
  if (!group) continue;
1651
1744
  const allSelected = group.items.every(
@@ -1681,6 +1774,7 @@ function MultiCombobox(props) {
1681
1774
  e.preventDefault();
1682
1775
  e.stopPropagation();
1683
1776
  setSelectedItems(value.filter((v) => v.id !== item.id));
1777
+ inputRef.current?.focus();
1684
1778
  }
1685
1779
  function renderSentinelRow(row) {
1686
1780
  if (isSelectAllSentinel2(row)) {
@@ -1699,16 +1793,24 @@ function MultiCombobox(props) {
1699
1793
  (item2) => value.some((s) => s.id === item2.id)
1700
1794
  ).length;
1701
1795
  const state = selectedCount === 0 ? "none" : selectedCount === groupItemsList.length ? "all" : "partial";
1702
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxGroupHeaderItem, { value: row, children: [
1703
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1704
- ComboboxGroupHeaderCheckbox,
1705
- {
1706
- $state: state,
1707
- id: `__header-${row.groupName}`
1708
- }
1709
- ),
1710
- renderGroupHeading ? renderGroupHeading(row.groupName) : row.groupName
1711
- ] }, `__header-${row.groupName}`);
1796
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1797
+ ComboboxGroupHeaderItem,
1798
+ {
1799
+ value: row,
1800
+ disabled: isGroupHeaderDisabled?.(row.groupName),
1801
+ children: [
1802
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1803
+ ComboboxGroupHeaderCheckbox,
1804
+ {
1805
+ $state: state,
1806
+ id: `__header-${row.groupName}`
1807
+ }
1808
+ ),
1809
+ renderGroupHeading ? renderGroupHeading(row.groupName) : row.groupName
1810
+ ]
1811
+ },
1812
+ `__header-${row.groupName}`
1813
+ );
1712
1814
  }
1713
1815
  if (isCreatableSentinel(row)) {
1714
1816
  return renderCreatableItem(row);
@@ -1762,7 +1864,10 @@ function MultiCombobox(props) {
1762
1864
  open,
1763
1865
  disabled: props.disabled,
1764
1866
  onOpenChange: (nextOpen, eventDetails) => {
1765
- if (!nextOpen && eventDetails.reason === "item-press") return;
1867
+ if (!nextOpen && eventDetails.reason === "item-press") {
1868
+ eventDetails.cancel();
1869
+ return;
1870
+ }
1766
1871
  setOpen(nextOpen);
1767
1872
  },
1768
1873
  filter: creatableProp ? (item, query) => {
@@ -1795,10 +1900,10 @@ function MultiCombobox(props) {
1795
1900
  if (!item || !virt) return;
1796
1901
  const isStart = index === 0;
1797
1902
  const isEnd = index === virt.options.count - 1;
1798
- if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
1903
+ if (reason === "keyboard" && (isStart || isEnd)) {
1799
1904
  queueMicrotask(() => {
1800
1905
  virt.scrollToIndex(index, {
1801
- align: isEnd ? "start" : "end"
1906
+ align: isStart ? "start" : "end"
1802
1907
  });
1803
1908
  });
1804
1909
  }
@@ -1825,42 +1930,52 @@ function MultiCombobox(props) {
1825
1930
  },
1826
1931
  items: rootItems,
1827
1932
  children: [
1828
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxTokenInputGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxToken, { children: [
1829
- renderSelection ? renderSelection(value) : (() => {
1830
- const visibleTokens = maxTokens != null ? value.slice(0, maxTokens) : value;
1831
- const overflow = maxTokens != null ? value.length - maxTokens : 0;
1832
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1833
- visibleTokens.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Token, { children: [
1834
- renderToken ? renderToken(item) : itemToString(item),
1835
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1836
- TokenRemove,
1837
- {
1838
- "aria-label": `Remove ${itemToString(item)}`,
1839
- onPointerDown: (e) => e.preventDefault(),
1840
- onClick: (e) => removeItem(item, e),
1841
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_seeds_react_icon3.default, { name: "x-outline", size: "mini" })
1842
- }
1843
- )
1844
- ] }, item.id)),
1845
- overflow > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Token, { children: [
1846
- "+",
1847
- overflow
1848
- ] }, "__overflow")
1849
- ] });
1850
- })(),
1851
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1852
- ComboboxTokenInput,
1853
- {
1854
- id,
1855
- placeholder: value.length > 0 ? "" : placeholder,
1856
- "aria-describedby": ariaDescribedBy
1857
- }
1858
- ),
1859
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxActionButtons, { children: [
1860
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxClear, { "aria-label": "Clear all", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ClearIcon, {}) }),
1861
- /* @__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, {}) }) })
1862
- ] })
1863
- ] }) }),
1933
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1934
+ ComboboxTokenInputGroup,
1935
+ {
1936
+ $isInvalid: isInvalid,
1937
+ onKeyDownCapture: onInputKeyDownCapture,
1938
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxToken, { children: [
1939
+ renderSelection ? renderSelection(value) : (() => {
1940
+ const visibleTokens = maxTokens != null ? value.slice(0, maxTokens) : value;
1941
+ const overflow = maxTokens != null ? value.length - maxTokens : 0;
1942
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1943
+ visibleTokens.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Token, { children: [
1944
+ renderToken ? renderToken(item) : itemToString(item),
1945
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1946
+ TokenRemove,
1947
+ {
1948
+ "aria-label": `Remove ${itemToString(item)}`,
1949
+ onPointerDown: (e) => e.preventDefault(),
1950
+ onClick: (e) => removeItem(item, e),
1951
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_seeds_react_icon3.default, { name: "x-outline", size: "mini" })
1952
+ }
1953
+ )
1954
+ ] }, item.id)),
1955
+ overflow > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Token, { children: [
1956
+ "+",
1957
+ overflow
1958
+ ] }, "__overflow")
1959
+ ] });
1960
+ })(),
1961
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1962
+ ComboboxTokenInput,
1963
+ {
1964
+ ref: inputRef,
1965
+ id,
1966
+ placeholder: value.length > 0 ? "" : placeholder,
1967
+ "aria-describedby": ariaDescribedBy,
1968
+ "aria-invalid": isInvalid || void 0,
1969
+ "aria-required": props.required || void 0
1970
+ }
1971
+ ),
1972
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxActionButtons, { children: [
1973
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxClear, { "aria-label": "Clear all", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ClearIcon, {}) }),
1974
+ /* @__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, {}) }) })
1975
+ ] })
1976
+ ] })
1977
+ }
1978
+ ),
1864
1979
  /* @__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)(
1865
1980
  ComboboxPopup,
1866
1981
  {
@@ -1891,6 +2006,7 @@ function MultiCombobox(props) {
1891
2006
  inputType,
1892
2007
  renderItem,
1893
2008
  renderGroupHeading,
2009
+ isGroupHeaderDisabled,
1894
2010
  renderCreatableItem: creatableProp ? (sentinel, style, index, measureRef) => renderCreatableItem(
1895
2011
  sentinel,
1896
2012
  style,
@@ -1898,12 +2014,12 @@ function MultiCombobox(props) {
1898
2014
  measureRef
1899
2015
  ) : void 0
1900
2016
  }
1901
- ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => {
2017
+ ) : children ? children : flatItems ? ((row) => renderSentinelRow(row)) : groups ? ((group, index) => {
1902
2018
  if (isCreatableSentinel(group)) {
1903
2019
  return renderCreatableItem(group);
1904
2020
  }
1905
2021
  const g = group;
1906
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(React9.Fragment, { children: [
2022
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(React10.Fragment, { children: [
1907
2023
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxGroup, { items: g.items, children: [
1908
2024
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(g.value) : g.value }),
1909
2025
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_combobox4.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -1921,7 +2037,7 @@ function MultiCombobox(props) {
1921
2037
  ] }),
1922
2038
  index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxSeparator, {})
1923
2039
  ] }, g.value);
1924
- } : (item) => {
2040
+ }) : ((item) => {
1925
2041
  if (isCreatableSentinel(item)) {
1926
2042
  return renderCreatableItem(item);
1927
2043
  }
@@ -1938,7 +2054,7 @@ function MultiCombobox(props) {
1938
2054
  },
1939
2055
  dataItem.id
1940
2056
  );
1941
- }
2057
+ })
1942
2058
  }
1943
2059
  )
1944
2060
  ]
@@ -1951,7 +2067,7 @@ function MultiCombobox(props) {
1951
2067
  }
1952
2068
 
1953
2069
  // src/v3/SingleSearchableSelect.tsx
1954
- var React10 = __toESM(require("react"));
2070
+ var React11 = __toESM(require("react"));
1955
2071
  var import_combobox5 = require("@base-ui/react/combobox");
1956
2072
  var import_react_virtual4 = require("@tanstack/react-virtual");
1957
2073
  var import_jsx_runtime10 = require("react/jsx-runtime");
@@ -1968,6 +2084,7 @@ function SingleSearchableSelect(props) {
1968
2084
  fullWidth = true
1969
2085
  } = props;
1970
2086
  const ariaDescribedBy = props["aria-describedby"];
2087
+ const isInvalid = props.isInvalid;
1971
2088
  const isChildrenMode = "children" in props && props.children != null;
1972
2089
  const data = isChildrenMode ? [] : props.data;
1973
2090
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1982,17 +2099,17 @@ function SingleSearchableSelect(props) {
1982
2099
  const defaultSelectedItemId = props.defaultSelectedItemId;
1983
2100
  const onSelectedItemIdChange = props.onSelectedItemIdChange;
1984
2101
  const { containerRef, portalContainer } = useSeedsPortalContainer();
1985
- const [open, setOpen] = React10.useState(false);
1986
- const virtualizerRef = React10.useRef(null);
2102
+ const [open, setOpen] = React11.useState(false);
2103
+ const virtualizerRef = React11.useRef(null);
1987
2104
  const isControlled = selectedItemId !== void 0;
1988
- const idToItem = React10.useCallback(
2105
+ const idToItem = React11.useCallback(
1989
2106
  (id2) => {
1990
2107
  if (id2 == null) return null;
1991
2108
  return data.find((d) => String(d.id) === String(id2)) ?? null;
1992
2109
  },
1993
2110
  [data]
1994
2111
  );
1995
- const [internalValue, setInternalValue] = React10.useState(
2112
+ const [internalValue, setInternalValue] = React11.useState(
1996
2113
  () => idToItem(defaultSelectedItemId)
1997
2114
  );
1998
2115
  const value = isControlled ? idToItem(selectedItemId) : internalValue;
@@ -2003,7 +2120,7 @@ function SingleSearchableSelect(props) {
2003
2120
  onSelectedItemIdChange(realItem ? realItem.id : null);
2004
2121
  }
2005
2122
  }
2006
- const groups = React10.useMemo(
2123
+ const groups = React11.useMemo(
2007
2124
  () => groupBy ? groupItems(data, groupBy) : null,
2008
2125
  [data, groupBy]
2009
2126
  );
@@ -2033,19 +2150,29 @@ function SingleSearchableSelect(props) {
2033
2150
  if (!item || !virt) return;
2034
2151
  const isStart = index === 0;
2035
2152
  const isEnd = index === virt.options.count - 1;
2036
- if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
2153
+ if (reason === "keyboard" && (isStart || isEnd)) {
2037
2154
  queueMicrotask(() => {
2038
2155
  virt.scrollToIndex(index, {
2039
- align: isEnd ? "start" : "end"
2156
+ align: isStart ? "start" : "end"
2040
2157
  });
2041
2158
  });
2042
2159
  }
2043
2160
  } : void 0,
2044
2161
  children: [
2045
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SearchableSelectTrigger, { id, "aria-describedby": ariaDescribedBy, children: [
2046
- /* @__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) : placeholder }) }),
2047
- /* @__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, {}) }) })
2048
- ] }),
2162
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2163
+ SearchableSelectTrigger,
2164
+ {
2165
+ id,
2166
+ "aria-describedby": ariaDescribedBy,
2167
+ "aria-invalid": isInvalid || void 0,
2168
+ "aria-required": props.required || void 0,
2169
+ $isInvalid: isInvalid,
2170
+ children: [
2171
+ /* @__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) : placeholder }) }),
2172
+ /* @__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, {}) }) })
2173
+ ]
2174
+ }
2175
+ ),
2049
2176
  /* @__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)(
2050
2177
  SearchableSelectPopup,
2051
2178
  {
@@ -2083,7 +2210,7 @@ function SingleSearchableSelect(props) {
2083
2210
  inputType,
2084
2211
  renderItem
2085
2212
  }
2086
- ) : children ? children : groups ? (group, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(React10.Fragment, { children: [
2213
+ ) : children ? children : groups ? ((group, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(React11.Fragment, { children: [
2087
2214
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ComboboxGroup, { items: group.items, children: [
2088
2215
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
2089
2216
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_combobox5.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
@@ -2100,7 +2227,7 @@ function SingleSearchableSelect(props) {
2100
2227
  ) })
2101
2228
  ] }),
2102
2229
  index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComboboxSeparator, {})
2103
- ] }, group.value) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2230
+ ] }, group.value)) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2104
2231
  includePlaceholderItem && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2105
2232
  ComboboxItem_default,
2106
2233
  {
@@ -2136,7 +2263,7 @@ function SingleSearchableSelect(props) {
2136
2263
  }
2137
2264
 
2138
2265
  // src/v3/MultiSearchableSelect.tsx
2139
- var React11 = __toESM(require("react"));
2266
+ var React12 = __toESM(require("react"));
2140
2267
  var import_combobox6 = require("@base-ui/react/combobox");
2141
2268
  var import_react_virtual5 = require("@tanstack/react-virtual");
2142
2269
  var import_seeds_react_icon4 = __toESM(require("@sproutsocial/seeds-react-icon"));
@@ -2170,6 +2297,7 @@ function MultiSearchableSelect(props) {
2170
2297
  fullWidth = true
2171
2298
  } = props;
2172
2299
  const ariaDescribedBy = props["aria-describedby"];
2300
+ const isInvalid = props.isInvalid;
2173
2301
  const isChildrenMode = "children" in props && props.children != null;
2174
2302
  const data = isChildrenMode ? [] : props.data;
2175
2303
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -2191,29 +2319,29 @@ function MultiSearchableSelect(props) {
2191
2319
  const defaultSelectedItemIds = props.defaultSelectedItemIds;
2192
2320
  const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
2193
2321
  const { containerRef, portalContainer } = useSeedsPortalContainer();
2194
- const [open, setOpen] = React11.useState(false);
2195
- const [internalInputValue, setInternalInputValue] = React11.useState("");
2196
- const skipNextInputChangeRef = React11.useRef(false);
2197
- const virtualizerRef = React11.useRef(null);
2322
+ const [open, setOpen] = React12.useState(false);
2323
+ const [internalInputValue, setInternalInputValue] = React12.useState("");
2324
+ const skipNextInputChangeRef = React12.useRef(false);
2325
+ const virtualizerRef = React12.useRef(null);
2198
2326
  const isControlled = selectedItemIds !== void 0;
2199
- const idsToItems = React11.useCallback(
2327
+ const idsToItems = React12.useCallback(
2200
2328
  (ids) => ids.map((id2) => data.find((d) => d.id === id2)).filter((d) => d != null),
2201
2329
  [data]
2202
2330
  );
2203
- const [internalValue, setInternalValue] = React11.useState(
2331
+ const [internalValue, setInternalValue] = React12.useState(
2204
2332
  () => defaultSelectedItemIds ? idsToItems(defaultSelectedItemIds) : []
2205
2333
  );
2206
2334
  const value = isControlled ? idsToItems(selectedItemIds) : internalValue;
2207
- const visibleData = React11.useMemo(
2335
+ const visibleData = React12.useMemo(
2208
2336
  () => removeSelectedItems ? data.filter((item) => !value.some((v) => v.id === item.id)) : data,
2209
2337
  [data, value, removeSelectedItems]
2210
2338
  );
2211
- const groups = React11.useMemo(
2339
+ const groups = React12.useMemo(
2212
2340
  () => groupBy ? groupItems(visibleData, groupBy) : null,
2213
2341
  [visibleData, groupBy]
2214
2342
  );
2215
2343
  const currentInputValue = internalInputValue;
2216
- const creatableSentinel = React11.useMemo(() => {
2344
+ const creatableSentinel = React12.useMemo(() => {
2217
2345
  if (!creatableProp) return null;
2218
2346
  const trimmed = currentInputValue.trim();
2219
2347
  if (!trimmed) return null;
@@ -2224,7 +2352,7 @@ function MultiSearchableSelect(props) {
2224
2352
  if (exactExists) return null;
2225
2353
  return makeCreatableSentinel(trimmed);
2226
2354
  }, [creatableProp, currentInputValue, data, itemToString]);
2227
- const flatItems = React11.useMemo(() => {
2355
+ const flatItems = React12.useMemo(() => {
2228
2356
  if (!groups || !selectHeadings && !selectAll) return null;
2229
2357
  const rows = [];
2230
2358
  if (selectAll) rows.push(SELECT_ALL_SENTINEL2);
@@ -2401,10 +2529,10 @@ function MultiSearchableSelect(props) {
2401
2529
  if (!item || !virt) return;
2402
2530
  const isStart = index === 0;
2403
2531
  const isEnd = index === virt.options.count - 1;
2404
- if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
2532
+ if (reason === "keyboard" && (isStart || isEnd)) {
2405
2533
  queueMicrotask(() => {
2406
2534
  virt.scrollToIndex(index, {
2407
- align: isEnd ? "start" : "end"
2535
+ align: isStart ? "start" : "end"
2408
2536
  });
2409
2537
  });
2410
2538
  }
@@ -2436,6 +2564,9 @@ function MultiSearchableSelect(props) {
2436
2564
  {
2437
2565
  id,
2438
2566
  "aria-describedby": ariaDescribedBy,
2567
+ "aria-invalid": isInvalid || void 0,
2568
+ "aria-required": props.required || void 0,
2569
+ $isInvalid: isInvalid,
2439
2570
  children: [
2440
2571
  renderSelection ? renderSelection(value) : value.length > 0 ? (() => {
2441
2572
  const visibleItems = maxSelections != null ? value.slice(0, maxSelections) : value;
@@ -2496,12 +2627,12 @@ function MultiSearchableSelect(props) {
2496
2627
  measureRef
2497
2628
  ) : void 0
2498
2629
  }
2499
- ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => {
2630
+ ) : children ? children : flatItems ? ((row) => renderSentinelRow(row)) : groups ? ((group, index) => {
2500
2631
  if (isCreatableSentinel(group)) {
2501
2632
  return renderCreatableItem(group);
2502
2633
  }
2503
2634
  const g = group;
2504
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React11.Fragment, { children: [
2635
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React12.Fragment, { children: [
2505
2636
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ComboboxGroup, { items: g.items, children: [
2506
2637
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(g.value) : g.value }),
2507
2638
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_combobox6.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
@@ -2519,7 +2650,7 @@ function MultiSearchableSelect(props) {
2519
2650
  ] }),
2520
2651
  index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxSeparator, {})
2521
2652
  ] }, g.value);
2522
- } : (item) => {
2653
+ }) : ((item) => {
2523
2654
  if (isCreatableSentinel(item)) {
2524
2655
  return renderCreatableItem(item);
2525
2656
  }
@@ -2536,7 +2667,7 @@ function MultiSearchableSelect(props) {
2536
2667
  },
2537
2668
  dataItem.id
2538
2669
  );
2539
- }
2670
+ })
2540
2671
  }
2541
2672
  )
2542
2673
  ]
@@ -2549,7 +2680,7 @@ function MultiSearchableSelect(props) {
2549
2680
  }
2550
2681
 
2551
2682
  // src/v3/ActionMenu.tsx
2552
- var React12 = __toESM(require("react"));
2683
+ var React13 = __toESM(require("react"));
2553
2684
  var import_menu2 = require("@base-ui/react/menu");
2554
2685
  var import_seeds_react_radio3 = __toESM(require("@sproutsocial/seeds-react-radio"));
2555
2686
  var import_seeds_react_checkbox4 = __toESM(require("@sproutsocial/seeds-react-checkbox"));
@@ -2564,16 +2695,18 @@ var ActionMenuPositioner = (0, import_styled_components8.default)(import_menu.Me
2564
2695
  min-width: var(--anchor-width);
2565
2696
  z-index: 7;
2566
2697
  `;
2567
- var ActionMenuPopup = (0, import_styled_components8.default)(import_menu.Menu.Popup)`
2698
+ var ActionMenuPopup = (0, import_styled_components8.default)(import_menu.Menu.Popup).attrs({
2699
+ "data-base-ui-swipe-ignore": ""
2700
+ })`
2568
2701
  font-family: ${({ theme }) => theme.fontFamily};
2569
2702
  background: ${({ theme }) => theme.colors.container.background.base};
2570
2703
  border: 1px solid ${({ theme }) => theme.colors.container.border.base};
2571
2704
  border-radius: ${({ theme }) => theme.radii[500]};
2572
2705
  box-shadow: ${({ theme }) => theme.shadows.low};
2573
2706
  outline: none;
2574
- max-height: min(var(--base-ui-available-height, 400px), 400px);
2707
+ max-height: min(var(--available-height, 400px), 400px);
2575
2708
  overflow-y: auto;
2576
- padding: ${({ theme }) => theme.space[200]};
2709
+ padding: ${({ theme }) => theme.space[300]};
2577
2710
 
2578
2711
  &[data-open] {
2579
2712
  animation: action-menu-popup-in 120ms ease-out;
@@ -2609,16 +2742,13 @@ var ActionMenuGroup = (0, import_styled_components8.default)(import_menu.Menu.Gr
2609
2742
  display: block;
2610
2743
  `;
2611
2744
  var ActionMenuGroupLabel = (0, import_styled_components8.default)(import_menu.Menu.GroupLabel)`
2612
- padding: ${({ theme }) => `${theme.space[300]} ${theme.space[300]} ${theme.space[200]}`};
2745
+ padding: ${({ theme }) => `${theme.space[300]}`};
2613
2746
  font-size: ${({ theme }) => theme.typography[100].fontSize};
2614
- font-weight: ${({ theme }) => theme.fontWeights.semibold};
2615
- text-transform: uppercase;
2616
- letter-spacing: 0.05em;
2617
- color: ${({ theme }) => theme.colors.text.subtext};
2747
+ color: ${({ theme }) => theme.colors.text.body};
2618
2748
  `;
2619
2749
  var ActionMenuSeparator = (0, import_styled_components8.default)(import_menu.Menu.Separator)`
2620
2750
  height: 1px;
2621
- margin: ${({ theme }) => `${theme.space[200]} ${theme.space[300]}`};
2751
+ margin: ${({ theme }) => `${theme.space[300]} -${theme.space[300]}`};
2622
2752
  background: ${({ theme }) => theme.colors.container.border.base};
2623
2753
  `;
2624
2754
  var menuItemStyles = import_styled_components8.css`
@@ -2750,7 +2880,7 @@ function MenuRadioGroup({
2750
2880
  );
2751
2881
  }
2752
2882
  function MenuItem(props) {
2753
- const generatedId = React12.useId();
2883
+ const generatedId = React13.useId();
2754
2884
  if (props.type === "checkbox") {
2755
2885
  const {
2756
2886
  children: children2,
@@ -2891,6 +3021,81 @@ function MenuSubTrigger({
2891
3021
  }
2892
3022
  );
2893
3023
  }
3024
+
3025
+ // src/v3/MenuButton.tsx
3026
+ var React14 = require("react");
3027
+ var import_seeds_react_button2 = require("@sproutsocial/seeds-react-button");
3028
+ var import_seeds_react_icon6 = require("@sproutsocial/seeds-react-icon");
3029
+
3030
+ // src/v3/MenuButtonStyles.tsx
3031
+ var import_styled_components9 = __toESM(require("styled-components"));
3032
+ var import_seeds_react_button = require("@sproutsocial/seeds-react-button");
3033
+ var MenuButtonContainer = import_styled_components9.default.div`
3034
+ display: inline-flex;
3035
+ gap: 1px;
3036
+ `;
3037
+ var MainButton = (0, import_styled_components9.default)(import_seeds_react_button.Button)`
3038
+ && {
3039
+ border-top-right-radius: 0;
3040
+ border-bottom-right-radius: 0;
3041
+ }
3042
+ `;
3043
+ var TriggerButton = (0, import_styled_components9.default)(import_seeds_react_button.Button)`
3044
+ && {
3045
+ border-top-left-radius: 0;
3046
+ border-bottom-left-radius: 0;
3047
+ }
3048
+
3049
+ .Icon-svg {
3050
+ transition: transform ${({ theme }) => theme.duration.fast} ease;
3051
+ }
3052
+
3053
+ &[data-popup-open] .Icon-svg {
3054
+ transform: rotate(180deg);
3055
+ }
3056
+ `;
3057
+
3058
+ // src/v3/MenuButton.tsx
3059
+ var import_jsx_runtime13 = require("react/jsx-runtime");
3060
+ function MenuButton({
3061
+ actionMenu,
3062
+ appearance = "primary",
3063
+ size,
3064
+ disabled,
3065
+ menuButtonAriaLabel,
3066
+ children,
3067
+ ...rest
3068
+ }) {
3069
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(MenuButtonContainer, { children: [
3070
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3071
+ MainButton,
3072
+ {
3073
+ appearance,
3074
+ size,
3075
+ disabled,
3076
+ ...rest,
3077
+ children
3078
+ }
3079
+ ),
3080
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3081
+ ActionMenu,
3082
+ {
3083
+ disabled,
3084
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3085
+ TriggerButton,
3086
+ {
3087
+ appearance,
3088
+ size,
3089
+ disabled,
3090
+ ariaLabel: menuButtonAriaLabel,
3091
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_seeds_react_icon6.Icon, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true })
3092
+ }
3093
+ ),
3094
+ children: actionMenu
3095
+ }
3096
+ )
3097
+ ] });
3098
+ }
2894
3099
  // Annotate the CommonJS export names for ESM import in node:
2895
3100
  0 && (module.exports = {
2896
3101
  ActionMenu,
@@ -2916,6 +3121,7 @@ function MenuSubTrigger({
2916
3121
  ComboboxTokenInput,
2917
3122
  ComboboxTokenInputGroup,
2918
3123
  ComboboxTrigger,
3124
+ MenuButton,
2919
3125
  MenuGroup,
2920
3126
  MenuItem,
2921
3127
  MenuRadioGroup,