diff --git a/packages/grafana-ui/src/components/ToolbarButton/ToolbarButtonRow.tsx b/packages/grafana-ui/src/components/ToolbarButton/ToolbarButtonRow.tsx index 1f43cd7d7b3..6ef76011688 100644 --- a/packages/grafana-ui/src/components/ToolbarButton/ToolbarButtonRow.tsx +++ b/packages/grafana-ui/src/components/ToolbarButton/ToolbarButtonRow.tsx @@ -15,8 +15,6 @@ export interface Props extends HTMLAttributes { alignment?: 'left' | 'right'; } -const OVERFLOW_BUTTON_ID = 'overflow-button'; - export const ToolbarButtonRow = forwardRef( ({ alignment = 'left', className, children, ...rest }, ref) => { // null is a valid react child so we need to filter it out to prevent unnecessary padding @@ -24,9 +22,15 @@ export const ToolbarButtonRow = forwardRef( const [childVisibility, setChildVisibility] = useState(Array(childrenWithoutNull.length).fill(true)); const containerRef = useRef(null); const [showOverflowItems, setShowOverflowItems] = useState(false); + const overflowRef = useRef(null); const overflowItemsRef = createRef(); const { overlayProps } = useOverlay( - { onClose: () => setShowOverflowItems(false), isDismissable: true, isOpen: showOverflowItems }, + { + onClose: () => setShowOverflowItems(false), + isDismissable: true, + isOpen: showOverflowItems, + shouldCloseOnInteractOutside: (element: Element) => !overflowRef.current?.contains(element), + }, overflowItemsRef ); const { dialogProps } = useDialog({}, overflowItemsRef); @@ -56,7 +60,7 @@ export const ToolbarButtonRow = forwardRef( if (containerRef.current) { Array.from(containerRef.current.children).forEach((item) => { // don't observe the overflow button - if (item instanceof HTMLElement && item.dataset.testid !== OVERFLOW_BUTTON_ID) { + if (item instanceof HTMLElement && item !== overflowRef.current) { intersectionObserver.observe(item); } }); @@ -76,7 +80,7 @@ export const ToolbarButtonRow = forwardRef( ))} {childVisibility.includes(false) && ( -
+