@tamagui/menu 1.138.0 → 1.138.1

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