@launchpad-ui/menu 0.12.10 → 0.12.12

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.
@@ -14,7 +14,7 @@ type MenuItemOwnProps = {
14
14
  nested?: boolean;
15
15
  groupHeader?: boolean;
16
16
  tooltip?: string | ReactElement;
17
- tooltipOptions?: typeof Tooltip;
17
+ tooltipOptions?: ComponentPropsWithRef<typeof Tooltip>;
18
18
  tooltipPlacement?: PopoverPlacement;
19
19
  asChild?: boolean;
20
20
  'data-test-id'?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"MenuItem.d.ts","sourceRoot":"","sources":["../src/MenuItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE5F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAShD,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;AAExC,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAE1E,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,KAAK,CAC5D,CAAC,SAAS,MAAM,GAAG,CAAC,iBAAiB,GACjC,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACtC,qBAAqB,CAAC,CAAC,CAAC,EAC5B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CACzB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAChC,cAAc,CAAC,EAAE,OAAO,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,cAAc,WAAW,CAAC;AAEhC,KAAK,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,GAAG,OAAO,cAAc,IAAI,uBAAuB,CAC1F,CAAC,gBAAgB,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC,GACF,CAAC,gBAAgB,GAAG;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC,EACJ,CAAC,CACF,CAAC;AAEF,QAAA,MAAM,QAAQ,qHAwEb,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"MenuItem.d.ts","sourceRoot":"","sources":["../src/MenuItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE5F,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAShD,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;AAExC,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAE1E,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,KAAK,CAC5D,CAAC,SAAS,MAAM,GAAG,CAAC,iBAAiB,GACjC,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACtC,qBAAqB,CAAC,CAAC,CAAC,EAC5B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CACzB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAChC,cAAc,CAAC,EAAE,qBAAqB,CAAC,OAAO,OAAO,CAAC,CAAC;IACvD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,cAAc,WAAW,CAAC;AAEhC,KAAK,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,GAAG,OAAO,cAAc,IAAI,uBAAuB,CAC1F,CAAC,gBAAgB,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC,GACF,CAAC,gBAAgB,GAAG;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC,EACJ,CAAC,CACF,CAAC;AAEF,QAAA,MAAM,QAAQ,qHAwEb,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,CAAC"}
package/dist/index.es.js CHANGED
@@ -29,21 +29,16 @@ const styles = {
29
29
  "VirtualMenu-item-list": "_VirtualMenu-item-list_dlpdi_142",
30
30
  "VirtualMenu-item": "_VirtualMenu-item_dlpdi_142"
31
31
  };
32
- const MenuBase = /* @__PURE__ */ forwardRef(({
33
- children,
34
- size,
35
- isVirtual,
36
- ...props
37
- }, ref) => {
38
- const classes = cx(styles.Menu, isVirtual && styles["Menu--isVirtual"], size && styles[`MenuSize--${size}`]);
39
- return /* @__PURE__ */ jsx("div", {
40
- ...props,
41
- role: "menu",
42
- className: classes,
43
- ref,
44
- children
45
- });
46
- });
32
+ const MenuBase = /* @__PURE__ */ forwardRef(
33
+ ({ children, size, isVirtual, ...props }, ref) => {
34
+ const classes = cx(
35
+ styles.Menu,
36
+ isVirtual && styles["Menu--isVirtual"],
37
+ size && styles[`MenuSize--${size}`]
38
+ );
39
+ return /* @__PURE__ */ jsx("div", { ...props, role: "menu", className: classes, ref, children });
40
+ }
41
+ );
47
42
  MenuBase.displayName = "MenuBase";
48
43
  const MenuDivider = ({
49
44
  elementType = "div",
@@ -51,18 +46,19 @@ const MenuDivider = ({
51
46
  innerRef,
52
47
  "data-test-id": testId = "menu-divider"
53
48
  }) => {
54
- const {
55
- separatorProps
56
- } = useSeparator({
49
+ const { separatorProps } = useSeparator({
57
50
  orientation,
58
51
  elementType
59
52
  });
60
- return /* @__PURE__ */ jsx("div", {
61
- ...separatorProps,
62
- "data-test-id": testId,
63
- ref: innerRef,
64
- className: styles["Menu-divider"]
65
- });
53
+ return /* @__PURE__ */ jsx(
54
+ "div",
55
+ {
56
+ ...separatorProps,
57
+ "data-test-id": testId,
58
+ ref: innerRef,
59
+ className: styles["Menu-divider"]
60
+ }
61
+ );
66
62
  };
67
63
  const defaultElement = "button";
68
64
  const MenuItem = ({
@@ -89,51 +85,45 @@ const MenuItem = ({
89
85
  ...rest
90
86
  } = props;
91
87
  const Component = component || (asChild ? Slot : defaultElement);
92
- const renderIcon = icon && /* @__PURE__ */ cloneElement(icon, {
93
- size: "small"
94
- });
95
- const renderedItem = /* @__PURE__ */ jsx(FocusRing, {
96
- focusRingClass: styles["has-focus"],
97
- children: /* @__PURE__ */ jsx(Component, {
88
+ const renderIcon = icon && /* @__PURE__ */ cloneElement(icon, { size: "small" });
89
+ const renderedItem = /* @__PURE__ */ jsx(FocusRing, { focusRingClass: styles["has-focus"], children: /* @__PURE__ */ jsx(
90
+ Component,
91
+ {
98
92
  ...rest,
99
93
  disabled,
100
94
  "aria-disabled": disabled ? disabled : void 0,
101
- className: cx(styles["Menu-item"], className, isHighlighted && styles["is-highlighted"], nested && styles["Menu-item--nested"], groupHeader && styles["Menu-item--header"]),
95
+ className: cx(
96
+ styles["Menu-item"],
97
+ className,
98
+ isHighlighted && styles["is-highlighted"],
99
+ nested && styles["Menu-item--nested"],
100
+ groupHeader && styles["Menu-item--header"]
101
+ ),
102
102
  "data-test-id": testId,
103
103
  role,
104
104
  onKeyDown,
105
- children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, {
106
- children: [icon && /* @__PURE__ */ jsx("span", {
107
- className: styles["Menu-item-icon"],
108
- children: renderIcon
109
- }), children]
110
- })
111
- })
112
- });
105
+ children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
106
+ icon && /* @__PURE__ */ jsx("span", { className: styles["Menu-item-icon"], children: renderIcon }),
107
+ children
108
+ ] })
109
+ }
110
+ ) });
113
111
  if (tooltip) {
114
- return /* @__PURE__ */ jsx(Tooltip, {
115
- content: tooltip,
116
- rootElementStyle: {
117
- display: "block"
118
- },
119
- allowBoundaryElementOverflow: true,
120
- placement: tooltipPlacement ? tooltipPlacement : "bottom",
121
- ...tooltipOptions || {},
122
- children: renderedItem
123
- });
112
+ return /* @__PURE__ */ jsx(
113
+ Tooltip,
114
+ {
115
+ content: tooltip,
116
+ rootElementStyle: { display: "block" },
117
+ allowBoundaryElementOverflow: true,
118
+ placement: tooltipPlacement ? tooltipPlacement : "bottom",
119
+ ...tooltipOptions || {},
120
+ children: renderedItem
121
+ }
122
+ );
124
123
  }
125
124
  return renderedItem;
126
125
  };
127
- const MenuItemList = /* @__PURE__ */ forwardRef(({
128
- children,
129
- ...rest
130
- }, ref) => /* @__PURE__ */ jsx("div", {
131
- ...rest,
132
- ref,
133
- "data-test-id": "menu-item-list",
134
- className: styles["Menu-item-list"],
135
- children
136
- }));
126
+ const MenuItemList = /* @__PURE__ */ forwardRef(({ children, ...rest }, ref) => /* @__PURE__ */ jsx("div", { ...rest, ref, "data-test-id": "menu-item-list", className: styles["Menu-item-list"], children }));
137
127
  MenuItemList.displayName = "MenuItemList";
138
128
  const MenuSearch = /* @__PURE__ */ forwardRef((props, ref) => {
139
129
  const {
@@ -143,9 +133,9 @@ const MenuSearch = /* @__PURE__ */ forwardRef((props, ref) => {
143
133
  "data-test-id": testId = "menu-search",
144
134
  ...finalProps
145
135
  } = props;
146
- return /* @__PURE__ */ jsx("div", {
147
- className: styles["Menu-search"],
148
- children: /* @__PURE__ */ jsx(TextField, {
136
+ return /* @__PURE__ */ jsx("div", { className: styles["Menu-search"], children: /* @__PURE__ */ jsx(
137
+ TextField,
138
+ {
149
139
  ...finalProps,
150
140
  ref,
151
141
  className: styles["Menu-search-input"],
@@ -156,8 +146,8 @@ const MenuSearch = /* @__PURE__ */ forwardRef((props, ref) => {
156
146
  autoComplete: "off",
157
147
  placeholder,
158
148
  "aria-label": ariaLabel || "Search"
159
- })
160
- });
149
+ }
150
+ ) });
161
151
  });
162
152
  MenuSearch.displayName = "MenuSearch";
163
153
  const createItemId = (index, id) => `${id}-item-${index}`;
@@ -190,14 +180,10 @@ const Menu = (props) => {
190
180
  } = props;
191
181
  const focusManager = useFocusManager();
192
182
  const handleArrowDown = useCallback(() => {
193
- focusManager == null ? void 0 : focusManager.focusNext({
194
- wrap: true
195
- });
183
+ focusManager == null ? void 0 : focusManager.focusNext({ wrap: true });
196
184
  }, [focusManager]);
197
185
  const handleArrowUp = useCallback(() => {
198
- focusManager == null ? void 0 : focusManager.focusPrevious({
199
- wrap: true
200
- });
186
+ focusManager == null ? void 0 : focusManager.focusPrevious({ wrap: true });
201
187
  }, [focusManager]);
202
188
  const reduceItems = useMemo(() => {
203
189
  const childrenProps = Children.toArray(children);
@@ -215,70 +201,58 @@ const Menu = (props) => {
215
201
  break;
216
202
  }
217
203
  });
218
- return {
219
- items: elements,
220
- searchElement: searchElem
221
- };
204
+ return { items: elements, searchElement: searchElem };
222
205
  }
223
- return childrenProps.reduce(({
224
- items,
225
- searchElement
226
- }, child) => {
227
- switch (child.type) {
228
- case MenuSearch:
229
- return {
230
- items,
231
- searchElement: /* @__PURE__ */ cloneElement(child, {
232
- onKeyDown: (e) => handleKeyboardInteractions(e, {
233
- handleDown: handleArrowDown,
234
- handleUp: handleArrowUp
235
- })
236
- })
237
- };
238
- case MenuItem:
239
- return {
240
- items: items.concat(child.props.disabled ? /* @__PURE__ */ cloneElement(child, {
241
- className: cx(child.props.className, menuItemClassName),
242
- onClick: () => void 0,
243
- onKeyDown: () => void 0,
244
- tabIndex: -1,
245
- disabled: true
246
- }) : /* @__PURE__ */ cloneElement(child, {
247
- className: cx(child.props.className, menuItemClassName),
248
- item: child.props.item ?? items.length,
249
- // set focus on the first menu item if there is no search input, and set in the tab order
250
- onClick: chainEventHandlers(child.props.onClick, () => {
251
- onSelect == null ? void 0 : onSelect(child.props.item ?? items.length);
252
- }),
253
- onKeyDown: (e) => handleKeyboardInteractions(e, {
254
- handleDown: handleArrowDown,
255
- handleUp: handleArrowUp
206
+ return childrenProps.reduce(
207
+ ({ items, searchElement }, child) => {
208
+ switch (child.type) {
209
+ case MenuSearch:
210
+ return {
211
+ items,
212
+ searchElement: /* @__PURE__ */ cloneElement(child, {
213
+ onKeyDown: (e) => handleKeyboardInteractions(e, {
214
+ handleDown: handleArrowDown,
215
+ handleUp: handleArrowUp
216
+ })
256
217
  })
257
- })),
258
- searchElement
259
- };
260
- case MenuDivider:
261
- return {
262
- items: items.concat(child),
263
- searchElement
264
- };
265
- default:
266
- return {
267
- items,
268
- searchElement
269
- };
270
- }
271
- }, {
272
- items: [],
273
- searchElement: null
274
- });
218
+ };
219
+ case MenuItem:
220
+ return {
221
+ items: items.concat(
222
+ child.props.disabled ? /* @__PURE__ */ cloneElement(child, {
223
+ className: cx(child.props.className, menuItemClassName),
224
+ onClick: () => void 0,
225
+ onKeyDown: () => void 0,
226
+ tabIndex: -1,
227
+ disabled: true
228
+ }) : /* @__PURE__ */ cloneElement(child, {
229
+ className: cx(child.props.className, menuItemClassName),
230
+ item: child.props.item ?? items.length,
231
+ // set focus on the first menu item if there is no search input, and set in the tab order
232
+ onClick: chainEventHandlers(child.props.onClick, () => {
233
+ onSelect == null ? void 0 : onSelect(child.props.item ?? items.length);
234
+ }),
235
+ onKeyDown: (e) => handleKeyboardInteractions(e, {
236
+ handleDown: handleArrowDown,
237
+ handleUp: handleArrowUp
238
+ })
239
+ })
240
+ ),
241
+ searchElement
242
+ };
243
+ case MenuDivider:
244
+ return { items: items.concat(child), searchElement };
245
+ default:
246
+ return { items, searchElement };
247
+ }
248
+ },
249
+ { items: [], searchElement: null }
250
+ );
275
251
  }, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);
276
252
  if (enableVirtualization) {
277
- return /* @__PURE__ */ jsx(MenuBase, {
278
- "data-test-id": testId,
279
- isVirtual: true,
280
- size,
281
- children: /* @__PURE__ */ jsx(ItemVirtualizer, {
253
+ return /* @__PURE__ */ jsx(MenuBase, { "data-test-id": testId, isVirtual: true, size, children: /* @__PURE__ */ jsx(
254
+ ItemVirtualizer,
255
+ {
282
256
  items: Children.toArray(reduceItems.items),
283
257
  searchElement: reduceItems.searchElement,
284
258
  overscan,
@@ -286,17 +260,13 @@ const Menu = (props) => {
286
260
  onSelect,
287
261
  itemHeight,
288
262
  focusManager
289
- })
290
- });
263
+ }
264
+ ) });
291
265
  }
292
- return /* @__PURE__ */ jsxs(MenuBase, {
293
- "data-test-id": testId,
294
- size,
295
- children: [reduceItems.searchElement, /* @__PURE__ */ jsx(MenuItemList, {
296
- role: "presentation",
297
- children: reduceItems.items
298
- })]
299
- });
266
+ return /* @__PURE__ */ jsxs(MenuBase, { "data-test-id": testId, size, children: [
267
+ reduceItems.searchElement,
268
+ /* @__PURE__ */ jsx(MenuItemList, { role: "presentation", children: reduceItems.items })
269
+ ] });
300
270
  };
301
271
  const ItemVirtualizer = (props) => {
302
272
  const {
@@ -326,61 +296,70 @@ const ItemVirtualizer = (props) => {
326
296
  rowVirtualizer.scrollToIndex(0);
327
297
  (_b = (_a = searchRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
328
298
  }, [rowVirtualizer]);
329
- const focusMenuItem = useCallback((index) => {
330
- rowVirtualizer.scrollToIndex(index);
331
- setNextFocusValue(index);
332
- }, [rowVirtualizer]);
333
- const handleKeyboardFocusInteraction = useCallback((direction) => {
334
- if (focusedItemIndex.current === null || focusedItemIndex.current === void 0) {
335
- return;
336
- }
337
- const nextIndex = direction === "next" ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;
338
- const shouldWrap = direction === "next" && focusedItemIndex.current === lastVirtualItemIndex || direction === "previous" && focusedItemIndex.current === 0;
339
- if (shouldWrap) {
340
- if (hasSearch) {
341
- focusSearchBar();
342
- } else {
343
- focusMenuItem(direction === "next" ? 0 : lastVirtualItemIndex);
299
+ const focusMenuItem = useCallback(
300
+ (index) => {
301
+ rowVirtualizer.scrollToIndex(index);
302
+ setNextFocusValue(index);
303
+ },
304
+ [rowVirtualizer]
305
+ );
306
+ const handleKeyboardFocusInteraction = useCallback(
307
+ (direction) => {
308
+ if (focusedItemIndex.current === null || focusedItemIndex.current === void 0) {
309
+ return;
344
310
  }
345
- return;
346
- }
347
- switch (direction) {
348
- case "next":
349
- rowVirtualizer.scrollToIndex(nextIndex);
350
- focusManager == null ? void 0 : focusManager.focusNext();
351
- break;
352
- case "previous":
353
- rowVirtualizer.scrollToIndex(nextIndex);
354
- focusManager == null ? void 0 : focusManager.focusPrevious();
355
- break;
356
- }
357
- }, [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]);
358
- const getItemProps = useCallback((itemElem, index) => {
359
- const childProps = itemElem.props;
360
- switch (itemElem.type) {
361
- case MenuItem:
362
- return {
363
- className: cx(childProps.className, menuItemClassName),
364
- // set focus on the first menu item if there is no search input, and set in the tab order
365
- onKeyDown: childProps.disabled ? () => void 0 : (e) => handleKeyboardFocusKeydown(e, {
366
- handleFocusBackward: handleKeyboardFocusInteraction,
367
- handleFocusForward: handleKeyboardFocusInteraction
368
- }),
369
- onFocus: chainEventHandlers(childProps.onFocus, () => {
370
- focusedItemIndex.current = index;
371
- }),
372
- id: createItemId(index, menuId.current),
373
- onBlur: chainEventHandlers(childProps.onBlur, () => {
374
- focusedItemIndex.current = null;
375
- }),
376
- onClick: childProps.disabled ? () => void 0 : chainEventHandlers(childProps.onClick, () => {
377
- onSelect == null ? void 0 : onSelect(childProps.item);
378
- })
379
- };
380
- default:
381
- return {};
382
- }
383
- }, [handleKeyboardFocusInteraction, menuItemClassName, onSelect]);
311
+ const nextIndex = direction === "next" ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;
312
+ const shouldWrap = direction === "next" && focusedItemIndex.current === lastVirtualItemIndex || direction === "previous" && focusedItemIndex.current === 0;
313
+ if (shouldWrap) {
314
+ if (hasSearch) {
315
+ focusSearchBar();
316
+ } else {
317
+ focusMenuItem(direction === "next" ? 0 : lastVirtualItemIndex);
318
+ }
319
+ return;
320
+ }
321
+ switch (direction) {
322
+ case "next":
323
+ rowVirtualizer.scrollToIndex(nextIndex);
324
+ focusManager == null ? void 0 : focusManager.focusNext();
325
+ break;
326
+ case "previous":
327
+ rowVirtualizer.scrollToIndex(nextIndex);
328
+ focusManager == null ? void 0 : focusManager.focusPrevious();
329
+ break;
330
+ }
331
+ },
332
+ [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]
333
+ );
334
+ const getItemProps = useCallback(
335
+ (itemElem, index) => {
336
+ const childProps = itemElem.props;
337
+ switch (itemElem.type) {
338
+ case MenuItem:
339
+ return {
340
+ className: cx(childProps.className, menuItemClassName),
341
+ // set focus on the first menu item if there is no search input, and set in the tab order
342
+ onKeyDown: childProps.disabled ? () => void 0 : (e) => handleKeyboardFocusKeydown(e, {
343
+ handleFocusBackward: handleKeyboardFocusInteraction,
344
+ handleFocusForward: handleKeyboardFocusInteraction
345
+ }),
346
+ onFocus: chainEventHandlers(childProps.onFocus, () => {
347
+ focusedItemIndex.current = index;
348
+ }),
349
+ id: createItemId(index, menuId.current),
350
+ onBlur: chainEventHandlers(childProps.onBlur, () => {
351
+ focusedItemIndex.current = null;
352
+ }),
353
+ onClick: childProps.disabled ? () => void 0 : chainEventHandlers(childProps.onClick, () => {
354
+ onSelect == null ? void 0 : onSelect(childProps.item);
355
+ })
356
+ };
357
+ default:
358
+ return {};
359
+ }
360
+ },
361
+ [handleKeyboardFocusInteraction, menuItemClassName, onSelect]
362
+ );
384
363
  useEffect(() => {
385
364
  if (nextFocusValue !== null) {
386
365
  requestAnimationFrame(() => {
@@ -403,42 +382,52 @@ const ItemVirtualizer = (props) => {
403
382
  }
404
383
  }
405
384
  };
406
- const renderSearch = useMemo(() => searchElement ? /* @__PURE__ */ cloneElement(searchElement, {
407
- onKeyDown: (e) => handleKeyboardFocusKeydown(e, {
408
- handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),
409
- handleFocusForward: () => focusMenuItem(0)
385
+ const renderSearch = useMemo(
386
+ () => searchElement ? /* @__PURE__ */ cloneElement(searchElement, {
387
+ onKeyDown: (e) => handleKeyboardFocusKeydown(e, {
388
+ handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),
389
+ handleFocusForward: () => focusMenuItem(0)
390
+ }),
391
+ ref: searchRef
392
+ }) : null,
393
+ [searchElement, lastVirtualItemIndex, focusMenuItem]
394
+ );
395
+ const renderItems = useMemo(
396
+ () => rowVirtualizer.virtualItems.map((virtualRow) => {
397
+ if (!items) {
398
+ return null;
399
+ }
400
+ const elem = items[virtualRow.index];
401
+ return /* @__PURE__ */ jsx(
402
+ "div",
403
+ {
404
+ ref: virtualRow.measureRef,
405
+ role: "presentation",
406
+ className: styles["VirtualMenu-item"],
407
+ style: {
408
+ transform: `translateY(${virtualRow.start}px)`
409
+ },
410
+ children: /* @__PURE__ */ cloneElement(elem, getItemProps(elem, virtualRow.index))
411
+ },
412
+ virtualRow.index
413
+ );
410
414
  }),
411
- ref: searchRef
412
- }) : null, [searchElement, lastVirtualItemIndex, focusMenuItem]);
413
- const renderItems = useMemo(() => rowVirtualizer.virtualItems.map((virtualRow) => {
414
- if (!items) {
415
- return null;
416
- }
417
- const elem = items[virtualRow.index];
418
- return /* @__PURE__ */ jsx("div", {
419
- ref: virtualRow.measureRef,
420
- role: "presentation",
421
- className: styles["VirtualMenu-item"],
422
- style: {
423
- transform: `translateY(${virtualRow.start}px)`
424
- },
425
- children: /* @__PURE__ */ cloneElement(elem, getItemProps(elem, virtualRow.index))
426
- }, virtualRow.index);
427
- }), [rowVirtualizer.virtualItems, items, getItemProps]);
428
- return /* @__PURE__ */ jsxs(Fragment, {
429
- children: [renderSearch, /* @__PURE__ */ jsx(MenuItemList, {
430
- ref: parentRef,
431
- role: "presentation",
432
- children: /* @__PURE__ */ jsx("div", {
415
+ [rowVirtualizer.virtualItems, items, getItemProps]
416
+ );
417
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
418
+ renderSearch,
419
+ /* @__PURE__ */ jsx(MenuItemList, { ref: parentRef, role: "presentation", children: /* @__PURE__ */ jsx(
420
+ "div",
421
+ {
433
422
  role: "presentation",
434
423
  className: styles["VirtualMenu-item-list"],
435
424
  style: {
436
425
  height: `${rowVirtualizer.totalSize}px`
437
426
  },
438
427
  children: renderItems
439
- })
440
- })]
441
- });
428
+ }
429
+ ) })
430
+ ] });
442
431
  };
443
432
  export {
444
433
  Menu,