@radix-ui/react-menu 2.0.7-rc.9 → 2.1.0-rc.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/index.d.mts +82 -70
- package/dist/index.d.ts +82 -70
- package/dist/index.js +807 -974
- package/dist/index.js.map +7 -1
- package/dist/index.mjs +802 -926
- package/dist/index.mjs.map +7 -1
- package/package.json +17 -18
- package/dist/index.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,993 +1,869 @@
|
|
|
1
|
-
|
|
2
|
-
import {useState as $epM9y$useState, useRef as $epM9y$useRef, useEffect as $epM9y$useEffect, createElement as $epM9y$createElement, useCallback as $epM9y$useCallback, forwardRef as $epM9y$forwardRef, Fragment as $epM9y$Fragment} from "react";
|
|
3
|
-
import {composeEventHandlers as $epM9y$composeEventHandlers} from "@radix-ui/primitive";
|
|
4
|
-
import {createCollection as $epM9y$createCollection} from "@radix-ui/react-collection";
|
|
5
|
-
import {useComposedRefs as $epM9y$useComposedRefs, composeRefs as $epM9y$composeRefs} from "@radix-ui/react-compose-refs";
|
|
6
|
-
import {createContextScope as $epM9y$createContextScope} from "@radix-ui/react-context";
|
|
7
|
-
import {useDirection as $epM9y$useDirection} from "@radix-ui/react-direction";
|
|
8
|
-
import {DismissableLayer as $epM9y$DismissableLayer} from "@radix-ui/react-dismissable-layer";
|
|
9
|
-
import {useFocusGuards as $epM9y$useFocusGuards} from "@radix-ui/react-focus-guards";
|
|
10
|
-
import {FocusScope as $epM9y$FocusScope} from "@radix-ui/react-focus-scope";
|
|
11
|
-
import {useId as $epM9y$useId} from "@radix-ui/react-id";
|
|
12
|
-
import {createPopperScope as $epM9y$createPopperScope, Root as $epM9y$Root, Anchor as $epM9y$Anchor, Content as $epM9y$Content, Arrow as $epM9y$Arrow} from "@radix-ui/react-popper";
|
|
13
|
-
import {Portal as $epM9y$Portal} from "@radix-ui/react-portal";
|
|
14
|
-
import {Presence as $epM9y$Presence} from "@radix-ui/react-presence";
|
|
15
|
-
import {Primitive as $epM9y$Primitive, dispatchDiscreteCustomEvent as $epM9y$dispatchDiscreteCustomEvent} from "@radix-ui/react-primitive";
|
|
16
|
-
import {createRovingFocusGroupScope as $epM9y$createRovingFocusGroupScope, Root as $epM9y$Root1, Item as $epM9y$Item} from "@radix-ui/react-roving-focus";
|
|
17
|
-
import {Slot as $epM9y$Slot} from "@radix-ui/react-slot";
|
|
18
|
-
import {useCallbackRef as $epM9y$useCallbackRef} from "@radix-ui/react-use-callback-ref";
|
|
19
|
-
import {hideOthers as $epM9y$hideOthers} from "aria-hidden";
|
|
20
|
-
import {RemoveScroll as $epM9y$RemoveScroll} from "react-remove-scroll";
|
|
1
|
+
"use client";
|
|
21
2
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
];
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
];
|
|
53
|
-
const $6cc32821e9371a1c$var$LAST_KEYS = [
|
|
54
|
-
'ArrowUp',
|
|
55
|
-
'PageDown',
|
|
56
|
-
'End'
|
|
57
|
-
];
|
|
58
|
-
const $6cc32821e9371a1c$var$FIRST_LAST_KEYS = [
|
|
59
|
-
...$6cc32821e9371a1c$var$FIRST_KEYS,
|
|
60
|
-
...$6cc32821e9371a1c$var$LAST_KEYS
|
|
61
|
-
];
|
|
62
|
-
const $6cc32821e9371a1c$var$SUB_OPEN_KEYS = {
|
|
63
|
-
ltr: [
|
|
64
|
-
...$6cc32821e9371a1c$var$SELECTION_KEYS,
|
|
65
|
-
'ArrowRight'
|
|
66
|
-
],
|
|
67
|
-
rtl: [
|
|
68
|
-
...$6cc32821e9371a1c$var$SELECTION_KEYS,
|
|
69
|
-
'ArrowLeft'
|
|
70
|
-
]
|
|
3
|
+
// packages/react/menu/src/Menu.tsx
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { composeEventHandlers } from "@radix-ui/primitive";
|
|
6
|
+
import { createCollection } from "@radix-ui/react-collection";
|
|
7
|
+
import { useComposedRefs, composeRefs } from "@radix-ui/react-compose-refs";
|
|
8
|
+
import { createContextScope } from "@radix-ui/react-context";
|
|
9
|
+
import { useDirection } from "@radix-ui/react-direction";
|
|
10
|
+
import { DismissableLayer } from "@radix-ui/react-dismissable-layer";
|
|
11
|
+
import { useFocusGuards } from "@radix-ui/react-focus-guards";
|
|
12
|
+
import { FocusScope } from "@radix-ui/react-focus-scope";
|
|
13
|
+
import { useId } from "@radix-ui/react-id";
|
|
14
|
+
import * as PopperPrimitive from "@radix-ui/react-popper";
|
|
15
|
+
import { createPopperScope } from "@radix-ui/react-popper";
|
|
16
|
+
import { Portal as PortalPrimitive } from "@radix-ui/react-portal";
|
|
17
|
+
import { Presence } from "@radix-ui/react-presence";
|
|
18
|
+
import { Primitive, dispatchDiscreteCustomEvent } from "@radix-ui/react-primitive";
|
|
19
|
+
import * as RovingFocusGroup from "@radix-ui/react-roving-focus";
|
|
20
|
+
import { createRovingFocusGroupScope } from "@radix-ui/react-roving-focus";
|
|
21
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
22
|
+
import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
|
|
23
|
+
import { hideOthers } from "aria-hidden";
|
|
24
|
+
import { RemoveScroll } from "react-remove-scroll";
|
|
25
|
+
import { jsx } from "react/jsx-runtime";
|
|
26
|
+
var SELECTION_KEYS = ["Enter", " "];
|
|
27
|
+
var FIRST_KEYS = ["ArrowDown", "PageUp", "Home"];
|
|
28
|
+
var LAST_KEYS = ["ArrowUp", "PageDown", "End"];
|
|
29
|
+
var FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
|
|
30
|
+
var SUB_OPEN_KEYS = {
|
|
31
|
+
ltr: [...SELECTION_KEYS, "ArrowRight"],
|
|
32
|
+
rtl: [...SELECTION_KEYS, "ArrowLeft"]
|
|
71
33
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
],
|
|
76
|
-
rtl: [
|
|
77
|
-
'ArrowRight'
|
|
78
|
-
]
|
|
34
|
+
var SUB_CLOSE_KEYS = {
|
|
35
|
+
ltr: ["ArrowLeft"],
|
|
36
|
+
rtl: ["ArrowRight"]
|
|
79
37
|
};
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
$epM9y$createPopperScope,
|
|
87
|
-
$epM9y$createRovingFocusGroupScope
|
|
38
|
+
var MENU_NAME = "Menu";
|
|
39
|
+
var [Collection, useCollection, createCollectionScope] = createCollection(MENU_NAME);
|
|
40
|
+
var [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, [
|
|
41
|
+
createCollectionScope,
|
|
42
|
+
createPopperScope,
|
|
43
|
+
createRovingFocusGroupScope
|
|
88
44
|
]);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
content: content,
|
|
136
|
-
onContentChange: setContent
|
|
137
|
-
}, /*#__PURE__*/ $epM9y$createElement($6cc32821e9371a1c$var$MenuRootProvider, {
|
|
138
|
-
scope: __scopeMenu,
|
|
139
|
-
onClose: $epM9y$useCallback(()=>handleOpenChange(false)
|
|
140
|
-
, [
|
|
141
|
-
handleOpenChange
|
|
142
|
-
]),
|
|
143
|
-
isUsingKeyboardRef: isUsingKeyboardRef,
|
|
144
|
-
dir: direction,
|
|
145
|
-
modal: modal
|
|
146
|
-
}, children)));
|
|
45
|
+
var usePopperScope = createPopperScope();
|
|
46
|
+
var useRovingFocusGroupScope = createRovingFocusGroupScope();
|
|
47
|
+
var [MenuProvider, useMenuContext] = createMenuContext(MENU_NAME);
|
|
48
|
+
var [MenuRootProvider, useMenuRootContext] = createMenuContext(MENU_NAME);
|
|
49
|
+
var Menu = (props) => {
|
|
50
|
+
const { __scopeMenu, open = false, children, dir, onOpenChange, modal = true } = props;
|
|
51
|
+
const popperScope = usePopperScope(__scopeMenu);
|
|
52
|
+
const [content, setContent] = React.useState(null);
|
|
53
|
+
const isUsingKeyboardRef = React.useRef(false);
|
|
54
|
+
const handleOpenChange = useCallbackRef(onOpenChange);
|
|
55
|
+
const direction = useDirection(dir);
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
const handleKeyDown = () => {
|
|
58
|
+
isUsingKeyboardRef.current = true;
|
|
59
|
+
document.addEventListener("pointerdown", handlePointer, { capture: true, once: true });
|
|
60
|
+
document.addEventListener("pointermove", handlePointer, { capture: true, once: true });
|
|
61
|
+
};
|
|
62
|
+
const handlePointer = () => isUsingKeyboardRef.current = false;
|
|
63
|
+
document.addEventListener("keydown", handleKeyDown, { capture: true });
|
|
64
|
+
return () => {
|
|
65
|
+
document.removeEventListener("keydown", handleKeyDown, { capture: true });
|
|
66
|
+
document.removeEventListener("pointerdown", handlePointer, { capture: true });
|
|
67
|
+
document.removeEventListener("pointermove", handlePointer, { capture: true });
|
|
68
|
+
};
|
|
69
|
+
}, []);
|
|
70
|
+
return /* @__PURE__ */ jsx(PopperPrimitive.Root, { ...popperScope, children: /* @__PURE__ */ jsx(
|
|
71
|
+
MenuProvider,
|
|
72
|
+
{
|
|
73
|
+
scope: __scopeMenu,
|
|
74
|
+
open,
|
|
75
|
+
onOpenChange: handleOpenChange,
|
|
76
|
+
content,
|
|
77
|
+
onContentChange: setContent,
|
|
78
|
+
children: /* @__PURE__ */ jsx(
|
|
79
|
+
MenuRootProvider,
|
|
80
|
+
{
|
|
81
|
+
scope: __scopeMenu,
|
|
82
|
+
onClose: React.useCallback(() => handleOpenChange(false), [handleOpenChange]),
|
|
83
|
+
isUsingKeyboardRef,
|
|
84
|
+
dir: direction,
|
|
85
|
+
modal,
|
|
86
|
+
children
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
) });
|
|
147
91
|
};
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
* -----------------------------------------------------------------------------------------------*/ const $6cc32821e9371a1c$var$PORTAL_NAME = 'MenuPortal';
|
|
167
|
-
const [$6cc32821e9371a1c$var$PortalProvider, $6cc32821e9371a1c$var$usePortalContext] = $6cc32821e9371a1c$var$createMenuContext($6cc32821e9371a1c$var$PORTAL_NAME, {
|
|
168
|
-
forceMount: undefined
|
|
169
|
-
});
|
|
170
|
-
const $6cc32821e9371a1c$export$793392f970497feb = (props)=>{
|
|
171
|
-
const { __scopeMenu: __scopeMenu , forceMount: forceMount , children: children , container: container } = props;
|
|
172
|
-
const context = $6cc32821e9371a1c$var$useMenuContext($6cc32821e9371a1c$var$PORTAL_NAME, __scopeMenu);
|
|
173
|
-
return /*#__PURE__*/ $epM9y$createElement($6cc32821e9371a1c$var$PortalProvider, {
|
|
174
|
-
scope: __scopeMenu,
|
|
175
|
-
forceMount: forceMount
|
|
176
|
-
}, /*#__PURE__*/ $epM9y$createElement($epM9y$Presence, {
|
|
177
|
-
present: forceMount || context.open
|
|
178
|
-
}, /*#__PURE__*/ $epM9y$createElement($epM9y$Portal, {
|
|
179
|
-
asChild: true,
|
|
180
|
-
container: container
|
|
181
|
-
}, children)));
|
|
92
|
+
Menu.displayName = MENU_NAME;
|
|
93
|
+
var ANCHOR_NAME = "MenuAnchor";
|
|
94
|
+
var MenuAnchor = React.forwardRef(
|
|
95
|
+
(props, forwardedRef) => {
|
|
96
|
+
const { __scopeMenu, ...anchorProps } = props;
|
|
97
|
+
const popperScope = usePopperScope(__scopeMenu);
|
|
98
|
+
return /* @__PURE__ */ jsx(PopperPrimitive.Anchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
MenuAnchor.displayName = ANCHOR_NAME;
|
|
102
|
+
var PORTAL_NAME = "MenuPortal";
|
|
103
|
+
var [PortalProvider, usePortalContext] = createMenuContext(PORTAL_NAME, {
|
|
104
|
+
forceMount: void 0
|
|
105
|
+
});
|
|
106
|
+
var MenuPortal = (props) => {
|
|
107
|
+
const { __scopeMenu, forceMount, children, container } = props;
|
|
108
|
+
const context = useMenuContext(PORTAL_NAME, __scopeMenu);
|
|
109
|
+
return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children }) }) });
|
|
182
110
|
};
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
})) : /*#__PURE__*/ $epM9y$createElement($6cc32821e9371a1c$var$MenuRootContentNonModal, $epM9y$babelruntimehelpersesmextends({}, contentProps, {
|
|
204
|
-
ref: forwardedRef
|
|
205
|
-
})))));
|
|
206
|
-
});
|
|
207
|
-
/* ---------------------------------------------------------------------------------------------- */ const $6cc32821e9371a1c$var$MenuRootContentModal = /*#__PURE__*/ $epM9y$forwardRef((props, forwardedRef)=>{
|
|
208
|
-
const context = $6cc32821e9371a1c$var$useMenuContext($6cc32821e9371a1c$var$CONTENT_NAME, props.__scopeMenu);
|
|
209
|
-
const ref = $epM9y$useRef(null);
|
|
210
|
-
const composedRefs = $epM9y$useComposedRefs(forwardedRef, ref); // Hide everything from ARIA except the `MenuContent`
|
|
211
|
-
$epM9y$useEffect(()=>{
|
|
212
|
-
const content = ref.current;
|
|
213
|
-
if (content) return $epM9y$hideOthers(content);
|
|
111
|
+
MenuPortal.displayName = PORTAL_NAME;
|
|
112
|
+
var CONTENT_NAME = "MenuContent";
|
|
113
|
+
var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME);
|
|
114
|
+
var MenuContent = React.forwardRef(
|
|
115
|
+
(props, forwardedRef) => {
|
|
116
|
+
const portalContext = usePortalContext(CONTENT_NAME, props.__scopeMenu);
|
|
117
|
+
const { forceMount = portalContext.forceMount, ...contentProps } = props;
|
|
118
|
+
const context = useMenuContext(CONTENT_NAME, props.__scopeMenu);
|
|
119
|
+
const rootContext = useMenuRootContext(CONTENT_NAME, props.__scopeMenu);
|
|
120
|
+
return /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
var MenuRootContentModal = React.forwardRef(
|
|
124
|
+
(props, forwardedRef) => {
|
|
125
|
+
const context = useMenuContext(CONTENT_NAME, props.__scopeMenu);
|
|
126
|
+
const ref = React.useRef(null);
|
|
127
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
128
|
+
React.useEffect(() => {
|
|
129
|
+
const content = ref.current;
|
|
130
|
+
if (content) return hideOthers(content);
|
|
214
131
|
}, []);
|
|
215
|
-
return
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
,
|
|
132
|
+
return /* @__PURE__ */ jsx(
|
|
133
|
+
MenuContentImpl,
|
|
134
|
+
{
|
|
135
|
+
...props,
|
|
136
|
+
ref: composedRefs,
|
|
137
|
+
trapFocus: context.open,
|
|
220
138
|
disableOutsidePointerEvents: context.open,
|
|
221
|
-
disableOutsideScroll: true
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
onDismiss: ()=>context.onOpenChange(false)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
139
|
+
disableOutsideScroll: true,
|
|
140
|
+
onFocusOutside: composeEventHandlers(
|
|
141
|
+
props.onFocusOutside,
|
|
142
|
+
(event) => event.preventDefault(),
|
|
143
|
+
{ checkForDefaultPrevented: false }
|
|
144
|
+
),
|
|
145
|
+
onDismiss: () => context.onOpenChange(false)
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
var MenuRootContentNonModal = React.forwardRef((props, forwardedRef) => {
|
|
151
|
+
const context = useMenuContext(CONTENT_NAME, props.__scopeMenu);
|
|
152
|
+
return /* @__PURE__ */ jsx(
|
|
153
|
+
MenuContentImpl,
|
|
154
|
+
{
|
|
155
|
+
...props,
|
|
156
|
+
ref: forwardedRef,
|
|
157
|
+
trapFocus: false,
|
|
158
|
+
disableOutsidePointerEvents: false,
|
|
159
|
+
disableOutsideScroll: false,
|
|
160
|
+
onDismiss: () => context.onOpenChange(false)
|
|
161
|
+
}
|
|
162
|
+
);
|
|
163
|
+
});
|
|
164
|
+
var MenuContentImpl = React.forwardRef(
|
|
165
|
+
(props, forwardedRef) => {
|
|
166
|
+
const {
|
|
167
|
+
__scopeMenu,
|
|
168
|
+
loop = false,
|
|
169
|
+
trapFocus,
|
|
170
|
+
onOpenAutoFocus,
|
|
171
|
+
onCloseAutoFocus,
|
|
172
|
+
disableOutsidePointerEvents,
|
|
173
|
+
onEntryFocus,
|
|
174
|
+
onEscapeKeyDown,
|
|
175
|
+
onPointerDownOutside,
|
|
176
|
+
onFocusOutside,
|
|
177
|
+
onInteractOutside,
|
|
178
|
+
onDismiss,
|
|
179
|
+
disableOutsideScroll,
|
|
180
|
+
...contentProps
|
|
181
|
+
} = props;
|
|
182
|
+
const context = useMenuContext(CONTENT_NAME, __scopeMenu);
|
|
183
|
+
const rootContext = useMenuRootContext(CONTENT_NAME, __scopeMenu);
|
|
184
|
+
const popperScope = usePopperScope(__scopeMenu);
|
|
185
|
+
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeMenu);
|
|
186
|
+
const getItems = useCollection(__scopeMenu);
|
|
187
|
+
const [currentItemId, setCurrentItemId] = React.useState(null);
|
|
188
|
+
const contentRef = React.useRef(null);
|
|
189
|
+
const composedRefs = useComposedRefs(forwardedRef, contentRef, context.onContentChange);
|
|
190
|
+
const timerRef = React.useRef(0);
|
|
191
|
+
const searchRef = React.useRef("");
|
|
192
|
+
const pointerGraceTimerRef = React.useRef(0);
|
|
193
|
+
const pointerGraceIntentRef = React.useRef(null);
|
|
194
|
+
const pointerDirRef = React.useRef("right");
|
|
195
|
+
const lastPointerXRef = React.useRef(0);
|
|
196
|
+
const ScrollLockWrapper = disableOutsideScroll ? RemoveScroll : React.Fragment;
|
|
197
|
+
const scrollLockWrapperProps = disableOutsideScroll ? { as: Slot, allowPinchZoom: true } : void 0;
|
|
198
|
+
const handleTypeaheadSearch = (key) => {
|
|
199
|
+
const search = searchRef.current + key;
|
|
200
|
+
const items = getItems().filter((item) => !item.disabled);
|
|
201
|
+
const currentItem = document.activeElement;
|
|
202
|
+
const currentMatch = items.find((item) => item.ref.current === currentItem)?.textValue;
|
|
203
|
+
const values = items.map((item) => item.textValue);
|
|
204
|
+
const nextMatch = getNextMatch(values, search, currentMatch);
|
|
205
|
+
const newItem = items.find((item) => item.textValue === nextMatch)?.ref.current;
|
|
206
|
+
(function updateSearch(value) {
|
|
207
|
+
searchRef.current = value;
|
|
208
|
+
window.clearTimeout(timerRef.current);
|
|
209
|
+
if (value !== "") timerRef.current = window.setTimeout(() => updateSearch(""), 1e3);
|
|
210
|
+
})(search);
|
|
211
|
+
if (newItem) {
|
|
212
|
+
setTimeout(() => newItem.focus());
|
|
213
|
+
}
|
|
285
214
|
};
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
;
|
|
289
|
-
}, []); // Make sure the whole tree has focus guards as our `MenuContent` may be
|
|
290
|
-
// the last element in the DOM (beacuse of the `Portal`)
|
|
291
|
-
$epM9y$useFocusGuards();
|
|
292
|
-
const isPointerMovingToSubmenu = $epM9y$useCallback((event)=>{
|
|
293
|
-
var _pointerGraceIntentRe, _pointerGraceIntentRe2;
|
|
294
|
-
const isMovingTowards = pointerDirRef.current === ((_pointerGraceIntentRe = pointerGraceIntentRef.current) === null || _pointerGraceIntentRe === void 0 ? void 0 : _pointerGraceIntentRe.side);
|
|
295
|
-
return isMovingTowards && $6cc32821e9371a1c$var$isPointerInGraceArea(event, (_pointerGraceIntentRe2 = pointerGraceIntentRef.current) === null || _pointerGraceIntentRe2 === void 0 ? void 0 : _pointerGraceIntentRe2.area);
|
|
215
|
+
React.useEffect(() => {
|
|
216
|
+
return () => window.clearTimeout(timerRef.current);
|
|
296
217
|
}, []);
|
|
297
|
-
|
|
218
|
+
useFocusGuards();
|
|
219
|
+
const isPointerMovingToSubmenu = React.useCallback((event) => {
|
|
220
|
+
const isMovingTowards = pointerDirRef.current === pointerGraceIntentRef.current?.side;
|
|
221
|
+
return isMovingTowards && isPointerInGraceArea(event, pointerGraceIntentRef.current?.area);
|
|
222
|
+
}, []);
|
|
223
|
+
return /* @__PURE__ */ jsx(
|
|
224
|
+
MenuContentProvider,
|
|
225
|
+
{
|
|
298
226
|
scope: __scopeMenu,
|
|
299
|
-
searchRef
|
|
300
|
-
onItemEnter:
|
|
227
|
+
searchRef,
|
|
228
|
+
onItemEnter: React.useCallback(
|
|
229
|
+
(event) => {
|
|
301
230
|
if (isPointerMovingToSubmenu(event)) event.preventDefault();
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
onItemLeave:
|
|
306
|
-
|
|
231
|
+
},
|
|
232
|
+
[isPointerMovingToSubmenu]
|
|
233
|
+
),
|
|
234
|
+
onItemLeave: React.useCallback(
|
|
235
|
+
(event) => {
|
|
307
236
|
if (isPointerMovingToSubmenu(event)) return;
|
|
308
|
-
|
|
237
|
+
contentRef.current?.focus();
|
|
309
238
|
setCurrentItemId(null);
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
onTriggerLeave:
|
|
239
|
+
},
|
|
240
|
+
[isPointerMovingToSubmenu]
|
|
241
|
+
),
|
|
242
|
+
onTriggerLeave: React.useCallback(
|
|
243
|
+
(event) => {
|
|
314
244
|
if (isPointerMovingToSubmenu(event)) event.preventDefault();
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
pointerGraceTimerRef
|
|
319
|
-
onPointerGraceIntentChange:
|
|
320
|
-
|
|
321
|
-
}, [])
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
})
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
})
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const
|
|
442
|
-
const
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
bubbles: true,
|
|
454
|
-
cancelable: true
|
|
455
|
-
});
|
|
456
|
-
menuItem.addEventListener($6cc32821e9371a1c$var$ITEM_SELECT, (event)=>onSelect === null || onSelect === void 0 ? void 0 : onSelect(event)
|
|
457
|
-
, {
|
|
458
|
-
once: true
|
|
459
|
-
});
|
|
460
|
-
$epM9y$dispatchDiscreteCustomEvent(menuItem, itemSelectEvent);
|
|
461
|
-
if (itemSelectEvent.defaultPrevented) isPointerDownRef.current = false;
|
|
462
|
-
else rootContext.onClose();
|
|
245
|
+
},
|
|
246
|
+
[isPointerMovingToSubmenu]
|
|
247
|
+
),
|
|
248
|
+
pointerGraceTimerRef,
|
|
249
|
+
onPointerGraceIntentChange: React.useCallback((intent) => {
|
|
250
|
+
pointerGraceIntentRef.current = intent;
|
|
251
|
+
}, []),
|
|
252
|
+
children: /* @__PURE__ */ jsx(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx(
|
|
253
|
+
FocusScope,
|
|
254
|
+
{
|
|
255
|
+
asChild: true,
|
|
256
|
+
trapped: trapFocus,
|
|
257
|
+
onMountAutoFocus: composeEventHandlers(onOpenAutoFocus, (event) => {
|
|
258
|
+
event.preventDefault();
|
|
259
|
+
contentRef.current?.focus({ preventScroll: true });
|
|
260
|
+
}),
|
|
261
|
+
onUnmountAutoFocus: onCloseAutoFocus,
|
|
262
|
+
children: /* @__PURE__ */ jsx(
|
|
263
|
+
DismissableLayer,
|
|
264
|
+
{
|
|
265
|
+
asChild: true,
|
|
266
|
+
disableOutsidePointerEvents,
|
|
267
|
+
onEscapeKeyDown,
|
|
268
|
+
onPointerDownOutside,
|
|
269
|
+
onFocusOutside,
|
|
270
|
+
onInteractOutside,
|
|
271
|
+
onDismiss,
|
|
272
|
+
children: /* @__PURE__ */ jsx(
|
|
273
|
+
RovingFocusGroup.Root,
|
|
274
|
+
{
|
|
275
|
+
asChild: true,
|
|
276
|
+
...rovingFocusGroupScope,
|
|
277
|
+
dir: rootContext.dir,
|
|
278
|
+
orientation: "vertical",
|
|
279
|
+
loop,
|
|
280
|
+
currentTabStopId: currentItemId,
|
|
281
|
+
onCurrentTabStopIdChange: setCurrentItemId,
|
|
282
|
+
onEntryFocus: composeEventHandlers(onEntryFocus, (event) => {
|
|
283
|
+
if (!rootContext.isUsingKeyboardRef.current) event.preventDefault();
|
|
284
|
+
}),
|
|
285
|
+
preventScrollOnEntryFocus: true,
|
|
286
|
+
children: /* @__PURE__ */ jsx(
|
|
287
|
+
PopperPrimitive.Content,
|
|
288
|
+
{
|
|
289
|
+
role: "menu",
|
|
290
|
+
"aria-orientation": "vertical",
|
|
291
|
+
"data-state": getOpenState(context.open),
|
|
292
|
+
"data-radix-menu-content": "",
|
|
293
|
+
dir: rootContext.dir,
|
|
294
|
+
...popperScope,
|
|
295
|
+
...contentProps,
|
|
296
|
+
ref: composedRefs,
|
|
297
|
+
style: { outline: "none", ...contentProps.style },
|
|
298
|
+
onKeyDown: composeEventHandlers(contentProps.onKeyDown, (event) => {
|
|
299
|
+
const target = event.target;
|
|
300
|
+
const isKeyDownInside = target.closest("[data-radix-menu-content]") === event.currentTarget;
|
|
301
|
+
const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
|
|
302
|
+
const isCharacterKey = event.key.length === 1;
|
|
303
|
+
if (isKeyDownInside) {
|
|
304
|
+
if (event.key === "Tab") event.preventDefault();
|
|
305
|
+
if (!isModifierKey && isCharacterKey) handleTypeaheadSearch(event.key);
|
|
306
|
+
}
|
|
307
|
+
const content = contentRef.current;
|
|
308
|
+
if (event.target !== content) return;
|
|
309
|
+
if (!FIRST_LAST_KEYS.includes(event.key)) return;
|
|
310
|
+
event.preventDefault();
|
|
311
|
+
const items = getItems().filter((item) => !item.disabled);
|
|
312
|
+
const candidateNodes = items.map((item) => item.ref.current);
|
|
313
|
+
if (LAST_KEYS.includes(event.key)) candidateNodes.reverse();
|
|
314
|
+
focusFirst(candidateNodes);
|
|
315
|
+
}),
|
|
316
|
+
onBlur: composeEventHandlers(props.onBlur, (event) => {
|
|
317
|
+
if (!event.currentTarget.contains(event.target)) {
|
|
318
|
+
window.clearTimeout(timerRef.current);
|
|
319
|
+
searchRef.current = "";
|
|
320
|
+
}
|
|
321
|
+
}),
|
|
322
|
+
onPointerMove: composeEventHandlers(
|
|
323
|
+
props.onPointerMove,
|
|
324
|
+
whenMouse((event) => {
|
|
325
|
+
const target = event.target;
|
|
326
|
+
const pointerXHasChanged = lastPointerXRef.current !== event.clientX;
|
|
327
|
+
if (event.currentTarget.contains(target) && pointerXHasChanged) {
|
|
328
|
+
const newDir = event.clientX > lastPointerXRef.current ? "right" : "left";
|
|
329
|
+
pointerDirRef.current = newDir;
|
|
330
|
+
lastPointerXRef.current = event.clientX;
|
|
331
|
+
}
|
|
332
|
+
})
|
|
333
|
+
)
|
|
334
|
+
}
|
|
335
|
+
)
|
|
336
|
+
}
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
)
|
|
340
|
+
}
|
|
341
|
+
) })
|
|
342
|
+
}
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
);
|
|
346
|
+
MenuContent.displayName = CONTENT_NAME;
|
|
347
|
+
var GROUP_NAME = "MenuGroup";
|
|
348
|
+
var MenuGroup = React.forwardRef(
|
|
349
|
+
(props, forwardedRef) => {
|
|
350
|
+
const { __scopeMenu, ...groupProps } = props;
|
|
351
|
+
return /* @__PURE__ */ jsx(Primitive.div, { role: "group", ...groupProps, ref: forwardedRef });
|
|
352
|
+
}
|
|
353
|
+
);
|
|
354
|
+
MenuGroup.displayName = GROUP_NAME;
|
|
355
|
+
var LABEL_NAME = "MenuLabel";
|
|
356
|
+
var MenuLabel = React.forwardRef(
|
|
357
|
+
(props, forwardedRef) => {
|
|
358
|
+
const { __scopeMenu, ...labelProps } = props;
|
|
359
|
+
return /* @__PURE__ */ jsx(Primitive.div, { ...labelProps, ref: forwardedRef });
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
MenuLabel.displayName = LABEL_NAME;
|
|
363
|
+
var ITEM_NAME = "MenuItem";
|
|
364
|
+
var ITEM_SELECT = "menu.itemSelect";
|
|
365
|
+
var MenuItem = React.forwardRef(
|
|
366
|
+
(props, forwardedRef) => {
|
|
367
|
+
const { disabled = false, onSelect, ...itemProps } = props;
|
|
368
|
+
const ref = React.useRef(null);
|
|
369
|
+
const rootContext = useMenuRootContext(ITEM_NAME, props.__scopeMenu);
|
|
370
|
+
const contentContext = useMenuContentContext(ITEM_NAME, props.__scopeMenu);
|
|
371
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
372
|
+
const isPointerDownRef = React.useRef(false);
|
|
373
|
+
const handleSelect = () => {
|
|
374
|
+
const menuItem = ref.current;
|
|
375
|
+
if (!disabled && menuItem) {
|
|
376
|
+
const itemSelectEvent = new CustomEvent(ITEM_SELECT, { bubbles: true, cancelable: true });
|
|
377
|
+
menuItem.addEventListener(ITEM_SELECT, (event) => onSelect?.(event), { once: true });
|
|
378
|
+
dispatchDiscreteCustomEvent(menuItem, itemSelectEvent);
|
|
379
|
+
if (itemSelectEvent.defaultPrevented) {
|
|
380
|
+
isPointerDownRef.current = false;
|
|
381
|
+
} else {
|
|
382
|
+
rootContext.onClose();
|
|
463
383
|
}
|
|
384
|
+
}
|
|
464
385
|
};
|
|
465
|
-
return
|
|
386
|
+
return /* @__PURE__ */ jsx(
|
|
387
|
+
MenuItemImpl,
|
|
388
|
+
{
|
|
389
|
+
...itemProps,
|
|
466
390
|
ref: composedRefs,
|
|
467
|
-
disabled
|
|
468
|
-
onClick:
|
|
469
|
-
onPointerDown: (event)=>{
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
isPointerDownRef.current = true;
|
|
391
|
+
disabled,
|
|
392
|
+
onClick: composeEventHandlers(props.onClick, handleSelect),
|
|
393
|
+
onPointerDown: (event) => {
|
|
394
|
+
props.onPointerDown?.(event);
|
|
395
|
+
isPointerDownRef.current = true;
|
|
473
396
|
},
|
|
474
|
-
onPointerUp:
|
|
475
|
-
|
|
476
|
-
// Pointer down can move to a different menu item which should activate it on pointer up.
|
|
477
|
-
// We dispatch a click for selection to allow composition with click based triggers and to
|
|
478
|
-
// prevent Firefox from getting stuck in text selection mode when the menu closes.
|
|
479
|
-
if (!isPointerDownRef.current) (_event$currentTarget = event.currentTarget) === null || _event$currentTarget === void 0 || _event$currentTarget.click();
|
|
397
|
+
onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
|
|
398
|
+
if (!isPointerDownRef.current) event.currentTarget?.click();
|
|
480
399
|
}),
|
|
481
|
-
onKeyDown:
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
* a selection only:
|
|
489
|
-
* - prevents space from scrolling the page.
|
|
490
|
-
* - if keydown causes focus to move, prevents keydown from firing on the new target.
|
|
491
|
-
*/ event.preventDefault();
|
|
492
|
-
}
|
|
400
|
+
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
401
|
+
const isTypingAhead = contentContext.searchRef.current !== "";
|
|
402
|
+
if (disabled || isTypingAhead && event.key === " ") return;
|
|
403
|
+
if (SELECTION_KEYS.includes(event.key)) {
|
|
404
|
+
event.currentTarget.click();
|
|
405
|
+
event.preventDefault();
|
|
406
|
+
}
|
|
493
407
|
})
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
const
|
|
502
|
-
const
|
|
503
|
-
const
|
|
504
|
-
const
|
|
505
|
-
const
|
|
506
|
-
const [
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}, [
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
408
|
+
}
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
);
|
|
412
|
+
MenuItem.displayName = ITEM_NAME;
|
|
413
|
+
var MenuItemImpl = React.forwardRef(
|
|
414
|
+
(props, forwardedRef) => {
|
|
415
|
+
const { __scopeMenu, disabled = false, textValue, ...itemProps } = props;
|
|
416
|
+
const contentContext = useMenuContentContext(ITEM_NAME, __scopeMenu);
|
|
417
|
+
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeMenu);
|
|
418
|
+
const ref = React.useRef(null);
|
|
419
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
420
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
421
|
+
const [textContent, setTextContent] = React.useState("");
|
|
422
|
+
React.useEffect(() => {
|
|
423
|
+
const menuItem = ref.current;
|
|
424
|
+
if (menuItem) {
|
|
425
|
+
setTextContent((menuItem.textContent ?? "").trim());
|
|
426
|
+
}
|
|
427
|
+
}, [itemProps.children]);
|
|
428
|
+
return /* @__PURE__ */ jsx(
|
|
429
|
+
Collection.ItemSlot,
|
|
430
|
+
{
|
|
517
431
|
scope: __scopeMenu,
|
|
518
|
-
disabled
|
|
519
|
-
textValue: textValue
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
432
|
+
disabled,
|
|
433
|
+
textValue: textValue ?? textContent,
|
|
434
|
+
children: /* @__PURE__ */ jsx(RovingFocusGroup.Item, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx(
|
|
435
|
+
Primitive.div,
|
|
436
|
+
{
|
|
437
|
+
role: "menuitem",
|
|
438
|
+
"data-highlighted": isFocused ? "" : void 0,
|
|
439
|
+
"aria-disabled": disabled || void 0,
|
|
440
|
+
"data-disabled": disabled ? "" : void 0,
|
|
441
|
+
...itemProps,
|
|
442
|
+
ref: composedRefs,
|
|
443
|
+
onPointerMove: composeEventHandlers(
|
|
444
|
+
props.onPointerMove,
|
|
445
|
+
whenMouse((event) => {
|
|
446
|
+
if (disabled) {
|
|
447
|
+
contentContext.onItemLeave(event);
|
|
448
|
+
} else {
|
|
449
|
+
contentContext.onItemEnter(event);
|
|
450
|
+
if (!event.defaultPrevented) {
|
|
536
451
|
const item = event.currentTarget;
|
|
537
452
|
item.focus();
|
|
453
|
+
}
|
|
538
454
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
})
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
455
|
+
})
|
|
456
|
+
),
|
|
457
|
+
onPointerLeave: composeEventHandlers(
|
|
458
|
+
props.onPointerLeave,
|
|
459
|
+
whenMouse((event) => contentContext.onItemLeave(event))
|
|
460
|
+
),
|
|
461
|
+
onFocus: composeEventHandlers(props.onFocus, () => setIsFocused(true)),
|
|
462
|
+
onBlur: composeEventHandlers(props.onBlur, () => setIsFocused(false))
|
|
463
|
+
}
|
|
464
|
+
) })
|
|
465
|
+
}
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
);
|
|
469
|
+
var CHECKBOX_ITEM_NAME = "MenuCheckboxItem";
|
|
470
|
+
var MenuCheckboxItem = React.forwardRef(
|
|
471
|
+
(props, forwardedRef) => {
|
|
472
|
+
const { checked = false, onCheckedChange, ...checkboxItemProps } = props;
|
|
473
|
+
return /* @__PURE__ */ jsx(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx(
|
|
474
|
+
MenuItem,
|
|
475
|
+
{
|
|
558
476
|
role: "menuitemcheckbox",
|
|
559
|
-
"aria-checked":
|
|
560
|
-
|
|
477
|
+
"aria-checked": isIndeterminate(checked) ? "mixed" : checked,
|
|
478
|
+
...checkboxItemProps,
|
|
561
479
|
ref: forwardedRef,
|
|
562
|
-
"data-state":
|
|
563
|
-
onSelect:
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
});
|
|
593
|
-
/* -------------------------------------------------------------------------------------------------
|
|
594
|
-
* MenuRadioItem
|
|
595
|
-
* -----------------------------------------------------------------------------------------------*/ const $6cc32821e9371a1c$var$RADIO_ITEM_NAME = 'MenuRadioItem';
|
|
596
|
-
const $6cc32821e9371a1c$export$69bd225e9817f6d0 = /*#__PURE__*/ $epM9y$forwardRef((props, forwardedRef)=>{
|
|
597
|
-
const { value: value , ...radioItemProps } = props;
|
|
598
|
-
const context = $6cc32821e9371a1c$var$useRadioGroupContext($6cc32821e9371a1c$var$RADIO_ITEM_NAME, props.__scopeMenu);
|
|
480
|
+
"data-state": getCheckedState(checked),
|
|
481
|
+
onSelect: composeEventHandlers(
|
|
482
|
+
checkboxItemProps.onSelect,
|
|
483
|
+
() => onCheckedChange?.(isIndeterminate(checked) ? true : !checked),
|
|
484
|
+
{ checkForDefaultPrevented: false }
|
|
485
|
+
)
|
|
486
|
+
}
|
|
487
|
+
) });
|
|
488
|
+
}
|
|
489
|
+
);
|
|
490
|
+
MenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
|
|
491
|
+
var RADIO_GROUP_NAME = "MenuRadioGroup";
|
|
492
|
+
var [RadioGroupProvider, useRadioGroupContext] = createMenuContext(
|
|
493
|
+
RADIO_GROUP_NAME,
|
|
494
|
+
{ value: void 0, onValueChange: () => {
|
|
495
|
+
} }
|
|
496
|
+
);
|
|
497
|
+
var MenuRadioGroup = React.forwardRef(
|
|
498
|
+
(props, forwardedRef) => {
|
|
499
|
+
const { value, onValueChange, ...groupProps } = props;
|
|
500
|
+
const handleValueChange = useCallbackRef(onValueChange);
|
|
501
|
+
return /* @__PURE__ */ jsx(RadioGroupProvider, { scope: props.__scopeMenu, value, onValueChange: handleValueChange, children: /* @__PURE__ */ jsx(MenuGroup, { ...groupProps, ref: forwardedRef }) });
|
|
502
|
+
}
|
|
503
|
+
);
|
|
504
|
+
MenuRadioGroup.displayName = RADIO_GROUP_NAME;
|
|
505
|
+
var RADIO_ITEM_NAME = "MenuRadioItem";
|
|
506
|
+
var MenuRadioItem = React.forwardRef(
|
|
507
|
+
(props, forwardedRef) => {
|
|
508
|
+
const { value, ...radioItemProps } = props;
|
|
509
|
+
const context = useRadioGroupContext(RADIO_ITEM_NAME, props.__scopeMenu);
|
|
599
510
|
const checked = value === context.value;
|
|
600
|
-
return
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
}, /*#__PURE__*/ $epM9y$createElement($6cc32821e9371a1c$export$2ce376c2cc3355c8, $epM9y$babelruntimehelpersesmextends({
|
|
511
|
+
return /* @__PURE__ */ jsx(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx(
|
|
512
|
+
MenuItem,
|
|
513
|
+
{
|
|
604
514
|
role: "menuitemradio",
|
|
605
|
-
"aria-checked": checked
|
|
606
|
-
|
|
607
|
-
ref: forwardedRef,
|
|
608
|
-
"data-state": $6cc32821e9371a1c$var$getCheckedState(checked),
|
|
609
|
-
onSelect: $epM9y$composeEventHandlers(radioItemProps.onSelect, ()=>{
|
|
610
|
-
var _context$onValueChang;
|
|
611
|
-
return (_context$onValueChang = context.onValueChange) === null || _context$onValueChang === void 0 ? void 0 : _context$onValueChang.call(context, value);
|
|
612
|
-
}, {
|
|
613
|
-
checkForDefaultPrevented: false
|
|
614
|
-
})
|
|
615
|
-
})));
|
|
616
|
-
});
|
|
617
|
-
/*#__PURE__*/ Object.assign($6cc32821e9371a1c$export$69bd225e9817f6d0, {
|
|
618
|
-
displayName: $6cc32821e9371a1c$var$RADIO_ITEM_NAME
|
|
619
|
-
});
|
|
620
|
-
/* -------------------------------------------------------------------------------------------------
|
|
621
|
-
* MenuItemIndicator
|
|
622
|
-
* -----------------------------------------------------------------------------------------------*/ const $6cc32821e9371a1c$var$ITEM_INDICATOR_NAME = 'MenuItemIndicator';
|
|
623
|
-
const [$6cc32821e9371a1c$var$ItemIndicatorProvider, $6cc32821e9371a1c$var$useItemIndicatorContext] = $6cc32821e9371a1c$var$createMenuContext($6cc32821e9371a1c$var$ITEM_INDICATOR_NAME, {
|
|
624
|
-
checked: false
|
|
625
|
-
});
|
|
626
|
-
const $6cc32821e9371a1c$export$a2593e23056970a3 = /*#__PURE__*/ $epM9y$forwardRef((props, forwardedRef)=>{
|
|
627
|
-
const { __scopeMenu: __scopeMenu , forceMount: forceMount , ...itemIndicatorProps } = props;
|
|
628
|
-
const indicatorContext = $6cc32821e9371a1c$var$useItemIndicatorContext($6cc32821e9371a1c$var$ITEM_INDICATOR_NAME, __scopeMenu);
|
|
629
|
-
return /*#__PURE__*/ $epM9y$createElement($epM9y$Presence, {
|
|
630
|
-
present: forceMount || $6cc32821e9371a1c$var$isIndeterminate(indicatorContext.checked) || indicatorContext.checked === true
|
|
631
|
-
}, /*#__PURE__*/ $epM9y$createElement($epM9y$Primitive.span, $epM9y$babelruntimehelpersesmextends({}, itemIndicatorProps, {
|
|
515
|
+
"aria-checked": checked,
|
|
516
|
+
...radioItemProps,
|
|
632
517
|
ref: forwardedRef,
|
|
633
|
-
"data-state":
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
518
|
+
"data-state": getCheckedState(checked),
|
|
519
|
+
onSelect: composeEventHandlers(
|
|
520
|
+
radioItemProps.onSelect,
|
|
521
|
+
() => context.onValueChange?.(value),
|
|
522
|
+
{ checkForDefaultPrevented: false }
|
|
523
|
+
)
|
|
524
|
+
}
|
|
525
|
+
) });
|
|
526
|
+
}
|
|
527
|
+
);
|
|
528
|
+
MenuRadioItem.displayName = RADIO_ITEM_NAME;
|
|
529
|
+
var ITEM_INDICATOR_NAME = "MenuItemIndicator";
|
|
530
|
+
var [ItemIndicatorProvider, useItemIndicatorContext] = createMenuContext(
|
|
531
|
+
ITEM_INDICATOR_NAME,
|
|
532
|
+
{ checked: false }
|
|
533
|
+
);
|
|
534
|
+
var MenuItemIndicator = React.forwardRef(
|
|
535
|
+
(props, forwardedRef) => {
|
|
536
|
+
const { __scopeMenu, forceMount, ...itemIndicatorProps } = props;
|
|
537
|
+
const indicatorContext = useItemIndicatorContext(ITEM_INDICATOR_NAME, __scopeMenu);
|
|
538
|
+
return /* @__PURE__ */ jsx(
|
|
539
|
+
Presence,
|
|
540
|
+
{
|
|
541
|
+
present: forceMount || isIndeterminate(indicatorContext.checked) || indicatorContext.checked === true,
|
|
542
|
+
children: /* @__PURE__ */ jsx(
|
|
543
|
+
Primitive.span,
|
|
544
|
+
{
|
|
545
|
+
...itemIndicatorProps,
|
|
546
|
+
ref: forwardedRef,
|
|
547
|
+
"data-state": getCheckedState(indicatorContext.checked)
|
|
548
|
+
}
|
|
549
|
+
)
|
|
550
|
+
}
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
);
|
|
554
|
+
MenuItemIndicator.displayName = ITEM_INDICATOR_NAME;
|
|
555
|
+
var SEPARATOR_NAME = "MenuSeparator";
|
|
556
|
+
var MenuSeparator = React.forwardRef(
|
|
557
|
+
(props, forwardedRef) => {
|
|
558
|
+
const { __scopeMenu, ...separatorProps } = props;
|
|
559
|
+
return /* @__PURE__ */ jsx(
|
|
560
|
+
Primitive.div,
|
|
561
|
+
{
|
|
645
562
|
role: "separator",
|
|
646
|
-
"aria-orientation": "horizontal"
|
|
647
|
-
|
|
648
|
-
ref: forwardedRef
|
|
649
|
-
}));
|
|
650
|
-
});
|
|
651
|
-
/*#__PURE__*/ Object.assign($6cc32821e9371a1c$export$1cec7dcdd713e220, {
|
|
652
|
-
displayName: $6cc32821e9371a1c$var$SEPARATOR_NAME
|
|
653
|
-
});
|
|
654
|
-
/* -------------------------------------------------------------------------------------------------
|
|
655
|
-
* MenuArrow
|
|
656
|
-
* -----------------------------------------------------------------------------------------------*/ const $6cc32821e9371a1c$var$ARROW_NAME = 'MenuArrow';
|
|
657
|
-
const $6cc32821e9371a1c$export$bcdda4773debf5fa = /*#__PURE__*/ $epM9y$forwardRef((props, forwardedRef)=>{
|
|
658
|
-
const { __scopeMenu: __scopeMenu , ...arrowProps } = props;
|
|
659
|
-
const popperScope = $6cc32821e9371a1c$var$usePopperScope(__scopeMenu);
|
|
660
|
-
return /*#__PURE__*/ $epM9y$createElement($epM9y$Arrow, $epM9y$babelruntimehelpersesmextends({}, popperScope, arrowProps, {
|
|
563
|
+
"aria-orientation": "horizontal",
|
|
564
|
+
...separatorProps,
|
|
661
565
|
ref: forwardedRef
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
const
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
566
|
+
}
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
);
|
|
570
|
+
MenuSeparator.displayName = SEPARATOR_NAME;
|
|
571
|
+
var ARROW_NAME = "MenuArrow";
|
|
572
|
+
var MenuArrow = React.forwardRef(
|
|
573
|
+
(props, forwardedRef) => {
|
|
574
|
+
const { __scopeMenu, ...arrowProps } = props;
|
|
575
|
+
const popperScope = usePopperScope(__scopeMenu);
|
|
576
|
+
return /* @__PURE__ */ jsx(PopperPrimitive.Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
|
|
577
|
+
}
|
|
578
|
+
);
|
|
579
|
+
MenuArrow.displayName = ARROW_NAME;
|
|
580
|
+
var SUB_NAME = "MenuSub";
|
|
581
|
+
var [MenuSubProvider, useMenuSubContext] = createMenuContext(SUB_NAME);
|
|
582
|
+
var MenuSub = (props) => {
|
|
583
|
+
const { __scopeMenu, children, open = false, onOpenChange } = props;
|
|
584
|
+
const parentMenuContext = useMenuContext(SUB_NAME, __scopeMenu);
|
|
585
|
+
const popperScope = usePopperScope(__scopeMenu);
|
|
586
|
+
const [trigger, setTrigger] = React.useState(null);
|
|
587
|
+
const [content, setContent] = React.useState(null);
|
|
588
|
+
const handleOpenChange = useCallbackRef(onOpenChange);
|
|
589
|
+
React.useEffect(() => {
|
|
590
|
+
if (parentMenuContext.open === false) handleOpenChange(false);
|
|
591
|
+
return () => handleOpenChange(false);
|
|
592
|
+
}, [parentMenuContext.open, handleOpenChange]);
|
|
593
|
+
return /* @__PURE__ */ jsx(PopperPrimitive.Root, { ...popperScope, children: /* @__PURE__ */ jsx(
|
|
594
|
+
MenuProvider,
|
|
595
|
+
{
|
|
596
|
+
scope: __scopeMenu,
|
|
597
|
+
open,
|
|
598
|
+
onOpenChange: handleOpenChange,
|
|
599
|
+
content,
|
|
600
|
+
onContentChange: setContent,
|
|
601
|
+
children: /* @__PURE__ */ jsx(
|
|
602
|
+
MenuSubProvider,
|
|
603
|
+
{
|
|
604
|
+
scope: __scopeMenu,
|
|
605
|
+
contentId: useId(),
|
|
606
|
+
triggerId: useId(),
|
|
607
|
+
trigger,
|
|
608
|
+
onTriggerChange: setTrigger,
|
|
609
|
+
children
|
|
610
|
+
}
|
|
611
|
+
)
|
|
612
|
+
}
|
|
613
|
+
) });
|
|
699
614
|
};
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
const
|
|
707
|
-
const
|
|
708
|
-
const
|
|
709
|
-
const
|
|
710
|
-
const
|
|
711
|
-
const
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
__scopeMenu: props.__scopeMenu
|
|
715
|
-
};
|
|
716
|
-
const clearOpenTimer = $epM9y$useCallback(()=>{
|
|
717
|
-
if (openTimerRef.current) window.clearTimeout(openTimerRef.current);
|
|
718
|
-
openTimerRef.current = null;
|
|
615
|
+
MenuSub.displayName = SUB_NAME;
|
|
616
|
+
var SUB_TRIGGER_NAME = "MenuSubTrigger";
|
|
617
|
+
var MenuSubTrigger = React.forwardRef(
|
|
618
|
+
(props, forwardedRef) => {
|
|
619
|
+
const context = useMenuContext(SUB_TRIGGER_NAME, props.__scopeMenu);
|
|
620
|
+
const rootContext = useMenuRootContext(SUB_TRIGGER_NAME, props.__scopeMenu);
|
|
621
|
+
const subContext = useMenuSubContext(SUB_TRIGGER_NAME, props.__scopeMenu);
|
|
622
|
+
const contentContext = useMenuContentContext(SUB_TRIGGER_NAME, props.__scopeMenu);
|
|
623
|
+
const openTimerRef = React.useRef(null);
|
|
624
|
+
const { pointerGraceTimerRef, onPointerGraceIntentChange } = contentContext;
|
|
625
|
+
const scope = { __scopeMenu: props.__scopeMenu };
|
|
626
|
+
const clearOpenTimer = React.useCallback(() => {
|
|
627
|
+
if (openTimerRef.current) window.clearTimeout(openTimerRef.current);
|
|
628
|
+
openTimerRef.current = null;
|
|
719
629
|
}, []);
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
pointerGraceTimerRef,
|
|
732
|
-
onPointerGraceIntentChange
|
|
733
|
-
]);
|
|
734
|
-
return /*#__PURE__*/ $epM9y$createElement($6cc32821e9371a1c$export$9fa5ebd18bee4d43, $epM9y$babelruntimehelpersesmextends({
|
|
735
|
-
asChild: true
|
|
736
|
-
}, scope), /*#__PURE__*/ $epM9y$createElement($6cc32821e9371a1c$var$MenuItemImpl, $epM9y$babelruntimehelpersesmextends({
|
|
630
|
+
React.useEffect(() => clearOpenTimer, [clearOpenTimer]);
|
|
631
|
+
React.useEffect(() => {
|
|
632
|
+
const pointerGraceTimer = pointerGraceTimerRef.current;
|
|
633
|
+
return () => {
|
|
634
|
+
window.clearTimeout(pointerGraceTimer);
|
|
635
|
+
onPointerGraceIntentChange(null);
|
|
636
|
+
};
|
|
637
|
+
}, [pointerGraceTimerRef, onPointerGraceIntentChange]);
|
|
638
|
+
return /* @__PURE__ */ jsx(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx(
|
|
639
|
+
MenuItemImpl,
|
|
640
|
+
{
|
|
737
641
|
id: subContext.triggerId,
|
|
738
642
|
"aria-haspopup": "menu",
|
|
739
643
|
"aria-expanded": context.open,
|
|
740
644
|
"aria-controls": subContext.contentId,
|
|
741
|
-
"data-state":
|
|
742
|
-
|
|
743
|
-
ref:
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
/**
|
|
750
|
-
* We manually focus because iOS Safari doesn't always focus on click (e.g. buttons)
|
|
751
|
-
* and we rely heavily on `onFocusOutside` for submenus to close when switching
|
|
752
|
-
* between separate submenus.
|
|
753
|
-
*/ event.currentTarget.focus();
|
|
754
|
-
if (!context.open) context.onOpenChange(true);
|
|
645
|
+
"data-state": getOpenState(context.open),
|
|
646
|
+
...props,
|
|
647
|
+
ref: composeRefs(forwardedRef, subContext.onTriggerChange),
|
|
648
|
+
onClick: (event) => {
|
|
649
|
+
props.onClick?.(event);
|
|
650
|
+
if (props.disabled || event.defaultPrevented) return;
|
|
651
|
+
event.currentTarget.focus();
|
|
652
|
+
if (!context.open) context.onOpenChange(true);
|
|
755
653
|
},
|
|
756
|
-
onPointerMove:
|
|
654
|
+
onPointerMove: composeEventHandlers(
|
|
655
|
+
props.onPointerMove,
|
|
656
|
+
whenMouse((event) => {
|
|
757
657
|
contentContext.onItemEnter(event);
|
|
758
658
|
if (event.defaultPrevented) return;
|
|
759
659
|
if (!props.disabled && !context.open && !openTimerRef.current) {
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
660
|
+
contentContext.onPointerGraceIntentChange(null);
|
|
661
|
+
openTimerRef.current = window.setTimeout(() => {
|
|
662
|
+
context.onOpenChange(true);
|
|
663
|
+
clearOpenTimer();
|
|
664
|
+
}, 100);
|
|
765
665
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
666
|
+
})
|
|
667
|
+
),
|
|
668
|
+
onPointerLeave: composeEventHandlers(
|
|
669
|
+
props.onPointerLeave,
|
|
670
|
+
whenMouse((event) => {
|
|
769
671
|
clearOpenTimer();
|
|
770
|
-
const contentRect =
|
|
672
|
+
const contentRect = context.content?.getBoundingClientRect();
|
|
771
673
|
if (contentRect) {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
{
|
|
795
|
-
x: contentFarEdge,
|
|
796
|
-
y: contentRect.bottom
|
|
797
|
-
},
|
|
798
|
-
{
|
|
799
|
-
x: contentNearEdge,
|
|
800
|
-
y: contentRect.bottom
|
|
801
|
-
}
|
|
802
|
-
],
|
|
803
|
-
side: side
|
|
804
|
-
});
|
|
805
|
-
window.clearTimeout(pointerGraceTimerRef.current);
|
|
806
|
-
pointerGraceTimerRef.current = window.setTimeout(()=>contentContext.onPointerGraceIntentChange(null)
|
|
807
|
-
, 300);
|
|
674
|
+
const side = context.content?.dataset.side;
|
|
675
|
+
const rightSide = side === "right";
|
|
676
|
+
const bleed = rightSide ? -5 : 5;
|
|
677
|
+
const contentNearEdge = contentRect[rightSide ? "left" : "right"];
|
|
678
|
+
const contentFarEdge = contentRect[rightSide ? "right" : "left"];
|
|
679
|
+
contentContext.onPointerGraceIntentChange({
|
|
680
|
+
area: [
|
|
681
|
+
// Apply a bleed on clientX to ensure that our exit point is
|
|
682
|
+
// consistently within polygon bounds
|
|
683
|
+
{ x: event.clientX + bleed, y: event.clientY },
|
|
684
|
+
{ x: contentNearEdge, y: contentRect.top },
|
|
685
|
+
{ x: contentFarEdge, y: contentRect.top },
|
|
686
|
+
{ x: contentFarEdge, y: contentRect.bottom },
|
|
687
|
+
{ x: contentNearEdge, y: contentRect.bottom }
|
|
688
|
+
],
|
|
689
|
+
side
|
|
690
|
+
});
|
|
691
|
+
window.clearTimeout(pointerGraceTimerRef.current);
|
|
692
|
+
pointerGraceTimerRef.current = window.setTimeout(
|
|
693
|
+
() => contentContext.onPointerGraceIntentChange(null),
|
|
694
|
+
300
|
|
695
|
+
);
|
|
808
696
|
} else {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
}
|
|
813
|
-
})),
|
|
814
|
-
onKeyDown: $epM9y$composeEventHandlers(props.onKeyDown, (event)=>{
|
|
815
|
-
const isTypingAhead = contentContext.searchRef.current !== '';
|
|
816
|
-
if (props.disabled || isTypingAhead && event.key === ' ') return;
|
|
817
|
-
if ($6cc32821e9371a1c$var$SUB_OPEN_KEYS[rootContext.dir].includes(event.key)) {
|
|
818
|
-
var _context$content3;
|
|
819
|
-
context.onOpenChange(true); // The trigger may hold focus if opened via pointer interaction
|
|
820
|
-
// so we ensure content is given focus again when switching to keyboard.
|
|
821
|
-
(_context$content3 = context.content) === null || _context$content3 === void 0 || _context$content3.focus(); // prevent window from scrolling
|
|
822
|
-
event.preventDefault();
|
|
697
|
+
contentContext.onTriggerLeave(event);
|
|
698
|
+
if (event.defaultPrevented) return;
|
|
699
|
+
contentContext.onPointerGraceIntentChange(null);
|
|
823
700
|
}
|
|
701
|
+
})
|
|
702
|
+
),
|
|
703
|
+
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
704
|
+
const isTypingAhead = contentContext.searchRef.current !== "";
|
|
705
|
+
if (props.disabled || isTypingAhead && event.key === " ") return;
|
|
706
|
+
if (SUB_OPEN_KEYS[rootContext.dir].includes(event.key)) {
|
|
707
|
+
context.onOpenChange(true);
|
|
708
|
+
context.content?.focus();
|
|
709
|
+
event.preventDefault();
|
|
710
|
+
}
|
|
824
711
|
})
|
|
825
|
-
|
|
826
|
-
});
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
const
|
|
834
|
-
const
|
|
835
|
-
const
|
|
836
|
-
const
|
|
837
|
-
const
|
|
838
|
-
const
|
|
839
|
-
const
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
}, /*#__PURE__*/ $epM9y$createElement($epM9y$Presence, {
|
|
844
|
-
present: forceMount || context.open
|
|
845
|
-
}, /*#__PURE__*/ $epM9y$createElement($6cc32821e9371a1c$var$Collection.Slot, {
|
|
846
|
-
scope: props.__scopeMenu
|
|
847
|
-
}, /*#__PURE__*/ $epM9y$createElement($6cc32821e9371a1c$var$MenuContentImpl, $epM9y$babelruntimehelpersesmextends({
|
|
712
|
+
}
|
|
713
|
+
) });
|
|
714
|
+
}
|
|
715
|
+
);
|
|
716
|
+
MenuSubTrigger.displayName = SUB_TRIGGER_NAME;
|
|
717
|
+
var SUB_CONTENT_NAME = "MenuSubContent";
|
|
718
|
+
var MenuSubContent = React.forwardRef(
|
|
719
|
+
(props, forwardedRef) => {
|
|
720
|
+
const portalContext = usePortalContext(CONTENT_NAME, props.__scopeMenu);
|
|
721
|
+
const { forceMount = portalContext.forceMount, ...subContentProps } = props;
|
|
722
|
+
const context = useMenuContext(CONTENT_NAME, props.__scopeMenu);
|
|
723
|
+
const rootContext = useMenuRootContext(CONTENT_NAME, props.__scopeMenu);
|
|
724
|
+
const subContext = useMenuSubContext(SUB_CONTENT_NAME, props.__scopeMenu);
|
|
725
|
+
const ref = React.useRef(null);
|
|
726
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
727
|
+
return /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(
|
|
728
|
+
MenuContentImpl,
|
|
729
|
+
{
|
|
848
730
|
id: subContext.contentId,
|
|
849
|
-
"aria-labelledby": subContext.triggerId
|
|
850
|
-
|
|
731
|
+
"aria-labelledby": subContext.triggerId,
|
|
732
|
+
...subContentProps,
|
|
851
733
|
ref: composedRefs,
|
|
852
734
|
align: "start",
|
|
853
|
-
side: rootContext.dir ===
|
|
735
|
+
side: rootContext.dir === "rtl" ? "left" : "right",
|
|
854
736
|
disableOutsidePointerEvents: false,
|
|
855
737
|
disableOutsideScroll: false,
|
|
856
738
|
trapFocus: false,
|
|
857
|
-
onOpenAutoFocus: (event)=>{
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
onCloseAutoFocus: (event)=>event.preventDefault()
|
|
865
|
-
,
|
|
866
|
-
onFocusOutside: $epM9y$composeEventHandlers(props.onFocusOutside, (event)=>{
|
|
867
|
-
// We prevent closing when the trigger is focused to avoid triggering a re-open animation
|
|
868
|
-
// on pointer interaction.
|
|
869
|
-
if (event.target !== subContext.trigger) context.onOpenChange(false);
|
|
739
|
+
onOpenAutoFocus: (event) => {
|
|
740
|
+
if (rootContext.isUsingKeyboardRef.current) ref.current?.focus();
|
|
741
|
+
event.preventDefault();
|
|
742
|
+
},
|
|
743
|
+
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
744
|
+
onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => {
|
|
745
|
+
if (event.target !== subContext.trigger) context.onOpenChange(false);
|
|
870
746
|
}),
|
|
871
|
-
onEscapeKeyDown:
|
|
872
|
-
|
|
873
|
-
|
|
747
|
+
onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, (event) => {
|
|
748
|
+
rootContext.onClose();
|
|
749
|
+
event.preventDefault();
|
|
874
750
|
}),
|
|
875
|
-
onKeyDown:
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
event.preventDefault();
|
|
884
|
-
}
|
|
751
|
+
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
752
|
+
const isKeyDownInside = event.currentTarget.contains(event.target);
|
|
753
|
+
const isCloseKey = SUB_CLOSE_KEYS[rootContext.dir].includes(event.key);
|
|
754
|
+
if (isKeyDownInside && isCloseKey) {
|
|
755
|
+
context.onOpenChange(false);
|
|
756
|
+
subContext.trigger?.focus();
|
|
757
|
+
event.preventDefault();
|
|
758
|
+
}
|
|
885
759
|
})
|
|
886
|
-
|
|
887
|
-
});
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
760
|
+
}
|
|
761
|
+
) }) }) });
|
|
762
|
+
}
|
|
763
|
+
);
|
|
764
|
+
MenuSubContent.displayName = SUB_CONTENT_NAME;
|
|
765
|
+
function getOpenState(open) {
|
|
766
|
+
return open ? "open" : "closed";
|
|
893
767
|
}
|
|
894
|
-
function
|
|
895
|
-
|
|
768
|
+
function isIndeterminate(checked) {
|
|
769
|
+
return checked === "indeterminate";
|
|
896
770
|
}
|
|
897
|
-
function
|
|
898
|
-
|
|
771
|
+
function getCheckedState(checked) {
|
|
772
|
+
return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
|
|
899
773
|
}
|
|
900
|
-
function
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
}
|
|
774
|
+
function focusFirst(candidates) {
|
|
775
|
+
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
|
|
776
|
+
for (const candidate of candidates) {
|
|
777
|
+
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
778
|
+
candidate.focus();
|
|
779
|
+
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
780
|
+
}
|
|
908
781
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
* Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
|
|
912
|
-
*/ function $6cc32821e9371a1c$var$wrapArray(array, startIndex) {
|
|
913
|
-
return array.map((_, index)=>array[(startIndex + index) % array.length]
|
|
914
|
-
);
|
|
782
|
+
function wrapArray(array, startIndex) {
|
|
783
|
+
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
915
784
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
*
|
|
928
|
-
* Finally, if the normalized search is exactly one character, we exclude the
|
|
929
|
-
* current match from the values because otherwise it would be the first to match always
|
|
930
|
-
* and focus would never move. This is as opposed to the regular case, where we
|
|
931
|
-
* don't want focus to move if the current match still matches.
|
|
932
|
-
*/ function $6cc32821e9371a1c$var$getNextMatch(values, search, currentMatch) {
|
|
933
|
-
const isRepeated = search.length > 1 && Array.from(search).every((char)=>char === search[0]
|
|
934
|
-
);
|
|
935
|
-
const normalizedSearch = isRepeated ? search[0] : search;
|
|
936
|
-
const currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
|
|
937
|
-
let wrappedValues = $6cc32821e9371a1c$var$wrapArray(values, Math.max(currentMatchIndex, 0));
|
|
938
|
-
const excludeCurrentMatch = normalizedSearch.length === 1;
|
|
939
|
-
if (excludeCurrentMatch) wrappedValues = wrappedValues.filter((v)=>v !== currentMatch
|
|
940
|
-
);
|
|
941
|
-
const nextMatch = wrappedValues.find((value)=>value.toLowerCase().startsWith(normalizedSearch.toLowerCase())
|
|
942
|
-
);
|
|
943
|
-
return nextMatch !== currentMatch ? nextMatch : undefined;
|
|
785
|
+
function getNextMatch(values, search, currentMatch) {
|
|
786
|
+
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
|
|
787
|
+
const normalizedSearch = isRepeated ? search[0] : search;
|
|
788
|
+
const currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
|
|
789
|
+
let wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0));
|
|
790
|
+
const excludeCurrentMatch = normalizedSearch.length === 1;
|
|
791
|
+
if (excludeCurrentMatch) wrappedValues = wrappedValues.filter((v) => v !== currentMatch);
|
|
792
|
+
const nextMatch = wrappedValues.find(
|
|
793
|
+
(value) => value.toLowerCase().startsWith(normalizedSearch.toLowerCase())
|
|
794
|
+
);
|
|
795
|
+
return nextMatch !== currentMatch ? nextMatch : void 0;
|
|
944
796
|
}
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
}
|
|
958
|
-
return inside;
|
|
797
|
+
function isPointInPolygon(point, polygon) {
|
|
798
|
+
const { x, y } = point;
|
|
799
|
+
let inside = false;
|
|
800
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
801
|
+
const xi = polygon[i].x;
|
|
802
|
+
const yi = polygon[i].y;
|
|
803
|
+
const xj = polygon[j].x;
|
|
804
|
+
const yj = polygon[j].y;
|
|
805
|
+
const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
|
|
806
|
+
if (intersect) inside = !inside;
|
|
807
|
+
}
|
|
808
|
+
return inside;
|
|
959
809
|
}
|
|
960
|
-
function
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
y: event.clientY
|
|
965
|
-
};
|
|
966
|
-
return $6cc32821e9371a1c$var$isPointInPolygon(cursorPos, area);
|
|
810
|
+
function isPointerInGraceArea(event, area) {
|
|
811
|
+
if (!area) return false;
|
|
812
|
+
const cursorPos = { x: event.clientX, y: event.clientY };
|
|
813
|
+
return isPointInPolygon(cursorPos, area);
|
|
967
814
|
}
|
|
968
|
-
function
|
|
969
|
-
|
|
970
|
-
;
|
|
815
|
+
function whenMouse(handler) {
|
|
816
|
+
return (event) => event.pointerType === "mouse" ? handler(event) : void 0;
|
|
971
817
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
818
|
+
var Root3 = Menu;
|
|
819
|
+
var Anchor2 = MenuAnchor;
|
|
820
|
+
var Portal = MenuPortal;
|
|
821
|
+
var Content2 = MenuContent;
|
|
822
|
+
var Group = MenuGroup;
|
|
823
|
+
var Label = MenuLabel;
|
|
824
|
+
var Item2 = MenuItem;
|
|
825
|
+
var CheckboxItem = MenuCheckboxItem;
|
|
826
|
+
var RadioGroup = MenuRadioGroup;
|
|
827
|
+
var RadioItem = MenuRadioItem;
|
|
828
|
+
var ItemIndicator = MenuItemIndicator;
|
|
829
|
+
var Separator = MenuSeparator;
|
|
830
|
+
var Arrow2 = MenuArrow;
|
|
831
|
+
var Sub = MenuSub;
|
|
832
|
+
var SubTrigger = MenuSubTrigger;
|
|
833
|
+
var SubContent = MenuSubContent;
|
|
834
|
+
export {
|
|
835
|
+
Anchor2 as Anchor,
|
|
836
|
+
Arrow2 as Arrow,
|
|
837
|
+
CheckboxItem,
|
|
838
|
+
Content2 as Content,
|
|
839
|
+
Group,
|
|
840
|
+
Item2 as Item,
|
|
841
|
+
ItemIndicator,
|
|
842
|
+
Label,
|
|
843
|
+
Menu,
|
|
844
|
+
MenuAnchor,
|
|
845
|
+
MenuArrow,
|
|
846
|
+
MenuCheckboxItem,
|
|
847
|
+
MenuContent,
|
|
848
|
+
MenuGroup,
|
|
849
|
+
MenuItem,
|
|
850
|
+
MenuItemIndicator,
|
|
851
|
+
MenuLabel,
|
|
852
|
+
MenuPortal,
|
|
853
|
+
MenuRadioGroup,
|
|
854
|
+
MenuRadioItem,
|
|
855
|
+
MenuSeparator,
|
|
856
|
+
MenuSub,
|
|
857
|
+
MenuSubContent,
|
|
858
|
+
MenuSubTrigger,
|
|
859
|
+
Portal,
|
|
860
|
+
RadioGroup,
|
|
861
|
+
RadioItem,
|
|
862
|
+
Root3 as Root,
|
|
863
|
+
Separator,
|
|
864
|
+
Sub,
|
|
865
|
+
SubContent,
|
|
866
|
+
SubTrigger,
|
|
867
|
+
createMenuScope
|
|
868
|
+
};
|
|
993
869
|
//# sourceMappingURL=index.mjs.map
|