UNPKG

@grafana/ui

Version:
1 lines 4.5 kB
{"version":3,"file":"ContextMenu.mjs","sources":["../../../../src/components/ContextMenu/ContextMenu.tsx"],"sourcesContent":["import { useRef, useState, useLayoutEffect } from 'react';\nimport * as React from 'react';\nimport { useClickAway } from 'react-use';\n\nimport { selectors } from '@grafana/e2e-selectors';\n\nimport { Menu } from '../Menu/Menu';\nimport { Portal } from '../Portal/Portal';\n\nexport interface ContextMenuProps {\n /** Starting horizontal position for the menu */\n x: number;\n /** Starting vertical position for the menu */\n y: number;\n /** Callback for closing the menu */\n onClose?: () => void;\n /** On menu open focus the first element */\n focusOnOpen?: boolean;\n /** RenderProp function that returns menu items to display */\n renderMenuItems?: () => React.ReactNode;\n /** A function that returns header element */\n renderHeader?: () => React.ReactNode;\n}\n\nexport const ContextMenu = React.memo(\n ({ x, y, onClose, focusOnOpen = true, renderMenuItems, renderHeader }: ContextMenuProps) => {\n const menuRef = useRef<HTMLDivElement>(null);\n const [positionStyles, setPositionStyles] = useState({});\n\n useLayoutEffect(() => {\n const menuElement = menuRef.current;\n if (menuElement) {\n const rect = menuElement.getBoundingClientRect();\n const OFFSET = 5;\n const collisions = {\n right: window.innerWidth < x + rect.width,\n bottom: window.innerHeight < y + rect.height + OFFSET,\n };\n\n setPositionStyles({\n position: 'fixed',\n left: collisions.right ? x - rect.width - OFFSET : x - OFFSET,\n top: Math.max(0, collisions.bottom ? y - rect.height - OFFSET : y + OFFSET),\n });\n }\n }, [x, y]);\n\n useClickAway(menuRef, () => {\n onClose?.();\n });\n const header = renderHeader?.();\n const menuItems = renderMenuItems?.();\n const onOpen = (setFocusedItem: (a: number) => void) => {\n if (focusOnOpen) {\n setFocusedItem(0);\n }\n };\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n onClose?.();\n }\n };\n\n return (\n <Portal>\n <Menu\n header={header}\n ref={menuRef}\n style={positionStyles}\n ariaLabel={selectors.components.Menu.MenuComponent('Context')}\n onOpen={onOpen}\n onClick={onClose}\n onKeyDown={onKeyDown}\n >\n {menuItems}\n </Menu>\n </Portal>\n );\n }\n);\n\nContextMenu.displayName = 'ContextMenu';\n"],"names":[],"mappings":";;;;;;;;AAwBO,MAAM,cAAc,KAAM,CAAA,IAAA;AAAA,EAC/B,CAAC,EAAE,CAAG,EAAA,CAAA,EAAG,SAAS,WAAc,GAAA,IAAA,EAAM,eAAiB,EAAA,YAAA,EAAqC,KAAA;AAC1F,IAAM,MAAA,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,IAAA,MAAM,CAAC,cAAgB,EAAA,iBAAiB,CAAI,GAAA,QAAA,CAAS,EAAE,CAAA;AAEvD,IAAA,eAAA,CAAgB,MAAM;AACpB,MAAA,MAAM,cAAc,OAAQ,CAAA,OAAA;AAC5B,MAAA,IAAI,WAAa,EAAA;AACf,QAAM,MAAA,IAAA,GAAO,YAAY,qBAAsB,EAAA;AAC/C,QAAA,MAAM,MAAS,GAAA,CAAA;AACf,QAAA,MAAM,UAAa,GAAA;AAAA,UACjB,KAAO,EAAA,MAAA,CAAO,UAAa,GAAA,CAAA,GAAI,IAAK,CAAA,KAAA;AAAA,UACpC,MAAQ,EAAA,MAAA,CAAO,WAAc,GAAA,CAAA,GAAI,KAAK,MAAS,GAAA;AAAA,SACjD;AAEA,QAAkB,iBAAA,CAAA;AAAA,UAChB,QAAU,EAAA,OAAA;AAAA,UACV,MAAM,UAAW,CAAA,KAAA,GAAQ,IAAI,IAAK,CAAA,KAAA,GAAQ,SAAS,CAAI,GAAA,MAAA;AAAA,UACvD,GAAA,EAAK,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,UAAA,CAAW,MAAS,GAAA,CAAA,GAAI,IAAK,CAAA,MAAA,GAAS,MAAS,GAAA,CAAA,GAAI,MAAM;AAAA,SAC3E,CAAA;AAAA;AACH,KACC,EAAA,CAAC,CAAG,EAAA,CAAC,CAAC,CAAA;AAET,IAAA,YAAA,CAAa,SAAS,MAAM;AAC1B,MAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,EAAA;AAAA,KACD,CAAA;AACD,IAAA,MAAM,MAAS,GAAA,YAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,YAAA,EAAA;AACf,IAAA,MAAM,SAAY,GAAA,eAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,eAAA,EAAA;AAClB,IAAM,MAAA,MAAA,GAAS,CAAC,cAAwC,KAAA;AACtD,MAAA,IAAI,WAAa,EAAA;AACf,QAAA,cAAA,CAAe,CAAC,CAAA;AAAA;AAClB,KACF;AACA,IAAM,MAAA,SAAA,GAAY,CAAC,CAA2B,KAAA;AAC5C,MAAI,IAAA,CAAA,CAAE,QAAQ,QAAU,EAAA;AACtB,QAAA,CAAA,CAAE,cAAe,EAAA;AACjB,QAAA,CAAA,CAAE,eAAgB,EAAA;AAClB,QAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,EAAA;AAAA;AACF,KACF;AAEA,IAAA,2BACG,MACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,GAAK,EAAA,OAAA;AAAA,QACL,KAAO,EAAA,cAAA;AAAA,QACP,SAAW,EAAA,SAAA,CAAU,UAAW,CAAA,IAAA,CAAK,cAAc,SAAS,CAAA;AAAA,QAC5D,MAAA;AAAA,QACA,OAAS,EAAA,OAAA;AAAA,QACT,SAAA;AAAA,QAEC,QAAA,EAAA;AAAA;AAAA,KAEL,EAAA,CAAA;AAAA;AAGN;AAEA,WAAA,CAAY,WAAc,GAAA,aAAA;;;;"}