diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index da5f2075564..b58a973140d 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -1,5 +1,5 @@ import { css, cx } from '@emotion/css'; -import { CSSProperties, ReactElement, ReactNode, useId } from 'react'; +import { CSSProperties, PointerEvent, ReactElement, ReactNode, useId, useRef } from 'react'; import * as React from 'react'; import { useMeasure, useToggle } from 'react-use'; @@ -151,6 +151,7 @@ export function PanelChrome({ const panelContentId = useId(); const panelTitleId = useId().replace(/:/g, '_'); const { isSelected, onSelect } = useElementSelection(selectionId); + const pointerDownEvt = useRef(null); const hasHeader = !hoverHeader; @@ -314,8 +315,28 @@ export function PanelChrome({ className={cx(styles.headerContainer, dragClass)} style={headerStyles} data-testid="header-container" - onPointerDown={onDragStart} - onPointerUp={onSelect} + onPointerDown={(evt) => { + evt.stopPropagation(); + pointerDownEvt.current = evt; + }} + onPointerMove={() => { + if (pointerDownEvt.current) { + onDragStart?.(pointerDownEvt.current); + pointerDownEvt.current = null; + } + }} + onPointerUp={(evt) => { + evt.stopPropagation(); + if ( + pointerDownEvt.current && + dragClassCancel && + evt.target instanceof HTMLElement && + !evt.target.closest(`.${dragClassCancel}`) + ) { + onSelect?.(pointerDownEvt.current); + pointerDownEvt.current = null; + } + }} > {statusMessage && (