@sproutsocial/seeds-react-menu 1.12.0 → 1.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,6 +13,7 @@ interface SingleSelectBaseProps {
13
13
  placeholder?: string;
14
14
  includePlaceholderItem?: boolean;
15
15
  disabled?: boolean;
16
+ "aria-describedby"?: string;
16
17
  }
17
18
  interface SingleSelectDataProps<T extends DataWithId> extends SingleSelectBaseProps {
18
19
  data: T[];
@@ -47,6 +48,7 @@ interface MultiSelectBaseProps {
47
48
  id?: string;
48
49
  placeholder?: string;
49
50
  disabled?: boolean;
51
+ "aria-describedby"?: string;
50
52
  }
51
53
  interface MultiSelectDataProps<T extends DataWithId> extends MultiSelectBaseProps {
52
54
  data: T[];
@@ -89,6 +91,7 @@ interface SingleComboboxBaseProps {
89
91
  emptyText?: string;
90
92
  disabled?: boolean;
91
93
  filter?: ((item: unknown, query: string) => boolean) | null;
94
+ "aria-describedby"?: string;
92
95
  }
93
96
  interface SingleComboboxDataBaseProps<T extends DataWithId> extends SingleComboboxBaseProps {
94
97
  data: T[];
@@ -134,6 +137,9 @@ interface MultiComboboxBaseProps {
134
137
  loadingText?: string;
135
138
  disabled?: boolean;
136
139
  filter?: ((item: unknown, query: string) => boolean) | null;
140
+ inputValue?: string;
141
+ onInputValueChange?: (value: string) => void;
142
+ "aria-describedby"?: string;
137
143
  }
138
144
  interface MultiComboboxDataProps<T extends DataWithId> extends MultiComboboxBaseProps {
139
145
  data: T[];
@@ -148,10 +154,12 @@ interface MultiComboboxDataProps<T extends DataWithId> extends MultiComboboxBase
148
154
  groupBy?: (item: T) => string;
149
155
  renderGroupHeading?: (label: string) => react.ReactNode;
150
156
  selectHeadings?: boolean;
151
- selectAll?: boolean;
157
+ selectAll?: boolean | string;
152
158
  isVirtualized?: boolean;
153
159
  removeSelectedItems?: boolean;
154
160
  maxTokens?: number;
161
+ creatable?: boolean;
162
+ onCreate?: (value: string) => T;
155
163
  children?: never;
156
164
  }
157
165
  interface MultiComboboxChildrenProps extends MultiComboboxBaseProps {
@@ -170,6 +178,8 @@ interface MultiComboboxChildrenProps extends MultiComboboxBaseProps {
170
178
  selectHeadings?: never;
171
179
  selectAll?: never;
172
180
  removeSelectedItems?: never;
181
+ creatable?: never;
182
+ onCreate?: never;
173
183
  }
174
184
  type MultiComboboxProps<T extends DataWithId> = MultiComboboxDataProps<T> | MultiComboboxChildrenProps;
175
185
  declare function MultiCombobox<T extends DataWithId>(props: MultiComboboxProps<T>): react_jsx_runtime.JSX.Element;
@@ -184,6 +194,7 @@ interface SingleSearchableSelectBaseProps {
184
194
  loadingText?: string;
185
195
  disabled?: boolean;
186
196
  filter?: ((item: unknown, query: string) => boolean) | null;
197
+ "aria-describedby"?: string;
187
198
  }
188
199
  interface SingleSearchableSelectDataBaseProps<T extends DataWithId> extends SingleSearchableSelectBaseProps {
189
200
  data: T[];
@@ -232,6 +243,7 @@ interface MultiSearchableSelectBaseProps {
232
243
  loadingText?: string;
233
244
  disabled?: boolean;
234
245
  filter?: ((item: unknown, query: string) => boolean) | null;
246
+ "aria-describedby"?: string;
235
247
  }
236
248
  interface MultiSearchableSelectDataProps<T extends DataWithId> extends MultiSearchableSelectBaseProps {
237
249
  data: T[];
@@ -13,6 +13,7 @@ interface SingleSelectBaseProps {
13
13
  placeholder?: string;
14
14
  includePlaceholderItem?: boolean;
15
15
  disabled?: boolean;
16
+ "aria-describedby"?: string;
16
17
  }
17
18
  interface SingleSelectDataProps<T extends DataWithId> extends SingleSelectBaseProps {
18
19
  data: T[];
@@ -47,6 +48,7 @@ interface MultiSelectBaseProps {
47
48
  id?: string;
48
49
  placeholder?: string;
49
50
  disabled?: boolean;
51
+ "aria-describedby"?: string;
50
52
  }
51
53
  interface MultiSelectDataProps<T extends DataWithId> extends MultiSelectBaseProps {
52
54
  data: T[];
@@ -89,6 +91,7 @@ interface SingleComboboxBaseProps {
89
91
  emptyText?: string;
90
92
  disabled?: boolean;
91
93
  filter?: ((item: unknown, query: string) => boolean) | null;
94
+ "aria-describedby"?: string;
92
95
  }
93
96
  interface SingleComboboxDataBaseProps<T extends DataWithId> extends SingleComboboxBaseProps {
94
97
  data: T[];
@@ -134,6 +137,9 @@ interface MultiComboboxBaseProps {
134
137
  loadingText?: string;
135
138
  disabled?: boolean;
136
139
  filter?: ((item: unknown, query: string) => boolean) | null;
140
+ inputValue?: string;
141
+ onInputValueChange?: (value: string) => void;
142
+ "aria-describedby"?: string;
137
143
  }
138
144
  interface MultiComboboxDataProps<T extends DataWithId> extends MultiComboboxBaseProps {
139
145
  data: T[];
@@ -148,10 +154,12 @@ interface MultiComboboxDataProps<T extends DataWithId> extends MultiComboboxBase
148
154
  groupBy?: (item: T) => string;
149
155
  renderGroupHeading?: (label: string) => react.ReactNode;
150
156
  selectHeadings?: boolean;
151
- selectAll?: boolean;
157
+ selectAll?: boolean | string;
152
158
  isVirtualized?: boolean;
153
159
  removeSelectedItems?: boolean;
154
160
  maxTokens?: number;
161
+ creatable?: boolean;
162
+ onCreate?: (value: string) => T;
155
163
  children?: never;
156
164
  }
157
165
  interface MultiComboboxChildrenProps extends MultiComboboxBaseProps {
@@ -170,6 +178,8 @@ interface MultiComboboxChildrenProps extends MultiComboboxBaseProps {
170
178
  selectHeadings?: never;
171
179
  selectAll?: never;
172
180
  removeSelectedItems?: never;
181
+ creatable?: never;
182
+ onCreate?: never;
173
183
  }
174
184
  type MultiComboboxProps<T extends DataWithId> = MultiComboboxDataProps<T> | MultiComboboxChildrenProps;
175
185
  declare function MultiCombobox<T extends DataWithId>(props: MultiComboboxProps<T>): react_jsx_runtime.JSX.Element;
@@ -184,6 +194,7 @@ interface SingleSearchableSelectBaseProps {
184
194
  loadingText?: string;
185
195
  disabled?: boolean;
186
196
  filter?: ((item: unknown, query: string) => boolean) | null;
197
+ "aria-describedby"?: string;
187
198
  }
188
199
  interface SingleSearchableSelectDataBaseProps<T extends DataWithId> extends SingleSearchableSelectBaseProps {
189
200
  data: T[];
@@ -232,6 +243,7 @@ interface MultiSearchableSelectBaseProps {
232
243
  loadingText?: string;
233
244
  disabled?: boolean;
234
245
  filter?: ((item: unknown, query: string) => boolean) | null;
246
+ "aria-describedby"?: string;
235
247
  }
236
248
  interface MultiSearchableSelectDataProps<T extends DataWithId> extends MultiSearchableSelectBaseProps {
237
249
  data: T[];
package/dist/v3/index.js CHANGED
@@ -364,6 +364,7 @@ var StyledValue = (0, import_styled_components4.default)(import_select3.Select.V
364
364
  `;
365
365
  function SingleSelect(props) {
366
366
  const { id, placeholder, includePlaceholderItem } = props;
367
+ const ariaDescribedBy = props["aria-describedby"];
367
368
  const isChildrenMode = "children" in props && props.children != null;
368
369
  const selectedItemId = props.selectedItemId;
369
370
  const defaultSelectedItemId = props.defaultSelectedItemId;
@@ -421,7 +422,7 @@ function SingleSelect(props) {
421
422
  onValueChange: handleValueChange,
422
423
  id,
423
424
  children: [
424
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(SelectTrigger, { children: [
425
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(SelectTrigger, { "aria-describedby": ariaDescribedBy, children: [
425
426
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledValue, { placeholder, children: renderSelection && selectedItem ? renderSelection(selectedItem) : void 0 }),
426
427
  /* @__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, {}) }) })
427
428
  ] }),
@@ -493,6 +494,7 @@ var Placeholder = import_styled_components5.default.div`
493
494
  `;
494
495
  function MultiSelect(props) {
495
496
  const { id, placeholder = "Select..." } = props;
497
+ const ariaDescribedBy = props["aria-describedby"];
496
498
  const isChildrenMode = "children" in props && props.children != null;
497
499
  const data = isChildrenMode ? [] : props.data;
498
500
  const itemToString = isChildrenMode ? () => "" : props.itemToString;
@@ -549,7 +551,7 @@ function MultiSelect(props) {
549
551
  disabled: props.disabled,
550
552
  id,
551
553
  children: [
552
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectTrigger, { children: [
554
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(SelectTrigger, { "aria-describedby": ariaDescribedBy, children: [
553
555
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SelectValue, { children: () => {
554
556
  if (renderSelection) return renderSelection(selectedItems);
555
557
  if (selectedItems.length === 0)
@@ -1160,6 +1162,12 @@ function makePlaceholderSentinel(label) {
1160
1162
  function isPlaceholderSentinel(v) {
1161
1163
  return typeof v === "object" && v !== null && "__placeholder" in v;
1162
1164
  }
1165
+ function makeCreatableSentinel(label) {
1166
+ return { __creatable: true, label };
1167
+ }
1168
+ function isCreatableSentinel(v) {
1169
+ return typeof v === "object" && v !== null && "__creatable" in v;
1170
+ }
1163
1171
 
1164
1172
  // src/v3/Common/VirtualizedComboboxList.tsx
1165
1173
  var import_jsx_runtime7 = require("react/jsx-runtime");
@@ -1179,7 +1187,8 @@ function VirtualizedComboboxList({
1179
1187
  itemToString,
1180
1188
  inputType,
1181
1189
  renderItem,
1182
- renderGroupHeading
1190
+ renderGroupHeading,
1191
+ renderCreatableItem
1183
1192
  }) {
1184
1193
  const filteredItems = import_combobox2.Combobox.useFilteredItems();
1185
1194
  const scrollElementRef = React7.useRef(null);
@@ -1297,6 +1306,17 @@ function VirtualizedComboboxList({
1297
1306
  virtualItem.key
1298
1307
  );
1299
1308
  }
1309
+ if (isCreatableSentinel(row)) {
1310
+ if (renderCreatableItem) {
1311
+ return renderCreatableItem(
1312
+ row,
1313
+ baseStyle,
1314
+ virtualItem.index,
1315
+ virtualizer.measureElement
1316
+ );
1317
+ }
1318
+ return null;
1319
+ }
1300
1320
  const item = row;
1301
1321
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1302
1322
  ComboboxItem_default,
@@ -1330,6 +1350,7 @@ function SingleCombobox(props) {
1330
1350
  emptyText = "No results found.",
1331
1351
  filter
1332
1352
  } = props;
1353
+ const ariaDescribedBy = props["aria-describedby"];
1333
1354
  const isChildrenMode = "children" in props && props.children != null;
1334
1355
  const data = isChildrenMode ? [] : props.data;
1335
1356
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1400,7 +1421,14 @@ function SingleCombobox(props) {
1400
1421
  } : void 0,
1401
1422
  children: [
1402
1423
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxInputGroup, { children: [
1403
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxInput, { placeholder, id }),
1424
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1425
+ ComboboxInput,
1426
+ {
1427
+ placeholder,
1428
+ id,
1429
+ "aria-describedby": ariaDescribedBy
1430
+ }
1431
+ ),
1404
1432
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ComboboxActionButtons, { children: [
1405
1433
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ComboboxClear, { "aria-label": "Clear selection", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ClearIcon, {}) }),
1406
1434
  /* @__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, {}) }) })
@@ -1498,8 +1526,11 @@ function MultiCombobox(props) {
1498
1526
  emptyText = "No results found.",
1499
1527
  isLoading = false,
1500
1528
  loadingText = "Loading...",
1501
- filter
1529
+ filter,
1530
+ inputValue,
1531
+ onInputValueChange
1502
1532
  } = props;
1533
+ const ariaDescribedBy = props["aria-describedby"];
1503
1534
  const isChildrenMode = "children" in props && props.children != null;
1504
1535
  const data = isChildrenMode ? [] : props.data;
1505
1536
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1512,14 +1543,20 @@ function MultiCombobox(props) {
1512
1543
  const groupBy = isChildrenMode ? void 0 : props.groupBy;
1513
1544
  const renderGroupHeading = isChildrenMode ? void 0 : props.renderGroupHeading;
1514
1545
  const selectHeadings = isChildrenMode ? false : props.selectHeadings ?? false;
1515
- const selectAll = isChildrenMode ? false : props.selectAll ?? false;
1546
+ const selectAllProp = isChildrenMode ? false : props.selectAll ?? false;
1547
+ const selectAll = Boolean(selectAllProp);
1548
+ const selectAllLabel = typeof selectAllProp === "string" ? selectAllProp : "Select all";
1516
1549
  const isVirtualized = isChildrenMode ? false : props.isVirtualized ?? false;
1550
+ const creatableProp = isChildrenMode ? false : props.creatable ?? false;
1551
+ const onCreateProp = isChildrenMode ? void 0 : props.onCreate;
1517
1552
  const children = isChildrenMode ? props.children : void 0;
1518
1553
  const selectedItemIds = props.selectedItemIds;
1519
1554
  const defaultSelectedItemIds = props.defaultSelectedItemIds;
1520
1555
  const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
1521
1556
  const { containerRef, portalContainer } = useSeedsPortalContainer();
1522
1557
  const [open, setOpen] = React9.useState(false);
1558
+ const [internalInputValue, setInternalInputValue] = React9.useState("");
1559
+ const skipNextInputChangeRef = React9.useRef(false);
1523
1560
  const virtualizerRef = React9.useRef(null);
1524
1561
  const isControlled = selectedItemIds !== void 0;
1525
1562
  const idsToItems = React9.useCallback(
@@ -1538,22 +1575,51 @@ function MultiCombobox(props) {
1538
1575
  () => groupBy ? groupItems(visibleData, groupBy) : null,
1539
1576
  [visibleData, groupBy]
1540
1577
  );
1578
+ const currentInputValue = inputValue ?? internalInputValue;
1579
+ const creatableSentinel = React9.useMemo(() => {
1580
+ if (!creatableProp) return null;
1581
+ const trimmed = currentInputValue.trim();
1582
+ if (!trimmed) return null;
1583
+ const lowered = trimmed.toLocaleLowerCase();
1584
+ const exactExists = data.some(
1585
+ (d) => itemToString(d).trim().toLocaleLowerCase() === lowered
1586
+ );
1587
+ if (exactExists) return null;
1588
+ return makeCreatableSentinel(trimmed);
1589
+ }, [creatableProp, currentInputValue, data, itemToString]);
1541
1590
  const flatItems = React9.useMemo(() => {
1542
- if (!groups || !selectHeadings && !selectAll) return null;
1591
+ if (!selectHeadings && !selectAll) return null;
1592
+ if (!groups && !selectAll) return null;
1543
1593
  const rows = [];
1544
1594
  if (selectAll) rows.push(SELECT_ALL_SENTINEL);
1545
- for (const group of groups) {
1546
- rows.push(makeGroupHeaderSentinel(group.value));
1547
- rows.push(...group.items);
1595
+ if (groups) {
1596
+ for (const group of groups) {
1597
+ rows.push(makeGroupHeaderSentinel(group.value));
1598
+ rows.push(...group.items);
1599
+ }
1600
+ } else {
1601
+ rows.push(...visibleData);
1548
1602
  }
1549
1603
  return rows;
1550
- }, [groups, selectHeadings, selectAll]);
1604
+ }, [groups, visibleData, selectHeadings, selectAll]);
1551
1605
  function setSelectedItems(items) {
1552
1606
  if (!isControlled) setInternalValue(items);
1553
1607
  if (onSelectedItemIdsChange)
1554
1608
  onSelectedItemIdsChange(items.map((item) => item.id));
1555
1609
  }
1556
1610
  function handleValueChange(next) {
1611
+ const creatableClicked = next.find(isCreatableSentinel);
1612
+ if (creatableClicked) {
1613
+ const newItem = onCreateProp?.(creatableClicked.label);
1614
+ const realItems2 = next.filter(
1615
+ (v) => !isGroupHeaderSentinel2(v) && !isSelectAllSentinel2(v) && !isCreatableSentinel(v)
1616
+ );
1617
+ setSelectedItems(newItem ? [...realItems2, newItem] : realItems2);
1618
+ skipNextInputChangeRef.current = true;
1619
+ setInternalInputValue("");
1620
+ onInputValueChange?.("");
1621
+ return;
1622
+ }
1557
1623
  const selectAllClicked = next.filter(isSelectAllSentinel2);
1558
1624
  const groupSentinels = next.filter(isGroupHeaderSentinel2);
1559
1625
  const realItems = next.filter(
@@ -1591,6 +1657,16 @@ function MultiCombobox(props) {
1591
1657
  setSelectedItems(updated);
1592
1658
  }
1593
1659
  function handleSimpleValueChange(newItems) {
1660
+ const creatableClicked = newItems.find(isCreatableSentinel);
1661
+ if (creatableClicked) {
1662
+ const newItem = onCreateProp?.(creatableClicked.label);
1663
+ const realItems = newItems.filter((v) => !isCreatableSentinel(v));
1664
+ setSelectedItems(newItem ? [...realItems, newItem] : realItems);
1665
+ skipNextInputChangeRef.current = true;
1666
+ setInternalInputValue("");
1667
+ onInputValueChange?.("");
1668
+ return;
1669
+ }
1594
1670
  setSelectedItems(newItems);
1595
1671
  }
1596
1672
  function removeItem(item, e) {
@@ -1605,7 +1681,7 @@ function MultiCombobox(props) {
1605
1681
  const state = selectedCount === 0 ? "none" : selectedCount === totalCount ? "all" : "partial";
1606
1682
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxSelectAllItem, { value: row, children: [
1607
1683
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxGroupHeaderCheckbox, { $state: state, id: "__selectAll" }),
1608
- "Select all"
1684
+ selectAllLabel
1609
1685
  ] }, "__selectAll");
1610
1686
  }
1611
1687
  if (isGroupHeaderSentinel2(row)) {
@@ -1626,6 +1702,9 @@ function MultiCombobox(props) {
1626
1702
  renderGroupHeading ? renderGroupHeading(row.groupName) : row.groupName
1627
1703
  ] }, `__header-${row.groupName}`);
1628
1704
  }
1705
+ if (isCreatableSentinel(row)) {
1706
+ return renderCreatableItem(row);
1707
+ }
1629
1708
  const item = row;
1630
1709
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1631
1710
  ComboboxItem_default,
@@ -1640,7 +1719,28 @@ function MultiCombobox(props) {
1640
1719
  item.id
1641
1720
  );
1642
1721
  }
1643
- const rootItems = flatItems ?? groups ?? (isChildrenMode ? void 0 : visibleData);
1722
+ function renderCreatableItem(sentinel, style, index, measureRef) {
1723
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1724
+ ComboboxItem_default,
1725
+ {
1726
+ value: sentinel,
1727
+ itemId: "__creatable",
1728
+ label: `Create "${sentinel.label}"`,
1729
+ inputType: "none",
1730
+ renderItem: () => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1731
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_seeds_react_icon3.default, { name: "plus-outline", size: "mini" }),
1732
+ `Create "${sentinel.label}"`
1733
+ ] }),
1734
+ style,
1735
+ index,
1736
+ "data-index": index,
1737
+ ref: measureRef
1738
+ },
1739
+ "__creatable"
1740
+ );
1741
+ }
1742
+ const baseItems = flatItems ?? groups ?? (isChildrenMode ? void 0 : visibleData);
1743
+ const rootItems = creatableSentinel && Array.isArray(baseItems) ? [...baseItems, creatableSentinel] : baseItems;
1644
1744
  const hasSentinels = selectAll || selectHeadings;
1645
1745
  const rootValue = hasSentinels ? [...value] : value;
1646
1746
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Field, { children: [
@@ -1653,8 +1753,27 @@ function MultiCombobox(props) {
1653
1753
  virtualized: isVirtualized,
1654
1754
  open,
1655
1755
  disabled: props.disabled,
1656
- onOpenChange: setOpen,
1657
- filter,
1756
+ onOpenChange: (nextOpen, eventDetails) => {
1757
+ if (!nextOpen && eventDetails.reason === "item-press") return;
1758
+ setOpen(nextOpen);
1759
+ },
1760
+ filter: creatableProp ? (item, query) => {
1761
+ if (isCreatableSentinel(item)) return true;
1762
+ if (filter) return filter(item, query);
1763
+ if (isGroupHeaderSentinel2(item) || isSelectAllSentinel2(item))
1764
+ return true;
1765
+ const label = itemToString(item);
1766
+ return label.toLowerCase().includes(query.toLowerCase());
1767
+ } : filter,
1768
+ inputValue: creatableProp ? currentInputValue : inputValue,
1769
+ onInputValueChange: creatableProp ? (v) => {
1770
+ if (skipNextInputChangeRef.current) {
1771
+ skipNextInputChangeRef.current = false;
1772
+ return;
1773
+ }
1774
+ setInternalInputValue(v);
1775
+ onInputValueChange?.(v);
1776
+ } : onInputValueChange,
1658
1777
  onItemHighlighted: isVirtualized ? (item, { reason, index }) => {
1659
1778
  const virt = virtualizerRef.current;
1660
1779
  if (!item || !virt) return;
@@ -1674,15 +1793,17 @@ function MultiCombobox(props) {
1674
1793
  hasSentinels ? handleValueChange : handleSimpleValueChange
1675
1794
  ),
1676
1795
  itemToStringLabel: (item) => {
1677
- if (!item || isGroupHeaderSentinel2(item) || isSelectAllSentinel2(item))
1796
+ if (!item || isGroupHeaderSentinel2(item) || isSelectAllSentinel2(item) || isCreatableSentinel(item))
1678
1797
  return "";
1679
1798
  return itemToString(item);
1680
1799
  },
1681
1800
  isItemEqualToValue: (a, b) => {
1801
+ if (isCreatableSentinel(a) && isCreatableSentinel(b))
1802
+ return a.label === b.label;
1682
1803
  if (isGroupHeaderSentinel2(a) && isGroupHeaderSentinel2(b))
1683
1804
  return a.groupName === b.groupName;
1684
1805
  if (isSelectAllSentinel2(a) && isSelectAllSentinel2(b)) return true;
1685
- if (!isGroupHeaderSentinel2(a) && !isSelectAllSentinel2(a) && !isGroupHeaderSentinel2(b) && !isSelectAllSentinel2(b))
1806
+ if (!isGroupHeaderSentinel2(a) && !isSelectAllSentinel2(a) && !isCreatableSentinel(a) && !isGroupHeaderSentinel2(b) && !isSelectAllSentinel2(b) && !isCreatableSentinel(b))
1686
1807
  return a.id === b.id;
1687
1808
  return false;
1688
1809
  },
@@ -1715,7 +1836,8 @@ function MultiCombobox(props) {
1715
1836
  ComboboxTokenInput,
1716
1837
  {
1717
1838
  id,
1718
- placeholder: value.length > 0 ? "" : placeholder
1839
+ placeholder: value.length > 0 ? "" : placeholder,
1840
+ "aria-describedby": ariaDescribedBy
1719
1841
  }
1720
1842
  ),
1721
1843
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxActionButtons, { children: [
@@ -1752,37 +1874,55 @@ function MultiCombobox(props) {
1752
1874
  itemToString,
1753
1875
  inputType,
1754
1876
  renderItem,
1755
- renderGroupHeading
1877
+ renderGroupHeading,
1878
+ renderCreatableItem: creatableProp ? (sentinel, style, index, measureRef) => renderCreatableItem(
1879
+ sentinel,
1880
+ style,
1881
+ index,
1882
+ measureRef
1883
+ ) : void 0
1756
1884
  }
1757
- ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(React9.Fragment, { children: [
1758
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxGroup, { items: group.items, children: [
1759
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
1760
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_combobox4.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1761
- ComboboxItem_default,
1762
- {
1763
- value: item,
1764
- itemId: String(item.id),
1765
- label: itemToString(item),
1766
- disabled: item.disabled,
1767
- inputType,
1768
- renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1769
- },
1770
- item.id
1771
- ) })
1772
- ] }),
1773
- index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxSeparator, {})
1774
- ] }, group.value) : (item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1775
- ComboboxItem_default,
1776
- {
1777
- value: item,
1778
- itemId: String(item.id),
1779
- label: itemToString(item),
1780
- disabled: item.disabled,
1781
- inputType,
1782
- renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1783
- },
1784
- item.id
1785
- )
1885
+ ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => {
1886
+ if (isCreatableSentinel(group)) {
1887
+ return renderCreatableItem(group);
1888
+ }
1889
+ const g = group;
1890
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(React9.Fragment, { children: [
1891
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ComboboxGroup, { items: g.items, children: [
1892
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(g.value) : g.value }),
1893
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_combobox4.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1894
+ ComboboxItem_default,
1895
+ {
1896
+ value: item,
1897
+ itemId: String(item.id),
1898
+ label: itemToString(item),
1899
+ disabled: item.disabled,
1900
+ inputType,
1901
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
1902
+ },
1903
+ item.id
1904
+ ) })
1905
+ ] }),
1906
+ index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComboboxSeparator, {})
1907
+ ] }, g.value);
1908
+ } : (item) => {
1909
+ if (isCreatableSentinel(item)) {
1910
+ return renderCreatableItem(item);
1911
+ }
1912
+ const dataItem = item;
1913
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1914
+ ComboboxItem_default,
1915
+ {
1916
+ value: dataItem,
1917
+ itemId: String(dataItem.id),
1918
+ label: itemToString(dataItem),
1919
+ disabled: dataItem.disabled,
1920
+ inputType,
1921
+ renderItem: renderItem ? () => renderItem(dataItem) : () => itemToString(dataItem)
1922
+ },
1923
+ dataItem.id
1924
+ );
1925
+ }
1786
1926
  }
1787
1927
  )
1788
1928
  ]
@@ -1810,6 +1950,7 @@ function SingleSearchableSelect(props) {
1810
1950
  loadingText = "Loading...",
1811
1951
  filter
1812
1952
  } = props;
1953
+ const ariaDescribedBy = props["aria-describedby"];
1813
1954
  const isChildrenMode = "children" in props && props.children != null;
1814
1955
  const data = isChildrenMode ? [] : props.data;
1815
1956
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -1884,7 +2025,7 @@ function SingleSearchableSelect(props) {
1884
2025
  }
1885
2026
  } : void 0,
1886
2027
  children: [
1887
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SearchableSelectTrigger, { id, children: [
2028
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SearchableSelectTrigger, { id, "aria-describedby": ariaDescribedBy, children: [
1888
2029
  /* @__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 }) }),
1889
2030
  /* @__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, {}) }) })
1890
2031
  ] }),
@@ -2009,6 +2150,7 @@ function MultiSearchableSelect(props) {
2009
2150
  loadingText = "Loading...",
2010
2151
  filter
2011
2152
  } = props;
2153
+ const ariaDescribedBy = props["aria-describedby"];
2012
2154
  const isChildrenMode = "children" in props && props.children != null;
2013
2155
  const data = isChildrenMode ? [] : props.data;
2014
2156
  const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
@@ -2192,20 +2334,27 @@ function MultiSearchableSelect(props) {
2192
2334
  },
2193
2335
  items: rootItems,
2194
2336
  children: [
2195
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SearchableSelectTokenTrigger, { id, children: [
2196
- renderSelection ? renderSelection(value) : value.length > 0 ? (() => {
2197
- const visibleItems = maxSelections != null ? value.slice(0, maxSelections) : value;
2198
- const overflowCount = maxSelections != null && value.length > maxSelections ? value.length - maxSelections : 0;
2199
- const text = visibleItems.map(
2200
- (item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
2201
- ).join(", ");
2202
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SelectionText2, { children: [
2203
- text,
2204
- overflowCount > 0 ? `, +${overflowCount}` : ""
2205
- ] });
2206
- })() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SearchableSelectPlaceholder, { children: placeholder }),
2207
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SearchableSelectTriggerIcon, { style: { marginLeft: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChevronIcon, {}) }) })
2208
- ] }),
2337
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2338
+ SearchableSelectTokenTrigger,
2339
+ {
2340
+ id,
2341
+ "aria-describedby": ariaDescribedBy,
2342
+ children: [
2343
+ renderSelection ? renderSelection(value) : value.length > 0 ? (() => {
2344
+ const visibleItems = maxSelections != null ? value.slice(0, maxSelections) : value;
2345
+ const overflowCount = maxSelections != null && value.length > maxSelections ? value.length - maxSelections : 0;
2346
+ const text = visibleItems.map(
2347
+ (item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
2348
+ ).join(", ");
2349
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SelectionText2, { children: [
2350
+ text,
2351
+ overflowCount > 0 ? `, +${overflowCount}` : ""
2352
+ ] });
2353
+ })() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SearchableSelectPlaceholder, { children: placeholder }),
2354
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SearchableSelectTriggerIcon, { style: { marginLeft: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChevronIcon, {}) }) })
2355
+ ]
2356
+ }
2357
+ ),
2209
2358
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_combobox6.Combobox.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2210
2359
  SearchableSelectPopup,
2211
2360
  {