From 00d0640b6e778ddaca021670fe851fe00982acf2 Mon Sep 17 00:00:00 2001 From: Dominik Prokop Date: Tue, 15 Oct 2019 13:38:22 +0200 Subject: [PATCH] DataLinks: Fix context menu not showing in singlestat-ish visualisations (#19809) * Fix data links menu being hidden in siglestat-ish visualizations * ts fix * Review updates --- .../components/ContextMenu/ContextMenu.tsx | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx index 83d739658b2..c2f35bfd064 100644 --- a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx +++ b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useRef } from 'react'; +import React, { useContext, useRef, useState, useLayoutEffect } from 'react'; import { css, cx } from 'emotion'; import useClickAway from 'react-use/lib/useClickAway'; import { GrafanaTheme, selectThemeVariant, ThemeContext } from '../../index'; @@ -107,6 +107,7 @@ const getContextMenuStyles = stylesFactory((theme: GrafanaTheme) => { z-index: 1; box-shadow: 0 2px 5px 0 ${wrapperShadow}; min-width: 200px; + display: inline-block; border-radius: ${theme.border.radius.sm}; `, link: css` @@ -151,7 +152,27 @@ const getContextMenuStyles = stylesFactory((theme: GrafanaTheme) => { export const ContextMenu: React.FC = React.memo(({ x, y, onClose, items, renderHeader }) => { const theme = useContext(ThemeContext); - const menuRef = useRef(null); + const menuRef = useRef(null); + const [positionStyles, setPositionStyles] = useState({}); + + useLayoutEffect(() => { + const menuElement = menuRef.current; + if (menuElement) { + const rect = menuElement.getBoundingClientRect(); + const OFFSET = 5; + const collisions = { + right: window.innerWidth < x + rect.width, + bottom: window.innerHeight < rect.bottom + rect.height + OFFSET, + }; + + setPositionStyles({ + position: 'fixed', + left: collisions.right ? x - rect.width - OFFSET : x - OFFSET, + top: collisions.bottom ? y - rect.height - OFFSET : y + OFFSET, + }); + } + }, [menuRef.current]); + useClickAway(menuRef, () => { if (onClose) { onClose(); @@ -159,10 +180,9 @@ export const ContextMenu: React.FC = React.memo(({ x, y, onClo }); const styles = getContextMenuStyles(theme); - return ( -
+
{renderHeader &&
{renderHeader()}
} = React.memo(({ x, y, onClo
); - - function getStyle(menuNode: HTMLDivElement | null) { - const haventMeasuredMenuYet = !menuNode; - if (haventMeasuredMenuYet) { - return { visibility: 'hidden' as const }; - } - const rect = menuNode!.getBoundingClientRect(); - const OFFSET = 5; - const collisions = { - right: window.innerWidth < x + rect.width, - bottom: window.innerHeight < rect.bottom + rect.height + OFFSET, - }; - - return { - position: 'fixed' as const, - left: collisions.right ? x - rect.width - OFFSET : x - OFFSET, - top: collisions.bottom ? y - rect.height - OFFSET : y + OFFSET, - }; - } }); interface ContextMenuItemProps {