@sproutsocial/seeds-react-menu 1.12.2 → 1.13.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
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/v3/index.ts
31
31
  var v3_exports = {};
32
32
  __export(v3_exports, {
33
+ ActionMenu: () => ActionMenu,
33
34
  ComboboxActionButtons: () => ComboboxActionButtons,
34
35
  ComboboxClear: () => ComboboxClear,
35
36
  ComboboxEmpty: () => ComboboxEmpty,
@@ -52,6 +53,11 @@ __export(v3_exports, {
52
53
  ComboboxTokenInput: () => ComboboxTokenInput,
53
54
  ComboboxTokenInputGroup: () => ComboboxTokenInputGroup,
54
55
  ComboboxTrigger: () => ComboboxTrigger,
56
+ MenuGroup: () => MenuGroup,
57
+ MenuItem: () => MenuItem,
58
+ MenuRadioGroup: () => MenuRadioGroup,
59
+ MenuSub: () => MenuSub,
60
+ MenuSubTrigger: () => MenuSubTrigger,
55
61
  MultiCombobox: () => MultiCombobox,
56
62
  MultiSearchableSelect: () => MultiSearchableSelect,
57
63
  MultiSelect: () => MultiSelect,
@@ -210,10 +216,10 @@ var import_select2 = require("@base-ui/react/select");
210
216
  var import_styled_components2 = __toESM(require("styled-components"));
211
217
  var import_seeds_react_mixins = require("@sproutsocial/seeds-react-mixins");
212
218
  var Field = import_styled_components2.default.div`
213
- display: flex;
219
+ display: ${({ $fullWidth }) => $fullWidth === false ? "inline-flex" : "flex"};
214
220
  flex-direction: column;
215
221
  gap: ${({ theme }) => theme.space[200]};
216
- width: 100%;
222
+ ${({ $fullWidth }) => $fullWidth !== false && "width: 100%;"}
217
223
  `;
218
224
  var SelectLabel = (0, import_styled_components2.default)(import_select2.Select.Label)`
219
225
  font-size: ${({ theme }) => theme.typography[200].fontSize};
@@ -363,7 +369,7 @@ var StyledValue = (0, import_styled_components4.default)(import_select3.Select.V
363
369
  }
364
370
  `;
365
371
  function SingleSelect(props) {
366
- const { id, placeholder, includePlaceholderItem } = props;
372
+ const { id, placeholder, includePlaceholderItem, fullWidth = true } = props;
367
373
  const ariaDescribedBy = props["aria-describedby"];
368
374
  const isChildrenMode = "children" in props && props.children != null;
369
375
  const selectedItemId = props.selectedItemId;
@@ -411,7 +417,7 @@ function SingleSelect(props) {
411
417
  }
412
418
  }
413
419
  }
414
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Field, { children: [
420
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Field, { $fullWidth: fullWidth, children: [
415
421
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
416
422
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
417
423
  import_select3.Select.Root,
@@ -493,7 +499,7 @@ var Placeholder = import_styled_components5.default.div`
493
499
  margin: 2px 8px 0px 0px;
494
500
  `;
495
501
  function MultiSelect(props) {
496
- const { id, placeholder = "Select..." } = props;
502
+ const { id, placeholder = "Select...", fullWidth = true } = props;
497
503
  const ariaDescribedBy = props["aria-describedby"];
498
504
  const isChildrenMode = "children" in props && props.children != null;
499
505
  const data = isChildrenMode ? [] : props.data;
@@ -539,7 +545,7 @@ function MultiSelect(props) {
539
545
  onSelectedItemIdsChange(ids);
540
546
  }
541
547
  }
542
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Field, { children: [
548
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Field, { $fullWidth: fullWidth, children: [
543
549
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
544
550
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
545
551
  import_select4.Select.Root,
@@ -1348,7 +1354,8 @@ function SingleCombobox(props) {
1348
1354
  id,
1349
1355
  placeholder = "Search...",
1350
1356
  emptyText = "No results found.",
1351
- filter
1357
+ filter,
1358
+ fullWidth = true
1352
1359
  } = props;
1353
1360
  const ariaDescribedBy = props["aria-describedby"];
1354
1361
  const isChildrenMode = "children" in props && props.children != null;
@@ -1390,7 +1397,7 @@ function SingleCombobox(props) {
1390
1397
  () => groupBy ? groupItems(data, groupBy) : null,
1391
1398
  [data, groupBy]
1392
1399
  );
1393
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Field, { children: [
1400
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Field, { $fullWidth: fullWidth, children: [
1394
1401
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
1395
1402
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1396
1403
  import_combobox3.Combobox.Root,
@@ -1528,7 +1535,8 @@ function MultiCombobox(props) {
1528
1535
  loadingText = "Loading...",
1529
1536
  filter,
1530
1537
  inputValue,
1531
- onInputValueChange
1538
+ onInputValueChange,
1539
+ fullWidth = true
1532
1540
  } = props;
1533
1541
  const ariaDescribedBy = props["aria-describedby"];
1534
1542
  const isChildrenMode = "children" in props && props.children != null;
@@ -1743,7 +1751,7 @@ function MultiCombobox(props) {
1743
1751
  const rootItems = creatableSentinel && Array.isArray(baseItems) ? [...baseItems, creatableSentinel] : baseItems;
1744
1752
  const hasSentinels = selectAll || selectHeadings;
1745
1753
  const rootValue = hasSentinels ? [...value] : value;
1746
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Field, { children: [
1754
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Field, { $fullWidth: fullWidth, children: [
1747
1755
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
1748
1756
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1749
1757
  import_combobox4.Combobox.Root,
@@ -1765,15 +1773,23 @@ function MultiCombobox(props) {
1765
1773
  const label = itemToString(item);
1766
1774
  return label.toLowerCase().includes(query.toLowerCase());
1767
1775
  } : filter,
1768
- inputValue: creatableProp ? currentInputValue : inputValue,
1769
- onInputValueChange: creatableProp ? (v) => {
1770
- if (skipNextInputChangeRef.current) {
1771
- skipNextInputChangeRef.current = false;
1772
- return;
1776
+ inputValue: creatableProp ? currentInputValue : inputValue ?? internalInputValue,
1777
+ onInputValueChange: (v, eventDetails) => {
1778
+ if (eventDetails.reason === "input-clear" && open) return;
1779
+ if (creatableProp) {
1780
+ if (skipNextInputChangeRef.current) {
1781
+ skipNextInputChangeRef.current = false;
1782
+ return;
1783
+ }
1784
+ setInternalInputValue(v);
1785
+ onInputValueChange?.(v);
1786
+ } else {
1787
+ if (inputValue === void 0) {
1788
+ setInternalInputValue(v);
1789
+ }
1790
+ onInputValueChange?.(v);
1773
1791
  }
1774
- setInternalInputValue(v);
1775
- onInputValueChange?.(v);
1776
- } : onInputValueChange,
1792
+ },
1777
1793
  onItemHighlighted: isVirtualized ? (item, { reason, index }) => {
1778
1794
  const virt = virtualizerRef.current;
1779
1795
  if (!item || !virt) return;
@@ -1948,7 +1964,8 @@ function SingleSearchableSelect(props) {
1948
1964
  emptyText = "No results found.",
1949
1965
  isLoading = false,
1950
1966
  loadingText = "Loading...",
1951
- filter
1967
+ filter,
1968
+ fullWidth = true
1952
1969
  } = props;
1953
1970
  const ariaDescribedBy = props["aria-describedby"];
1954
1971
  const isChildrenMode = "children" in props && props.children != null;
@@ -1990,7 +2007,7 @@ function SingleSearchableSelect(props) {
1990
2007
  () => groupBy ? groupItems(data, groupBy) : null,
1991
2008
  [data, groupBy]
1992
2009
  );
1993
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Field, { children: [
2010
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Field, { $fullWidth: fullWidth, children: [
1994
2011
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
1995
2012
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1996
2013
  import_combobox5.Combobox.Root,
@@ -2122,6 +2139,7 @@ function SingleSearchableSelect(props) {
2122
2139
  var React11 = __toESM(require("react"));
2123
2140
  var import_combobox6 = require("@base-ui/react/combobox");
2124
2141
  var import_react_virtual5 = require("@tanstack/react-virtual");
2142
+ var import_seeds_react_icon4 = __toESM(require("@sproutsocial/seeds-react-icon"));
2125
2143
  var import_styled_components7 = __toESM(require("styled-components"));
2126
2144
  var import_jsx_runtime11 = require("react/jsx-runtime");
2127
2145
  var SelectionText2 = import_styled_components7.default.span`
@@ -2148,7 +2166,8 @@ function MultiSearchableSelect(props) {
2148
2166
  emptyText = "No results found.",
2149
2167
  isLoading = false,
2150
2168
  loadingText = "Loading...",
2151
- filter
2169
+ filter,
2170
+ fullWidth = true
2152
2171
  } = props;
2153
2172
  const ariaDescribedBy = props["aria-describedby"];
2154
2173
  const isChildrenMode = "children" in props && props.children != null;
@@ -2165,12 +2184,16 @@ function MultiSearchableSelect(props) {
2165
2184
  const selectHeadings = isChildrenMode ? false : props.selectHeadings ?? false;
2166
2185
  const selectAll = isChildrenMode ? false : props.selectAll ?? false;
2167
2186
  const isVirtualized = isChildrenMode ? false : props.isVirtualized ?? false;
2187
+ const creatableProp = isChildrenMode ? false : props.creatable ?? false;
2188
+ const onCreateProp = isChildrenMode ? void 0 : props.onCreate;
2168
2189
  const children = isChildrenMode ? props.children : void 0;
2169
2190
  const selectedItemIds = props.selectedItemIds;
2170
2191
  const defaultSelectedItemIds = props.defaultSelectedItemIds;
2171
2192
  const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
2172
2193
  const { containerRef, portalContainer } = useSeedsPortalContainer();
2173
2194
  const [open, setOpen] = React11.useState(false);
2195
+ const [internalInputValue, setInternalInputValue] = React11.useState("");
2196
+ const skipNextInputChangeRef = React11.useRef(false);
2174
2197
  const virtualizerRef = React11.useRef(null);
2175
2198
  const isControlled = selectedItemIds !== void 0;
2176
2199
  const idsToItems = React11.useCallback(
@@ -2189,6 +2212,18 @@ function MultiSearchableSelect(props) {
2189
2212
  () => groupBy ? groupItems(visibleData, groupBy) : null,
2190
2213
  [visibleData, groupBy]
2191
2214
  );
2215
+ const currentInputValue = internalInputValue;
2216
+ const creatableSentinel = React11.useMemo(() => {
2217
+ if (!creatableProp) return null;
2218
+ const trimmed = currentInputValue.trim();
2219
+ if (!trimmed) return null;
2220
+ const lowered = trimmed.toLocaleLowerCase();
2221
+ const exactExists = data.some(
2222
+ (d) => itemToString(d).trim().toLocaleLowerCase() === lowered
2223
+ );
2224
+ if (exactExists) return null;
2225
+ return makeCreatableSentinel(trimmed);
2226
+ }, [creatableProp, currentInputValue, data, itemToString]);
2192
2227
  const flatItems = React11.useMemo(() => {
2193
2228
  if (!groups || !selectHeadings && !selectAll) return null;
2194
2229
  const rows = [];
@@ -2205,10 +2240,21 @@ function MultiSearchableSelect(props) {
2205
2240
  onSelectedItemIdsChange(items.map((item) => item.id));
2206
2241
  }
2207
2242
  function handleValueChange(next) {
2243
+ const creatableClicked = next.find(isCreatableSentinel);
2244
+ if (creatableClicked) {
2245
+ const newItem = onCreateProp?.(creatableClicked.label);
2246
+ const realItems2 = next.filter(
2247
+ (v) => !isGroupHeaderSentinel3(v) && !isSelectAllSentinel3(v) && !isCreatableSentinel(v)
2248
+ );
2249
+ setSelectedItems(newItem ? [...realItems2, newItem] : realItems2);
2250
+ skipNextInputChangeRef.current = true;
2251
+ setInternalInputValue("");
2252
+ return;
2253
+ }
2208
2254
  const selectAllClicked = next.filter(isSelectAllSentinel3);
2209
2255
  const groupSentinels = next.filter(isGroupHeaderSentinel3);
2210
2256
  const realItems = next.filter(
2211
- (v) => !isGroupHeaderSentinel3(v) && !isSelectAllSentinel3(v)
2257
+ (v) => !isGroupHeaderSentinel3(v) && !isSelectAllSentinel3(v) && !isCreatableSentinel(v)
2212
2258
  );
2213
2259
  if (selectAllClicked.length > 0) {
2214
2260
  const allSelected = data.every(
@@ -2242,6 +2288,15 @@ function MultiSearchableSelect(props) {
2242
2288
  setSelectedItems(updated);
2243
2289
  }
2244
2290
  function handleSimpleValueChange(newItems) {
2291
+ const creatableClicked = newItems.find(isCreatableSentinel);
2292
+ if (creatableClicked) {
2293
+ const newItem = onCreateProp?.(creatableClicked.label);
2294
+ const realItems = newItems.filter((v) => !isCreatableSentinel(v));
2295
+ setSelectedItems(newItem ? [...realItems, newItem] : realItems);
2296
+ skipNextInputChangeRef.current = true;
2297
+ setInternalInputValue("");
2298
+ return;
2299
+ }
2245
2300
  setSelectedItems(newItems);
2246
2301
  }
2247
2302
  function renderSentinelRow(row) {
@@ -2272,6 +2327,9 @@ function MultiSearchableSelect(props) {
2272
2327
  renderGroupHeading ? renderGroupHeading(row.groupName) : row.groupName
2273
2328
  ] }, `__header-${row.groupName}`);
2274
2329
  }
2330
+ if (isCreatableSentinel(row)) {
2331
+ return renderCreatableItem(row);
2332
+ }
2275
2333
  const item = row;
2276
2334
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2277
2335
  ComboboxItem_default,
@@ -2286,10 +2344,31 @@ function MultiSearchableSelect(props) {
2286
2344
  item.id
2287
2345
  );
2288
2346
  }
2289
- const rootItems = flatItems ?? groups ?? (isChildrenMode ? void 0 : visibleData);
2347
+ function renderCreatableItem(sentinel, style, index, measureRef) {
2348
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2349
+ ComboboxItem_default,
2350
+ {
2351
+ value: sentinel,
2352
+ itemId: "__creatable",
2353
+ label: `Create "${sentinel.label}"`,
2354
+ inputType: "none",
2355
+ renderItem: () => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2356
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_seeds_react_icon4.default, { name: "plus-outline", size: "mini" }),
2357
+ `Create "${sentinel.label}"`
2358
+ ] }),
2359
+ style,
2360
+ index,
2361
+ "data-index": index,
2362
+ ref: measureRef
2363
+ },
2364
+ "__creatable"
2365
+ );
2366
+ }
2367
+ const baseItems = flatItems ?? groups ?? (isChildrenMode ? void 0 : visibleData);
2368
+ const rootItems = creatableSentinel && Array.isArray(baseItems) ? [...baseItems, creatableSentinel] : baseItems;
2290
2369
  const hasSentinels = selectAll || selectHeadings;
2291
2370
  const rootValue = hasSentinels ? [...value] : value;
2292
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Field, { children: [
2371
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Field, { $fullWidth: fullWidth, children: [
2293
2372
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
2294
2373
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2295
2374
  import_combobox6.Combobox.Root,
@@ -2297,7 +2376,23 @@ function MultiSearchableSelect(props) {
2297
2376
  multiple: true,
2298
2377
  id,
2299
2378
  virtualized: isVirtualized,
2300
- filter,
2379
+ filter: creatableProp ? (item, query) => {
2380
+ if (isCreatableSentinel(item)) return true;
2381
+ if (filter) return filter(item, query);
2382
+ if (isGroupHeaderSentinel3(item) || isSelectAllSentinel3(item))
2383
+ return true;
2384
+ const label = itemToString(item);
2385
+ return label.toLowerCase().includes(query.toLowerCase());
2386
+ } : filter,
2387
+ inputValue: internalInputValue,
2388
+ onInputValueChange: (v, eventDetails) => {
2389
+ if (eventDetails.reason === "input-clear" && open) return;
2390
+ if (skipNextInputChangeRef.current) {
2391
+ skipNextInputChangeRef.current = false;
2392
+ return;
2393
+ }
2394
+ setInternalInputValue(v);
2395
+ },
2301
2396
  open,
2302
2397
  disabled: props.disabled,
2303
2398
  onOpenChange: setOpen,
@@ -2320,15 +2415,17 @@ function MultiSearchableSelect(props) {
2320
2415
  hasSentinels ? handleValueChange : handleSimpleValueChange
2321
2416
  ),
2322
2417
  itemToStringLabel: (item) => {
2323
- if (!item || isGroupHeaderSentinel3(item) || isSelectAllSentinel3(item))
2418
+ if (!item || isGroupHeaderSentinel3(item) || isSelectAllSentinel3(item) || isCreatableSentinel(item))
2324
2419
  return "";
2325
2420
  return itemToString(item);
2326
2421
  },
2327
2422
  isItemEqualToValue: (a, b) => {
2423
+ if (isCreatableSentinel(a) && isCreatableSentinel(b))
2424
+ return a.label === b.label;
2328
2425
  if (isGroupHeaderSentinel3(a) && isGroupHeaderSentinel3(b))
2329
2426
  return a.groupName === b.groupName;
2330
2427
  if (isSelectAllSentinel3(a) && isSelectAllSentinel3(b)) return true;
2331
- if (!isGroupHeaderSentinel3(a) && !isSelectAllSentinel3(a) && !isGroupHeaderSentinel3(b) && !isSelectAllSentinel3(b))
2428
+ if (!isGroupHeaderSentinel3(a) && !isSelectAllSentinel3(a) && !isCreatableSentinel(a) && !isGroupHeaderSentinel3(b) && !isSelectAllSentinel3(b) && !isCreatableSentinel(b))
2332
2429
  return a.id === b.id;
2333
2430
  return false;
2334
2431
  },
@@ -2391,37 +2488,55 @@ function MultiSearchableSelect(props) {
2391
2488
  itemToString,
2392
2489
  inputType,
2393
2490
  renderItem,
2394
- renderGroupHeading
2491
+ renderGroupHeading,
2492
+ renderCreatableItem: creatableProp ? (sentinel, style, index, measureRef) => renderCreatableItem(
2493
+ sentinel,
2494
+ style,
2495
+ index,
2496
+ measureRef
2497
+ ) : void 0
2395
2498
  }
2396
- ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React11.Fragment, { children: [
2397
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ComboboxGroup, { items: group.items, children: [
2398
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
2399
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_combobox6.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2400
- ComboboxItem_default,
2401
- {
2402
- value: item,
2403
- itemId: String(item.id),
2404
- label: itemToString(item),
2405
- disabled: item.disabled,
2406
- inputType,
2407
- renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
2408
- },
2409
- item.id
2410
- ) })
2411
- ] }),
2412
- index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxSeparator, {})
2413
- ] }, group.value) : (item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2414
- ComboboxItem_default,
2415
- {
2416
- value: item,
2417
- itemId: String(item.id),
2418
- label: itemToString(item),
2419
- disabled: item.disabled,
2420
- inputType,
2421
- renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
2422
- },
2423
- item.id
2424
- )
2499
+ ) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => {
2500
+ if (isCreatableSentinel(group)) {
2501
+ return renderCreatableItem(group);
2502
+ }
2503
+ const g = group;
2504
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React11.Fragment, { children: [
2505
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ComboboxGroup, { items: g.items, children: [
2506
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(g.value) : g.value }),
2507
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_combobox6.Combobox.Collection, { children: (item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2508
+ ComboboxItem_default,
2509
+ {
2510
+ value: item,
2511
+ itemId: String(item.id),
2512
+ label: itemToString(item),
2513
+ disabled: item.disabled,
2514
+ inputType,
2515
+ renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
2516
+ },
2517
+ item.id
2518
+ ) })
2519
+ ] }),
2520
+ index < groups.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ComboboxSeparator, {})
2521
+ ] }, g.value);
2522
+ } : (item) => {
2523
+ if (isCreatableSentinel(item)) {
2524
+ return renderCreatableItem(item);
2525
+ }
2526
+ const dataItem = item;
2527
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2528
+ ComboboxItem_default,
2529
+ {
2530
+ value: dataItem,
2531
+ itemId: String(dataItem.id),
2532
+ label: itemToString(dataItem),
2533
+ disabled: dataItem.disabled,
2534
+ inputType,
2535
+ renderItem: renderItem ? () => renderItem(dataItem) : () => itemToString(dataItem)
2536
+ },
2537
+ dataItem.id
2538
+ );
2539
+ }
2425
2540
  }
2426
2541
  )
2427
2542
  ]
@@ -2432,8 +2547,353 @@ function MultiSearchableSelect(props) {
2432
2547
  )
2433
2548
  ] });
2434
2549
  }
2550
+
2551
+ // src/v3/ActionMenu.tsx
2552
+ var React12 = __toESM(require("react"));
2553
+ var import_menu2 = require("@base-ui/react/menu");
2554
+ var import_seeds_react_radio3 = __toESM(require("@sproutsocial/seeds-react-radio"));
2555
+ var import_seeds_react_checkbox4 = __toESM(require("@sproutsocial/seeds-react-checkbox"));
2556
+ var import_seeds_react_icon5 = require("@sproutsocial/seeds-react-icon");
2557
+
2558
+ // src/v3/ActionMenuStyles.tsx
2559
+ var import_menu = require("@base-ui/react/menu");
2560
+ var import_styled_components8 = __toESM(require("styled-components"));
2561
+ var import_seeds_react_mixins3 = require("@sproutsocial/seeds-react-mixins");
2562
+ var ActionMenuTrigger = (0, import_styled_components8.default)(import_menu.Menu.Trigger)``;
2563
+ var ActionMenuPositioner = (0, import_styled_components8.default)(import_menu.Menu.Positioner)`
2564
+ min-width: var(--anchor-width);
2565
+ z-index: 7;
2566
+ `;
2567
+ var ActionMenuPopup = (0, import_styled_components8.default)(import_menu.Menu.Popup)`
2568
+ font-family: ${({ theme }) => theme.fontFamily};
2569
+ background: ${({ theme }) => theme.colors.container.background.base};
2570
+ border: 1px solid ${({ theme }) => theme.colors.container.border.base};
2571
+ border-radius: ${({ theme }) => theme.radii[500]};
2572
+ box-shadow: ${({ theme }) => theme.shadows.low};
2573
+ outline: none;
2574
+ max-height: min(var(--base-ui-available-height, 400px), 400px);
2575
+ overflow-y: auto;
2576
+ padding: ${({ theme }) => theme.space[200]};
2577
+
2578
+ &[data-open] {
2579
+ animation: action-menu-popup-in 120ms ease-out;
2580
+ }
2581
+
2582
+ &[data-closed] {
2583
+ animation: action-menu-popup-out 100ms ease-in;
2584
+ }
2585
+
2586
+ @keyframes action-menu-popup-in {
2587
+ from {
2588
+ opacity: 0;
2589
+ transform: scale(0.95);
2590
+ }
2591
+ to {
2592
+ opacity: 1;
2593
+ transform: scale(1);
2594
+ }
2595
+ }
2596
+
2597
+ @keyframes action-menu-popup-out {
2598
+ from {
2599
+ opacity: 1;
2600
+ transform: scale(1);
2601
+ }
2602
+ to {
2603
+ opacity: 0;
2604
+ transform: scale(0.95);
2605
+ }
2606
+ }
2607
+ `;
2608
+ var ActionMenuGroup = (0, import_styled_components8.default)(import_menu.Menu.Group)`
2609
+ display: block;
2610
+ `;
2611
+ var ActionMenuGroupLabel = (0, import_styled_components8.default)(import_menu.Menu.GroupLabel)`
2612
+ padding: ${({ theme }) => `${theme.space[300]} ${theme.space[300]} ${theme.space[200]}`};
2613
+ 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};
2618
+ `;
2619
+ var ActionMenuSeparator = (0, import_styled_components8.default)(import_menu.Menu.Separator)`
2620
+ height: 1px;
2621
+ margin: ${({ theme }) => `${theme.space[200]} ${theme.space[300]}`};
2622
+ background: ${({ theme }) => theme.colors.container.border.base};
2623
+ `;
2624
+ var menuItemStyles = import_styled_components8.css`
2625
+ box-sizing: border-box;
2626
+ display: block;
2627
+ width: 100%;
2628
+ border-radius: ${({ theme }) => theme.radii[500]};
2629
+ background-color: ${({ theme }) => theme.colors.listItem.background.base};
2630
+ border: 1px solid ${({ theme }) => theme.colors.listItem.background.base};
2631
+ color: ${({ theme }) => theme.colors.text.body};
2632
+ font-family: ${({ theme }) => theme.fontFamily};
2633
+ font-weight: ${({ theme }) => theme.fontWeights.normal};
2634
+ text-align: left;
2635
+ text-decoration: none;
2636
+ padding: ${({ theme }) => theme.space[300]};
2637
+ outline: 0;
2638
+ ${({ theme }) => theme.typography[200]};
2639
+ transition: all ${({ theme }) => theme.duration.fast};
2640
+ cursor: pointer;
2641
+ user-select: none;
2642
+
2643
+ &[data-highlighted] {
2644
+ border-color: ${({ theme }) => theme.colors.listItem.border.base};
2645
+ background-color: ${({ theme }) => theme.colors.listItem.background.hover};
2646
+ color: ${({ theme }) => theme.colors.text.body};
2647
+ text-decoration: none;
2648
+ }
2649
+
2650
+ &[data-disabled] {
2651
+ cursor: not-allowed;
2652
+ opacity: 0.4;
2653
+ }
2654
+ `;
2655
+ var StyledMenuItem = (0, import_styled_components8.default)(import_menu.Menu.Item)`
2656
+ ${menuItemStyles}
2657
+ `;
2658
+ var StyledCheckboxItem = (0, import_styled_components8.default)(import_menu.Menu.CheckboxItem)`
2659
+ ${menuItemStyles}
2660
+ display: flex;
2661
+ align-items: center;
2662
+ gap: ${({ theme }) => theme.space[300]};
2663
+ `;
2664
+ var StyledRadioItem = (0, import_styled_components8.default)(import_menu.Menu.RadioItem)`
2665
+ ${menuItemStyles}
2666
+ display: flex;
2667
+ align-items: center;
2668
+ gap: ${({ theme }) => theme.space[300]};
2669
+ `;
2670
+ var StyledCheckboxItemIndicator = (0, import_styled_components8.default)(import_menu.Menu.CheckboxItemIndicator)`
2671
+ display: flex;
2672
+ align-items: center;
2673
+ width: 16px;
2674
+ color: ${({ theme }) => theme.colors.text.body};
2675
+ `;
2676
+ var StyledRadioItemIndicator = (0, import_styled_components8.default)(import_menu.Menu.RadioItemIndicator)`
2677
+ display: flex;
2678
+ align-items: center;
2679
+ width: 16px;
2680
+ color: ${({ theme }) => theme.colors.text.body};
2681
+ `;
2682
+ var StyledSubmenuTrigger = (0, import_styled_components8.default)(import_menu.Menu.SubmenuTrigger)`
2683
+ ${menuItemStyles}
2684
+ display: flex;
2685
+ align-items: center;
2686
+ gap: ${({ theme }) => theme.space[300]};
2687
+ justify-content: space-between;
2688
+
2689
+ &[data-popup-open] {
2690
+ border-color: ${({ theme }) => theme.colors.listItem.border.base};
2691
+ background-color: ${({ theme }) => theme.colors.listItem.background.hover};
2692
+ }
2693
+ `;
2694
+ var StyledLinkItem = (0, import_styled_components8.default)(import_menu.Menu.LinkItem)`
2695
+ ${menuItemStyles}
2696
+ `;
2697
+
2698
+ // src/v3/ActionMenu.tsx
2699
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2700
+ function ActionMenu({
2701
+ trigger,
2702
+ children,
2703
+ open,
2704
+ defaultOpen,
2705
+ onOpenChange,
2706
+ disabled
2707
+ }) {
2708
+ const { containerRef, portalContainer } = useSeedsPortalContainer();
2709
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2710
+ import_menu2.Menu.Root,
2711
+ {
2712
+ open,
2713
+ defaultOpen,
2714
+ onOpenChange,
2715
+ children: [
2716
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
2717
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ActionMenuTrigger, { render: trigger, disabled }),
2718
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_menu2.Menu.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ActionMenuPositioner, { sideOffset: 8, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ActionMenuPopup, { children }) }) })
2719
+ ]
2720
+ }
2721
+ );
2722
+ }
2723
+ function MenuGroup({
2724
+ children,
2725
+ label,
2726
+ showSeparator = false
2727
+ }) {
2728
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2729
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(ActionMenuGroup, { children: [
2730
+ label && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ActionMenuGroupLabel, { children: label }),
2731
+ children
2732
+ ] }),
2733
+ showSeparator && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ActionMenuSeparator, {})
2734
+ ] });
2735
+ }
2736
+ function MenuRadioGroup({
2737
+ children,
2738
+ value,
2739
+ defaultValue,
2740
+ onValueChange
2741
+ }) {
2742
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2743
+ import_menu2.Menu.RadioGroup,
2744
+ {
2745
+ value,
2746
+ defaultValue,
2747
+ onValueChange,
2748
+ children
2749
+ }
2750
+ );
2751
+ }
2752
+ function MenuItem(props) {
2753
+ const generatedId = React12.useId();
2754
+ if (props.type === "checkbox") {
2755
+ const {
2756
+ children: children2,
2757
+ checked,
2758
+ defaultChecked,
2759
+ onCheckedChange,
2760
+ disabled: disabled2,
2761
+ closeOnClick: closeOnClick2 = false,
2762
+ id
2763
+ } = props;
2764
+ const itemId = id ?? `checkbox-menu-item-${generatedId}`;
2765
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2766
+ StyledCheckboxItem,
2767
+ {
2768
+ checked,
2769
+ defaultChecked,
2770
+ onCheckedChange,
2771
+ disabled: disabled2,
2772
+ closeOnClick: closeOnClick2,
2773
+ children: [
2774
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2775
+ StyledCheckboxItemIndicator,
2776
+ {
2777
+ keepMounted: true,
2778
+ render: (_indicatorProps, state) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2779
+ import_seeds_react_checkbox4.default,
2780
+ {
2781
+ checked: state.checked,
2782
+ onChange: () => {
2783
+ },
2784
+ tabIndex: -1,
2785
+ id: itemId,
2786
+ name: "menu-checkbox-item"
2787
+ }
2788
+ )
2789
+ }
2790
+ ),
2791
+ children2
2792
+ ]
2793
+ }
2794
+ );
2795
+ }
2796
+ if (props.type === "radio") {
2797
+ const { children: children2, value, disabled: disabled2, closeOnClick: closeOnClick2 = false } = props;
2798
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2799
+ StyledRadioItem,
2800
+ {
2801
+ value,
2802
+ disabled: disabled2,
2803
+ closeOnClick: closeOnClick2,
2804
+ children: [
2805
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2806
+ StyledRadioItemIndicator,
2807
+ {
2808
+ keepMounted: true,
2809
+ render: (_indicatorProps, state) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2810
+ import_seeds_react_radio3.default,
2811
+ {
2812
+ checked: state.checked,
2813
+ onChange: () => {
2814
+ },
2815
+ tabIndex: -1,
2816
+ id: `radio-menu-item-${value}`,
2817
+ name: "menu-radio-item"
2818
+ }
2819
+ )
2820
+ }
2821
+ ),
2822
+ children2
2823
+ ]
2824
+ }
2825
+ );
2826
+ }
2827
+ const {
2828
+ children,
2829
+ onClick,
2830
+ disabled,
2831
+ closeOnClick = true,
2832
+ href,
2833
+ target
2834
+ } = props;
2835
+ if (href) {
2836
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StyledLinkItem, { href, target, closeOnClick, children });
2837
+ }
2838
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2839
+ StyledMenuItem,
2840
+ {
2841
+ onClick,
2842
+ disabled,
2843
+ closeOnClick,
2844
+ children
2845
+ }
2846
+ );
2847
+ }
2848
+ function MenuSub({
2849
+ trigger,
2850
+ children,
2851
+ open,
2852
+ defaultOpen,
2853
+ onOpenChange,
2854
+ closeParentOnEsc = false
2855
+ }) {
2856
+ const { containerRef, portalContainer } = useSeedsPortalContainer();
2857
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2858
+ import_menu2.Menu.SubmenuRoot,
2859
+ {
2860
+ open,
2861
+ defaultOpen,
2862
+ onOpenChange,
2863
+ closeParentOnEsc,
2864
+ children: [
2865
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: containerRef, style: { position: "relative" } }),
2866
+ trigger,
2867
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_menu2.Menu.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ActionMenuPositioner, { sideOffset: getOffset, alignOffset: getOffset, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ActionMenuPopup, { children }) }) })
2868
+ ]
2869
+ }
2870
+ );
2871
+ }
2872
+ function getOffset({ side }) {
2873
+ return side === "top" || side === "bottom" ? 4 : -8;
2874
+ }
2875
+ function MenuSubTrigger({
2876
+ children,
2877
+ disabled,
2878
+ label,
2879
+ openOnHover = true
2880
+ }) {
2881
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2882
+ StyledSubmenuTrigger,
2883
+ {
2884
+ disabled,
2885
+ label,
2886
+ openOnHover,
2887
+ children: [
2888
+ children,
2889
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_seeds_react_icon5.Icon, { name: "chevron-right-outline", fixedWidth: true, "aria-hidden": true })
2890
+ ]
2891
+ }
2892
+ );
2893
+ }
2435
2894
  // Annotate the CommonJS export names for ESM import in node:
2436
2895
  0 && (module.exports = {
2896
+ ActionMenu,
2437
2897
  ComboboxActionButtons,
2438
2898
  ComboboxClear,
2439
2899
  ComboboxEmpty,
@@ -2456,6 +2916,11 @@ function MultiSearchableSelect(props) {
2456
2916
  ComboboxTokenInput,
2457
2917
  ComboboxTokenInputGroup,
2458
2918
  ComboboxTrigger,
2919
+ MenuGroup,
2920
+ MenuItem,
2921
+ MenuRadioGroup,
2922
+ MenuSub,
2923
+ MenuSubTrigger,
2459
2924
  MultiCombobox,
2460
2925
  MultiSearchableSelect,
2461
2926
  MultiSelect,