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