@tamagui/create-menu 2.0.0-rc.4 → 2.0.0-rc.40

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