@launchpad-ui/menu 0.4.8 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Menu.d.ts +3 -3
- package/dist/Menu.d.ts.map +1 -1
- package/dist/MenuBase.d.ts +2 -2
- package/dist/MenuBase.d.ts.map +1 -1
- package/dist/MenuDivider.d.ts +2 -2
- package/dist/MenuDivider.d.ts.map +1 -1
- package/dist/MenuItem.d.ts +8 -8
- package/dist/MenuItem.d.ts.map +1 -1
- package/dist/MenuItemList.d.ts +2 -2
- package/dist/MenuItemList.d.ts.map +1 -1
- package/dist/index.es.js +233 -270
- package/dist/index.es.js.map +1 -7
- package/dist/index.js +263 -325
- package/dist/index.js.map +1 -7
- package/dist/style.css +222 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/styles/Menu.css +0 -2
- package/dist/styles/Menu.css.map +0 -1
package/dist/index.es.js
CHANGED
@@ -1,49 +1,51 @@
|
|
1
|
-
|
1
|
+
import './style.css';
|
2
2
|
import { cx } from "classix";
|
3
|
-
import { forwardRef } from "react";
|
4
|
-
import "
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
6
|
-
var MenuBase = forwardRef(
|
7
|
-
({ children, size, isVirtual, ...props }, ref) => {
|
8
|
-
const classes = cx("Menu", isVirtual && "Menu--isVirtual", size && `MenuSize--${size}`);
|
9
|
-
return /* @__PURE__ */ jsx("div", {
|
10
|
-
...props,
|
11
|
-
role: "menu",
|
12
|
-
className: classes,
|
13
|
-
ref,
|
14
|
-
children
|
15
|
-
});
|
16
|
-
}
|
17
|
-
);
|
18
|
-
MenuBase.displayName = "MenuBase";
|
19
|
-
|
20
|
-
// src/MenuDivider.tsx
|
3
|
+
import { forwardRef, useCallback, useMemo, Children, cloneElement, useRef, useId, useState, useEffect } from "react";
|
4
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
21
5
|
import { useSeparator } from "@react-aria/separator";
|
22
|
-
import "
|
23
|
-
import {
|
24
|
-
|
25
|
-
|
6
|
+
import { IconSize } from "@launchpad-ui/icons";
|
7
|
+
import { Tooltip } from "@launchpad-ui/tooltip";
|
8
|
+
import { Slot } from "@radix-ui/react-slot";
|
9
|
+
import { FocusRing, useFocusManager } from "@react-aria/focus";
|
10
|
+
import { Link } from "react-router-dom";
|
11
|
+
import { TextField } from "@launchpad-ui/form";
|
12
|
+
import { useVirtual } from "react-virtual";
|
13
|
+
const Menu$1 = "";
|
14
|
+
const MenuBase = forwardRef(({
|
15
|
+
children,
|
16
|
+
size,
|
17
|
+
isVirtual,
|
18
|
+
...props
|
19
|
+
}, ref) => {
|
20
|
+
const classes = cx("Menu", isVirtual && "Menu--isVirtual", size && `MenuSize--${size}`);
|
21
|
+
return /* @__PURE__ */ jsx("div", {
|
22
|
+
...props,
|
23
|
+
role: "menu",
|
24
|
+
className: classes,
|
25
|
+
ref,
|
26
|
+
children
|
27
|
+
});
|
28
|
+
});
|
29
|
+
MenuBase.displayName = "MenuBase";
|
30
|
+
const MenuDivider = ({
|
31
|
+
elementType = "div",
|
32
|
+
orientation,
|
33
|
+
innerRef
|
34
|
+
}) => {
|
35
|
+
const {
|
36
|
+
separatorProps
|
37
|
+
} = useSeparator({
|
26
38
|
orientation,
|
27
39
|
elementType
|
28
40
|
});
|
29
|
-
return /* @__PURE__ */
|
41
|
+
return /* @__PURE__ */ jsx("div", {
|
30
42
|
...separatorProps,
|
31
43
|
ref: innerRef,
|
32
44
|
className: "Menu-divider"
|
33
45
|
});
|
34
46
|
};
|
35
|
-
|
36
|
-
|
37
|
-
import { IconSize } from "@launchpad-ui/icons";
|
38
|
-
import { Tooltip } from "@launchpad-ui/tooltip";
|
39
|
-
import { Slot } from "@radix-ui/react-slot";
|
40
|
-
import { FocusRing } from "@react-aria/focus";
|
41
|
-
import { cx as cx2 } from "classix";
|
42
|
-
import { Link } from "react-router-dom";
|
43
|
-
import "./styles/Menu.css";
|
44
|
-
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
45
|
-
var defaultElement = "button";
|
46
|
-
var MenuItem = ({
|
47
|
+
const defaultElement = "button";
|
48
|
+
const MenuItem = ({
|
47
49
|
...props
|
48
50
|
}) => {
|
49
51
|
const {
|
@@ -65,38 +67,31 @@ var MenuItem = ({
|
|
65
67
|
...rest
|
66
68
|
} = props;
|
67
69
|
const Component = component || (asChild ? Slot : defaultElement);
|
68
|
-
const renderedItem = /* @__PURE__ */
|
70
|
+
const renderedItem = /* @__PURE__ */ jsx(FocusRing, {
|
69
71
|
focusRingClass: "has-focus",
|
70
|
-
children: /* @__PURE__ */
|
72
|
+
children: /* @__PURE__ */ jsx(Component, {
|
71
73
|
...rest,
|
72
74
|
disabled,
|
73
75
|
"aria-disabled": disabled ? disabled : void 0,
|
74
|
-
className:
|
75
|
-
"Menu-item",
|
76
|
-
className,
|
77
|
-
isHighlighted && "is-highlighted",
|
78
|
-
nested && "Menu-item--nested",
|
79
|
-
groupHeader && "Menu-item--header"
|
80
|
-
),
|
76
|
+
className: cx("Menu-item", className, isHighlighted && "is-highlighted", nested && "Menu-item--nested", groupHeader && "Menu-item--header"),
|
81
77
|
role,
|
82
78
|
onKeyDown,
|
83
79
|
children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, {
|
84
|
-
children: [
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
}),
|
91
|
-
children
|
92
|
-
]
|
80
|
+
children: [Icon && /* @__PURE__ */ jsx("span", {
|
81
|
+
className: "Menu-item-icon",
|
82
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
83
|
+
size: IconSize.SMALL
|
84
|
+
})
|
85
|
+
}), children]
|
93
86
|
})
|
94
87
|
})
|
95
88
|
});
|
96
89
|
if (tooltip) {
|
97
|
-
return /* @__PURE__ */
|
90
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
98
91
|
content: tooltip,
|
99
|
-
rootElementStyle: {
|
92
|
+
rootElementStyle: {
|
93
|
+
display: "block"
|
94
|
+
},
|
100
95
|
allowBoundaryElementOverflow: true,
|
101
96
|
placement: tooltipPlacement ? tooltipPlacement : "bottom",
|
102
97
|
...tooltipOptions || {},
|
@@ -105,7 +100,7 @@ var MenuItem = ({
|
|
105
100
|
}
|
106
101
|
return renderedItem;
|
107
102
|
};
|
108
|
-
|
103
|
+
const MenuItemLink = ({
|
109
104
|
to,
|
110
105
|
disabled = false,
|
111
106
|
useHistory = true,
|
@@ -121,17 +116,15 @@ var MenuItemLink = ({
|
|
121
116
|
rel: newTab ? "noopener noreferrer" : void 0,
|
122
117
|
target: newTab ? "_blank" : void 0
|
123
118
|
};
|
124
|
-
return /* @__PURE__ */
|
119
|
+
return /* @__PURE__ */ jsx(MenuItem, {
|
125
120
|
...finalProps,
|
126
121
|
children
|
127
122
|
});
|
128
123
|
};
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
134
|
-
var MenuItemList = forwardRef2(({ children, ...rest }, ref) => /* @__PURE__ */ jsx4("div", {
|
124
|
+
const MenuItemList = forwardRef(({
|
125
|
+
children,
|
126
|
+
...rest
|
127
|
+
}, ref) => /* @__PURE__ */ jsx("div", {
|
135
128
|
...rest,
|
136
129
|
ref,
|
137
130
|
"data-test-id": "menu-item-list",
|
@@ -139,17 +132,15 @@ var MenuItemList = forwardRef2(({ children, ...rest }, ref) => /* @__PURE__ */ j
|
|
139
132
|
children
|
140
133
|
}));
|
141
134
|
MenuItemList.displayName = "MenuItemList";
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
const { ariaLabel, placeholder, ...finalProps } = props;
|
150
|
-
return /* @__PURE__ */ jsx5("div", {
|
135
|
+
const MenuSearch = forwardRef((props, ref) => {
|
136
|
+
const {
|
137
|
+
ariaLabel,
|
138
|
+
placeholder,
|
139
|
+
...finalProps
|
140
|
+
} = props;
|
141
|
+
return /* @__PURE__ */ jsx("div", {
|
151
142
|
className: "Menu-search",
|
152
|
-
children: /* @__PURE__ */
|
143
|
+
children: /* @__PURE__ */ jsx(TextField, {
|
153
144
|
...finalProps,
|
154
145
|
ref,
|
155
146
|
className: "Menu-search-input",
|
@@ -162,26 +153,10 @@ var MenuSearch = forwardRef3((props, ref) => {
|
|
162
153
|
});
|
163
154
|
});
|
164
155
|
MenuSearch.displayName = "MenuSearch";
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
import {
|
170
|
-
Children,
|
171
|
-
cloneElement,
|
172
|
-
useCallback,
|
173
|
-
useEffect,
|
174
|
-
useId,
|
175
|
-
useMemo,
|
176
|
-
useRef,
|
177
|
-
useState
|
178
|
-
} from "react";
|
179
|
-
import { useVirtual } from "react-virtual";
|
180
|
-
|
181
|
-
// src/utils.ts
|
182
|
-
var createItemId = (index, id) => `${id}-item-${index}`;
|
183
|
-
var getNodeForIndex = (index, menuId) => index === null ? index : document.getElementById(createItemId(index, menuId));
|
184
|
-
var handleKeyboardInteractions = (event, keyHandlers) => {
|
156
|
+
const createItemId = (index, id) => `${id}-item-${index}`;
|
157
|
+
const getNodeForIndex = (index, menuId) => index === null ? index : document.getElementById(createItemId(index, menuId));
|
158
|
+
const handleKeyboardInteractions = (event, keyHandlers) => {
|
159
|
+
var _a;
|
185
160
|
const ops = {
|
186
161
|
ArrowUp: keyHandlers.handleUp,
|
187
162
|
ArrowDown: keyHandlers.handleDown,
|
@@ -189,16 +164,13 @@ var handleKeyboardInteractions = (event, keyHandlers) => {
|
|
189
164
|
};
|
190
165
|
if (ops[event.key]) {
|
191
166
|
event.preventDefault();
|
192
|
-
ops[event.key]
|
167
|
+
(_a = ops[event.key]) == null ? void 0 : _a.call(globalThis, event);
|
193
168
|
}
|
194
169
|
};
|
195
|
-
|
170
|
+
const chainEventHandlers = (...handlers) => (event) => {
|
196
171
|
handlers.forEach((h) => typeof h === "function" && h(event));
|
197
172
|
};
|
198
|
-
|
199
|
-
// src/Menu.tsx
|
200
|
-
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
201
|
-
var Menu = (props) => {
|
173
|
+
const Menu = (props) => {
|
202
174
|
const {
|
203
175
|
children,
|
204
176
|
menuItemClassName,
|
@@ -210,10 +182,14 @@ var Menu = (props) => {
|
|
210
182
|
} = props;
|
211
183
|
const focusManager = useFocusManager();
|
212
184
|
const handleArrowDown = useCallback(() => {
|
213
|
-
focusManager.focusNext({
|
185
|
+
focusManager.focusNext({
|
186
|
+
wrap: true
|
187
|
+
});
|
214
188
|
}, [focusManager]);
|
215
189
|
const handleArrowUp = useCallback(() => {
|
216
|
-
focusManager.focusPrevious({
|
190
|
+
focusManager.focusPrevious({
|
191
|
+
wrap: true
|
192
|
+
});
|
217
193
|
}, [focusManager]);
|
218
194
|
const reduceItems = useMemo(() => {
|
219
195
|
const childrenProps = Children.toArray(children);
|
@@ -230,62 +206,72 @@ var Menu = (props) => {
|
|
230
206
|
case MenuDivider:
|
231
207
|
elements = elements.concat(child);
|
232
208
|
break;
|
233
|
-
default:
|
234
|
-
break;
|
235
209
|
}
|
236
210
|
});
|
237
|
-
return {
|
211
|
+
return {
|
212
|
+
items: elements,
|
213
|
+
searchElement: searchElem
|
214
|
+
};
|
238
215
|
}
|
239
|
-
return childrenProps.reduce(
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
216
|
+
return childrenProps.reduce(({
|
217
|
+
items,
|
218
|
+
searchElement
|
219
|
+
}, child) => {
|
220
|
+
var _a;
|
221
|
+
switch (child.type) {
|
222
|
+
case MenuSearch:
|
223
|
+
return {
|
224
|
+
items,
|
225
|
+
searchElement: cloneElement(child, {
|
226
|
+
onKeyDown: (e) => handleKeyboardInteractions(e, {
|
227
|
+
handleDown: handleArrowDown,
|
228
|
+
handleUp: handleArrowUp
|
250
229
|
})
|
251
|
-
}
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
230
|
+
})
|
231
|
+
};
|
232
|
+
case MenuItem:
|
233
|
+
case MenuItemLink:
|
234
|
+
return {
|
235
|
+
items: items.concat(child.props.disabled ? cloneElement(child, {
|
236
|
+
onClick: () => void 0,
|
237
|
+
onKeyDown: () => void 0,
|
238
|
+
tabIndex: -1,
|
239
|
+
disabled: true
|
240
|
+
}) : cloneElement(child, {
|
241
|
+
className: cx(child.props.className, menuItemClassName),
|
242
|
+
item: (_a = child.props.item) != null ? _a : items.length,
|
243
|
+
onClick: chainEventHandlers(child.props.onClick, () => {
|
244
|
+
var _a2;
|
245
|
+
onSelect == null ? void 0 : onSelect((_a2 = child.props.item) != null ? _a2 : items.length);
|
246
|
+
}),
|
247
|
+
onKeyDown: (e) => handleKeyboardInteractions(e, {
|
248
|
+
handleDown: handleArrowDown,
|
249
|
+
handleUp: handleArrowUp
|
250
|
+
})
|
251
|
+
})),
|
252
|
+
searchElement
|
253
|
+
};
|
254
|
+
case MenuDivider:
|
255
|
+
return {
|
256
|
+
items: items.concat(child),
|
257
|
+
searchElement
|
258
|
+
};
|
259
|
+
default:
|
260
|
+
return {
|
261
|
+
items,
|
262
|
+
searchElement
|
263
|
+
};
|
264
|
+
}
|
265
|
+
}, {
|
266
|
+
items: [],
|
267
|
+
searchElement: null
|
268
|
+
});
|
283
269
|
}, [children, enableVirtualization, menuItemClassName, handleArrowDown, handleArrowUp, onSelect]);
|
284
270
|
if (enableVirtualization) {
|
285
|
-
return /* @__PURE__ */
|
271
|
+
return /* @__PURE__ */ jsx(MenuBase, {
|
286
272
|
isVirtual: true,
|
287
273
|
size,
|
288
|
-
children: /* @__PURE__ */
|
274
|
+
children: /* @__PURE__ */ jsx(ItemVirtualizer, {
|
289
275
|
items: Children.toArray(reduceItems.items),
|
290
276
|
searchElement: reduceItems.searchElement,
|
291
277
|
overscan,
|
@@ -296,18 +282,15 @@ var Menu = (props) => {
|
|
296
282
|
})
|
297
283
|
});
|
298
284
|
}
|
299
|
-
return /* @__PURE__ */
|
285
|
+
return /* @__PURE__ */ jsxs(MenuBase, {
|
300
286
|
size,
|
301
|
-
children: [
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
children: reduceItems.items
|
306
|
-
})
|
307
|
-
]
|
287
|
+
children: [reduceItems.searchElement, /* @__PURE__ */ jsx(MenuItemList, {
|
288
|
+
role: "presentation",
|
289
|
+
children: reduceItems.items
|
290
|
+
})]
|
308
291
|
});
|
309
292
|
};
|
310
|
-
|
293
|
+
const ItemVirtualizer = (props) => {
|
311
294
|
const {
|
312
295
|
overscan,
|
313
296
|
searchElement,
|
@@ -331,144 +314,124 @@ var ItemVirtualizer = (props) => {
|
|
331
314
|
overscan
|
332
315
|
});
|
333
316
|
const focusSearchBar = useCallback(() => {
|
317
|
+
var _a, _b;
|
334
318
|
rowVirtualizer.scrollToIndex(0);
|
335
|
-
searchRef.current
|
319
|
+
(_b = (_a = searchRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
336
320
|
}, [rowVirtualizer]);
|
337
|
-
const focusMenuItem = useCallback(
|
338
|
-
(index)
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
if (hasSearch) {
|
353
|
-
focusSearchBar();
|
354
|
-
} else {
|
355
|
-
focusMenuItem(direction === "next" ? 0 : lastVirtualItemIndex);
|
356
|
-
}
|
357
|
-
return;
|
358
|
-
}
|
359
|
-
switch (direction) {
|
360
|
-
case "next":
|
361
|
-
rowVirtualizer.scrollToIndex(nextIndex);
|
362
|
-
focusManager.focusNext();
|
363
|
-
break;
|
364
|
-
case "previous":
|
365
|
-
rowVirtualizer.scrollToIndex(nextIndex);
|
366
|
-
focusManager.focusPrevious();
|
367
|
-
break;
|
368
|
-
default:
|
369
|
-
break;
|
370
|
-
}
|
371
|
-
},
|
372
|
-
[focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]
|
373
|
-
);
|
374
|
-
const getItemProps = useCallback(
|
375
|
-
(itemElem, index) => {
|
376
|
-
const childProps = itemElem.props;
|
377
|
-
switch (itemElem.type) {
|
378
|
-
case MenuItem:
|
379
|
-
case MenuItemLink:
|
380
|
-
return {
|
381
|
-
className: cx3(childProps.className, menuItemClassName),
|
382
|
-
onKeyDown: childProps.disabled ? () => void 0 : (e) => handleKeyboardFocusKeydown(e, {
|
383
|
-
handleFocusBackward: handleKeyboardFocusInteraction,
|
384
|
-
handleFocusForward: handleKeyboardFocusInteraction
|
385
|
-
}),
|
386
|
-
onFocus: chainEventHandlers(childProps.onFocus, () => {
|
387
|
-
focusedItemIndex.current = index;
|
388
|
-
}),
|
389
|
-
id: createItemId(index, menuId.current),
|
390
|
-
onBlur: chainEventHandlers(childProps.onBlur, () => {
|
391
|
-
focusedItemIndex.current = null;
|
392
|
-
}),
|
393
|
-
onClick: childProps.disabled ? () => void 0 : chainEventHandlers(childProps.onClick, () => {
|
394
|
-
onSelect?.(childProps.item);
|
395
|
-
})
|
396
|
-
};
|
397
|
-
default:
|
398
|
-
return {};
|
321
|
+
const focusMenuItem = useCallback((index) => {
|
322
|
+
rowVirtualizer.scrollToIndex(index);
|
323
|
+
setNextFocusValue(index);
|
324
|
+
}, [rowVirtualizer]);
|
325
|
+
const handleKeyboardFocusInteraction = useCallback((direction) => {
|
326
|
+
if (focusedItemIndex.current === null || focusedItemIndex.current === void 0) {
|
327
|
+
return;
|
328
|
+
}
|
329
|
+
const nextIndex = direction === "next" ? focusedItemIndex.current + 1 : focusedItemIndex.current - 1;
|
330
|
+
const shouldWrap = direction === "next" && focusedItemIndex.current === lastVirtualItemIndex || direction === "previous" && focusedItemIndex.current === 0;
|
331
|
+
if (shouldWrap) {
|
332
|
+
if (hasSearch) {
|
333
|
+
focusSearchBar();
|
334
|
+
} else {
|
335
|
+
focusMenuItem(direction === "next" ? 0 : lastVirtualItemIndex);
|
399
336
|
}
|
400
|
-
|
401
|
-
|
402
|
-
|
337
|
+
return;
|
338
|
+
}
|
339
|
+
switch (direction) {
|
340
|
+
case "next":
|
341
|
+
rowVirtualizer.scrollToIndex(nextIndex);
|
342
|
+
focusManager.focusNext();
|
343
|
+
break;
|
344
|
+
case "previous":
|
345
|
+
rowVirtualizer.scrollToIndex(nextIndex);
|
346
|
+
focusManager.focusPrevious();
|
347
|
+
break;
|
348
|
+
}
|
349
|
+
}, [focusManager, focusMenuItem, focusSearchBar, hasSearch, lastVirtualItemIndex, rowVirtualizer]);
|
350
|
+
const getItemProps = useCallback((itemElem, index) => {
|
351
|
+
const childProps = itemElem.props;
|
352
|
+
switch (itemElem.type) {
|
353
|
+
case MenuItem:
|
354
|
+
case MenuItemLink:
|
355
|
+
return {
|
356
|
+
className: cx(childProps.className, menuItemClassName),
|
357
|
+
onKeyDown: childProps.disabled ? () => void 0 : (e) => handleKeyboardFocusKeydown(e, {
|
358
|
+
handleFocusBackward: handleKeyboardFocusInteraction,
|
359
|
+
handleFocusForward: handleKeyboardFocusInteraction
|
360
|
+
}),
|
361
|
+
onFocus: chainEventHandlers(childProps.onFocus, () => {
|
362
|
+
focusedItemIndex.current = index;
|
363
|
+
}),
|
364
|
+
id: createItemId(index, menuId.current),
|
365
|
+
onBlur: chainEventHandlers(childProps.onBlur, () => {
|
366
|
+
focusedItemIndex.current = null;
|
367
|
+
}),
|
368
|
+
onClick: childProps.disabled ? () => void 0 : chainEventHandlers(childProps.onClick, () => {
|
369
|
+
onSelect == null ? void 0 : onSelect(childProps.item);
|
370
|
+
})
|
371
|
+
};
|
372
|
+
default:
|
373
|
+
return {};
|
374
|
+
}
|
375
|
+
}, [handleKeyboardFocusInteraction, menuItemClassName, onSelect]);
|
403
376
|
useEffect(() => {
|
404
377
|
if (nextFocusValue !== null) {
|
405
378
|
requestAnimationFrame(() => {
|
406
379
|
const element = getNodeForIndex(nextFocusValue, menuId.current);
|
407
|
-
element
|
380
|
+
element == null ? void 0 : element.focus();
|
408
381
|
});
|
409
382
|
setNextFocusValue(null);
|
410
383
|
}
|
411
384
|
}, [nextFocusValue]);
|
412
385
|
const handleKeyboardFocusKeydown = (e, callbacks) => {
|
386
|
+
var _a, _b;
|
413
387
|
const keyOps = ["Tab", "ArrowUp", "ArrowDown"];
|
414
388
|
if (keyOps.includes(e.key)) {
|
415
389
|
e.preventDefault();
|
416
390
|
e.stopPropagation();
|
417
391
|
if (e.key === "Tab" && e.shiftKey || e.key === "ArrowUp") {
|
418
|
-
callbacks.handleFocusBackward
|
392
|
+
(_a = callbacks.handleFocusBackward) == null ? void 0 : _a.call(callbacks, "previous");
|
419
393
|
} else if (e.key === "ArrowDown" || e.key === "Tab") {
|
420
|
-
callbacks.handleFocusForward
|
394
|
+
(_b = callbacks.handleFocusForward) == null ? void 0 : _b.call(callbacks, "next");
|
421
395
|
}
|
422
396
|
}
|
423
397
|
};
|
424
|
-
const renderSearch = useMemo(
|
425
|
-
() =>
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
398
|
+
const renderSearch = useMemo(() => searchElement ? cloneElement(searchElement, {
|
399
|
+
onKeyDown: (e) => handleKeyboardFocusKeydown(e, {
|
400
|
+
handleFocusBackward: () => focusMenuItem(lastVirtualItemIndex),
|
401
|
+
handleFocusForward: () => focusMenuItem(0)
|
402
|
+
}),
|
403
|
+
ref: searchRef
|
404
|
+
}) : null, [searchElement, lastVirtualItemIndex, focusMenuItem]);
|
405
|
+
const renderItems = useMemo(() => rowVirtualizer.virtualItems.map((virtualRow) => {
|
406
|
+
if (!items) {
|
407
|
+
return null;
|
408
|
+
}
|
409
|
+
const elem = items[virtualRow.index];
|
410
|
+
return /* @__PURE__ */ jsx("div", {
|
411
|
+
ref: elem.type !== MenuItem || elem.type !== MenuItemLink ? virtualRow.measureRef : void 0,
|
412
|
+
role: "presentation",
|
413
|
+
className: cx("VirtualMenu-item"),
|
414
|
+
style: {
|
415
|
+
transform: `translateY(${virtualRow.start}px)`
|
416
|
+
},
|
417
|
+
children: cloneElement(elem, getItemProps(elem, virtualRow.index))
|
418
|
+
}, virtualRow.index);
|
419
|
+
}), [rowVirtualizer.virtualItems, items, getItemProps]);
|
420
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
421
|
+
children: [renderSearch, /* @__PURE__ */ jsx(MenuItemList, {
|
422
|
+
ref: parentRef,
|
423
|
+
role: "presentation",
|
424
|
+
children: /* @__PURE__ */ jsx("div", {
|
442
425
|
role: "presentation",
|
443
|
-
className:
|
426
|
+
className: "VirtualMenu-item-list",
|
444
427
|
style: {
|
445
|
-
|
428
|
+
height: `${rowVirtualizer.totalSize}px`
|
446
429
|
},
|
447
|
-
children:
|
448
|
-
}, virtualRow.index);
|
449
|
-
}),
|
450
|
-
[rowVirtualizer.virtualItems, items, getItemProps]
|
451
|
-
);
|
452
|
-
return /* @__PURE__ */ jsxs2(Fragment2, {
|
453
|
-
children: [
|
454
|
-
renderSearch,
|
455
|
-
/* @__PURE__ */ jsx6(MenuItemList, {
|
456
|
-
ref: parentRef,
|
457
|
-
role: "presentation",
|
458
|
-
children: /* @__PURE__ */ jsx6("div", {
|
459
|
-
role: "presentation",
|
460
|
-
className: "VirtualMenu-item-list",
|
461
|
-
style: {
|
462
|
-
height: `${rowVirtualizer.totalSize}px`
|
463
|
-
},
|
464
|
-
children: renderItems
|
465
|
-
})
|
430
|
+
children: renderItems
|
466
431
|
})
|
467
|
-
]
|
432
|
+
})]
|
468
433
|
});
|
469
434
|
};
|
470
|
-
|
471
|
-
// src/types.ts
|
472
435
|
var MenuSize = /* @__PURE__ */ ((MenuSize2) => {
|
473
436
|
MenuSize2["SMALL"] = "sm";
|
474
437
|
MenuSize2["MEDIUM"] = "md";
|