@tamagui/create-menu 2.0.0-rc.8 → 2.0.0

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