@tamagui/menu 2.7.7 → 3.0.0-beta.1093.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/cjs/Menu.cjs +151 -174
  2. package/dist/cjs/Menu.native.cjs +180 -0
  3. package/dist/cjs/Menu.native.js +160 -182
  4. package/dist/cjs/Menu.native.js.map +1 -1
  5. package/dist/cjs/createNonNativeMenu.cjs +323 -369
  6. package/dist/cjs/createNonNativeMenu.native.cjs +367 -0
  7. package/dist/cjs/createNonNativeMenu.native.js +339 -389
  8. package/dist/cjs/createNonNativeMenu.native.js.map +1 -1
  9. package/dist/cjs/index.cjs +14 -29
  10. package/dist/cjs/index.native.cjs +28 -0
  11. package/dist/cjs/index.native.js +15 -29
  12. package/dist/cjs/index.native.js.map +1 -1
  13. package/dist/esm/Menu.mjs +136 -148
  14. package/dist/esm/Menu.mjs.map +1 -1
  15. package/dist/esm/Menu.native.js +146 -158
  16. package/dist/esm/Menu.native.js.map +1 -1
  17. package/dist/esm/createNonNativeMenu.mjs +308 -345
  18. package/dist/esm/createNonNativeMenu.mjs.map +1 -1
  19. package/dist/esm/createNonNativeMenu.native.js +325 -367
  20. package/dist/esm/createNonNativeMenu.native.js.map +1 -1
  21. package/dist/esm/index.js +3 -12
  22. package/dist/esm/index.js.map +1 -1
  23. package/dist/esm/index.mjs +3 -12
  24. package/dist/esm/index.mjs.map +1 -1
  25. package/dist/esm/index.native.js +3 -12
  26. package/dist/esm/index.native.js.map +1 -1
  27. package/dist/jsx/Menu.mjs +136 -148
  28. package/dist/jsx/Menu.mjs.map +1 -1
  29. package/dist/jsx/Menu.native.cjs +180 -0
  30. package/dist/jsx/Menu.native.js +160 -182
  31. package/dist/jsx/Menu.native.js.map +1 -1
  32. package/dist/jsx/createNonNativeMenu.mjs +308 -345
  33. package/dist/jsx/createNonNativeMenu.mjs.map +1 -1
  34. package/dist/jsx/createNonNativeMenu.native.cjs +367 -0
  35. package/dist/jsx/createNonNativeMenu.native.js +339 -389
  36. package/dist/jsx/createNonNativeMenu.native.js.map +1 -1
  37. package/dist/jsx/index.js +3 -12
  38. package/dist/jsx/index.js.map +1 -1
  39. package/dist/jsx/index.mjs +3 -12
  40. package/dist/jsx/index.mjs.map +1 -1
  41. package/dist/jsx/index.native.cjs +28 -0
  42. package/dist/jsx/index.native.js +15 -29
  43. package/dist/jsx/index.native.js.map +1 -1
  44. package/package.json +13 -11
  45. package/src/Menu.tsx +3 -7
  46. package/src/createNonNativeMenu.tsx +55 -49
  47. package/src/index.tsx +1 -13
  48. package/types/Menu.d.ts +88 -75
  49. package/types/Menu.d.ts.map +1 -1
  50. package/types/createNonNativeMenu.d.ts +75 -111
  51. package/types/createNonNativeMenu.d.ts.map +1 -1
  52. package/types/index.d.ts +87 -73
  53. package/types/index.d.ts.map +1 -1
@@ -5,38 +5,32 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __getProtoOf = Object.getPrototypeOf;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
7
  var __export = (target, all) => {
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: true
11
- });
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
12
  };
13
13
  var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
- get: () => from[key],
17
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
- });
19
- }
20
- return to;
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: () => from[key],
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
21
  };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
- // If the importer is in node compatibility mode or this is not an ESM
24
- // file that has been converted to a CommonJS file using a Babel-
25
- // compatible transform (i.e. "__esModule" has not been set), then set
26
- // "default" to the CommonJS "module.exports" for node compatibility.
27
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
- value: mod,
29
- enumerable: true
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
30
25
  }) : target, mod));
31
- var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
32
- value: true
33
- }), mod);
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
27
  var createNonNativeMenu_exports = {};
35
28
  __export(createNonNativeMenu_exports, {
36
- DROPDOWN_MENU_CONTEXT: () => DROPDOWN_MENU_CONTEXT,
37
- createNonNativeMenu: () => createNonNativeMenu
29
+ DROPDOWN_MENU_CONTEXT: () => DROPDOWN_MENU_CONTEXT,
30
+ createNonNativeMenu: () => createNonNativeMenu
38
31
  });
39
32
  module.exports = __toCommonJS(createNonNativeMenu_exports);
33
+ var import_core = require("@tamagui/core");
40
34
  var import_create_menu = require("@tamagui/create-menu");
41
35
  var import_popper = require("@tamagui/popper");
42
36
  var import_scroll_view = require("@tamagui/scroll-view");
@@ -47,349 +41,309 @@ var import_react = require("react");
47
41
  var import_jsx_runtime = require("react/jsx-runtime");
48
42
  const DROPDOWN_MENU_CONTEXT = "MenuContext";
49
43
  function useMenuTriggerSetup(open) {
50
- const triggerStateSettersRef = React.useRef(/* @__PURE__ */new Map());
51
- const activeTriggerIdRef = React.useRef(null);
52
- const setActiveTrigger = (0, import_web.useEvent)(id => {
53
- const prevId = activeTriggerIdRef.current;
54
- if (prevId === id) return;
55
- if (prevId) {
56
- triggerStateSettersRef.current.get(prevId)?.(false);
57
- }
58
- activeTriggerIdRef.current = id;
59
- if (id && open) {
60
- triggerStateSettersRef.current.get(id)?.(true);
61
- }
62
- });
63
- const registerTrigger = (0, import_web.useEvent)((id, setOpenState) => {
64
- triggerStateSettersRef.current.set(id, setOpenState);
65
- setOpenState(activeTriggerIdRef.current === id && open);
66
- });
67
- const unregisterTrigger = (0, import_web.useEvent)(id => {
68
- triggerStateSettersRef.current.delete(id);
69
- if (activeTriggerIdRef.current === id) {
70
- activeTriggerIdRef.current = null;
71
- }
72
- });
73
- React.useEffect(() => {
74
- if (!open) {
75
- setActiveTrigger(null);
76
- return;
77
- }
78
- const activeId = activeTriggerIdRef.current;
79
- if (activeId) {
80
- triggerStateSettersRef.current.get(activeId)?.(true);
81
- }
82
- }, [open, setActiveTrigger]);
83
- return {
84
- setActiveTrigger,
85
- registerTrigger,
86
- unregisterTrigger
87
- };
44
+ const triggerStateSettersRef = React.useRef(/* @__PURE__ */ new Map());
45
+ const activeTriggerIdRef = React.useRef(null);
46
+ const setActiveTrigger = (0, import_web.useEvent)((id) => {
47
+ const prevId = activeTriggerIdRef.current;
48
+ if (prevId === id) return;
49
+ if (prevId) {
50
+ triggerStateSettersRef.current.get(prevId)?.(false);
51
+ }
52
+ activeTriggerIdRef.current = id;
53
+ if (id && open) {
54
+ triggerStateSettersRef.current.get(id)?.(true);
55
+ }
56
+ });
57
+ const registerTrigger = (0, import_web.useEvent)((id, setOpenState) => {
58
+ triggerStateSettersRef.current.set(id, setOpenState);
59
+ setOpenState(activeTriggerIdRef.current === id && open);
60
+ });
61
+ const unregisterTrigger = (0, import_web.useEvent)((id) => {
62
+ triggerStateSettersRef.current.delete(id);
63
+ if (activeTriggerIdRef.current === id) {
64
+ activeTriggerIdRef.current = null;
65
+ }
66
+ });
67
+ React.useEffect(() => {
68
+ if (!open) {
69
+ setActiveTrigger(null);
70
+ return;
71
+ }
72
+ const activeId = activeTriggerIdRef.current;
73
+ if (activeId) {
74
+ triggerStateSettersRef.current.get(activeId)?.(true);
75
+ }
76
+ }, [open, setActiveTrigger]);
77
+ return {
78
+ setActiveTrigger,
79
+ registerTrigger,
80
+ unregisterTrigger
81
+ };
82
+ }
83
+ function createNonNativeMenu() {
84
+ const { Menu } = (0, import_create_menu.createBaseMenu)();
85
+ const DROPDOWN_MENU_NAME = "Menu";
86
+ const { Provider: MenuProvider, useStyledContext: useMenuContext } = (0, import_web.createStyledContext)();
87
+ const MenuComp = (props) => {
88
+ const { scope, children, dir, open: openProp, defaultOpen, onOpenChange, modal = true, ...rest } = props;
89
+ const triggerRef = React.useRef(null);
90
+ const [open = false, setOpen] = (0, import_use_controllable_state.useControllableState)({
91
+ prop: openProp,
92
+ defaultProp: defaultOpen,
93
+ onChange: onOpenChange
94
+ });
95
+ const openRef = React.useRef(open);
96
+ openRef.current = open;
97
+ const { setActiveTrigger, registerTrigger, unregisterTrigger } = useMenuTriggerSetup(open);
98
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuProvider, {
99
+ scope,
100
+ triggerId: (0, import_react.useId)(),
101
+ triggerRef,
102
+ contentId: (0, import_react.useId)(),
103
+ openRef,
104
+ onOpenChange: React.useCallback((nextOpen) => setOpen(nextOpen), [setOpen]),
105
+ onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
106
+ modal,
107
+ setActiveTrigger,
108
+ registerTrigger,
109
+ unregisterTrigger,
110
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu, {
111
+ scope: scope || DROPDOWN_MENU_CONTEXT,
112
+ open,
113
+ onOpenChange: setOpen,
114
+ dir,
115
+ modal,
116
+ ...rest,
117
+ children
118
+ })
119
+ });
120
+ };
121
+ MenuComp.displayName = DROPDOWN_MENU_NAME;
122
+ const TRIGGER_NAME = "MenuTrigger";
123
+ const MenuTriggerFrame = Menu.Anchor;
124
+ const MenuTrigger = (0, import_core.createStyledHOC)(import_web.View, (props, forwardedRef) => {
125
+ const { scope, asChild, children, disabled = false, onKeydown, onKeyDown = onKeydown, ...triggerProps } = props;
126
+ const context = useMenuContext(scope);
127
+ const popperCtx = (0, import_popper.usePopperContextSlow)(scope || DROPDOWN_MENU_CONTEXT);
128
+ const Comp = asChild ? import_web.Slot : import_web.View;
129
+ const isTouchDevice = (0, import_web.useIsTouchDevice)();
130
+ const triggerElRef = React.useRef(null);
131
+ const triggerId = React.useId();
132
+ const [triggerOpen, setTriggerOpen] = React.useState(false);
133
+ const { registerTrigger, unregisterTrigger } = context;
134
+ React.useEffect(() => {
135
+ registerTrigger(triggerId, setTriggerOpen);
136
+ return () => unregisterTrigger(triggerId);
137
+ }, [
138
+ registerTrigger,
139
+ unregisterTrigger,
140
+ triggerId
141
+ ]);
142
+ const activateSelf = React.useCallback(() => {
143
+ context.setActiveTrigger(triggerId);
144
+ const el = triggerElRef.current;
145
+ if (el) {
146
+ context.triggerRef.current = el;
147
+ if (el instanceof HTMLElement) {
148
+ popperCtx.refs?.setReference(el);
149
+ requestAnimationFrame(() => popperCtx.update?.());
150
+ }
151
+ }
152
+ }, [
153
+ context,
154
+ triggerId,
155
+ popperCtx
156
+ ]);
157
+ const pressEvent = import_web.isWeb ? isTouchDevice ? "onClick" : "onPointerDown" : "onPress";
158
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuTriggerFrame, {
159
+ asChild: true,
160
+ className: `is_${TRIGGER_NAME}`,
161
+ scope: scope || DROPDOWN_MENU_CONTEXT,
162
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comp, {
163
+ role: "button",
164
+ id: context.triggerId,
165
+ "aria-haspopup": "menu",
166
+ "aria-expanded": triggerOpen,
167
+ "aria-controls": triggerOpen ? context.contentId : void 0,
168
+ "data-state": triggerOpen ? "open" : "closed",
169
+ "data-disabled": disabled ? "" : void 0,
170
+ "aria-disabled": disabled || void 0,
171
+ ref: (0, import_web.composeRefs)(forwardedRef, context.triggerRef, triggerElRef),
172
+ ...triggerProps,
173
+ ...{ [pressEvent]: (0, import_web.composeEventHandlers)(props[pressEvent], (event) => {
174
+ if (!disabled) {
175
+ if (import_web.isWeb && event instanceof PointerEvent && event.button !== 0 && event.ctrlKey === true) return;
176
+ if (context.openRef.current) {
177
+ context.setActiveTrigger(null);
178
+ } else {
179
+ activateSelf();
180
+ }
181
+ context.onOpenToggle();
182
+ if (!context.openRef.current) event.preventDefault();
183
+ }
184
+ }) },
185
+ ...import_web.isWeb && { onKeyDown: (0, import_web.composeEventHandlers)(onKeyDown, (event) => {
186
+ if (disabled) return;
187
+ if (["Enter", " "].includes(event.key)) {
188
+ if (context.openRef.current) {
189
+ context.setActiveTrigger(null);
190
+ } else {
191
+ activateSelf();
192
+ }
193
+ context.onOpenToggle();
194
+ }
195
+ if (event.key === "ArrowDown") {
196
+ activateSelf();
197
+ context.onOpenChange(true);
198
+ }
199
+ if ([
200
+ "Enter",
201
+ " ",
202
+ "ArrowDown"
203
+ ].includes(event.key)) event.preventDefault();
204
+ }) },
205
+ children
206
+ })
207
+ });
208
+ });
209
+ MenuTrigger.displayName = TRIGGER_NAME;
210
+ const PORTAL_NAME = "MenuPortal";
211
+ const MenuPortal = (props) => {
212
+ const { scope, children, ...portalProps } = props;
213
+ const context = import_web.isAndroid ? useMenuContext(scope) : null;
214
+ const content = import_web.isAndroid ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuProvider, {
215
+ ...context,
216
+ children
217
+ }) : children;
218
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Portal, {
219
+ scope: scope || DROPDOWN_MENU_CONTEXT,
220
+ ...portalProps,
221
+ children: content
222
+ });
223
+ };
224
+ MenuPortal.displayName = PORTAL_NAME;
225
+ const CONTENT_NAME = "MenuContent";
226
+ const MenuContent = (0, import_core.createStyledHOC)(Menu.Content, (props, forwardedRef) => {
227
+ const { scope, ...contentProps } = props;
228
+ const context = useMenuContext(scope);
229
+ const hasInteractedOutsideRef = React.useRef(false);
230
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Content, {
231
+ id: context.contentId,
232
+ "aria-labelledby": context.triggerId,
233
+ scope: scope || DROPDOWN_MENU_CONTEXT,
234
+ ...contentProps,
235
+ ref: forwardedRef,
236
+ onCloseAutoFocus: (0, import_web.composeEventHandlers)(props.onCloseAutoFocus, (event) => {
237
+ if (!hasInteractedOutsideRef.current) {
238
+ requestAnimationFrame(() => {
239
+ const activeEl = document.activeElement;
240
+ if (!activeEl || activeEl === document.body) {
241
+ context.triggerRef.current?.focus();
242
+ }
243
+ });
244
+ }
245
+ hasInteractedOutsideRef.current = false;
246
+ event.cancel();
247
+ }),
248
+ onInteractOutside: (0, import_web.composeEventHandlers)(props.onInteractOutside, (event) => {
249
+ if (event.interaction !== "pointer" || !event.event) return;
250
+ const originalEvent = event.event;
251
+ const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
252
+ const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
253
+ if (!context.modal || isRightClick) hasInteractedOutsideRef.current = true;
254
+ }),
255
+ style: import_web.isWeb ? {
256
+ ...props.style,
257
+ ...{
258
+ "--tamagui-menu-content-transform-origin": "var(--tamagui-popper-transform-origin)",
259
+ "--tamagui-menu-content-available-width": "var(--tamagui-popper-available-width)",
260
+ "--tamagui-menu-content-available-height": "var(--tamagui-popper-available-height)",
261
+ "--tamagui-menu-trigger-width": "var(--tamagui-popper-anchor-width)",
262
+ "--tamagui-menu-trigger-height": "var(--tamagui-popper-anchor-height)"
263
+ }
264
+ } : props.style
265
+ });
266
+ });
267
+ MenuContent.displayName = CONTENT_NAME;
268
+ const DROPDOWN_MENU_SUB_NAME = "MenuSub";
269
+ const MenuSub = (props) => {
270
+ const { scope, children, open: openProp, onOpenChange, defaultOpen, ...rest } = props;
271
+ const [open = false, setOpen] = (0, import_use_controllable_state.useControllableState)({
272
+ prop: openProp,
273
+ defaultProp: defaultOpen,
274
+ onChange: onOpenChange
275
+ });
276
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Sub, {
277
+ scope: scope || DROPDOWN_MENU_CONTEXT,
278
+ open,
279
+ onOpenChange: setOpen,
280
+ ...rest,
281
+ children
282
+ });
283
+ };
284
+ MenuSub.displayName = DROPDOWN_MENU_SUB_NAME;
285
+ const SUB_CONTENT_NAME = "MenuSubContent";
286
+ const MenuSubContent = (0, import_core.createStyledHOC)(Menu.SubContent, (props, forwardedRef) => {
287
+ const { scope, ...subContentProps } = props;
288
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.SubContent, {
289
+ scope: scope || DROPDOWN_MENU_CONTEXT,
290
+ ...subContentProps,
291
+ ref: forwardedRef,
292
+ style: import_web.isWeb ? {
293
+ ...props.style,
294
+ ...{
295
+ "--tamagui-menu-content-transform-origin": "var(--tamagui-popper-transform-origin)",
296
+ "--tamagui-menu-content-available-width": "var(--tamagui-popper-available-width)",
297
+ "--tamagui-menu-content-available-height": "var(--tamagui-popper-available-height)",
298
+ "--tamagui-menu-trigger-width": "var(--tamagui-popper-anchor-width)",
299
+ "--tamagui-menu-trigger-height": "var(--tamagui-popper-anchor-height)"
300
+ }
301
+ } : null
302
+ });
303
+ });
304
+ MenuSubContent.displayName = SUB_CONTENT_NAME;
305
+ const MenuScrollView = (0, import_web.styled)(import_scroll_view.ScrollView, {
306
+ flexShrink: 1,
307
+ alignSelf: "stretch",
308
+ maxHeight: "web:var(--tamagui-menu-content-available-height)",
309
+ showsHorizontalScrollIndicator: false,
310
+ showsVerticalScrollIndicator: false
311
+ });
312
+ const Group = Menu.Group;
313
+ const Label = Menu.Label;
314
+ const Item = Menu.Item;
315
+ const CheckboxItem = Menu.CheckboxItem;
316
+ const RadioGroup = Menu.RadioGroup;
317
+ const RadioItem = Menu.RadioItem;
318
+ const ItemIndicator = Menu.ItemIndicator;
319
+ const Separator = Menu.Separator;
320
+ const Arrow = Menu.Arrow;
321
+ const SubTrigger = Menu.SubTrigger;
322
+ const ItemTitle = Menu.ItemTitle;
323
+ const ItemSubtitle = Menu.ItemSubtitle;
324
+ const ItemImage = Menu.ItemImage;
325
+ const ItemIcon = Menu.ItemIcon;
326
+ return (0, import_web.withStaticProperties)(MenuComp, {
327
+ Root: MenuComp,
328
+ Trigger: MenuTrigger,
329
+ Portal: MenuPortal,
330
+ Content: MenuContent,
331
+ Group,
332
+ Label,
333
+ Item,
334
+ CheckboxItem,
335
+ RadioGroup,
336
+ RadioItem,
337
+ ItemIndicator,
338
+ Separator,
339
+ Arrow,
340
+ Sub: MenuSub,
341
+ SubTrigger,
342
+ SubContent: MenuSubContent,
343
+ ItemTitle,
344
+ ItemSubtitle,
345
+ ItemImage,
346
+ ItemIcon,
347
+ ScrollView: MenuScrollView
348
+ });
88
349
  }
89
- function createNonNativeMenu(params) {
90
- const {
91
- Menu
92
- } = (0, import_create_menu.createBaseMenu)(params);
93
- const DROPDOWN_MENU_NAME = "Menu";
94
- const {
95
- Provider: MenuProvider,
96
- useStyledContext: useMenuContext
97
- } = (0, import_web.createStyledContext)();
98
- const MenuComp = props => {
99
- const {
100
- scope,
101
- children,
102
- dir,
103
- open: openProp,
104
- defaultOpen,
105
- onOpenChange,
106
- modal = true,
107
- ...rest
108
- } = props;
109
- const triggerRef = React.useRef(null);
110
- const [open = false, setOpen] = (0, import_use_controllable_state.useControllableState)({
111
- prop: openProp,
112
- defaultProp: defaultOpen,
113
- onChange: onOpenChange
114
- });
115
- const openRef = React.useRef(open);
116
- openRef.current = open;
117
- const {
118
- setActiveTrigger,
119
- registerTrigger,
120
- unregisterTrigger
121
- } = useMenuTriggerSetup(open);
122
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuProvider, {
123
- scope,
124
- triggerId: (0, import_react.useId)(),
125
- triggerRef,
126
- contentId: (0, import_react.useId)(),
127
- openRef,
128
- onOpenChange: React.useCallback(nextOpen => setOpen(nextOpen), [setOpen]),
129
- onOpenToggle: React.useCallback(() => setOpen(prevOpen => !prevOpen), [setOpen]),
130
- modal,
131
- setActiveTrigger,
132
- registerTrigger,
133
- unregisterTrigger,
134
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(Menu, {
135
- scope: scope || DROPDOWN_MENU_CONTEXT,
136
- open,
137
- onOpenChange: setOpen,
138
- dir,
139
- modal,
140
- ...rest,
141
- children
142
- })
143
- });
144
- };
145
- MenuComp.displayName = DROPDOWN_MENU_NAME;
146
- const TRIGGER_NAME = "MenuTrigger";
147
- const MenuTriggerFrame = Menu.Anchor;
148
- const MenuTrigger = import_web.View.styleable((props, forwardedRef) => {
149
- const {
150
- scope,
151
- asChild,
152
- children,
153
- disabled = false,
154
- onKeydown,
155
- ...triggerProps
156
- } = props;
157
- const context = useMenuContext(scope);
158
- const popperCtx = (0, import_popper.usePopperContextSlow)(scope || DROPDOWN_MENU_CONTEXT);
159
- const Comp = asChild ? import_web.Slot : import_web.View;
160
- const isTouchDevice = (0, import_web.useIsTouchDevice)();
161
- const triggerElRef = React.useRef(null);
162
- const triggerId = React.useId();
163
- const [triggerOpen, setTriggerOpen] = React.useState(false);
164
- const {
165
- registerTrigger,
166
- unregisterTrigger
167
- } = context;
168
- React.useEffect(() => {
169
- registerTrigger(triggerId, setTriggerOpen);
170
- return () => unregisterTrigger(triggerId);
171
- }, [registerTrigger, unregisterTrigger, triggerId]);
172
- const activateSelf = React.useCallback(() => {
173
- context.setActiveTrigger(triggerId);
174
- const el = triggerElRef.current;
175
- if (el) {
176
- context.triggerRef.current = el;
177
- if (el instanceof HTMLElement) {
178
- popperCtx.refs?.setReference(el);
179
- requestAnimationFrame(() => popperCtx.update?.());
180
- }
181
- }
182
- }, [context, triggerId, popperCtx]);
183
- const pressEvent = import_web.isWeb ? isTouchDevice ? "onClick" : "onPointerDown" : "onPress";
184
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuTriggerFrame, {
185
- asChild: true,
186
- componentName: TRIGGER_NAME,
187
- scope: scope || DROPDOWN_MENU_CONTEXT,
188
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(Comp, {
189
- role: "button",
190
- id: context.triggerId,
191
- "aria-haspopup": "menu",
192
- "aria-expanded": triggerOpen,
193
- "aria-controls": triggerOpen ? context.contentId : void 0,
194
- "data-state": triggerOpen ? "open" : "closed",
195
- "data-disabled": disabled ? "" : void 0,
196
- "aria-disabled": disabled || void 0,
197
- ref: (0, import_web.composeRefs)(forwardedRef, context.triggerRef, triggerElRef),
198
- ...{
199
- [pressEvent]: (0, import_web.composeEventHandlers)(
200
- //@ts-ignore
201
- props[pressEvent], event => {
202
- if (!disabled) {
203
- if (import_web.isWeb && event instanceof PointerEvent && event.button !== 0 && event.ctrlKey === true) return;
204
- if (context.openRef.current) {
205
- context.setActiveTrigger(null);
206
- } else {
207
- activateSelf();
208
- }
209
- context.onOpenToggle();
210
- if (!context.openRef.current) event.preventDefault();
211
- }
212
- })
213
- },
214
- ...(import_web.isWeb && {
215
- onKeyDown: (0, import_web.composeEventHandlers)(onKeydown, event => {
216
- if (disabled) return;
217
- if (["Enter", " "].includes(event.key)) {
218
- if (context.openRef.current) {
219
- context.setActiveTrigger(null);
220
- } else {
221
- activateSelf();
222
- }
223
- context.onOpenToggle();
224
- }
225
- if (event.key === "ArrowDown") {
226
- activateSelf();
227
- context.onOpenChange(true);
228
- }
229
- if (["Enter", " ", "ArrowDown"].includes(event.key)) event.preventDefault();
230
- })
231
- }),
232
- ...triggerProps,
233
- children
234
- })
235
- });
236
- });
237
- MenuTrigger.displayName = TRIGGER_NAME;
238
- const PORTAL_NAME = "MenuPortal";
239
- const MenuPortal = props => {
240
- const {
241
- scope,
242
- children,
243
- ...portalProps
244
- } = props;
245
- const context = import_web.isAndroid ? useMenuContext(scope) : null;
246
- const content = import_web.isAndroid ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(MenuProvider, {
247
- ...context,
248
- children
249
- }) : children;
250
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Menu.Portal, {
251
- scope: scope || DROPDOWN_MENU_CONTEXT,
252
- ...portalProps,
253
- children: content
254
- });
255
- };
256
- MenuPortal.displayName = PORTAL_NAME;
257
- const CONTENT_NAME = "MenuContent";
258
- const MenuContent = React.forwardRef((props, forwardedRef) => {
259
- const {
260
- scope,
261
- ...contentProps
262
- } = props;
263
- const context = useMenuContext(scope);
264
- const hasInteractedOutsideRef = React.useRef(false);
265
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Menu.Content, {
266
- id: context.contentId,
267
- "aria-labelledby": context.triggerId,
268
- scope: scope || DROPDOWN_MENU_CONTEXT,
269
- ...contentProps,
270
- ref: forwardedRef,
271
- onCloseAutoFocus: (0, import_web.composeEventHandlers)(props.onCloseAutoFocus, event => {
272
- if (!hasInteractedOutsideRef.current) {
273
- requestAnimationFrame(() => {
274
- const activeEl = document.activeElement;
275
- if (!activeEl || activeEl === document.body) {
276
- context.triggerRef.current?.focus();
277
- }
278
- });
279
- }
280
- hasInteractedOutsideRef.current = false;
281
- event.preventDefault();
282
- }),
283
- onInteractOutside: (0, import_web.composeEventHandlers)(props.onInteractOutside, event => {
284
- const originalEvent = event.detail.originalEvent;
285
- const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
286
- const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
287
- if (!context.modal || isRightClick) hasInteractedOutsideRef.current = true;
288
- }),
289
- style: import_web.isWeb ? {
290
- ...props.style,
291
- ...{
292
- "--tamagui-menu-content-transform-origin": "var(--tamagui-popper-transform-origin)",
293
- "--tamagui-menu-content-available-width": "var(--tamagui-popper-available-width)",
294
- "--tamagui-menu-content-available-height": "var(--tamagui-popper-available-height)",
295
- "--tamagui-menu-trigger-width": "var(--tamagui-popper-anchor-width)",
296
- "--tamagui-menu-trigger-height": "var(--tamagui-popper-anchor-height)"
297
- }
298
- } : props.style
299
- });
300
- });
301
- MenuContent.displayName = CONTENT_NAME;
302
- const DROPDOWN_MENU_SUB_NAME = "MenuSub";
303
- const MenuSub = props => {
304
- const {
305
- scope,
306
- children,
307
- open: openProp,
308
- onOpenChange,
309
- defaultOpen,
310
- ...rest
311
- } = props;
312
- const [open = false, setOpen] = (0, import_use_controllable_state.useControllableState)({
313
- prop: openProp,
314
- defaultProp: defaultOpen,
315
- onChange: onOpenChange
316
- });
317
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Menu.Sub, {
318
- scope: scope || DROPDOWN_MENU_CONTEXT,
319
- open,
320
- onOpenChange: setOpen,
321
- ...rest,
322
- children
323
- });
324
- };
325
- MenuSub.displayName = DROPDOWN_MENU_SUB_NAME;
326
- const SUB_CONTENT_NAME = "MenuSubContent";
327
- const MenuSubContent = React.forwardRef((props, forwardedRef) => {
328
- const {
329
- scope,
330
- ...subContentProps
331
- } = props;
332
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Menu.SubContent, {
333
- scope: scope || DROPDOWN_MENU_CONTEXT,
334
- ...subContentProps,
335
- ref: forwardedRef,
336
- style: import_web.isWeb ? {
337
- ...props.style,
338
- ...{
339
- "--tamagui-menu-content-transform-origin": "var(--tamagui-popper-transform-origin)",
340
- "--tamagui-menu-content-available-width": "var(--tamagui-popper-available-width)",
341
- "--tamagui-menu-content-available-height": "var(--tamagui-popper-available-height)",
342
- "--tamagui-menu-trigger-width": "var(--tamagui-popper-anchor-width)",
343
- "--tamagui-menu-trigger-height": "var(--tamagui-popper-anchor-height)"
344
- }
345
- } : null
346
- });
347
- });
348
- MenuSubContent.displayName = SUB_CONTENT_NAME;
349
- const MenuScrollView = (0, import_web.styled)(import_scroll_view.ScrollView, {
350
- flexShrink: 1,
351
- alignSelf: "stretch",
352
- showsHorizontalScrollIndicator: false,
353
- showsVerticalScrollIndicator: false,
354
- "$platform-web": {
355
- maxHeight: "var(--tamagui-menu-content-available-height)"
356
- }
357
- });
358
- const Group = Menu.Group;
359
- const Label = Menu.Label;
360
- const Item = Menu.Item;
361
- const CheckboxItem = Menu.CheckboxItem;
362
- const RadioGroup = Menu.RadioGroup;
363
- const RadioItem = Menu.RadioItem;
364
- const ItemIndicator = Menu.ItemIndicator;
365
- const Separator = Menu.Separator;
366
- const Arrow = Menu.Arrow;
367
- const SubTrigger = Menu.SubTrigger;
368
- const ItemTitle = Menu.ItemTitle;
369
- const ItemSubtitle = Menu.ItemSubtitle;
370
- const ItemImage = Menu.ItemImage;
371
- const ItemIcon = Menu.ItemIcon;
372
- return (0, import_web.withStaticProperties)(MenuComp, {
373
- Root: MenuComp,
374
- Trigger: MenuTrigger,
375
- Portal: MenuPortal,
376
- Content: MenuContent,
377
- Group,
378
- Label,
379
- Item,
380
- CheckboxItem,
381
- RadioGroup,
382
- RadioItem,
383
- ItemIndicator,
384
- Separator,
385
- Arrow,
386
- Sub: MenuSub,
387
- SubTrigger,
388
- SubContent: MenuSubContent,
389
- ItemTitle,
390
- ItemSubtitle,
391
- ItemImage,
392
- ItemIcon,
393
- ScrollView: MenuScrollView
394
- });
395
- }