@sproutsocial/seeds-react-menu 1.13.0 → 1.15.10

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.
@@ -134,20 +134,50 @@ function groupItems(data, groupBy) {
134
134
 
135
135
  // src/v3/Common/SelectStyles.tsx
136
136
  import { Select as Select2 } from "@base-ui/react/select";
137
- import styled2 from "styled-components";
137
+ import styled3, { css } from "styled-components";
138
138
  import { focusRing } from "@sproutsocial/seeds-react-mixins";
139
- var Field = styled2.div`
139
+
140
+ // src/v3/Common/SelectIcons.tsx
141
+ import "react";
142
+ import styled2 from "styled-components";
143
+ import { Icon as Icon2 } from "@sproutsocial/seeds-react-icon";
144
+ import { jsx as jsx2 } from "react/jsx-runtime";
145
+ var StyledChevron = styled2.div`
146
+ display: flex;
147
+ align-items: center;
148
+ transition: transform 0.15s;
149
+ ${({ $isOpen }) => $isOpen && "transform: rotate(-180deg);"}
150
+ `;
151
+ function ChevronIcon() {
152
+ return /* @__PURE__ */ jsx2(Icon2, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true });
153
+ }
154
+ function ClearIcon() {
155
+ return /* @__PURE__ */ jsx2(Icon2, { name: "circle-x-outline", fixedWidth: true, "aria-hidden": true, size: "mini" });
156
+ }
157
+ function CheckIcon2() {
158
+ return /* @__PURE__ */ jsx2(Icon2, { name: "check-outline", fixedWidth: true, "aria-hidden": true });
159
+ }
160
+
161
+ // src/v3/Common/SelectStyles.tsx
162
+ var invalidStyles = css`
163
+ border-color: ${({ theme }) => theme.colors.form.border.error};
164
+
165
+ ${StyledChevron} {
166
+ color: ${({ theme }) => theme.colors.icon.error};
167
+ }
168
+ `;
169
+ var Field = styled3.div`
140
170
  display: ${({ $fullWidth }) => $fullWidth === false ? "inline-flex" : "flex"};
141
171
  flex-direction: column;
142
172
  gap: ${({ theme }) => theme.space[200]};
143
173
  ${({ $fullWidth }) => $fullWidth !== false && "width: 100%;"}
144
174
  `;
145
- var SelectLabel = styled2(Select2.Label)`
175
+ var SelectLabel = styled3(Select2.Label)`
146
176
  font-size: ${({ theme }) => theme.typography[200].fontSize};
147
177
  font-weight: ${({ theme }) => theme.fontWeights.semibold};
148
178
  color: ${({ theme }) => theme.colors.text.body};
149
179
  `;
150
- var SelectTrigger = styled2(Select2.Trigger)`
180
+ var SelectTrigger = styled3(Select2.Trigger)`
151
181
  display: flex;
152
182
  align-items: center;
153
183
  justify-content: space-between;
@@ -182,21 +212,23 @@ var SelectTrigger = styled2(Select2.Trigger)`
182
212
  opacity: 0.4;
183
213
  cursor: not-allowed;
184
214
  }
215
+
216
+ ${({ $isInvalid }) => $isInvalid && invalidStyles}
185
217
  `;
186
- var SelectValue = styled2(Select2.Value)`
218
+ var SelectValue = styled3(Select2.Value)`
187
219
  min-width: 0;
188
220
  overflow: hidden;
189
221
  `;
190
- var SelectIcon = styled2(Select2.Icon)`
222
+ var SelectIcon = styled3(Select2.Icon)`
191
223
  display: flex;
192
224
  align-items: center;
193
225
  color: ${({ theme }) => theme.colors.icon.base};
194
226
  flex-shrink: 0;
195
227
  `;
196
- var SelectGroup = styled2(Select2.Group)`
228
+ var SelectGroup = styled3(Select2.Group)`
197
229
  display: block;
198
230
  `;
199
- var SelectGroupLabel = styled2(Select2.GroupLabel)`
231
+ var SelectGroupLabel = styled3(Select2.GroupLabel)`
200
232
  padding: ${({ theme }) => `${theme.space[300]} ${theme.space[300]} ${theme.space[200]}`};
201
233
  font-size: ${({ theme }) => theme.typography[100].fontSize};
202
234
  font-weight: ${({ theme }) => theme.fontWeights.semibold};
@@ -204,23 +236,23 @@ var SelectGroupLabel = styled2(Select2.GroupLabel)`
204
236
  letter-spacing: 0.05em;
205
237
  color: ${({ theme }) => theme.colors.text.subtext};
206
238
  `;
207
- var SelectSeparator = styled2(Select2.Separator)`
239
+ var SelectSeparator = styled3(Select2.Separator)`
208
240
  height: 1px;
209
241
  margin: ${({ theme }) => `${theme.space[200]} ${theme.space[300]}`};
210
242
  background: ${({ theme }) => theme.colors.container.border.base};
211
243
  `;
212
- var SelectPositioner = styled2(Select2.Positioner)`
244
+ var SelectPositioner = styled3(Select2.Positioner)`
213
245
  width: var(--anchor-width);
214
246
  z-index: 7;
215
247
  `;
216
- var SelectPopup = styled2(Select2.Popup)`
248
+ var SelectPopup = styled3(Select2.Popup)`
217
249
  font-family: ${({ theme }) => theme.fontFamily};
218
250
  background: ${({ theme }) => theme.colors.container.background.base};
219
251
  border: 1px solid ${({ theme }) => theme.colors.container.border.base};
220
252
  border-radius: ${({ theme }) => theme.radii[500]};
221
253
  box-shadow: ${({ theme }) => theme.shadows.low};
222
254
  outline: none;
223
- max-height: min(var(--base-ui-available-height, 400px), 400px);
255
+ max-height: min(var(--available-height, 400px), 400px);
224
256
  overflow-y: auto;
225
257
  padding: ${({ theme }) => theme.space[200]};
226
258
 
@@ -255,27 +287,6 @@ var SelectPopup = styled2(Select2.Popup)`
255
287
  }
256
288
  `;
257
289
 
258
- // src/v3/Common/SelectIcons.tsx
259
- import "react";
260
- import styled3 from "styled-components";
261
- import { Icon as Icon2 } from "@sproutsocial/seeds-react-icon";
262
- import { jsx as jsx2 } from "react/jsx-runtime";
263
- var StyledChevron = styled3.div`
264
- display: flex;
265
- align-items: center;
266
- transition: transform 0.15s;
267
- ${({ $isOpen }) => $isOpen && "transform: rotate(-180deg);"}
268
- `;
269
- function ChevronIcon() {
270
- return /* @__PURE__ */ jsx2(Icon2, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true });
271
- }
272
- function ClearIcon() {
273
- return /* @__PURE__ */ jsx2(Icon2, { name: "circle-x-outline", fixedWidth: true, "aria-hidden": true, size: "mini" });
274
- }
275
- function CheckIcon2() {
276
- return /* @__PURE__ */ jsx2(Icon2, { name: "check-outline", fixedWidth: true, "aria-hidden": true });
277
- }
278
-
279
290
  // src/v3/SingleSelect.tsx
280
291
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
281
292
  var StyledValue = styled4(Select3.Value)`
@@ -292,6 +303,7 @@ var StyledValue = styled4(Select3.Value)`
292
303
  function SingleSelect(props) {
293
304
  const { id, placeholder, includePlaceholderItem, fullWidth = true } = props;
294
305
  const ariaDescribedBy = props["aria-describedby"];
306
+ const isInvalid = props.isInvalid;
295
307
  const isChildrenMode = "children" in props && props.children != null;
296
308
  const selectedItemId = props.selectedItemId;
297
309
  const defaultSelectedItemId = props.defaultSelectedItemId;
@@ -349,10 +361,19 @@ function SingleSelect(props) {
349
361
  onValueChange: handleValueChange,
350
362
  id,
351
363
  children: [
352
- /* @__PURE__ */ jsxs2(SelectTrigger, { "aria-describedby": ariaDescribedBy, children: [
353
- /* @__PURE__ */ jsx3(StyledValue, { placeholder, children: renderSelection && selectedItem ? renderSelection(selectedItem) : void 0 }),
354
- /* @__PURE__ */ jsx3(SelectIcon, { children: /* @__PURE__ */ jsx3(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx3(ChevronIcon, {}) }) })
355
- ] }),
364
+ /* @__PURE__ */ jsxs2(
365
+ SelectTrigger,
366
+ {
367
+ "aria-describedby": ariaDescribedBy,
368
+ "aria-invalid": isInvalid || void 0,
369
+ "aria-required": props.required || void 0,
370
+ $isInvalid: isInvalid,
371
+ children: [
372
+ /* @__PURE__ */ jsx3(StyledValue, { placeholder, children: renderSelection && selectedItem ? renderSelection(selectedItem) : void 0 }),
373
+ /* @__PURE__ */ jsx3(SelectIcon, { children: /* @__PURE__ */ jsx3(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx3(ChevronIcon, {}) }) })
374
+ ]
375
+ }
376
+ ),
356
377
  /* @__PURE__ */ jsx3(Select3.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx3(SelectPositioner, { sideOffset: 8, alignItemWithTrigger: false, children: /* @__PURE__ */ jsxs2(SelectPopup, { children: [
357
378
  /* @__PURE__ */ jsx3(Select3.ScrollUpArrow, {}),
358
379
  /* @__PURE__ */ jsx3(Select3.List, { children: children ? children : groupBy ? groupItems(data, groupBy).map((group, index, arr) => /* @__PURE__ */ jsxs2(React4.Fragment, { children: [
@@ -422,6 +443,7 @@ var Placeholder = styled5.div`
422
443
  function MultiSelect(props) {
423
444
  const { id, placeholder = "Select...", fullWidth = true } = props;
424
445
  const ariaDescribedBy = props["aria-describedby"];
446
+ const isInvalid = props.isInvalid;
425
447
  const isChildrenMode = "children" in props && props.children != null;
426
448
  const data = isChildrenMode ? [] : props.data;
427
449
  const itemToString = isChildrenMode ? () => "" : props.itemToString;
@@ -478,23 +500,32 @@ function MultiSelect(props) {
478
500
  disabled: props.disabled,
479
501
  id,
480
502
  children: [
481
- /* @__PURE__ */ jsxs3(SelectTrigger, { "aria-describedby": ariaDescribedBy, children: [
482
- /* @__PURE__ */ jsx4(SelectValue, { children: () => {
483
- if (renderSelection) return renderSelection(selectedItems);
484
- if (selectedItems.length === 0)
485
- return /* @__PURE__ */ jsx4(Placeholder, { children: placeholder });
486
- const visibleItems = maxSelections != null ? selectedItems.slice(0, maxSelections) : selectedItems;
487
- const overflowCount = maxSelections != null && selectedItems.length > maxSelections ? selectedItems.length - maxSelections : 0;
488
- const text = visibleItems.map(
489
- (item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
490
- ).join(", ");
491
- return /* @__PURE__ */ jsxs3(SelectionText, { children: [
492
- text,
493
- overflowCount > 0 ? `, +${overflowCount}` : ""
494
- ] });
495
- } }),
496
- /* @__PURE__ */ jsx4(SelectIcon, { children: /* @__PURE__ */ jsx4(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx4(ChevronIcon, {}) }) })
497
- ] }),
503
+ /* @__PURE__ */ jsxs3(
504
+ SelectTrigger,
505
+ {
506
+ "aria-describedby": ariaDescribedBy,
507
+ "aria-invalid": isInvalid || void 0,
508
+ "aria-required": props.required || void 0,
509
+ $isInvalid: isInvalid,
510
+ children: [
511
+ /* @__PURE__ */ jsx4(SelectValue, { children: () => {
512
+ if (renderSelection) return renderSelection(selectedItems);
513
+ if (selectedItems.length === 0)
514
+ return /* @__PURE__ */ jsx4(Placeholder, { children: placeholder });
515
+ const visibleItems = maxSelections != null ? selectedItems.slice(0, maxSelections) : selectedItems;
516
+ const overflowCount = maxSelections != null && selectedItems.length > maxSelections ? selectedItems.length - maxSelections : 0;
517
+ const text = visibleItems.map(
518
+ (item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
519
+ ).join(", ");
520
+ return /* @__PURE__ */ jsxs3(SelectionText, { children: [
521
+ text,
522
+ overflowCount > 0 ? `, +${overflowCount}` : ""
523
+ ] });
524
+ } }),
525
+ /* @__PURE__ */ jsx4(SelectIcon, { children: /* @__PURE__ */ jsx4(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx4(ChevronIcon, {}) }) })
526
+ ]
527
+ }
528
+ ),
498
529
  /* @__PURE__ */ jsx4(Select4.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx4(SelectPositioner, { sideOffset: 8, alignItemWithTrigger: false, children: /* @__PURE__ */ jsxs3(SelectPopup, { children: [
499
530
  /* @__PURE__ */ jsx4(Select4.ScrollUpArrow, {}),
500
531
  /* @__PURE__ */ jsx4(Select4.List, { children: children ? children : groupBy ? groupItems(data, groupBy).map((group, index, arr) => /* @__PURE__ */ jsxs3(React5.Fragment, { children: [
@@ -535,21 +566,41 @@ function MultiSelect(props) {
535
566
  }
536
567
 
537
568
  // src/v3/SingleCombobox.tsx
538
- import * as React8 from "react";
569
+ import * as React9 from "react";
539
570
  import { Combobox as Combobox3 } from "@base-ui/react/combobox";
540
571
  import "@tanstack/react-virtual";
541
572
 
542
- // src/v3/Common/ComboboxItem.tsx
573
+ // src/v3/Common/useSuppressEscapeClear.ts
543
574
  import * as React6 from "react";
575
+ function useSuppressEscapeClear(open) {
576
+ return React6.useCallback(
577
+ (event) => {
578
+ if (event.key === "Escape" && !open) {
579
+ event.stopPropagation();
580
+ }
581
+ },
582
+ [open]
583
+ );
584
+ }
585
+
586
+ // src/v3/Common/ComboboxItem.tsx
587
+ import * as React7 from "react";
544
588
  import Radio2 from "@sproutsocial/seeds-react-radio";
545
589
  import Checkbox3 from "@sproutsocial/seeds-react-checkbox";
546
590
 
547
591
  // src/v3/Common/ComboboxStyles.tsx
548
592
  import { Combobox } from "@base-ui/react/combobox";
549
- import styled6 from "styled-components";
593
+ import styled6, { css as css2 } from "styled-components";
550
594
  import { focusRing as focusRing2 } from "@sproutsocial/seeds-react-mixins";
551
595
  import Checkbox2 from "@sproutsocial/seeds-react-checkbox";
552
596
  import { jsx as jsx5 } from "react/jsx-runtime";
597
+ var invalidStyles2 = css2`
598
+ border-color: ${({ theme }) => theme.colors.form.border.error};
599
+
600
+ ${StyledChevron} {
601
+ color: ${({ theme }) => theme.colors.icon.error};
602
+ }
603
+ `;
553
604
  var ComboboxLabel = styled6.label`
554
605
  font-size: ${({ theme }) => theme.typography[200].fontSize};
555
606
  font-weight: ${({ theme }) => theme.fontWeights.semibold};
@@ -576,6 +627,8 @@ var ComboboxInputGroup = styled6(Combobox.InputGroup)`
576
627
  opacity: 0.4;
577
628
  cursor: not-allowed;
578
629
  }
630
+
631
+ ${({ $isInvalid }) => $isInvalid && invalidStyles2}
579
632
  `;
580
633
  var ComboboxInput = styled6(Combobox.Input)`
581
634
  flex: 1;
@@ -623,7 +676,7 @@ var ComboboxActionButtons = styled6.div`
623
676
  margin-left: auto;
624
677
  gap: ${({ theme }) => theme.space[100]};
625
678
  `;
626
- var ComboboxClear = styled6(Combobox.Clear)`
679
+ var ComboboxClear = styled6(Combobox.Clear).attrs({ tabIndex: 0 })`
627
680
  display: flex;
628
681
  align-items: center;
629
682
  justify-content: center;
@@ -640,6 +693,10 @@ var ComboboxClear = styled6(Combobox.Clear)`
640
693
  color: ${({ theme }) => theme.colors.text.body};
641
694
  }
642
695
 
696
+ &:focus-visible {
697
+ ${focusRing2}
698
+ }
699
+
643
700
  &[data-empty] {
644
701
  display: none;
645
702
  }
@@ -672,7 +729,7 @@ var ComboboxPopup = styled6(Combobox.Popup)`
672
729
  box-shadow: ${({ theme }) => theme.shadows.medium};
673
730
  outline: none;
674
731
  width: 100%;
675
- max-height: min(var(--base-ui-available-height, 400px), 400px);
732
+ max-height: min(var(--available-height, 400px), 400px);
676
733
  overflow-y: auto;
677
734
  padding: 0;
678
735
 
@@ -839,6 +896,7 @@ var ComboboxToken = styled6(Combobox.Chips)`
839
896
  display: flex;
840
897
  width: 100%;
841
898
  flex-wrap: wrap;
899
+ gap: ${({ theme }) => theme.space[200]};
842
900
  `;
843
901
  var ComboboxTokenInputGroup = styled6(Combobox.InputGroup)`
844
902
  display: flex;
@@ -863,6 +921,8 @@ var ComboboxTokenInputGroup = styled6(Combobox.InputGroup)`
863
921
  opacity: 0.4;
864
922
  cursor: not-allowed;
865
923
  }
924
+
925
+ ${({ $isInvalid }) => $isInvalid && invalidStyles2}
866
926
  `;
867
927
  var Token = styled6.span`
868
928
  display: inline-flex;
@@ -895,6 +955,10 @@ var TokenRemove = styled6.button`
895
955
  cursor: pointer;
896
956
  padding: 0;
897
957
  line-height: 1;
958
+
959
+ &:focus-visible {
960
+ ${focusRing2}
961
+ }
898
962
  `;
899
963
  var SearchableSelectTrigger = styled6(Combobox.Trigger)`
900
964
  display: flex;
@@ -928,6 +992,8 @@ var SearchableSelectTrigger = styled6(Combobox.Trigger)`
928
992
  opacity: 0.4;
929
993
  cursor: not-allowed;
930
994
  }
995
+
996
+ ${({ $isInvalid }) => $isInvalid && invalidStyles2}
931
997
  `;
932
998
  var SearchableSelectTriggerIcon = styled6(Combobox.Icon)`
933
999
  display: flex;
@@ -1010,6 +1076,8 @@ var SearchableSelectTokenTrigger = styled6(Combobox.Trigger)`
1010
1076
  opacity: 0.4;
1011
1077
  cursor: not-allowed;
1012
1078
  }
1079
+
1080
+ ${({ $isInvalid }) => $isInvalid && invalidStyles2}
1013
1081
  `;
1014
1082
 
1015
1083
  // src/v3/Common/ComboboxItem.tsx
@@ -1074,11 +1142,11 @@ function ComboboxItemInner({
1074
1142
  }
1075
1143
  );
1076
1144
  }
1077
- var ComboboxItem2 = React6.forwardRef(ComboboxItemInner);
1145
+ var ComboboxItem2 = React7.forwardRef(ComboboxItemInner);
1078
1146
  var ComboboxItem_default = ComboboxItem2;
1079
1147
 
1080
1148
  // src/v3/Common/VirtualizedComboboxList.tsx
1081
- import * as React7 from "react";
1149
+ import * as React8 from "react";
1082
1150
  import { Combobox as Combobox2 } from "@base-ui/react/combobox";
1083
1151
  import { useVirtualizer } from "@tanstack/react-virtual";
1084
1152
 
@@ -1118,7 +1186,7 @@ function VirtualizedComboboxList({
1118
1186
  renderCreatableItem
1119
1187
  }) {
1120
1188
  const filteredItems = Combobox2.useFilteredItems();
1121
- const scrollElementRef = React7.useRef(null);
1189
+ const scrollElementRef = React8.useRef(null);
1122
1190
  const virtualizer = useVirtualizer({
1123
1191
  enabled: open,
1124
1192
  count: filteredItems.length,
@@ -1130,8 +1198,8 @@ function VirtualizedComboboxList({
1130
1198
  scrollPaddingStart: 4,
1131
1199
  scrollPaddingEnd: 4
1132
1200
  });
1133
- React7.useImperativeHandle(virtualizerRef, () => virtualizer);
1134
- const handleScrollRef = React7.useCallback(
1201
+ React8.useImperativeHandle(virtualizerRef, () => virtualizer);
1202
+ const handleScrollRef = React8.useCallback(
1135
1203
  (el) => {
1136
1204
  scrollElementRef.current = el;
1137
1205
  if (el) requestAnimationFrame(() => virtualizer.measure());
@@ -1279,6 +1347,7 @@ function SingleCombobox(props) {
1279
1347
  fullWidth = true
1280
1348
  } = props;
1281
1349
  const ariaDescribedBy = props["aria-describedby"];
1350
+ const isInvalid = props.isInvalid;
1282
1351
  const isChildrenMode = "children" in props && props.children != null;
1283
1352
  const data = isChildrenMode ? [] : props.data;
1284
1353
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1292,17 +1361,18 @@ function SingleCombobox(props) {
1292
1361
  const defaultSelectedItemId = props.defaultSelectedItemId;
1293
1362
  const onSelectedItemIdChange = props.onSelectedItemIdChange;
1294
1363
  const { containerRef, portalContainer } = useSeedsPortalContainer();
1295
- const [open, setOpen] = React8.useState(false);
1296
- const virtualizerRef = React8.useRef(null);
1364
+ const [open, setOpen] = React9.useState(false);
1365
+ const virtualizerRef = React9.useRef(null);
1366
+ const onInputKeyDownCapture = useSuppressEscapeClear(open);
1297
1367
  const isControlled = selectedItemId !== void 0;
1298
- const idToItem = React8.useCallback(
1368
+ const idToItem = React9.useCallback(
1299
1369
  (id2) => {
1300
1370
  if (id2 == null) return null;
1301
1371
  return data.find((d) => String(d.id) === String(id2)) ?? null;
1302
1372
  },
1303
1373
  [data]
1304
1374
  );
1305
- const [internalValue, setInternalValue] = React8.useState(
1375
+ const [internalValue, setInternalValue] = React9.useState(
1306
1376
  () => idToItem(defaultSelectedItemId)
1307
1377
  );
1308
1378
  const value = isControlled ? idToItem(selectedItemId) : internalValue;
@@ -1314,7 +1384,7 @@ function SingleCombobox(props) {
1314
1384
  onSelectedItemIdChange(newItem ? newItem.id : null);
1315
1385
  }
1316
1386
  }
1317
- const groups = React8.useMemo(
1387
+ const groups = React9.useMemo(
1318
1388
  () => groupBy ? groupItems(data, groupBy) : null,
1319
1389
  [data, groupBy]
1320
1390
  );
@@ -1339,29 +1409,38 @@ function SingleCombobox(props) {
1339
1409
  if (!item || !virt) return;
1340
1410
  const isStart = index === 0;
1341
1411
  const isEnd = index === virt.options.count - 1;
1342
- if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
1412
+ if (reason === "keyboard" && (isStart || isEnd)) {
1343
1413
  queueMicrotask(() => {
1344
1414
  virt.scrollToIndex(index, {
1345
- align: isEnd ? "start" : "end"
1415
+ align: isStart ? "start" : "end"
1346
1416
  });
1347
1417
  });
1348
1418
  }
1349
1419
  } : void 0,
1350
1420
  children: [
1351
- /* @__PURE__ */ jsxs6(ComboboxInputGroup, { children: [
1352
- /* @__PURE__ */ jsx8(
1353
- ComboboxInput,
1354
- {
1355
- placeholder,
1356
- id,
1357
- "aria-describedby": ariaDescribedBy
1358
- }
1359
- ),
1360
- /* @__PURE__ */ jsxs6(ComboboxActionButtons, { children: [
1361
- /* @__PURE__ */ jsx8(ComboboxClear, { "aria-label": "Clear selection", children: /* @__PURE__ */ jsx8(ClearIcon, {}) }),
1362
- /* @__PURE__ */ jsx8(ComboboxTrigger, { "aria-label": "Open popup", children: /* @__PURE__ */ jsx8(StyledChevron, { $isOpen: open, children: /* @__PURE__ */ jsx8(ChevronIcon, {}) }) })
1363
- ] })
1364
- ] }),
1421
+ /* @__PURE__ */ jsxs6(
1422
+ ComboboxInputGroup,
1423
+ {
1424
+ $isInvalid: isInvalid,
1425
+ onKeyDownCapture: onInputKeyDownCapture,
1426
+ children: [
1427
+ /* @__PURE__ */ jsx8(
1428
+ ComboboxInput,
1429
+ {
1430
+ placeholder,
1431
+ id,
1432
+ "aria-describedby": ariaDescribedBy,
1433
+ "aria-invalid": isInvalid || void 0,
1434
+ "aria-required": props.required || void 0
1435
+ }
1436
+ ),
1437
+ /* @__PURE__ */ jsxs6(ComboboxActionButtons, { children: [
1438
+ /* @__PURE__ */ jsx8(ComboboxClear, { "aria-label": "Clear selection", children: /* @__PURE__ */ jsx8(ClearIcon, {}) }),
1439
+ /* @__PURE__ */ jsx8(ComboboxTrigger, { "aria-label": "Open popup", children: /* @__PURE__ */ jsx8(StyledChevron, { $isOpen: open, children: /* @__PURE__ */ jsx8(ChevronIcon, {}) }) })
1440
+ ] })
1441
+ ]
1442
+ }
1443
+ ),
1365
1444
  /* @__PURE__ */ jsx8(Combobox3.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx8(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ jsxs6(
1366
1445
  ComboboxPopup,
1367
1446
  {
@@ -1391,7 +1470,7 @@ function SingleCombobox(props) {
1391
1470
  renderItem,
1392
1471
  renderGroupHeading
1393
1472
  }
1394
- ) : children ? children : groups ? (group, index) => /* @__PURE__ */ jsxs6(React8.Fragment, { children: [
1473
+ ) : children ? children : groups ? ((group, index) => /* @__PURE__ */ jsxs6(React9.Fragment, { children: [
1395
1474
  /* @__PURE__ */ jsxs6(ComboboxGroup, { items: group.items, children: [
1396
1475
  /* @__PURE__ */ jsx8(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
1397
1476
  /* @__PURE__ */ jsx8(Combobox3.Collection, { children: (item) => /* @__PURE__ */ jsx8(
@@ -1408,7 +1487,7 @@ function SingleCombobox(props) {
1408
1487
  ) })
1409
1488
  ] }),
1410
1489
  index < groups.length - 1 && /* @__PURE__ */ jsx8(ComboboxSeparator, {})
1411
- ] }, group.value) : (item) => /* @__PURE__ */ jsx8(
1490
+ ] }, group.value)) : ((item) => /* @__PURE__ */ jsx8(
1412
1491
  ComboboxItem_default,
1413
1492
  {
1414
1493
  value: item,
@@ -1419,7 +1498,7 @@ function SingleCombobox(props) {
1419
1498
  renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1420
1499
  },
1421
1500
  item.id
1422
- )
1501
+ ))
1423
1502
  }
1424
1503
  )
1425
1504
  ]
@@ -1432,7 +1511,7 @@ function SingleCombobox(props) {
1432
1511
  }
1433
1512
 
1434
1513
  // src/v3/MultiCombobox.tsx
1435
- import * as React9 from "react";
1514
+ import * as React10 from "react";
1436
1515
  import { Combobox as Combobox4 } from "@base-ui/react/combobox";
1437
1516
  import "@tanstack/react-virtual";
1438
1517
  import Icon3 from "@sproutsocial/seeds-react-icon";
@@ -1460,6 +1539,7 @@ function MultiCombobox(props) {
1460
1539
  fullWidth = true
1461
1540
  } = props;
1462
1541
  const ariaDescribedBy = props["aria-describedby"];
1542
+ const isInvalid = props.isInvalid;
1463
1543
  const isChildrenMode = "children" in props && props.children != null;
1464
1544
  const data = isChildrenMode ? [] : props.data;
1465
1545
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1483,29 +1563,31 @@ function MultiCombobox(props) {
1483
1563
  const defaultSelectedItemIds = props.defaultSelectedItemIds;
1484
1564
  const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
1485
1565
  const { containerRef, portalContainer } = useSeedsPortalContainer();
1486
- const [open, setOpen] = React9.useState(false);
1487
- const [internalInputValue, setInternalInputValue] = React9.useState("");
1488
- const skipNextInputChangeRef = React9.useRef(false);
1489
- const virtualizerRef = React9.useRef(null);
1566
+ const [open, setOpen] = React10.useState(false);
1567
+ const [internalInputValue, setInternalInputValue] = React10.useState("");
1568
+ const skipNextInputChangeRef = React10.useRef(false);
1569
+ const virtualizerRef = React10.useRef(null);
1570
+ const inputRef = React10.useRef(null);
1571
+ const onInputKeyDownCapture = useSuppressEscapeClear(open);
1490
1572
  const isControlled = selectedItemIds !== void 0;
1491
- const idsToItems = React9.useCallback(
1573
+ const idsToItems = React10.useCallback(
1492
1574
  (ids) => ids.map((id2) => data.find((d) => d.id === id2)).filter((d) => d != null),
1493
1575
  [data]
1494
1576
  );
1495
- const [internalValue, setInternalValue] = React9.useState(
1577
+ const [internalValue, setInternalValue] = React10.useState(
1496
1578
  () => defaultSelectedItemIds ? idsToItems(defaultSelectedItemIds) : []
1497
1579
  );
1498
1580
  const value = isControlled ? idsToItems(selectedItemIds) : internalValue;
1499
- const visibleData = React9.useMemo(
1581
+ const visibleData = React10.useMemo(
1500
1582
  () => removeSelectedItems ? data.filter((item) => !value.some((v) => v.id === item.id)) : data,
1501
1583
  [data, value, removeSelectedItems]
1502
1584
  );
1503
- const groups = React9.useMemo(
1585
+ const groups = React10.useMemo(
1504
1586
  () => groupBy ? groupItems(visibleData, groupBy) : null,
1505
1587
  [visibleData, groupBy]
1506
1588
  );
1507
1589
  const currentInputValue = inputValue ?? internalInputValue;
1508
- const creatableSentinel = React9.useMemo(() => {
1590
+ const creatableSentinel = React10.useMemo(() => {
1509
1591
  if (!creatableProp) return null;
1510
1592
  const trimmed = currentInputValue.trim();
1511
1593
  if (!trimmed) return null;
@@ -1516,7 +1598,7 @@ function MultiCombobox(props) {
1516
1598
  if (exactExists) return null;
1517
1599
  return makeCreatableSentinel(trimmed);
1518
1600
  }, [creatableProp, currentInputValue, data, itemToString]);
1519
- const flatItems = React9.useMemo(() => {
1601
+ const flatItems = React10.useMemo(() => {
1520
1602
  if (!selectHeadings && !selectAll) return null;
1521
1603
  if (!groups && !selectAll) return null;
1522
1604
  const rows = [];
@@ -1602,6 +1684,7 @@ function MultiCombobox(props) {
1602
1684
  e.preventDefault();
1603
1685
  e.stopPropagation();
1604
1686
  setSelectedItems(value.filter((v) => v.id !== item.id));
1687
+ inputRef.current?.focus();
1605
1688
  }
1606
1689
  function renderSentinelRow(row) {
1607
1690
  if (isSelectAllSentinel2(row)) {
@@ -1683,7 +1766,10 @@ function MultiCombobox(props) {
1683
1766
  open,
1684
1767
  disabled: props.disabled,
1685
1768
  onOpenChange: (nextOpen, eventDetails) => {
1686
- if (!nextOpen && eventDetails.reason === "item-press") return;
1769
+ if (!nextOpen && eventDetails.reason === "item-press") {
1770
+ eventDetails.cancel();
1771
+ return;
1772
+ }
1687
1773
  setOpen(nextOpen);
1688
1774
  },
1689
1775
  filter: creatableProp ? (item, query) => {
@@ -1716,10 +1802,10 @@ function MultiCombobox(props) {
1716
1802
  if (!item || !virt) return;
1717
1803
  const isStart = index === 0;
1718
1804
  const isEnd = index === virt.options.count - 1;
1719
- if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
1805
+ if (reason === "keyboard" && (isStart || isEnd)) {
1720
1806
  queueMicrotask(() => {
1721
1807
  virt.scrollToIndex(index, {
1722
- align: isEnd ? "start" : "end"
1808
+ align: isStart ? "start" : "end"
1723
1809
  });
1724
1810
  });
1725
1811
  }
@@ -1746,42 +1832,52 @@ function MultiCombobox(props) {
1746
1832
  },
1747
1833
  items: rootItems,
1748
1834
  children: [
1749
- /* @__PURE__ */ jsx9(ComboboxTokenInputGroup, { children: /* @__PURE__ */ jsxs7(ComboboxToken, { children: [
1750
- renderSelection ? renderSelection(value) : (() => {
1751
- const visibleTokens = maxTokens != null ? value.slice(0, maxTokens) : value;
1752
- const overflow = maxTokens != null ? value.length - maxTokens : 0;
1753
- return /* @__PURE__ */ jsxs7(Fragment6, { children: [
1754
- visibleTokens.map((item) => /* @__PURE__ */ jsxs7(Token, { children: [
1755
- renderToken ? renderToken(item) : itemToString(item),
1756
- /* @__PURE__ */ jsx9(
1757
- TokenRemove,
1758
- {
1759
- "aria-label": `Remove ${itemToString(item)}`,
1760
- onPointerDown: (e) => e.preventDefault(),
1761
- onClick: (e) => removeItem(item, e),
1762
- children: /* @__PURE__ */ jsx9(Icon3, { name: "x-outline", size: "mini" })
1763
- }
1764
- )
1765
- ] }, item.id)),
1766
- overflow > 0 && /* @__PURE__ */ jsxs7(Token, { children: [
1767
- "+",
1768
- overflow
1769
- ] }, "__overflow")
1770
- ] });
1771
- })(),
1772
- /* @__PURE__ */ jsx9(
1773
- ComboboxTokenInput,
1774
- {
1775
- id,
1776
- placeholder: value.length > 0 ? "" : placeholder,
1777
- "aria-describedby": ariaDescribedBy
1778
- }
1779
- ),
1780
- /* @__PURE__ */ jsxs7(ComboboxActionButtons, { children: [
1781
- /* @__PURE__ */ jsx9(ComboboxClear, { "aria-label": "Clear all", children: /* @__PURE__ */ jsx9(ClearIcon, {}) }),
1782
- /* @__PURE__ */ jsx9(ComboboxTrigger, { "aria-label": "Open popup", children: /* @__PURE__ */ jsx9(StyledChevron, { $isOpen: open, children: /* @__PURE__ */ jsx9(ChevronIcon, {}) }) })
1783
- ] })
1784
- ] }) }),
1835
+ /* @__PURE__ */ jsx9(
1836
+ ComboboxTokenInputGroup,
1837
+ {
1838
+ $isInvalid: isInvalid,
1839
+ onKeyDownCapture: onInputKeyDownCapture,
1840
+ children: /* @__PURE__ */ jsxs7(ComboboxToken, { children: [
1841
+ renderSelection ? renderSelection(value) : (() => {
1842
+ const visibleTokens = maxTokens != null ? value.slice(0, maxTokens) : value;
1843
+ const overflow = maxTokens != null ? value.length - maxTokens : 0;
1844
+ return /* @__PURE__ */ jsxs7(Fragment6, { children: [
1845
+ visibleTokens.map((item) => /* @__PURE__ */ jsxs7(Token, { children: [
1846
+ renderToken ? renderToken(item) : itemToString(item),
1847
+ /* @__PURE__ */ jsx9(
1848
+ TokenRemove,
1849
+ {
1850
+ "aria-label": `Remove ${itemToString(item)}`,
1851
+ onPointerDown: (e) => e.preventDefault(),
1852
+ onClick: (e) => removeItem(item, e),
1853
+ children: /* @__PURE__ */ jsx9(Icon3, { name: "x-outline", size: "mini" })
1854
+ }
1855
+ )
1856
+ ] }, item.id)),
1857
+ overflow > 0 && /* @__PURE__ */ jsxs7(Token, { children: [
1858
+ "+",
1859
+ overflow
1860
+ ] }, "__overflow")
1861
+ ] });
1862
+ })(),
1863
+ /* @__PURE__ */ jsx9(
1864
+ ComboboxTokenInput,
1865
+ {
1866
+ ref: inputRef,
1867
+ id,
1868
+ placeholder: value.length > 0 ? "" : placeholder,
1869
+ "aria-describedby": ariaDescribedBy,
1870
+ "aria-invalid": isInvalid || void 0,
1871
+ "aria-required": props.required || void 0
1872
+ }
1873
+ ),
1874
+ /* @__PURE__ */ jsxs7(ComboboxActionButtons, { children: [
1875
+ /* @__PURE__ */ jsx9(ComboboxClear, { "aria-label": "Clear all", children: /* @__PURE__ */ jsx9(ClearIcon, {}) }),
1876
+ /* @__PURE__ */ jsx9(ComboboxTrigger, { "aria-label": "Open popup", children: /* @__PURE__ */ jsx9(StyledChevron, { $isOpen: open, children: /* @__PURE__ */ jsx9(ChevronIcon, {}) }) })
1877
+ ] })
1878
+ ] })
1879
+ }
1880
+ ),
1785
1881
  /* @__PURE__ */ jsx9(Combobox4.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx9(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ jsxs7(
1786
1882
  ComboboxPopup,
1787
1883
  {
@@ -1819,12 +1915,12 @@ function MultiCombobox(props) {
1819
1915
  measureRef
1820
1916
  ) : void 0
1821
1917
  }
1822
- ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => {
1918
+ ) : children ? children : flatItems ? ((row) => renderSentinelRow(row)) : groups ? ((group, index) => {
1823
1919
  if (isCreatableSentinel(group)) {
1824
1920
  return renderCreatableItem(group);
1825
1921
  }
1826
1922
  const g = group;
1827
- return /* @__PURE__ */ jsxs7(React9.Fragment, { children: [
1923
+ return /* @__PURE__ */ jsxs7(React10.Fragment, { children: [
1828
1924
  /* @__PURE__ */ jsxs7(ComboboxGroup, { items: g.items, children: [
1829
1925
  /* @__PURE__ */ jsx9(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(g.value) : g.value }),
1830
1926
  /* @__PURE__ */ jsx9(Combobox4.Collection, { children: (item) => /* @__PURE__ */ jsx9(
@@ -1842,7 +1938,7 @@ function MultiCombobox(props) {
1842
1938
  ] }),
1843
1939
  index < groups.length - 1 && /* @__PURE__ */ jsx9(ComboboxSeparator, {})
1844
1940
  ] }, g.value);
1845
- } : (item) => {
1941
+ }) : ((item) => {
1846
1942
  if (isCreatableSentinel(item)) {
1847
1943
  return renderCreatableItem(item);
1848
1944
  }
@@ -1859,7 +1955,7 @@ function MultiCombobox(props) {
1859
1955
  },
1860
1956
  dataItem.id
1861
1957
  );
1862
- }
1958
+ })
1863
1959
  }
1864
1960
  )
1865
1961
  ]
@@ -1872,7 +1968,7 @@ function MultiCombobox(props) {
1872
1968
  }
1873
1969
 
1874
1970
  // src/v3/SingleSearchableSelect.tsx
1875
- import * as React10 from "react";
1971
+ import * as React11 from "react";
1876
1972
  import { Combobox as Combobox5 } from "@base-ui/react/combobox";
1877
1973
  import "@tanstack/react-virtual";
1878
1974
  import { Fragment as Fragment8, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
@@ -1889,6 +1985,7 @@ function SingleSearchableSelect(props) {
1889
1985
  fullWidth = true
1890
1986
  } = props;
1891
1987
  const ariaDescribedBy = props["aria-describedby"];
1988
+ const isInvalid = props.isInvalid;
1892
1989
  const isChildrenMode = "children" in props && props.children != null;
1893
1990
  const data = isChildrenMode ? [] : props.data;
1894
1991
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1903,17 +2000,17 @@ function SingleSearchableSelect(props) {
1903
2000
  const defaultSelectedItemId = props.defaultSelectedItemId;
1904
2001
  const onSelectedItemIdChange = props.onSelectedItemIdChange;
1905
2002
  const { containerRef, portalContainer } = useSeedsPortalContainer();
1906
- const [open, setOpen] = React10.useState(false);
1907
- const virtualizerRef = React10.useRef(null);
2003
+ const [open, setOpen] = React11.useState(false);
2004
+ const virtualizerRef = React11.useRef(null);
1908
2005
  const isControlled = selectedItemId !== void 0;
1909
- const idToItem = React10.useCallback(
2006
+ const idToItem = React11.useCallback(
1910
2007
  (id2) => {
1911
2008
  if (id2 == null) return null;
1912
2009
  return data.find((d) => String(d.id) === String(id2)) ?? null;
1913
2010
  },
1914
2011
  [data]
1915
2012
  );
1916
- const [internalValue, setInternalValue] = React10.useState(
2013
+ const [internalValue, setInternalValue] = React11.useState(
1917
2014
  () => idToItem(defaultSelectedItemId)
1918
2015
  );
1919
2016
  const value = isControlled ? idToItem(selectedItemId) : internalValue;
@@ -1924,7 +2021,7 @@ function SingleSearchableSelect(props) {
1924
2021
  onSelectedItemIdChange(realItem ? realItem.id : null);
1925
2022
  }
1926
2023
  }
1927
- const groups = React10.useMemo(
2024
+ const groups = React11.useMemo(
1928
2025
  () => groupBy ? groupItems(data, groupBy) : null,
1929
2026
  [data, groupBy]
1930
2027
  );
@@ -1954,19 +2051,29 @@ function SingleSearchableSelect(props) {
1954
2051
  if (!item || !virt) return;
1955
2052
  const isStart = index === 0;
1956
2053
  const isEnd = index === virt.options.count - 1;
1957
- if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
2054
+ if (reason === "keyboard" && (isStart || isEnd)) {
1958
2055
  queueMicrotask(() => {
1959
2056
  virt.scrollToIndex(index, {
1960
- align: isEnd ? "start" : "end"
2057
+ align: isStart ? "start" : "end"
1961
2058
  });
1962
2059
  });
1963
2060
  }
1964
2061
  } : void 0,
1965
2062
  children: [
1966
- /* @__PURE__ */ jsxs8(SearchableSelectTrigger, { id, "aria-describedby": ariaDescribedBy, children: [
1967
- /* @__PURE__ */ jsx10(SearchableSelectPlaceholder, { children: /* @__PURE__ */ jsx10(Combobox5.Value, { placeholder, children: value ? renderSelection ? renderSelection(value) : itemToString(value) : placeholder }) }),
1968
- /* @__PURE__ */ jsx10(SearchableSelectTriggerIcon, { children: /* @__PURE__ */ jsx10(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx10(ChevronIcon, {}) }) })
1969
- ] }),
2063
+ /* @__PURE__ */ jsxs8(
2064
+ SearchableSelectTrigger,
2065
+ {
2066
+ id,
2067
+ "aria-describedby": ariaDescribedBy,
2068
+ "aria-invalid": isInvalid || void 0,
2069
+ "aria-required": props.required || void 0,
2070
+ $isInvalid: isInvalid,
2071
+ children: [
2072
+ /* @__PURE__ */ jsx10(SearchableSelectPlaceholder, { children: /* @__PURE__ */ jsx10(Combobox5.Value, { placeholder, children: value ? renderSelection ? renderSelection(value) : itemToString(value) : placeholder }) }),
2073
+ /* @__PURE__ */ jsx10(SearchableSelectTriggerIcon, { children: /* @__PURE__ */ jsx10(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx10(ChevronIcon, {}) }) })
2074
+ ]
2075
+ }
2076
+ ),
1970
2077
  /* @__PURE__ */ jsx10(Combobox5.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx10(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ jsxs8(
1971
2078
  SearchableSelectPopup,
1972
2079
  {
@@ -2004,7 +2111,7 @@ function SingleSearchableSelect(props) {
2004
2111
  inputType,
2005
2112
  renderItem
2006
2113
  }
2007
- ) : children ? children : groups ? (group, index) => /* @__PURE__ */ jsxs8(React10.Fragment, { children: [
2114
+ ) : children ? children : groups ? ((group, index) => /* @__PURE__ */ jsxs8(React11.Fragment, { children: [
2008
2115
  /* @__PURE__ */ jsxs8(ComboboxGroup, { items: group.items, children: [
2009
2116
  /* @__PURE__ */ jsx10(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
2010
2117
  /* @__PURE__ */ jsx10(Combobox5.Collection, { children: (item) => /* @__PURE__ */ jsx10(
@@ -2021,7 +2128,7 @@ function SingleSearchableSelect(props) {
2021
2128
  ) })
2022
2129
  ] }),
2023
2130
  index < groups.length - 1 && /* @__PURE__ */ jsx10(ComboboxSeparator, {})
2024
- ] }, group.value) : /* @__PURE__ */ jsxs8(Fragment8, { children: [
2131
+ ] }, group.value)) : /* @__PURE__ */ jsxs8(Fragment8, { children: [
2025
2132
  includePlaceholderItem && /* @__PURE__ */ jsx10(
2026
2133
  ComboboxItem_default,
2027
2134
  {
@@ -2057,7 +2164,7 @@ function SingleSearchableSelect(props) {
2057
2164
  }
2058
2165
 
2059
2166
  // src/v3/MultiSearchableSelect.tsx
2060
- import * as React11 from "react";
2167
+ import * as React12 from "react";
2061
2168
  import { Combobox as Combobox6 } from "@base-ui/react/combobox";
2062
2169
  import "@tanstack/react-virtual";
2063
2170
  import Icon4 from "@sproutsocial/seeds-react-icon";
@@ -2091,6 +2198,7 @@ function MultiSearchableSelect(props) {
2091
2198
  fullWidth = true
2092
2199
  } = props;
2093
2200
  const ariaDescribedBy = props["aria-describedby"];
2201
+ const isInvalid = props.isInvalid;
2094
2202
  const isChildrenMode = "children" in props && props.children != null;
2095
2203
  const data = isChildrenMode ? [] : props.data;
2096
2204
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -2112,29 +2220,29 @@ function MultiSearchableSelect(props) {
2112
2220
  const defaultSelectedItemIds = props.defaultSelectedItemIds;
2113
2221
  const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
2114
2222
  const { containerRef, portalContainer } = useSeedsPortalContainer();
2115
- const [open, setOpen] = React11.useState(false);
2116
- const [internalInputValue, setInternalInputValue] = React11.useState("");
2117
- const skipNextInputChangeRef = React11.useRef(false);
2118
- const virtualizerRef = React11.useRef(null);
2223
+ const [open, setOpen] = React12.useState(false);
2224
+ const [internalInputValue, setInternalInputValue] = React12.useState("");
2225
+ const skipNextInputChangeRef = React12.useRef(false);
2226
+ const virtualizerRef = React12.useRef(null);
2119
2227
  const isControlled = selectedItemIds !== void 0;
2120
- const idsToItems = React11.useCallback(
2228
+ const idsToItems = React12.useCallback(
2121
2229
  (ids) => ids.map((id2) => data.find((d) => d.id === id2)).filter((d) => d != null),
2122
2230
  [data]
2123
2231
  );
2124
- const [internalValue, setInternalValue] = React11.useState(
2232
+ const [internalValue, setInternalValue] = React12.useState(
2125
2233
  () => defaultSelectedItemIds ? idsToItems(defaultSelectedItemIds) : []
2126
2234
  );
2127
2235
  const value = isControlled ? idsToItems(selectedItemIds) : internalValue;
2128
- const visibleData = React11.useMemo(
2236
+ const visibleData = React12.useMemo(
2129
2237
  () => removeSelectedItems ? data.filter((item) => !value.some((v) => v.id === item.id)) : data,
2130
2238
  [data, value, removeSelectedItems]
2131
2239
  );
2132
- const groups = React11.useMemo(
2240
+ const groups = React12.useMemo(
2133
2241
  () => groupBy ? groupItems(visibleData, groupBy) : null,
2134
2242
  [visibleData, groupBy]
2135
2243
  );
2136
2244
  const currentInputValue = internalInputValue;
2137
- const creatableSentinel = React11.useMemo(() => {
2245
+ const creatableSentinel = React12.useMemo(() => {
2138
2246
  if (!creatableProp) return null;
2139
2247
  const trimmed = currentInputValue.trim();
2140
2248
  if (!trimmed) return null;
@@ -2145,7 +2253,7 @@ function MultiSearchableSelect(props) {
2145
2253
  if (exactExists) return null;
2146
2254
  return makeCreatableSentinel(trimmed);
2147
2255
  }, [creatableProp, currentInputValue, data, itemToString]);
2148
- const flatItems = React11.useMemo(() => {
2256
+ const flatItems = React12.useMemo(() => {
2149
2257
  if (!groups || !selectHeadings && !selectAll) return null;
2150
2258
  const rows = [];
2151
2259
  if (selectAll) rows.push(SELECT_ALL_SENTINEL2);
@@ -2322,10 +2430,10 @@ function MultiSearchableSelect(props) {
2322
2430
  if (!item || !virt) return;
2323
2431
  const isStart = index === 0;
2324
2432
  const isEnd = index === virt.options.count - 1;
2325
- if (reason === "none" || reason === "keyboard" && (isStart || isEnd)) {
2433
+ if (reason === "keyboard" && (isStart || isEnd)) {
2326
2434
  queueMicrotask(() => {
2327
2435
  virt.scrollToIndex(index, {
2328
- align: isEnd ? "start" : "end"
2436
+ align: isStart ? "start" : "end"
2329
2437
  });
2330
2438
  });
2331
2439
  }
@@ -2357,6 +2465,9 @@ function MultiSearchableSelect(props) {
2357
2465
  {
2358
2466
  id,
2359
2467
  "aria-describedby": ariaDescribedBy,
2468
+ "aria-invalid": isInvalid || void 0,
2469
+ "aria-required": props.required || void 0,
2470
+ $isInvalid: isInvalid,
2360
2471
  children: [
2361
2472
  renderSelection ? renderSelection(value) : value.length > 0 ? (() => {
2362
2473
  const visibleItems = maxSelections != null ? value.slice(0, maxSelections) : value;
@@ -2417,12 +2528,12 @@ function MultiSearchableSelect(props) {
2417
2528
  measureRef
2418
2529
  ) : void 0
2419
2530
  }
2420
- ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => {
2531
+ ) : children ? children : flatItems ? ((row) => renderSentinelRow(row)) : groups ? ((group, index) => {
2421
2532
  if (isCreatableSentinel(group)) {
2422
2533
  return renderCreatableItem(group);
2423
2534
  }
2424
2535
  const g = group;
2425
- return /* @__PURE__ */ jsxs9(React11.Fragment, { children: [
2536
+ return /* @__PURE__ */ jsxs9(React12.Fragment, { children: [
2426
2537
  /* @__PURE__ */ jsxs9(ComboboxGroup, { items: g.items, children: [
2427
2538
  /* @__PURE__ */ jsx11(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(g.value) : g.value }),
2428
2539
  /* @__PURE__ */ jsx11(Combobox6.Collection, { children: (item) => /* @__PURE__ */ jsx11(
@@ -2440,7 +2551,7 @@ function MultiSearchableSelect(props) {
2440
2551
  ] }),
2441
2552
  index < groups.length - 1 && /* @__PURE__ */ jsx11(ComboboxSeparator, {})
2442
2553
  ] }, g.value);
2443
- } : (item) => {
2554
+ }) : ((item) => {
2444
2555
  if (isCreatableSentinel(item)) {
2445
2556
  return renderCreatableItem(item);
2446
2557
  }
@@ -2457,7 +2568,7 @@ function MultiSearchableSelect(props) {
2457
2568
  },
2458
2569
  dataItem.id
2459
2570
  );
2460
- }
2571
+ })
2461
2572
  }
2462
2573
  )
2463
2574
  ]
@@ -2470,7 +2581,7 @@ function MultiSearchableSelect(props) {
2470
2581
  }
2471
2582
 
2472
2583
  // src/v3/ActionMenu.tsx
2473
- import * as React12 from "react";
2584
+ import * as React13 from "react";
2474
2585
  import { Menu as Menu2 } from "@base-ui/react/menu";
2475
2586
  import Radio3 from "@sproutsocial/seeds-react-radio";
2476
2587
  import Checkbox4 from "@sproutsocial/seeds-react-checkbox";
@@ -2478,23 +2589,25 @@ import { Icon as Icon5 } from "@sproutsocial/seeds-react-icon";
2478
2589
 
2479
2590
  // src/v3/ActionMenuStyles.tsx
2480
2591
  import { Menu } from "@base-ui/react/menu";
2481
- import styled8, { css } from "styled-components";
2592
+ import styled8, { css as css3 } from "styled-components";
2482
2593
  import "@sproutsocial/seeds-react-mixins";
2483
2594
  var ActionMenuTrigger = styled8(Menu.Trigger)``;
2484
2595
  var ActionMenuPositioner = styled8(Menu.Positioner)`
2485
2596
  min-width: var(--anchor-width);
2486
2597
  z-index: 7;
2487
2598
  `;
2488
- var ActionMenuPopup = styled8(Menu.Popup)`
2599
+ var ActionMenuPopup = styled8(Menu.Popup).attrs({
2600
+ "data-base-ui-swipe-ignore": ""
2601
+ })`
2489
2602
  font-family: ${({ theme }) => theme.fontFamily};
2490
2603
  background: ${({ theme }) => theme.colors.container.background.base};
2491
2604
  border: 1px solid ${({ theme }) => theme.colors.container.border.base};
2492
2605
  border-radius: ${({ theme }) => theme.radii[500]};
2493
2606
  box-shadow: ${({ theme }) => theme.shadows.low};
2494
2607
  outline: none;
2495
- max-height: min(var(--base-ui-available-height, 400px), 400px);
2608
+ max-height: min(var(--available-height, 400px), 400px);
2496
2609
  overflow-y: auto;
2497
- padding: ${({ theme }) => theme.space[200]};
2610
+ padding: ${({ theme }) => theme.space[300]};
2498
2611
 
2499
2612
  &[data-open] {
2500
2613
  animation: action-menu-popup-in 120ms ease-out;
@@ -2530,19 +2643,16 @@ var ActionMenuGroup = styled8(Menu.Group)`
2530
2643
  display: block;
2531
2644
  `;
2532
2645
  var ActionMenuGroupLabel = styled8(Menu.GroupLabel)`
2533
- padding: ${({ theme }) => `${theme.space[300]} ${theme.space[300]} ${theme.space[200]}`};
2646
+ padding: ${({ theme }) => `${theme.space[300]}`};
2534
2647
  font-size: ${({ theme }) => theme.typography[100].fontSize};
2535
- font-weight: ${({ theme }) => theme.fontWeights.semibold};
2536
- text-transform: uppercase;
2537
- letter-spacing: 0.05em;
2538
- color: ${({ theme }) => theme.colors.text.subtext};
2648
+ color: ${({ theme }) => theme.colors.text.body};
2539
2649
  `;
2540
2650
  var ActionMenuSeparator = styled8(Menu.Separator)`
2541
2651
  height: 1px;
2542
- margin: ${({ theme }) => `${theme.space[200]} ${theme.space[300]}`};
2652
+ margin: ${({ theme }) => `${theme.space[300]} -${theme.space[300]}`};
2543
2653
  background: ${({ theme }) => theme.colors.container.border.base};
2544
2654
  `;
2545
- var menuItemStyles = css`
2655
+ var menuItemStyles = css3`
2546
2656
  box-sizing: border-box;
2547
2657
  display: block;
2548
2658
  width: 100%;
@@ -2671,7 +2781,7 @@ function MenuRadioGroup({
2671
2781
  );
2672
2782
  }
2673
2783
  function MenuItem(props) {
2674
- const generatedId = React12.useId();
2784
+ const generatedId = React13.useId();
2675
2785
  if (props.type === "checkbox") {
2676
2786
  const {
2677
2787
  children: children2,
@@ -2812,6 +2922,81 @@ function MenuSubTrigger({
2812
2922
  }
2813
2923
  );
2814
2924
  }
2925
+
2926
+ // src/v3/MenuButton.tsx
2927
+ import "react";
2928
+ import "@sproutsocial/seeds-react-button";
2929
+ import { Icon as Icon6 } from "@sproutsocial/seeds-react-icon";
2930
+
2931
+ // src/v3/MenuButtonStyles.tsx
2932
+ import styled9 from "styled-components";
2933
+ import { Button } from "@sproutsocial/seeds-react-button";
2934
+ var MenuButtonContainer = styled9.div`
2935
+ display: inline-flex;
2936
+ gap: 1px;
2937
+ `;
2938
+ var MainButton = styled9(Button)`
2939
+ && {
2940
+ border-top-right-radius: 0;
2941
+ border-bottom-right-radius: 0;
2942
+ }
2943
+ `;
2944
+ var TriggerButton = styled9(Button)`
2945
+ && {
2946
+ border-top-left-radius: 0;
2947
+ border-bottom-left-radius: 0;
2948
+ }
2949
+
2950
+ .Icon-svg {
2951
+ transition: transform ${({ theme }) => theme.duration.fast} ease;
2952
+ }
2953
+
2954
+ &[data-popup-open] .Icon-svg {
2955
+ transform: rotate(180deg);
2956
+ }
2957
+ `;
2958
+
2959
+ // src/v3/MenuButton.tsx
2960
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
2961
+ function MenuButton({
2962
+ actionMenu,
2963
+ appearance = "primary",
2964
+ size,
2965
+ disabled,
2966
+ menuButtonAriaLabel,
2967
+ children,
2968
+ ...rest
2969
+ }) {
2970
+ return /* @__PURE__ */ jsxs11(MenuButtonContainer, { children: [
2971
+ /* @__PURE__ */ jsx13(
2972
+ MainButton,
2973
+ {
2974
+ appearance,
2975
+ size,
2976
+ disabled,
2977
+ ...rest,
2978
+ children
2979
+ }
2980
+ ),
2981
+ /* @__PURE__ */ jsx13(
2982
+ ActionMenu,
2983
+ {
2984
+ disabled,
2985
+ trigger: /* @__PURE__ */ jsx13(
2986
+ TriggerButton,
2987
+ {
2988
+ appearance,
2989
+ size,
2990
+ disabled,
2991
+ ariaLabel: menuButtonAriaLabel,
2992
+ children: /* @__PURE__ */ jsx13(Icon6, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true })
2993
+ }
2994
+ ),
2995
+ children: actionMenu
2996
+ }
2997
+ )
2998
+ ] });
2999
+ }
2815
3000
  export {
2816
3001
  ActionMenu,
2817
3002
  ComboboxActionButtons,
@@ -2836,6 +3021,7 @@ export {
2836
3021
  ComboboxTokenInput,
2837
3022
  ComboboxTokenInputGroup,
2838
3023
  ComboboxTrigger,
3024
+ MenuButton,
2839
3025
  MenuGroup,
2840
3026
  MenuItem,
2841
3027
  MenuRadioGroup,