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