@vector-im/compound-web 7.11.0 → 7.12.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.
- package/dist/components/Menu/ContextMenu.cjs +2 -1
- package/dist/components/Menu/ContextMenu.cjs.map +1 -1
- package/dist/components/Menu/ContextMenu.d.ts +5 -0
- package/dist/components/Menu/ContextMenu.d.ts.map +1 -1
- package/dist/components/Menu/ContextMenu.js +2 -1
- package/dist/components/Menu/ContextMenu.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Menu/ContextMenu.tsx +9 -1
|
@@ -16,6 +16,7 @@ const ContextMenuItemWrapper = ({
|
|
|
16
16
|
}) => /* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.ContextMenuItem, { onSelect: onSelect ?? void 0, asChild: true, children });
|
|
17
17
|
const ContextMenu = ({
|
|
18
18
|
title,
|
|
19
|
+
showTitle = true,
|
|
19
20
|
onOpenChange: onOpenChangeProp,
|
|
20
21
|
trigger: triggerProp,
|
|
21
22
|
hasAccessibleAlternative,
|
|
@@ -56,7 +57,7 @@ const ContextMenu = ({
|
|
|
56
57
|
] }) })
|
|
57
58
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(reactContextMenu.Root, { onOpenChange, children: [
|
|
58
59
|
trigger,
|
|
59
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.Content, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(FloatingMenu.FloatingMenu, { title, children }) }) })
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.Content, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(FloatingMenu.FloatingMenu, { showTitle, title, children }) }) })
|
|
60
61
|
] });
|
|
61
62
|
};
|
|
62
63
|
exports.ContextMenu = ContextMenu;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.cjs","sources":["../../../src/components/Menu/ContextMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { FC, ReactNode, useCallback, useMemo, useState } from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n ContextMenuItem,\n} from \"@radix-ui/react-context-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerStyles from \"./DrawerMenu.module.css\";\nimport { MenuContext, MenuData, MenuItemWrapperProps } from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Event handler called when the open state of the menu changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger that can be right-clicked or long-pressed to open the menu.\n * This must be a component that accepts a ref and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * Whether the functionality of this menu is available through some other\n * keyboard-accessible means. Preferably this should be true, because context\n * menus are potentially difficult to discover, but if false the trigger will\n * become focusable so that it can be opened via keyboard navigation.\n */\n hasAccessibleAlternative: boolean;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\nconst ContextMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <ContextMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </ContextMenuItem>\n);\n\n/**\n * A menu opened by right-clicking or long-pressing another UI element.\n */\nexport const ContextMenu: FC<Props> = ({\n title,\n onOpenChange: onOpenChangeProp,\n trigger: triggerProp,\n hasAccessibleAlternative,\n children: childrenProp,\n}) => {\n const [open, setOpen] = useState(false);\n const onOpenChange = useCallback(\n (value: boolean) => {\n setOpen(value);\n onOpenChangeProp?.(value);\n },\n [setOpen, onOpenChangeProp],\n );\n\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : ContextMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n const trigger = (\n <Trigger\n aria-haspopup=\"menu\"\n tabIndex={hasAccessibleAlternative ? undefined : 0}\n asChild\n >\n {triggerProp}\n </Trigger>\n );\n\n // This is a small hack: Vaul drawers only support buttons as triggers, so\n // we end up mounting an empty Radix context menu tree alongside the\n // drawer tree, purely so we can use its Trigger component (which supports\n // touch for free). The resulting behavior and DOM tree looks exactly the\n // same as if Vaul provided a long-press trigger of its own, so I think\n // this is fine.\n return drawer ? (\n <>\n <Root onOpenChange={onOpenChange}>{trigger}</Root>\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerStyles.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n </>\n ) : (\n <Root onOpenChange={onOpenChange}>\n {trigger}\n <Portal>\n <Content asChild>\n <FloatingMenu title={title}
|
|
1
|
+
{"version":3,"file":"ContextMenu.cjs","sources":["../../../src/components/Menu/ContextMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { FC, ReactNode, useCallback, useMemo, useState } from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n ContextMenuItem,\n} from \"@radix-ui/react-context-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerStyles from \"./DrawerMenu.module.css\";\nimport { MenuContext, MenuData, MenuItemWrapperProps } from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Wether the title is displayed.\n * @default true\n */\n showTitle?: boolean;\n /**\n * Event handler called when the open state of the menu changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger that can be right-clicked or long-pressed to open the menu.\n * This must be a component that accepts a ref and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * Whether the functionality of this menu is available through some other\n * keyboard-accessible means. Preferably this should be true, because context\n * menus are potentially difficult to discover, but if false the trigger will\n * become focusable so that it can be opened via keyboard navigation.\n */\n hasAccessibleAlternative: boolean;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\nconst ContextMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <ContextMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </ContextMenuItem>\n);\n\n/**\n * A menu opened by right-clicking or long-pressing another UI element.\n */\nexport const ContextMenu: FC<Props> = ({\n title,\n showTitle = true,\n onOpenChange: onOpenChangeProp,\n trigger: triggerProp,\n hasAccessibleAlternative,\n children: childrenProp,\n}) => {\n const [open, setOpen] = useState(false);\n const onOpenChange = useCallback(\n (value: boolean) => {\n setOpen(value);\n onOpenChangeProp?.(value);\n },\n [setOpen, onOpenChangeProp],\n );\n\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : ContextMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n const trigger = (\n <Trigger\n aria-haspopup=\"menu\"\n tabIndex={hasAccessibleAlternative ? undefined : 0}\n asChild\n >\n {triggerProp}\n </Trigger>\n );\n\n // This is a small hack: Vaul drawers only support buttons as triggers, so\n // we end up mounting an empty Radix context menu tree alongside the\n // drawer tree, purely so we can use its Trigger component (which supports\n // touch for free). The resulting behavior and DOM tree looks exactly the\n // same as if Vaul provided a long-press trigger of its own, so I think\n // this is fine.\n return drawer ? (\n <>\n <Root onOpenChange={onOpenChange}>{trigger}</Root>\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerStyles.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n </>\n ) : (\n <Root onOpenChange={onOpenChange}>\n {trigger}\n <Portal>\n <Content asChild>\n <FloatingMenu showTitle={showTitle} title={title}>\n {children}\n </FloatingMenu>\n </Content>\n </Portal>\n </Root>\n );\n};\n"],"names":["ContextMenuItem","useState","useCallback","platform","getPlatform","useMemo","jsx","MenuContext","Trigger","jsxs","Fragment","Root","Drawer","classnames","drawerStyles","DrawerMenu","Portal","Content","FloatingMenu"],"mappings":";;;;;;;;;;;;AAwDA,MAAM,yBAAmD,CAAC;AAAA,EACxD;AAAA,EACA;AACF,qCACGA,kCAAgB,EAAA,UAAU,YAAY,QAAW,SAAO,MACtD,UACH;AAMK,MAAM,cAAyB,CAAC;AAAA,EACrC;AAAA,EACA,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,SAAS;AAAA,EACT;AAAA,EACA,UAAU;AACZ,MAAM;AACJ,QAAM,CAAC,MAAM,OAAO,IAAIC,MAAAA,SAAS,KAAK;AACtC,QAAM,eAAeC,MAAA;AAAA,IACnB,CAAC,UAAmB;AAClB,cAAQ,KAAK;AACb,yBAAmB,KAAK;AAAA,IAC1B;AAAA,IACA,CAAC,SAAS,gBAAgB;AAAA,EAC5B;AAIA,QAAMC,aAAWC,SAAAA,YAAY;AACvB,QAAA,SAASD,eAAa,aAAaA,eAAa;AACtD,QAAM,UAAoBE,MAAA;AAAA,IACxB,OAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC;AAAA,IAAA;AAAA,IAEF,CAAC,YAAY;AAAA,EACf;AACA,QAAM,WACHC,+BAAAC,YAAAA,YAAY,UAAZ,EAAqB,OAAO,SAAU,UAAa,cAAA;AAGtD,QAAM,UACJD,2BAAA;AAAA,IAACE,iBAAA;AAAA,IAAA;AAAA,MACC,iBAAc;AAAA,MACd,UAAU,2BAA2B,SAAY;AAAA,MACjD,SAAO;AAAA,MAEN,UAAA;AAAA,IAAA;AAAA,EACH;AASF,SAAO,SAEHC,2BAAAA,KAAAC,WAAA,UAAA,EAAA,UAAA;AAAA,IAACJ,2BAAAA,IAAAK,iBAAAA,MAAA,EAAK,cAA6B,UAAQ,QAAA,CAAA;AAAA,IAC3CL,2BAAAA,IAACM,YAAO,MAAP,EAAY,MAAY,cACvB,UAAAH,gCAACG,KAAAA,OAAO,QAAP,EACC,UAAA;AAAA,MAAAN,+BAACM,KAAAA,OAAO,SAAP,EAAe,WAAWC,WAAWC,kBAAA,QAAa,EAAE,GAAG;AAAA,MACxDR,2BAAAA,IAACM,KAAO,OAAA,SAAP,EAAe,SAAO,MACrB,UAACN,2BAAAA,IAAAS,WAAAA,YAAA,EAAW,OAAe,SAAS,CAAA,EACtC,CAAA;AAAA,IAAA,EAAA,CACF,EACF,CAAA;AAAA,EACF,EAAA,CAAA,IAECN,2BAAA,KAAAE,iBAAA,MAAA,EAAK,cACH,UAAA;AAAA,IAAA;AAAA,IACAL,2BAAA,IAAAU,iBAAA,QAAA,EACC,UAACV,2BAAA,IAAAW,iBAAA,SAAA,EAAQ,SAAO,MACd,UAACX,2BAAA,IAAAY,aAAA,cAAA,EAAa,WAAsB,OACjC,SACH,CAAA,EAAA,CACF,EACF,CAAA;AAAA,EAAA,GACF;AAEJ;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/ContextMenu.tsx"],"names":[],"mappings":"AAOA,OAAc,EAAE,EAAE,EAAE,SAAS,EAAkC,MAAM,OAAO,CAAC;AAgB7E,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAWD;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/ContextMenu.tsx"],"names":[],"mappings":"AAOA,OAAc,EAAE,EAAE,EAAE,SAAS,EAAkC,MAAM,OAAO,CAAC;AAgB7E,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAWD;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,KAAK,CAwEjC,CAAC"}
|
|
@@ -14,6 +14,7 @@ const ContextMenuItemWrapper = ({
|
|
|
14
14
|
}) => /* @__PURE__ */ jsx(ContextMenuItem, { onSelect: onSelect ?? void 0, asChild: true, children });
|
|
15
15
|
const ContextMenu = ({
|
|
16
16
|
title,
|
|
17
|
+
showTitle = true,
|
|
17
18
|
onOpenChange: onOpenChangeProp,
|
|
18
19
|
trigger: triggerProp,
|
|
19
20
|
hasAccessibleAlternative,
|
|
@@ -54,7 +55,7 @@ const ContextMenu = ({
|
|
|
54
55
|
] }) })
|
|
55
56
|
] }) : /* @__PURE__ */ jsxs(Root, { onOpenChange, children: [
|
|
56
57
|
trigger,
|
|
57
|
-
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Content, { asChild: true, children: /* @__PURE__ */ jsx(FloatingMenu, { title, children }) }) })
|
|
58
|
+
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Content, { asChild: true, children: /* @__PURE__ */ jsx(FloatingMenu, { showTitle, title, children }) }) })
|
|
58
59
|
] });
|
|
59
60
|
};
|
|
60
61
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.js","sources":["../../../src/components/Menu/ContextMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { FC, ReactNode, useCallback, useMemo, useState } from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n ContextMenuItem,\n} from \"@radix-ui/react-context-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerStyles from \"./DrawerMenu.module.css\";\nimport { MenuContext, MenuData, MenuItemWrapperProps } from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Event handler called when the open state of the menu changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger that can be right-clicked or long-pressed to open the menu.\n * This must be a component that accepts a ref and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * Whether the functionality of this menu is available through some other\n * keyboard-accessible means. Preferably this should be true, because context\n * menus are potentially difficult to discover, but if false the trigger will\n * become focusable so that it can be opened via keyboard navigation.\n */\n hasAccessibleAlternative: boolean;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\nconst ContextMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <ContextMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </ContextMenuItem>\n);\n\n/**\n * A menu opened by right-clicking or long-pressing another UI element.\n */\nexport const ContextMenu: FC<Props> = ({\n title,\n onOpenChange: onOpenChangeProp,\n trigger: triggerProp,\n hasAccessibleAlternative,\n children: childrenProp,\n}) => {\n const [open, setOpen] = useState(false);\n const onOpenChange = useCallback(\n (value: boolean) => {\n setOpen(value);\n onOpenChangeProp?.(value);\n },\n [setOpen, onOpenChangeProp],\n );\n\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : ContextMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n const trigger = (\n <Trigger\n aria-haspopup=\"menu\"\n tabIndex={hasAccessibleAlternative ? undefined : 0}\n asChild\n >\n {triggerProp}\n </Trigger>\n );\n\n // This is a small hack: Vaul drawers only support buttons as triggers, so\n // we end up mounting an empty Radix context menu tree alongside the\n // drawer tree, purely so we can use its Trigger component (which supports\n // touch for free). The resulting behavior and DOM tree looks exactly the\n // same as if Vaul provided a long-press trigger of its own, so I think\n // this is fine.\n return drawer ? (\n <>\n <Root onOpenChange={onOpenChange}>{trigger}</Root>\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerStyles.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n </>\n ) : (\n <Root onOpenChange={onOpenChange}>\n {trigger}\n <Portal>\n <Content asChild>\n <FloatingMenu title={title}
|
|
1
|
+
{"version":3,"file":"ContextMenu.js","sources":["../../../src/components/Menu/ContextMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { FC, ReactNode, useCallback, useMemo, useState } from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n ContextMenuItem,\n} from \"@radix-ui/react-context-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerStyles from \"./DrawerMenu.module.css\";\nimport { MenuContext, MenuData, MenuItemWrapperProps } from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Wether the title is displayed.\n * @default true\n */\n showTitle?: boolean;\n /**\n * Event handler called when the open state of the menu changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger that can be right-clicked or long-pressed to open the menu.\n * This must be a component that accepts a ref and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * Whether the functionality of this menu is available through some other\n * keyboard-accessible means. Preferably this should be true, because context\n * menus are potentially difficult to discover, but if false the trigger will\n * become focusable so that it can be opened via keyboard navigation.\n */\n hasAccessibleAlternative: boolean;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\nconst ContextMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <ContextMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </ContextMenuItem>\n);\n\n/**\n * A menu opened by right-clicking or long-pressing another UI element.\n */\nexport const ContextMenu: FC<Props> = ({\n title,\n showTitle = true,\n onOpenChange: onOpenChangeProp,\n trigger: triggerProp,\n hasAccessibleAlternative,\n children: childrenProp,\n}) => {\n const [open, setOpen] = useState(false);\n const onOpenChange = useCallback(\n (value: boolean) => {\n setOpen(value);\n onOpenChangeProp?.(value);\n },\n [setOpen, onOpenChangeProp],\n );\n\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : ContextMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n const trigger = (\n <Trigger\n aria-haspopup=\"menu\"\n tabIndex={hasAccessibleAlternative ? undefined : 0}\n asChild\n >\n {triggerProp}\n </Trigger>\n );\n\n // This is a small hack: Vaul drawers only support buttons as triggers, so\n // we end up mounting an empty Radix context menu tree alongside the\n // drawer tree, purely so we can use its Trigger component (which supports\n // touch for free). The resulting behavior and DOM tree looks exactly the\n // same as if Vaul provided a long-press trigger of its own, so I think\n // this is fine.\n return drawer ? (\n <>\n <Root onOpenChange={onOpenChange}>{trigger}</Root>\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerStyles.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n </>\n ) : (\n <Root onOpenChange={onOpenChange}>\n {trigger}\n <Portal>\n <Content asChild>\n <FloatingMenu showTitle={showTitle} title={title}>\n {children}\n </FloatingMenu>\n </Content>\n </Portal>\n </Root>\n );\n};\n"],"names":["classnames","drawerStyles"],"mappings":";;;;;;;;;;AAwDA,MAAM,yBAAmD,CAAC;AAAA,EACxD;AAAA,EACA;AACF,0BACG,iBAAgB,EAAA,UAAU,YAAY,QAAW,SAAO,MACtD,UACH;AAMK,MAAM,cAAyB,CAAC;AAAA,EACrC;AAAA,EACA,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,SAAS;AAAA,EACT;AAAA,EACA,UAAU;AACZ,MAAM;AACJ,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,eAAe;AAAA,IACnB,CAAC,UAAmB;AAClB,cAAQ,KAAK;AACb,yBAAmB,KAAK;AAAA,IAC1B;AAAA,IACA,CAAC,SAAS,gBAAgB;AAAA,EAC5B;AAIA,QAAM,WAAW,YAAY;AACvB,QAAA,SAAS,aAAa,aAAa,aAAa;AACtD,QAAM,UAAoB;AAAA,IACxB,OAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC;AAAA,IAAA;AAAA,IAEF,CAAC,YAAY;AAAA,EACf;AACA,QAAM,WACH,oBAAA,YAAY,UAAZ,EAAqB,OAAO,SAAU,UAAa,cAAA;AAGtD,QAAM,UACJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,iBAAc;AAAA,MACd,UAAU,2BAA2B,SAAY;AAAA,MACjD,SAAO;AAAA,MAEN,UAAA;AAAA,IAAA;AAAA,EACH;AASF,SAAO,SAEH,qBAAA,UAAA,EAAA,UAAA;AAAA,IAAC,oBAAA,MAAA,EAAK,cAA6B,UAAQ,QAAA,CAAA;AAAA,IAC3C,oBAAC,OAAO,MAAP,EAAY,MAAY,cACvB,UAAA,qBAAC,OAAO,QAAP,EACC,UAAA;AAAA,MAAA,oBAAC,OAAO,SAAP,EAAe,WAAWA,WAAWC,WAAa,EAAE,GAAG;AAAA,MACxD,oBAAC,OAAO,SAAP,EAAe,SAAO,MACrB,UAAC,oBAAA,YAAA,EAAW,OAAe,SAAS,CAAA,EACtC,CAAA;AAAA,IAAA,EAAA,CACF,EACF,CAAA;AAAA,EACF,EAAA,CAAA,IAEC,qBAAA,MAAA,EAAK,cACH,UAAA;AAAA,IAAA;AAAA,IACA,oBAAA,QAAA,EACC,UAAC,oBAAA,SAAA,EAAQ,SAAO,MACd,UAAC,oBAAA,cAAA,EAAa,WAAsB,OACjC,SACH,CAAA,EAAA,CACF,EACF,CAAA;AAAA,EAAA,GACF;AAEJ;"}
|
package/package.json
CHANGED
|
@@ -26,6 +26,11 @@ interface Props {
|
|
|
26
26
|
* The menu title.
|
|
27
27
|
*/
|
|
28
28
|
title: string;
|
|
29
|
+
/**
|
|
30
|
+
* Wether the title is displayed.
|
|
31
|
+
* @default true
|
|
32
|
+
*/
|
|
33
|
+
showTitle?: boolean;
|
|
29
34
|
/**
|
|
30
35
|
* Event handler called when the open state of the menu changes.
|
|
31
36
|
*/
|
|
@@ -63,6 +68,7 @@ const ContextMenuItemWrapper: FC<MenuItemWrapperProps> = ({
|
|
|
63
68
|
*/
|
|
64
69
|
export const ContextMenu: FC<Props> = ({
|
|
65
70
|
title,
|
|
71
|
+
showTitle = true,
|
|
66
72
|
onOpenChange: onOpenChangeProp,
|
|
67
73
|
trigger: triggerProp,
|
|
68
74
|
hasAccessibleAlternative,
|
|
@@ -125,7 +131,9 @@ export const ContextMenu: FC<Props> = ({
|
|
|
125
131
|
{trigger}
|
|
126
132
|
<Portal>
|
|
127
133
|
<Content asChild>
|
|
128
|
-
<FloatingMenu title={title}>
|
|
134
|
+
<FloatingMenu showTitle={showTitle} title={title}>
|
|
135
|
+
{children}
|
|
136
|
+
</FloatingMenu>
|
|
129
137
|
</Content>
|
|
130
138
|
</Portal>
|
|
131
139
|
</Root>
|