@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,1097 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Animate } from "@tamagui/animate";
3
+ import { AnimatePresence as Presence } from "@tamagui/animate-presence";
4
+ import { createCollection } from "@tamagui/collection";
5
+ import { Text, composeEventHandlers, composeRefs, createStyledContext, useComposedRefs } from "@tamagui/core";
6
+ import { Dismissable as DismissableLayer, dispatchDiscreteCustomEvent } from "@tamagui/dismissable";
7
+ import { useFocusGuards } from "@tamagui/focus-guard";
8
+ import { FocusScope } from "@tamagui/focus-scope";
9
+ import * as PopperPrimitive from "@tamagui/popper";
10
+ import { Portal as PortalPrimitive } from "@tamagui/portal";
11
+ import { RemoveScroll } from "@tamagui/remove-scroll";
12
+ import { RovingFocusGroup } from "@tamagui/roving-focus";
13
+ import { ThemeableStack, YStack } from "@tamagui/stacks";
14
+ import { useCallbackRef } from "@tamagui/use-callback-ref";
15
+ import { useDirection } from "@tamagui/use-direction";
16
+ import { isAndroid, isWeb, withStaticProperties } from "@tamagui/web";
17
+ import * as React from "react";
18
+ import { useId } from "react";
19
+ import { MenuPredefinied } from "./Menu.native.js";
20
+ var SELECTION_KEYS = ["Enter", " "],
21
+ FIRST_KEYS = ["ArrowDown", "PageUp", "Home"],
22
+ LAST_KEYS = ["ArrowUp", "PageDown", "End"],
23
+ FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS],
24
+ SUB_OPEN_KEYS = {
25
+ ltr: [...SELECTION_KEYS, "ArrowRight"],
26
+ rtl: [...SELECTION_KEYS, "ArrowLeft"]
27
+ },
28
+ SUB_CLOSE_KEYS = {
29
+ ltr: ["ArrowLeft"],
30
+ rtl: ["ArrowRight"]
31
+ },
32
+ MENU_NAME = "Menu",
33
+ [Collection, useCollection] = createCollection(MENU_NAME),
34
+ {
35
+ Provider: MenuProvider,
36
+ useStyledContext: useMenuContext
37
+ } = createStyledContext(),
38
+ {
39
+ Provider: MenuRootProvider,
40
+ useStyledContext: useMenuRootContext
41
+ } = createStyledContext(),
42
+ MENU_CONTEXT = "MenuContext",
43
+ {
44
+ Provider: NativePropProvider,
45
+ useStyledContext: useNativeProp
46
+ } = createStyledContext({
47
+ native: !1
48
+ });
49
+ function createMenu(param) {
50
+ var {
51
+ Item: _Item = MenuPredefinied.MenuItem,
52
+ Title: _Title = MenuPredefinied.Title,
53
+ SubTitle: _SubTitle = MenuPredefinied.SubTitle,
54
+ Image: _Image = MenuPredefinied.MenuImage,
55
+ Icon: _Icon = MenuPredefinied.MenuIcon,
56
+ Indicator: _Indicator = MenuPredefinied.MenuIndicator,
57
+ Separator: _Separator = MenuPredefinied.MenuSeparator,
58
+ MenuGroup: _MenuGroup = MenuPredefinied.MenuGroup,
59
+ Label: _Label = MenuPredefinied.MenuLabel
60
+ } = param,
61
+ MenuComp = function (props) {
62
+ var {
63
+ scope,
64
+ open = !1,
65
+ children,
66
+ dir,
67
+ onOpenChange,
68
+ modal = !0,
69
+ ...rest
70
+ } = props,
71
+ [content, setContent] = React.useState(null),
72
+ isUsingKeyboardRef = React.useRef(!1),
73
+ handleOpenChange = useCallbackRef(onOpenChange),
74
+ direction = useDirection(dir);
75
+ return isWeb && React.useEffect(function () {
76
+ var handleKeyDown = function () {
77
+ isUsingKeyboardRef.current = !0, document.addEventListener("pointerdown", handlePointer, {
78
+ capture: !0,
79
+ once: !0
80
+ }), document.addEventListener("pointermove", handlePointer, {
81
+ capture: !0,
82
+ once: !0
83
+ });
84
+ },
85
+ handlePointer = function () {
86
+ return isUsingKeyboardRef.current = !1;
87
+ };
88
+ return document.addEventListener("keydown", handleKeyDown, {
89
+ capture: !0
90
+ }), function () {
91
+ document.removeEventListener("keydown", handleKeyDown, {
92
+ capture: !0
93
+ }), document.removeEventListener("pointerdown", handlePointer, {
94
+ capture: !0
95
+ }), document.removeEventListener("pointermove", handlePointer, {
96
+ capture: !0
97
+ });
98
+ };
99
+ }, []), /* @__PURE__ */_jsx(PopperPrimitive.Popper, {
100
+ scope: scope || MENU_CONTEXT,
101
+ ...rest,
102
+ children: /* @__PURE__ */_jsx(MenuProvider, {
103
+ scope,
104
+ open,
105
+ onOpenChange: handleOpenChange,
106
+ content,
107
+ onContentChange: setContent,
108
+ children: /* @__PURE__ */_jsx(NativePropProvider, {
109
+ native: !1,
110
+ scope,
111
+ children: /* @__PURE__ */_jsx(MenuRootProvider, {
112
+ scope,
113
+ onClose: React.useCallback(function () {
114
+ return handleOpenChange(!1);
115
+ }, [handleOpenChange]),
116
+ isUsingKeyboardRef,
117
+ dir: direction,
118
+ modal,
119
+ children: (/** this provider is just to avoid crashing when using useSubMenuContext() inside MenuPortal */
120
+ /* @__PURE__ */_jsx(MenuSubProvider, {
121
+ scope,
122
+ children
123
+ }))
124
+ })
125
+ })
126
+ })
127
+ });
128
+ },
129
+ RepropagateMenuAndMenuRootProvider = function (props) {
130
+ var {
131
+ scope,
132
+ menuContext,
133
+ rootContext,
134
+ popperContext,
135
+ menuSubContext,
136
+ children
137
+ } = props;
138
+ return /* @__PURE__ */_jsx(PopperPrimitive.PopperProvider, {
139
+ ...popperContext,
140
+ scope: scope || MENU_CONTEXT,
141
+ children: /* @__PURE__ */_jsx(NativePropProvider, {
142
+ native: !1,
143
+ scope,
144
+ children: /* @__PURE__ */_jsx(MenuProvider, {
145
+ scope,
146
+ ...menuContext,
147
+ children: /* @__PURE__ */_jsx(MenuRootProvider, {
148
+ scope,
149
+ ...rootContext,
150
+ children: menuSubContext ? /* @__PURE__ */_jsx(MenuSubProvider, {
151
+ scope,
152
+ ...menuSubContext,
153
+ children
154
+ }) : children
155
+ })
156
+ })
157
+ })
158
+ });
159
+ };
160
+ MenuComp.displayName = MENU_NAME;
161
+ var ANCHOR_NAME = "MenuAnchor",
162
+ MenuAnchor = function (props) {
163
+ return /* @__PURE__ */_jsx(PopperPrimitive.PopperAnchor, {
164
+ scope: MENU_CONTEXT,
165
+ ...props
166
+ });
167
+ };
168
+ MenuAnchor.displayName = ANCHOR_NAME;
169
+ var PORTAL_NAME = "MenuPortal",
170
+ {
171
+ Provider: PortalProvider,
172
+ useStyledContext: usePortalContext
173
+ } = createStyledContext(void 0, "Portal"),
174
+ MenuPortal = function (props) {
175
+ var {
176
+ scope,
177
+ forceMount,
178
+ zIndex,
179
+ children
180
+ } =
181
+ // TODO removed
182
+ // host
183
+ props,
184
+ menuContext = useMenuContext(scope),
185
+ rootContext = useMenuRootContext(scope),
186
+ popperContext = PopperPrimitive.usePopperContext(scope || MENU_CONTEXT),
187
+ menuSubContext = useMenuSubContext(scope),
188
+ content = isAndroid ? /* @__PURE__ */_jsx(RepropagateMenuAndMenuRootProvider, {
189
+ menuContext,
190
+ rootContext,
191
+ popperContext,
192
+ menuSubContext,
193
+ scope,
194
+ children
195
+ }) : children;
196
+ return /* @__PURE__ */_jsx(Animate, {
197
+ type: "presence",
198
+ present: forceMount || menuContext.open,
199
+ children: (/* @ts-expect-error TODO */
200
+ /* @__PURE__ */_jsx(PortalPrimitive, {
201
+ host,
202
+ children: /* @__PURE__ */_jsx(_Fragment, {
203
+ children: /* @__PURE__ */_jsx(PortalProvider, {
204
+ scope,
205
+ forceMount,
206
+ children: /* @__PURE__ */_jsxs(YStack, {
207
+ zIndex: zIndex || 100,
208
+ fullscreen: !0,
209
+ children: [!!menuContext.open && !isWeb && /* @__PURE__ */_jsx(YStack, {
210
+ fullscreen: !0,
211
+ onPress: function () {
212
+ return menuContext.onOpenChange(!menuContext.open);
213
+ }
214
+ }), content]
215
+ })
216
+ })
217
+ })
218
+ }))
219
+ });
220
+ };
221
+ MenuPortal.displayName = PORTAL_NAME;
222
+ var CONTENT_NAME = "MenuContent",
223
+ {
224
+ Provider: MenuContentProvider,
225
+ useStyledContext: useMenuContentContext
226
+ } = createStyledContext(),
227
+ MenuContent = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
228
+ var portalContext = usePortalContext(props.scope),
229
+ {
230
+ forceMount = portalContext.forceMount,
231
+ ...contentProps
232
+ } = props,
233
+ rootContext = useMenuRootContext(props.scope);
234
+ return /* @__PURE__ */_jsx(Collection.Provider, {
235
+ scope: props.scope || MENU_CONTEXT,
236
+ children: /* @__PURE__ */_jsx(Collection.Slot, {
237
+ scope: props.scope || MENU_CONTEXT,
238
+ children: rootContext.modal ? /* @__PURE__ */_jsx(MenuRootContentModal, {
239
+ ...contentProps,
240
+ ref: forwardedRef
241
+ }) : /* @__PURE__ */_jsx(MenuRootContentNonModal, {
242
+ ...contentProps,
243
+ ref: forwardedRef
244
+ })
245
+ })
246
+ });
247
+ }),
248
+ MenuRootContentModal = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
249
+ var context = useMenuContext(props.scope),
250
+ ref = React.useRef(null),
251
+ composedRefs = useComposedRefs(forwardedRef, ref);
252
+ return /* @__PURE__ */_jsx(MenuContentImpl, {
253
+ ...props,
254
+ ref: composedRefs,
255
+ // we make sure we're not trapping once it's been closed
256
+ // (closed !== unmounted when animating out)
257
+ trapFocus: context.open,
258
+ // make sure to only disable pointer events when open
259
+ // this avoids blocking interactions while animating out
260
+ disableOutsidePointerEvents: context.open,
261
+ disableOutsideScroll: !0,
262
+ // When focus is trapped, a `focusout` event may still happen.
263
+ // We make sure we don't trigger our `onDismiss` in such case.
264
+ onFocusOutside: composeEventHandlers(props.onFocusOutside, function (event) {
265
+ return event.preventDefault();
266
+ }, {
267
+ checkDefaultPrevented: !1
268
+ }),
269
+ onDismiss: function () {
270
+ return context.onOpenChange(!1);
271
+ }
272
+ });
273
+ }),
274
+ MenuRootContentNonModal = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
275
+ var context = useMenuContext(props.scope);
276
+ return /* @__PURE__ */_jsx(MenuContentImpl, {
277
+ ...props,
278
+ ref: forwardedRef,
279
+ trapFocus: !1,
280
+ disableOutsidePointerEvents: !1,
281
+ disableOutsideScroll: !1,
282
+ onDismiss: function () {
283
+ return context.onOpenChange(!1);
284
+ }
285
+ });
286
+ }),
287
+ Fragment = /* @__PURE__ */React.forwardRef(function (props, ref) {
288
+ return props.children;
289
+ }),
290
+ MenuContentImpl = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
291
+ var {
292
+ scope = MENU_CONTEXT,
293
+ loop = !1,
294
+ trapFocus,
295
+ onOpenAutoFocus,
296
+ onCloseAutoFocus,
297
+ disableOutsidePointerEvents,
298
+ onEntryFocus,
299
+ onEscapeKeyDown,
300
+ onPointerDownOutside,
301
+ onFocusOutside,
302
+ onInteractOutside,
303
+ onDismiss,
304
+ disableOutsideScroll,
305
+ unstyled = process.env.TAMAGUI_HEADLESS === "1",
306
+ ...contentProps
307
+ } = props,
308
+ context = useMenuContext(scope),
309
+ rootContext = useMenuRootContext(scope),
310
+ getItems = useCollection(scope),
311
+ [currentItemId, setCurrentItemId] = React.useState(null),
312
+ contentRef = React.useRef(null),
313
+ composedRefs = useComposedRefs(forwardedRef, contentRef, context.onContentChange),
314
+ timerRef = React.useRef(0),
315
+ searchRef = React.useRef(""),
316
+ pointerGraceTimerRef = React.useRef(0),
317
+ pointerGraceIntentRef = React.useRef(null),
318
+ pointerDirRef = React.useRef("right"),
319
+ lastPointerXRef = React.useRef(0),
320
+ handleTypeaheadSearch = function (key) {
321
+ var _items_find,
322
+ _items_find1,
323
+ search = searchRef.current + key,
324
+ items = getItems().filter(function (item) {
325
+ return !item.disabled;
326
+ }),
327
+ currentItem = document.activeElement,
328
+ currentMatch = (_items_find = items.find(function (item) {
329
+ return item.ref.current === currentItem;
330
+ })) === null || _items_find === void 0 ? void 0 : _items_find.textValue,
331
+ values = items.map(function (item) {
332
+ return item.textValue;
333
+ }),
334
+ nextMatch = getNextMatch(values, search, currentMatch),
335
+ newItem = (_items_find1 = items.find(function (item) {
336
+ return item.textValue === nextMatch;
337
+ })) === null || _items_find1 === void 0 ? void 0 : _items_find1.ref.current;
338
+ (function updateSearch(value) {
339
+ searchRef.current = value, clearTimeout(timerRef.current), value !== "" && (timerRef.current = setTimeout(function () {
340
+ return updateSearch("");
341
+ }, 1e3));
342
+ })(search), newItem && setTimeout(function () {
343
+ return newItem.focus();
344
+ });
345
+ };
346
+ React.useEffect(function () {
347
+ return function () {
348
+ return clearTimeout(timerRef.current);
349
+ };
350
+ }, []), isWeb && useFocusGuards();
351
+ var isPointerMovingToSubmenu = React.useCallback(function (event) {
352
+ var _pointerGraceIntentRef_current,
353
+ _pointerGraceIntentRef_current1,
354
+ isMovingTowards = pointerDirRef.current === ((_pointerGraceIntentRef_current = pointerGraceIntentRef.current) === null || _pointerGraceIntentRef_current === void 0 ? void 0 : _pointerGraceIntentRef_current.side);
355
+ return isMovingTowards && isPointerInGraceArea(event, (_pointerGraceIntentRef_current1 = pointerGraceIntentRef.current) === null || _pointerGraceIntentRef_current1 === void 0 ? void 0 : _pointerGraceIntentRef_current1.area);
356
+ }, []),
357
+ content = /* @__PURE__ */_jsx(PopperPrimitive.PopperContent, {
358
+ role: "menu",
359
+ ...(!unstyled && {
360
+ elevation: 30,
361
+ paddingVertical: "$2",
362
+ backgroundColor: "$background",
363
+ borderColor: "$borderColor",
364
+ outlineWidth: 0
365
+ }),
366
+ "aria-orientation": "vertical",
367
+ "data-state": getOpenState(context.open),
368
+ "data-tamagui-menu-content": "",
369
+ // @ts-ignore
370
+ dir: rootContext.dir,
371
+ scope: scope || MENU_CONTEXT,
372
+ ...contentProps,
373
+ ref: composedRefs,
374
+ className: contentProps.animation ? void 0 : contentProps.className,
375
+ ...(isWeb ? {
376
+ onKeyDown: composeEventHandlers(
377
+ //@ts-ignore
378
+ contentProps.onKeyDown, function (event) {
379
+ var target = event.target,
380
+ isKeyDownInside = target.closest("[data-tamagui-menu-content]") === event.currentTarget,
381
+ isModifierKey = event.ctrlKey || event.altKey || event.metaKey,
382
+ isCharacterKey = event.key.length === 1;
383
+ isKeyDownInside && (event.key === "Tab" && event.preventDefault(), !isModifierKey && isCharacterKey && handleTypeaheadSearch(event.key));
384
+ var content2 = contentRef.current;
385
+ if (event.target === content2 && FIRST_LAST_KEYS.includes(event.key)) {
386
+ event.preventDefault();
387
+ var items = getItems().filter(function (item) {
388
+ return !item.disabled;
389
+ }),
390
+ candidateNodes = items.map(function (item) {
391
+ return item.ref.current;
392
+ });
393
+ LAST_KEYS.includes(event.key) && candidateNodes.reverse(), focusFirst(candidateNodes);
394
+ }
395
+ }),
396
+ // @ts-ignore
397
+ onBlur: composeEventHandlers(props.onBlur, function (event) {
398
+ var _event_currentTarget;
399
+ !((_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0) && _event_currentTarget.contains(event.target) || (clearTimeout(timerRef.current), searchRef.current = "");
400
+ }),
401
+ onPointerMove: composeEventHandlers(
402
+ // @ts-ignore
403
+ props.onPointerMove,
404
+ // @ts-ignore
405
+ whenMouse(function (event) {
406
+ var _event_currentTarget,
407
+ target = event.target,
408
+ pointerXHasChanged = lastPointerXRef.current !== event.clientX;
409
+ if (!((_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0) && _event_currentTarget.contains(target) && pointerXHasChanged) {
410
+ var newDir = event.clientX > lastPointerXRef.current ? "right" : "left";
411
+ pointerDirRef.current = newDir, lastPointerXRef.current = event.clientX;
412
+ }
413
+ }))
414
+ } : {})
415
+ });
416
+ return /* @__PURE__ */_jsx(MenuContentProvider, {
417
+ scope,
418
+ searchRef,
419
+ onItemEnter: React.useCallback(function (event) {
420
+ isPointerMovingToSubmenu(event) && event.preventDefault();
421
+ }, [isPointerMovingToSubmenu]),
422
+ onItemLeave: React.useCallback(function (event) {
423
+ var _contentRef_current;
424
+ isPointerMovingToSubmenu(event) || ((_contentRef_current = contentRef.current) === null || _contentRef_current === void 0 || _contentRef_current.focus(), setCurrentItemId(null));
425
+ }, [isPointerMovingToSubmenu]),
426
+ onTriggerLeave: React.useCallback(function (event) {
427
+ isPointerMovingToSubmenu(event) && event.preventDefault();
428
+ }, [isPointerMovingToSubmenu]),
429
+ pointerGraceTimerRef,
430
+ onPointerGraceIntentChange: React.useCallback(function (intent) {
431
+ pointerGraceIntentRef.current = intent;
432
+ }, []),
433
+ children: /* @__PURE__ */_jsx(RemoveScroll, {
434
+ enabled: disableOutsideScroll,
435
+ children: /* @__PURE__ */_jsx(FocusScope, {
436
+ asChild: !1,
437
+ trapped: trapFocus,
438
+ onMountAutoFocus: composeEventHandlers(onOpenAutoFocus, function (event) {
439
+ var _contentRef_current;
440
+ event.preventDefault(), (_contentRef_current = contentRef.current) === null || _contentRef_current === void 0 || _contentRef_current.focus();
441
+ }),
442
+ onUnmountAutoFocus: onCloseAutoFocus,
443
+ children: /* @__PURE__ */_jsx(DismissableLayer, {
444
+ disableOutsidePointerEvents,
445
+ onEscapeKeyDown,
446
+ onPointerDownOutside,
447
+ onFocusOutside,
448
+ onInteractOutside,
449
+ onDismiss,
450
+ asChild: !0,
451
+ children: /* @__PURE__ */_jsx(RovingFocusGroup, {
452
+ asChild: !0,
453
+ __scopeRovingFocusGroup: scope || MENU_CONTEXT,
454
+ dir: rootContext.dir,
455
+ orientation: "vertical",
456
+ loop,
457
+ currentTabStopId: currentItemId,
458
+ onCurrentTabStopIdChange: setCurrentItemId,
459
+ onEntryFocus: composeEventHandlers(onEntryFocus, function (event) {
460
+ rootContext.isUsingKeyboardRef.current || event.preventDefault();
461
+ }),
462
+ children: content
463
+ })
464
+ })
465
+ })
466
+ })
467
+ });
468
+ });
469
+ MenuContent.displayName = CONTENT_NAME;
470
+ var ITEM_NAME = "MenuItem",
471
+ ITEM_SELECT = "menu.itemSelect",
472
+ MenuItem = ThemeableStack.styleable(function (props, forwardedRef) {
473
+ var {
474
+ disabled = !1,
475
+ onSelect,
476
+ children,
477
+ ...itemProps
478
+ } = props,
479
+ ref = React.useRef(null),
480
+ rootContext = useMenuRootContext(props.scope),
481
+ contentContext = useMenuContentContext(props.scope),
482
+ composedRefs = useComposedRefs(forwardedRef, ref),
483
+ isPointerDownRef = React.useRef(!1),
484
+ handleSelect = function () {
485
+ var menuItem = ref.current;
486
+ if (!disabled && menuItem) if (isWeb) {
487
+ var itemSelectEvent = new CustomEvent(ITEM_SELECT, {
488
+ bubbles: !0,
489
+ cancelable: !0
490
+ });
491
+ menuItem.addEventListener(ITEM_SELECT, function (event) {
492
+ return onSelect?.(event);
493
+ }, {
494
+ once: !0
495
+ }), dispatchDiscreteCustomEvent(menuItem, itemSelectEvent), itemSelectEvent.defaultPrevented ? isPointerDownRef.current = !1 : rootContext.onClose();
496
+ } else onSelect?.({
497
+ target: menuItem
498
+ }), isPointerDownRef.current = !1, rootContext.onClose();
499
+ },
500
+ content = typeof children == "string" ? /* @__PURE__ */_jsx(Text, {
501
+ children
502
+ }) : children;
503
+ return /* @__PURE__ */_jsx(MenuItemImpl, {
504
+ outlineStyle: "none",
505
+ ...itemProps,
506
+ // @ts-ignore
507
+ ref: composedRefs,
508
+ disabled,
509
+ onPress: composeEventHandlers(props.onPress, handleSelect),
510
+ onPointerDown: function (event) {
511
+ var _props_onPointerDown;
512
+ (_props_onPointerDown = props.onPointerDown) === null || _props_onPointerDown === void 0 || _props_onPointerDown.call(props, event), isPointerDownRef.current = !0;
513
+ },
514
+ onPointerUp: composeEventHandlers(props.onPointerUp, function (event) {
515
+ if (isWeb) {
516
+ var _event_currentTarget;
517
+ isPointerDownRef.current || (_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 || _event_currentTarget.click();
518
+ }
519
+ }),
520
+ ...(isWeb ? {
521
+ onKeyDown: composeEventHandlers(
522
+ // @ts-ignore
523
+ props.onKeyDown, function (event) {
524
+ var isTypingAhead = contentContext.searchRef.current !== "";
525
+ if (!(disabled || isTypingAhead && event.key === " ") && SELECTION_KEYS.includes(event.key)) {
526
+ var _event_currentTarget;
527
+ (_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 || _event_currentTarget.click(), event.preventDefault();
528
+ }
529
+ })
530
+ } : {}),
531
+ children: content
532
+ });
533
+ }),
534
+ MenuItemImpl = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
535
+ var {
536
+ scope,
537
+ disabled = !1,
538
+ textValue,
539
+ unstyled = process.env.TAMAGUI_HEADLESS === "1",
540
+ ...itemProps
541
+ } = props,
542
+ contentContext = useMenuContentContext(scope),
543
+ ref = React.useRef(null),
544
+ composedRefs = useComposedRefs(forwardedRef, ref),
545
+ [isFocused, setIsFocused] = React.useState(!1),
546
+ [textContent, setTextContent] = React.useState("");
547
+ return isWeb && React.useEffect(function () {
548
+ var menuItem = ref.current;
549
+ if (menuItem) {
550
+ var _menuItem_textContent;
551
+ setTextContent(((_menuItem_textContent = menuItem.textContent) !== null && _menuItem_textContent !== void 0 ? _menuItem_textContent : "").trim());
552
+ }
553
+ }, [itemProps.children]), /* @__PURE__ */_jsx(Collection.ItemSlot, {
554
+ scope: scope || MENU_CONTEXT,
555
+ disabled,
556
+ textValue: textValue ?? textContent,
557
+ children: /* @__PURE__ */_jsx(RovingFocusGroup.Item, {
558
+ asChild: !0,
559
+ __scopeRovingFocusGroup: scope || MENU_CONTEXT,
560
+ focusable: !disabled,
561
+ ...(!unstyled && {
562
+ flexDirection: "row",
563
+ alignItems: "center"
564
+ }),
565
+ ...itemProps,
566
+ children: /* @__PURE__ */_jsx(_Item, {
567
+ ...(!unstyled && {
568
+ hoverTheme: !0,
569
+ pressTheme: !0,
570
+ focusTheme: !0,
571
+ paddingVertical: "$2",
572
+ paddingHorizontal: "$4",
573
+ width: "100%"
574
+ }),
575
+ componentName: ITEM_NAME,
576
+ role: "menuitem",
577
+ "data-highlighted": isFocused ? "" : void 0,
578
+ "aria-disabled": disabled || void 0,
579
+ "data-disabled": disabled ? "" : void 0,
580
+ ...itemProps,
581
+ ref: composedRefs,
582
+ /**
583
+ * We focus items on `pointerMove` to achieve the following:
584
+ *
585
+ * - Mouse over an item (it focuses)
586
+ * - Leave mouse where it is and use keyboard to focus a different item
587
+ * - Wiggle mouse without it leaving previously focused item
588
+ * - Previously focused item should re-focus
589
+ *
590
+ * If we used `mouseOver`/`mouseEnter` it would not re-focus when the mouse
591
+ * wiggles. This is to match native menu implementation.
592
+ */
593
+ onPointerMove: composeEventHandlers(props.onPointerMove,
594
+ // @ts-ignore
595
+ whenMouse(function (event) {
596
+ if (disabled) contentContext.onItemLeave(event);else if (contentContext.onItemEnter(event), !event.defaultPrevented) {
597
+ var item = event.currentTarget;
598
+ item.focus();
599
+ }
600
+ })),
601
+ onPointerLeave: composeEventHandlers(
602
+ // @ts-ignore
603
+ props.onPointerLeave,
604
+ // @ts-ignore
605
+ whenMouse(function (event) {
606
+ return contentContext.onItemLeave(event);
607
+ })),
608
+ onFocus: composeEventHandlers(props.onFocus, function () {
609
+ return setIsFocused(!0);
610
+ }),
611
+ onBlur: composeEventHandlers(props.onBlur, function () {
612
+ return setIsFocused(!1);
613
+ })
614
+ })
615
+ })
616
+ });
617
+ });
618
+ MenuItem.displayName = ITEM_NAME;
619
+ var ITEM_TITLE_NAME = "MenuItemTitle",
620
+ MenuItemTitle = _Title.styleable(function (props, forwardedRef) {
621
+ return /* @__PURE__ */_jsx(_Title, {
622
+ ...props,
623
+ ref: forwardedRef
624
+ });
625
+ });
626
+ MenuItemTitle.displayName = ITEM_TITLE_NAME;
627
+ var ITEM_SUB_TITLE_NAME = "MenuItemSubTitle",
628
+ MenuItemSubTitle = _SubTitle.styleable(function (props, forwardedRef) {
629
+ return /* @__PURE__ */_jsx(_SubTitle, {
630
+ ...props,
631
+ ref: forwardedRef
632
+ });
633
+ });
634
+ MenuItemSubTitle.displayName = ITEM_SUB_TITLE_NAME;
635
+ var ITEM_IMAGE = "MenuItemImage",
636
+ MenuItemImage = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
637
+ return /* @__PURE__ */_jsx(_Image, {
638
+ ...props,
639
+ ref: forwardedRef
640
+ });
641
+ });
642
+ MenuItemImage.displayName = ITEM_IMAGE;
643
+ var ITEM_ICON = "MenuItemIcon",
644
+ MenuItemIcon = _Icon.styleable(function (props, forwardedRef) {
645
+ return /* @__PURE__ */_jsx(_Icon, {
646
+ ...props,
647
+ ref: forwardedRef
648
+ });
649
+ });
650
+ MenuItemIcon.displayName = ITEM_ICON;
651
+ var CHECKBOX_ITEM_NAME = "MenuCheckboxItem",
652
+ MenuCheckboxItem = ThemeableStack.styleable(function (props, forwardedRef) {
653
+ var {
654
+ checked = !1,
655
+ onCheckedChange,
656
+ ...checkboxItemProps
657
+ } = props;
658
+ return /* @__PURE__ */_jsx(ItemIndicatorProvider, {
659
+ scope: props.scope,
660
+ checked,
661
+ children: (/* @ts-ignore */
662
+ /* @__PURE__ */_jsx(MenuItem, {
663
+ componentName: CHECKBOX_ITEM_NAME,
664
+ role: isWeb ? "menuitemcheckbox" : "menuitem",
665
+ "aria-checked": isIndeterminate(checked) ? "mixed" : checked,
666
+ ...checkboxItemProps,
667
+ ref: forwardedRef,
668
+ "data-state": getCheckedState(checked),
669
+ onSelect: composeEventHandlers(checkboxItemProps.onSelect, function () {
670
+ return onCheckedChange?.(isIndeterminate(checked) ? !0 : !checked);
671
+ }, {
672
+ checkDefaultPrevented: !1
673
+ })
674
+ }))
675
+ });
676
+ });
677
+ MenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
678
+ var RADIO_GROUP_NAME = "MenuRadioGroup",
679
+ {
680
+ Provider: RadioGroupProvider,
681
+ useStyledContext: useRadioGroupContext
682
+ } = createStyledContext(),
683
+ MenuRadioGroup = _MenuGroup.styleable(function (props, forwardedRef) {
684
+ var {
685
+ value,
686
+ onValueChange,
687
+ scope,
688
+ ...groupProps
689
+ } = props,
690
+ handleValueChange = useCallbackRef(onValueChange);
691
+ return /* @__PURE__ */_jsx(RadioGroupProvider, {
692
+ scope,
693
+ value,
694
+ onValueChange: handleValueChange,
695
+ children: /* @__PURE__ */_jsx(_MenuGroup, {
696
+ componentName: RADIO_GROUP_NAME,
697
+ ...groupProps,
698
+ ref: forwardedRef
699
+ })
700
+ });
701
+ });
702
+ MenuRadioGroup.displayName = RADIO_GROUP_NAME;
703
+ var RADIO_ITEM_NAME = "MenuRadioItem",
704
+ MenuRadioItem = ThemeableStack.styleable(function (props, forwardedRef) {
705
+ var {
706
+ value,
707
+ ...radioItemProps
708
+ } = props,
709
+ context = useRadioGroupContext(props.scope),
710
+ checked = value === context.value;
711
+ return /* @__PURE__ */_jsx(ItemIndicatorProvider, {
712
+ scope: props.scope,
713
+ checked,
714
+ children: (/* @ts-ignore */
715
+ /* @__PURE__ */_jsx(MenuItem, {
716
+ componentName: RADIO_ITEM_NAME,
717
+ ...radioItemProps,
718
+ "aria-checked": checked,
719
+ ref: forwardedRef,
720
+ role: isWeb ? "menuitemradio" : "menuitem",
721
+ "data-state": getCheckedState(checked),
722
+ onSelect: composeEventHandlers(radioItemProps.onSelect, function () {
723
+ var _context_onValueChange;
724
+ return (_context_onValueChange = context.onValueChange) === null || _context_onValueChange === void 0 ? void 0 : _context_onValueChange.call(context, value);
725
+ }, {
726
+ checkDefaultPrevented: !1
727
+ })
728
+ }))
729
+ });
730
+ });
731
+ MenuRadioItem.displayName = RADIO_ITEM_NAME;
732
+ var ITEM_INDICATOR_NAME = "MenuItemIndicator",
733
+ {
734
+ Provider: ItemIndicatorProvider,
735
+ useStyledContext: useItemIndicatorContext
736
+ } = createStyledContext(),
737
+ MenuItemIndicator = _Indicator.styleable(function (props, forwardedRef) {
738
+ var {
739
+ scope,
740
+ forceMount,
741
+ ...itemIndicatorProps
742
+ } = props,
743
+ indicatorContext = useItemIndicatorContext(scope);
744
+ return /* @__PURE__ */_jsx(Presence, {
745
+ children: forceMount || isIndeterminate(indicatorContext.checked) || indicatorContext.checked === !0 ? /* @__PURE__ */_jsx(_Indicator, {
746
+ componentName: ITEM_INDICATOR_NAME,
747
+ tag: "span",
748
+ ...itemIndicatorProps,
749
+ ref: forwardedRef,
750
+ "data-state": getCheckedState(indicatorContext.checked)
751
+ }) : null
752
+ });
753
+ });
754
+ MenuItemIndicator.displayName = ITEM_INDICATOR_NAME;
755
+ var MenuArrow = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
756
+ var {
757
+ scope,
758
+ unstyled = process.env.TAMAGUI_HEADLESS === "1",
759
+ ...rest
760
+ } = props;
761
+ return /* @__PURE__ */_jsx(PopperPrimitive.PopperArrow, {
762
+ scope: scope || MENU_CONTEXT,
763
+ componentName: "PopperArrow",
764
+ ...(!unstyled && {
765
+ backgroundColor: "$background"
766
+ }),
767
+ ...rest,
768
+ ref: forwardedRef
769
+ });
770
+ }),
771
+ SUB_NAME = "MenuSub",
772
+ {
773
+ Provider: MenuSubProvider,
774
+ useStyledContext: useMenuSubContext
775
+ } = createStyledContext(),
776
+ MenuSub = function (props) {
777
+ var {
778
+ scope,
779
+ children,
780
+ open = !1,
781
+ onOpenChange,
782
+ ...rest
783
+ } = props,
784
+ parentMenuContext = useMenuContext(scope),
785
+ [trigger, setTrigger] = React.useState(null),
786
+ [content, setContent] = React.useState(null),
787
+ handleOpenChange = useCallbackRef(onOpenChange);
788
+ return React.useEffect(function () {
789
+ return parentMenuContext.open === !1 && handleOpenChange(!1), function () {
790
+ return handleOpenChange(!1);
791
+ };
792
+ }, [parentMenuContext.open, handleOpenChange]), /* @__PURE__ */_jsx(PopperPrimitive.Popper, {
793
+ ...rest,
794
+ scope: scope || MENU_CONTEXT,
795
+ children: /* @__PURE__ */_jsx(MenuProvider, {
796
+ scope,
797
+ open,
798
+ onOpenChange: handleOpenChange,
799
+ content,
800
+ onContentChange: setContent,
801
+ children: /* @__PURE__ */_jsx(MenuSubProvider, {
802
+ scope,
803
+ contentId: useId(),
804
+ triggerId: useId(),
805
+ trigger,
806
+ onTriggerChange: setTrigger,
807
+ children
808
+ })
809
+ })
810
+ });
811
+ };
812
+ MenuSub.displayName = SUB_NAME;
813
+ var SUB_TRIGGER_NAME = "MenuSubTrigger",
814
+ MenuSubTrigger = YStack.styleable(function (props, forwardedRef) {
815
+ var context = useMenuContext(props.scope),
816
+ rootContext = useMenuRootContext(props.scope),
817
+ subContext = useMenuSubContext(props.scope),
818
+ contentContext = useMenuContentContext(props.scope),
819
+ openTimerRef = React.useRef(null),
820
+ {
821
+ pointerGraceTimerRef,
822
+ onPointerGraceIntentChange
823
+ } = contentContext,
824
+ clearOpenTimer = React.useCallback(function () {
825
+ openTimerRef.current && window.clearTimeout(openTimerRef.current), openTimerRef.current = null;
826
+ }, []);
827
+ return React.useEffect(function () {
828
+ return clearOpenTimer;
829
+ }, [clearOpenTimer]), React.useEffect(function () {
830
+ var pointerGraceTimer = pointerGraceTimerRef.current;
831
+ return function () {
832
+ window.clearTimeout(pointerGraceTimer), onPointerGraceIntentChange(null);
833
+ };
834
+ }, [pointerGraceTimerRef, onPointerGraceIntentChange]), /* @__PURE__ */_jsx(MenuAnchor, {
835
+ componentName: SUB_TRIGGER_NAME,
836
+ asChild: !0,
837
+ scope: props.scope || MENU_CONTEXT,
838
+ children: /* @__PURE__ */_jsx(MenuItemImpl, {
839
+ id: subContext.triggerId,
840
+ "aria-haspopup": "menu",
841
+ "aria-expanded": context.open,
842
+ "aria-controls": subContext.contentId,
843
+ "data-state": getOpenState(context.open),
844
+ outlineStyle: "none",
845
+ ...props,
846
+ ref: composeRefs(forwardedRef, subContext.onTriggerChange),
847
+ // This is redundant for mouse users but we cannot determine pointer type from
848
+ // click event and we cannot use pointerup event (see git history for reasons why)
849
+ onPress: function (event) {
850
+ var _props_onPress;
851
+ (_props_onPress = props.onPress) === null || _props_onPress === void 0 || _props_onPress.call(props, event), !(props.disabled || event.defaultPrevented) && (isWeb && event.currentTarget.focus(), context.open || context.onOpenChange(!0));
852
+ },
853
+ onPointerMove: composeEventHandlers(props.onPointerMove,
854
+ // @ts-ignore
855
+ whenMouse(function (event) {
856
+ contentContext.onItemEnter(event), !event.defaultPrevented && !props.disabled && !context.open && !openTimerRef.current && (contentContext.onPointerGraceIntentChange(null), openTimerRef.current = window.setTimeout(function () {
857
+ context.onOpenChange(!0), clearOpenTimer();
858
+ }, 100));
859
+ })),
860
+ onPointerLeave: composeEventHandlers(props.onPointerLeave,
861
+ // @ts-ignore
862
+ whenMouse(function (event) {
863
+ var _context_content;
864
+ clearOpenTimer();
865
+ var contentRect = (_context_content = context.content) === null || _context_content === void 0 ? void 0 : _context_content.getBoundingClientRect();
866
+ if (contentRect) {
867
+ var _context_content1,
868
+ side = (_context_content1 = context.content) === null || _context_content1 === void 0 ? void 0 : _context_content1.dataset.side,
869
+ rightSide = side === "right",
870
+ bleed = rightSide ? -5 : 5,
871
+ contentNearEdge = contentRect[rightSide ? "left" : "right"],
872
+ contentFarEdge = contentRect[rightSide ? "right" : "left"];
873
+ contentContext.onPointerGraceIntentChange({
874
+ area: [
875
+ // Apply a bleed on clientX to ensure that our exit point is
876
+ // consistently within polygon bounds
877
+ {
878
+ x: event.clientX + bleed,
879
+ y: event.clientY
880
+ }, {
881
+ x: contentNearEdge,
882
+ y: contentRect.top
883
+ }, {
884
+ x: contentFarEdge,
885
+ y: contentRect.top
886
+ }, {
887
+ x: contentFarEdge,
888
+ y: contentRect.bottom
889
+ }, {
890
+ x: contentNearEdge,
891
+ y: contentRect.bottom
892
+ }],
893
+ side
894
+ }), window.clearTimeout(pointerGraceTimerRef.current), pointerGraceTimerRef.current = window.setTimeout(function () {
895
+ return contentContext.onPointerGraceIntentChange(null);
896
+ }, 300);
897
+ } else {
898
+ if (contentContext.onTriggerLeave(event), event.defaultPrevented) return;
899
+ contentContext.onPointerGraceIntentChange(null);
900
+ }
901
+ })),
902
+ ...(isWeb ? {
903
+ onKeyDown: composeEventHandlers(
904
+ // @ts-ignore
905
+ props.onKeyDown, function (event) {
906
+ var isTypingAhead = contentContext.searchRef.current !== "";
907
+ if (!(props.disabled || isTypingAhead && event.key === " ") && SUB_OPEN_KEYS[rootContext.dir].includes(event.key)) {
908
+ var _context_content;
909
+ context.onOpenChange(!0), (_context_content = context.content) === null || _context_content === void 0 || _context_content.focus(), event.preventDefault();
910
+ }
911
+ })
912
+ } : null)
913
+ })
914
+ });
915
+ });
916
+ MenuSubTrigger.displayName = SUB_TRIGGER_NAME;
917
+ var SUB_CONTENT_NAME = "MenuSubContent",
918
+ MenuSubContent = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
919
+ var portalContext = usePortalContext(props.scope),
920
+ {
921
+ forceMount = portalContext.forceMount,
922
+ ...subContentProps
923
+ } = props,
924
+ context = useMenuContext(props.scope),
925
+ rootContext = useMenuRootContext(props.scope),
926
+ subContext = useMenuSubContext(props.scope),
927
+ ref = React.useRef(null),
928
+ composedRefs = useComposedRefs(forwardedRef, ref);
929
+ return /* @__PURE__ */_jsx(Collection.Provider, {
930
+ scope: props.scope || MENU_CONTEXT,
931
+ children: /* @__PURE__ */_jsx(Collection.Slot, {
932
+ scope: props.scope || MENU_CONTEXT,
933
+ children: /* @__PURE__ */_jsx(MenuContentImpl, {
934
+ id: subContext.contentId,
935
+ "aria-labelledby": subContext.triggerId,
936
+ ...subContentProps,
937
+ ref: composedRefs,
938
+ "data-side": rootContext.dir === "rtl" ? "left" : "right",
939
+ disableOutsidePointerEvents: !1,
940
+ disableOutsideScroll: !1,
941
+ trapFocus: !1,
942
+ onOpenAutoFocus: function (event) {
943
+ var _ref_current;
944
+ rootContext.isUsingKeyboardRef.current && ((_ref_current = ref.current) === null || _ref_current === void 0 || _ref_current.focus()), event.preventDefault();
945
+ },
946
+ // The menu might close because of focusing another menu item in the parent menu. We
947
+ // don't want it to refocus the trigger in that case so we handle trigger focus ourselves.
948
+ onCloseAutoFocus: function (event) {
949
+ return event.preventDefault();
950
+ },
951
+ onFocusOutside: composeEventHandlers(props.onFocusOutside, function (event) {
952
+ event.target !== subContext.trigger && context.onOpenChange(!1);
953
+ }),
954
+ onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, function (event) {
955
+ rootContext.onClose(), event.preventDefault();
956
+ }),
957
+ ...(isWeb ? {
958
+ // @ts-ignore
959
+ onKeyDown: composeEventHandlers(
960
+ // @ts-ignore
961
+ props.onKeyDown, function (event) {
962
+ var isKeyDownInside = event.currentTarget.contains(event.target),
963
+ isCloseKey = SUB_CLOSE_KEYS[rootContext.dir].includes(event.key);
964
+ if (isKeyDownInside && isCloseKey) {
965
+ var _subContext_trigger;
966
+ context.onOpenChange(!1), (_subContext_trigger = subContext.trigger) === null || _subContext_trigger === void 0 || _subContext_trigger.focus(), event.preventDefault();
967
+ }
968
+ })
969
+ } : null)
970
+ })
971
+ })
972
+ });
973
+ });
974
+ MenuSubContent.displayName = SUB_CONTENT_NAME;
975
+ var Anchor = MenuAnchor,
976
+ Portal = MenuPortal,
977
+ Content = MenuContent,
978
+ Group = _MenuGroup,
979
+ Label = _Label,
980
+ Item = MenuItem,
981
+ CheckboxItem = MenuCheckboxItem,
982
+ RadioGroup = MenuRadioGroup,
983
+ RadioItem = MenuRadioItem,
984
+ ItemIndicator = MenuItemIndicator,
985
+ Separator = _Separator,
986
+ Arrow = MenuArrow,
987
+ Sub = MenuSub,
988
+ SubTrigger = MenuSubTrigger,
989
+ SubContent = MenuSubContent,
990
+ ItemTitle = MenuItemTitle,
991
+ ItemSubtitle = MenuItemSubTitle,
992
+ ItemImage = MenuItemImage,
993
+ ItemIcon = MenuItemIcon,
994
+ Menu = withStaticProperties(MenuComp, {
995
+ Anchor,
996
+ Portal,
997
+ Content,
998
+ Group,
999
+ Label,
1000
+ Item,
1001
+ CheckboxItem,
1002
+ RadioGroup,
1003
+ RadioItem,
1004
+ ItemIndicator,
1005
+ Separator,
1006
+ Arrow,
1007
+ Sub,
1008
+ SubTrigger,
1009
+ SubContent,
1010
+ ItemTitle,
1011
+ ItemSubtitle,
1012
+ ItemImage,
1013
+ ItemIcon
1014
+ });
1015
+ return {
1016
+ Menu
1017
+ };
1018
+ }
1019
+ function getOpenState(open) {
1020
+ return open ? "open" : "closed";
1021
+ }
1022
+ function isIndeterminate(checked) {
1023
+ return checked === "indeterminate";
1024
+ }
1025
+ function getCheckedState(checked) {
1026
+ return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
1027
+ }
1028
+ function focusFirst(candidates) {
1029
+ var PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement,
1030
+ _iteratorNormalCompletion = !0,
1031
+ _didIteratorError = !1,
1032
+ _iteratorError = void 0;
1033
+ try {
1034
+ for (var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
1035
+ var candidate = _step.value;
1036
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT || (candidate.focus(), document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT)) return;
1037
+ }
1038
+ } catch (err) {
1039
+ _didIteratorError = !0, _iteratorError = err;
1040
+ } finally {
1041
+ try {
1042
+ !_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
1043
+ } finally {
1044
+ if (_didIteratorError) throw _iteratorError;
1045
+ }
1046
+ }
1047
+ }
1048
+ function wrapArray(array, startIndex) {
1049
+ return array.map(function (_, index) {
1050
+ return array[(startIndex + index) % array.length];
1051
+ });
1052
+ }
1053
+ function getNextMatch(values, search, currentMatch) {
1054
+ var isRepeated = search.length > 1 && Array.from(search).every(function (char) {
1055
+ return char === search[0];
1056
+ }),
1057
+ normalizedSearch = isRepeated ? search[0] : search,
1058
+ currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1,
1059
+ wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0)),
1060
+ excludeCurrentMatch = normalizedSearch.length === 1;
1061
+ excludeCurrentMatch && (wrappedValues = wrappedValues.filter(function (v) {
1062
+ return v !== currentMatch;
1063
+ }));
1064
+ var nextMatch = wrappedValues.find(function (value) {
1065
+ return value.toLowerCase().startsWith(normalizedSearch.toLowerCase());
1066
+ });
1067
+ return nextMatch !== currentMatch ? nextMatch : void 0;
1068
+ }
1069
+ function isPointInPolygon(point, polygon) {
1070
+ for (var {
1071
+ x,
1072
+ y
1073
+ } = point, inside = !1, i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
1074
+ var xi = polygon[i].x,
1075
+ yi = polygon[i].y,
1076
+ xj = polygon[j].x,
1077
+ yj = polygon[j].y,
1078
+ intersect = yi > y != yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
1079
+ intersect && (inside = !inside);
1080
+ }
1081
+ return inside;
1082
+ }
1083
+ function isPointerInGraceArea(event, area) {
1084
+ if (!area) return !1;
1085
+ var cursorPos = {
1086
+ x: event.clientX,
1087
+ y: event.clientY
1088
+ };
1089
+ return isPointInPolygon(cursorPos, area);
1090
+ }
1091
+ function whenMouse(handler) {
1092
+ return function (event) {
1093
+ return event.pointerType === "mouse" ? handler(event) : void 0;
1094
+ };
1095
+ }
1096
+ export { NativePropProvider, createMenu, useNativeProp };
1097
+ //# sourceMappingURL=createMenu.native.js.map