@sproutsocial/seeds-react-menu 0.4.1 → 0.6.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 (105) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/CHANGELOG.md +32 -0
  3. package/dist/esm/index.js +1553 -423
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/index.d.mts +303 -122
  6. package/dist/index.d.ts +303 -122
  7. package/dist/index.js +1561 -405
  8. package/dist/index.js.map +1 -1
  9. package/package.json +4 -1
  10. package/src/ActionMenu/ActionMenu.stories.tsx +426 -0
  11. package/src/ActionMenu/ActionMenu.tsx +30 -26
  12. package/src/ActionMenu/ActionMenuTypes.ts +13 -8
  13. package/src/ActionMenu/__tests__/ActionMenu.test.tsx +17 -30
  14. package/src/ActionMenu/__tests__/ActionMenu.typetest.tsx +32 -3
  15. package/src/Autocomplete/Autocomplete.stories.tsx +61 -2
  16. package/src/Autocomplete/Autocomplete.tsx +15 -74
  17. package/src/Autocomplete/AutocompleteInput.tsx +18 -27
  18. package/src/Autocomplete/AutocompleteTokenInput.tsx +50 -0
  19. package/src/Autocomplete/AutocompleteTypes.ts +27 -11
  20. package/src/Autocomplete/MultiAutocomplete.tsx +189 -0
  21. package/src/Autocomplete/SingleAutocomplete.tsx +74 -0
  22. package/src/Autocomplete/__tests__/Autocomplete.test.tsx +171 -3
  23. package/src/Autocomplete/__tests__/Autocomplete.typetest.tsx +116 -3
  24. package/src/MenuContent/MenuContent.stories.tsx +164 -0
  25. package/src/MenuContent/MenuContent.tsx +35 -8
  26. package/src/MenuContent/MenuContentTypes.ts +7 -5
  27. package/src/MenuContent/__tests__/MenuContent.typetest.tsx +18 -2
  28. package/src/MenuContext.tsx +191 -37
  29. package/src/MenuFooter/MenuFooter.stories.tsx +202 -0
  30. package/src/MenuFooter/__tests__/MenuFooter.test.tsx +16 -11
  31. package/src/MenuGroup/MenuGroup.feature +21 -21
  32. package/src/MenuGroup/MenuGroup.stories.tsx +248 -0
  33. package/src/MenuGroup/MenuGroup.tsx +9 -7
  34. package/src/MenuGroup/MenuGroupTypes.ts +8 -6
  35. package/src/MenuGroup/__tests__/MenuGroup.test.tsx +6 -6
  36. package/src/MenuGroup/__tests__/MenuGroup.typetest.tsx +23 -4
  37. package/src/MenuGroup/styles.tsx +4 -2
  38. package/src/MenuHeader/MenuHeader.stories.tsx +276 -0
  39. package/src/MenuHeader/MenuHeader.tsx +3 -1
  40. package/src/MenuHeader/__tests__/MenuHeader.test.tsx +23 -13
  41. package/src/MenuHeader/styles.tsx +18 -14
  42. package/src/MenuItem/MenuItem.stories.tsx +507 -0
  43. package/src/MenuItem/MenuItem.tsx +18 -9
  44. package/src/MenuItem/MenuItemTypes.ts +9 -4
  45. package/src/MenuItem/__tests__/MenuItem.test.tsx +6 -6
  46. package/src/MenuItem/styles.tsx +21 -5
  47. package/src/MenuItem/useOptionProps.tsx +10 -8
  48. package/src/MenuLabel.tsx +2 -2
  49. package/src/MenuRoot/MenuRoot.tsx +37 -23
  50. package/src/MenuRoot/__tests__/MenuRoot.test.tsx +59 -32
  51. package/src/MenuSearchInput/MenuSearchInput.tsx +63 -0
  52. package/src/MenuSearchInput/__tests__/MenuSearchInput.test.tsx +157 -0
  53. package/src/MenuSearchInput/__tests__/MenuSearchInput.typetest.tsx +31 -0
  54. package/src/MenuSearchInput/index.ts +1 -0
  55. package/src/MenuSearchTokenInput/MenuSearchTokenInput.tsx +98 -0
  56. package/src/MenuSearchTokenInput/__tests__/MenuSearchTokenInput.test.tsx +247 -0
  57. package/src/MenuSearchTokenInput/__tests__/MenuSearchTokenInput.typetest.tsx +33 -0
  58. package/src/MenuSearchTokenInput/index.ts +1 -0
  59. package/src/MenuToggleButton/MenuToggleButton.stories.tsx +72 -0
  60. package/src/{MenuToggleButton.tsx → MenuToggleButton/MenuToggleButton.tsx} +6 -5
  61. package/src/MenuToggleButton/index.ts +1 -0
  62. package/src/MenuTokenInput.tsx +104 -0
  63. package/src/MultiSelectMenu/MultiSelectMenu.stories.tsx +214 -0
  64. package/src/MultiSelectMenu/MultiSelectMenu.tsx +44 -67
  65. package/src/MultiSelectMenu/MultiSelectMenuTypes.ts +9 -5
  66. package/src/MultiSelectMenu/__tests__/MultiSelectMenu.test.tsx +46 -60
  67. package/src/MultiSelectMenu/__tests__/MultiSelectMenu.typetest.tsx +29 -2
  68. package/src/NestedMenu/NestedMenu.feature +109 -0
  69. package/src/NestedMenu/NestedMenu.stories.tsx +157 -0
  70. package/src/NestedMenu/NestedMenu.tsx +102 -0
  71. package/src/NestedMenu/NestedMenuContent.tsx +71 -0
  72. package/src/NestedMenu/NestedMenuContext.tsx +56 -0
  73. package/src/NestedMenu/NestedMenuHeader.tsx +25 -0
  74. package/src/NestedMenu/NestedMenuItem.tsx +37 -0
  75. package/src/NestedMenu/NestedMenuTypes.ts +47 -0
  76. package/src/NestedMenu/__tests__/NestedMenu.test.tsx +31 -0
  77. package/src/NestedMenu/__tests__/NestedMenu.typetest.tsx +134 -0
  78. package/src/NestedMenu/index.ts +5 -0
  79. package/src/SingleSelectMenu/SingleSelectMenu.stories.tsx +227 -0
  80. package/src/SingleSelectMenu/SingleSelectMenu.tsx +29 -25
  81. package/src/SingleSelectMenu/SingleSelectMenuTypes.ts +9 -5
  82. package/src/SingleSelectMenu/__tests__/SingleSelectMenu.typetest.tsx +32 -2
  83. package/src/SubmenuItem/SubmenuItem.feature +82 -0
  84. package/src/SubmenuItem/SubmenuItem.stories.tsx +163 -0
  85. package/src/SubmenuItem/SubmenuItem.tsx +254 -0
  86. package/src/SubmenuItem/SubmenuItemTypes.ts +24 -0
  87. package/src/SubmenuItem/__tests__/SubmenuItem.test.tsx +3 -0
  88. package/src/SubmenuItem/__tests__/SubmenuItem.typetest.tsx +112 -0
  89. package/src/SubmenuItem/index.ts +2 -0
  90. package/src/__tests__/Menu.test.tsx +38 -0
  91. package/src/hooks/useDownshiftDefaults.tsx +107 -0
  92. package/src/hooks/useItemFiltering.tsx +66 -0
  93. package/src/hooks/useMenuChildren.tsx +279 -0
  94. package/src/index.ts +7 -1
  95. package/src/menuTestingUtils.tsx +21 -10
  96. package/src/reducers/nestedMenuStateReducer.tsx +23 -0
  97. package/src/reducers/useComboboxStateReducer.tsx +26 -8
  98. package/src/reducers/useSelectStateReducer.tsx +24 -6
  99. package/src/storybookUtilities/menu-storybook-components.tsx +5 -3
  100. package/src/types.ts +38 -5
  101. package/src/utils/downshiftDefaults.ts +9 -0
  102. package/src/utils/getMultiSelectOverrides.ts +21 -0
  103. package/src/utils/reduceReducers.ts +19 -0
  104. package/src/hooks/useItemsFromChildren.tsx +0 -131
  105. package/src/utils/itemToString.ts +0 -5
package/dist/index.js CHANGED
@@ -108,50 +108,85 @@ __export(index_exports, {
108
108
  AutocompleteInput: () => AutocompleteInput,
109
109
  INPUT_TYPES: () => INPUT_TYPES,
110
110
  MenuContent: () => MenuContent,
111
- MenuContext: () => MenuContext,
111
+ MenuContentContext: () => MenuContentContext,
112
+ MenuContentProvider: () => MenuContentProvider,
112
113
  MenuFooter: () => MenuFooter,
113
114
  MenuGroup: () => MenuGroup,
114
115
  MenuHeader: () => MenuHeader,
115
116
  MenuItem: () => MenuItem,
116
117
  MenuItemAction: () => MenuItemAction,
118
+ MenuItemActionLeft: () => MenuItemActionLeft,
119
+ MenuItemActionRight: () => MenuItemActionRight,
117
120
  MenuItemContainer: () => MenuItemContainer,
118
121
  MenuItemRow: () => MenuItemRow,
119
122
  MenuItemText: () => MenuItemText,
120
123
  MenuLabel: () => MenuLabel,
121
- MenuProvider: () => MenuProvider,
122
124
  MenuRoot: () => MenuRoot,
125
+ MenuSearchInput: () => MenuSearchInput,
126
+ MenuSearchTokenInput: () => MenuSearchTokenInput,
123
127
  MenuToggleButton: () => MenuToggleButton,
128
+ MenuToggleContext: () => MenuToggleContext,
129
+ MenuToggleProvider: () => MenuToggleProvider,
130
+ MenuTokenInput: () => MenuTokenInput,
124
131
  MultiSelectMenu: () => MultiSelectMenu,
132
+ NestedMenu: () => NestedMenu,
133
+ NestedMenuContent: () => NestedMenuContent,
134
+ NestedMenuContext: () => NestedMenuContext,
135
+ NestedMenuHeader: () => NestedMenuHeader,
136
+ NestedMenuItem: () => NestedMenuItem,
137
+ NestedMenuProvider: () => NestedMenuProvider,
125
138
  SingleSelectMenu: () => SingleSelectMenu,
126
139
  StyledMenuGroup: () => StyledMenuGroup,
127
140
  StyledMenuGroupUl: () => StyledMenuGroupUl,
128
141
  StyledMenuItem: () => StyledMenuItem,
129
142
  StyledTitle: () => StyledTitle,
130
- defaultUseSelectProps: () => defaultUseSelectProps,
131
- useItemsFromChildren: () => useItemsFromChildren,
143
+ SubmenuItem: () => SubmenuItem,
144
+ checkIfItemSelected: () => checkIfItemSelected,
145
+ defaultMenuContext: () => defaultMenuContext,
146
+ getChildrenFromMenuItems: () => getChildrenFromMenuItems,
147
+ getSelectedItemIds: () => getSelectedItemIds,
148
+ mapMenuItems: () => mapMenuItems,
132
149
  useMenu: () => useMenu,
133
- useMenuContext: () => useMenuContext,
134
- useSelectStateReducer: () => useSelectStateReducer
150
+ useMenuChildren: () => useMenuChildren,
151
+ useMenuContentContext: () => useMenuContentContext,
152
+ useMenuToggleContext: () => useMenuToggleContext,
153
+ useNestedMenuContext: () => useNestedMenuContext,
154
+ useSelectStateReducer: () => useSelectStateReducer,
155
+ useSelectStateReducerForMulti: () => useSelectStateReducerForMulti
135
156
  });
136
157
  module.exports = __toCommonJS(index_exports);
137
158
 
138
- // src/MenuItem/MenuItem.tsx
139
- var import_react3 = require("react");
140
-
141
159
  // src/MenuContext.tsx
142
- var import_react = require("react");
160
+ var import_react = __toESM(require("react"));
143
161
  var import_jsx_runtime = require("react/jsx-runtime");
144
162
  var defaultMenuContext = {
145
163
  items: [],
146
- itemsMap: {}
147
- };
164
+ itemsMap: {},
165
+ isItemSelected: () => false,
166
+ getInputComponentProps: () => ({})
167
+ };
168
+ var getSelectedItemIds = (selectedItems) => selectedItems?.reduce(
169
+ (selected, item) => ({ ...selected, [item.id]: true }),
170
+ {}
171
+ );
172
+ var checkIfItemSelected = ({
173
+ id,
174
+ selectedItem,
175
+ selectedItemIds
176
+ }) => selectedItemIds ? !!selectedItemIds[id] : selectedItem?.id === id;
148
177
  var useMenu = ({
149
178
  items = [],
150
179
  isListbox = false,
151
180
  isOpen = false,
152
181
  itemsMap: itemsMapFromProps,
182
+ selectedItemIds: selectedItemIdsFromProps,
183
+ selectedItem,
184
+ selectedItems,
185
+ getInputProps,
186
+ contentRef: contentRefFromProps,
153
187
  ...rest
154
188
  } = {}) => {
189
+ const contentRef = contentRefFromProps || import_react.default.createRef();
155
190
  const menuProps = (0, import_react.useMemo)(() => ({ ...rest }), [rest]);
156
191
  const itemsMap = (0, import_react.useMemo)(
157
192
  () => itemsMapFromProps || items.reduce((map, item) => {
@@ -162,27 +197,90 @@ var useMenu = ({
162
197
  }, {}),
163
198
  [items, itemsMapFromProps]
164
199
  );
200
+ const selectedItemIds = (0, import_react.useMemo)(
201
+ () => selectedItemIdsFromProps || getSelectedItemIds(selectedItems),
202
+ [selectedItems, selectedItemIdsFromProps]
203
+ );
204
+ const isItemSelected = import_react.default.useCallback(
205
+ (id) => checkIfItemSelected({ id, selectedItem, selectedItemIds }),
206
+ [selectedItem, selectedItemIds]
207
+ );
208
+ const getInputComponentProps = import_react.default.useCallback(
209
+ ({ inputProps, ...props }) => {
210
+ if (!getInputProps) return {};
211
+ const {
212
+ ["aria-activedescendant"]: activedescendant,
213
+ ["aria-autocomplete"]: autocomplete,
214
+ ["aria-controls"]: controls,
215
+ ["aria-expanded"]: expanded,
216
+ ["aria-labelledby"]: labelledby,
217
+ role,
218
+ autoComplete,
219
+ onClick,
220
+ value,
221
+ ...restProps
222
+ } = getInputProps(props);
223
+ return {
224
+ ...restProps,
225
+ inputProps: {
226
+ ["aria-activedescendant"]: activedescendant,
227
+ ["aria-autocomplete"]: autocomplete,
228
+ ["aria-controls"]: controls,
229
+ ["aria-expanded"]: expanded,
230
+ ["aria-labelledby"]: labelledby,
231
+ role,
232
+ autoComplete,
233
+ onClick,
234
+ value,
235
+ ...inputProps
236
+ }
237
+ };
238
+ },
239
+ [getInputProps]
240
+ );
165
241
  return {
166
242
  isOpen,
167
243
  isListbox,
168
244
  items,
169
245
  itemsMap,
246
+ selectedItem,
247
+ selectedItems,
248
+ selectedItemIds,
249
+ isItemSelected,
250
+ getInputProps,
251
+ getInputComponentProps,
252
+ contentRef,
170
253
  ...menuProps
171
254
  };
172
255
  };
173
- var MenuContext = (0, import_react.createContext)(defaultMenuContext);
174
- var MenuProvider = ({
256
+ var MenuToggleContext = (0, import_react.createContext)(defaultMenuContext);
257
+ var MenuToggleProvider = ({
258
+ children,
259
+ menuContext
260
+ }) => {
261
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuToggleContext.Provider, { value: { ...menuContext }, children });
262
+ };
263
+ var useMenuToggleContext = () => {
264
+ const menuContextValue = (0, import_react.useContext)(MenuToggleContext);
265
+ if (menuContextValue === null) {
266
+ throw new Error(
267
+ "useMenuToggleContext must be used within a <MenuToggleContext.Provider />"
268
+ );
269
+ }
270
+ return menuContextValue;
271
+ };
272
+ var MenuContentContext = (0, import_react.createContext)(defaultMenuContext);
273
+ var MenuContentProvider = ({
175
274
  children,
176
- menuProps
275
+ menuContext
177
276
  }) => {
178
- const filterContext = useMenu(menuProps);
179
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuContext.Provider, { value: { ...filterContext }, children });
277
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuContentContext.Provider, { value: { ...menuContext }, children });
180
278
  };
181
- var useMenuContext = () => {
182
- const menuContextValue = (0, import_react.useContext)(MenuContext);
279
+ var useMenuContentContext = () => {
280
+ const menuContextValue = (0, import_react.useContext)(MenuContentContext);
183
281
  if (menuContextValue === null) {
184
282
  throw new Error(
185
- "useMenuContext must be used within a <MenuContext.Provider />"
283
+ "useMenuContentContext must be used within a <MenuContentContext.Provider />"
186
284
  );
187
285
  }
188
286
  return menuContextValue;
@@ -1725,6 +1823,10 @@ var highlightedStyles = import_styled_components2.css`
1725
1823
  color: ${({ theme: theme2 }) => theme2.colors.text.body};
1726
1824
  text-decoration: none;
1727
1825
  `;
1826
+ var activeStyles = import_styled_components2.css`
1827
+ background-color: ${({ theme: theme2 }) => theme2.colors.listItem.background.active};
1828
+ color: ${({ theme: theme2 }) => theme2.colors.text.inverse};
1829
+ `;
1728
1830
  var MenuItemContainer = import_styled_components2.default.li`
1729
1831
  box-sizing: border-box;
1730
1832
  list-style-type: none;
@@ -1739,7 +1841,7 @@ var MenuItemContainer = import_styled_components2.default.li`
1739
1841
  margin-bottom: ${({ theme: theme2 }) => theme2.space[300]};
1740
1842
  }
1741
1843
  `;
1742
- var StyledMenuItem = import_styled_components2.default.div`
1844
+ var StyledMenuItem = import_styled_components2.default.button`
1743
1845
  display: block;
1744
1846
  box-sizing: border-box;
1745
1847
  width: 100%;
@@ -1778,10 +1880,12 @@ var StyledMenuItem = import_styled_components2.default.div`
1778
1880
  ${focusRing}
1779
1881
  }
1780
1882
 
1883
+ /* Active */
1884
+ ${({ $active }) => $active && activeStyles}
1885
+
1781
1886
  /* Pressed state*/
1782
1887
  &:active {
1783
- background-color: ${({ theme: theme2 }) => theme2.colors.listItem.background.active};
1784
- color: ${({ theme: theme2 }) => theme2.colors.text.inverse};
1888
+ ${activeStyles}
1785
1889
  }
1786
1890
 
1787
1891
  &[aria-disabled="true"] {
@@ -1802,12 +1906,17 @@ var MenuItemRow = import_styled_components2.default.div`
1802
1906
  pointer-events: none;
1803
1907
  `;
1804
1908
  var MenuItemAction = import_styled_components2.default.div`
1805
- margin-right: ${({ theme: theme2 }) => theme2.space[300]};
1806
1909
  display: flex;
1807
1910
  align-items: center;
1808
1911
  justify-content: center;
1809
1912
  flex-shrink: 0;
1810
1913
  `;
1914
+ var MenuItemActionLeft = (0, import_styled_components2.default)(MenuItemAction)`
1915
+ margin-right: ${({ theme: theme2 }) => theme2.space[300]};
1916
+ `;
1917
+ var MenuItemActionRight = (0, import_styled_components2.default)(MenuItemAction)`
1918
+ margin-left: ${({ theme: theme2 }) => theme2.space[300]};
1919
+ `;
1811
1920
  var MenuItemText = import_styled_components2.default.div`
1812
1921
  word-break: break-word;
1813
1922
  flex-grow: 1;
@@ -1838,6 +1947,7 @@ var SelectionIndicator = ({
1838
1947
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1839
1948
  import_seeds_react_checkbox2.Checkbox,
1840
1949
  {
1950
+ tabIndex: -1,
1841
1951
  onChange: () => {
1842
1952
  },
1843
1953
  checked: selected,
@@ -1849,6 +1959,7 @@ var SelectionIndicator = ({
1849
1959
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1850
1960
  import_seeds_react_switch.Switch,
1851
1961
  {
1962
+ tabIndex: -1,
1852
1963
  onClick: inputStub,
1853
1964
  checked: !!selected,
1854
1965
  "aria-labelledby": labeledBy,
@@ -1859,6 +1970,7 @@ var SelectionIndicator = ({
1859
1970
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1860
1971
  import_seeds_react_radio.Radio,
1861
1972
  {
1973
+ tabIndex: -1,
1862
1974
  checked: selected,
1863
1975
  id: `MenuItem-${inputType}-${id}`,
1864
1976
  name: `MenuItem-${inputType}`,
@@ -1882,9 +1994,9 @@ var useOptionProps = ({
1882
1994
  inputLabelId,
1883
1995
  ...props
1884
1996
  }) => {
1885
- const { selectedItem, selectedItems, isListbox } = (0, import_react2.useContext)(MenuContext);
1997
+ const { selectedItem, selectedItems, isListbox, isItemSelected } = useMenuContentContext();
1886
1998
  const selected = (0, import_react2.useMemo)(
1887
- () => selectedItem?.id === id || !!selectedItems?.find((item) => item?.id === id),
1999
+ () => isItemSelected(id),
1888
2000
  [selectedItem, selectedItems]
1889
2001
  );
1890
2002
  const label = inputLabelId || `menu-item-child-${id}`;
@@ -1892,7 +2004,7 @@ var useOptionProps = ({
1892
2004
  active: selected,
1893
2005
  ["aria-selected"]: selected,
1894
2006
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(MenuItemRow, { children: [
1895
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MenuItemAction, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2007
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MenuItemActionLeft, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1896
2008
  SelectionIndicator,
1897
2009
  {
1898
2010
  id,
@@ -1915,12 +2027,19 @@ var MenuItem = ({
1915
2027
  onClick,
1916
2028
  onKeyDown,
1917
2029
  disabled: disabled2 = false,
1918
- ref,
2030
+ active,
2031
+ innerRef,
1919
2032
  href,
1920
2033
  color: color2,
1921
2034
  ...props
1922
2035
  }) => {
1923
- const { getItemProps, itemsMap, highlightedIndex, isListbox } = useMenuContext();
2036
+ const {
2037
+ getItemProps,
2038
+ itemsMap,
2039
+ highlightedIndex,
2040
+ isListbox,
2041
+ hiddenItemsMap = {}
2042
+ } = useMenuContentContext();
1924
2043
  const { ...optionProps } = useOptionProps({
1925
2044
  id,
1926
2045
  children,
@@ -1928,23 +2047,26 @@ var MenuItem = ({
1928
2047
  });
1929
2048
  const item = itemsMap[id] || { index: 0, id };
1930
2049
  const highlighted = highlightedIndex === item?.index;
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)(
2050
+ return hiddenItemsMap[item.id] ? /* @__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)(
1932
2051
  StyledMenuItem,
1933
2052
  {
1934
2053
  id,
1935
2054
  $highlighted: highlighted,
2055
+ $active: active,
1936
2056
  ...getItemProps?.({
1937
2057
  ...isListbox ? {} : { role: "menuitem" },
1938
2058
  item,
1939
2059
  index: item.index,
1940
- // This prop no longer supported in downshift
2060
+ // The disabled prop no longer supported in downshift. Use isItemDisabled instead.
1941
2061
  // disabled,
1942
2062
  onClick,
1943
- onKeyDown
2063
+ onKeyDown,
2064
+ ref: innerRef
1944
2065
  }),
1945
2066
  as: isListbox ? void 0 : href ? "a" : "button",
1946
2067
  href,
1947
2068
  children,
2069
+ tabIndex: -1,
1948
2070
  ...optionProps,
1949
2071
  ...props
1950
2072
  }
@@ -1960,7 +2082,7 @@ var INPUT_TYPES = {
1960
2082
  };
1961
2083
 
1962
2084
  // src/MenuHeader/MenuHeader.tsx
1963
- var import_react4 = require("react");
2085
+ var import_react3 = require("react");
1964
2086
 
1965
2087
  // src/MenuHeader/styles.tsx
1966
2088
  var import_styled_components4 = __toESM(require("styled-components"));
@@ -1987,14 +2109,13 @@ var MenuTitleText = import_styled_components4.default.h3`
1987
2109
  color: ${({ theme: theme2 }) => theme2.colors.text.headline};
1988
2110
  font-weight: ${({ theme: theme2 }) => theme2.fontWeights.bold};
1989
2111
  margin: 0px;
1990
- flex-grow: 2;
1991
- justify-self: start;
2112
+ flex-grow: 1;
1992
2113
 
1993
2114
  ${({ theme: theme2 }) => theme2.typography[200]}
1994
2115
 
1995
2116
  ${({ $leftAction, theme: theme2 }) => $leftAction && `
1996
- padding-left: ${theme2.space[350]};
1997
- `}
2117
+ padding-left: ${theme2.space[350]};
2118
+ `}
1998
2119
  `;
1999
2120
  var MenuChildrenContainer = import_styled_components4.default.div`
2000
2121
  grid-column: 1 / -1;
@@ -2002,19 +2123,24 @@ var MenuChildrenContainer = import_styled_components4.default.div`
2002
2123
  `;
2003
2124
  var MenuHeaderFeatures = import_styled_components4.default.div`
2004
2125
  display: flex;
2126
+ align-items: center;
2127
+ justify-content: space-between;
2128
+ width: 100%;
2005
2129
 
2006
- > a {
2007
- white-space: nowrap;
2008
- }
2009
-
2010
- &:first-child {
2011
- flex-grow: 1;
2012
- justify-self: start;
2130
+ .right-action {
2131
+ margin-left: auto; /* Pushes the right action to the right */
2132
+ display: flex;
2133
+ justify-content: flex-end;
2134
+ flex-shrink: 0; /* Prevents it from shrinking */
2135
+ max-width: 40%; /* Prevents it from taking too much space */
2136
+ text-align: right;
2013
2137
  }
2014
2138
 
2015
- &:last-child {
2016
- flex-grow: 1;
2017
- justify-self: end;
2139
+ > a,
2140
+ > button {
2141
+ display: flex;
2142
+ align-items: center;
2143
+ word-break: break-word;
2018
2144
  }
2019
2145
  `;
2020
2146
 
@@ -2031,7 +2157,7 @@ var MenuHeader = ({
2031
2157
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuHeaderFeatures, { $leftAction: !!leftAction, children: [
2032
2158
  leftAction && leftAction,
2033
2159
  title && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MenuTitleText, { $leftAction: !!leftAction, children: title }),
2034
- rightAction && rightAction
2160
+ rightAction && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "right-action", children: rightAction })
2035
2161
  ] }),
2036
2162
  children && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MenuChildrenContainer, { children })
2037
2163
  ] }) });
@@ -2039,31 +2165,222 @@ var MenuHeader = ({
2039
2165
 
2040
2166
  // src/MenuContent/styles.tsx
2041
2167
  var import_styled_components5 = __toESM(require("styled-components"));
2042
- var import_react5 = require("motion/react");
2043
- var StyledMenuContent = (0, import_styled_components5.default)(import_react5.motion.ul)`
2168
+ var import_react4 = require("motion/react");
2169
+ var StyledMenuContent = (0, import_styled_components5.default)(import_react4.motion.ul)`
2044
2170
  margin: 0;
2045
2171
  padding: 0;
2046
2172
  `;
2047
2173
 
2048
- // src/MenuContent/MenuContent.tsx
2174
+ // src/hooks/useMenuChildren.tsx
2175
+ var import_react5 = __toESM(require("react"));
2049
2176
  var import_jsx_runtime5 = require("react/jsx-runtime");
2177
+ var walkAllChildren = (children, callback) => {
2178
+ const walk = (element, parents2) => {
2179
+ if (element === null || element === void 0) return;
2180
+ callback(element, parents2);
2181
+ const newParents = [...parents2, element];
2182
+ const children2 = element.props?.children;
2183
+ import_react5.default.Children.toArray(children2).forEach((child) => {
2184
+ walk(child, newParents);
2185
+ });
2186
+ };
2187
+ const parents = [];
2188
+ import_react5.default.Children.toArray(children).forEach((child) => {
2189
+ walk(child, parents);
2190
+ });
2191
+ };
2192
+ var getComponentName = (element) => {
2193
+ if (element && typeof element === "object" && "type" in element && typeof element.type !== "string" && typeof element.type.name === "string") {
2194
+ return element.type.name;
2195
+ }
2196
+ };
2197
+ var addMenuItem = ({
2198
+ itemProps,
2199
+ allMenuItems,
2200
+ menuItemsMap
2201
+ }) => {
2202
+ const item = {
2203
+ ...itemProps,
2204
+ index: allMenuItems.length
2205
+ };
2206
+ allMenuItems.push(item);
2207
+ menuItemsMap[`${item.id}`] = item;
2208
+ };
2209
+ var addItemsFromGroup = ({
2210
+ groupElement: menuGroup,
2211
+ allMenuItems,
2212
+ menuItemsMap
2213
+ }) => {
2214
+ const menuItems = menuGroup.props.menuItems;
2215
+ if (menuItems) {
2216
+ menuItems.forEach((menuItem) => {
2217
+ addMenuItem({
2218
+ itemProps: {
2219
+ id: menuItem.id,
2220
+ disabled: menuItem.disabled,
2221
+ menuItemProps: menuItem,
2222
+ menuGroupProps: menuGroup.props
2223
+ },
2224
+ allMenuItems,
2225
+ menuItemsMap
2226
+ });
2227
+ });
2228
+ } else if (menuGroup.props.children) {
2229
+ let children = menuGroup.props.children;
2230
+ if (!Array.isArray(children)) {
2231
+ children = [children];
2232
+ }
2233
+ children.forEach((menuItem) => {
2234
+ addMenuItem({
2235
+ itemProps: {
2236
+ id: menuItem.props.id,
2237
+ disabled: menuItem.props.disabled,
2238
+ menuItemProps: menuItem.props,
2239
+ menuGroupProps: menuGroup.props
2240
+ },
2241
+ allMenuItems,
2242
+ menuItemsMap
2243
+ });
2244
+ });
2245
+ }
2246
+ };
2247
+ var addItemsFromContent = ({
2248
+ contentElement: menuContent,
2249
+ allMenuItems,
2250
+ menuItemsMap
2251
+ }) => {
2252
+ if (!("menuItems" in menuContent.props)) return;
2253
+ if (menuContent.props.menuItems) {
2254
+ menuContent.props.menuItems.forEach((menuItem) => {
2255
+ addMenuItem({
2256
+ itemProps: {
2257
+ id: menuItem.id,
2258
+ disabled: menuItem.disabled,
2259
+ menuItemProps: menuItem
2260
+ },
2261
+ allMenuItems,
2262
+ menuItemsMap
2263
+ });
2264
+ });
2265
+ }
2266
+ };
2267
+ var setMenuItemsFromChildren = ({
2268
+ children,
2269
+ allMenuItems,
2270
+ menuItemsMap
2271
+ }) => {
2272
+ walkAllChildren(children, (element) => {
2273
+ switch (getComponentName(element)) {
2274
+ case "MenuItem":
2275
+ case "SubmenuItem":
2276
+ case "NestedMenuItem":
2277
+ const menuItem = element;
2278
+ if (menuItemsMap[`${menuItem.props.id}`]) return;
2279
+ addMenuItem({
2280
+ itemProps: {
2281
+ id: menuItem.props.id,
2282
+ disabled: menuItem.props.disabled,
2283
+ menuItemProps: menuItem.props
2284
+ },
2285
+ allMenuItems,
2286
+ menuItemsMap
2287
+ });
2288
+ break;
2289
+ case "MenuGroup":
2290
+ addItemsFromGroup({
2291
+ // Cast element to the TypeMenuGroupElement since we know it's a group and is needed for addItemsFromGroup.
2292
+ groupElement: element,
2293
+ allMenuItems,
2294
+ menuItemsMap
2295
+ });
2296
+ break;
2297
+ case "MenuContent":
2298
+ case "NestedMenuContent":
2299
+ addItemsFromContent({
2300
+ // Cast element to the TypeMenuContentElement since we know it's a content and is needed for addItemsFromContent.
2301
+ contentElement: element,
2302
+ allMenuItems,
2303
+ menuItemsMap
2304
+ });
2305
+ break;
2306
+ default:
2307
+ break;
2308
+ }
2309
+ });
2310
+ };
2311
+ var mapMenuItems = ({
2312
+ menuItems,
2313
+ MenuItemComponent = MenuItem
2314
+ }) => {
2315
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: menuItems.map((menuItemProps) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MenuItemComponent, { ...menuItemProps }, menuItemProps.id)) });
2316
+ };
2317
+ var getChildrenFromMenuItems = ({
2318
+ menuItems,
2319
+ MenuItemComponent
2320
+ }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MenuContent, { menuItems, MenuItemComponent });
2321
+ var useMenuChildren = ({
2322
+ children: childrenProp,
2323
+ menuItems,
2324
+ MenuItemComponent
2325
+ }) => {
2326
+ const { allMenuItems, menuItemsMap, children } = (0, import_react5.useMemo)(() => {
2327
+ let children2 = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, {});
2328
+ const menuItemsMap2 = {};
2329
+ const allMenuItems2 = [];
2330
+ if (menuItems && menuItems.length) {
2331
+ menuItems.forEach((menuItem) => {
2332
+ addMenuItem({ itemProps: menuItem, allMenuItems: allMenuItems2, menuItemsMap: menuItemsMap2 });
2333
+ });
2334
+ children2 = getChildrenFromMenuItems({ menuItems, MenuItemComponent });
2335
+ } else if (childrenProp) {
2336
+ children2 = childrenProp;
2337
+ setMenuItemsFromChildren({
2338
+ children: childrenProp,
2339
+ allMenuItems: allMenuItems2,
2340
+ menuItemsMap: menuItemsMap2
2341
+ });
2342
+ }
2343
+ return { allMenuItems: allMenuItems2, menuItemsMap: menuItemsMap2, children: children2 };
2344
+ }, [childrenProp, menuItems, MenuItemComponent]);
2345
+ return { allMenuItems, menuItemsMap, children };
2346
+ };
2347
+
2348
+ // src/MenuContent/MenuContent.tsx
2349
+ var import_react6 = require("react");
2350
+ var import_jsx_runtime6 = require("react/jsx-runtime");
2050
2351
  var MenuContent = ({
2051
2352
  id = "menu_content",
2052
- children,
2353
+ children: childrenProp,
2354
+ menuItems,
2355
+ MenuItemComponent,
2356
+ onKeyDown,
2357
+ innerRef = null,
2053
2358
  ...rest
2054
2359
  }) => {
2055
- const { getToggleButtonProps, getMenuProps, isListbox } = useMenuContext();
2056
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2360
+ const { getToggleButtonProps, getMenuProps, isListbox } = useMenuContentContext();
2361
+ const toggleButtonProps = getToggleButtonProps?.();
2362
+ const children = childrenProp || !menuItems || !menuItems.length ? childrenProp : mapMenuItems({ menuItems, MenuItemComponent });
2363
+ if (!children) {
2364
+ return null;
2365
+ }
2366
+ const handleKeyDown = (0, import_react6.useCallback)(
2367
+ (e) => {
2368
+ toggleButtonProps?.["onKeyDown"]?.(e);
2369
+ onKeyDown?.(e);
2370
+ },
2371
+ [onKeyDown, toggleButtonProps?.["onKeyDown"]]
2372
+ );
2373
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2057
2374
  StyledMenuContent,
2058
2375
  {
2059
2376
  autoFocus: true,
2060
2377
  id,
2061
2378
  tabIndex: 0,
2062
- onKeyDown: getToggleButtonProps?.()["onKeyDown"] || void 0,
2063
- "aria-activedescendant": getToggleButtonProps?.()["aria-activedescendant"],
2379
+ onKeyDown: handleKeyDown,
2380
+ "aria-activedescendant": toggleButtonProps?.["aria-activedescendant"],
2064
2381
  ...getMenuProps?.(
2065
2382
  {
2066
- ...isListbox ? {} : { role: "menu" }
2383
+ ...isListbox ? { ref: innerRef } : { ref: innerRef, role: "menu" }
2067
2384
  },
2068
2385
  // Suppress ref error for now
2069
2386
  { suppressRefError: true }
@@ -2075,7 +2392,7 @@ var MenuContent = ({
2075
2392
  };
2076
2393
 
2077
2394
  // src/MenuFooter/MenuFooter.tsx
2078
- var import_react6 = require("react");
2395
+ var import_react7 = require("react");
2079
2396
 
2080
2397
  // src/MenuFooter/styles.tsx
2081
2398
  var import_styled_components6 = __toESM(require("styled-components"));
@@ -2086,24 +2403,24 @@ var StyledMenuFooterBox = (0, import_styled_components6.default)(import_seeds_re
2086
2403
  `;
2087
2404
 
2088
2405
  // src/MenuFooter/MenuFooter.tsx
2089
- var import_jsx_runtime6 = require("react/jsx-runtime");
2406
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2090
2407
  var MenuFooter = ({ children, ...rest }) => {
2091
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StyledMenuFooterBox, { ...rest, children });
2408
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StyledMenuFooterBox, { ...rest, children });
2092
2409
  };
2093
2410
 
2094
2411
  // src/MenuGroup/MenuGroup.tsx
2095
- var import_react9 = require("react");
2412
+ var import_react10 = require("react");
2096
2413
 
2097
2414
  // src/MenuGroup/styles.tsx
2098
2415
  var import_styled_components9 = __toESM(require("styled-components"));
2099
2416
 
2100
2417
  // ../seeds-react-text/dist/esm/index.js
2101
- var import_react7 = require("react");
2418
+ var import_react8 = require("react");
2102
2419
  var import_styled_components7 = __toESM(require("styled-components"));
2103
2420
  var import_styled_components8 = __toESM(require("styled-components"));
2104
2421
  var import_seeds_react_system_props = require("@sproutsocial/seeds-react-system-props");
2105
- var import_jsx_runtime7 = require("react/jsx-runtime");
2106
- var import_react8 = require("react");
2422
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2423
+ var import_react9 = require("react");
2107
2424
  var Container = import_styled_components8.default.span`
2108
2425
  margin: 0;
2109
2426
  padding-left: 0;
@@ -2163,7 +2480,7 @@ var SmallBodyCopy = (0, import_styled_components7.default)(styles_default)`
2163
2480
  `;
2164
2481
  var Text = ({ fontSize: fontSize2, children, qa, color: color2, ...rest }) => {
2165
2482
  const qaText = typeof children === "string" ? children : void 0;
2166
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2483
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2167
2484
  styles_default,
2168
2485
  {
2169
2486
  typeScale: fontSize2,
@@ -2178,7 +2495,7 @@ var Text = ({ fontSize: fontSize2, children, qa, color: color2, ...rest }) => {
2178
2495
  var withTextLogic = (Component) => {
2179
2496
  return ({ children, ...props }) => {
2180
2497
  const qaText = typeof children === "string" ? children : void 0;
2181
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Component, { "data-qa-text": qaText, ...props, children });
2498
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Component, { "data-qa-text": qaText, ...props, children });
2182
2499
  };
2183
2500
  };
2184
2501
  var HeadlineWithLogic = withTextLogic(Headline);
@@ -2223,6 +2540,7 @@ var StyledMenuGroup = import_styled_components9.default.li`
2223
2540
  ${space}
2224
2541
  `;
2225
2542
  var StyledTitle = (0, import_styled_components9.default)(index_default.SmallSubHeadline)`
2543
+ font-size: ${({ theme: theme2 }) => theme2.typography[200].fontSize};
2226
2544
  margin: ${({ theme: theme2 }) => theme2.space[400]} ${({ theme: theme2 }) => theme2.space[400]}
2227
2545
  0px ${({ theme: theme2 }) => theme2.space[400]};
2228
2546
  `;
@@ -2232,7 +2550,7 @@ var StyledMenuGroupUl = import_styled_components9.default.ul`
2232
2550
  `;
2233
2551
 
2234
2552
  // src/MenuGroup/MenuGroup.tsx
2235
- var import_jsx_runtime8 = require("react/jsx-runtime");
2553
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2236
2554
  var MenuGroup = ({
2237
2555
  titleAs = "h3",
2238
2556
  children: childrenProp,
@@ -2240,16 +2558,16 @@ var MenuGroup = ({
2240
2558
  color: color2,
2241
2559
  isSingleSelect,
2242
2560
  id,
2243
- items,
2244
- MenuItemComponent = MenuItem,
2561
+ menuItems,
2562
+ MenuItemComponent,
2245
2563
  ...rest
2246
2564
  }) => {
2247
2565
  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));
2566
+ const children = childrenProp || !menuItems || !menuItems.length ? childrenProp : mapMenuItems({ menuItems, MenuItemComponent });
2249
2567
  if (!children) {
2250
2568
  return null;
2251
2569
  }
2252
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2570
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2253
2571
  StyledMenuGroup,
2254
2572
  {
2255
2573
  role: "group",
@@ -2259,18 +2577,18 @@ var MenuGroup = ({
2259
2577
  color: color2,
2260
2578
  ...rest,
2261
2579
  children: [
2262
- title && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StyledTitle, { role: "heading", as: titleAs, id: titleId, children: title }),
2263
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StyledMenuGroupUl, { children })
2580
+ title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StyledTitle, { role: "heading", as: titleAs, id: titleId, children: title }),
2581
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StyledMenuGroupUl, { children })
2264
2582
  ]
2265
2583
  }
2266
2584
  );
2267
2585
  };
2268
2586
 
2269
2587
  // src/MenuRoot/MenuRoot.tsx
2270
- var import_react10 = require("react");
2588
+ var import_react11 = require("react");
2271
2589
  var import_styled_components10 = __toESM(require("styled-components"));
2272
2590
  var import_seeds_react_popout = require("@sproutsocial/seeds-react-popout");
2273
- var import_jsx_runtime9 = require("react/jsx-runtime");
2591
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2274
2592
  var CustomPopoutContent = (0, import_styled_components10.default)(import_seeds_react_popout.Popout.Content)`
2275
2593
  padding: 0;
2276
2594
  margin-left: 0;
@@ -2279,24 +2597,26 @@ var CustomPopoutContent = (0, import_styled_components10.default)(import_seeds_r
2279
2597
  var MenuRoot = ({
2280
2598
  children,
2281
2599
  menuToggleElement,
2282
- popoutProps: { focusLockProps, ...popoutProps } = {},
2600
+ popoutProps: { placement = "bottom", focusLockProps, ...popoutProps } = {},
2283
2601
  width: width2 = "300px",
2284
2602
  ...contextProps
2285
2603
  }) => {
2286
2604
  const { isOpen, openMenu, closeMenu } = contextProps;
2287
- const setIsOpen = (0, import_react10.useCallback)(
2605
+ const setIsOpen = (0, import_react11.useCallback)(
2288
2606
  (newIsOpen) => {
2289
2607
  newIsOpen ? openMenu?.() : closeMenu?.();
2290
2608
  },
2291
2609
  [openMenu, closeMenu]
2292
2610
  );
2293
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MenuProvider, { menuProps: contextProps, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2611
+ const menuContext = useMenu(contextProps);
2612
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2294
2613
  import_seeds_react_popout.Popout,
2295
2614
  {
2296
2615
  menuPopout: true,
2616
+ placement,
2297
2617
  isOpen: !!isOpen,
2298
2618
  setIsOpen,
2299
- content: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CustomPopoutContent, { width: width2, children }),
2619
+ content: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuContentProvider, { menuContext, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CustomPopoutContent, { width: width2, children }) }),
2300
2620
  focusLockProps: {
2301
2621
  // correct jerking motion when scrolling while the Popout is open
2302
2622
  // returnFocus: false,
@@ -2305,37 +2625,38 @@ var MenuRoot = ({
2305
2625
  },
2306
2626
  disableWrapperAria: true,
2307
2627
  ...popoutProps,
2308
- children: menuToggleElement
2628
+ children: (toggleProps) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuToggleProvider, { menuContext: { ...menuContext, ...toggleProps }, children: menuToggleElement })
2309
2629
  }
2310
- ) });
2630
+ );
2311
2631
  };
2312
2632
 
2313
2633
  // src/MenuLabel.tsx
2314
- var import_react11 = require("react");
2634
+ var import_react12 = require("react");
2315
2635
  var import_seeds_react_label = require("@sproutsocial/seeds-react-label");
2316
- var import_jsx_runtime10 = require("react/jsx-runtime");
2636
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2317
2637
  var MenuLabel = ({ children, ...rest }) => {
2318
- const { getLabelProps } = useMenuContext();
2319
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_seeds_react_label.Label, { htmlFor: "fallback_menu_label", ...getLabelProps?.(), ...rest, children });
2638
+ const { getLabelProps } = useMenuToggleContext();
2639
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_seeds_react_label.Label, { htmlFor: "fallback_menu_label", ...getLabelProps?.(), ...rest, children });
2320
2640
  };
2321
2641
 
2322
- // src/MenuToggleButton.tsx
2323
- var import_react12 = require("react");
2642
+ // src/MenuToggleButton/MenuToggleButton.tsx
2643
+ var import_react13 = require("react");
2324
2644
  var import_seeds_react_button = require("@sproutsocial/seeds-react-button");
2325
- var import_jsx_runtime11 = require("react/jsx-runtime");
2645
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2326
2646
  var MenuToggleButton = ({
2327
2647
  children,
2328
2648
  ...rest
2329
2649
  }) => {
2330
- const { getToggleButtonProps, isListbox, getDropdownProps } = (0, import_react12.useContext)(MenuContext);
2331
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2650
+ const { getToggleButtonProps, isListbox, getDropdownProps, ref, ariaProps } = useMenuToggleContext();
2651
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2332
2652
  import_seeds_react_button.Button,
2333
2653
  {
2334
2654
  appearance: "secondary",
2335
2655
  ...getToggleButtonProps?.({
2336
2656
  // Decide if we want the preventKeyAction stuff. Maybe create a prop to allow for this to be overriden.
2337
- ...getDropdownProps?.({ preventKeyAction: true }),
2657
+ ...getDropdownProps?.({ ref, preventKeyAction: true }) || { ref },
2338
2658
  refKey: "innerRef",
2659
+ ...ariaProps,
2339
2660
  ...isListbox ? {} : { role: "button", "aria-haspopup": "menu" }
2340
2661
  }),
2341
2662
  ...rest,
@@ -2344,192 +2665,654 @@ var MenuToggleButton = ({
2344
2665
  );
2345
2666
  };
2346
2667
 
2347
- // src/ActionMenu/ActionMenu.tsx
2668
+ // src/MenuSearchInput/MenuSearchInput.tsx
2669
+ var import_react15 = __toESM(require("react"));
2670
+ var import_seeds_react_input = require("@sproutsocial/seeds-react-input");
2671
+
2672
+ // src/hooks/useItemFiltering.tsx
2348
2673
  var import_react14 = __toESM(require("react"));
2349
- var import_downshift2 = require("downshift");
2350
2674
 
2351
- // src/hooks/useItemsFromChildren.tsx
2352
- var import_react13 = __toESM(require("react"));
2353
- var walkAllChildren = (children, callback) => {
2354
- const walk = (element, parents2) => {
2355
- if (element === null || element === void 0) return;
2356
- callback(element, parents2);
2357
- const newParents = [...parents2, element];
2358
- const children2 = element.props?.children;
2359
- import_react13.default.Children.toArray(children2).forEach((child) => {
2360
- walk(child, newParents);
2361
- });
2362
- };
2363
- const parents = [];
2364
- import_react13.default.Children.toArray(children).forEach((child) => {
2365
- walk(child, parents);
2366
- });
2367
- };
2368
- var checkIfIsElement = (element, name) => {
2369
- return !!(element && typeof element === "object" && "type" in element && typeof element.type !== "string" && typeof element.type.name === "string" && element.type.name === name);
2370
- };
2371
- var getAllMenuItems = (children) => {
2372
- const orderedElements = [];
2373
- walkAllChildren(children, (element) => {
2374
- if (checkIfIsElement(element, "MenuItem")) {
2375
- orderedElements.push({
2376
- type: "item",
2377
- element
2378
- });
2379
- } else if (checkIfIsElement(element, "MenuGroup")) {
2380
- orderedElements.push({
2381
- type: "group",
2382
- element
2383
- });
2384
- }
2385
- });
2386
- return { orderedElements };
2675
+ // src/utils/downshiftDefaults.ts
2676
+ var itemToString = (item) => {
2677
+ return item ? item.id : "";
2387
2678
  };
2388
- var useItemsFromChildren = ({
2389
- children
2390
- }) => {
2391
- const { allMenuItems, menuItemsMap } = (0, import_react13.useMemo)(() => {
2392
- const { orderedElements } = getAllMenuItems(children);
2393
- const menuItemsMap2 = {};
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;
2432
- const item = {
2433
- id: menuItem.props.id,
2434
- index: index++,
2435
- disabled: menuItem.props.disabled,
2436
- menuItemProps: menuItem.props
2437
- };
2438
- allMenuItems2.push(item);
2439
- menuItemsMap2[`${item.id}`] = item;
2440
- }
2441
- });
2442
- return { allMenuItems: allMenuItems2, menuItemsMap: menuItemsMap2 };
2443
- }, [children]);
2444
- return { allMenuItems, menuItemsMap };
2679
+ var itemToKey = (item) => {
2680
+ return item ? item.id : "";
2445
2681
  };
2446
2682
 
2447
- // src/reducers/useSelectStateReducer.tsx
2448
- var import_downshift = require("downshift");
2449
- var useSelectStateReducer = (state, actionAndChanges) => {
2450
- const { type, changes } = actionAndChanges;
2451
- switch (type) {
2452
- /** If downshift is blurred by tabbing within the menu, stay open */
2453
- case import_downshift.useSelect.stateChangeTypes.ToggleButtonBlur:
2454
- return {
2455
- ...changes,
2456
- // keep menu open on blur
2457
- isOpen: true
2458
- };
2459
- /** Return standard change payload */
2460
- default:
2461
- return changes;
2462
- }
2463
- };
2464
- var defaultUseSelectProps = {
2465
- stateReducer: useSelectStateReducer,
2466
- isItemDisabled: (item) => !!item.disabled
2683
+ // src/hooks/useItemFiltering.tsx
2684
+ var getDefaultGetIsItemVisible = (itemToString2 = itemToString) => (item, inputValue) => itemToString2(item).toLowerCase().includes(inputValue.toLowerCase());
2685
+ var defaultGetShouldFilter = ({ inputValue }) => Boolean(inputValue);
2686
+ var useItemFiltering = ({
2687
+ allMenuItems,
2688
+ itemToString: itemToString2,
2689
+ getIsItemVisible = getDefaultGetIsItemVisible(itemToString2),
2690
+ getShouldFilter = defaultGetShouldFilter,
2691
+ setHiddenItemsMap: setHiddenItemsMapProp
2692
+ }) => {
2693
+ const [hiddenItemsMap, setHiddenItemsMap] = import_react14.default.useState({});
2694
+ const updateFilteredItems = import_react14.default.useCallback(
2695
+ ({ inputValue }) => {
2696
+ const newHiddenItems = getShouldFilter({ inputValue }) ? allMenuItems.reduce((map, item) => {
2697
+ const isItemVisible = getIsItemVisible(item, inputValue);
2698
+ return isItemVisible ? map : { ...map, [item.id]: true };
2699
+ }, {}) : {};
2700
+ setHiddenItemsMap(newHiddenItems);
2701
+ setHiddenItemsMapProp?.(newHiddenItems);
2702
+ },
2703
+ [allMenuItems, getIsItemVisible, getShouldFilter]
2704
+ );
2705
+ return {
2706
+ getIsItemVisible,
2707
+ updateFilteredItems
2708
+ };
2467
2709
  };
2468
2710
 
2469
- // src/utils/itemToString.ts
2470
- var itemToString = (item) => {
2471
- return item ? item.id : "";
2711
+ // src/MenuSearchInput/MenuSearchInput.tsx
2712
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2713
+ var MenuSearchInput = ({
2714
+ getIsItemVisible,
2715
+ ...inputProps
2716
+ }) => {
2717
+ const {
2718
+ items,
2719
+ itemToString: itemToString2,
2720
+ setHiddenItemsMap,
2721
+ isOpen,
2722
+ getToggleButtonProps
2723
+ } = useMenuContentContext();
2724
+ const { updateFilteredItems } = useItemFiltering({
2725
+ allMenuItems: items,
2726
+ itemToString: itemToString2,
2727
+ getIsItemVisible,
2728
+ setHiddenItemsMap
2729
+ });
2730
+ import_react15.default.useEffect(() => {
2731
+ updateFilteredItems({ inputValue: inputProps.value || "" });
2732
+ }, [isOpen, inputProps.value]);
2733
+ const handleKeyDown = import_react15.default.useCallback(
2734
+ (e) => {
2735
+ if (e.key === " ") return;
2736
+ getToggleButtonProps?.()["onKeyDown"](e);
2737
+ },
2738
+ [getToggleButtonProps]
2739
+ );
2740
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2741
+ import_seeds_react_input.Input,
2742
+ {
2743
+ onChange: (e, value) => {
2744
+ updateFilteredItems({ inputValue: value });
2745
+ },
2746
+ onKeyDown: handleKeyDown,
2747
+ autoComplete: false,
2748
+ ...inputProps
2749
+ }
2750
+ );
2472
2751
  };
2473
2752
 
2474
- // src/ActionMenu/ActionMenu.tsx
2475
- var import_jsx_runtime12 = require("react/jsx-runtime");
2476
- var handleStateChange = (changes, currentSelectedItem) => {
2477
- if (!(changes.type === import_downshift2.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter || changes.type === import_downshift2.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton)) {
2478
- return;
2479
- }
2480
- const selectedItem = changes.selectedItem || currentSelectedItem;
2481
- if (!selectedItem) return;
2482
- if (selectedItem.disabled) {
2483
- return;
2753
+ // src/MenuTokenInput.tsx
2754
+ var import_react16 = __toESM(require("react"));
2755
+ var import_styled_components11 = __toESM(require("styled-components"));
2756
+ var import_seeds_react_token_input = require("@sproutsocial/seeds-react-token-input");
2757
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2758
+ var StyledTokenInputWrapper = import_styled_components11.default.div`
2759
+ > div {
2760
+ padding: 4px;
2484
2761
  }
2485
- const isEnterKeyDown = changes.type === import_downshift2.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter;
2486
- const selectedItemProps = selectedItem.menuItemProps;
2487
- if (selectedItemProps?.onClick) {
2488
- const syntheticKeyboardEvent = new KeyboardEvent("keydown", {
2489
- key: isEnterKeyDown ? "Enter" : " ",
2490
- code: isEnterKeyDown ? "Enter" : "Space",
2491
- bubbles: true,
2492
- cancelable: true,
2493
- view: window
2494
- });
2495
- selectedItemProps?.onClick?.(
2496
- syntheticKeyboardEvent
2497
- );
2762
+
2763
+ input {
2764
+ line-height: 21px;
2765
+ margin: 0;
2766
+ padding: 2px 4px;
2498
2767
  }
2499
- if (selectedItemProps?.href) {
2500
- if (selectedItemProps.target) {
2501
- window.open(selectedItemProps.href, selectedItemProps.target);
2502
- } else {
2503
- window.location.href = selectedItemProps?.href;
2504
- }
2768
+
2769
+ .TokenInput-token button {
2770
+ margin-top: 0;
2771
+ padding: 1px 4px;
2505
2772
  }
2506
- };
2507
- var ActionMenu = ({
2508
- children,
2509
- stateReducer: externalStateReducer,
2510
- ...useSelectProps
2773
+ `;
2774
+ var MenuTokenInput = ({
2775
+ inputProps = {},
2776
+ getTokenProps,
2777
+ onKeyDown,
2778
+ MenuContext = MenuToggleContext,
2779
+ ...tokenInputProps
2780
+ }) => {
2781
+ const {
2782
+ itemToString: itemToString2,
2783
+ getSelectedItemProps,
2784
+ removeSelectedItem,
2785
+ setActiveIndex,
2786
+ selectedItems = []
2787
+ } = import_react16.default.useContext(MenuContext);
2788
+ const removeToken = (tokenId) => {
2789
+ const tokenToRemove = selectedItems?.find((item) => item.id === tokenId);
2790
+ tokenToRemove && removeSelectedItem?.(tokenToRemove);
2791
+ };
2792
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StyledTokenInputWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2793
+ import_seeds_react_token_input.TokenInput,
2794
+ {
2795
+ onKeyDown: (e, value) => {
2796
+ if (e.key === "ArrowLeft" && !value && selectedItems.length) {
2797
+ setActiveIndex?.(selectedItems.length - 1);
2798
+ }
2799
+ onKeyDown?.(e, value);
2800
+ },
2801
+ inputProps: {
2802
+ autoComplete: "off",
2803
+ type: "search",
2804
+ ...inputProps
2805
+ },
2806
+ tokens: selectedItems.map((item, index) => {
2807
+ const {
2808
+ tokenProps: { ref, onKeyDown: onKeyDown2, ...restTokenProps } = {
2809
+ ref: void 0,
2810
+ onKeyDown: void 0
2811
+ },
2812
+ ...rest
2813
+ } = getTokenProps?.(item.id) || {};
2814
+ return {
2815
+ id: item.id,
2816
+ value: itemToString2?.(item) || item.id,
2817
+ tokenProps: {
2818
+ ...getSelectedItemProps?.({
2819
+ selectedItem: item,
2820
+ index,
2821
+ ref,
2822
+ refKey: "innerRef",
2823
+ onKeyDown: onKeyDown2
2824
+ }),
2825
+ // nullify the onclick provided from downshift
2826
+ // TokenInput deletes the token on click
2827
+ onClick: void 0,
2828
+ tabIndex: 0,
2829
+ ...restTokenProps
2830
+ },
2831
+ ...rest
2832
+ };
2833
+ }),
2834
+ onRemoveToken: removeToken,
2835
+ ...tokenInputProps
2836
+ }
2837
+ ) });
2838
+ };
2839
+
2840
+ // src/MenuSearchTokenInput/MenuSearchTokenInput.tsx
2841
+ var import_react17 = __toESM(require("react"));
2842
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2843
+ var MenuSearchTokenInput = ({
2844
+ getIsItemVisible,
2845
+ getTokenProps,
2846
+ onChange,
2847
+ inputProps: { value: inputPropsValue, ...inputProps } = {},
2848
+ value,
2849
+ ...tokenInputProps
2850
+ }) => {
2851
+ const {
2852
+ items,
2853
+ itemToString: itemToString2,
2854
+ setHiddenItemsMap,
2855
+ isOpen,
2856
+ getToggleButtonProps
2857
+ } = useMenuContentContext();
2858
+ const { updateFilteredItems } = useItemFiltering({
2859
+ allMenuItems: items,
2860
+ itemToString: itemToString2,
2861
+ getIsItemVisible,
2862
+ setHiddenItemsMap
2863
+ });
2864
+ const controlledValue = value || inputPropsValue !== void 0 ? `${inputPropsValue}` : void 0;
2865
+ const [internalValue, setInternalValue] = import_react17.default.useState(
2866
+ controlledValue || ""
2867
+ );
2868
+ const updateFilteredState = import_react17.default.useCallback(
2869
+ // defaults to an empty string if no value is passed
2870
+ (value2 = "") => {
2871
+ setInternalValue(value2);
2872
+ updateFilteredItems({ inputValue: value2 });
2873
+ },
2874
+ [updateFilteredItems]
2875
+ );
2876
+ import_react17.default.useEffect(() => {
2877
+ updateFilteredState(controlledValue);
2878
+ }, [controlledValue]);
2879
+ import_react17.default.useEffect(() => {
2880
+ updateFilteredState(controlledValue);
2881
+ }, [isOpen]);
2882
+ const handleKeyDown = import_react17.default.useCallback(
2883
+ (e) => {
2884
+ if (e.key === " ") return;
2885
+ getToggleButtonProps?.()["onKeyDown"](e);
2886
+ },
2887
+ [getToggleButtonProps]
2888
+ );
2889
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2890
+ MenuTokenInput,
2891
+ {
2892
+ onChange: (e, value2) => {
2893
+ updateFilteredState(value2);
2894
+ onChange?.(e, value2);
2895
+ },
2896
+ onKeyDown: handleKeyDown,
2897
+ inputProps: {
2898
+ value: internalValue,
2899
+ ...inputProps
2900
+ },
2901
+ MenuContext: MenuContentContext,
2902
+ ...tokenInputProps
2903
+ }
2904
+ );
2905
+ };
2906
+
2907
+ // src/SubmenuItem/SubmenuItem.tsx
2908
+ var import_react18 = __toESM(require("react"));
2909
+ var import_seeds_react_icon2 = require("@sproutsocial/seeds-react-icon");
2910
+ var import_seeds_react_box3 = require("@sproutsocial/seeds-react-box");
2911
+ var import_seeds_react_utilities = require("@sproutsocial/seeds-react-utilities");
2912
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2913
+ var SubmenuItemTrigger = ({
2914
+ id,
2915
+ children,
2916
+ innerRef,
2917
+ ...rest
2918
+ }) => {
2919
+ const { getToggleButtonProps, getDropdownProps, ref, ariaProps } = useMenuToggleContext();
2920
+ const toggleRef = ref && innerRef ? (0, import_seeds_react_utilities.mergeRefs)([ref, innerRef].filter(Boolean)) : ref || innerRef;
2921
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2922
+ MenuItem,
2923
+ {
2924
+ ...rest,
2925
+ ...getToggleButtonProps?.(
2926
+ {
2927
+ ...getDropdownProps?.({
2928
+ ref: toggleRef,
2929
+ preventKeyAction: true
2930
+ }) || { ref: toggleRef },
2931
+ refKey: "innerRef",
2932
+ role: "menuitem",
2933
+ ...ariaProps
2934
+ },
2935
+ { suppressRefError: true }
2936
+ ),
2937
+ id,
2938
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_seeds_react_box3.Box, { display: "flex", justifyContent: "space-between", children: [
2939
+ children,
2940
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MenuItemActionRight, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_seeds_react_icon2.Icon, { name: "chevron-right-outline" }) })
2941
+ ] })
2942
+ }
2943
+ );
2944
+ };
2945
+ var doesRefContainEventTarget = (ref, event) => {
2946
+ return ref.current && event.target instanceof Node && ref.current.contains(event.target);
2947
+ };
2948
+ var SubmenuItem = ({
2949
+ MenuComponent,
2950
+ menuProps: {
2951
+ children: menuChildren,
2952
+ menuItems,
2953
+ MenuItemComponent,
2954
+ popoutProps: { popperProps, ...popoutProps } = {},
2955
+ onStateChange,
2956
+ ...menuProps
2957
+ },
2958
+ // isOpen,
2959
+ // onToggleSubmenu,
2960
+ id,
2961
+ children,
2962
+ ...rest
2963
+ }) => {
2964
+ const {
2965
+ highlightedIndex,
2966
+ setHighlightedIndex,
2967
+ itemsMap,
2968
+ isOpen: parentIsOpen
2969
+ } = useMenuContentContext();
2970
+ const [submenuIsFocused, setSubmenuIsFocused] = import_react18.default.useState(false);
2971
+ const [submenuIsOpen, setSubmenuIsOpen] = import_react18.default.useState(false);
2972
+ const [submenuIsActive, setSubmenuIsActive] = import_react18.default.useState(false);
2973
+ const submenuItemRef = import_react18.default.useRef(null);
2974
+ const submenuRef = import_react18.default.useRef(null);
2975
+ const menuContent = menuItems ? getChildrenFromMenuItems({ menuItems, MenuItemComponent }) : menuChildren;
2976
+ const item = itemsMap[id] || {
2977
+ index: 0,
2978
+ id
2979
+ };
2980
+ import_react18.default.useEffect(() => {
2981
+ if (highlightedIndex === item.index) {
2982
+ !submenuIsOpen && setSubmenuIsOpen(true);
2983
+ } else if (submenuIsOpen && highlightedIndex !== -1) {
2984
+ setSubmenuIsOpen(false);
2985
+ setSubmenuIsActive(false);
2986
+ }
2987
+ }, [highlightedIndex, item.index, submenuIsOpen, setSubmenuIsOpen]);
2988
+ const onSubmenuStateChange = import_react18.default.useCallback(
2989
+ (state) => {
2990
+ if (state.isOpen !== void 0) {
2991
+ setSubmenuIsOpen(state.isOpen);
2992
+ if (!state.isOpen) {
2993
+ setSubmenuIsFocused(false);
2994
+ setHighlightedIndex?.(-1);
2995
+ }
2996
+ }
2997
+ onStateChange?.(state);
2998
+ },
2999
+ [onStateChange, setSubmenuIsOpen]
3000
+ );
3001
+ const onSubmenuKeydown = (e) => {
3002
+ switch (e.key) {
3003
+ case "ArrowRight":
3004
+ case " ":
3005
+ case "Enter":
3006
+ if (!submenuIsFocused && submenuIsOpen) {
3007
+ e.stopPropagation();
3008
+ setSubmenuIsFocused(true);
3009
+ }
3010
+ break;
3011
+ case "ArrowLeft":
3012
+ if (submenuIsFocused) {
3013
+ e.stopPropagation();
3014
+ setSubmenuIsFocused(false);
3015
+ }
3016
+ break;
3017
+ default:
3018
+ break;
3019
+ }
3020
+ };
3021
+ const onMenuItemClick = () => {
3022
+ const newIsActive = !submenuIsActive;
3023
+ setSubmenuIsActive(newIsActive);
3024
+ setSubmenuIsOpen(newIsActive);
3025
+ };
3026
+ const onBodyClick = (e) => {
3027
+ if (doesRefContainEventTarget(submenuItemRef, e)) {
3028
+ e.stopPropagation();
3029
+ onMenuItemClick();
3030
+ }
3031
+ };
3032
+ import_react18.default.useEffect(() => {
3033
+ if (document && document.body) {
3034
+ document.body.addEventListener("click", onBodyClick, {
3035
+ capture: true
3036
+ });
3037
+ document.body.addEventListener("keydown", onSubmenuKeydown, {
3038
+ capture: true
3039
+ });
3040
+ return () => {
3041
+ document.body.removeEventListener("click", onBodyClick, {
3042
+ capture: true
3043
+ });
3044
+ document.body.removeEventListener("keydown", onSubmenuKeydown, {
3045
+ capture: true
3046
+ });
3047
+ };
3048
+ }
3049
+ }, [document, onSubmenuKeydown]);
3050
+ const subMenuContent = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3051
+ "div",
3052
+ {
3053
+ ref: submenuRef,
3054
+ onKeyDown: (e) => {
3055
+ e.stopPropagation();
3056
+ },
3057
+ tabIndex: -1,
3058
+ children: menuContent
3059
+ }
3060
+ );
3061
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3062
+ MenuComponent,
3063
+ {
3064
+ ...{
3065
+ ...menuProps,
3066
+ children: subMenuContent,
3067
+ menuToggleElement: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3068
+ SubmenuItemTrigger,
3069
+ {
3070
+ innerRef: submenuItemRef,
3071
+ id,
3072
+ children,
3073
+ active: submenuIsActive,
3074
+ ...rest
3075
+ }
3076
+ ),
3077
+ isOpen: submenuIsOpen,
3078
+ onStateChange: onSubmenuStateChange,
3079
+ popoutProps: {
3080
+ placement: "right",
3081
+ popperProps: {
3082
+ modifiers: {
3083
+ offset: {
3084
+ offset: "0,18"
3085
+ }
3086
+ },
3087
+ ...popperProps
3088
+ },
3089
+ focusOnContent: submenuIsFocused,
3090
+ ...popoutProps
3091
+ }
3092
+ }
3093
+ }
3094
+ );
3095
+ };
3096
+
3097
+ // src/ActionMenu/ActionMenu.tsx
3098
+ var import_react20 = __toESM(require("react"));
3099
+ var import_downshift3 = require("downshift");
3100
+
3101
+ // src/hooks/useDownshiftDefaults.tsx
3102
+ var import_react19 = __toESM(require("react"));
3103
+
3104
+ // src/reducers/useComboboxStateReducer.tsx
3105
+ var import_downshift = require("downshift");
3106
+
3107
+ // src/utils/reduceReducers.ts
3108
+ var reduceReducers = (...reducers) => (state, action) => reducers.reduce(
3109
+ (changes, nextReducer) => nextReducer ? nextReducer(state, {
3110
+ ...action,
3111
+ changes
3112
+ }) : changes,
3113
+ action.changes
3114
+ );
3115
+
3116
+ // src/reducers/useComboboxStateReducer.tsx
3117
+ var useComboboxStateReducer = (state, actionAndChanges) => {
3118
+ const { type, changes } = actionAndChanges;
3119
+ switch (type) {
3120
+ /** If downshift is blurred by tabbing within the menu, stay open */
3121
+ case import_downshift.useCombobox.stateChangeTypes.InputBlur:
3122
+ return {
3123
+ ...changes,
3124
+ // keep menu open on blur
3125
+ isOpen: true
3126
+ };
3127
+ /** Return standard change payload */
3128
+ default:
3129
+ return changes;
3130
+ }
3131
+ };
3132
+ var useComboboxStateReducerForMulti = reduceReducers(
3133
+ useComboboxStateReducer,
3134
+ (state, actionAndChanges) => {
3135
+ const { changes, type } = actionAndChanges;
3136
+ switch (type) {
3137
+ case import_downshift.useCombobox.stateChangeTypes.InputKeyDownEnter:
3138
+ case import_downshift.useCombobox.stateChangeTypes.ItemClick:
3139
+ case import_downshift.useCombobox.stateChangeTypes.InputBlur:
3140
+ return {
3141
+ ...changes,
3142
+ ...changes.selectedItem && {
3143
+ inputValue: ""
3144
+ }
3145
+ };
3146
+ default:
3147
+ return changes;
3148
+ }
3149
+ }
3150
+ );
3151
+
3152
+ // src/reducers/useSelectStateReducer.tsx
3153
+ var import_downshift2 = require("downshift");
3154
+ var useSelectStateReducer = (state, actionAndChanges) => {
3155
+ const { type, changes } = actionAndChanges;
3156
+ switch (type) {
3157
+ /** If downshift is blurred by tabbing within the menu, stay open */
3158
+ case import_downshift2.useSelect.stateChangeTypes.ToggleButtonBlur:
3159
+ return {
3160
+ ...changes,
3161
+ // keep menu open on blur
3162
+ isOpen: true
3163
+ };
3164
+ /** Return standard change payload */
3165
+ default:
3166
+ return changes;
3167
+ }
3168
+ };
3169
+ var useSelectStateReducerForMulti = reduceReducers(
3170
+ useSelectStateReducer,
3171
+ (state, actionAndChanges) => {
3172
+ const { changes, type } = actionAndChanges;
3173
+ switch (type) {
3174
+ case import_downshift2.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
3175
+ case import_downshift2.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
3176
+ case import_downshift2.useSelect.stateChangeTypes.ItemClick:
3177
+ return {
3178
+ ...changes,
3179
+ isOpen: true,
3180
+ // keep the menu open after selection.
3181
+ // TODO: Confirm that keeping highlightedIndex the same is the desired UX
3182
+ // highlightedIndex: 0, // with the first option highlighted.
3183
+ highlightedIndex: state.highlightedIndex
3184
+ // keep highlightedIndex the same instead of returning to 0
3185
+ };
3186
+ }
3187
+ return changes;
3188
+ }
3189
+ );
3190
+
3191
+ // src/utils/getMultiSelectOverrides.ts
3192
+ var getMultiSelectOverrides = ({
3193
+ getA11yMultiStatusMessage,
3194
+ onMultiSelectStateChange,
3195
+ multiSelectStateReducer,
3196
+ ...useSelectProps
3197
+ }) => Object.entries({
3198
+ ...useSelectProps,
3199
+ getA11yStatusMessage: getA11yMultiStatusMessage,
3200
+ onStateChange: onMultiSelectStateChange,
3201
+ stateReducer: multiSelectStateReducer
3202
+ }).reduce(
3203
+ (a, [k, v]) => v ? (a[k] = v, a) : a,
3204
+ {}
3205
+ );
3206
+
3207
+ // src/hooks/useDownshiftDefaults.tsx
3208
+ var defaultUseSelectProps = {
3209
+ stateReducer: useSelectStateReducer
3210
+ };
3211
+ var defaultUseComboboxProps = {
3212
+ stateReducer: useComboboxStateReducer
3213
+ };
3214
+ var defaultUseSelectPropsForMulti = {
3215
+ stateReducer: useSelectStateReducerForMulti
3216
+ };
3217
+ var defaultUseComboboxPropsForMulti = {
3218
+ stateReducer: useComboboxStateReducerForMulti
3219
+ };
3220
+ var useDownshiftDefaults = ({
3221
+ isCombobox = false,
3222
+ isMulti = false,
3223
+ multiSelectProps = {}
3224
+ } = {}) => {
3225
+ const [hiddenItemsMap, setHiddenItemsMap] = import_react19.default.useState({});
3226
+ const isItemDisabled = import_react19.default.useCallback(
3227
+ (item) => Boolean(item.disabled || hiddenItemsMap[item.id]),
3228
+ [hiddenItemsMap]
3229
+ );
3230
+ return {
3231
+ hiddenItemsMap,
3232
+ setHiddenItemsMap,
3233
+ defaultDownshiftProps: {
3234
+ select: !isCombobox ? {
3235
+ // disabling while item.hidden so that hidden items are ignored by downshift
3236
+ isItemDisabled,
3237
+ ...isMulti ? defaultUseSelectPropsForMulti : defaultUseSelectProps
3238
+ } : {},
3239
+ combobox: isCombobox ? {
3240
+ // disabling while item.hidden so that hidden items are ignored by downshift
3241
+ isItemDisabled,
3242
+ ...isMulti ? defaultUseComboboxPropsForMulti : defaultUseComboboxProps
3243
+ } : {},
3244
+ multi: isMulti ? {
3245
+ // handles the prop name mapping for multi select
3246
+ ...getMultiSelectOverrides(multiSelectProps)
3247
+ } : {}
3248
+ }
3249
+ };
3250
+ };
3251
+
3252
+ // src/ActionMenu/ActionMenu.tsx
3253
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3254
+ var handleStateChange = (changes, currentSelectedItem) => {
3255
+ if (!(changes.type === import_downshift3.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter || changes.type === import_downshift3.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton)) {
3256
+ return;
3257
+ }
3258
+ const selectedItem = changes.selectedItem || currentSelectedItem;
3259
+ if (!selectedItem) return;
3260
+ if (selectedItem.disabled) {
3261
+ return;
3262
+ }
3263
+ const isEnterKeyDown = changes.type === import_downshift3.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter;
3264
+ const selectedItemProps = selectedItem.menuItemProps;
3265
+ if (selectedItemProps?.onClick) {
3266
+ const syntheticKeyboardEvent = new KeyboardEvent("keydown", {
3267
+ key: isEnterKeyDown ? "Enter" : " ",
3268
+ code: isEnterKeyDown ? "Enter" : "Space",
3269
+ bubbles: true,
3270
+ cancelable: true,
3271
+ view: window
3272
+ });
3273
+ selectedItemProps?.onClick?.(
3274
+ syntheticKeyboardEvent
3275
+ );
3276
+ }
3277
+ if (selectedItemProps?.href) {
3278
+ if (selectedItemProps.target) {
3279
+ window.open(selectedItemProps.href, selectedItemProps.target);
3280
+ } else {
3281
+ window.location.href = selectedItemProps?.href;
3282
+ }
3283
+ }
3284
+ };
3285
+ var ActionMenu = ({
3286
+ children: childrenProp,
3287
+ menuItems,
3288
+ MenuItemComponent,
3289
+ stateReducer: externalStateReducer,
3290
+ ...useSelectProps
2511
3291
  }) => {
2512
- const { allMenuItems, menuItemsMap } = useItemsFromChildren({ children });
2513
- const [currentSelectedItem, setCurrentSelectedItem] = import_react14.default.useState(null);
2514
- const { isOpen, ...useSelectReturnProps } = (0, import_downshift2.useSelect)({
2515
- ...defaultUseSelectProps,
3292
+ const { allMenuItems, menuItemsMap, children } = useMenuChildren({
3293
+ children: childrenProp,
3294
+ menuItems,
3295
+ MenuItemComponent
3296
+ });
3297
+ const { defaultDownshiftProps, ...restDefaults } = useDownshiftDefaults({
3298
+ isCombobox: false
3299
+ });
3300
+ const [currentSelectedItem, setCurrentSelectedItem] = import_react20.default.useState(null);
3301
+ const { isOpen, ...useSelectReturnProps } = (0, import_downshift3.useSelect)({
3302
+ ...defaultDownshiftProps.select,
2516
3303
  items: allMenuItems,
2517
3304
  itemToString,
2518
3305
  onStateChange: (changes) => handleStateChange(changes, currentSelectedItem),
2519
- stateReducer: (state, actionAndChanges) => {
2520
- let newState;
2521
- newState = useSelectStateReducer(state, actionAndChanges);
2522
- return externalStateReducer ? externalStateReducer(state, {
2523
- ...actionAndChanges,
2524
- changes: newState
2525
- }) : newState;
2526
- },
3306
+ stateReducer: reduceReducers(
3307
+ defaultDownshiftProps.select.stateReducer,
3308
+ externalStateReducer
3309
+ ),
2527
3310
  ...useSelectProps
2528
3311
  });
2529
- (0, import_react14.useEffect)(() => {
3312
+ (0, import_react20.useEffect)(() => {
2530
3313
  setCurrentSelectedItem(useSelectReturnProps.selectedItem);
2531
3314
  }, [useSelectReturnProps.selectedItem]);
2532
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3315
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2533
3316
  MenuRoot,
2534
3317
  {
2535
3318
  ...{
@@ -2539,7 +3322,8 @@ var ActionMenu = ({
2539
3322
  itemToString,
2540
3323
  isOpen,
2541
3324
  ...useSelectProps,
2542
- ...useSelectReturnProps
3325
+ ...useSelectReturnProps,
3326
+ ...restDefaults
2543
3327
  },
2544
3328
  children
2545
3329
  }
@@ -2547,30 +3331,35 @@ var ActionMenu = ({
2547
3331
  };
2548
3332
 
2549
3333
  // src/SingleSelectMenu/SingleSelectMenu.tsx
2550
- var import_react15 = require("react");
2551
- var import_downshift3 = require("downshift");
2552
- var import_jsx_runtime13 = require("react/jsx-runtime");
3334
+ var import_react21 = require("react");
3335
+ var import_downshift4 = require("downshift");
3336
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2553
3337
  var SingleSelectMenu = ({
2554
- children,
3338
+ children: childrenProp,
2555
3339
  stateReducer: externalStateReducer,
3340
+ menuItems,
3341
+ MenuItemComponent,
2556
3342
  ...useSelectProps
2557
3343
  }) => {
2558
- const { allMenuItems, menuItemsMap } = useItemsFromChildren({ children });
2559
- const { isOpen, ...useSelectReturnProps } = (0, import_downshift3.useSelect)({
2560
- ...defaultUseSelectProps,
3344
+ const { allMenuItems, menuItemsMap, children } = useMenuChildren({
3345
+ children: childrenProp,
3346
+ menuItems,
3347
+ MenuItemComponent
3348
+ });
3349
+ const { defaultDownshiftProps, ...restDefaults } = useDownshiftDefaults({
3350
+ isCombobox: false
3351
+ });
3352
+ const { isOpen, ...useSelectReturnProps } = (0, import_downshift4.useSelect)({
3353
+ ...defaultDownshiftProps.select,
2561
3354
  items: allMenuItems,
2562
3355
  itemToString,
2563
- stateReducer: (state, actionAndChanges) => {
2564
- let newState;
2565
- newState = useSelectStateReducer(state, actionAndChanges);
2566
- return externalStateReducer ? externalStateReducer(state, {
2567
- ...actionAndChanges,
2568
- changes: newState
2569
- }) : newState;
2570
- },
3356
+ stateReducer: reduceReducers(
3357
+ defaultDownshiftProps.select.stateReducer,
3358
+ externalStateReducer
3359
+ ),
2571
3360
  ...useSelectProps
2572
3361
  });
2573
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3362
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2574
3363
  MenuRoot,
2575
3364
  {
2576
3365
  ...{
@@ -2580,7 +3369,8 @@ var SingleSelectMenu = ({
2580
3369
  itemToString,
2581
3370
  isOpen,
2582
3371
  ...useSelectProps,
2583
- ...useSelectReturnProps
3372
+ ...useSelectReturnProps,
3373
+ ...restDefaults
2584
3374
  },
2585
3375
  children
2586
3376
  }
@@ -2588,45 +3378,36 @@ var SingleSelectMenu = ({
2588
3378
  };
2589
3379
 
2590
3380
  // src/MultiSelectMenu/MultiSelectMenu.tsx
2591
- var import_react16 = require("react");
2592
- var import_downshift4 = require("downshift");
2593
- var import_jsx_runtime14 = require("react/jsx-runtime");
2594
- var selectReducerForMultiSelect = (state, actionAndChanges) => {
2595
- const { changes, type } = actionAndChanges;
2596
- switch (type) {
2597
- case import_downshift4.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
2598
- case import_downshift4.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
2599
- case import_downshift4.useSelect.stateChangeTypes.ItemClick:
2600
- return {
2601
- ...changes,
2602
- isOpen: true,
2603
- // keep the menu open after selection.
2604
- // TODO: Confirm that keeping highlightedIndex the same is the desired UX
2605
- // highlightedIndex: 0, // with the first option highlighted.
2606
- highlightedIndex: state.highlightedIndex
2607
- // keep highlightedIndex the same instead of returning to 0
2608
- };
2609
- }
2610
- return changes;
2611
- };
3381
+ var import_react22 = require("react");
3382
+ var import_downshift5 = require("downshift");
3383
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2612
3384
  var MultiSelectMenu = ({
2613
- children,
3385
+ children: childrenProp,
3386
+ menuItems,
3387
+ MenuItemComponent,
3388
+ onSelectedItemChange: externalOnSelectedItemChange,
2614
3389
  stateReducer: externalStateReducer,
2615
3390
  getA11yMultiStatusMessage,
2616
3391
  onMultiSelectStateChange,
2617
3392
  multiSelectStateReducer,
2618
3393
  ...useSelectProps
2619
3394
  }) => {
2620
- const { allMenuItems, menuItemsMap } = useItemsFromChildren({ children });
2621
- const multiSelectOverrides = Object.entries({
2622
- ...useSelectProps,
2623
- getA11yStatusMessage: getA11yMultiStatusMessage,
2624
- onStateChange: onMultiSelectStateChange,
2625
- stateReducer: multiSelectStateReducer
2626
- }).reduce(
2627
- (a, [k, v]) => v ? (a[k] = v, a) : a,
2628
- {}
2629
- );
3395
+ const { allMenuItems, menuItemsMap, children } = useMenuChildren({
3396
+ children: childrenProp,
3397
+ menuItems,
3398
+ MenuItemComponent
3399
+ });
3400
+ const { defaultDownshiftProps, ...restDefaults } = useDownshiftDefaults({
3401
+ isCombobox: false,
3402
+ isMulti: true,
3403
+ // handles the prop name mapping for multi select
3404
+ multiSelectProps: {
3405
+ getA11yMultiStatusMessage,
3406
+ onMultiSelectStateChange,
3407
+ multiSelectStateReducer,
3408
+ ...useSelectProps
3409
+ }
3410
+ });
2630
3411
  const {
2631
3412
  getSelectedItemProps,
2632
3413
  addSelectedItem,
@@ -2634,30 +3415,23 @@ var MultiSelectMenu = ({
2634
3415
  selectedItems,
2635
3416
  getDropdownProps,
2636
3417
  ...useMultipleSelectionReturnProps
2637
- } = (0, import_downshift4.useMultipleSelection)(multiSelectOverrides);
2638
- const { isOpen, ...useSelectReturnProps } = (0, import_downshift4.useSelect)({
2639
- ...defaultUseSelectProps,
3418
+ } = (0, import_downshift5.useMultipleSelection)(defaultDownshiftProps.multi);
3419
+ const { isOpen, ...useSelectReturnProps } = (0, import_downshift5.useSelect)({
3420
+ ...defaultDownshiftProps.select,
2640
3421
  items: allMenuItems,
2641
3422
  itemToString,
2642
3423
  selectedItem: null,
2643
3424
  defaultHighlightedIndex: 0,
2644
- stateReducer: (state, actionAndChanges) => {
2645
- let newState;
2646
- newState = useSelectStateReducer(state, actionAndChanges);
2647
- newState = selectReducerForMultiSelect(state, {
2648
- ...actionAndChanges,
2649
- changes: newState
2650
- });
2651
- return externalStateReducer ? externalStateReducer(state, {
2652
- ...actionAndChanges,
2653
- changes: newState
2654
- }) : newState;
2655
- },
2656
- onStateChange: ({ type, selectedItem: newSelectedItem }) => {
3425
+ stateReducer: reduceReducers(
3426
+ defaultDownshiftProps.select.stateReducer,
3427
+ externalStateReducer
3428
+ ),
3429
+ onSelectedItemChange: (changes) => {
3430
+ const { type, selectedItem: newSelectedItem } = changes;
2657
3431
  switch (type) {
2658
- case import_downshift4.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
2659
- case import_downshift4.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
2660
- case import_downshift4.useSelect.stateChangeTypes.ItemClick:
3432
+ case import_downshift5.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
3433
+ case import_downshift5.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
3434
+ case import_downshift5.useSelect.stateChangeTypes.ItemClick:
2661
3435
  if (!newSelectedItem) break;
2662
3436
  if (selectedItems?.find((item) => item?.id === newSelectedItem.id)) {
2663
3437
  removeSelectedItem(newSelectedItem);
@@ -2674,10 +3448,11 @@ var MultiSelectMenu = ({
2674
3448
  default:
2675
3449
  break;
2676
3450
  }
3451
+ externalOnSelectedItemChange?.(changes);
2677
3452
  },
2678
3453
  ...useSelectProps
2679
3454
  });
2680
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3455
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2681
3456
  MenuRoot,
2682
3457
  {
2683
3458
  ...{
@@ -2696,7 +3471,8 @@ var MultiSelectMenu = ({
2696
3471
  multiSelectStateReducer,
2697
3472
  ...useSelectProps,
2698
3473
  ...useSelectReturnProps,
2699
- ...useMultipleSelectionReturnProps
3474
+ ...useMultipleSelectionReturnProps,
3475
+ ...restDefaults
2700
3476
  },
2701
3477
  children
2702
3478
  }
@@ -2704,77 +3480,191 @@ var MultiSelectMenu = ({
2704
3480
  };
2705
3481
 
2706
3482
  // 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
- };
3483
+ var import_react25 = require("react");
2731
3484
 
2732
- // src/Autocomplete/Autocomplete.tsx
2733
- var import_jsx_runtime15 = require("react/jsx-runtime");
2734
- var Autocomplete = ({
2735
- children,
3485
+ // src/Autocomplete/SingleAutocomplete.tsx
3486
+ var import_react23 = require("react");
3487
+ var import_downshift6 = require("downshift");
3488
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3489
+ var SingleAutocomplete = ({
3490
+ children: childrenProp,
2736
3491
  stateReducer: externalStateReducer,
3492
+ menuItems,
3493
+ MenuItemComponent,
2737
3494
  itemToString: itemToString2 = itemToString,
2738
- getIsItemVisible = (item, inputValue) => itemToString2(item).toLowerCase().startsWith(inputValue.toLowerCase()),
3495
+ getIsItemVisible,
2739
3496
  ...useComboboxProps
2740
3497
  }) => {
2741
- const { allMenuItems } = useItemsFromChildren({ children });
2742
- const [items, setItems] = import_react17.default.useState(allMenuItems);
3498
+ const { allMenuItems, children } = useMenuChildren({
3499
+ children: childrenProp,
3500
+ menuItems,
3501
+ MenuItemComponent
3502
+ });
3503
+ const { setHiddenItemsMap, defaultDownshiftProps, ...restDefaults } = useDownshiftDefaults({ isCombobox: true });
3504
+ const { updateFilteredItems } = useItemFiltering({
3505
+ allMenuItems,
3506
+ itemToString: itemToString2,
3507
+ getIsItemVisible,
3508
+ setHiddenItemsMap
3509
+ });
2743
3510
  const { isOpen, ...useComboboxReturnProps } = (0, import_downshift6.useCombobox)({
2744
- ...defaultUseComboboxProps,
2745
- items,
3511
+ ...defaultDownshiftProps.combobox,
3512
+ items: allMenuItems,
2746
3513
  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
- );
3514
+ onInputValueChange: updateFilteredItems,
3515
+ stateReducer: reduceReducers(
3516
+ defaultDownshiftProps.combobox.stateReducer,
3517
+ externalStateReducer
3518
+ ),
3519
+ ...useComboboxProps
3520
+ });
3521
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3522
+ MenuRoot,
3523
+ {
3524
+ ...{
3525
+ isListbox: true,
3526
+ items: allMenuItems,
3527
+ itemToString: itemToString2,
3528
+ isOpen,
3529
+ setHiddenItemsMap,
3530
+ ...useComboboxProps,
3531
+ ...useComboboxReturnProps,
3532
+ ...restDefaults
3533
+ },
3534
+ popoutProps: {
3535
+ focusOnContent: false
3536
+ },
3537
+ children
3538
+ }
3539
+ );
3540
+ };
3541
+
3542
+ // src/Autocomplete/MultiAutocomplete.tsx
3543
+ var import_react24 = __toESM(require("react"));
3544
+ var import_downshift7 = require("downshift");
3545
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3546
+ var MultiAutocomplete = ({
3547
+ children: childrenProp,
3548
+ stateReducer: externalStateReducer,
3549
+ menuItems,
3550
+ MenuItemComponent,
3551
+ itemToString: itemToString2 = itemToString,
3552
+ itemToKey: itemToKey2 = itemToKey,
3553
+ getIsItemVisible = getDefaultGetIsItemVisible(itemToString2),
3554
+ showSelectedItemsInDropdown = false,
3555
+ initialSelectedItems = [],
3556
+ onStateChange,
3557
+ onSelectedItemsChange,
3558
+ getA11yMultiStatusMessage,
3559
+ onMultiSelectStateChange,
3560
+ multiSelectStateReducer,
3561
+ ...useComboboxProps
3562
+ }) => {
3563
+ const { allMenuItems, children } = useMenuChildren({
3564
+ children: childrenProp,
3565
+ menuItems,
3566
+ MenuItemComponent
3567
+ });
3568
+ const [selectedItems, setSelectedItems] = import_react24.default.useState(initialSelectedItems);
3569
+ const [selectedItemIds, setSelectedItemIds] = import_react24.default.useState(getSelectedItemIds(initialSelectedItems));
3570
+ const getIsItemVisibleMulti = import_react24.default.useCallback(
3571
+ (item, inputValue) => {
3572
+ return (showSelectedItemsInDropdown || !selectedItemIds[item.id]) && getIsItemVisible(item, inputValue);
2757
3573
  },
2758
- stateReducer: (state, actionAndChanges) => {
2759
- let newState;
2760
- newState = useComboboxStateReducer(state, actionAndChanges);
2761
- return externalStateReducer ? externalStateReducer(state, {
2762
- ...actionAndChanges,
2763
- changes: newState
2764
- }) : newState;
3574
+ [selectedItemIds, showSelectedItemsInDropdown, getIsItemVisible]
3575
+ );
3576
+ const getShouldFilterMulti = import_react24.default.useCallback(
3577
+ (args) => {
3578
+ return !showSelectedItemsInDropdown && Object.keys(selectedItemIds).length > 0 || defaultGetShouldFilter(args);
3579
+ },
3580
+ [selectedItemIds, showSelectedItemsInDropdown, getIsItemVisible]
3581
+ );
3582
+ const { setHiddenItemsMap, defaultDownshiftProps, ...restDefaults } = useDownshiftDefaults({
3583
+ isCombobox: true,
3584
+ isMulti: true,
3585
+ // handles the prop name mapping for multi select
3586
+ multiSelectProps: {
3587
+ getA11yMultiStatusMessage,
3588
+ onMultiSelectStateChange,
3589
+ multiSelectStateReducer,
3590
+ ...useComboboxProps
3591
+ }
3592
+ });
3593
+ const { updateFilteredItems } = useItemFiltering({
3594
+ allMenuItems,
3595
+ itemToString: itemToString2,
3596
+ getIsItemVisible: getIsItemVisibleMulti,
3597
+ getShouldFilter: getShouldFilterMulti,
3598
+ setHiddenItemsMap
3599
+ });
3600
+ import_react24.default.useEffect(() => {
3601
+ updateFilteredItems({ inputValue: "" });
3602
+ }, [selectedItemIds]);
3603
+ const useMultipleSelectionReturnProps = (0, import_downshift7.useMultipleSelection)({
3604
+ ...defaultDownshiftProps.multi,
3605
+ itemToKey: itemToKey2,
3606
+ selectedItems,
3607
+ onSelectedItemsChange: ({ selectedItems: selectedItems2, ...changes }) => {
3608
+ setSelectedItems(selectedItems2);
3609
+ setSelectedItemIds(getSelectedItemIds(selectedItems2));
3610
+ onSelectedItemsChange && onSelectedItemsChange({ selectedItems: selectedItems2, ...changes });
3611
+ }
3612
+ });
3613
+ const { isOpen, ...useComboboxReturnProps } = (0, import_downshift7.useCombobox)({
3614
+ ...defaultDownshiftProps.combobox,
3615
+ items: allMenuItems,
3616
+ itemToString: itemToString2,
3617
+ itemToKey: itemToKey2,
3618
+ stateReducer: reduceReducers(
3619
+ defaultDownshiftProps.combobox.stateReducer,
3620
+ externalStateReducer
3621
+ ),
3622
+ onStateChange(changes) {
3623
+ const { type, selectedItem: newSelectedItem, inputValue } = changes;
3624
+ switch (type) {
3625
+ // Add the selected item to the selected items list
3626
+ case import_downshift7.useCombobox.stateChangeTypes.InputKeyDownEnter:
3627
+ case import_downshift7.useCombobox.stateChangeTypes.ItemClick:
3628
+ if (newSelectedItem) {
3629
+ const newSelectedItems = [...selectedItems, newSelectedItem];
3630
+ setSelectedItems(newSelectedItems);
3631
+ setSelectedItemIds({
3632
+ ...selectedItemIds,
3633
+ [newSelectedItem.id]: true
3634
+ });
3635
+ onSelectedItemsChange && onSelectedItemsChange({
3636
+ selectedItems: newSelectedItems,
3637
+ type: import_downshift7.useMultipleSelection.stateChangeTypes.FunctionSetSelectedItems
3638
+ });
3639
+ }
3640
+ break;
3641
+ default:
3642
+ break;
3643
+ }
3644
+ if (inputValue !== void 0) updateFilteredItems({ inputValue });
3645
+ onStateChange && onStateChange(changes);
2765
3646
  },
2766
3647
  ...useComboboxProps
2767
3648
  });
2768
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3649
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2769
3650
  MenuRoot,
2770
3651
  {
2771
3652
  ...{
2772
3653
  isListbox: true,
2773
- items,
3654
+ items: allMenuItems,
2774
3655
  itemToString: itemToString2,
2775
3656
  isOpen,
3657
+ initialSelectedItems,
3658
+ onStateChange,
3659
+ onSelectedItemsChange,
3660
+ getA11yMultiStatusMessage,
3661
+ onMultiSelectStateChange,
3662
+ multiSelectStateReducer,
3663
+ setHiddenItemsMap,
2776
3664
  ...useComboboxProps,
2777
- ...useComboboxReturnProps
3665
+ ...useComboboxReturnProps,
3666
+ ...useMultipleSelectionReturnProps,
3667
+ ...restDefaults
2778
3668
  },
2779
3669
  popoutProps: {
2780
3670
  focusOnContent: false
@@ -2784,10 +3674,22 @@ var Autocomplete = ({
2784
3674
  );
2785
3675
  };
2786
3676
 
3677
+ // src/Autocomplete/Autocomplete.tsx
3678
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3679
+ var Autocomplete = ({
3680
+ multiSelect,
3681
+ ...rest
3682
+ }) => {
3683
+ if (multiSelect) {
3684
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MultiAutocomplete, { ...rest });
3685
+ }
3686
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SingleAutocomplete, { ...rest });
3687
+ };
3688
+
2787
3689
  // 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");
3690
+ var import_react26 = require("react");
3691
+ var import_seeds_react_input2 = require("@sproutsocial/seeds-react-input");
3692
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2791
3693
  var AutocompleteInput = ({
2792
3694
  onKeyDown,
2793
3695
  onChange,
@@ -2797,30 +3699,263 @@ var AutocompleteInput = ({
2797
3699
  inputProps,
2798
3700
  ...rest
2799
3701
  }) => {
2800
- const { getInputProps, inputValue } = (0, import_react18.useContext)(MenuContext);
2801
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2802
- import_seeds_react_input.Input,
3702
+ const { getInputComponentProps, inputValue, ref, ariaProps } = useMenuToggleContext();
3703
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3704
+ import_seeds_react_input2.Input,
2803
3705
  {
2804
3706
  id: "autocomplete_input",
2805
3707
  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
- },
3708
+ ...getInputComponentProps({
3709
+ onKeyDown,
3710
+ onChange,
3711
+ onInput,
3712
+ onBlur,
3713
+ onClick,
3714
+ value: inputValue,
3715
+ ref,
3716
+ refKey: "innerRef",
3717
+ inputProps,
3718
+ ...ariaProps
3719
+ }),
2818
3720
  autoComplete: false,
2819
3721
  value: inputValue,
2820
3722
  ...rest
2821
3723
  }
2822
3724
  );
2823
3725
  };
3726
+
3727
+ // src/NestedMenu/NestedMenu.tsx
3728
+ var import_react29 = require("react");
3729
+
3730
+ // src/NestedMenu/NestedMenuContext.tsx
3731
+ var import_react27 = require("react");
3732
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3733
+ var defaultNestedMenuContext = {
3734
+ selectedMenuPath: [],
3735
+ setSelectedMenuId: () => {
3736
+ },
3737
+ setSelectedMenuPath: () => {
3738
+ },
3739
+ goBack: () => {
3740
+ }
3741
+ };
3742
+ var NestedMenuContext = (0, import_react27.createContext)(
3743
+ defaultNestedMenuContext
3744
+ );
3745
+ var NestedMenuProvider = ({
3746
+ children,
3747
+ ...nestedMenuProps
3748
+ }) => {
3749
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(NestedMenuContext.Provider, { value: nestedMenuProps, children });
3750
+ };
3751
+ var useNestedMenuContext = () => {
3752
+ const nestedMenuContextValue = (0, import_react27.useContext)(NestedMenuContext);
3753
+ if (nestedMenuContextValue === null) {
3754
+ throw new Error(
3755
+ "useNestedMenuContext must be used within a <NestedMenuContext.Provider />"
3756
+ );
3757
+ }
3758
+ return nestedMenuContextValue;
3759
+ };
3760
+
3761
+ // src/NestedMenu/NestedMenuHeader.tsx
3762
+ var import_seeds_react_button2 = require("@sproutsocial/seeds-react-button");
3763
+ var import_seeds_react_icon3 = require("@sproutsocial/seeds-react-icon");
3764
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3765
+ var NestedMenuHeader = ({
3766
+ backArrowLabel,
3767
+ ...props
3768
+ }) => {
3769
+ const { goBack, selectedMenuPath } = useNestedMenuContext();
3770
+ const showBackArrow = selectedMenuPath.length > 1;
3771
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3772
+ MenuHeader,
3773
+ {
3774
+ leftAction: showBackArrow ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_seeds_react_button2.Button, { onClick: goBack, ariaLabel: backArrowLabel, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_seeds_react_icon3.Icon, { name: "arrow-left" }) }) : void 0,
3775
+ ...props
3776
+ }
3777
+ );
3778
+ };
3779
+
3780
+ // src/reducers/nestedMenuStateReducer.tsx
3781
+ var import_downshift8 = require("downshift");
3782
+ var nestedMenuStateReducer = (_state, actionAndChanges) => {
3783
+ const { type, changes } = actionAndChanges;
3784
+ const hasChildMenu = !!changes?.selectedItem?.menuItemProps?.childMenuId;
3785
+ if (!hasChildMenu) {
3786
+ return changes;
3787
+ }
3788
+ switch (type) {
3789
+ case import_downshift8.useSelect.stateChangeTypes.ToggleButtonBlur:
3790
+ case import_downshift8.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
3791
+ case import_downshift8.useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
3792
+ case import_downshift8.useSelect.stateChangeTypes.ItemClick:
3793
+ case import_downshift8.useCombobox.stateChangeTypes.ItemClick:
3794
+ return {
3795
+ ...changes,
3796
+ isOpen: true,
3797
+ highlightedIndex: 0
3798
+ };
3799
+ default:
3800
+ return changes;
3801
+ }
3802
+ };
3803
+
3804
+ // src/NestedMenu/NestedMenuContent.tsx
3805
+ var import_react28 = require("react");
3806
+ var import_src = require("@sproutsocial/seeds-react-utilities/src/index");
3807
+
3808
+ // src/NestedMenu/NestedMenuItem.tsx
3809
+ var import_seeds_react_icon4 = require("@sproutsocial/seeds-react-icon");
3810
+ var import_seeds_react_box4 = require("@sproutsocial/seeds-react-box");
3811
+ var import_jsx_runtime26 = require("react/jsx-runtime");
3812
+ var NestedMenuItem = ({
3813
+ children,
3814
+ childMenuId,
3815
+ onClick: onClickProp,
3816
+ ...rest
3817
+ }) => {
3818
+ const { setSelectedMenuId } = useNestedMenuContext();
3819
+ const onClickProps = childMenuId ? {
3820
+ onClick: (e) => {
3821
+ onClickProp?.(e);
3822
+ setSelectedMenuId?.(childMenuId);
3823
+ }
3824
+ } : {};
3825
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MenuItem, { ...onClickProps, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_seeds_react_box4.Box, { display: "flex", justifyContent: "space-between", children: [
3826
+ children,
3827
+ childMenuId && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MenuItemActionRight, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_seeds_react_icon4.Icon, { name: "arrow-right-outline" }) })
3828
+ ] }) });
3829
+ };
3830
+
3831
+ // src/NestedMenu/NestedMenuContent.tsx
3832
+ var import_jsx_runtime27 = require("react/jsx-runtime");
3833
+ var NestedMenuContent = ({
3834
+ innerRef: innerRefProp = null,
3835
+ onKeyDown: onKeyDownProp,
3836
+ children,
3837
+ menuItems,
3838
+ MenuItemComponent = NestedMenuItem,
3839
+ ...props
3840
+ }) => {
3841
+ const { highlightedIndex, items } = useMenuContentContext();
3842
+ const { setSelectedMenuId, selectedMenuPath, goBack } = useNestedMenuContext();
3843
+ const internalRef = (0, import_react28.useRef)(null);
3844
+ const innerRef = (0, import_src.mergeRefs)(internalRef, innerRefProp);
3845
+ const contentProps = children ? { children } : { menuItems, MenuItemComponent };
3846
+ (0, import_react28.useEffect)(() => {
3847
+ internalRef?.current?.focus();
3848
+ }, []);
3849
+ const onKeyDown = (e) => {
3850
+ onKeyDownProp?.(e);
3851
+ switch (e.key) {
3852
+ case "ArrowRight":
3853
+ case " ":
3854
+ case "Enter":
3855
+ if (highlightedIndex !== void 0 && highlightedIndex !== -1) {
3856
+ const item = items[highlightedIndex];
3857
+ if (item?.menuItemProps?.childMenuId !== void 0) {
3858
+ setSelectedMenuId?.(item?.menuItemProps?.childMenuId);
3859
+ }
3860
+ }
3861
+ break;
3862
+ case "ArrowLeft":
3863
+ if (selectedMenuPath.length > 1) {
3864
+ goBack?.();
3865
+ }
3866
+ break;
3867
+ }
3868
+ };
3869
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3870
+ MenuContent,
3871
+ {
3872
+ onKeyDown,
3873
+ innerRef,
3874
+ ...contentProps,
3875
+ ...props
3876
+ }
3877
+ );
3878
+ };
3879
+
3880
+ // src/NestedMenu/NestedMenu.tsx
3881
+ var import_jsx_runtime28 = require("react/jsx-runtime");
3882
+ var NestedMenu = ({
3883
+ initialMenuId,
3884
+ menus,
3885
+ onBackButtonClick,
3886
+ backArrowLabel,
3887
+ menuToggleElement
3888
+ }) => {
3889
+ const [selectedMenuPath, setSelectedMenuPath] = (0, import_react29.useState)([initialMenuId]);
3890
+ const selectedMenuId = selectedMenuPath[selectedMenuPath.length - 1];
3891
+ const setSelectedMenuId = (id) => {
3892
+ setSelectedMenuPath((currentPath) => [...currentPath, id]);
3893
+ };
3894
+ const goBack = () => {
3895
+ setSelectedMenuPath((currentPath) => currentPath.slice(0, -1));
3896
+ onBackButtonClick?.(selectedMenuId);
3897
+ };
3898
+ const {
3899
+ MenuComponent,
3900
+ menuProps,
3901
+ MenuHeaderComponent = NestedMenuHeader,
3902
+ menuHeaderProps = {}
3903
+ } = menus[selectedMenuId] || {};
3904
+ const {
3905
+ children,
3906
+ menuItems,
3907
+ MenuItemComponent,
3908
+ stateReducer: externalStateReducer,
3909
+ onStateChange: externalOnStateChange,
3910
+ ...props
3911
+ } = menuProps || {};
3912
+ const stateReducer = reduceReducers(
3913
+ nestedMenuStateReducer,
3914
+ externalStateReducer
3915
+ );
3916
+ const onStateChange = (changes) => {
3917
+ externalOnStateChange?.(changes);
3918
+ if (changes.isOpen === false) {
3919
+ setTimeout(() => {
3920
+ setSelectedMenuPath([initialMenuId]);
3921
+ }, 100);
3922
+ }
3923
+ };
3924
+ const nestedMenuProps = {
3925
+ menuToggleElement,
3926
+ stateReducer,
3927
+ onStateChange,
3928
+ initialIsOpen: selectedMenuPath.length > 1,
3929
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
3930
+ MenuHeaderComponent && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3931
+ MenuHeaderComponent,
3932
+ {
3933
+ backArrowLabel,
3934
+ ...menuHeaderProps
3935
+ }
3936
+ ),
3937
+ children && children,
3938
+ menuItems && !children && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3939
+ NestedMenuContent,
3940
+ {
3941
+ menuItems,
3942
+ MenuItemComponent: MenuItemComponent ?? NestedMenuItem
3943
+ }
3944
+ )
3945
+ ] }),
3946
+ ...props
3947
+ };
3948
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3949
+ NestedMenuProvider,
3950
+ {
3951
+ selectedMenuPath,
3952
+ setSelectedMenuPath,
3953
+ setSelectedMenuId,
3954
+ goBack,
3955
+ children: MenuComponent && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MenuComponent, { ...nestedMenuProps })
3956
+ }
3957
+ );
3958
+ };
2824
3959
  // Annotate the CommonJS export names for ESM import in node:
2825
3960
  0 && (module.exports = {
2826
3961
  ActionMenu,
@@ -2828,30 +3963,51 @@ var AutocompleteInput = ({
2828
3963
  AutocompleteInput,
2829
3964
  INPUT_TYPES,
2830
3965
  MenuContent,
2831
- MenuContext,
3966
+ MenuContentContext,
3967
+ MenuContentProvider,
2832
3968
  MenuFooter,
2833
3969
  MenuGroup,
2834
3970
  MenuHeader,
2835
3971
  MenuItem,
2836
3972
  MenuItemAction,
3973
+ MenuItemActionLeft,
3974
+ MenuItemActionRight,
2837
3975
  MenuItemContainer,
2838
3976
  MenuItemRow,
2839
3977
  MenuItemText,
2840
3978
  MenuLabel,
2841
- MenuProvider,
2842
3979
  MenuRoot,
3980
+ MenuSearchInput,
3981
+ MenuSearchTokenInput,
2843
3982
  MenuToggleButton,
3983
+ MenuToggleContext,
3984
+ MenuToggleProvider,
3985
+ MenuTokenInput,
2844
3986
  MultiSelectMenu,
3987
+ NestedMenu,
3988
+ NestedMenuContent,
3989
+ NestedMenuContext,
3990
+ NestedMenuHeader,
3991
+ NestedMenuItem,
3992
+ NestedMenuProvider,
2845
3993
  SingleSelectMenu,
2846
3994
  StyledMenuGroup,
2847
3995
  StyledMenuGroupUl,
2848
3996
  StyledMenuItem,
2849
3997
  StyledTitle,
2850
- defaultUseSelectProps,
2851
- useItemsFromChildren,
3998
+ SubmenuItem,
3999
+ checkIfItemSelected,
4000
+ defaultMenuContext,
4001
+ getChildrenFromMenuItems,
4002
+ getSelectedItemIds,
4003
+ mapMenuItems,
2852
4004
  useMenu,
2853
- useMenuContext,
2854
- useSelectStateReducer
4005
+ useMenuChildren,
4006
+ useMenuContentContext,
4007
+ useMenuToggleContext,
4008
+ useNestedMenuContext,
4009
+ useSelectStateReducer,
4010
+ useSelectStateReducerForMulti
2855
4011
  });
2856
4012
  /*! Bundled license information:
2857
4013