@tamagui/menu 1.138.0 → 1.138.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/cjs/createMenu.cjs +952 -0
  2. package/dist/cjs/createMenu.js +751 -0
  3. package/dist/cjs/createMenu.js.map +6 -0
  4. package/dist/cjs/createMenu.native.js +1136 -0
  5. package/dist/cjs/createMenu.native.js.map +1 -0
  6. package/dist/cjs/createNativeMenu/createNativeMenu.android.js +261 -0
  7. package/dist/cjs/createNativeMenu/createNativeMenu.android.js.map +6 -0
  8. package/dist/cjs/createNativeMenu/createNativeMenu.cjs +47 -0
  9. package/dist/cjs/createNativeMenu/createNativeMenu.ios.js +373 -0
  10. package/dist/cjs/createNativeMenu/createNativeMenu.ios.js.map +6 -0
  11. package/dist/cjs/createNativeMenu/createNativeMenu.js +42 -0
  12. package/dist/cjs/createNativeMenu/createNativeMenu.js.map +6 -0
  13. package/dist/cjs/createNativeMenu/createNativeMenu.native.js +356 -0
  14. package/dist/cjs/createNativeMenu/createNativeMenu.native.js.map +1 -0
  15. package/dist/cjs/createNativeMenu/createNativeMenuTypes.cjs +16 -0
  16. package/dist/cjs/createNativeMenu/createNativeMenuTypes.js +14 -0
  17. package/dist/cjs/createNativeMenu/createNativeMenuTypes.js.map +6 -0
  18. package/dist/cjs/createNativeMenu/createNativeMenuTypes.native.js +19 -0
  19. package/dist/cjs/createNativeMenu/createNativeMenuTypes.native.js.map +1 -0
  20. package/dist/cjs/createNativeMenu/index.cjs +19 -0
  21. package/dist/cjs/createNativeMenu/index.js +16 -0
  22. package/dist/cjs/createNativeMenu/index.js.map +6 -0
  23. package/dist/cjs/createNativeMenu/index.native.js +22 -0
  24. package/dist/cjs/createNativeMenu/index.native.js.map +1 -0
  25. package/dist/cjs/createNativeMenu/utils.cjs +68 -0
  26. package/dist/cjs/createNativeMenu/utils.js +66 -0
  27. package/dist/cjs/createNativeMenu/utils.js.map +6 -0
  28. package/dist/cjs/createNativeMenu/utils.native.js +94 -0
  29. package/dist/cjs/createNativeMenu/utils.native.js.map +1 -0
  30. package/dist/cjs/createNativeMenu/withNativeMenu.cjs +45 -0
  31. package/dist/cjs/createNativeMenu/withNativeMenu.js +35 -0
  32. package/dist/cjs/createNativeMenu/withNativeMenu.js.map +6 -0
  33. package/dist/cjs/createNativeMenu/withNativeMenu.native.js +49 -0
  34. package/dist/cjs/createNativeMenu/withNativeMenu.native.js.map +1 -0
  35. package/dist/esm/createMenu.js +757 -0
  36. package/dist/esm/createMenu.js.map +6 -0
  37. package/dist/esm/createMenu.mjs +916 -0
  38. package/dist/esm/createMenu.mjs.map +1 -0
  39. package/dist/esm/createMenu.native.js +1097 -0
  40. package/dist/esm/createMenu.native.js.map +1 -0
  41. package/dist/esm/createNativeMenu/createNativeMenu.android.js +251 -0
  42. package/dist/esm/createNativeMenu/createNativeMenu.android.js.map +6 -0
  43. package/dist/esm/createNativeMenu/createNativeMenu.ios.js +363 -0
  44. package/dist/esm/createNativeMenu/createNativeMenu.ios.js.map +6 -0
  45. package/dist/esm/createNativeMenu/createNativeMenu.js +26 -0
  46. package/dist/esm/createNativeMenu/createNativeMenu.js.map +6 -0
  47. package/dist/esm/createNativeMenu/createNativeMenu.mjs +24 -0
  48. package/dist/esm/createNativeMenu/createNativeMenu.mjs.map +1 -0
  49. package/dist/esm/createNativeMenu/createNativeMenu.native.js +330 -0
  50. package/dist/esm/createNativeMenu/createNativeMenu.native.js.map +1 -0
  51. package/dist/esm/createNativeMenu/createNativeMenuTypes.js +1 -0
  52. package/dist/esm/createNativeMenu/createNativeMenuTypes.js.map +6 -0
  53. package/dist/esm/createNativeMenu/createNativeMenuTypes.mjs +2 -0
  54. package/dist/esm/createNativeMenu/createNativeMenuTypes.mjs.map +1 -0
  55. package/dist/esm/createNativeMenu/createNativeMenuTypes.native.js +2 -0
  56. package/dist/esm/createNativeMenu/createNativeMenuTypes.native.js.map +1 -0
  57. package/dist/esm/createNativeMenu/index.js +3 -0
  58. package/dist/esm/createNativeMenu/index.js.map +6 -0
  59. package/dist/esm/createNativeMenu/index.mjs +3 -0
  60. package/dist/esm/createNativeMenu/index.mjs.map +1 -0
  61. package/dist/esm/createNativeMenu/index.native.js +3 -0
  62. package/dist/esm/createNativeMenu/index.native.js.map +1 -0
  63. package/dist/esm/createNativeMenu/utils.js +47 -0
  64. package/dist/esm/createNativeMenu/utils.js.map +6 -0
  65. package/dist/esm/createNativeMenu/utils.mjs +29 -0
  66. package/dist/esm/createNativeMenu/utils.mjs.map +1 -0
  67. package/dist/esm/createNativeMenu/utils.native.js +52 -0
  68. package/dist/esm/createNativeMenu/utils.native.js.map +1 -0
  69. package/dist/esm/createNativeMenu/withNativeMenu.js +20 -0
  70. package/dist/esm/createNativeMenu/withNativeMenu.js.map +6 -0
  71. package/dist/esm/createNativeMenu/withNativeMenu.mjs +22 -0
  72. package/dist/esm/createNativeMenu/withNativeMenu.mjs.map +1 -0
  73. package/dist/esm/createNativeMenu/withNativeMenu.native.js +23 -0
  74. package/dist/esm/createNativeMenu/withNativeMenu.native.js.map +1 -0
  75. package/dist/jsx/createMenu.js +757 -0
  76. package/dist/jsx/createMenu.js.map +6 -0
  77. package/dist/jsx/createMenu.mjs +916 -0
  78. package/dist/jsx/createMenu.mjs.map +1 -0
  79. package/dist/jsx/createMenu.native.js +1136 -0
  80. package/dist/jsx/createMenu.native.js.map +1 -0
  81. package/dist/jsx/createNativeMenu/createNativeMenu.android.js +261 -0
  82. package/dist/jsx/createNativeMenu/createNativeMenu.android.js.map +6 -0
  83. package/dist/jsx/createNativeMenu/createNativeMenu.ios.js +373 -0
  84. package/dist/jsx/createNativeMenu/createNativeMenu.ios.js.map +6 -0
  85. package/dist/jsx/createNativeMenu/createNativeMenu.js +26 -0
  86. package/dist/jsx/createNativeMenu/createNativeMenu.js.map +6 -0
  87. package/dist/jsx/createNativeMenu/createNativeMenu.mjs +24 -0
  88. package/dist/jsx/createNativeMenu/createNativeMenu.mjs.map +1 -0
  89. package/dist/jsx/createNativeMenu/createNativeMenu.native.js +356 -0
  90. package/dist/jsx/createNativeMenu/createNativeMenu.native.js.map +1 -0
  91. package/dist/jsx/createNativeMenu/createNativeMenuTypes.js +1 -0
  92. package/dist/jsx/createNativeMenu/createNativeMenuTypes.js.map +6 -0
  93. package/dist/jsx/createNativeMenu/createNativeMenuTypes.mjs +2 -0
  94. package/dist/jsx/createNativeMenu/createNativeMenuTypes.mjs.map +1 -0
  95. package/dist/jsx/createNativeMenu/createNativeMenuTypes.native.js +19 -0
  96. package/dist/jsx/createNativeMenu/createNativeMenuTypes.native.js.map +1 -0
  97. package/dist/jsx/createNativeMenu/index.js +3 -0
  98. package/dist/jsx/createNativeMenu/index.js.map +6 -0
  99. package/dist/jsx/createNativeMenu/index.mjs +3 -0
  100. package/dist/jsx/createNativeMenu/index.mjs.map +1 -0
  101. package/dist/jsx/createNativeMenu/index.native.js +22 -0
  102. package/dist/jsx/createNativeMenu/index.native.js.map +1 -0
  103. package/dist/jsx/createNativeMenu/utils.js +47 -0
  104. package/dist/jsx/createNativeMenu/utils.js.map +6 -0
  105. package/dist/jsx/createNativeMenu/utils.mjs +29 -0
  106. package/dist/jsx/createNativeMenu/utils.mjs.map +1 -0
  107. package/dist/jsx/createNativeMenu/utils.native.js +94 -0
  108. package/dist/jsx/createNativeMenu/utils.native.js.map +1 -0
  109. package/dist/jsx/createNativeMenu/withNativeMenu.js +20 -0
  110. package/dist/jsx/createNativeMenu/withNativeMenu.js.map +6 -0
  111. package/dist/jsx/createNativeMenu/withNativeMenu.mjs +22 -0
  112. package/dist/jsx/createNativeMenu/withNativeMenu.mjs.map +1 -0
  113. package/dist/jsx/createNativeMenu/withNativeMenu.native.js +49 -0
  114. package/dist/jsx/createNativeMenu/withNativeMenu.native.js.map +1 -0
  115. package/package.json +6 -6
  116. package/types/createMenu.d.ts.map +1 -0
  117. package/types/createNativeMenu/createNativeMenu.android.d.ts.map +1 -0
  118. package/types/createNativeMenu/createNativeMenu.d.ts.map +1 -0
  119. package/types/createNativeMenu/createNativeMenu.ios.d.ts.map +1 -0
  120. package/types/createNativeMenu/createNativeMenu.native.d.ts.map +1 -0
  121. package/types/createNativeMenu/createNativeMenuTypes.d.ts.map +1 -0
  122. package/types/createNativeMenu/index.d.ts.map +1 -0
  123. package/types/createNativeMenu/utils.d.ts.map +1 -0
  124. package/types/createNativeMenu/withNativeMenu.d.ts.map +1 -0
@@ -0,0 +1,952 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf,
6
+ __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: !0
11
+ });
12
+ },
13
+ __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, {
15
+ get: () => from[key],
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
26
+ value: mod,
27
+ enumerable: !0
28
+ }) : target, mod)),
29
+ __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
30
+ value: !0
31
+ }), mod);
32
+ var createMenu_exports = {};
33
+ __export(createMenu_exports, {
34
+ NativePropProvider: () => NativePropProvider,
35
+ createMenu: () => createMenu,
36
+ useNativeProp: () => useNativeProp
37
+ });
38
+ module.exports = __toCommonJS(createMenu_exports);
39
+ var import_animate = require("@tamagui/animate"),
40
+ import_animate_presence = require("@tamagui/animate-presence"),
41
+ import_collection = require("@tamagui/collection"),
42
+ import_core = require("@tamagui/core"),
43
+ import_dismissable = require("@tamagui/dismissable"),
44
+ import_focus_guard = require("@tamagui/focus-guard"),
45
+ import_focus_scope = require("@tamagui/focus-scope"),
46
+ PopperPrimitive = __toESM(require("@tamagui/popper"), 1),
47
+ import_portal = require("@tamagui/portal"),
48
+ import_remove_scroll = require("@tamagui/remove-scroll"),
49
+ import_roving_focus = require("@tamagui/roving-focus"),
50
+ import_stacks = require("@tamagui/stacks"),
51
+ import_use_callback_ref = require("@tamagui/use-callback-ref"),
52
+ import_use_direction = require("@tamagui/use-direction"),
53
+ import_web = require("@tamagui/web"),
54
+ React = __toESM(require("react"), 1),
55
+ import_react = require("react"),
56
+ import_Menu = require("./Menu.cjs"),
57
+ import_jsx_runtime = require("react/jsx-runtime");
58
+ const SELECTION_KEYS = ["Enter", " "],
59
+ FIRST_KEYS = ["ArrowDown", "PageUp", "Home"],
60
+ LAST_KEYS = ["ArrowUp", "PageDown", "End"],
61
+ FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS],
62
+ SUB_OPEN_KEYS = {
63
+ ltr: [...SELECTION_KEYS, "ArrowRight"],
64
+ rtl: [...SELECTION_KEYS, "ArrowLeft"]
65
+ },
66
+ SUB_CLOSE_KEYS = {
67
+ ltr: ["ArrowLeft"],
68
+ rtl: ["ArrowRight"]
69
+ },
70
+ MENU_NAME = "Menu",
71
+ [Collection, useCollection] = (0, import_collection.createCollection)(MENU_NAME),
72
+ {
73
+ Provider: MenuProvider,
74
+ useStyledContext: useMenuContext
75
+ } = (0, import_core.createStyledContext)(),
76
+ {
77
+ Provider: MenuRootProvider,
78
+ useStyledContext: useMenuRootContext
79
+ } = (0, import_core.createStyledContext)(),
80
+ MENU_CONTEXT = "MenuContext",
81
+ {
82
+ Provider: NativePropProvider,
83
+ useStyledContext: useNativeProp
84
+ } = (0, import_core.createStyledContext)({
85
+ native: !1
86
+ });
87
+ function createMenu({
88
+ Item: _Item = import_Menu.MenuPredefinied.MenuItem,
89
+ Title: _Title = import_Menu.MenuPredefinied.Title,
90
+ SubTitle: _SubTitle = import_Menu.MenuPredefinied.SubTitle,
91
+ Image: _Image = import_Menu.MenuPredefinied.MenuImage,
92
+ Icon: _Icon = import_Menu.MenuPredefinied.MenuIcon,
93
+ Indicator: _Indicator = import_Menu.MenuPredefinied.MenuIndicator,
94
+ Separator: _Separator = import_Menu.MenuPredefinied.MenuSeparator,
95
+ MenuGroup: _MenuGroup = import_Menu.MenuPredefinied.MenuGroup,
96
+ Label: _Label = import_Menu.MenuPredefinied.MenuLabel
97
+ }) {
98
+ const MenuComp = props => {
99
+ const {
100
+ scope,
101
+ open = !1,
102
+ children,
103
+ dir,
104
+ onOpenChange,
105
+ modal = !0,
106
+ ...rest
107
+ } = props,
108
+ [content, setContent] = React.useState(null),
109
+ isUsingKeyboardRef = React.useRef(!1),
110
+ handleOpenChange = (0, import_use_callback_ref.useCallbackRef)(onOpenChange),
111
+ direction = (0, import_use_direction.useDirection)(dir);
112
+ return import_web.isWeb && React.useEffect(() => {
113
+ const handleKeyDown = () => {
114
+ isUsingKeyboardRef.current = !0, document.addEventListener("pointerdown", handlePointer, {
115
+ capture: !0,
116
+ once: !0
117
+ }), document.addEventListener("pointermove", handlePointer, {
118
+ capture: !0,
119
+ once: !0
120
+ });
121
+ },
122
+ handlePointer = () => isUsingKeyboardRef.current = !1;
123
+ return document.addEventListener("keydown", handleKeyDown, {
124
+ capture: !0
125
+ }), () => {
126
+ document.removeEventListener("keydown", handleKeyDown, {
127
+ capture: !0
128
+ }), document.removeEventListener("pointerdown", handlePointer, {
129
+ capture: !0
130
+ }), document.removeEventListener("pointermove", handlePointer, {
131
+ capture: !0
132
+ });
133
+ };
134
+ }, []), /* @__PURE__ */(0, import_jsx_runtime.jsx)(PopperPrimitive.Popper, {
135
+ scope: scope || MENU_CONTEXT,
136
+ ...rest,
137
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuProvider, {
138
+ scope,
139
+ open,
140
+ onOpenChange: handleOpenChange,
141
+ content,
142
+ onContentChange: setContent,
143
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(NativePropProvider, {
144
+ native: !1,
145
+ scope,
146
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuRootProvider, {
147
+ scope,
148
+ onClose: React.useCallback(() => handleOpenChange(!1), [handleOpenChange]),
149
+ isUsingKeyboardRef,
150
+ dir: direction,
151
+ modal,
152
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuSubProvider, {
153
+ scope,
154
+ children
155
+ })
156
+ })
157
+ })
158
+ })
159
+ });
160
+ },
161
+ RepropagateMenuAndMenuRootProvider = props => {
162
+ const {
163
+ scope,
164
+ menuContext,
165
+ rootContext,
166
+ popperContext,
167
+ menuSubContext,
168
+ children
169
+ } = props;
170
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(PopperPrimitive.PopperProvider, {
171
+ ...popperContext,
172
+ scope: scope || MENU_CONTEXT,
173
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(NativePropProvider, {
174
+ native: !1,
175
+ scope,
176
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuProvider, {
177
+ scope,
178
+ ...menuContext,
179
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuRootProvider, {
180
+ scope,
181
+ ...rootContext,
182
+ children: menuSubContext ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuSubProvider, {
183
+ scope,
184
+ ...menuSubContext,
185
+ children
186
+ }) : children
187
+ })
188
+ })
189
+ })
190
+ });
191
+ };
192
+ MenuComp.displayName = MENU_NAME;
193
+ const ANCHOR_NAME = "MenuAnchor",
194
+ MenuAnchor = props => /* @__PURE__ */(0, import_jsx_runtime.jsx)(PopperPrimitive.PopperAnchor, {
195
+ scope: MENU_CONTEXT,
196
+ ...props
197
+ });
198
+ MenuAnchor.displayName = ANCHOR_NAME;
199
+ const PORTAL_NAME = "MenuPortal",
200
+ {
201
+ Provider: PortalProvider,
202
+ useStyledContext: usePortalContext
203
+ } = (0, import_core.createStyledContext)(void 0, "Portal"),
204
+ MenuPortal = props => {
205
+ const {
206
+ scope,
207
+ forceMount,
208
+ zIndex,
209
+ children
210
+ // TODO removed
211
+ // host
212
+ } = props,
213
+ menuContext = useMenuContext(scope),
214
+ rootContext = useMenuRootContext(scope),
215
+ popperContext = PopperPrimitive.usePopperContext(scope || MENU_CONTEXT),
216
+ menuSubContext = useMenuSubContext(scope),
217
+ content = import_web.isAndroid ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(RepropagateMenuAndMenuRootProvider, {
218
+ menuContext,
219
+ rootContext,
220
+ popperContext,
221
+ menuSubContext,
222
+ scope,
223
+ children
224
+ }) : children;
225
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_animate.Animate, {
226
+ type: "presence",
227
+ present: forceMount || menuContext.open,
228
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_portal.Portal, {
229
+ host,
230
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {
231
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(PortalProvider, {
232
+ scope,
233
+ forceMount,
234
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_stacks.YStack, {
235
+ zIndex: zIndex || 100,
236
+ fullscreen: !0,
237
+ children: [!!menuContext.open && !import_web.isWeb && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_stacks.YStack, {
238
+ fullscreen: !0,
239
+ onPress: () => menuContext.onOpenChange(!menuContext.open)
240
+ }), content]
241
+ })
242
+ })
243
+ })
244
+ })
245
+ });
246
+ };
247
+ MenuPortal.displayName = PORTAL_NAME;
248
+ const CONTENT_NAME = "MenuContent",
249
+ {
250
+ Provider: MenuContentProvider,
251
+ useStyledContext: useMenuContentContext
252
+ } = (0, import_core.createStyledContext)(),
253
+ MenuContent = React.forwardRef((props, forwardedRef) => {
254
+ const portalContext = usePortalContext(props.scope),
255
+ {
256
+ forceMount = portalContext.forceMount,
257
+ ...contentProps
258
+ } = props,
259
+ rootContext = useMenuRootContext(props.scope);
260
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Collection.Provider, {
261
+ scope: props.scope || MENU_CONTEXT,
262
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(Collection.Slot, {
263
+ scope: props.scope || MENU_CONTEXT,
264
+ children: rootContext.modal ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuRootContentModal, {
265
+ ...contentProps,
266
+ ref: forwardedRef
267
+ }) : /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuRootContentNonModal, {
268
+ ...contentProps,
269
+ ref: forwardedRef
270
+ })
271
+ })
272
+ });
273
+ }),
274
+ MenuRootContentModal = React.forwardRef((props, forwardedRef) => {
275
+ const context = useMenuContext(props.scope),
276
+ ref = React.useRef(null),
277
+ composedRefs = (0, import_core.useComposedRefs)(forwardedRef, ref);
278
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuContentImpl, {
279
+ ...props,
280
+ ref: composedRefs,
281
+ trapFocus: context.open,
282
+ disableOutsidePointerEvents: context.open,
283
+ disableOutsideScroll: !0,
284
+ onFocusOutside: (0, import_core.composeEventHandlers)(props.onFocusOutside, event => event.preventDefault(), {
285
+ checkDefaultPrevented: !1
286
+ }),
287
+ onDismiss: () => context.onOpenChange(!1)
288
+ });
289
+ }),
290
+ MenuRootContentNonModal = React.forwardRef((props, forwardedRef) => {
291
+ const context = useMenuContext(props.scope);
292
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuContentImpl, {
293
+ ...props,
294
+ ref: forwardedRef,
295
+ trapFocus: !1,
296
+ disableOutsidePointerEvents: !1,
297
+ disableOutsideScroll: !1,
298
+ onDismiss: () => context.onOpenChange(!1)
299
+ });
300
+ }),
301
+ Fragment2 = React.forwardRef((props, ref) => props.children),
302
+ MenuContentImpl = React.forwardRef((props, forwardedRef) => {
303
+ const {
304
+ scope = MENU_CONTEXT,
305
+ loop = !1,
306
+ trapFocus,
307
+ onOpenAutoFocus,
308
+ onCloseAutoFocus,
309
+ disableOutsidePointerEvents,
310
+ onEntryFocus,
311
+ onEscapeKeyDown,
312
+ onPointerDownOutside,
313
+ onFocusOutside,
314
+ onInteractOutside,
315
+ onDismiss,
316
+ disableOutsideScroll,
317
+ unstyled = process.env.TAMAGUI_HEADLESS === "1",
318
+ ...contentProps
319
+ } = props,
320
+ context = useMenuContext(scope),
321
+ rootContext = useMenuRootContext(scope),
322
+ getItems = useCollection(scope),
323
+ [currentItemId, setCurrentItemId] = React.useState(null),
324
+ contentRef = React.useRef(null),
325
+ composedRefs = (0, import_core.useComposedRefs)(forwardedRef, contentRef, context.onContentChange),
326
+ timerRef = React.useRef(0),
327
+ searchRef = React.useRef(""),
328
+ pointerGraceTimerRef = React.useRef(0),
329
+ pointerGraceIntentRef = React.useRef(null),
330
+ pointerDirRef = React.useRef("right"),
331
+ lastPointerXRef = React.useRef(0),
332
+ handleTypeaheadSearch = key => {
333
+ const search = searchRef.current + key,
334
+ items = getItems().filter(item => !item.disabled),
335
+ currentItem = document.activeElement,
336
+ currentMatch = items.find(item => item.ref.current === currentItem)?.textValue,
337
+ values = items.map(item => item.textValue),
338
+ nextMatch = getNextMatch(values, search, currentMatch),
339
+ newItem = items.find(item => item.textValue === nextMatch)?.ref.current;
340
+ (function updateSearch(value) {
341
+ searchRef.current = value, clearTimeout(timerRef.current), value !== "" && (timerRef.current = setTimeout(() => updateSearch(""), 1e3));
342
+ })(search), newItem && setTimeout(() => newItem.focus());
343
+ };
344
+ React.useEffect(() => () => clearTimeout(timerRef.current), []), import_web.isWeb && (0, import_focus_guard.useFocusGuards)();
345
+ const isPointerMovingToSubmenu = React.useCallback(event => pointerDirRef.current === pointerGraceIntentRef.current?.side && isPointerInGraceArea(event, pointerGraceIntentRef.current?.area), []),
346
+ content = /* @__PURE__ */(0, import_jsx_runtime.jsx)(PopperPrimitive.PopperContent, {
347
+ role: "menu",
348
+ ...(!unstyled && {
349
+ elevation: 30,
350
+ paddingVertical: "$2",
351
+ backgroundColor: "$background",
352
+ borderColor: "$borderColor",
353
+ outlineWidth: 0
354
+ }),
355
+ "aria-orientation": "vertical",
356
+ "data-state": getOpenState(context.open),
357
+ "data-tamagui-menu-content": "",
358
+ dir: rootContext.dir,
359
+ scope: scope || MENU_CONTEXT,
360
+ ...contentProps,
361
+ ref: composedRefs,
362
+ className: contentProps.animation ? void 0 : contentProps.className,
363
+ ...(import_web.isWeb ? {
364
+ onKeyDown: (0, import_core.composeEventHandlers)(
365
+ //@ts-ignore
366
+ contentProps.onKeyDown, event => {
367
+ const isKeyDownInside = event.target.closest("[data-tamagui-menu-content]") === event.currentTarget,
368
+ isModifierKey = event.ctrlKey || event.altKey || event.metaKey,
369
+ isCharacterKey = event.key.length === 1;
370
+ isKeyDownInside && (event.key === "Tab" && event.preventDefault(), !isModifierKey && isCharacterKey && handleTypeaheadSearch(event.key));
371
+ const content2 = contentRef.current;
372
+ if (event.target !== content2 || !FIRST_LAST_KEYS.includes(event.key)) return;
373
+ event.preventDefault();
374
+ const candidateNodes = getItems().filter(item => !item.disabled).map(item => item.ref.current);
375
+ LAST_KEYS.includes(event.key) && candidateNodes.reverse(), focusFirst(candidateNodes);
376
+ }),
377
+ // @ts-ignore
378
+ onBlur: (0, import_core.composeEventHandlers)(props.onBlur, event => {
379
+ event.currentTarget?.contains(event.target) || (clearTimeout(timerRef.current), searchRef.current = "");
380
+ }),
381
+ onPointerMove: (0, import_core.composeEventHandlers)(
382
+ // @ts-ignore
383
+ props.onPointerMove,
384
+ // @ts-ignore
385
+ whenMouse(event => {
386
+ const target = event.target,
387
+ pointerXHasChanged = lastPointerXRef.current !== event.clientX;
388
+ if (event.currentTarget?.contains(target) && pointerXHasChanged) {
389
+ const newDir = event.clientX > lastPointerXRef.current ? "right" : "left";
390
+ pointerDirRef.current = newDir, lastPointerXRef.current = event.clientX;
391
+ }
392
+ }))
393
+ } : {})
394
+ });
395
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuContentProvider, {
396
+ scope,
397
+ searchRef,
398
+ onItemEnter: React.useCallback(event => {
399
+ isPointerMovingToSubmenu(event) && event.preventDefault();
400
+ }, [isPointerMovingToSubmenu]),
401
+ onItemLeave: React.useCallback(event => {
402
+ isPointerMovingToSubmenu(event) || (contentRef.current?.focus(), setCurrentItemId(null));
403
+ }, [isPointerMovingToSubmenu]),
404
+ onTriggerLeave: React.useCallback(event => {
405
+ isPointerMovingToSubmenu(event) && event.preventDefault();
406
+ }, [isPointerMovingToSubmenu]),
407
+ pointerGraceTimerRef,
408
+ onPointerGraceIntentChange: React.useCallback(intent => {
409
+ pointerGraceIntentRef.current = intent;
410
+ }, []),
411
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_remove_scroll.RemoveScroll, {
412
+ enabled: disableOutsideScroll,
413
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_focus_scope.FocusScope, {
414
+ asChild: !1,
415
+ trapped: trapFocus,
416
+ onMountAutoFocus: (0, import_core.composeEventHandlers)(onOpenAutoFocus, event => {
417
+ event.preventDefault(), contentRef.current?.focus();
418
+ }),
419
+ onUnmountAutoFocus: onCloseAutoFocus,
420
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_dismissable.Dismissable, {
421
+ disableOutsidePointerEvents,
422
+ onEscapeKeyDown,
423
+ onPointerDownOutside,
424
+ onFocusOutside,
425
+ onInteractOutside,
426
+ onDismiss,
427
+ asChild: !0,
428
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_roving_focus.RovingFocusGroup, {
429
+ asChild: !0,
430
+ __scopeRovingFocusGroup: scope || MENU_CONTEXT,
431
+ dir: rootContext.dir,
432
+ orientation: "vertical",
433
+ loop,
434
+ currentTabStopId: currentItemId,
435
+ onCurrentTabStopIdChange: setCurrentItemId,
436
+ onEntryFocus: (0, import_core.composeEventHandlers)(onEntryFocus, event => {
437
+ rootContext.isUsingKeyboardRef.current || event.preventDefault();
438
+ }),
439
+ children: content
440
+ })
441
+ })
442
+ })
443
+ })
444
+ });
445
+ });
446
+ MenuContent.displayName = CONTENT_NAME;
447
+ const ITEM_NAME = "MenuItem",
448
+ ITEM_SELECT = "menu.itemSelect",
449
+ MenuItem = import_stacks.ThemeableStack.styleable((props, forwardedRef) => {
450
+ const {
451
+ disabled = !1,
452
+ onSelect,
453
+ children,
454
+ ...itemProps
455
+ } = props,
456
+ ref = React.useRef(null),
457
+ rootContext = useMenuRootContext(props.scope),
458
+ contentContext = useMenuContentContext(props.scope),
459
+ composedRefs = (0, import_core.useComposedRefs)(forwardedRef, ref),
460
+ isPointerDownRef = React.useRef(!1),
461
+ handleSelect = () => {
462
+ const menuItem = ref.current;
463
+ if (!disabled && menuItem) if (import_web.isWeb) {
464
+ const itemSelectEvent = new CustomEvent(ITEM_SELECT, {
465
+ bubbles: !0,
466
+ cancelable: !0
467
+ });
468
+ menuItem.addEventListener(ITEM_SELECT, event => onSelect?.(event), {
469
+ once: !0
470
+ }), (0, import_dismissable.dispatchDiscreteCustomEvent)(menuItem, itemSelectEvent), itemSelectEvent.defaultPrevented ? isPointerDownRef.current = !1 : rootContext.onClose();
471
+ } else onSelect?.({
472
+ target: menuItem
473
+ }), isPointerDownRef.current = !1, rootContext.onClose();
474
+ },
475
+ content = typeof children == "string" ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_core.Text, {
476
+ children
477
+ }) : children;
478
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuItemImpl, {
479
+ outlineStyle: "none",
480
+ ...itemProps,
481
+ ref: composedRefs,
482
+ disabled,
483
+ onPress: (0, import_core.composeEventHandlers)(props.onPress, handleSelect),
484
+ onPointerDown: event => {
485
+ props.onPointerDown?.(event), isPointerDownRef.current = !0;
486
+ },
487
+ onPointerUp: (0, import_core.composeEventHandlers)(props.onPointerUp, event => {
488
+ import_web.isWeb && (isPointerDownRef.current || event.currentTarget?.click());
489
+ }),
490
+ ...(import_web.isWeb ? {
491
+ onKeyDown: (0, import_core.composeEventHandlers)(
492
+ // @ts-ignore
493
+ props.onKeyDown, event => {
494
+ const isTypingAhead = contentContext.searchRef.current !== "";
495
+ disabled || isTypingAhead && event.key === " " || SELECTION_KEYS.includes(event.key) && (event.currentTarget?.click(), event.preventDefault());
496
+ })
497
+ } : {}),
498
+ children: content
499
+ });
500
+ }),
501
+ MenuItemImpl = React.forwardRef((props, forwardedRef) => {
502
+ const {
503
+ scope,
504
+ disabled = !1,
505
+ textValue,
506
+ unstyled = process.env.TAMAGUI_HEADLESS === "1",
507
+ ...itemProps
508
+ } = props,
509
+ contentContext = useMenuContentContext(scope),
510
+ ref = React.useRef(null),
511
+ composedRefs = (0, import_core.useComposedRefs)(forwardedRef, ref),
512
+ [isFocused, setIsFocused] = React.useState(!1),
513
+ [textContent, setTextContent] = React.useState("");
514
+ return import_web.isWeb && React.useEffect(() => {
515
+ const menuItem = ref.current;
516
+ menuItem && setTextContent((menuItem.textContent ?? "").trim());
517
+ }, [itemProps.children]), /* @__PURE__ */(0, import_jsx_runtime.jsx)(Collection.ItemSlot, {
518
+ scope: scope || MENU_CONTEXT,
519
+ disabled,
520
+ textValue: textValue ?? textContent,
521
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_roving_focus.RovingFocusGroup.Item, {
522
+ asChild: !0,
523
+ __scopeRovingFocusGroup: scope || MENU_CONTEXT,
524
+ focusable: !disabled,
525
+ ...(!unstyled && {
526
+ flexDirection: "row",
527
+ alignItems: "center"
528
+ }),
529
+ ...itemProps,
530
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(_Item, {
531
+ ...(!unstyled && {
532
+ hoverTheme: !0,
533
+ pressTheme: !0,
534
+ focusTheme: !0,
535
+ paddingVertical: "$2",
536
+ paddingHorizontal: "$4",
537
+ width: "100%"
538
+ }),
539
+ componentName: ITEM_NAME,
540
+ role: "menuitem",
541
+ "data-highlighted": isFocused ? "" : void 0,
542
+ "aria-disabled": disabled || void 0,
543
+ "data-disabled": disabled ? "" : void 0,
544
+ ...itemProps,
545
+ ref: composedRefs,
546
+ onPointerMove: (0, import_core.composeEventHandlers)(props.onPointerMove,
547
+ // @ts-ignore
548
+ whenMouse(event => {
549
+ disabled ? contentContext.onItemLeave(event) : (contentContext.onItemEnter(event), event.defaultPrevented || event.currentTarget.focus());
550
+ })),
551
+ onPointerLeave: (0, import_core.composeEventHandlers)(
552
+ // @ts-ignore
553
+ props.onPointerLeave,
554
+ // @ts-ignore
555
+ whenMouse(event => contentContext.onItemLeave(event))),
556
+ onFocus: (0, import_core.composeEventHandlers)(props.onFocus, () => setIsFocused(!0)),
557
+ onBlur: (0, import_core.composeEventHandlers)(props.onBlur, () => setIsFocused(!1))
558
+ })
559
+ })
560
+ });
561
+ });
562
+ MenuItem.displayName = ITEM_NAME;
563
+ const ITEM_TITLE_NAME = "MenuItemTitle",
564
+ MenuItemTitle = _Title.styleable((props, forwardedRef) => /* @__PURE__ */(0, import_jsx_runtime.jsx)(_Title, {
565
+ ...props,
566
+ ref: forwardedRef
567
+ }));
568
+ MenuItemTitle.displayName = ITEM_TITLE_NAME;
569
+ const ITEM_SUB_TITLE_NAME = "MenuItemSubTitle",
570
+ MenuItemSubTitle = _SubTitle.styleable((props, forwardedRef) => /* @__PURE__ */(0, import_jsx_runtime.jsx)(_SubTitle, {
571
+ ...props,
572
+ ref: forwardedRef
573
+ }));
574
+ MenuItemSubTitle.displayName = ITEM_SUB_TITLE_NAME;
575
+ const ITEM_IMAGE = "MenuItemImage",
576
+ MenuItemImage = React.forwardRef((props, forwardedRef) => /* @__PURE__ */(0, import_jsx_runtime.jsx)(_Image, {
577
+ ...props,
578
+ ref: forwardedRef
579
+ }));
580
+ MenuItemImage.displayName = ITEM_IMAGE;
581
+ const ITEM_ICON = "MenuItemIcon",
582
+ MenuItemIcon = _Icon.styleable((props, forwardedRef) => /* @__PURE__ */(0, import_jsx_runtime.jsx)(_Icon, {
583
+ ...props,
584
+ ref: forwardedRef
585
+ }));
586
+ MenuItemIcon.displayName = ITEM_ICON;
587
+ const CHECKBOX_ITEM_NAME = "MenuCheckboxItem",
588
+ MenuCheckboxItem = import_stacks.ThemeableStack.styleable((props, forwardedRef) => {
589
+ const {
590
+ checked = !1,
591
+ onCheckedChange,
592
+ ...checkboxItemProps
593
+ } = props;
594
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(ItemIndicatorProvider, {
595
+ scope: props.scope,
596
+ checked,
597
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuItem, {
598
+ componentName: CHECKBOX_ITEM_NAME,
599
+ role: import_web.isWeb ? "menuitemcheckbox" : "menuitem",
600
+ "aria-checked": isIndeterminate(checked) ? "mixed" : checked,
601
+ ...checkboxItemProps,
602
+ ref: forwardedRef,
603
+ "data-state": getCheckedState(checked),
604
+ onSelect: (0, import_core.composeEventHandlers)(checkboxItemProps.onSelect, () => onCheckedChange?.(isIndeterminate(checked) ? !0 : !checked), {
605
+ checkDefaultPrevented: !1
606
+ })
607
+ })
608
+ });
609
+ });
610
+ MenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
611
+ const RADIO_GROUP_NAME = "MenuRadioGroup",
612
+ {
613
+ Provider: RadioGroupProvider,
614
+ useStyledContext: useRadioGroupContext
615
+ } = (0, import_core.createStyledContext)(),
616
+ MenuRadioGroup = _MenuGroup.styleable((props, forwardedRef) => {
617
+ const {
618
+ value,
619
+ onValueChange,
620
+ scope,
621
+ ...groupProps
622
+ } = props,
623
+ handleValueChange = (0, import_use_callback_ref.useCallbackRef)(onValueChange);
624
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(RadioGroupProvider, {
625
+ scope,
626
+ value,
627
+ onValueChange: handleValueChange,
628
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(_MenuGroup, {
629
+ componentName: RADIO_GROUP_NAME,
630
+ ...groupProps,
631
+ ref: forwardedRef
632
+ })
633
+ });
634
+ });
635
+ MenuRadioGroup.displayName = RADIO_GROUP_NAME;
636
+ const RADIO_ITEM_NAME = "MenuRadioItem",
637
+ MenuRadioItem = import_stacks.ThemeableStack.styleable((props, forwardedRef) => {
638
+ const {
639
+ value,
640
+ ...radioItemProps
641
+ } = props,
642
+ context = useRadioGroupContext(props.scope),
643
+ checked = value === context.value;
644
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(ItemIndicatorProvider, {
645
+ scope: props.scope,
646
+ checked,
647
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuItem, {
648
+ componentName: RADIO_ITEM_NAME,
649
+ ...radioItemProps,
650
+ "aria-checked": checked,
651
+ ref: forwardedRef,
652
+ role: import_web.isWeb ? "menuitemradio" : "menuitem",
653
+ "data-state": getCheckedState(checked),
654
+ onSelect: (0, import_core.composeEventHandlers)(radioItemProps.onSelect, () => context.onValueChange?.(value), {
655
+ checkDefaultPrevented: !1
656
+ })
657
+ })
658
+ });
659
+ });
660
+ MenuRadioItem.displayName = RADIO_ITEM_NAME;
661
+ const ITEM_INDICATOR_NAME = "MenuItemIndicator",
662
+ {
663
+ Provider: ItemIndicatorProvider,
664
+ useStyledContext: useItemIndicatorContext
665
+ } = (0, import_core.createStyledContext)(),
666
+ MenuItemIndicator = _Indicator.styleable((props, forwardedRef) => {
667
+ const {
668
+ scope,
669
+ forceMount,
670
+ ...itemIndicatorProps
671
+ } = props,
672
+ indicatorContext = useItemIndicatorContext(scope);
673
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_animate_presence.AnimatePresence, {
674
+ children: forceMount || isIndeterminate(indicatorContext.checked) || indicatorContext.checked === !0 ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(_Indicator, {
675
+ componentName: ITEM_INDICATOR_NAME,
676
+ tag: "span",
677
+ ...itemIndicatorProps,
678
+ ref: forwardedRef,
679
+ "data-state": getCheckedState(indicatorContext.checked)
680
+ }) : null
681
+ });
682
+ });
683
+ MenuItemIndicator.displayName = ITEM_INDICATOR_NAME;
684
+ const MenuArrow = React.forwardRef(function (props, forwardedRef) {
685
+ const {
686
+ scope,
687
+ unstyled = process.env.TAMAGUI_HEADLESS === "1",
688
+ ...rest
689
+ } = props;
690
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(PopperPrimitive.PopperArrow, {
691
+ scope: scope || MENU_CONTEXT,
692
+ componentName: "PopperArrow",
693
+ ...(!unstyled && {
694
+ backgroundColor: "$background"
695
+ }),
696
+ ...rest,
697
+ ref: forwardedRef
698
+ });
699
+ }),
700
+ SUB_NAME = "MenuSub",
701
+ {
702
+ Provider: MenuSubProvider,
703
+ useStyledContext: useMenuSubContext
704
+ } = (0, import_core.createStyledContext)(),
705
+ MenuSub = props => {
706
+ const {
707
+ scope,
708
+ children,
709
+ open = !1,
710
+ onOpenChange,
711
+ ...rest
712
+ } = props,
713
+ parentMenuContext = useMenuContext(scope),
714
+ [trigger, setTrigger] = React.useState(null),
715
+ [content, setContent] = React.useState(null),
716
+ handleOpenChange = (0, import_use_callback_ref.useCallbackRef)(onOpenChange);
717
+ return React.useEffect(() => (parentMenuContext.open === !1 && handleOpenChange(!1), () => handleOpenChange(!1)), [parentMenuContext.open, handleOpenChange]), /* @__PURE__ */(0, import_jsx_runtime.jsx)(PopperPrimitive.Popper, {
718
+ ...rest,
719
+ scope: scope || MENU_CONTEXT,
720
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuProvider, {
721
+ scope,
722
+ open,
723
+ onOpenChange: handleOpenChange,
724
+ content,
725
+ onContentChange: setContent,
726
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuSubProvider, {
727
+ scope,
728
+ contentId: (0, import_react.useId)(),
729
+ triggerId: (0, import_react.useId)(),
730
+ trigger,
731
+ onTriggerChange: setTrigger,
732
+ children
733
+ })
734
+ })
735
+ });
736
+ };
737
+ MenuSub.displayName = SUB_NAME;
738
+ const SUB_TRIGGER_NAME = "MenuSubTrigger",
739
+ MenuSubTrigger = import_stacks.YStack.styleable((props, forwardedRef) => {
740
+ const context = useMenuContext(props.scope),
741
+ rootContext = useMenuRootContext(props.scope),
742
+ subContext = useMenuSubContext(props.scope),
743
+ contentContext = useMenuContentContext(props.scope),
744
+ openTimerRef = React.useRef(null),
745
+ {
746
+ pointerGraceTimerRef,
747
+ onPointerGraceIntentChange
748
+ } = contentContext,
749
+ clearOpenTimer = React.useCallback(() => {
750
+ openTimerRef.current && window.clearTimeout(openTimerRef.current), openTimerRef.current = null;
751
+ }, []);
752
+ return React.useEffect(() => clearOpenTimer, [clearOpenTimer]), React.useEffect(() => {
753
+ const pointerGraceTimer = pointerGraceTimerRef.current;
754
+ return () => {
755
+ window.clearTimeout(pointerGraceTimer), onPointerGraceIntentChange(null);
756
+ };
757
+ }, [pointerGraceTimerRef, onPointerGraceIntentChange]), /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuAnchor, {
758
+ componentName: SUB_TRIGGER_NAME,
759
+ asChild: !0,
760
+ scope: props.scope || MENU_CONTEXT,
761
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuItemImpl, {
762
+ id: subContext.triggerId,
763
+ "aria-haspopup": "menu",
764
+ "aria-expanded": context.open,
765
+ "aria-controls": subContext.contentId,
766
+ "data-state": getOpenState(context.open),
767
+ outlineStyle: "none",
768
+ ...props,
769
+ ref: (0, import_core.composeRefs)(forwardedRef, subContext.onTriggerChange),
770
+ onPress: event => {
771
+ props.onPress?.(event), !(props.disabled || event.defaultPrevented) && (import_web.isWeb && event.currentTarget.focus(), context.open || context.onOpenChange(!0));
772
+ },
773
+ onPointerMove: (0, import_core.composeEventHandlers)(props.onPointerMove,
774
+ // @ts-ignore
775
+ whenMouse(event => {
776
+ contentContext.onItemEnter(event), !event.defaultPrevented && !props.disabled && !context.open && !openTimerRef.current && (contentContext.onPointerGraceIntentChange(null), openTimerRef.current = window.setTimeout(() => {
777
+ context.onOpenChange(!0), clearOpenTimer();
778
+ }, 100));
779
+ })),
780
+ onPointerLeave: (0, import_core.composeEventHandlers)(props.onPointerLeave,
781
+ // @ts-ignore
782
+ whenMouse(event => {
783
+ clearOpenTimer();
784
+ const contentRect = context.content?.getBoundingClientRect();
785
+ if (contentRect) {
786
+ const side = context.content?.dataset.side,
787
+ rightSide = side === "right",
788
+ bleed = rightSide ? -5 : 5,
789
+ contentNearEdge = contentRect[rightSide ? "left" : "right"],
790
+ contentFarEdge = contentRect[rightSide ? "right" : "left"];
791
+ contentContext.onPointerGraceIntentChange({
792
+ area: [
793
+ // Apply a bleed on clientX to ensure that our exit point is
794
+ // consistently within polygon bounds
795
+ {
796
+ x: event.clientX + bleed,
797
+ y: event.clientY
798
+ }, {
799
+ x: contentNearEdge,
800
+ y: contentRect.top
801
+ }, {
802
+ x: contentFarEdge,
803
+ y: contentRect.top
804
+ }, {
805
+ x: contentFarEdge,
806
+ y: contentRect.bottom
807
+ }, {
808
+ x: contentNearEdge,
809
+ y: contentRect.bottom
810
+ }],
811
+ side
812
+ }), window.clearTimeout(pointerGraceTimerRef.current), pointerGraceTimerRef.current = window.setTimeout(() => contentContext.onPointerGraceIntentChange(null), 300);
813
+ } else {
814
+ if (contentContext.onTriggerLeave(event), event.defaultPrevented) return;
815
+ contentContext.onPointerGraceIntentChange(null);
816
+ }
817
+ })),
818
+ ...(import_web.isWeb ? {
819
+ onKeyDown: (0, import_core.composeEventHandlers)(
820
+ // @ts-ignore
821
+ props.onKeyDown, event => {
822
+ const isTypingAhead = contentContext.searchRef.current !== "";
823
+ props.disabled || isTypingAhead && event.key === " " || SUB_OPEN_KEYS[rootContext.dir].includes(event.key) && (context.onOpenChange(!0), context.content?.focus(), event.preventDefault());
824
+ })
825
+ } : null)
826
+ })
827
+ });
828
+ });
829
+ MenuSubTrigger.displayName = SUB_TRIGGER_NAME;
830
+ const SUB_CONTENT_NAME = "MenuSubContent",
831
+ MenuSubContent = React.forwardRef((props, forwardedRef) => {
832
+ const portalContext = usePortalContext(props.scope),
833
+ {
834
+ forceMount = portalContext.forceMount,
835
+ ...subContentProps
836
+ } = props,
837
+ context = useMenuContext(props.scope),
838
+ rootContext = useMenuRootContext(props.scope),
839
+ subContext = useMenuSubContext(props.scope),
840
+ ref = React.useRef(null),
841
+ composedRefs = (0, import_core.useComposedRefs)(forwardedRef, ref);
842
+ return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Collection.Provider, {
843
+ scope: props.scope || MENU_CONTEXT,
844
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(Collection.Slot, {
845
+ scope: props.scope || MENU_CONTEXT,
846
+ children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuContentImpl, {
847
+ id: subContext.contentId,
848
+ "aria-labelledby": subContext.triggerId,
849
+ ...subContentProps,
850
+ ref: composedRefs,
851
+ "data-side": rootContext.dir === "rtl" ? "left" : "right",
852
+ disableOutsidePointerEvents: !1,
853
+ disableOutsideScroll: !1,
854
+ trapFocus: !1,
855
+ onOpenAutoFocus: event => {
856
+ rootContext.isUsingKeyboardRef.current && ref.current?.focus(), event.preventDefault();
857
+ },
858
+ onCloseAutoFocus: event => event.preventDefault(),
859
+ onFocusOutside: (0, import_core.composeEventHandlers)(props.onFocusOutside, event => {
860
+ event.target !== subContext.trigger && context.onOpenChange(!1);
861
+ }),
862
+ onEscapeKeyDown: (0, import_core.composeEventHandlers)(props.onEscapeKeyDown, event => {
863
+ rootContext.onClose(), event.preventDefault();
864
+ }),
865
+ ...(import_web.isWeb ? {
866
+ // @ts-ignore
867
+ onKeyDown: (0, import_core.composeEventHandlers)(
868
+ // @ts-ignore
869
+ props.onKeyDown, event => {
870
+ const isKeyDownInside = event.currentTarget.contains(event.target),
871
+ isCloseKey = SUB_CLOSE_KEYS[rootContext.dir].includes(event.key);
872
+ isKeyDownInside && isCloseKey && (context.onOpenChange(!1), subContext.trigger?.focus(), event.preventDefault());
873
+ })
874
+ } : null)
875
+ })
876
+ })
877
+ });
878
+ });
879
+ return MenuSubContent.displayName = SUB_CONTENT_NAME, {
880
+ Menu: (0, import_web.withStaticProperties)(MenuComp, {
881
+ Anchor: MenuAnchor,
882
+ Portal: MenuPortal,
883
+ Content: MenuContent,
884
+ Group: _MenuGroup,
885
+ Label: _Label,
886
+ Item: MenuItem,
887
+ CheckboxItem: MenuCheckboxItem,
888
+ RadioGroup: MenuRadioGroup,
889
+ RadioItem: MenuRadioItem,
890
+ ItemIndicator: MenuItemIndicator,
891
+ Separator: _Separator,
892
+ Arrow: MenuArrow,
893
+ Sub: MenuSub,
894
+ SubTrigger: MenuSubTrigger,
895
+ SubContent: MenuSubContent,
896
+ ItemTitle: MenuItemTitle,
897
+ ItemSubtitle: MenuItemSubTitle,
898
+ ItemImage: MenuItemImage,
899
+ ItemIcon: MenuItemIcon
900
+ })
901
+ };
902
+ }
903
+ function getOpenState(open) {
904
+ return open ? "open" : "closed";
905
+ }
906
+ function isIndeterminate(checked) {
907
+ return checked === "indeterminate";
908
+ }
909
+ function getCheckedState(checked) {
910
+ return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
911
+ }
912
+ function focusFirst(candidates) {
913
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
914
+ for (const candidate of candidates) if (candidate === PREVIOUSLY_FOCUSED_ELEMENT || (candidate.focus(), document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT)) return;
915
+ }
916
+ function wrapArray(array, startIndex) {
917
+ return array.map((_, index) => array[(startIndex + index) % array.length]);
918
+ }
919
+ function getNextMatch(values, search, currentMatch) {
920
+ const normalizedSearch = search.length > 1 && Array.from(search).every(char => char === search[0]) ? search[0] : search,
921
+ currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
922
+ let wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0));
923
+ normalizedSearch.length === 1 && (wrappedValues = wrappedValues.filter(v => v !== currentMatch));
924
+ const nextMatch = wrappedValues.find(value => value.toLowerCase().startsWith(normalizedSearch.toLowerCase()));
925
+ return nextMatch !== currentMatch ? nextMatch : void 0;
926
+ }
927
+ function isPointInPolygon(point, polygon) {
928
+ const {
929
+ x,
930
+ y
931
+ } = point;
932
+ let inside = !1;
933
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
934
+ const xi = polygon[i].x,
935
+ yi = polygon[i].y,
936
+ xj = polygon[j].x,
937
+ yj = polygon[j].y;
938
+ yi > y != yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi && (inside = !inside);
939
+ }
940
+ return inside;
941
+ }
942
+ function isPointerInGraceArea(event, area) {
943
+ if (!area) return !1;
944
+ const cursorPos = {
945
+ x: event.clientX,
946
+ y: event.clientY
947
+ };
948
+ return isPointInPolygon(cursorPos, area);
949
+ }
950
+ function whenMouse(handler) {
951
+ return event => event.pointerType === "mouse" ? handler(event) : void 0;
952
+ }