@tamagui/context-menu 2.7.7 → 3.0.0-beta.637.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/ContextMenu.cjs +152 -166
  2. package/dist/cjs/ContextMenu.native.cjs +178 -0
  3. package/dist/cjs/ContextMenu.native.js +157 -170
  4. package/dist/cjs/ContextMenu.native.js.map +1 -1
  5. package/dist/cjs/createNonNativeContextMenu.cjs +358 -422
  6. package/dist/cjs/createNonNativeContextMenu.native.cjs +405 -0
  7. package/dist/cjs/createNonNativeContextMenu.native.js +380 -443
  8. package/dist/cjs/createNonNativeContextMenu.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/ContextMenu.mjs +136 -140
  14. package/dist/esm/ContextMenu.mjs.map +1 -1
  15. package/dist/esm/ContextMenu.native.js +141 -145
  16. package/dist/esm/ContextMenu.native.js.map +1 -1
  17. package/dist/esm/createNonNativeContextMenu.mjs +342 -398
  18. package/dist/esm/createNonNativeContextMenu.mjs.map +1 -1
  19. package/dist/esm/createNonNativeContextMenu.native.js +365 -421
  20. package/dist/esm/createNonNativeContextMenu.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/ContextMenu.mjs +136 -140
  28. package/dist/jsx/ContextMenu.mjs.map +1 -1
  29. package/dist/jsx/ContextMenu.native.cjs +178 -0
  30. package/dist/jsx/ContextMenu.native.js +157 -170
  31. package/dist/jsx/ContextMenu.native.js.map +1 -1
  32. package/dist/jsx/createNonNativeContextMenu.mjs +342 -398
  33. package/dist/jsx/createNonNativeContextMenu.mjs.map +1 -1
  34. package/dist/jsx/createNonNativeContextMenu.native.cjs +405 -0
  35. package/dist/jsx/createNonNativeContextMenu.native.js +380 -443
  36. package/dist/jsx/createNonNativeContextMenu.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 +9 -7
  45. package/src/ContextMenu.tsx +2 -3
  46. package/src/createNonNativeContextMenu.tsx +131 -104
  47. package/src/index.tsx +1 -13
  48. package/types/ContextMenu.d.ts +85 -76
  49. package/types/ContextMenu.d.ts.map +1 -1
  50. package/types/createNonNativeContextMenu.d.ts +77 -107
  51. package/types/createNonNativeContextMenu.d.ts.map +1 -1
  52. package/types/index.d.ts +84 -74
  53. package/types/index.d.ts.map +1 -1
@@ -0,0 +1,405 @@
1
+ "use strict";
2
+
3
+
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __export = (target, all) => {
11
+ for (var name in all) __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
19
+ get: () => from[key],
20
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
21
+ });
22
+ }
23
+ return to;
24
+ };
25
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
26
+ value: mod,
27
+ enumerable: true
28
+ }) : target, mod));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var createNonNativeContextMenu_exports = {};
31
+ __export(createNonNativeContextMenu_exports, {
32
+ CONTEXTMENU_CONTEXT: () => CONTEXTMENU_CONTEXT,
33
+ createNonNativeContextMenu: () => createNonNativeContextMenu
34
+ });
35
+ module.exports = __toCommonJS(createNonNativeContextMenu_exports);
36
+ var import_jsx_runtime = require("react/jsx-runtime");
37
+ var import_compose_refs = require("@tamagui/compose-refs");
38
+ var import_create_menu = require("@tamagui/create-menu");
39
+ var import_use_controllable_state = require("@tamagui/use-controllable-state");
40
+ var import_web = require("@tamagui/web");
41
+ var import_react = __toESM(require("react"), 1);
42
+ function _instanceof(left, right) {
43
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
44
+ return !!right[Symbol.hasInstance](left);
45
+ } else {
46
+ return left instanceof right;
47
+ }
48
+ }
49
+ var CONTEXTMENU_CONTEXT = "ContextMenuContext";
50
+ function createNonNativeContextMenu() {
51
+ var { Menu } = (0, import_create_menu.createBaseMenu)();
52
+ var CONTEXT_MENU_NAME = "ContextMenu";
53
+ var { Provider: ContextMenuProvider, useStyledContext: useContextMenuContext } = (0, import_web.createStyledContext)();
54
+ var ContextMenuComp = function(props) {
55
+ var { scope, children, onOpenChange, open: openProp, defaultOpen, dir, modal = true, ...rest } = props;
56
+ var [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
57
+ prop: openProp,
58
+ defaultProp: defaultOpen !== null && defaultOpen !== void 0 ? defaultOpen : false
59
+ });
60
+ var triggerRef = import_react.default.useRef(null);
61
+ var handleOpenChange = import_react.default.useCallback(function(open2, event) {
62
+ onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(open2, event);
63
+ if (event === null || event === void 0 ? void 0 : event.defaultPrevented) return;
64
+ setOpen(open2);
65
+ }, [onOpenChange, setOpen]);
66
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuProvider, {
67
+ scope,
68
+ triggerId: (0, import_react.useId)(),
69
+ triggerRef,
70
+ contentId: (0, import_react.useId)(),
71
+ open,
72
+ onOpenChange: handleOpenChange,
73
+ modal,
74
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu, {
75
+ scope: scope || CONTEXTMENU_CONTEXT,
76
+ dir,
77
+ open,
78
+ onOpenChange: handleOpenChange,
79
+ modal,
80
+ ...rest,
81
+ children
82
+ })
83
+ });
84
+ };
85
+ ContextMenuComp.displayName = CONTEXT_MENU_NAME;
86
+ var TRIGGER_NAME = "ContextMenuTrigger";
87
+ var ContextMenuTrigger = (0, import_web.createStyledHOC)(import_web.View, function(props, forwardedRef) {
88
+ var { scope, style, className, disabled = false, asChild, children, ...triggerProps } = props;
89
+ var context = useContextMenuContext(scope);
90
+ var pointRef = import_react.default.useRef({
91
+ x: 0,
92
+ y: 0
93
+ });
94
+ var virtualRef = import_react.default.useMemo(function() {
95
+ return { current: {
96
+ getBoundingClientRect: function() {
97
+ if (import_web.isWeb) {
98
+ var scrollX = window.scrollX || document.documentElement.scrollLeft;
99
+ var scrollY = window.scrollY || document.documentElement.scrollTop;
100
+ return DOMRect.fromRect({
101
+ width: 0,
102
+ height: 0,
103
+ x: pointRef.current.x - scrollX,
104
+ y: pointRef.current.y - scrollY
105
+ });
106
+ }
107
+ return {
108
+ width: 0,
109
+ height: 0,
110
+ top: 0,
111
+ left: 0,
112
+ ...pointRef.current
113
+ };
114
+ },
115
+ ...!import_web.isWeb && {
116
+ measure: function(c) {
117
+ return c(pointRef.current.x, pointRef.current.y, 0, 0);
118
+ },
119
+ measureInWindow: function(c) {
120
+ return c(pointRef.current.x, pointRef.current.y, 0, 0);
121
+ }
122
+ }
123
+ } };
124
+ }, [pointRef.current.x, pointRef.current.y]);
125
+ var longPressTimerRef = import_react.default.useRef(0);
126
+ var clearLongPress = import_react.default.useCallback(function() {
127
+ return window.clearTimeout(longPressTimerRef.current);
128
+ }, []);
129
+ var createOpenChangeEvent = function() {
130
+ var defaultPrevented = false;
131
+ return {
132
+ get defaultPrevented() {
133
+ return defaultPrevented;
134
+ },
135
+ preventDefault() {
136
+ defaultPrevented = true;
137
+ }
138
+ };
139
+ };
140
+ var handleOpen = function(event) {
141
+ if (import_web.isWeb && (_instanceof(event, MouseEvent) || _instanceof(event, PointerEvent))) {
142
+ pointRef.current = {
143
+ x: event.clientX,
144
+ y: event.clientY
145
+ };
146
+ } else {
147
+ pointRef.current = {
148
+ x: event.nativeEvent.pageX,
149
+ y: event.nativeEvent.pageY
150
+ };
151
+ }
152
+ var openChangeEvent = createOpenChangeEvent();
153
+ context.onOpenChange(true, openChangeEvent);
154
+ return openChangeEvent;
155
+ };
156
+ import_react.default.useEffect(function() {
157
+ return clearLongPress;
158
+ }, [clearLongPress]);
159
+ import_react.default.useEffect(function() {
160
+ return void (disabled && clearLongPress());
161
+ }, [disabled, clearLongPress]);
162
+ var Comp = asChild ? import_web.Slot : import_web.View;
163
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Anchor, {
164
+ scope: scope || CONTEXTMENU_CONTEXT,
165
+ virtualRef
166
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comp, {
167
+ render: "span",
168
+ className: `is_${TRIGGER_NAME} ${className || ""}`.trim(),
169
+ id: context.triggerId,
170
+ "data-state": context.open ? "open" : "closed",
171
+ "data-disabled": disabled ? "" : void 0,
172
+ ...triggerProps,
173
+ ref: (0, import_web.composeRefs)(forwardedRef, context.triggerRef),
174
+ style: import_web.isWeb ? {
175
+ WebkitTouchCallout: "none",
176
+ ...style
177
+ } : null,
178
+ ...import_web.isWeb && {
179
+ onContextMenu: disabled ? props.onContextMenu : (0, import_web.composeEventHandlers)(props.onContextMenu, function(event) {
180
+ clearLongPress();
181
+ var openChangeEvent = handleOpen(event);
182
+ if (!openChangeEvent.defaultPrevented) {
183
+ event.preventDefault();
184
+ }
185
+ }),
186
+ onPointerDown: disabled ? props.onPointerDown : (0, import_web.composeEventHandlers)(props.onPointerDown, function(event) {
187
+ if (event.pointerType === "mouse") return;
188
+ clearLongPress();
189
+ longPressTimerRef.current = window.setTimeout(function() {
190
+ return handleOpen(event);
191
+ }, 700);
192
+ }),
193
+ onPointerMove: disabled ? props.onPointerMove : (0, import_web.composeEventHandlers)(props.onPointerMove, function(event) {
194
+ if (event.pointerType === "mouse") return;
195
+ clearLongPress();
196
+ }),
197
+ onPointerCancel: disabled ? props.onPointerCancel : (0, import_web.composeEventHandlers)(props.onPointerCancel, function(event) {
198
+ if (event.pointerType === "mouse") return;
199
+ clearLongPress();
200
+ }),
201
+ onPointerUp: disabled ? props.onPointerUp : (0, import_web.composeEventHandlers)(props.onPointerUp, function(event) {
202
+ if (event.pointerType === "mouse") return;
203
+ clearLongPress();
204
+ })
205
+ },
206
+ ...!import_web.isWeb && { onLongPress: disabled ? props.onLongPress : (0, import_web.composeEventHandlers)(props.onLongPress, function(event) {
207
+ clearLongPress();
208
+ var openChangeEvent = handleOpen(event);
209
+ if (!openChangeEvent.defaultPrevented) {
210
+ event.preventDefault();
211
+ }
212
+ }) },
213
+ children
214
+ })] });
215
+ });
216
+ ContextMenuTrigger.displayName = TRIGGER_NAME;
217
+ var PORTAL_NAME = "ContextMenuPortal";
218
+ var ContextMenuPortal = function(props) {
219
+ var { scope, children, ...portalProps } = props;
220
+ var context = import_web.isAndroid ? useContextMenuContext(scope) : null;
221
+ var content = import_web.isAndroid ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextMenuProvider, {
222
+ ...context,
223
+ children
224
+ }) : children;
225
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Portal, {
226
+ scope: scope || CONTEXTMENU_CONTEXT,
227
+ ...portalProps,
228
+ children: content
229
+ });
230
+ };
231
+ ContextMenuPortal.displayName = PORTAL_NAME;
232
+ var CONTENT_NAME = "ContextMenuContent";
233
+ var ContextMenuContent = (0, import_web.createStyledHOC)(Menu.Content, function(props, forwardedRef) {
234
+ var { scope, ...contentProps } = props;
235
+ var context = useContextMenuContext(scope);
236
+ var hasInteractedOutsideRef = import_react.default.useRef(false);
237
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Content, {
238
+ id: context.contentId,
239
+ "aria-labelledby": context.triggerId,
240
+ scope: scope || CONTEXTMENU_CONTEXT,
241
+ ...contentProps,
242
+ ref: forwardedRef,
243
+ onCloseAutoFocus: (0, import_web.composeEventHandlers)(props.onCloseAutoFocus, function(event) {
244
+ var _context_triggerRef_current;
245
+ if (!hasInteractedOutsideRef.current) (_context_triggerRef_current = context.triggerRef.current) === null || _context_triggerRef_current === void 0 ? void 0 : _context_triggerRef_current.focus();
246
+ hasInteractedOutsideRef.current = false;
247
+ event.cancel();
248
+ }),
249
+ onInteractOutside: (0, import_web.composeEventHandlers)(props.onInteractOutside, function(event) {
250
+ if (event.interaction !== "pointer" || !event.event) return;
251
+ var originalEvent = event.event;
252
+ var ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
253
+ var isRightClick = originalEvent.button === 2 || ctrlLeftClick;
254
+ if (!context.modal || isRightClick) hasInteractedOutsideRef.current = true;
255
+ })
256
+ });
257
+ });
258
+ ContextMenuContent.displayName = CONTENT_NAME;
259
+ var ITEM_NAME = "ContextMenuItem";
260
+ var ContextMenuItem = (0, import_compose_refs.createRefComponent)(function(props, forwardedRef) {
261
+ var { scope, className, ...itemProps } = props;
262
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Item, {
263
+ className: `is_${ITEM_NAME} ${className || ""}`.trim(),
264
+ scope: scope || CONTEXTMENU_CONTEXT,
265
+ ...itemProps,
266
+ ref: forwardedRef
267
+ });
268
+ });
269
+ ContextMenuItem.displayName = ITEM_NAME;
270
+ var CHECKBOX_ITEM_NAME = "ContextMenuCheckboxItem";
271
+ var ContextMenuCheckboxItem = (0, import_compose_refs.createRefComponent)(function(props, forwardedRef) {
272
+ var { scope, className, ...checkboxItemProps } = props;
273
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.CheckboxItem, {
274
+ className: `is_${CHECKBOX_ITEM_NAME} ${className || ""}`.trim(),
275
+ scope: scope || CONTEXTMENU_CONTEXT,
276
+ ...checkboxItemProps,
277
+ ref: forwardedRef
278
+ });
279
+ });
280
+ ContextMenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
281
+ var RADIO_GROUP_NAME = "ContextMenuRadioGroup";
282
+ var ContextMenuRadioGroup = (0, import_compose_refs.createRefComponent)(function(props, forwardedRef) {
283
+ var { scope, ...radioGroupProps } = props;
284
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.RadioGroup, {
285
+ scope: scope || CONTEXTMENU_CONTEXT,
286
+ ...radioGroupProps,
287
+ ref: forwardedRef
288
+ });
289
+ });
290
+ ContextMenuRadioGroup.displayName = RADIO_GROUP_NAME;
291
+ var RADIO_ITEM_NAME = "ContextMenuRadioItem";
292
+ var ContextMenuRadioItem = (0, import_compose_refs.createRefComponent)(function(props, forwardedRef) {
293
+ var { scope, className, ...radioItemProps } = props;
294
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.RadioItem, {
295
+ className: `is_${RADIO_ITEM_NAME} ${className || ""}`.trim(),
296
+ scope: scope || CONTEXTMENU_CONTEXT,
297
+ ...radioItemProps,
298
+ ref: forwardedRef
299
+ });
300
+ });
301
+ ContextMenuRadioItem.displayName = RADIO_ITEM_NAME;
302
+ var INDICATOR_NAME = "ContextMenuItemIndicator";
303
+ var ContextMenuItemIndicator = (0, import_web.createStyledHOC)(Menu.ItemIndicator, function(props, forwardedRef) {
304
+ var { scope, className, ...itemIndicatorProps } = props;
305
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.ItemIndicator, {
306
+ className: `is_${INDICATOR_NAME} ${className || ""}`.trim(),
307
+ scope: scope || CONTEXTMENU_CONTEXT,
308
+ ...itemIndicatorProps,
309
+ ref: forwardedRef
310
+ });
311
+ });
312
+ ContextMenuItemIndicator.displayName = INDICATOR_NAME;
313
+ var SUB_NAME = "ContextMenuSub";
314
+ var ContextMenuSub = function(props) {
315
+ var { scope, children, onOpenChange, open: openProp, defaultOpen, ...rest } = props;
316
+ var [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
317
+ prop: openProp,
318
+ defaultProp: defaultOpen,
319
+ onChange: onOpenChange
320
+ });
321
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Sub, {
322
+ scope: scope || CONTEXTMENU_CONTEXT,
323
+ open,
324
+ onOpenChange: setOpen,
325
+ ...rest,
326
+ children
327
+ });
328
+ };
329
+ ContextMenuSub.displayName = SUB_NAME;
330
+ var SUB_TRIGGER_NAME = "ContextMenuSubTrigger";
331
+ var ContextMenuSubTrigger = (0, import_web.createStyledHOC)(import_web.View, function(props, forwardedRef) {
332
+ var { scope, className, ...subTriggerProps } = props;
333
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.SubTrigger, {
334
+ className: `is_${SUB_TRIGGER_NAME} ${className || ""}`.trim(),
335
+ scope: scope || CONTEXTMENU_CONTEXT,
336
+ ...subTriggerProps,
337
+ ref: forwardedRef
338
+ });
339
+ });
340
+ ContextMenuSubTrigger.displayName = SUB_TRIGGER_NAME;
341
+ var SUB_CONTENT_NAME = "ContextMenuSubContent";
342
+ var ContextMenuSubContent = (0, import_web.createStyledHOC)(Menu.SubContent, function(props, forwardedRef) {
343
+ var { scope, ...subContentProps } = props;
344
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.SubContent, {
345
+ scope: scope || CONTEXTMENU_CONTEXT,
346
+ ...subContentProps,
347
+ ref: forwardedRef,
348
+ style: import_web.isWeb ? {
349
+ ...props.style,
350
+ ...{
351
+ "--tamagui-context-menu-content-transform-origin": "var(--tamagui-popper-transform-origin)",
352
+ "--tamagui-context-menu-content-available-width": "var(--tamagui-popper-available-width)",
353
+ "--tamagui-context-menu-content-available-height": "var(--tamagui-popper-available-height)",
354
+ "--tamagui-context-menu-trigger-width": "var(--tamagui-popper-anchor-width)",
355
+ "--tamagui-context-menu-trigger-height": "var(--tamagui-popper-anchor-height)"
356
+ }
357
+ } : null
358
+ });
359
+ });
360
+ ContextMenuSubContent.displayName = SUB_CONTENT_NAME;
361
+ var ARROW_NAME = "ContextMenuArrow";
362
+ var ContextMenuArrow = (0, import_compose_refs.createRefComponent)(function(props, forwardedRef) {
363
+ var { scope, className, ...arrowProps } = props;
364
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Arrow, {
365
+ className: `is_${ARROW_NAME} ${className || ""}`.trim(),
366
+ scope: scope || CONTEXTMENU_CONTEXT,
367
+ ...arrowProps,
368
+ ref: forwardedRef
369
+ });
370
+ });
371
+ ContextMenuArrow.displayName = ARROW_NAME;
372
+ var ContextMenuGroup = Menu.Group;
373
+ var ContextMenuLabel = Menu.Label;
374
+ var ContextMenuSeparator = Menu.Separator;
375
+ var ContextMenuItemTitle = Menu.ItemTitle;
376
+ var ContextMenuItemSubTitle = Menu.ItemSubtitle;
377
+ var ContextMenuItemImage = Menu.ItemImage;
378
+ var ContextMenuItemIcon = Menu.ItemIcon;
379
+ var ContextMenuPreview = function() {
380
+ return null;
381
+ };
382
+ return (0, import_web.withStaticProperties)(ContextMenuComp, {
383
+ Root: ContextMenuComp,
384
+ Trigger: ContextMenuTrigger,
385
+ Portal: ContextMenuPortal,
386
+ Content: ContextMenuContent,
387
+ Group: ContextMenuGroup,
388
+ Label: ContextMenuLabel,
389
+ Item: ContextMenuItem,
390
+ CheckboxItem: ContextMenuCheckboxItem,
391
+ RadioGroup: ContextMenuRadioGroup,
392
+ RadioItem: ContextMenuRadioItem,
393
+ ItemIndicator: ContextMenuItemIndicator,
394
+ Separator: ContextMenuSeparator,
395
+ Arrow: ContextMenuArrow,
396
+ Sub: ContextMenuSub,
397
+ SubTrigger: ContextMenuSubTrigger,
398
+ SubContent: ContextMenuSubContent,
399
+ ItemTitle: ContextMenuItemTitle,
400
+ ItemSubtitle: ContextMenuItemSubTitle,
401
+ ItemIcon: ContextMenuItemIcon,
402
+ ItemImage: ContextMenuItemImage,
403
+ Preview: ContextMenuPreview
404
+ });
405
+ }