@tamagui/create-menu 2.7.7 → 3.0.0-beta.643.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 (113) hide show
  1. package/dist/cjs/createBaseMenu.cjs +1033 -1247
  2. package/dist/cjs/createBaseMenu.native.cjs +1217 -0
  3. package/dist/cjs/createBaseMenu.native.js +1155 -1387
  4. package/dist/cjs/createBaseMenu.native.js.map +1 -1
  5. package/dist/cjs/createNativeMenu/createNativeMenu.cjs +346 -377
  6. package/dist/cjs/createNativeMenu/createNativeMenu.native.cjs +439 -0
  7. package/dist/cjs/createNativeMenu/createNativeMenu.native.js +405 -439
  8. package/dist/cjs/createNativeMenu/createNativeMenu.native.js.map +1 -1
  9. package/dist/cjs/createNativeMenu/createNativeMenuTypes.cjs +10 -11
  10. package/dist/cjs/createNativeMenu/createNativeMenuTypes.native.cjs +19 -0
  11. package/dist/cjs/createNativeMenu/createNativeMenuTypes.native.js +10 -10
  12. package/dist/cjs/createNativeMenu/createNativeMenuTypes.native.js.map +1 -1
  13. package/dist/cjs/createNativeMenu/utils.cjs +76 -86
  14. package/dist/cjs/createNativeMenu/utils.native.cjs +107 -0
  15. package/dist/cjs/createNativeMenu/utils.native.js +82 -92
  16. package/dist/cjs/createNativeMenu/utils.native.js.map +1 -1
  17. package/dist/cjs/createNativeMenu/withNativeMenu.cjs +27 -35
  18. package/dist/cjs/createNativeMenu/withNativeMenu.native.cjs +42 -0
  19. package/dist/cjs/createNativeMenu/withNativeMenu.native.js +27 -34
  20. package/dist/cjs/createNativeMenu/withNativeMenu.native.js.map +1 -1
  21. package/dist/cjs/index.cjs +9 -20
  22. package/dist/cjs/index.native.cjs +23 -0
  23. package/dist/cjs/index.native.js +10 -20
  24. package/dist/cjs/index.native.js.map +1 -1
  25. package/dist/esm/createBaseMenu.mjs +1021 -1225
  26. package/dist/esm/createBaseMenu.mjs.map +1 -1
  27. package/dist/esm/createBaseMenu.native.js +1144 -1367
  28. package/dist/esm/createBaseMenu.native.js.map +1 -1
  29. package/dist/esm/createNativeMenu/createNativeMenu.mjs +332 -353
  30. package/dist/esm/createNativeMenu/createNativeMenu.mjs.map +1 -1
  31. package/dist/esm/createNativeMenu/createNativeMenu.native.js +392 -417
  32. package/dist/esm/createNativeMenu/createNativeMenu.native.js.map +1 -1
  33. package/dist/esm/createNativeMenu/createNativeMenuTypes.mjs +0 -2
  34. package/dist/esm/createNativeMenu/createNativeMenuTypes.native.js +0 -2
  35. package/dist/esm/createNativeMenu/utils.mjs +55 -57
  36. package/dist/esm/createNativeMenu/utils.mjs.map +1 -1
  37. package/dist/esm/createNativeMenu/utils.native.js +62 -65
  38. package/dist/esm/createNativeMenu/utils.native.js.map +1 -1
  39. package/dist/esm/createNativeMenu/withNativeMenu.mjs +14 -17
  40. package/dist/esm/createNativeMenu/withNativeMenu.mjs.map +1 -1
  41. package/dist/esm/createNativeMenu/withNativeMenu.native.js +15 -18
  42. package/dist/esm/createNativeMenu/withNativeMenu.native.js.map +1 -1
  43. package/dist/esm/index.js +5 -6
  44. package/dist/esm/index.mjs +5 -6
  45. package/dist/esm/index.native.js +5 -6
  46. package/dist/jsx/createBaseMenu.mjs +1021 -1225
  47. package/dist/jsx/createBaseMenu.mjs.map +1 -1
  48. package/dist/jsx/createBaseMenu.native.cjs +1217 -0
  49. package/dist/jsx/createBaseMenu.native.js +1155 -1387
  50. package/dist/jsx/createBaseMenu.native.js.map +1 -1
  51. package/dist/jsx/createNativeMenu/createNativeMenu.mjs +332 -353
  52. package/dist/jsx/createNativeMenu/createNativeMenu.mjs.map +1 -1
  53. package/dist/jsx/createNativeMenu/createNativeMenu.native.cjs +439 -0
  54. package/dist/jsx/createNativeMenu/createNativeMenu.native.js +405 -439
  55. package/dist/jsx/createNativeMenu/createNativeMenu.native.js.map +1 -1
  56. package/dist/jsx/createNativeMenu/createNativeMenuTypes.mjs +0 -2
  57. package/dist/jsx/createNativeMenu/createNativeMenuTypes.native.cjs +19 -0
  58. package/dist/jsx/createNativeMenu/createNativeMenuTypes.native.js +10 -10
  59. package/dist/jsx/createNativeMenu/createNativeMenuTypes.native.js.map +1 -1
  60. package/dist/jsx/createNativeMenu/utils.mjs +55 -57
  61. package/dist/jsx/createNativeMenu/utils.mjs.map +1 -1
  62. package/dist/jsx/createNativeMenu/utils.native.cjs +107 -0
  63. package/dist/jsx/createNativeMenu/utils.native.js +82 -92
  64. package/dist/jsx/createNativeMenu/utils.native.js.map +1 -1
  65. package/dist/jsx/createNativeMenu/withNativeMenu.mjs +14 -17
  66. package/dist/jsx/createNativeMenu/withNativeMenu.mjs.map +1 -1
  67. package/dist/jsx/createNativeMenu/withNativeMenu.native.cjs +42 -0
  68. package/dist/jsx/createNativeMenu/withNativeMenu.native.js +27 -34
  69. package/dist/jsx/createNativeMenu/withNativeMenu.native.js.map +1 -1
  70. package/dist/jsx/index.js +5 -6
  71. package/dist/jsx/index.mjs +5 -6
  72. package/dist/jsx/index.native.cjs +23 -0
  73. package/dist/jsx/index.native.js +10 -20
  74. package/dist/jsx/index.native.js.map +1 -1
  75. package/package.json +23 -22
  76. package/src/createBaseMenu.tsx +211 -231
  77. package/src/createNativeMenu/createNativeMenuTypes.ts +0 -6
  78. package/src/createNativeMenu/utils.tsx +6 -6
  79. package/src/createNativeMenu/withNativeMenu.tsx +1 -2
  80. package/src/index.tsx +0 -1
  81. package/types/createBaseMenu.d.ts +38 -126
  82. package/types/createBaseMenu.d.ts.map +1 -1
  83. package/types/createNativeMenu/createNativeMenu.d.ts +1 -1
  84. package/types/createNativeMenu/createNativeMenu.d.ts.map +1 -1
  85. package/types/createNativeMenu/createNativeMenuTypes.d.ts +0 -6
  86. package/types/createNativeMenu/createNativeMenuTypes.d.ts.map +1 -1
  87. package/types/createNativeMenu/utils.d.ts +5 -5
  88. package/types/createNativeMenu/utils.d.ts.map +1 -1
  89. package/types/createNativeMenu/withNativeMenu.d.ts.map +1 -1
  90. package/types/index.d.ts +0 -1
  91. package/types/index.d.ts.map +1 -1
  92. package/dist/cjs/MenuPredefined.cjs +0 -191
  93. package/dist/cjs/MenuPredefined.native.js +0 -194
  94. package/dist/cjs/MenuPredefined.native.js.map +0 -1
  95. package/dist/esm/MenuPredefined.mjs +0 -166
  96. package/dist/esm/MenuPredefined.mjs.map +0 -1
  97. package/dist/esm/MenuPredefined.native.js +0 -166
  98. package/dist/esm/MenuPredefined.native.js.map +0 -1
  99. package/dist/esm/createNativeMenu/createNativeMenuTypes.mjs.map +0 -1
  100. package/dist/esm/createNativeMenu/createNativeMenuTypes.native.js.map +0 -1
  101. package/dist/esm/index.js.map +0 -1
  102. package/dist/esm/index.mjs.map +0 -1
  103. package/dist/esm/index.native.js.map +0 -1
  104. package/dist/jsx/MenuPredefined.mjs +0 -166
  105. package/dist/jsx/MenuPredefined.mjs.map +0 -1
  106. package/dist/jsx/MenuPredefined.native.js +0 -194
  107. package/dist/jsx/MenuPredefined.native.js.map +0 -1
  108. package/dist/jsx/createNativeMenu/createNativeMenuTypes.mjs.map +0 -1
  109. package/dist/jsx/index.js.map +0 -1
  110. package/dist/jsx/index.mjs.map +0 -1
  111. package/src/MenuPredefined.tsx +0 -204
  112. package/types/MenuPredefined.d.ts +0 -31
  113. package/types/MenuPredefined.d.ts.map +0 -1
@@ -1,1412 +1,1189 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { createRefComponent, createStyledHOC } from "@tamagui/core";
2
3
  import { Animate } from "@tamagui/animate";
3
- import { AnimatePresence as Presence } from "@tamagui/animate-presence";
4
+ import { AnimatePresence } from "@tamagui/animate-presence";
4
5
  import { createCollection } from "@tamagui/collection";
5
- import { Dismissable as DismissableLayer, dispatchDiscreteCustomEvent } from "@tamagui/dismissable";
6
+ import { Dismissable, dispatchDiscreteCustomEvent } from "@tamagui/dismissable";
6
7
  import { useFocusGuards } from "@tamagui/focus-guard";
7
8
  import { FocusScope } from "@tamagui/focus-scope";
9
+ import { Image } from "@tamagui/image";
8
10
  import * as PopperPrimitive from "@tamagui/popper";
9
- import { needsPortalRepropagation, Portal as PortalPrimitive } from "@tamagui/portal";
11
+ import { Portal, needsPortalRepropagation } from "@tamagui/portal";
10
12
  import { RemoveScroll } from "@tamagui/remove-scroll";
11
13
  import { RovingFocusGroup } from "@tamagui/roving-focus";
12
14
  import { useCallbackRef } from "@tamagui/use-callback-ref";
13
15
  import { useDirection } from "@tamagui/use-direction";
14
- import { composeEventHandlers, composeRefs, createStyledContext, isWeb, styled, Text, Theme, useComposedRefs, useIsTouchDevice, useThemeName, View, withStaticProperties } from "@tamagui/web";
16
+ import { Text, Theme, View, composeEventHandlers, composeRefs, createStyledContext, isWeb, styled, useComposedRefs, useIsTouchDevice, useThemeName, withStaticProperties } from "@tamagui/web";
15
17
  import * as React from "react";
16
18
  import { useId } from "react";
17
- import { MenuPredefined } from "./MenuPredefined.native.js";
19
+
18
20
  function _instanceof(left, right) {
19
- if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
20
- return !!right[Symbol.hasInstance](left);
21
- } else {
22
- return left instanceof right;
23
- }
21
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
22
+ return !!right[Symbol.hasInstance](left);
23
+ } else {
24
+ return left instanceof right;
25
+ }
24
26
  }
25
27
  function _type_of(obj) {
26
- "@swc/helpers - typeof";
27
-
28
- return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
28
+ "@swc/helpers - typeof";
29
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
29
30
  }
30
31
  function whenMouse(handler) {
31
- return function (event) {
32
- return event.pointerType === "mouse" ? handler(event) : void 0;
33
- };
32
+ return function(event) {
33
+ return event.pointerType === "mouse" ? handler(event) : void 0;
34
+ };
34
35
  }
35
36
  var SELECTION_KEYS = ["Enter", " "];
36
- var FIRST_KEYS = ["ArrowDown", "PageUp", "Home"];
37
- var LAST_KEYS = ["ArrowUp", "PageDown", "End"];
37
+ var FIRST_KEYS = [
38
+ "ArrowDown",
39
+ "PageUp",
40
+ "Home"
41
+ ];
42
+ var LAST_KEYS = [
43
+ "ArrowUp",
44
+ "PageDown",
45
+ "End"
46
+ ];
38
47
  var FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
39
48
  var SUB_OPEN_KEYS = {
40
- ltr: [...SELECTION_KEYS, "ArrowRight"],
41
- rtl: [...SELECTION_KEYS, "ArrowLeft"]
49
+ ltr: [...SELECTION_KEYS, "ArrowRight"],
50
+ rtl: [...SELECTION_KEYS, "ArrowLeft"]
42
51
  };
43
52
  var SUB_CLOSE_KEYS = {
44
- ltr: ["ArrowLeft"],
45
- rtl: ["ArrowRight"]
53
+ ltr: ["ArrowLeft"],
54
+ rtl: ["ArrowRight"]
46
55
  };
47
56
  var MENU_NAME = "Menu";
48
57
  var [Collection, useCollection] = createCollection(MENU_NAME);
49
- var {
50
- Provider: MenuProvider,
51
- useStyledContext: useMenuContext
52
- } = createStyledContext();
53
- var {
54
- Provider: MenuRootProvider,
55
- useStyledContext: useMenuRootContext
56
- } = createStyledContext();
58
+ var { Provider: MenuProvider, useStyledContext: useMenuContext } = createStyledContext();
59
+ var { Provider: MenuRootProvider, useStyledContext: useMenuRootContext } = createStyledContext();
57
60
  var MENU_CONTEXT = "MenuContext";
58
- function createBaseMenu(param) {
59
- var {
60
- Item: _Item = MenuPredefined.MenuItem,
61
- Title: _Title = MenuPredefined.Title,
62
- SubTitle: _SubTitle = MenuPredefined.SubTitle,
63
- Image: _Image = MenuPredefined.MenuImage,
64
- Icon: _Icon = MenuPredefined.MenuIcon,
65
- Indicator: _Indicator = MenuPredefined.MenuIndicator,
66
- Separator: _Separator = MenuPredefined.MenuSeparator,
67
- MenuGroup: _MenuGroup = MenuPredefined.MenuGroup,
68
- Label: _Label = MenuPredefined.MenuLabel
69
- } = param;
70
- var MenuComp = function (props) {
71
- var direction = useDirection(props.dir);
72
- var defaultPlacement = direction === "rtl" ? "bottom-end" : "bottom-start";
73
- var {
74
- scope = MENU_CONTEXT,
75
- open = false,
76
- children,
77
- dir,
78
- onOpenChange,
79
- modal = true,
80
- allowFlip = {
81
- padding: 10
82
- },
83
- stayInFrame = {
84
- padding: 10
85
- },
86
- placement = defaultPlacement,
87
- resize = true,
88
- offset = 10,
89
- ...rest
90
- } = props;
91
- var [content, setContent] = React.useState(null);
92
- var isUsingKeyboardRef = React.useRef(false);
93
- var handleOpenChange = useCallbackRef(onOpenChange);
94
- if (isWeb) {
95
- React.useEffect(function () {
96
- var handleKeyDown = function () {
97
- isUsingKeyboardRef.current = true;
98
- document.addEventListener("pointerdown", handlePointer, {
99
- capture: true,
100
- once: true
101
- });
102
- document.addEventListener("pointermove", handlePointer, {
103
- capture: true,
104
- once: true
105
- });
106
- };
107
- var handlePointer = function () {
108
- return isUsingKeyboardRef.current = false;
109
- };
110
- document.addEventListener("keydown", handleKeyDown, {
111
- capture: true
112
- });
113
- return function () {
114
- document.removeEventListener("keydown", handleKeyDown, {
115
- capture: true
116
- });
117
- document.removeEventListener("pointerdown", handlePointer, {
118
- capture: true
119
- });
120
- document.removeEventListener("pointermove", handlePointer, {
121
- capture: true
122
- });
123
- };
124
- }, []);
125
- }
126
- return /* @__PURE__ */_jsx(PopperPrimitive.Popper, {
127
- scope,
128
- open,
129
- placement,
130
- allowFlip,
131
- stayInFrame,
132
- resize,
133
- offset,
134
- ...rest,
135
- children: /* @__PURE__ */_jsx(MenuProvider, {
136
- scope,
137
- open,
138
- onOpenChange: handleOpenChange,
139
- content,
140
- onContentChange: setContent,
141
- children: /* @__PURE__ */_jsx(MenuRootProvider, {
142
- scope,
143
- open,
144
- onClose: React.useCallback(function () {
145
- return handleOpenChange(false);
146
- }, [handleOpenChange]),
147
- isUsingKeyboardRef,
148
- dir: direction,
149
- modal,
150
- children: (/** this provider is just to avoid crashing when using useSubMenuContext() inside MenuPortal */
151
- /* @__PURE__ */_jsx(MenuSubProvider, {
152
- scope,
153
- children
154
- }))
155
- })
156
- })
157
- });
158
- };
159
- var RepropagateMenuAndMenuRootProvider = function (props) {
160
- var {
161
- scope = MENU_CONTEXT,
162
- menuContext,
163
- rootContext,
164
- popperContext,
165
- menuSubContext,
166
- children
167
- } = props;
168
- return /* @__PURE__ */_jsx(PopperPrimitive.PopperProvider, {
169
- ...popperContext,
170
- scope,
171
- children: /* @__PURE__ */_jsx(MenuProvider, {
172
- scope,
173
- ...menuContext,
174
- children: /* @__PURE__ */_jsx(MenuRootProvider, {
175
- scope,
176
- ...rootContext,
177
- children: menuSubContext ? /* @__PURE__ */_jsx(MenuSubProvider, {
178
- scope,
179
- ...menuSubContext,
180
- children
181
- }) : children
182
- })
183
- })
184
- });
185
- };
186
- MenuComp.displayName = MENU_NAME;
187
- var ANCHOR_NAME = "MenuAnchor";
188
- var MenuAnchor = function (props) {
189
- return /* @__PURE__ */_jsx(PopperPrimitive.PopperAnchor, {
190
- scope: MENU_CONTEXT,
191
- ...props
192
- });
193
- };
194
- MenuAnchor.displayName = ANCHOR_NAME;
195
- var PORTAL_NAME = "MenuPortal";
196
- var {
197
- Provider: PortalProvider,
198
- useStyledContext: usePortalContext
199
- } = createStyledContext(void 0, "Portal");
200
- var MenuPortal = function (props) {
201
- var {
202
- scope = MENU_CONTEXT,
203
- forceMount,
204
- zIndex,
205
- children
206
- } = props;
207
- var menuContext = useMenuContext(scope);
208
- var rootContext = useMenuRootContext(scope);
209
- var popperContext = PopperPrimitive.usePopperContext(scope);
210
- var menuSubContext = useMenuSubContext(scope);
211
- var themeName = useThemeName();
212
- var themedChildren = /* @__PURE__ */_jsx(Theme, {
213
- forceClassName: true,
214
- name: themeName,
215
- children
216
- });
217
- var content = needsPortalRepropagation() ? /* @__PURE__ */_jsx(RepropagateMenuAndMenuRootProvider, {
218
- menuContext,
219
- rootContext,
220
- popperContext,
221
- menuSubContext,
222
- scope,
223
- children: themedChildren
224
- }) : themedChildren;
225
- var isPresent = forceMount || rootContext.open && menuContext.open;
226
- return /* @__PURE__ */_jsx(Animate, {
227
- type: "presence",
228
- present: isPresent,
229
- children: /* @__PURE__ */_jsx(PortalPrimitive, {
230
- stackZIndex: true,
231
- children: /* @__PURE__ */_jsx(_Fragment, {
232
- children: /* @__PURE__ */_jsx(PortalProvider, {
233
- scope,
234
- forceMount,
235
- children: /* @__PURE__ */_jsxs(View, {
236
- zIndex: zIndex || 100,
237
- inset: 0,
238
- position: "absolute",
239
- children: [!!menuContext.open && !isWeb && /* @__PURE__ */_jsx(View, {
240
- inset: 0,
241
- position: "absolute",
242
- onPress: function () {
243
- return menuContext.onOpenChange(!menuContext.open);
244
- }
245
- }), content]
246
- })
247
- })
248
- })
249
- })
250
- });
251
- };
252
- MenuPortal.displayName = PORTAL_NAME;
253
- var CONTENT_NAME = "MenuContent";
254
- var {
255
- Provider: MenuContentProvider,
256
- useStyledContext: useMenuContentContext
257
- } = createStyledContext();
258
- var MenuContentFrame = styled(PopperPrimitive.PopperContentFrame, {
259
- name: CONTENT_NAME
260
- });
261
- var MenuContent = MenuContentFrame.styleable(function (props, forwardedRef) {
262
- var scope = props.scope || MENU_CONTEXT;
263
- var portalContext = usePortalContext(scope);
264
- var {
265
- forceMount = portalContext.forceMount,
266
- ...contentProps
267
- } = props;
268
- var rootContext = useMenuRootContext(scope);
269
- return /* @__PURE__ */_jsx(Collection.Provider, {
270
- scope,
271
- children: /* @__PURE__ */_jsx(Collection.Slot, {
272
- scope,
273
- children: rootContext.modal ? /* @__PURE__ */_jsx(MenuRootContentModal, {
274
- ...contentProps,
275
- ref: forwardedRef
276
- }) : /* @__PURE__ */_jsx(MenuRootContentNonModal, {
277
- ...contentProps,
278
- ref: forwardedRef
279
- })
280
- })
281
- });
282
- });
283
- var MenuRootContentModal = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
284
- var scope = props.scope || MENU_CONTEXT;
285
- var context = useMenuContext(scope);
286
- var ref = React.useRef(null);
287
- var composedRefs = useComposedRefs(forwardedRef, ref);
288
- return /* @__PURE__ */_jsx(MenuContentImpl, {
289
- ...props,
290
- scope,
291
- ref: composedRefs,
292
- // we make sure we're not trapping once it's been closed
293
- // (closed !== unmounted when animating out)
294
- trapFocus: context.open,
295
- // make sure to only disable pointer events when open
296
- // this avoids blocking interactions while animating out
297
- disableOutsidePointerEvents: context.open,
298
- disableOutsideScroll: false,
299
- // When focus is trapped, a `focusout` event may still happen.
300
- // We make sure we don't trigger our `onDismiss` in such case.
301
- onFocusOutside: composeEventHandlers(props.onFocusOutside, function (event) {
302
- return event.preventDefault();
303
- }, {
304
- checkDefaultPrevented: false
305
- }),
306
- onDismiss: function () {
307
- return context.onOpenChange(false);
308
- }
309
- });
310
- });
311
- var MenuRootContentNonModal = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
312
- var scope = props.scope || MENU_CONTEXT;
313
- var context = useMenuContext(scope);
314
- return /* @__PURE__ */_jsx(MenuContentImpl, {
315
- ...props,
316
- scope,
317
- ref: forwardedRef,
318
- trapFocus: false,
319
- disableOutsidePointerEvents: false,
320
- disableOutsideScroll: false,
321
- onDismiss: function () {
322
- return context.onOpenChange(false);
323
- }
324
- });
325
- });
326
- var MenuContentImpl = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
327
- var {
328
- scope = MENU_CONTEXT,
329
- loop = false,
330
- trapFocus,
331
- onOpenAutoFocus,
332
- onCloseAutoFocus,
333
- disableOutsidePointerEvents,
334
- onEntryFocus,
335
- onEscapeKeyDown,
336
- onPointerDownOutside,
337
- onFocusOutside,
338
- onInteractOutside,
339
- onDismiss,
340
- disableOutsideScroll,
341
- disableDismissOnScroll = false,
342
- unstyled = process.env.TAMAGUI_HEADLESS === "1",
343
- ...contentProps
344
- } = props;
345
- var context = useMenuContext(scope);
346
- var rootContext = useMenuRootContext(scope);
347
- var popperContext = PopperPrimitive.usePopperContext(scope);
348
- var getItems = useCollection(scope);
349
- var [currentItemId, setCurrentItemId] = React.useState(null);
350
- var contentRef = React.useRef(null);
351
- var focusableContentRef = React.useRef(null);
352
- var composedRefs = useComposedRefs(forwardedRef, contentRef, context.onContentChange);
353
- var timerRef = React.useRef(0);
354
- var searchRef = React.useRef("");
355
- var pointerGraceTimerRef = React.useRef(0);
356
- var pointerGraceIntentRef = React.useRef(null);
357
- var pointerDirRef = React.useRef("right");
358
- var lastPointerXRef = React.useRef(0);
359
- var handleTypeaheadSearch = function (key) {
360
- var _items_find, _items_find1;
361
- var search = searchRef.current + key;
362
- var items = getItems().filter(function (item) {
363
- return !item.disabled;
364
- });
365
- var currentItem = document.activeElement;
366
- var currentMatch = (_items_find = items.find(function (item) {
367
- return item.ref.current === currentItem;
368
- })) === null || _items_find === void 0 ? void 0 : _items_find.textValue;
369
- var values = items.map(function (item) {
370
- return item.textValue;
371
- });
372
- var nextMatch = getNextMatch(values, search, currentMatch);
373
- var newItem = (_items_find1 = items.find(function (item) {
374
- return item.textValue === nextMatch;
375
- })) === null || _items_find1 === void 0 ? void 0 : _items_find1.ref.current;
376
- (function updateSearch(value) {
377
- searchRef.current = value;
378
- clearTimeout(timerRef.current);
379
- if (value !== "") timerRef.current = setTimeout(function () {
380
- return updateSearch("");
381
- }, 1e3);
382
- })(search);
383
- if (newItem) {
384
- setTimeout(function () {
385
- return newItem.focus();
386
- });
387
- }
388
- };
389
- React.useEffect(function () {
390
- return function () {
391
- return clearTimeout(timerRef.current);
392
- };
393
- }, []);
394
- React.useEffect(function () {
395
- if (!isWeb || !context.open) return;
396
- var frame = requestAnimationFrame(function () {
397
- var container = contentRef.current;
398
- var el = container === null || container === void 0 ? void 0 : container.querySelector("[data-tamagui-menu-content]");
399
- if (el) focusableContentRef.current = el;
400
- });
401
- return function () {
402
- return cancelAnimationFrame(frame);
403
- };
404
- }, [context.open]);
405
- React.useEffect(function () {
406
- if (!isWeb || disableDismissOnScroll || !context.open) return;
407
- var handleScroll = function (event) {
408
- var _popperContext_refs_reference, _popperContext_refs;
409
- var scrolled = event.target;
410
- if (!scrolled) return;
411
- var content2 = contentRef.current;
412
- if (content2 === null || content2 === void 0 ? void 0 : content2.contains(scrolled)) return;
413
- var reference = (_popperContext_refs = popperContext.refs) === null || _popperContext_refs === void 0 ? void 0 : (_popperContext_refs_reference = _popperContext_refs.reference) === null || _popperContext_refs_reference === void 0 ? void 0 : _popperContext_refs_reference.current;
414
- var _reference_contextElement;
415
- var anchor = _instanceof(reference, Element) ? reference : (_reference_contextElement = reference === null || reference === void 0 ? void 0 : reference.contextElement) !== null && _reference_contextElement !== void 0 ? _reference_contextElement : null;
416
- if (anchor && !scrolled.contains(anchor)) return;
417
- onDismiss === null || onDismiss === void 0 ? void 0 : onDismiss();
418
- };
419
- window.addEventListener("scroll", handleScroll, {
420
- capture: true,
421
- passive: true
422
- });
423
- return function () {
424
- window.removeEventListener("scroll", handleScroll, {
425
- capture: true
426
- });
427
- };
428
- }, [disableDismissOnScroll, context.open, onDismiss, popperContext.refs]);
429
- if (isWeb) {
430
- useFocusGuards();
431
- }
432
- var isPointerMovingToSubmenu = React.useCallback(function (event) {
433
- var _pointerGraceIntentRef_current, _pointerGraceIntentRef_current1;
434
- var isMovingTowards = pointerDirRef.current === ((_pointerGraceIntentRef_current = pointerGraceIntentRef.current) === null || _pointerGraceIntentRef_current === void 0 ? void 0 : _pointerGraceIntentRef_current.side);
435
- var inArea = isPointerInGraceArea(event, (_pointerGraceIntentRef_current1 = pointerGraceIntentRef.current) === null || _pointerGraceIntentRef_current1 === void 0 ? void 0 : _pointerGraceIntentRef_current1.area);
436
- return isMovingTowards && inArea;
437
- }, []);
438
- var content = /* @__PURE__ */_jsx(PopperPrimitive.PopperContent, {
439
- role: "menu",
440
- // tabIndex allows the content to be focusable so that onItemLeave can
441
- // focus the content frame and properly blur the previously focused item
442
- tabIndex: -1,
443
- unstyled,
444
- ...(!unstyled && {
445
- backgroundColor: "$background",
446
- borderWidth: 1,
447
- borderColor: "$borderColor",
448
- outlineWidth: 0,
449
- minWidth: 180
450
- }),
451
- "aria-orientation": "vertical",
452
- "data-state": getOpenState(context.open),
453
- "data-tamagui-menu-content": "",
454
- // TODO
455
- // @ts-ignore
456
- dir: rootContext.dir,
457
- scope: scope || MENU_CONTEXT,
458
- ...contentProps,
459
- ref: composedRefs,
460
- className: contentProps.transition ? void 0 : contentProps.className,
461
- ...(isWeb ? {
462
- onKeyDown: composeEventHandlers(contentProps.onKeyDown, function (event) {
463
- var target = event.target;
464
- var isKeyDownInside = target.closest("[data-tamagui-menu-content]") === event.currentTarget;
465
- var isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
466
- var isCharacterKey = event.key.length === 1;
467
- if (isKeyDownInside) {
468
- if (event.key === "Tab") event.preventDefault();
469
- if (!isModifierKey && isCharacterKey) handleTypeaheadSearch(event.key);
470
- }
471
- var isOnContentFrame = event.target.hasAttribute("data-tamagui-menu-content");
472
- if (!isKeyDownInside || !isOnContentFrame) return;
473
- if (!FIRST_LAST_KEYS.includes(event.key)) return;
474
- event.preventDefault();
475
- var items = getItems().filter(function (item) {
476
- return !item.disabled;
477
- });
478
- var candidateNodes = items.map(function (item) {
479
- return item.ref.current;
480
- });
481
- if (LAST_KEYS.includes(event.key)) candidateNodes.reverse();
482
- focusFirst(candidateNodes, {
483
- focusVisible: true
484
- });
485
- }),
486
- // TODO
487
- // @ts-ignore
488
- onBlur: composeEventHandlers(props.onBlur, function (event) {
489
- var _event_currentTarget;
490
- if (!((_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 ? void 0 : _event_currentTarget.contains(event.target))) {
491
- clearTimeout(timerRef.current);
492
- searchRef.current = "";
493
- }
494
- }),
495
- // TODO
496
- onPointerMove: composeEventHandlers(props.onPointerMove, function (event) {
497
- var _event_currentTarget;
498
- if (event.pointerType !== "mouse") return;
499
- var target = event.target;
500
- var pointerXHasChanged = lastPointerXRef.current !== event.clientX;
501
- if (((_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 ? void 0 : _event_currentTarget.contains(target)) && pointerXHasChanged) {
502
- var newDir = event.clientX > lastPointerXRef.current ? "right" : "left";
503
- pointerDirRef.current = newDir;
504
- lastPointerXRef.current = event.clientX;
505
- }
506
- })
507
- } : {})
508
- });
509
- return /* @__PURE__ */_jsx(MenuContentProvider, {
510
- scope,
511
- searchRef,
512
- onItemEnter: React.useCallback(function (event) {
513
- if (isPointerMovingToSubmenu(event)) event.preventDefault();
514
- }, [isPointerMovingToSubmenu]),
515
- onItemLeave: React.useCallback(function (event) {
516
- var _focusableContentRef_current;
517
- if (isPointerMovingToSubmenu(event)) return;
518
- (_focusableContentRef_current = focusableContentRef.current) === null || _focusableContentRef_current === void 0 ? void 0 : _focusableContentRef_current.focus();
519
- setCurrentItemId(null);
520
- }, [isPointerMovingToSubmenu]),
521
- onTriggerLeave: React.useCallback(function (event) {
522
- if (isPointerMovingToSubmenu(event)) event.preventDefault();
523
- }, [isPointerMovingToSubmenu]),
524
- pointerGraceTimerRef,
525
- onPointerGraceIntentChange: React.useCallback(function (intent) {
526
- pointerGraceIntentRef.current = intent;
527
- }, []),
528
- children: /* @__PURE__ */_jsx(RemoveScroll, {
529
- enabled: disableOutsideScroll,
530
- children: /* @__PURE__ */_jsx(FocusScope, {
531
- asChild: false,
532
- trapped: trapFocus,
533
- onMountAutoFocus: composeEventHandlers(onOpenAutoFocus, function (event) {
534
- event.preventDefault();
535
- var content2 = document.querySelector("[data-tamagui-menu-content]");
536
- content2 === null || content2 === void 0 ? void 0 : content2.focus({
537
- preventScroll: true
538
- });
539
- }),
540
- onUnmountAutoFocus: onCloseAutoFocus,
541
- children: /* @__PURE__ */_jsx(DismissableLayer, {
542
- disableOutsidePointerEvents,
543
- onEscapeKeyDown,
544
- onPointerDownOutside,
545
- onFocusOutside,
546
- onInteractOutside,
547
- onDismiss,
548
- asChild: true,
549
- children: /* @__PURE__ */_jsx(RovingFocusGroup, {
550
- asChild: true,
551
- __scopeRovingFocusGroup: scope || MENU_CONTEXT,
552
- dir: rootContext.dir,
553
- orientation: "vertical",
554
- loop,
555
- currentTabStopId: currentItemId,
556
- onCurrentTabStopIdChange: setCurrentItemId,
557
- onEntryFocus: composeEventHandlers(onEntryFocus, function (event) {
558
- if (!rootContext.isUsingKeyboardRef.current) {
559
- event.preventDefault();
560
- }
561
- }),
562
- children: content
563
- })
564
- })
565
- })
566
- })
567
- });
568
- });
569
- MenuContent.displayName = CONTENT_NAME;
570
- var ITEM_NAME = "MenuItem";
571
- var ITEM_SELECT = "menu.itemSelect";
572
- var MenuItem = _Item.styleable(function (props, forwardedRef) {
573
- var {
574
- disabled = false,
575
- onSelect,
576
- preventCloseOnSelect,
577
- children,
578
- scope = MENU_CONTEXT,
579
- // filter out native-only props that shouldn't reach the DOM
580
- // @ts-ignore
581
- destructive,
582
- // @ts-ignore
583
- hidden,
584
- // @ts-ignore
585
- androidIconName,
586
- // @ts-ignore
587
- iosIconName,
588
- ...itemProps
589
- } = props;
590
- var ref = React.useRef(null);
591
- var rootContext = useMenuRootContext(scope);
592
- var contentContext = useMenuContentContext(scope);
593
- var composedRefs = useComposedRefs(forwardedRef, ref);
594
- var isPointerDownRef = React.useRef(false);
595
- var handleSelect = function () {
596
- var menuItem = ref.current;
597
- if (!disabled && menuItem) {
598
- if (isWeb) {
599
- var menuItemEl = menuItem;
600
- var itemSelectEvent = new CustomEvent(ITEM_SELECT, {
601
- bubbles: true,
602
- cancelable: true
603
- });
604
- menuItemEl.addEventListener(ITEM_SELECT, function (event) {
605
- return onSelect === null || onSelect === void 0 ? void 0 : onSelect(event);
606
- }, {
607
- once: true
608
- });
609
- dispatchDiscreteCustomEvent(menuItemEl, itemSelectEvent);
610
- if (itemSelectEvent.defaultPrevented || preventCloseOnSelect) {
611
- isPointerDownRef.current = false;
612
- } else {
613
- rootContext.onClose();
614
- }
615
- } else {
616
- onSelect === null || onSelect === void 0 ? void 0 : onSelect({
617
- target: menuItem
618
- });
619
- isPointerDownRef.current = false;
620
- if (!preventCloseOnSelect) {
621
- rootContext.onClose();
622
- }
623
- }
624
- }
625
- };
626
- var content = typeof children === "string" ? /* @__PURE__ */_jsx(Text, {
627
- children
628
- }) : children;
629
- return /* @__PURE__ */_jsx(MenuItemImpl, {
630
- outlineStyle: "none",
631
- ...itemProps,
632
- scope,
633
- // @ts-ignore
634
- ref: composedRefs,
635
- disabled,
636
- onPress: composeEventHandlers(props.onPress, handleSelect),
637
- onPointerDown: function (event) {
638
- var _props_onPointerDown;
639
- (_props_onPointerDown = props.onPointerDown) === null || _props_onPointerDown === void 0 ? void 0 : _props_onPointerDown.call(props, event);
640
- isPointerDownRef.current = true;
641
- },
642
- onPointerUp: composeEventHandlers(props.onPointerUp, function (event) {
643
- if (isWeb) {
644
- var _event_currentTarget;
645
- if (!isPointerDownRef.current) (_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 ? void 0 : _event_currentTarget.click();
646
- }
647
- }),
648
- ...(isWeb ? {
649
- onKeyDown: composeEventHandlers(props.onKeyDown, function (event) {
650
- var isTypingAhead = contentContext.searchRef.current !== "";
651
- if (disabled || isTypingAhead && event.key === " ") return;
652
- if (SELECTION_KEYS.includes(event.key)) {
653
- var _event_currentTarget;
654
- (_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 ? void 0 : _event_currentTarget.click();
655
- event.preventDefault();
656
- }
657
- })
658
- } : {}),
659
- children: content
660
- });
661
- });
662
- var MenuItemImpl = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
663
- var {
664
- scope = MENU_CONTEXT,
665
- disabled = false,
666
- textValue,
667
- unstyled = process.env.TAMAGUI_HEADLESS === "1",
668
- ...itemProps
669
- } = props;
670
- var contentContext = useMenuContentContext(scope);
671
- var ref = React.useRef(null);
672
- var composedRefs = useComposedRefs(forwardedRef, ref);
673
- var [isFocused, setIsFocused] = React.useState(false);
674
- var [textContent, setTextContent] = React.useState("");
675
- if (isWeb) {
676
- React.useEffect(function () {
677
- var menuItem = ref.current;
678
- if (menuItem) {
679
- var _menuItem_textContent;
680
- setTextContent(((_menuItem_textContent = menuItem.textContent) !== null && _menuItem_textContent !== void 0 ? _menuItem_textContent : "").trim());
681
- }
682
- }, [itemProps.children]);
683
- }
684
- return /* @__PURE__ */_jsx(Collection.ItemSlot, {
685
- scope,
686
- disabled,
687
- textValue: textValue !== null && textValue !== void 0 ? textValue : textContent,
688
- children: /* @__PURE__ */_jsx(RovingFocusGroup.Item, {
689
- asChild: true,
690
- __scopeRovingFocusGroup: scope,
691
- focusable: !disabled,
692
- children: /* @__PURE__ */_jsx(_Item, {
693
- unstyled,
694
- componentName: ITEM_NAME,
695
- role: "menuitem",
696
- "data-highlighted": isFocused ? "" : void 0,
697
- "aria-disabled": disabled || void 0,
698
- "data-disabled": disabled ? "" : void 0,
699
- ...itemProps,
700
- ref: composedRefs,
701
- /**
702
- * We focus items on `pointerMove` to achieve the following:
703
- *
704
- * - Mouse over an item (it focuses)
705
- * - Leave mouse where it is and use keyboard to focus a different item
706
- * - Wiggle mouse without it leaving previously focused item
707
- * - Previously focused item should re-focus
708
- *
709
- * If we used `mouseOver`/`mouseEnter` it would not re-focus when the mouse
710
- * wiggles. This is to match native menu implementation.
711
- */
712
- onPointerMove: composeEventHandlers(props.onPointerMove, function (event) {
713
- if (event.pointerType !== "mouse") return;
714
- if (disabled) {
715
- contentContext.onItemLeave(event);
716
- } else {
717
- contentContext.onItemEnter(event);
718
- if (!event.defaultPrevented) {
719
- var item = event.currentTarget;
720
- item.focus({
721
- preventScroll: true,
722
- focusVisible: false
723
- });
724
- }
725
- }
726
- }),
727
- onPointerLeave: composeEventHandlers(props.onPointerLeave, function (event) {
728
- contentContext.onItemLeave(event);
729
- }),
730
- onFocus: composeEventHandlers(props.onFocus, function () {
731
- return setIsFocused(true);
732
- }),
733
- onBlur: composeEventHandlers(props.onBlur, function () {
734
- return setIsFocused(false);
735
- })
736
- })
737
- })
738
- });
739
- });
740
- MenuItem.displayName = ITEM_NAME;
741
- var ITEM_TITLE_NAME = "MenuItemTitle";
742
- var MenuItemTitle = _Title.styleable(function (props, forwardedRef) {
743
- return /* @__PURE__ */_jsx(_Title, {
744
- ...props,
745
- ref: forwardedRef
746
- });
747
- });
748
- MenuItemTitle.displayName = ITEM_TITLE_NAME;
749
- var ITEM_SUB_TITLE_NAME = "MenuItemSubTitle";
750
- var MenuItemSubTitle = _SubTitle.styleable(function (props, forwardedRef) {
751
- return /* @__PURE__ */_jsx(_SubTitle, {
752
- ...props,
753
- ref: forwardedRef
754
- });
755
- });
756
- MenuItemSubTitle.displayName = ITEM_SUB_TITLE_NAME;
757
- var ITEM_IMAGE = "MenuItemImage";
758
- var MenuItemImage = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
759
- var {
760
- // @ts-ignore - native menu ios config
761
- ios,
762
- // @ts-ignore
763
- androidIconName,
764
- // @ts-ignore
765
- iosIconName,
766
- ...rest
767
- } = props;
768
- return /* @__PURE__ */_jsx(_Image, {
769
- ...rest,
770
- ref: forwardedRef
771
- });
772
- });
773
- MenuItemImage.displayName = ITEM_IMAGE;
774
- var ITEM_ICON = "MenuItemIcon";
775
- var MenuItemIcon = _Icon.styleable(function (props, forwardedRef) {
776
- var {
777
- // @ts-ignore
778
- ios,
779
- // @ts-ignore
780
- android,
781
- // @ts-ignore
782
- androidIconName,
783
- // @ts-ignore
784
- iosIconName,
785
- ...rest
786
- } = props;
787
- return /* @__PURE__ */_jsx(_Icon, {
788
- ...rest,
789
- ref: forwardedRef
790
- });
791
- });
792
- MenuItemIcon.displayName = ITEM_ICON;
793
- var CHECKBOX_ITEM_NAME = "MenuCheckboxItem";
794
- var MenuCheckboxItem = _Item.styleable(function (props, forwardedRef) {
795
- var {
796
- checked = false,
797
- onCheckedChange,
798
- scope = MENU_CONTEXT,
799
- // filter out native-only props
800
- // @ts-ignore - native menu value state
801
- value,
802
- // @ts-ignore - native menu value change handler
803
- onValueChange,
804
- ...checkboxItemProps
805
- } = props;
806
- return /* @__PURE__ */_jsx(ItemIndicatorProvider, {
807
- scope,
808
- checked,
809
- children: /* @__PURE__ */_jsx(MenuItem, {
810
- componentName: CHECKBOX_ITEM_NAME,
811
- role: isWeb ? "menuitemcheckbox" : "menuitem",
812
- "aria-checked": isIndeterminate(checked) ? "mixed" : checked,
813
- ...checkboxItemProps,
814
- scope,
815
- ref: forwardedRef,
816
- "data-state": getCheckedState(checked),
817
- onSelect: composeEventHandlers(checkboxItemProps.onSelect, function () {
818
- return onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(isIndeterminate(checked) ? true : !checked);
819
- }, {
820
- checkDefaultPrevented: false
821
- })
822
- })
823
- });
824
- });
825
- MenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
826
- var RADIO_GROUP_NAME = "MenuRadioGroup";
827
- var {
828
- Provider: RadioGroupProvider,
829
- useStyledContext: useRadioGroupContext
830
- } = createStyledContext();
831
- var MenuRadioGroup = _MenuGroup.styleable(function (props, forwardedRef) {
832
- var {
833
- value,
834
- onValueChange,
835
- scope = MENU_CONTEXT,
836
- ...groupProps
837
- } = props;
838
- var handleValueChange = useCallbackRef(onValueChange);
839
- return /* @__PURE__ */_jsx(RadioGroupProvider, {
840
- scope,
841
- value,
842
- onValueChange: handleValueChange,
843
- children: /* @__PURE__ */_jsx(_MenuGroup, {
844
- componentName: RADIO_GROUP_NAME,
845
- ...groupProps,
846
- ref: forwardedRef
847
- })
848
- });
849
- });
850
- MenuRadioGroup.displayName = RADIO_GROUP_NAME;
851
- var RADIO_ITEM_NAME = "MenuRadioItem";
852
- var MenuRadioItem = _Item.styleable(function (props, forwardedRef) {
853
- var {
854
- value,
855
- scope = MENU_CONTEXT,
856
- ...radioItemProps
857
- } = props;
858
- var context = useRadioGroupContext(scope);
859
- var checked = value === context.value;
860
- return /* @__PURE__ */_jsx(ItemIndicatorProvider, {
861
- scope,
862
- checked,
863
- children: /* @__PURE__ */_jsx(MenuItem, {
864
- componentName: RADIO_ITEM_NAME,
865
- ...radioItemProps,
866
- scope,
867
- "aria-checked": checked,
868
- ref: forwardedRef,
869
- role: isWeb ? "menuitemradio" : "menuitem",
870
- "data-state": getCheckedState(checked),
871
- onSelect: composeEventHandlers(radioItemProps.onSelect, function () {
872
- var _context_onValueChange;
873
- return (_context_onValueChange = context.onValueChange) === null || _context_onValueChange === void 0 ? void 0 : _context_onValueChange.call(context, value);
874
- }, {
875
- checkDefaultPrevented: false
876
- })
877
- })
878
- });
879
- });
880
- MenuRadioItem.displayName = RADIO_ITEM_NAME;
881
- var ITEM_INDICATOR_NAME = "MenuItemIndicator";
882
- var {
883
- Provider: ItemIndicatorProvider,
884
- useStyledContext: useItemIndicatorContext
885
- } = createStyledContext();
886
- var MenuItemIndicator = _Indicator.styleable(function (props, forwardedRef) {
887
- var {
888
- scope = MENU_CONTEXT,
889
- forceMount,
890
- ...itemIndicatorProps
891
- } = props;
892
- var indicatorContext = useItemIndicatorContext(scope);
893
- return /* @__PURE__ */_jsx(Presence, {
894
- children: forceMount || isIndeterminate(indicatorContext.checked) || indicatorContext.checked === true ? /* @__PURE__ */_jsx(_Indicator, {
895
- componentName: ITEM_INDICATOR_NAME,
896
- render: "span",
897
- ...itemIndicatorProps,
898
- ref: forwardedRef,
899
- "data-state": getCheckedState(indicatorContext.checked)
900
- }) : null
901
- });
902
- });
903
- MenuItemIndicator.displayName = ITEM_INDICATOR_NAME;
904
- var MenuArrow = /* @__PURE__ */React.forwardRef(function MenuArrow2(props, forwardedRef) {
905
- var {
906
- scope = MENU_CONTEXT,
907
- unstyled = process.env.TAMAGUI_HEADLESS === "1",
908
- ...rest
909
- } = props;
910
- return /* @__PURE__ */_jsx(PopperPrimitive.PopperArrow, {
911
- scope,
912
- componentName: "PopperArrow",
913
- unstyled,
914
- ...(!unstyled && {
915
- backgroundColor: "$background"
916
- }),
917
- ...rest,
918
- ref: forwardedRef
919
- });
920
- });
921
- var SUB_NAME = "MenuSub";
922
- var {
923
- Provider: MenuSubProvider,
924
- useStyledContext: useMenuSubContext
925
- } = createStyledContext();
926
- var MenuSub = function (props) {
927
- var _parentPopperContext_placement;
928
- var isTouchDevice = useIsTouchDevice();
929
- var {
930
- scope = MENU_CONTEXT
931
- } = props;
932
- var rootContext = useMenuRootContext(scope);
933
- var parentPopperContext = PopperPrimitive.usePopperContext(scope);
934
- var parentSide = (_parentPopperContext_placement = parentPopperContext.placement) === null || _parentPopperContext_placement === void 0 ? void 0 : _parentPopperContext_placement.split("-")[0];
935
- var isNestedSubmenu = parentSide === "left" || parentSide === "right";
936
- var defaultPlacement = isTouchDevice ? "bottom" : isNestedSubmenu ? `${parentSide}-start` : rootContext.dir === "rtl" ? "left-start" : "right-start";
937
- var {
938
- children,
939
- open = false,
940
- onOpenChange,
941
- allowFlip: allowFlipProp = {
942
- padding: 10
943
- },
944
- stayInFrame = {
945
- padding: 10
946
- },
947
- placement = defaultPlacement,
948
- ...rest
949
- } = props;
950
- var allowFlip = React.useMemo(function () {
951
- if (!isNestedSubmenu || typeof allowFlipProp === "boolean") return allowFlipProp;
952
- if (allowFlipProp.fallbackPlacements) return allowFlipProp;
953
- var side = placement.split("-")[0];
954
- var align = placement.split("-")[1] || "start";
955
- var otherAlign = align === "start" ? "end" : "start";
956
- if (side === "left" || side === "right") {
957
- var oppositeSide = side === "right" ? "left" : "right";
958
- return {
959
- ...((typeof allowFlipProp === "undefined" ? "undefined" : _type_of(allowFlipProp)) === "object" ? allowFlipProp : {}),
960
- fallbackPlacements: [`${side}-${otherAlign}`, `${oppositeSide}-${align}`, `${oppositeSide}-${otherAlign}`]
961
- };
962
- }
963
- return allowFlipProp;
964
- }, [isNestedSubmenu, allowFlipProp, placement]);
965
- var parentMenuContext = useMenuContext(scope);
966
- var [trigger, setTrigger] = React.useState(null);
967
- var [content, setContent] = React.useState(null);
968
- var handleOpenChange = useCallbackRef(onOpenChange);
969
- React.useEffect(function () {
970
- if (parentMenuContext.open === false) handleOpenChange(false);
971
- return function () {
972
- return handleOpenChange(false);
973
- };
974
- }, [parentMenuContext.open, handleOpenChange]);
975
- return /* @__PURE__ */_jsx(PopperPrimitive.Popper, {
976
- open,
977
- placement,
978
- allowFlip,
979
- stayInFrame,
980
- ...rest,
981
- scope,
982
- children: /* @__PURE__ */_jsx(MenuProvider, {
983
- scope,
984
- open,
985
- onOpenChange: handleOpenChange,
986
- content,
987
- onContentChange: setContent,
988
- children: /* @__PURE__ */_jsx(MenuSubProvider, {
989
- scope,
990
- contentId: useId(),
991
- triggerId: useId(),
992
- trigger,
993
- onTriggerChange: setTrigger,
994
- children
995
- })
996
- })
997
- });
998
- };
999
- MenuSub.displayName = SUB_NAME;
1000
- var SUB_TRIGGER_NAME = "MenuSubTrigger";
1001
- var MenuSubTrigger = /* @__PURE__ */React.forwardRef(function (props, forwardedRef) {
1002
- var scope = props.scope || MENU_CONTEXT;
1003
- var context = useMenuContext(scope);
1004
- var rootContext = useMenuRootContext(scope);
1005
- var subContext = useMenuSubContext(scope);
1006
- var contentContext = useMenuContentContext(scope);
1007
- var popperContext = PopperPrimitive.usePopperContext(scope);
1008
- var openTimerRef = React.useRef(null);
1009
- var {
1010
- pointerGraceTimerRef,
1011
- onPointerGraceIntentChange
1012
- } = contentContext;
1013
- var effectiveDir = rootContext.dir;
1014
- var clearOpenTimer = React.useCallback(function () {
1015
- if (openTimerRef.current) window.clearTimeout(openTimerRef.current);
1016
- openTimerRef.current = null;
1017
- }, []);
1018
- React.useEffect(function () {
1019
- return clearOpenTimer;
1020
- }, [clearOpenTimer]);
1021
- React.useEffect(function () {
1022
- var pointerGraceTimer = pointerGraceTimerRef.current;
1023
- return function () {
1024
- window.clearTimeout(pointerGraceTimer);
1025
- onPointerGraceIntentChange(null);
1026
- };
1027
- }, [pointerGraceTimerRef, onPointerGraceIntentChange]);
1028
- return /* @__PURE__ */_jsx(MenuAnchor, {
1029
- componentName: SUB_TRIGGER_NAME,
1030
- asChild: "except-style",
1031
- scope,
1032
- children: /* @__PURE__ */_jsx(MenuItemImpl, {
1033
- id: subContext.triggerId,
1034
- "aria-haspopup": "menu",
1035
- "aria-expanded": context.open,
1036
- "aria-controls": subContext.contentId,
1037
- "data-state": getOpenState(context.open),
1038
- outlineStyle: "none",
1039
- ...props,
1040
- ref: composeRefs(forwardedRef, subContext.onTriggerChange),
1041
- // This is redundant for mouse users but we cannot determine pointer type from
1042
- // click event and we cannot use pointerup event (see git history for reasons why)
1043
- onPress: function (event) {
1044
- var _props_onPress;
1045
- (_props_onPress = props.onPress) === null || _props_onPress === void 0 ? void 0 : _props_onPress.call(props, event);
1046
- if (props.disabled || event.defaultPrevented) return;
1047
- if (isWeb) {
1048
- event.currentTarget.focus();
1049
- }
1050
- if (!context.open) context.onOpenChange(true);
1051
- },
1052
- onPointerMove: composeEventHandlers(props.onPointerMove,
1053
- // @ts-ignore
1054
- whenMouse(function (event) {
1055
- contentContext.onItemEnter(event);
1056
- if (event.defaultPrevented) return;
1057
- if (!props.disabled && !context.open && !openTimerRef.current) {
1058
- contentContext.onPointerGraceIntentChange(null);
1059
- openTimerRef.current = window.setTimeout(function () {
1060
- context.onOpenChange(true);
1061
- clearOpenTimer();
1062
- }, 100);
1063
- }
1064
- })),
1065
- onPointerLeave: composeEventHandlers(props.onPointerLeave, function (eventIn) {
1066
- var _context_content;
1067
- var event = eventIn;
1068
- clearOpenTimer();
1069
- var contentRect = (_context_content = context.content) === null || _context_content === void 0 ? void 0 : _context_content.getBoundingClientRect();
1070
- if (contentRect) {
1071
- var _contentEl_dataset, _sideEl_dataset;
1072
- var contentEl = context.content;
1073
- var sideEl = (contentEl === null || contentEl === void 0 ? void 0 : (_contentEl_dataset = contentEl.dataset) === null || _contentEl_dataset === void 0 ? void 0 : _contentEl_dataset.side) ? contentEl : contentEl === null || contentEl === void 0 ? void 0 : contentEl.querySelector("[data-side]");
1074
- var side = (sideEl === null || sideEl === void 0 ? void 0 : (_sideEl_dataset = sideEl.dataset) === null || _sideEl_dataset === void 0 ? void 0 : _sideEl_dataset.side) || "right";
1075
- var rightSide = side === "right";
1076
- var bleed = rightSide ? -5 : 5;
1077
- var contentNearEdge = contentRect[rightSide ? "left" : "right"];
1078
- var contentFarEdge = contentRect[rightSide ? "right" : "left"];
1079
- var polygon = {
1080
- area: [
1081
- // Apply a bleed on clientX to ensure that our exit point is
1082
- // consistently within polygon bounds
1083
- {
1084
- x: event.clientX + bleed,
1085
- y: event.clientY
1086
- }, {
1087
- x: contentNearEdge,
1088
- y: contentRect.top
1089
- }, {
1090
- x: contentFarEdge,
1091
- y: contentRect.top
1092
- }, {
1093
- x: contentFarEdge,
1094
- y: contentRect.bottom
1095
- }, {
1096
- x: contentNearEdge,
1097
- y: contentRect.bottom
1098
- }],
1099
- side
1100
- };
1101
- contentContext.onPointerGraceIntentChange(polygon);
1102
- window.clearTimeout(pointerGraceTimerRef.current);
1103
- pointerGraceTimerRef.current = window.setTimeout(function () {
1104
- return contentContext.onPointerGraceIntentChange(null);
1105
- }, 300);
1106
- } else if (isWeb && subContext.trigger) {
1107
- var triggerEl = subContext.trigger;
1108
- var triggerRect = triggerEl === null || triggerEl === void 0 ? void 0 : triggerEl.getBoundingClientRect();
1109
- if (triggerRect) {
1110
- var _popperContext_placement;
1111
- var placementSide = (_popperContext_placement = popperContext.placement) === null || _popperContext_placement === void 0 ? void 0 : _popperContext_placement.split("-")[0];
1112
- var side1 = placementSide === "left" || placementSide === "right" ? placementSide : rootContext.dir === "rtl" ? "left" : "right";
1113
- var rightSide1 = side1 === "right";
1114
- var bleed1 = rightSide1 ? -5 : 5;
1115
- var nearEdge = rightSide1 ? triggerRect.right + 4 : triggerRect.left - 4;
1116
- var farEdge = rightSide1 ? nearEdge + 200 : nearEdge - 200;
1117
- var polygon1 = {
1118
- area: [{
1119
- x: event.clientX + bleed1,
1120
- y: event.clientY
1121
- }, {
1122
- x: nearEdge,
1123
- y: triggerRect.top - 50
1124
- }, {
1125
- x: farEdge,
1126
- y: triggerRect.top - 50
1127
- }, {
1128
- x: farEdge,
1129
- y: triggerRect.bottom + 50
1130
- }, {
1131
- x: nearEdge,
1132
- y: triggerRect.bottom + 50
1133
- }],
1134
- side: side1
1135
- };
1136
- contentContext.onPointerGraceIntentChange(polygon1);
1137
- window.clearTimeout(pointerGraceTimerRef.current);
1138
- pointerGraceTimerRef.current = window.setTimeout(function () {
1139
- return contentContext.onPointerGraceIntentChange(null);
1140
- }, 300);
1141
- }
1142
- } else {
1143
- contentContext.onTriggerLeave(event);
1144
- if (event.defaultPrevented) return;
1145
- contentContext.onPointerGraceIntentChange(null);
1146
- }
1147
- }),
1148
- ...(isWeb ? {
1149
- onKeyDown: composeEventHandlers(props.onKeyDown, function (event) {
1150
- var isTypingAhead = contentContext.searchRef.current !== "";
1151
- if (props.disabled || isTypingAhead && event.key === " ") return;
1152
- var willOpen = SUB_OPEN_KEYS[effectiveDir].includes(event.key);
1153
- if (willOpen) {
1154
- var _popperContext_refs, _context_content;
1155
- if (context.open && context.content) {
1156
- var _contentEl_querySelector;
1157
- var contentEl = context.content;
1158
- var firstItem = (_contentEl_querySelector = contentEl.querySelector) === null || _contentEl_querySelector === void 0 ? void 0 : _contentEl_querySelector.call(contentEl, '[role="menuitem"]:not([data-disabled])');
1159
- if (firstItem) {
1160
- firstItem.focus({
1161
- focusVisible: true
1162
- });
1163
- event.preventDefault();
1164
- return;
1165
- }
1166
- }
1167
- var triggerEl = event.currentTarget;
1168
- (_popperContext_refs = popperContext.refs) === null || _popperContext_refs === void 0 ? void 0 : _popperContext_refs.setReference(triggerEl);
1169
- context.onOpenChange(true);
1170
- requestAnimationFrame(function () {
1171
- var _popperContext_update;
1172
- (_popperContext_update = popperContext.update) === null || _popperContext_update === void 0 ? void 0 : _popperContext_update.call(popperContext);
1173
- });
1174
- (_context_content = context.content) === null || _context_content === void 0 ? void 0 : _context_content.focus({
1175
- focusVisible: true
1176
- });
1177
- event.preventDefault();
1178
- }
1179
- })
1180
- } : null)
1181
- })
1182
- });
1183
- });
1184
- MenuSubTrigger.displayName = SUB_TRIGGER_NAME;
1185
- var SUB_CONTENT_NAME = "MenuSubContent";
1186
- var MenuSubContentFrame = styled(PopperPrimitive.PopperContentFrame, {
1187
- name: SUB_CONTENT_NAME
1188
- });
1189
- var MenuSubContent = MenuSubContentFrame.styleable(function (props, forwardedRef) {
1190
- var _popperContext_placement;
1191
- var scope = props.scope || MENU_CONTEXT;
1192
- var portalContext = usePortalContext(scope);
1193
- var {
1194
- forceMount = portalContext.forceMount,
1195
- ...subContentProps
1196
- } = props;
1197
- var context = useMenuContext(scope);
1198
- var rootContext = useMenuRootContext(scope);
1199
- var subContext = useMenuSubContext(scope);
1200
- var popperContext = PopperPrimitive.usePopperContext(scope);
1201
- var ref = React.useRef(null);
1202
- var composedRefs = useComposedRefs(forwardedRef, ref);
1203
- var placementSide = (_popperContext_placement = popperContext.placement) === null || _popperContext_placement === void 0 ? void 0 : _popperContext_placement.split("-")[0];
1204
- var dataSide = placementSide === "left" || placementSide === "right" ? placementSide : rootContext.dir === "rtl" ? "left" : "right";
1205
- var effectiveDir = rootContext.dir;
1206
- return /* @__PURE__ */_jsx(Collection.Provider, {
1207
- scope,
1208
- children: /* @__PURE__ */_jsx(Collection.Slot, {
1209
- scope,
1210
- children: /* @__PURE__ */_jsx(MenuContentImpl, {
1211
- id: subContext.contentId,
1212
- "aria-labelledby": subContext.triggerId,
1213
- ...subContentProps,
1214
- ref: composedRefs,
1215
- "data-side": dataSide,
1216
- disableOutsidePointerEvents: false,
1217
- disableOutsideScroll: false,
1218
- trapFocus: false,
1219
- onOpenAutoFocus: function (event) {
1220
- if (rootContext.isUsingKeyboardRef.current) {
1221
- var _root_querySelector, _this;
1222
- var root = ref.current;
1223
- var content = root === null || root === void 0 ? void 0 : (_root_querySelector = root.querySelector) === null || _root_querySelector === void 0 ? void 0 : _root_querySelector.call(root, "[data-tamagui-menu-content]");
1224
- (_this = content || root) === null || _this === void 0 ? void 0 : _this.focus({
1225
- preventScroll: true
1226
- });
1227
- }
1228
- event.preventDefault();
1229
- },
1230
- // The menu might close because of focusing another menu item in the parent menu. We
1231
- // don't want it to refocus the trigger in that case so we handle trigger focus ourselves.
1232
- onCloseAutoFocus: function (event) {
1233
- return event.preventDefault();
1234
- },
1235
- onFocusOutside: composeEventHandlers(props.onFocusOutside, function (event) {
1236
- if (event.target !== subContext.trigger) context.onOpenChange(false);
1237
- }),
1238
- onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, function (event) {
1239
- var _subContext_trigger;
1240
- context.onOpenChange(false);
1241
- (_subContext_trigger = subContext.trigger) === null || _subContext_trigger === void 0 ? void 0 : _subContext_trigger.focus({
1242
- focusVisible: true
1243
- });
1244
- event.preventDefault();
1245
- }),
1246
- ...(isWeb ? {
1247
- onKeyDown: composeEventHandlers(props.onKeyDown, function (event) {
1248
- var isKeyDownInside = event.currentTarget.contains(event.target);
1249
- var isCloseKey = SUB_CLOSE_KEYS[effectiveDir].includes(event.key);
1250
- if (isKeyDownInside && isCloseKey) {
1251
- var _subContext_trigger;
1252
- context.onOpenChange(false);
1253
- (_subContext_trigger = subContext.trigger) === null || _subContext_trigger === void 0 ? void 0 : _subContext_trigger.focus({
1254
- focusVisible: true
1255
- });
1256
- event.preventDefault();
1257
- }
1258
- })
1259
- } : null)
1260
- })
1261
- })
1262
- });
1263
- });
1264
- MenuSubContent.displayName = SUB_CONTENT_NAME;
1265
- var Anchor = MenuAnchor;
1266
- var Portal = MenuPortal;
1267
- var Content = MenuContent;
1268
- var Group = _MenuGroup.styleable(function (props, ref) {
1269
- return /* @__PURE__ */_jsx(_MenuGroup, {
1270
- ...props,
1271
- ref
1272
- });
1273
- });
1274
- Group.displayName = "MenuGroup";
1275
- var Label = _Label.styleable(function (props, ref) {
1276
- return /* @__PURE__ */_jsx(_Label, {
1277
- ...props,
1278
- ref
1279
- });
1280
- });
1281
- Label.displayName = "MenuLabel";
1282
- var Item = MenuItem;
1283
- var CheckboxItem = MenuCheckboxItem;
1284
- var RadioGroup = MenuRadioGroup;
1285
- var RadioItem = MenuRadioItem;
1286
- var ItemIndicator = MenuItemIndicator;
1287
- var Separator = _Separator.styleable(function (props, ref) {
1288
- return /* @__PURE__ */_jsx(_Separator, {
1289
- ...props,
1290
- ref
1291
- });
1292
- });
1293
- Separator.displayName = "MenuSeparator";
1294
- var Arrow = MenuArrow;
1295
- var Sub = MenuSub;
1296
- var SubTrigger = MenuSubTrigger;
1297
- var SubContent = MenuSubContent;
1298
- var ItemTitle = MenuItemTitle;
1299
- var ItemSubtitle = MenuItemSubTitle;
1300
- var ItemImage = MenuItemImage;
1301
- var ItemIcon = MenuItemIcon;
1302
- var Menu = withStaticProperties(MenuComp, {
1303
- Anchor,
1304
- Portal,
1305
- Content,
1306
- Group,
1307
- Label,
1308
- Item,
1309
- CheckboxItem,
1310
- RadioGroup,
1311
- RadioItem,
1312
- ItemIndicator,
1313
- Separator,
1314
- Arrow,
1315
- Sub,
1316
- SubTrigger,
1317
- SubContent,
1318
- ItemTitle,
1319
- ItemSubtitle,
1320
- ItemImage,
1321
- ItemIcon
1322
- });
1323
- return {
1324
- Menu
1325
- };
61
+ var MenuImageFrame = styled(Image, { displayName: "MenuItemImage" });
62
+ function createBaseMenu() {
63
+ var MenuComp = function(props) {
64
+ var direction = useDirection(props.dir);
65
+ var defaultPlacement = direction === "rtl" ? "bottom-end" : "bottom-start";
66
+ var { scope = MENU_CONTEXT, open = false, children, dir, onOpenChange, modal = true, allowFlip = { padding: 10 }, stayInFrame = { padding: 10 }, placement = defaultPlacement, resize = true, offset = 10, ...rest } = props;
67
+ var [content, setContent] = React.useState(null);
68
+ var isUsingKeyboardRef = React.useRef(false);
69
+ var handleOpenChange = useCallbackRef(onOpenChange);
70
+ if (isWeb) {
71
+ React.useEffect(function() {
72
+ var handleKeyDown = function() {
73
+ isUsingKeyboardRef.current = true;
74
+ document.addEventListener("pointerdown", handlePointer, {
75
+ capture: true,
76
+ once: true
77
+ });
78
+ document.addEventListener("pointermove", handlePointer, {
79
+ capture: true,
80
+ once: true
81
+ });
82
+ };
83
+ var handlePointer = function() {
84
+ return isUsingKeyboardRef.current = false;
85
+ };
86
+ document.addEventListener("keydown", handleKeyDown, { capture: true });
87
+ return function() {
88
+ document.removeEventListener("keydown", handleKeyDown, { capture: true });
89
+ document.removeEventListener("pointerdown", handlePointer, { capture: true });
90
+ document.removeEventListener("pointermove", handlePointer, { capture: true });
91
+ };
92
+ }, []);
93
+ }
94
+ return /* @__PURE__ */ jsx(PopperPrimitive.Popper, {
95
+ scope,
96
+ open,
97
+ placement,
98
+ allowFlip,
99
+ stayInFrame,
100
+ resize,
101
+ offset,
102
+ ...rest,
103
+ children: /* @__PURE__ */ jsx(MenuProvider, {
104
+ scope,
105
+ open,
106
+ onOpenChange: handleOpenChange,
107
+ content,
108
+ onContentChange: setContent,
109
+ children: /* @__PURE__ */ jsx(MenuRootProvider, {
110
+ scope,
111
+ open,
112
+ onClose: React.useCallback(function() {
113
+ return handleOpenChange(false);
114
+ }, [handleOpenChange]),
115
+ isUsingKeyboardRef,
116
+ dir: direction,
117
+ modal,
118
+ children: /* @__PURE__ */ jsx(MenuSubProvider, {
119
+ scope,
120
+ children
121
+ })
122
+ })
123
+ })
124
+ });
125
+ };
126
+ var RepropagateMenuAndMenuRootProvider = function(props) {
127
+ var { scope = MENU_CONTEXT, menuContext, rootContext, popperContext, menuSubContext, children } = props;
128
+ return /* @__PURE__ */ jsx(PopperPrimitive.PopperProvider, {
129
+ ...popperContext,
130
+ scope,
131
+ children: /* @__PURE__ */ jsx(MenuProvider, {
132
+ scope,
133
+ ...menuContext,
134
+ children: /* @__PURE__ */ jsx(MenuRootProvider, {
135
+ scope,
136
+ ...rootContext,
137
+ children: menuSubContext ? /* @__PURE__ */ jsx(MenuSubProvider, {
138
+ scope,
139
+ ...menuSubContext,
140
+ children
141
+ }) : children
142
+ })
143
+ })
144
+ });
145
+ };
146
+ MenuComp.displayName = MENU_NAME;
147
+ var ANCHOR_NAME = "MenuAnchor";
148
+ var MenuAnchor = function(props) {
149
+ return /* @__PURE__ */ jsx(PopperPrimitive.PopperAnchor, {
150
+ scope: MENU_CONTEXT,
151
+ ...props
152
+ });
153
+ };
154
+ MenuAnchor.displayName = ANCHOR_NAME;
155
+ var PORTAL_NAME = "MenuPortal";
156
+ var { Provider: PortalProvider, useStyledContext: usePortalContext } = createStyledContext(void 0, "Portal");
157
+ var MenuPortal = function(props) {
158
+ var { scope = MENU_CONTEXT, forceMount, zIndex, children } = props;
159
+ var menuContext = useMenuContext(scope);
160
+ var rootContext = useMenuRootContext(scope);
161
+ var popperContext = PopperPrimitive.usePopperContext(scope);
162
+ var menuSubContext = useMenuSubContext(scope);
163
+ var themeName = useThemeName();
164
+ var themedChildren = /* @__PURE__ */ jsx(Theme, {
165
+ forceClassName: true,
166
+ name: themeName,
167
+ children
168
+ });
169
+ var content = needsPortalRepropagation() ? /* @__PURE__ */ jsx(RepropagateMenuAndMenuRootProvider, {
170
+ menuContext,
171
+ rootContext,
172
+ popperContext,
173
+ menuSubContext,
174
+ scope,
175
+ children: themedChildren
176
+ }) : themedChildren;
177
+ var isPresent = forceMount || rootContext.open && menuContext.open;
178
+ return /* @__PURE__ */ jsx(Animate, {
179
+ type: "presence",
180
+ present: isPresent,
181
+ children: /* @__PURE__ */ jsx(Portal, {
182
+ stackZIndex: true,
183
+ children: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(PortalProvider, {
184
+ scope,
185
+ forceMount,
186
+ children: /* @__PURE__ */ jsxs(View, {
187
+ zIndex: zIndex || 100,
188
+ inset: 0,
189
+ position: "absolute",
190
+ children: [!!menuContext.open && !isWeb && /* @__PURE__ */ jsx(View, {
191
+ inset: 0,
192
+ position: "absolute",
193
+ onPress: function() {
194
+ return menuContext.onOpenChange(!menuContext.open);
195
+ }
196
+ }), content]
197
+ })
198
+ }) })
199
+ })
200
+ });
201
+ };
202
+ MenuPortal.displayName = PORTAL_NAME;
203
+ var CONTENT_NAME = "MenuContent";
204
+ var { Provider: MenuContentProvider, useStyledContext: useMenuContentContext } = createStyledContext();
205
+ var MenuContentFrame = styled(PopperPrimitive.PopperContentFrame, { displayName: CONTENT_NAME });
206
+ var MenuContent = createStyledHOC(MenuContentFrame, function(props, forwardedRef) {
207
+ var scope = props.scope || MENU_CONTEXT;
208
+ var portalContext = usePortalContext(scope);
209
+ var { forceMount = portalContext.forceMount, ...contentProps } = props;
210
+ var rootContext = useMenuRootContext(scope);
211
+ return /* @__PURE__ */ jsx(Collection.Provider, {
212
+ scope,
213
+ children: /* @__PURE__ */ jsx(Collection.Slot, {
214
+ scope,
215
+ children: rootContext.modal ? /* @__PURE__ */ jsx(MenuRootContentModal, {
216
+ ...contentProps,
217
+ ref: forwardedRef
218
+ }) : /* @__PURE__ */ jsx(MenuRootContentNonModal, {
219
+ ...contentProps,
220
+ ref: forwardedRef
221
+ })
222
+ })
223
+ });
224
+ });
225
+ var MenuRootContentModal = createRefComponent(function(props, forwardedRef) {
226
+ var scope = props.scope || MENU_CONTEXT;
227
+ var context = useMenuContext(scope);
228
+ var ref = React.useRef(null);
229
+ var composedRefs = useComposedRefs(forwardedRef, ref);
230
+ return /* @__PURE__ */ jsx(MenuContentImpl, {
231
+ ...props,
232
+ scope,
233
+ ref: composedRefs,
234
+ trapFocus: context.open,
235
+ disableOutsidePointerEvents: context.open,
236
+ disableOutsideScroll: false,
237
+ onFocusOutside: composeEventHandlers(props.onFocusOutside, function(event) {
238
+ return event.cancel();
239
+ }, { checkDefaultPrevented: false }),
240
+ onDismiss: function() {
241
+ return context.onOpenChange(false);
242
+ }
243
+ });
244
+ });
245
+ var MenuRootContentNonModal = createRefComponent(function(props, forwardedRef) {
246
+ var scope = props.scope || MENU_CONTEXT;
247
+ var context = useMenuContext(scope);
248
+ return /* @__PURE__ */ jsx(MenuContentImpl, {
249
+ ...props,
250
+ scope,
251
+ ref: forwardedRef,
252
+ trapFocus: false,
253
+ disableOutsidePointerEvents: false,
254
+ disableOutsideScroll: false,
255
+ onDismiss: function() {
256
+ return context.onOpenChange(false);
257
+ }
258
+ });
259
+ });
260
+ var MenuContentImpl = createRefComponent(function(props, forwardedRef) {
261
+ var { scope = MENU_CONTEXT, loop = false, trapFocus, onOpenAutoFocus, onCloseAutoFocus, disableOutsidePointerEvents, onEntryFocus, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss, disableOutsideScroll, disableDismissOnScroll = false, ...contentProps } = props;
262
+ var context = useMenuContext(scope);
263
+ var rootContext = useMenuRootContext(scope);
264
+ var popperContext = PopperPrimitive.usePopperContext(scope);
265
+ var getItems = useCollection(scope);
266
+ var [currentItemId, setCurrentItemId] = React.useState(null);
267
+ var contentRef = React.useRef(null);
268
+ var focusableContentRef = React.useRef(null);
269
+ var composedRefs = useComposedRefs(forwardedRef, contentRef, context.onContentChange);
270
+ var timerRef = React.useRef(0);
271
+ var searchRef = React.useRef("");
272
+ var pointerGraceTimerRef = React.useRef(0);
273
+ var pointerGraceIntentRef = React.useRef(null);
274
+ var pointerDirRef = React.useRef("right");
275
+ var lastPointerXRef = React.useRef(0);
276
+ var handleTypeaheadSearch = function(key) {
277
+ var _items_find, _items_find1;
278
+ var search = searchRef.current + key;
279
+ var items = getItems().filter(function(item) {
280
+ return !item.disabled;
281
+ });
282
+ var currentItem = document.activeElement;
283
+ var currentMatch = (_items_find = items.find(function(item) {
284
+ return item.ref.current === currentItem;
285
+ })) === null || _items_find === void 0 ? void 0 : _items_find.textValue;
286
+ var values = items.map(function(item) {
287
+ return item.textValue;
288
+ });
289
+ var nextMatch = getNextMatch(values, search, currentMatch);
290
+ var newItem = (_items_find1 = items.find(function(item) {
291
+ return item.textValue === nextMatch;
292
+ })) === null || _items_find1 === void 0 ? void 0 : _items_find1.ref.current;
293
+ (function updateSearch(value) {
294
+ searchRef.current = value;
295
+ clearTimeout(timerRef.current);
296
+ if (value !== "") timerRef.current = setTimeout(function() {
297
+ return updateSearch("");
298
+ }, 1e3);
299
+ })(search);
300
+ if (newItem) {
301
+ setTimeout(function() {
302
+ return newItem.focus();
303
+ });
304
+ }
305
+ };
306
+ React.useEffect(function() {
307
+ return function() {
308
+ return clearTimeout(timerRef.current);
309
+ };
310
+ }, []);
311
+ React.useEffect(function() {
312
+ if (!isWeb || !context.open) return;
313
+ var frame = requestAnimationFrame(function() {
314
+ var container = contentRef.current;
315
+ var el = container === null || container === void 0 ? void 0 : container.querySelector("[data-tamagui-menu-content]");
316
+ if (el) focusableContentRef.current = el;
317
+ });
318
+ return function() {
319
+ return cancelAnimationFrame(frame);
320
+ };
321
+ }, [context.open]);
322
+ React.useEffect(function() {
323
+ if (!isWeb || disableDismissOnScroll || !context.open) return;
324
+ var handleScroll = function(event) {
325
+ var _popperContext_refs_reference, _popperContext_refs;
326
+ var scrolled = event.target;
327
+ if (!scrolled) return;
328
+ var content2 = contentRef.current;
329
+ if (content2 === null || content2 === void 0 ? void 0 : content2.contains(scrolled)) return;
330
+ var reference = (_popperContext_refs = popperContext.refs) === null || _popperContext_refs === void 0 ? void 0 : (_popperContext_refs_reference = _popperContext_refs.reference) === null || _popperContext_refs_reference === void 0 ? void 0 : _popperContext_refs_reference.current;
331
+ var _reference_contextElement;
332
+ var anchor = _instanceof(reference, Element) ? reference : (_reference_contextElement = reference === null || reference === void 0 ? void 0 : reference.contextElement) !== null && _reference_contextElement !== void 0 ? _reference_contextElement : null;
333
+ if (anchor && !scrolled.contains(anchor)) return;
334
+ context.onOpenChange(false);
335
+ };
336
+ window.addEventListener("scroll", handleScroll, {
337
+ capture: true,
338
+ passive: true
339
+ });
340
+ return function() {
341
+ window.removeEventListener("scroll", handleScroll, { capture: true });
342
+ };
343
+ }, [
344
+ disableDismissOnScroll,
345
+ context.open,
346
+ context.onOpenChange,
347
+ popperContext.refs
348
+ ]);
349
+ if (isWeb) {
350
+ useFocusGuards();
351
+ }
352
+ var isPointerMovingToSubmenu = React.useCallback(function(event) {
353
+ var _pointerGraceIntentRef_current, _pointerGraceIntentRef_current1;
354
+ var isMovingTowards = pointerDirRef.current === ((_pointerGraceIntentRef_current = pointerGraceIntentRef.current) === null || _pointerGraceIntentRef_current === void 0 ? void 0 : _pointerGraceIntentRef_current.side);
355
+ var inArea = isPointerInGraceArea(event, (_pointerGraceIntentRef_current1 = pointerGraceIntentRef.current) === null || _pointerGraceIntentRef_current1 === void 0 ? void 0 : _pointerGraceIntentRef_current1.area);
356
+ return isMovingTowards && inArea;
357
+ }, []);
358
+ var content = /* @__PURE__ */ jsx(PopperPrimitive.PopperContent, {
359
+ role: "menu",
360
+ tabIndex: -1,
361
+ "aria-orientation": "vertical",
362
+ "data-state": getOpenState(context.open),
363
+ "data-tamagui-menu-content": "",
364
+ dir: rootContext.dir,
365
+ scope: scope || MENU_CONTEXT,
366
+ ...contentProps,
367
+ ref: composedRefs,
368
+ className: contentProps.transition ? void 0 : contentProps.className,
369
+ ...isWeb ? {
370
+ onKeyDown: composeEventHandlers(contentProps.onKeyDown, function(event) {
371
+ var target = event.target;
372
+ var isKeyDownInside = target.closest("[data-tamagui-menu-content]") === event.currentTarget;
373
+ var isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
374
+ var isCharacterKey = event.key.length === 1;
375
+ if (isKeyDownInside) {
376
+ if (event.key === "Tab") event.preventDefault();
377
+ if (!isModifierKey && isCharacterKey) handleTypeaheadSearch(event.key);
378
+ }
379
+ var isOnContentFrame = event.target.hasAttribute("data-tamagui-menu-content");
380
+ if (!isKeyDownInside || !isOnContentFrame) return;
381
+ if (!FIRST_LAST_KEYS.includes(event.key)) return;
382
+ event.preventDefault();
383
+ var items = getItems().filter(function(item) {
384
+ return !item.disabled;
385
+ });
386
+ var candidateNodes = items.map(function(item) {
387
+ return item.ref.current;
388
+ });
389
+ if (LAST_KEYS.includes(event.key)) candidateNodes.reverse();
390
+ focusFirst(candidateNodes, { focusVisible: true });
391
+ }),
392
+ onBlur: composeEventHandlers(props.onBlur, function(event) {
393
+ var _event_currentTarget;
394
+ if (!((_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 ? void 0 : _event_currentTarget.contains(event.target))) {
395
+ clearTimeout(timerRef.current);
396
+ searchRef.current = "";
397
+ }
398
+ }),
399
+ onPointerMove: composeEventHandlers(props.onPointerMove, function(event) {
400
+ var _event_currentTarget;
401
+ if (event.pointerType !== "mouse") return;
402
+ var target = event.target;
403
+ var pointerXHasChanged = lastPointerXRef.current !== event.clientX;
404
+ if (((_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 ? void 0 : _event_currentTarget.contains(target)) && pointerXHasChanged) {
405
+ var newDir = event.clientX > lastPointerXRef.current ? "right" : "left";
406
+ pointerDirRef.current = newDir;
407
+ lastPointerXRef.current = event.clientX;
408
+ }
409
+ })
410
+ } : {}
411
+ });
412
+ return /* @__PURE__ */ jsx(MenuContentProvider, {
413
+ scope,
414
+ searchRef,
415
+ onItemEnter: React.useCallback(function(event) {
416
+ if (isPointerMovingToSubmenu(event)) event.preventDefault();
417
+ }, [isPointerMovingToSubmenu]),
418
+ onItemLeave: React.useCallback(function(event) {
419
+ var _focusableContentRef_current;
420
+ if (isPointerMovingToSubmenu(event)) return;
421
+ (_focusableContentRef_current = focusableContentRef.current) === null || _focusableContentRef_current === void 0 ? void 0 : _focusableContentRef_current.focus();
422
+ setCurrentItemId(null);
423
+ }, [isPointerMovingToSubmenu]),
424
+ onTriggerLeave: React.useCallback(function(event) {
425
+ if (isPointerMovingToSubmenu(event)) event.preventDefault();
426
+ }, [isPointerMovingToSubmenu]),
427
+ pointerGraceTimerRef,
428
+ onPointerGraceIntentChange: React.useCallback(function(intent) {
429
+ pointerGraceIntentRef.current = intent;
430
+ }, []),
431
+ children: /* @__PURE__ */ jsx(RemoveScroll, {
432
+ enabled: disableOutsideScroll,
433
+ children: /* @__PURE__ */ jsx(FocusScope, {
434
+ asChild: false,
435
+ trapped: trapFocus,
436
+ onMountAutoFocus: composeEventHandlers(onOpenAutoFocus, function(event) {
437
+ event.cancel();
438
+ var content2 = document.querySelector("[data-tamagui-menu-content]");
439
+ content2 === null || content2 === void 0 ? void 0 : content2.focus({ preventScroll: true });
440
+ }),
441
+ onUnmountAutoFocus: onCloseAutoFocus,
442
+ children: /* @__PURE__ */ jsx(Dismissable, {
443
+ disableOutsidePointerEvents,
444
+ onEscapeKeyDown,
445
+ onPointerDownOutside,
446
+ onFocusOutside,
447
+ onInteractOutside,
448
+ onDismiss,
449
+ asChild: true,
450
+ children: /* @__PURE__ */ jsx(RovingFocusGroup, {
451
+ asChild: true,
452
+ __scopeRovingFocusGroup: scope || MENU_CONTEXT,
453
+ dir: rootContext.dir,
454
+ orientation: "vertical",
455
+ loop,
456
+ currentTabStopId: currentItemId,
457
+ onCurrentTabStopIdChange: setCurrentItemId,
458
+ onEntryFocus: composeEventHandlers(onEntryFocus, function(event) {
459
+ if (!rootContext.isUsingKeyboardRef.current) {
460
+ event.cancel();
461
+ }
462
+ }),
463
+ children: content
464
+ })
465
+ })
466
+ })
467
+ })
468
+ });
469
+ });
470
+ MenuContent.displayName = CONTENT_NAME;
471
+ var ITEM_NAME = "MenuItem";
472
+ var ITEM_SELECT = "menu.itemSelect";
473
+ var MenuItem = createStyledHOC(View, function(props, forwardedRef) {
474
+ var { disabled = false, onSelect, preventCloseOnSelect, children, scope = MENU_CONTEXT, destructive, hidden, androidIconName, ...itemProps } = props;
475
+ var ref = React.useRef(null);
476
+ var rootContext = useMenuRootContext(scope);
477
+ var contentContext = useMenuContentContext(scope);
478
+ var composedRefs = useComposedRefs(forwardedRef, ref);
479
+ var isPointerDownRef = React.useRef(false);
480
+ var handleSelect = function() {
481
+ var menuItem = ref.current;
482
+ if (!disabled && menuItem) {
483
+ if (isWeb) {
484
+ var menuItemEl = menuItem;
485
+ var itemSelectEvent = new CustomEvent(ITEM_SELECT, {
486
+ bubbles: true,
487
+ cancelable: true
488
+ });
489
+ menuItemEl.addEventListener(ITEM_SELECT, function(event) {
490
+ return onSelect === null || onSelect === void 0 ? void 0 : onSelect(event);
491
+ }, { once: true });
492
+ dispatchDiscreteCustomEvent(menuItemEl, itemSelectEvent);
493
+ if (itemSelectEvent.defaultPrevented || preventCloseOnSelect) {
494
+ isPointerDownRef.current = false;
495
+ } else {
496
+ rootContext.onClose();
497
+ }
498
+ } else {
499
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect({ target: menuItem });
500
+ isPointerDownRef.current = false;
501
+ if (!preventCloseOnSelect) {
502
+ rootContext.onClose();
503
+ }
504
+ }
505
+ }
506
+ };
507
+ var content = typeof children === "string" ? /* @__PURE__ */ jsx(Text, { children }) : children;
508
+ return /* @__PURE__ */ jsx(MenuItemImpl, {
509
+ ...itemProps,
510
+ scope,
511
+ ref: composedRefs,
512
+ disabled,
513
+ onPress: composeEventHandlers(props.onPress, handleSelect),
514
+ onPointerDown: function(event) {
515
+ var _props_onPointerDown;
516
+ (_props_onPointerDown = props.onPointerDown) === null || _props_onPointerDown === void 0 ? void 0 : _props_onPointerDown.call(props, event);
517
+ isPointerDownRef.current = true;
518
+ },
519
+ onPointerUp: composeEventHandlers(props.onPointerUp, function(event) {
520
+ if (isWeb) {
521
+ var _event_currentTarget;
522
+ if (!isPointerDownRef.current) (_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 ? void 0 : _event_currentTarget.click();
523
+ }
524
+ }),
525
+ ...isWeb ? { onKeyDown: composeEventHandlers(props.onKeyDown, function(event) {
526
+ var isTypingAhead = contentContext.searchRef.current !== "";
527
+ if (disabled || isTypingAhead && event.key === " ") return;
528
+ if (SELECTION_KEYS.includes(event.key)) {
529
+ var _event_currentTarget;
530
+ (_event_currentTarget = event.currentTarget) === null || _event_currentTarget === void 0 ? void 0 : _event_currentTarget.click();
531
+ event.preventDefault();
532
+ }
533
+ }) } : {},
534
+ children: content
535
+ });
536
+ });
537
+ var MenuItemImpl = createRefComponent(function(props, forwardedRef) {
538
+ var { scope = MENU_CONTEXT, className, disabled = false, textValue, ...itemProps } = props;
539
+ var contentContext = useMenuContentContext(scope);
540
+ var ref = React.useRef(null);
541
+ var composedRefs = useComposedRefs(forwardedRef, ref);
542
+ var [isFocused, setIsFocused] = React.useState(false);
543
+ var [textContent, setTextContent] = React.useState("");
544
+ if (isWeb) {
545
+ React.useEffect(function() {
546
+ var menuItem = ref.current;
547
+ if (menuItem) {
548
+ var _menuItem_textContent;
549
+ setTextContent(((_menuItem_textContent = menuItem.textContent) !== null && _menuItem_textContent !== void 0 ? _menuItem_textContent : "").trim());
550
+ }
551
+ }, [itemProps.children]);
552
+ }
553
+ return /* @__PURE__ */ jsx(Collection.ItemSlot, {
554
+ scope,
555
+ disabled,
556
+ textValue: textValue !== null && textValue !== void 0 ? textValue : textContent,
557
+ children: /* @__PURE__ */ jsx(RovingFocusGroup.Item, {
558
+ asChild: true,
559
+ __scopeRovingFocusGroup: scope,
560
+ tabIndex: disabled ? -1 : 0,
561
+ children: /* @__PURE__ */ jsx(View, {
562
+ className: `is_${ITEM_NAME} ${className || ""}`.trim(),
563
+ role: "menuitem",
564
+ "data-highlighted": isFocused ? "" : void 0,
565
+ "aria-disabled": disabled || void 0,
566
+ "data-disabled": disabled ? "" : void 0,
567
+ ...itemProps,
568
+ ref: composedRefs,
569
+ /**
570
+ * We focus items on `pointerMove` to achieve the following:
571
+ *
572
+ * - Mouse over an item (it focuses)
573
+ * - Leave mouse where it is and use keyboard to focus a different item
574
+ * - Wiggle mouse without it leaving previously focused item
575
+ * - Previously focused item should re-focus
576
+ *
577
+ * If we used `mouseOver`/`mouseEnter` it would not re-focus when the mouse
578
+ * wiggles. This is to match native menu implementation.
579
+ */
580
+ onPointerMove: composeEventHandlers(props.onPointerMove, function(event) {
581
+ if (event.pointerType !== "mouse") return;
582
+ if (disabled) {
583
+ contentContext.onItemLeave(event);
584
+ } else {
585
+ contentContext.onItemEnter(event);
586
+ if (!event.defaultPrevented) {
587
+ var item = event.currentTarget;
588
+ item.focus({
589
+ preventScroll: true,
590
+ focusVisible: false
591
+ });
592
+ }
593
+ }
594
+ }),
595
+ onPointerLeave: composeEventHandlers(props.onPointerLeave, function(event) {
596
+ contentContext.onItemLeave(event);
597
+ }),
598
+ onFocus: composeEventHandlers(props.onFocus, function() {
599
+ return setIsFocused(true);
600
+ }),
601
+ onBlur: composeEventHandlers(props.onBlur, function() {
602
+ return setIsFocused(false);
603
+ })
604
+ })
605
+ })
606
+ });
607
+ });
608
+ MenuItem.displayName = ITEM_NAME;
609
+ var ITEM_TITLE_NAME = "MenuItemTitle";
610
+ var MenuItemTitle = createStyledHOC(Text, function(props, forwardedRef) {
611
+ return /* @__PURE__ */ jsx(Text, {
612
+ ...props,
613
+ ref: forwardedRef
614
+ });
615
+ });
616
+ MenuItemTitle.displayName = ITEM_TITLE_NAME;
617
+ var ITEM_SUB_TITLE_NAME = "MenuItemSubTitle";
618
+ var MenuItemSubTitle = createStyledHOC(Text, function(props, forwardedRef) {
619
+ return /* @__PURE__ */ jsx(Text, {
620
+ ...props,
621
+ ref: forwardedRef
622
+ });
623
+ });
624
+ MenuItemSubTitle.displayName = ITEM_SUB_TITLE_NAME;
625
+ var ITEM_IMAGE = "MenuItemImage";
626
+ var MenuItemImage = createRefComponent(function(props, forwardedRef) {
627
+ var { ios, androidIconName, ...rest } = props;
628
+ return /* @__PURE__ */ jsx(MenuImageFrame, {
629
+ ...rest,
630
+ ref: forwardedRef
631
+ });
632
+ });
633
+ MenuItemImage.displayName = ITEM_IMAGE;
634
+ var ITEM_ICON = "MenuItemIcon";
635
+ var MenuItemIcon = createStyledHOC(View, function(props, forwardedRef) {
636
+ var { ios, android, androidIconName, ...rest } = props;
637
+ return /* @__PURE__ */ jsx(View, {
638
+ ...rest,
639
+ ref: forwardedRef
640
+ });
641
+ });
642
+ MenuItemIcon.displayName = ITEM_ICON;
643
+ var CHECKBOX_ITEM_NAME = "MenuCheckboxItem";
644
+ var MenuCheckboxItem = createStyledHOC(View, function(props, forwardedRef) {
645
+ var { checked = false, onCheckedChange, scope = MENU_CONTEXT, value, onValueChange, className, ...checkboxItemProps } = props;
646
+ return /* @__PURE__ */ jsx(ItemIndicatorProvider, {
647
+ scope,
648
+ checked,
649
+ children: /* @__PURE__ */ jsx(MenuItem, {
650
+ className: `is_${CHECKBOX_ITEM_NAME} ${className || ""}`.trim(),
651
+ role: isWeb ? "menuitemcheckbox" : "menuitem",
652
+ "aria-checked": isIndeterminate(checked) ? "mixed" : checked,
653
+ ...checkboxItemProps,
654
+ scope,
655
+ ref: forwardedRef,
656
+ "data-state": getCheckedState(checked),
657
+ onSelect: composeEventHandlers(checkboxItemProps.onSelect, function() {
658
+ return onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(isIndeterminate(checked) ? true : !checked);
659
+ }, { checkDefaultPrevented: false })
660
+ })
661
+ });
662
+ });
663
+ MenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
664
+ var RADIO_GROUP_NAME = "MenuRadioGroup";
665
+ var { Provider: RadioGroupProvider, useStyledContext: useRadioGroupContext } = createStyledContext();
666
+ var MenuRadioGroup = createStyledHOC(View, function(props, forwardedRef) {
667
+ var { value, onValueChange, scope = MENU_CONTEXT, className, ...groupProps } = props;
668
+ var handleValueChange = useCallbackRef(onValueChange);
669
+ return /* @__PURE__ */ jsx(RadioGroupProvider, {
670
+ scope,
671
+ value,
672
+ onValueChange: handleValueChange,
673
+ children: /* @__PURE__ */ jsx(View, {
674
+ className: `is_${RADIO_GROUP_NAME} ${className || ""}`.trim(),
675
+ ...groupProps,
676
+ ref: forwardedRef
677
+ })
678
+ });
679
+ });
680
+ MenuRadioGroup.displayName = RADIO_GROUP_NAME;
681
+ var RADIO_ITEM_NAME = "MenuRadioItem";
682
+ var MenuRadioItem = createStyledHOC(View, function(props, forwardedRef) {
683
+ var { value, scope = MENU_CONTEXT, className, ...radioItemProps } = props;
684
+ var context = useRadioGroupContext(scope);
685
+ var checked = value === context.value;
686
+ return /* @__PURE__ */ jsx(ItemIndicatorProvider, {
687
+ scope,
688
+ checked,
689
+ children: /* @__PURE__ */ jsx(MenuItem, {
690
+ className: `is_${RADIO_ITEM_NAME} ${className || ""}`.trim(),
691
+ ...radioItemProps,
692
+ scope,
693
+ "aria-checked": checked,
694
+ ref: forwardedRef,
695
+ role: isWeb ? "menuitemradio" : "menuitem",
696
+ "data-state": getCheckedState(checked),
697
+ onSelect: composeEventHandlers(radioItemProps.onSelect, function() {
698
+ var _context_onValueChange;
699
+ return (_context_onValueChange = context.onValueChange) === null || _context_onValueChange === void 0 ? void 0 : _context_onValueChange.call(context, value);
700
+ }, { checkDefaultPrevented: false })
701
+ })
702
+ });
703
+ });
704
+ MenuRadioItem.displayName = RADIO_ITEM_NAME;
705
+ var ITEM_INDICATOR_NAME = "MenuItemIndicator";
706
+ var { Provider: ItemIndicatorProvider, useStyledContext: useItemIndicatorContext } = createStyledContext();
707
+ var MenuItemIndicator = createStyledHOC(View, function(props, forwardedRef) {
708
+ var { scope = MENU_CONTEXT, className, forceMount, ...itemIndicatorProps } = props;
709
+ var indicatorContext = useItemIndicatorContext(scope);
710
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: forceMount || isIndeterminate(indicatorContext.checked) || indicatorContext.checked === true ? /* @__PURE__ */ jsx(View, {
711
+ className: `is_${ITEM_INDICATOR_NAME} ${className || ""}`.trim(),
712
+ render: "span",
713
+ ...itemIndicatorProps,
714
+ ref: forwardedRef,
715
+ "data-state": getCheckedState(indicatorContext.checked)
716
+ }) : null });
717
+ });
718
+ MenuItemIndicator.displayName = ITEM_INDICATOR_NAME;
719
+ var MenuArrow = createRefComponent(function MenuArrow2(props, forwardedRef) {
720
+ var { scope = MENU_CONTEXT, className, ...rest } = props;
721
+ return /* @__PURE__ */ jsx(PopperPrimitive.PopperArrow, {
722
+ scope,
723
+ className: `is_PopperArrow ${className || ""}`.trim(),
724
+ ...rest,
725
+ ref: forwardedRef
726
+ });
727
+ });
728
+ var SUB_NAME = "MenuSub";
729
+ var { Provider: MenuSubProvider, useStyledContext: useMenuSubContext } = createStyledContext();
730
+ var MenuSub = function(props) {
731
+ var _parentPopperContext_placement;
732
+ var isTouchDevice = useIsTouchDevice();
733
+ var { scope = MENU_CONTEXT } = props;
734
+ var rootContext = useMenuRootContext(scope);
735
+ var parentPopperContext = PopperPrimitive.usePopperContext(scope);
736
+ var parentSide = (_parentPopperContext_placement = parentPopperContext.placement) === null || _parentPopperContext_placement === void 0 ? void 0 : _parentPopperContext_placement.split("-")[0];
737
+ var isNestedSubmenu = parentSide === "left" || parentSide === "right";
738
+ var defaultPlacement = isTouchDevice ? "bottom" : isNestedSubmenu ? `${parentSide}-start` : rootContext.dir === "rtl" ? "left-start" : "right-start";
739
+ var { children, open = false, onOpenChange, allowFlip: allowFlipProp = { padding: 10 }, stayInFrame = { padding: 10 }, placement = defaultPlacement, ...rest } = props;
740
+ var allowFlip = React.useMemo(function() {
741
+ if (!isNestedSubmenu || typeof allowFlipProp === "boolean") return allowFlipProp;
742
+ if (allowFlipProp.fallbackPlacements) return allowFlipProp;
743
+ var side = placement.split("-")[0];
744
+ var align = placement.split("-")[1] || "start";
745
+ var otherAlign = align === "start" ? "end" : "start";
746
+ if (side === "left" || side === "right") {
747
+ var oppositeSide = side === "right" ? "left" : "right";
748
+ return {
749
+ ...(typeof allowFlipProp === "undefined" ? "undefined" : _type_of(allowFlipProp)) === "object" ? allowFlipProp : {},
750
+ fallbackPlacements: [
751
+ `${side}-${otherAlign}`,
752
+ `${oppositeSide}-${align}`,
753
+ `${oppositeSide}-${otherAlign}`
754
+ ]
755
+ };
756
+ }
757
+ return allowFlipProp;
758
+ }, [
759
+ isNestedSubmenu,
760
+ allowFlipProp,
761
+ placement
762
+ ]);
763
+ var parentMenuContext = useMenuContext(scope);
764
+ var [trigger, setTrigger] = React.useState(null);
765
+ var [content, setContent] = React.useState(null);
766
+ var handleOpenChange = useCallbackRef(onOpenChange);
767
+ React.useEffect(function() {
768
+ if (parentMenuContext.open === false) handleOpenChange(false);
769
+ return function() {
770
+ return handleOpenChange(false);
771
+ };
772
+ }, [parentMenuContext.open, handleOpenChange]);
773
+ return /* @__PURE__ */ jsx(PopperPrimitive.Popper, {
774
+ open,
775
+ placement,
776
+ allowFlip,
777
+ stayInFrame,
778
+ ...rest,
779
+ scope,
780
+ children: /* @__PURE__ */ jsx(MenuProvider, {
781
+ scope,
782
+ open,
783
+ onOpenChange: handleOpenChange,
784
+ content,
785
+ onContentChange: setContent,
786
+ children: /* @__PURE__ */ jsx(MenuSubProvider, {
787
+ scope,
788
+ contentId: useId(),
789
+ triggerId: useId(),
790
+ trigger,
791
+ onTriggerChange: setTrigger,
792
+ children
793
+ })
794
+ })
795
+ });
796
+ };
797
+ MenuSub.displayName = SUB_NAME;
798
+ var SUB_TRIGGER_NAME = "MenuSubTrigger";
799
+ var MenuSubTrigger = createRefComponent(function(props, forwardedRef) {
800
+ var scope = props.scope || MENU_CONTEXT;
801
+ var context = useMenuContext(scope);
802
+ var rootContext = useMenuRootContext(scope);
803
+ var subContext = useMenuSubContext(scope);
804
+ var contentContext = useMenuContentContext(scope);
805
+ var popperContext = PopperPrimitive.usePopperContext(scope);
806
+ var openTimerRef = React.useRef(null);
807
+ var { pointerGraceTimerRef, onPointerGraceIntentChange } = contentContext;
808
+ var effectiveDir = rootContext.dir;
809
+ var clearOpenTimer = React.useCallback(function() {
810
+ if (openTimerRef.current) window.clearTimeout(openTimerRef.current);
811
+ openTimerRef.current = null;
812
+ }, []);
813
+ React.useEffect(function() {
814
+ return clearOpenTimer;
815
+ }, [clearOpenTimer]);
816
+ React.useEffect(function() {
817
+ var pointerGraceTimer = pointerGraceTimerRef.current;
818
+ return function() {
819
+ window.clearTimeout(pointerGraceTimer);
820
+ onPointerGraceIntentChange(null);
821
+ };
822
+ }, [pointerGraceTimerRef, onPointerGraceIntentChange]);
823
+ return /* @__PURE__ */ jsx(MenuAnchor, {
824
+ className: `is_${SUB_TRIGGER_NAME}`,
825
+ asChild: "except-style",
826
+ scope,
827
+ children: /* @__PURE__ */ jsx(MenuItemImpl, {
828
+ id: subContext.triggerId,
829
+ "aria-haspopup": "menu",
830
+ "aria-expanded": context.open,
831
+ "aria-controls": subContext.contentId,
832
+ "data-state": getOpenState(context.open),
833
+ ...props,
834
+ ref: composeRefs(forwardedRef, subContext.onTriggerChange),
835
+ onPress: function(event) {
836
+ var _props_onPress;
837
+ (_props_onPress = props.onPress) === null || _props_onPress === void 0 ? void 0 : _props_onPress.call(props, event);
838
+ if (props.disabled || event.defaultPrevented) return;
839
+ if (isWeb) {
840
+ event.currentTarget.focus();
841
+ }
842
+ if (!context.open) context.onOpenChange(true);
843
+ },
844
+ onPointerMove: composeEventHandlers(props.onPointerMove, whenMouse(function(event) {
845
+ contentContext.onItemEnter(event);
846
+ if (event.defaultPrevented) return;
847
+ if (!props.disabled && !context.open && !openTimerRef.current) {
848
+ contentContext.onPointerGraceIntentChange(null);
849
+ openTimerRef.current = window.setTimeout(function() {
850
+ context.onOpenChange(true);
851
+ clearOpenTimer();
852
+ }, 100);
853
+ }
854
+ })),
855
+ onPointerLeave: composeEventHandlers(props.onPointerLeave, function(eventIn) {
856
+ var _context_content;
857
+ var event = eventIn;
858
+ clearOpenTimer();
859
+ var contentRect = (_context_content = context.content) === null || _context_content === void 0 ? void 0 : _context_content.getBoundingClientRect();
860
+ if (contentRect) {
861
+ var _contentEl_dataset, _sideEl_dataset;
862
+ var contentEl = context.content;
863
+ var sideEl = (contentEl === null || contentEl === void 0 ? void 0 : (_contentEl_dataset = contentEl.dataset) === null || _contentEl_dataset === void 0 ? void 0 : _contentEl_dataset.side) ? contentEl : contentEl === null || contentEl === void 0 ? void 0 : contentEl.querySelector("[data-side]");
864
+ var side = (sideEl === null || sideEl === void 0 ? void 0 : (_sideEl_dataset = sideEl.dataset) === null || _sideEl_dataset === void 0 ? void 0 : _sideEl_dataset.side) || "right";
865
+ var rightSide = side === "right";
866
+ var bleed = rightSide ? -5 : 5;
867
+ var contentNearEdge = contentRect[rightSide ? "left" : "right"];
868
+ var contentFarEdge = contentRect[rightSide ? "right" : "left"];
869
+ var polygon = {
870
+ area: [
871
+ {
872
+ x: event.clientX + bleed,
873
+ y: event.clientY
874
+ },
875
+ {
876
+ x: contentNearEdge,
877
+ y: contentRect.top
878
+ },
879
+ {
880
+ x: contentFarEdge,
881
+ y: contentRect.top
882
+ },
883
+ {
884
+ x: contentFarEdge,
885
+ y: contentRect.bottom
886
+ },
887
+ {
888
+ x: contentNearEdge,
889
+ y: contentRect.bottom
890
+ }
891
+ ],
892
+ side
893
+ };
894
+ contentContext.onPointerGraceIntentChange(polygon);
895
+ window.clearTimeout(pointerGraceTimerRef.current);
896
+ pointerGraceTimerRef.current = window.setTimeout(function() {
897
+ return contentContext.onPointerGraceIntentChange(null);
898
+ }, 300);
899
+ } else if (isWeb && subContext.trigger) {
900
+ var triggerEl = subContext.trigger;
901
+ var triggerRect = triggerEl === null || triggerEl === void 0 ? void 0 : triggerEl.getBoundingClientRect();
902
+ if (triggerRect) {
903
+ var _popperContext_placement;
904
+ var placementSide = (_popperContext_placement = popperContext.placement) === null || _popperContext_placement === void 0 ? void 0 : _popperContext_placement.split("-")[0];
905
+ var side1 = placementSide === "left" || placementSide === "right" ? placementSide : rootContext.dir === "rtl" ? "left" : "right";
906
+ var rightSide1 = side1 === "right";
907
+ var bleed1 = rightSide1 ? -5 : 5;
908
+ var nearEdge = rightSide1 ? triggerRect.right + 4 : triggerRect.left - 4;
909
+ var farEdge = rightSide1 ? nearEdge + 200 : nearEdge - 200;
910
+ var polygon1 = {
911
+ area: [
912
+ {
913
+ x: event.clientX + bleed1,
914
+ y: event.clientY
915
+ },
916
+ {
917
+ x: nearEdge,
918
+ y: triggerRect.top - 50
919
+ },
920
+ {
921
+ x: farEdge,
922
+ y: triggerRect.top - 50
923
+ },
924
+ {
925
+ x: farEdge,
926
+ y: triggerRect.bottom + 50
927
+ },
928
+ {
929
+ x: nearEdge,
930
+ y: triggerRect.bottom + 50
931
+ }
932
+ ],
933
+ side: side1
934
+ };
935
+ contentContext.onPointerGraceIntentChange(polygon1);
936
+ window.clearTimeout(pointerGraceTimerRef.current);
937
+ pointerGraceTimerRef.current = window.setTimeout(function() {
938
+ return contentContext.onPointerGraceIntentChange(null);
939
+ }, 300);
940
+ }
941
+ } else {
942
+ contentContext.onTriggerLeave(event);
943
+ if (event.defaultPrevented) return;
944
+ contentContext.onPointerGraceIntentChange(null);
945
+ }
946
+ }),
947
+ ...isWeb ? { onKeyDown: composeEventHandlers(props.onKeyDown, function(event) {
948
+ var isTypingAhead = contentContext.searchRef.current !== "";
949
+ if (props.disabled || isTypingAhead && event.key === " ") return;
950
+ var willOpen = SUB_OPEN_KEYS[effectiveDir].includes(event.key);
951
+ if (willOpen) {
952
+ var _popperContext_refs, _context_content;
953
+ if (context.open && context.content) {
954
+ var _contentEl_querySelector;
955
+ var contentEl = context.content;
956
+ var firstItem = (_contentEl_querySelector = contentEl.querySelector) === null || _contentEl_querySelector === void 0 ? void 0 : _contentEl_querySelector.call(contentEl, "[role=\"menuitem\"]:not([data-disabled])");
957
+ if (firstItem) {
958
+ firstItem.focus({ focusVisible: true });
959
+ event.preventDefault();
960
+ return;
961
+ }
962
+ }
963
+ var triggerEl = event.currentTarget;
964
+ (_popperContext_refs = popperContext.refs) === null || _popperContext_refs === void 0 ? void 0 : _popperContext_refs.setReference(triggerEl);
965
+ context.onOpenChange(true);
966
+ requestAnimationFrame(function() {
967
+ var _popperContext_update;
968
+ (_popperContext_update = popperContext.update) === null || _popperContext_update === void 0 ? void 0 : _popperContext_update.call(popperContext);
969
+ });
970
+ (_context_content = context.content) === null || _context_content === void 0 ? void 0 : _context_content.focus({ focusVisible: true });
971
+ event.preventDefault();
972
+ }
973
+ }) } : null
974
+ })
975
+ });
976
+ });
977
+ MenuSubTrigger.displayName = SUB_TRIGGER_NAME;
978
+ var SUB_CONTENT_NAME = "MenuSubContent";
979
+ var MenuSubContentFrame = styled(PopperPrimitive.PopperContentFrame, { displayName: SUB_CONTENT_NAME });
980
+ var MenuSubContent = createStyledHOC(MenuSubContentFrame, function(props, forwardedRef) {
981
+ var _popperContext_placement;
982
+ var scope = props.scope || MENU_CONTEXT;
983
+ var portalContext = usePortalContext(scope);
984
+ var { forceMount = portalContext.forceMount, ...subContentProps } = props;
985
+ var context = useMenuContext(scope);
986
+ var rootContext = useMenuRootContext(scope);
987
+ var subContext = useMenuSubContext(scope);
988
+ var popperContext = PopperPrimitive.usePopperContext(scope);
989
+ var ref = React.useRef(null);
990
+ var composedRefs = useComposedRefs(forwardedRef, ref);
991
+ var placementSide = (_popperContext_placement = popperContext.placement) === null || _popperContext_placement === void 0 ? void 0 : _popperContext_placement.split("-")[0];
992
+ var dataSide = placementSide === "left" || placementSide === "right" ? placementSide : rootContext.dir === "rtl" ? "left" : "right";
993
+ var effectiveDir = rootContext.dir;
994
+ return /* @__PURE__ */ jsx(Collection.Provider, {
995
+ scope,
996
+ children: /* @__PURE__ */ jsx(Collection.Slot, {
997
+ scope,
998
+ children: /* @__PURE__ */ jsx(MenuContentImpl, {
999
+ id: subContext.contentId,
1000
+ "aria-labelledby": subContext.triggerId,
1001
+ ...subContentProps,
1002
+ ref: composedRefs,
1003
+ "data-side": dataSide,
1004
+ disableOutsidePointerEvents: false,
1005
+ disableOutsideScroll: false,
1006
+ trapFocus: false,
1007
+ onOpenAutoFocus: function(event) {
1008
+ if (rootContext.isUsingKeyboardRef.current) {
1009
+ var _root_querySelector, _this;
1010
+ var root = ref.current;
1011
+ var content = root === null || root === void 0 ? void 0 : (_root_querySelector = root.querySelector) === null || _root_querySelector === void 0 ? void 0 : _root_querySelector.call(root, "[data-tamagui-menu-content]");
1012
+ (_this = content || root) === null || _this === void 0 ? void 0 : _this.focus({ preventScroll: true });
1013
+ }
1014
+ event.cancel();
1015
+ },
1016
+ onCloseAutoFocus: function(event) {
1017
+ return event.cancel();
1018
+ },
1019
+ onFocusOutside: composeEventHandlers(props.onFocusOutside, function(event) {
1020
+ var _event_event;
1021
+ if (((_event_event = event.event) === null || _event_event === void 0 ? void 0 : _event_event.target) !== subContext.trigger) context.onOpenChange(false);
1022
+ }),
1023
+ onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, function(event) {
1024
+ var _subContext_trigger, _event_event_preventDefault, _event_event;
1025
+ context.onOpenChange(false);
1026
+ (_subContext_trigger = subContext.trigger) === null || _subContext_trigger === void 0 ? void 0 : _subContext_trigger.focus({ focusVisible: true });
1027
+ event.cancel();
1028
+ (_event_event = event.event) === null || _event_event === void 0 ? void 0 : (_event_event_preventDefault = _event_event.preventDefault) === null || _event_event_preventDefault === void 0 ? void 0 : _event_event_preventDefault.call(_event_event);
1029
+ }),
1030
+ ...isWeb ? { onKeyDown: composeEventHandlers(props.onKeyDown, function(event) {
1031
+ var isKeyDownInside = event.currentTarget.contains(event.target);
1032
+ var isCloseKey = SUB_CLOSE_KEYS[effectiveDir].includes(event.key);
1033
+ if (isKeyDownInside && isCloseKey) {
1034
+ var _subContext_trigger;
1035
+ context.onOpenChange(false);
1036
+ (_subContext_trigger = subContext.trigger) === null || _subContext_trigger === void 0 ? void 0 : _subContext_trigger.focus({ focusVisible: true });
1037
+ event.preventDefault();
1038
+ }
1039
+ }) } : null
1040
+ })
1041
+ })
1042
+ });
1043
+ });
1044
+ MenuSubContent.displayName = SUB_CONTENT_NAME;
1045
+ var Anchor = MenuAnchor;
1046
+ var Portal$1 = MenuPortal;
1047
+ var Content = MenuContent;
1048
+ var Group = createStyledHOC(View, function(props, ref) {
1049
+ return /* @__PURE__ */ jsx(View, {
1050
+ role: "group",
1051
+ ...props,
1052
+ ref
1053
+ });
1054
+ });
1055
+ Group.displayName = "MenuGroup";
1056
+ var Label = createStyledHOC(Text, function(props, ref) {
1057
+ return /* @__PURE__ */ jsx(Text, {
1058
+ ...props,
1059
+ ref
1060
+ });
1061
+ });
1062
+ Label.displayName = "MenuLabel";
1063
+ var Item = MenuItem;
1064
+ var CheckboxItem = MenuCheckboxItem;
1065
+ var RadioGroup = MenuRadioGroup;
1066
+ var RadioItem = MenuRadioItem;
1067
+ var ItemIndicator = MenuItemIndicator;
1068
+ var Separator = createStyledHOC(View, function(props, ref) {
1069
+ return /* @__PURE__ */ jsx(View, {
1070
+ role: "separator",
1071
+ "aria-orientation": "horizontal",
1072
+ ...props,
1073
+ ref
1074
+ });
1075
+ });
1076
+ Separator.displayName = "MenuSeparator";
1077
+ var Arrow = MenuArrow;
1078
+ var Sub = MenuSub;
1079
+ var SubTrigger = MenuSubTrigger;
1080
+ var SubContent = MenuSubContent;
1081
+ var ItemTitle = MenuItemTitle;
1082
+ var ItemSubtitle = MenuItemSubTitle;
1083
+ var ItemImage = MenuItemImage;
1084
+ var ItemIcon = MenuItemIcon;
1085
+ var Menu = withStaticProperties(MenuComp, {
1086
+ Anchor,
1087
+ Portal: Portal$1,
1088
+ Content,
1089
+ Group,
1090
+ Label,
1091
+ Item,
1092
+ CheckboxItem,
1093
+ RadioGroup,
1094
+ RadioItem,
1095
+ ItemIndicator,
1096
+ Separator,
1097
+ Arrow,
1098
+ Sub,
1099
+ SubTrigger,
1100
+ SubContent,
1101
+ ItemTitle,
1102
+ ItemSubtitle,
1103
+ ItemImage,
1104
+ ItemIcon
1105
+ });
1106
+ return { Menu };
1326
1107
  }
1327
1108
  function getOpenState(open) {
1328
- return open ? "open" : "closed";
1109
+ return open ? "open" : "closed";
1329
1110
  }
1330
1111
  function isIndeterminate(checked) {
1331
- return checked === "indeterminate";
1112
+ return checked === "indeterminate";
1332
1113
  }
1333
1114
  function getCheckedState(checked) {
1334
- return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
1115
+ return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
1335
1116
  }
1336
1117
  function focusFirst(candidates, options) {
1337
- var PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
1338
- var _iteratorNormalCompletion = true,
1339
- _didIteratorError = false,
1340
- _iteratorError = void 0;
1341
- try {
1342
- for (var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
1343
- var candidate = _step.value;
1344
- if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
1345
- candidate.focus({
1346
- preventScroll: true,
1347
- focusVisible: options === null || options === void 0 ? void 0 : options.focusVisible
1348
- });
1349
- if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
1350
- }
1351
- } catch (err) {
1352
- _didIteratorError = true;
1353
- _iteratorError = err;
1354
- } finally {
1355
- try {
1356
- if (!_iteratorNormalCompletion && _iterator.return != null) {
1357
- _iterator.return();
1358
- }
1359
- } finally {
1360
- if (_didIteratorError) {
1361
- throw _iteratorError;
1362
- }
1363
- }
1364
- }
1118
+ var PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
1119
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
1120
+ try {
1121
+ for (var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
1122
+ var candidate = _step.value;
1123
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
1124
+ candidate.focus({
1125
+ preventScroll: true,
1126
+ focusVisible: options === null || options === void 0 ? void 0 : options.focusVisible
1127
+ });
1128
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
1129
+ }
1130
+ } catch (err) {
1131
+ _didIteratorError = true;
1132
+ _iteratorError = err;
1133
+ } finally {
1134
+ try {
1135
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1136
+ _iterator.return();
1137
+ }
1138
+ } finally {
1139
+ if (_didIteratorError) {
1140
+ throw _iteratorError;
1141
+ }
1142
+ }
1143
+ }
1365
1144
  }
1366
1145
  function wrapArray(array, startIndex) {
1367
- return array.map(function (_, index) {
1368
- return array[(startIndex + index) % array.length];
1369
- });
1146
+ return array.map(function(_, index) {
1147
+ return array[(startIndex + index) % array.length];
1148
+ });
1370
1149
  }
1371
1150
  function getNextMatch(values, search, currentMatch) {
1372
- var isRepeated = search.length > 1 && Array.from(search).every(function (char) {
1373
- return char === search[0];
1374
- });
1375
- var normalizedSearch = isRepeated ? search[0] : search;
1376
- var currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
1377
- var wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0));
1378
- var excludeCurrentMatch = normalizedSearch.length === 1;
1379
- if (excludeCurrentMatch) wrappedValues = wrappedValues.filter(function (v) {
1380
- return v !== currentMatch;
1381
- });
1382
- var nextMatch = wrappedValues.find(function (value) {
1383
- return value.toLowerCase().startsWith(normalizedSearch.toLowerCase());
1384
- });
1385
- return nextMatch !== currentMatch ? nextMatch : void 0;
1151
+ var isRepeated = search.length > 1 && Array.from(search).every(function(char) {
1152
+ return char === search[0];
1153
+ });
1154
+ var normalizedSearch = isRepeated ? search[0] : search;
1155
+ var currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
1156
+ var wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0));
1157
+ var excludeCurrentMatch = normalizedSearch.length === 1;
1158
+ if (excludeCurrentMatch) wrappedValues = wrappedValues.filter(function(v) {
1159
+ return v !== currentMatch;
1160
+ });
1161
+ var nextMatch = wrappedValues.find(function(value) {
1162
+ return value.toLowerCase().startsWith(normalizedSearch.toLowerCase());
1163
+ });
1164
+ return nextMatch !== currentMatch ? nextMatch : void 0;
1386
1165
  }
1387
1166
  function isPointInPolygon(point, polygon) {
1388
- var {
1389
- x,
1390
- y
1391
- } = point;
1392
- var inside = false;
1393
- for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
1394
- var xi = polygon[i].x;
1395
- var yi = polygon[i].y;
1396
- var xj = polygon[j].x;
1397
- var yj = polygon[j].y;
1398
- var intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
1399
- if (intersect) inside = !inside;
1400
- }
1401
- return inside;
1167
+ var { x, y } = point;
1168
+ var inside = false;
1169
+ for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
1170
+ var xi = polygon[i].x;
1171
+ var yi = polygon[i].y;
1172
+ var xj = polygon[j].x;
1173
+ var yj = polygon[j].y;
1174
+ var intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
1175
+ if (intersect) inside = !inside;
1176
+ }
1177
+ return inside;
1402
1178
  }
1403
1179
  function isPointerInGraceArea(event, area) {
1404
- if (!area) return false;
1405
- var cursorPos = {
1406
- x: event.clientX,
1407
- y: event.clientY
1408
- };
1409
- return isPointInPolygon(cursorPos, area);
1180
+ if (!area) return false;
1181
+ var cursorPos = {
1182
+ x: event.clientX,
1183
+ y: event.clientY
1184
+ };
1185
+ return isPointInPolygon(cursorPos, area);
1410
1186
  }
1187
+
1411
1188
  export { createBaseMenu };
1412
1189
  //# sourceMappingURL=createBaseMenu.native.js.map