@sproutsocial/seeds-react-menu 0.2.3 → 0.4.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.
Files changed (39) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/CHANGELOG.md +27 -0
  3. package/dist/esm/index.js +243 -75
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/index.d.mts +81 -49
  6. package/dist/index.d.ts +81 -49
  7. package/dist/index.js +237 -67
  8. package/dist/index.js.map +1 -1
  9. package/package.json +3 -1
  10. package/src/Autocomplete/Autocomplete.feature +14 -43
  11. package/src/Autocomplete/Autocomplete.stories.tsx +128 -0
  12. package/src/Autocomplete/Autocomplete.tsx +29 -11
  13. package/src/Autocomplete/AutocompleteInput.tsx +51 -0
  14. package/src/Autocomplete/AutocompleteTypes.ts +8 -1
  15. package/src/Autocomplete/__tests__/Autocomplete.test.tsx +142 -89
  16. package/src/Autocomplete/__tests__/Autocomplete.typetest.tsx +25 -43
  17. package/src/Autocomplete/index.ts +1 -0
  18. package/src/MenuContent/MenuContent.tsx +2 -2
  19. package/src/MenuContext.tsx +11 -5
  20. package/src/MenuGroup/MenuGroup.feature +19 -37
  21. package/src/MenuGroup/MenuGroup.tsx +18 -3
  22. package/src/MenuGroup/MenuGroupTypes.ts +6 -1
  23. package/src/MenuGroup/__tests__/MenuGroup.test.tsx +167 -9
  24. package/src/MenuGroup/__tests__/MenuGroup.typetest.tsx +27 -13
  25. package/src/MenuItem/MenuItem.tsx +7 -4
  26. package/src/MenuLabel.tsx +4 -4
  27. package/src/MenuRoot/MenuRoot.tsx +5 -3
  28. package/src/MenuRoot/__tests__/MenuRoot.test.tsx +1 -1
  29. package/src/MultiSelectMenu/MultiSelectMenu.tsx +8 -0
  30. package/src/MultiSelectMenu/__tests__/MultiSelectMenu.test.tsx +6 -6
  31. package/src/SingleSelectMenu/SingleSelectMenu.tsx +2 -2
  32. package/src/SingleSelectMenu/__tests__/SingleSelectMenu.test.tsx +3 -3
  33. package/src/__fixtures__/menu-test-data.ts +36 -0
  34. package/src/__tests__/Menu.test.tsx +29 -96
  35. package/src/hooks/useItemsFromChildren.tsx +71 -21
  36. package/src/index.ts +1 -0
  37. package/src/reducers/useComboboxStateReducer.tsx +11 -8
  38. package/src/storybookUtilities/menu-storybook-components.tsx +39 -0
  39. package/src/types.ts +3 -0
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
 
33
33
  // ../../node_modules/object-assign/index.js
34
34
  var require_object_assign = __commonJS({
35
- "../../node_modules/object-assign/index.js"(exports, module2) {
35
+ "../../node_modules/object-assign/index.js"(exports2, module2) {
36
36
  "use strict";
37
37
  var getOwnPropertySymbols = Object.getOwnPropertySymbols;
38
38
  var hasOwnProperty = Object.prototype.hasOwnProperty;
@@ -101,9 +101,11 @@ var require_object_assign = __commonJS({
101
101
  });
102
102
 
103
103
  // src/index.ts
104
- var src_exports = {};
105
- __export(src_exports, {
104
+ var index_exports = {};
105
+ __export(index_exports, {
106
106
  ActionMenu: () => ActionMenu,
107
+ Autocomplete: () => Autocomplete,
108
+ AutocompleteInput: () => AutocompleteInput,
107
109
  INPUT_TYPES: () => INPUT_TYPES,
108
110
  MenuContent: () => MenuContent,
109
111
  MenuContext: () => MenuContext,
@@ -131,7 +133,7 @@ __export(src_exports, {
131
133
  useMenuContext: () => useMenuContext,
132
134
  useSelectStateReducer: () => useSelectStateReducer
133
135
  });
134
- module.exports = __toCommonJS(src_exports);
136
+ module.exports = __toCommonJS(index_exports);
135
137
 
136
138
  // src/MenuItem/MenuItem.tsx
137
139
  var import_react3 = require("react");
@@ -147,15 +149,18 @@ var useMenu = ({
147
149
  items = [],
148
150
  isListbox = false,
149
151
  isOpen = false,
152
+ itemsMap: itemsMapFromProps,
150
153
  ...rest
151
154
  } = {}) => {
152
155
  const menuProps = (0, import_react.useMemo)(() => ({ ...rest }), [rest]);
153
156
  const itemsMap = (0, import_react.useMemo)(
154
- () => items.reduce((map, item) => {
155
- map[`${item.id}`] = item;
157
+ () => itemsMapFromProps || items.reduce((map, item) => {
158
+ map[`${item.id}`] = {
159
+ ...item
160
+ };
156
161
  return map;
157
162
  }, {}),
158
- [items]
163
+ [items, itemsMapFromProps]
159
164
  );
160
165
  return {
161
166
  isOpen,
@@ -168,9 +173,9 @@ var useMenu = ({
168
173
  var MenuContext = (0, import_react.createContext)(defaultMenuContext);
169
174
  var MenuProvider = ({
170
175
  children,
171
- ...overrides
176
+ menuProps
172
177
  }) => {
173
- const filterContext = useMenu(overrides);
178
+ const filterContext = useMenu(menuProps);
174
179
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuContext.Provider, { value: { ...filterContext }, children });
175
180
  };
176
181
  var useMenuContext = () => {
@@ -257,8 +262,7 @@ function _isNativeReflectConstruct() {
257
262
 
258
263
  // ../../node_modules/@babel/runtime/helpers/esm/construct.js
259
264
  function _construct(t, e, r) {
260
- if (_isNativeReflectConstruct())
261
- return Reflect.construct.apply(null, arguments);
265
+ if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
262
266
  var o = [null];
263
267
  o.push.apply(o, e);
264
268
  var p = new (t.bind.apply(t, o))();
@@ -269,14 +273,12 @@ function _construct(t, e, r) {
269
273
  function _wrapNativeSuper(Class) {
270
274
  var _cache = typeof Map === "function" ? /* @__PURE__ */ new Map() : void 0;
271
275
  _wrapNativeSuper = function _wrapNativeSuper2(Class2) {
272
- if (Class2 === null || !_isNativeFunction(Class2))
273
- return Class2;
276
+ if (Class2 === null || !_isNativeFunction(Class2)) return Class2;
274
277
  if (typeof Class2 !== "function") {
275
278
  throw new TypeError("Super expression must either be null or a function");
276
279
  }
277
280
  if (typeof _cache !== "undefined") {
278
- if (_cache.has(Class2))
279
- return _cache.get(Class2);
281
+ if (_cache.has(Class2)) return _cache.get(Class2);
280
282
  _cache.set(Class2, Wrapper);
281
283
  }
282
284
  function Wrapper() {
@@ -599,8 +601,7 @@ var namedColorMap = {
599
601
  yellowgreen: "9acd32"
600
602
  };
601
603
  function nameToHex(color2) {
602
- if (typeof color2 !== "string")
603
- return color2;
604
+ if (typeof color2 !== "string") return color2;
604
605
  var normalizedColorName = color2.toLowerCase();
605
606
  return namedColorMap[normalizedColorName] ? "#" + namedColorMap[normalizedColorName] : color2;
606
607
  }
@@ -743,8 +744,7 @@ function guard(lowerBoundary, upperBoundary, value) {
743
744
  return Math.max(lowerBoundary, Math.min(upperBoundary, value));
744
745
  }
745
746
  function transparentize(amount, color2) {
746
- if (color2 === "transparent")
747
- return color2;
747
+ if (color2 === "transparent") return color2;
748
748
  var parsedColor = parseToRgb(color2);
749
749
  var alpha = typeof parsedColor.alpha === "number" ? parsedColor.alpha : 1;
750
750
  var colorWithAlpha = _extends({}, parsedColor, {
@@ -754,7 +754,7 @@ function transparentize(amount, color2) {
754
754
  }
755
755
  var curriedTransparentize = /* @__PURE__ */ curry(transparentize);
756
756
 
757
- // ../seeds-react-mixins/src/index.ts
757
+ // ../seeds-react-mixins/dist/esm/index.js
758
758
  var import_styled_components = require("styled-components");
759
759
  var import_seeds_react_theme = require("@sproutsocial/seeds-react-theme");
760
760
  var visuallyHidden = import_styled_components.css`
@@ -794,8 +794,7 @@ var merge = function merge2(a, b) {
794
794
  var result = (0, import_object_assign.default)({}, a, b);
795
795
  for (var key in a) {
796
796
  var _assign;
797
- if (!a[key] || typeof b[key] !== "object")
798
- continue;
797
+ if (!a[key] || typeof b[key] !== "object") continue;
799
798
  (0, import_object_assign.default)(result, (_assign = {}, _assign[key] = (0, import_object_assign.default)(a[key], b[key]), _assign));
800
799
  }
801
800
  return result;
@@ -837,8 +836,7 @@ var createParser = function createParser2(config9) {
837
836
  var shouldSort = false;
838
837
  var isCacheDisabled = props.theme && props.theme.disableStyledSystemCache;
839
838
  for (var key in props) {
840
- if (!config9[key])
841
- continue;
839
+ if (!config9[key]) continue;
842
840
  var sx = config9[key];
843
841
  var raw = props[key];
844
842
  var scale = get(props.theme, sx.scale, sx.defaults);
@@ -912,8 +910,7 @@ var createStyleFunction = function createStyleFunction2(_ref) {
912
910
  var sx = function sx2(value, scale2, _props) {
913
911
  var result = {};
914
912
  var n = transform(value, scale2, _props);
915
- if (n === null)
916
- return;
913
+ if (n === null) return;
917
914
  properties.forEach(function(prop) {
918
915
  result[prop] = n;
919
916
  });
@@ -952,8 +949,7 @@ var compose = function compose2() {
952
949
  parsers[_key] = arguments[_key];
953
950
  }
954
951
  parsers.forEach(function(parser2) {
955
- if (!parser2 || !parser2.config)
956
- return;
952
+ if (!parser2 || !parser2.config) return;
957
953
  (0, import_object_assign.default)(config9, parser2.config);
958
954
  });
959
955
  var parser = createParser(config9);
@@ -1549,8 +1545,7 @@ var positiveOrNegative = function positiveOrNegative2(scale, value) {
1549
1545
  }
1550
1546
  var absolute = Math.abs(value);
1551
1547
  var n = get3(scale, absolute, absolute);
1552
- if (typeof n === "string")
1553
- return "-" + n;
1548
+ if (typeof n === "string") return "-" + n;
1554
1549
  return n * -1;
1555
1550
  };
1556
1551
  var transforms = ["margin", "marginTop", "marginRight", "marginBottom", "marginLeft", "marginX", "marginY", "top", "bottom", "left", "right"].reduce(function(acc, curr) {
@@ -1566,8 +1561,7 @@ var responsive = function responsive2(styles) {
1566
1561
  }));
1567
1562
  for (var key in styles) {
1568
1563
  var value = typeof styles[key] === "function" ? styles[key](theme2) : styles[key];
1569
- if (value == null)
1570
- continue;
1564
+ if (value == null) continue;
1571
1565
  if (!Array.isArray(value)) {
1572
1566
  next[key] = value;
1573
1567
  continue;
@@ -1579,8 +1573,7 @@ var responsive = function responsive2(styles) {
1579
1573
  continue;
1580
1574
  }
1581
1575
  next[media] = next[media] || {};
1582
- if (value[i] == null)
1583
- continue;
1576
+ if (value[i] == null) continue;
1584
1577
  next[media][key] = value[i];
1585
1578
  }
1586
1579
  }
@@ -1927,7 +1920,7 @@ var MenuItem = ({
1927
1920
  color: color2,
1928
1921
  ...props
1929
1922
  }) => {
1930
- const { getItemProps, itemsMap, highlightedIndex, isListbox } = (0, import_react3.useContext)(MenuContext);
1923
+ const { getItemProps, itemsMap, highlightedIndex, isListbox } = useMenuContext();
1931
1924
  const { ...optionProps } = useOptionProps({
1932
1925
  id,
1933
1926
  children,
@@ -1935,7 +1928,7 @@ var MenuItem = ({
1935
1928
  });
1936
1929
  const item = itemsMap[id] || { index: 0, id };
1937
1930
  const highlighted = highlightedIndex === item?.index;
1938
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MenuItemContainer, { role: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1931
+ return item.hidden ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MenuItemContainer, { role: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1939
1932
  StyledMenuItem,
1940
1933
  {
1941
1934
  id,
@@ -2116,9 +2109,7 @@ var Container = import_styled_components8.default.span`
2116
2109
  padding-left: 0;
2117
2110
  padding-right: 0;
2118
2111
  font-family: ${(props) => props.theme.fontFamily};
2119
- font-style: ${(props) => {
2120
- return props.isItalicized && "italic";
2121
- }};
2112
+ font-style: ${(props) => props.isItalicized && "italic"};
2122
2113
 
2123
2114
  ${(props) => props.truncated && import_styled_components8.css`
2124
2115
  display: block;
@@ -2212,7 +2203,7 @@ var SmallBodyCopyWithLogic = withTextLogic(SmallBodyCopy);
2212
2203
  SmallBodyCopyWithLogic.displayName = "Text.SmallBodyCopy";
2213
2204
  Text.SmallBodyCopy = SmallBodyCopyWithLogic;
2214
2205
  var Text_default = Text;
2215
- var src_default = Text_default;
2206
+ var index_default = Text_default;
2216
2207
 
2217
2208
  // src/MenuGroup/styles.tsx
2218
2209
  var StyledMenuGroup = import_styled_components9.default.li`
@@ -2231,7 +2222,7 @@ var StyledMenuGroup = import_styled_components9.default.li`
2231
2222
  ${layout}
2232
2223
  ${space}
2233
2224
  `;
2234
- var StyledTitle = (0, import_styled_components9.default)(src_default.SmallSubHeadline)`
2225
+ var StyledTitle = (0, import_styled_components9.default)(index_default.SmallSubHeadline)`
2235
2226
  margin: ${({ theme: theme2 }) => theme2.space[400]} ${({ theme: theme2 }) => theme2.space[400]}
2236
2227
  0px ${({ theme: theme2 }) => theme2.space[400]};
2237
2228
  `;
@@ -2244,16 +2235,26 @@ var StyledMenuGroupUl = import_styled_components9.default.ul`
2244
2235
  var import_jsx_runtime8 = require("react/jsx-runtime");
2245
2236
  var MenuGroup = ({
2246
2237
  titleAs = "h3",
2247
- children,
2238
+ children: childrenProp,
2248
2239
  title,
2249
2240
  color: color2,
2241
+ isSingleSelect,
2242
+ id,
2243
+ items,
2244
+ MenuItemComponent = MenuItem,
2250
2245
  ...rest
2251
2246
  }) => {
2252
2247
  const titleId = `menu-group-title-${Math.random().toString(36).slice(2, 11)}`;
2248
+ const children = childrenProp || !items || !items.length ? childrenProp : items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MenuItemComponent, { ...item }, item.id));
2249
+ if (!children) {
2250
+ return null;
2251
+ }
2253
2252
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2254
2253
  StyledMenuGroup,
2255
2254
  {
2256
2255
  role: "group",
2256
+ id,
2257
+ isSingleSelect,
2257
2258
  "aria-labelledby": title ? titleId : void 0,
2258
2259
  color: color2,
2259
2260
  ...rest,
@@ -2278,7 +2279,7 @@ var CustomPopoutContent = (0, import_styled_components10.default)(import_seeds_r
2278
2279
  var MenuRoot = ({
2279
2280
  children,
2280
2281
  menuToggleElement,
2281
- popoutProps,
2282
+ popoutProps: { focusLockProps, ...popoutProps } = {},
2282
2283
  width: width2 = "300px",
2283
2284
  ...contextProps
2284
2285
  }) => {
@@ -2289,7 +2290,7 @@ var MenuRoot = ({
2289
2290
  },
2290
2291
  [openMenu, closeMenu]
2291
2292
  );
2292
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MenuProvider, { ...contextProps, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2293
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MenuProvider, { menuProps: contextProps, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2293
2294
  import_seeds_react_popout.Popout,
2294
2295
  {
2295
2296
  menuPopout: true,
@@ -2299,7 +2300,8 @@ var MenuRoot = ({
2299
2300
  focusLockProps: {
2300
2301
  // correct jerking motion when scrolling while the Popout is open
2301
2302
  // returnFocus: false,
2302
- crossFrame: false
2303
+ crossFrame: false,
2304
+ ...focusLockProps
2303
2305
  },
2304
2306
  disableWrapperAria: true,
2305
2307
  ...popoutProps,
@@ -2310,10 +2312,11 @@ var MenuRoot = ({
2310
2312
 
2311
2313
  // src/MenuLabel.tsx
2312
2314
  var import_react11 = require("react");
2315
+ var import_seeds_react_label = require("@sproutsocial/seeds-react-label");
2313
2316
  var import_jsx_runtime10 = require("react/jsx-runtime");
2314
2317
  var MenuLabel = ({ children, ...rest }) => {
2315
2318
  const { getLabelProps } = useMenuContext();
2316
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text_default, { as: "label", color: "text.body", ...getLabelProps?.(), ...rest, children });
2319
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_seeds_react_label.Label, { htmlFor: "fallback_menu_label", ...getLabelProps?.(), ...rest, children });
2317
2320
  };
2318
2321
 
2319
2322
  // src/MenuToggleButton.tsx
@@ -2349,8 +2352,7 @@ var import_downshift2 = require("downshift");
2349
2352
  var import_react13 = __toESM(require("react"));
2350
2353
  var walkAllChildren = (children, callback) => {
2351
2354
  const walk = (element, parents2) => {
2352
- if (element === null || element === void 0)
2353
- return;
2355
+ if (element === null || element === void 0) return;
2354
2356
  callback(element, parents2);
2355
2357
  const newParents = [...parents2, element];
2356
2358
  const children2 = element.props?.children;
@@ -2367,35 +2369,76 @@ var checkIfIsElement = (element, name) => {
2367
2369
  return !!(element && typeof element === "object" && "type" in element && typeof element.type !== "string" && typeof element.type.name === "string" && element.type.name === name);
2368
2370
  };
2369
2371
  var getAllMenuItems = (children) => {
2370
- const allMenuItems = [];
2371
- walkAllChildren(children, (element, parents) => {
2372
+ const orderedElements = [];
2373
+ walkAllChildren(children, (element) => {
2372
2374
  if (checkIfIsElement(element, "MenuItem")) {
2373
- allMenuItems.push({
2374
- element,
2375
- parents
2375
+ orderedElements.push({
2376
+ type: "item",
2377
+ element
2378
+ });
2379
+ } else if (checkIfIsElement(element, "MenuGroup")) {
2380
+ orderedElements.push({
2381
+ type: "group",
2382
+ element
2376
2383
  });
2377
2384
  }
2378
2385
  });
2379
- return allMenuItems;
2386
+ return { orderedElements };
2380
2387
  };
2381
2388
  var useItemsFromChildren = ({
2382
2389
  children
2383
2390
  }) => {
2384
2391
  const { allMenuItems, menuItemsMap } = (0, import_react13.useMemo)(() => {
2385
- const allMenuItemElements = getAllMenuItems(children);
2392
+ const { orderedElements } = getAllMenuItems(children);
2386
2393
  const menuItemsMap2 = {};
2387
- const allMenuItems2 = allMenuItemElements.map(
2388
- ({ element }, index) => {
2394
+ const allMenuItems2 = [];
2395
+ let index = 0;
2396
+ orderedElements.forEach(({ type, element }) => {
2397
+ if (type === "group") {
2398
+ const menuGroup = element;
2399
+ const items = menuGroup.props.items;
2400
+ if (items) {
2401
+ items.forEach((menuItem) => {
2402
+ const item = {
2403
+ id: menuItem.id,
2404
+ index: index++,
2405
+ disabled: menuItem.disabled,
2406
+ menuItemProps: menuItem,
2407
+ menuGroupProps: element.props
2408
+ };
2409
+ allMenuItems2.push(item);
2410
+ menuItemsMap2[`${item.id}`] = item;
2411
+ });
2412
+ } else if (menuGroup.props.children) {
2413
+ let children2 = menuGroup.props.children;
2414
+ if (!Array.isArray(children2)) {
2415
+ children2 = [children2];
2416
+ }
2417
+ children2.forEach((menuItem) => {
2418
+ const item = {
2419
+ id: menuItem.props.id,
2420
+ index: index++,
2421
+ disabled: menuItem.props.disabled,
2422
+ menuItemProps: menuItem.props,
2423
+ menuGroupProps: element.props
2424
+ };
2425
+ allMenuItems2.push(item);
2426
+ menuItemsMap2[`${item.id}`] = item;
2427
+ });
2428
+ }
2429
+ } else {
2430
+ if (menuItemsMap2[`${element.props.id}`]) return;
2431
+ const menuItem = element;
2389
2432
  const item = {
2390
- id: element.props.id,
2391
- disabled: element.props.disabled,
2392
- index,
2393
- menuItemProps: element.props
2433
+ id: menuItem.props.id,
2434
+ index: index++,
2435
+ disabled: menuItem.props.disabled,
2436
+ menuItemProps: menuItem.props
2394
2437
  };
2438
+ allMenuItems2.push(item);
2395
2439
  menuItemsMap2[`${item.id}`] = item;
2396
- return item;
2397
2440
  }
2398
- );
2441
+ });
2399
2442
  return { allMenuItems: allMenuItems2, menuItemsMap: menuItemsMap2 };
2400
2443
  }, [children]);
2401
2444
  return { allMenuItems, menuItemsMap };
@@ -2406,12 +2449,14 @@ var import_downshift = require("downshift");
2406
2449
  var useSelectStateReducer = (state, actionAndChanges) => {
2407
2450
  const { type, changes } = actionAndChanges;
2408
2451
  switch (type) {
2452
+ /** If downshift is blurred by tabbing within the menu, stay open */
2409
2453
  case import_downshift.useSelect.stateChangeTypes.ToggleButtonBlur:
2410
2454
  return {
2411
2455
  ...changes,
2412
2456
  // keep menu open on blur
2413
2457
  isOpen: true
2414
2458
  };
2459
+ /** Return standard change payload */
2415
2460
  default:
2416
2461
  return changes;
2417
2462
  }
@@ -2433,8 +2478,7 @@ var handleStateChange = (changes, currentSelectedItem) => {
2433
2478
  return;
2434
2479
  }
2435
2480
  const selectedItem = changes.selectedItem || currentSelectedItem;
2436
- if (!selectedItem)
2437
- return;
2481
+ if (!selectedItem) return;
2438
2482
  if (selectedItem.disabled) {
2439
2483
  return;
2440
2484
  }
@@ -2614,13 +2658,18 @@ var MultiSelectMenu = ({
2614
2658
  case import_downshift4.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
2615
2659
  case import_downshift4.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
2616
2660
  case import_downshift4.useSelect.stateChangeTypes.ItemClick:
2617
- if (!newSelectedItem)
2618
- break;
2661
+ if (!newSelectedItem) break;
2619
2662
  if (selectedItems?.find((item) => item?.id === newSelectedItem.id)) {
2620
2663
  removeSelectedItem(newSelectedItem);
2621
2664
  } else {
2622
2665
  addSelectedItem(newSelectedItem);
2623
2666
  }
2667
+ if (newSelectedItem.menuGroupProps?.isSingleSelect) {
2668
+ const groupItems = selectedItems.filter(
2669
+ (item) => item.menuGroupProps?.id === newSelectedItem.menuGroupProps?.id
2670
+ );
2671
+ groupItems.forEach((item) => removeSelectedItem(item));
2672
+ }
2624
2673
  break;
2625
2674
  default:
2626
2675
  break;
@@ -2653,9 +2702,130 @@ var MultiSelectMenu = ({
2653
2702
  }
2654
2703
  );
2655
2704
  };
2705
+
2706
+ // src/Autocomplete/Autocomplete.tsx
2707
+ var import_react17 = __toESM(require("react"));
2708
+ var import_downshift6 = require("downshift");
2709
+
2710
+ // src/reducers/useComboboxStateReducer.tsx
2711
+ var import_downshift5 = require("downshift");
2712
+ var useComboboxStateReducer = (state, actionAndChanges) => {
2713
+ const { type, changes } = actionAndChanges;
2714
+ switch (type) {
2715
+ /** If downshift is blurred by tabbing within the menu, stay open */
2716
+ case import_downshift5.useCombobox.stateChangeTypes.InputBlur:
2717
+ return {
2718
+ ...changes,
2719
+ // keep menu open on blur
2720
+ isOpen: true
2721
+ };
2722
+ /** Return standard change payload */
2723
+ default:
2724
+ return changes;
2725
+ }
2726
+ };
2727
+ var defaultUseComboboxProps = {
2728
+ // disabling while item.hidden so that hidden items are ignored by downshift
2729
+ isItemDisabled: (item) => Boolean(item.disabled || item.hidden)
2730
+ };
2731
+
2732
+ // src/Autocomplete/Autocomplete.tsx
2733
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2734
+ var Autocomplete = ({
2735
+ children,
2736
+ stateReducer: externalStateReducer,
2737
+ itemToString: itemToString2 = itemToString,
2738
+ getIsItemVisible = (item, inputValue) => itemToString2(item).toLowerCase().startsWith(inputValue.toLowerCase()),
2739
+ ...useComboboxProps
2740
+ }) => {
2741
+ const { allMenuItems } = useItemsFromChildren({ children });
2742
+ const [items, setItems] = import_react17.default.useState(allMenuItems);
2743
+ const { isOpen, ...useComboboxReturnProps } = (0, import_downshift6.useCombobox)({
2744
+ ...defaultUseComboboxProps,
2745
+ items,
2746
+ itemToString: itemToString2,
2747
+ onInputValueChange({ inputValue }) {
2748
+ setItems(
2749
+ inputValue ? allMenuItems.reduce(
2750
+ (items2, item) => [
2751
+ ...items2,
2752
+ { ...item, hidden: !getIsItemVisible(item, inputValue) }
2753
+ ],
2754
+ []
2755
+ ) : allMenuItems
2756
+ );
2757
+ },
2758
+ stateReducer: (state, actionAndChanges) => {
2759
+ let newState;
2760
+ newState = useComboboxStateReducer(state, actionAndChanges);
2761
+ return externalStateReducer ? externalStateReducer(state, {
2762
+ ...actionAndChanges,
2763
+ changes: newState
2764
+ }) : newState;
2765
+ },
2766
+ ...useComboboxProps
2767
+ });
2768
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2769
+ MenuRoot,
2770
+ {
2771
+ ...{
2772
+ isListbox: true,
2773
+ items,
2774
+ itemToString: itemToString2,
2775
+ isOpen,
2776
+ ...useComboboxProps,
2777
+ ...useComboboxReturnProps
2778
+ },
2779
+ popoutProps: {
2780
+ focusOnContent: false
2781
+ },
2782
+ children
2783
+ }
2784
+ );
2785
+ };
2786
+
2787
+ // src/Autocomplete/AutocompleteInput.tsx
2788
+ var import_react18 = require("react");
2789
+ var import_seeds_react_input = require("@sproutsocial/seeds-react-input");
2790
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2791
+ var AutocompleteInput = ({
2792
+ onKeyDown,
2793
+ onChange,
2794
+ onInput,
2795
+ onBlur,
2796
+ onClick,
2797
+ inputProps,
2798
+ ...rest
2799
+ }) => {
2800
+ const { getInputProps, inputValue } = (0, import_react18.useContext)(MenuContext);
2801
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2802
+ import_seeds_react_input.Input,
2803
+ {
2804
+ id: "autocomplete_input",
2805
+ name: "autocomplete_input",
2806
+ inputProps: {
2807
+ ...getInputProps?.({
2808
+ // refKey: "innerRef",
2809
+ onKeyDown,
2810
+ onChange,
2811
+ onInput,
2812
+ onBlur,
2813
+ onClick,
2814
+ value: inputValue
2815
+ }),
2816
+ ...inputProps
2817
+ },
2818
+ autoComplete: false,
2819
+ value: inputValue,
2820
+ ...rest
2821
+ }
2822
+ );
2823
+ };
2656
2824
  // Annotate the CommonJS export names for ESM import in node:
2657
2825
  0 && (module.exports = {
2658
2826
  ActionMenu,
2827
+ Autocomplete,
2828
+ AutocompleteInput,
2659
2829
  INPUT_TYPES,
2660
2830
  MenuContent,
2661
2831
  MenuContext,