TableNG: Fix click events bubbling up (#107156)

This commit is contained in:
Adela Almasan
2025-07-01 15:27:06 +00:00
committed by GitHub
parent f09e85c048
commit 1620f028b4
9 changed files with 38 additions and 23 deletions
@@ -15,6 +15,7 @@ import {
getCellColors,
getCellOptions,
getDataLinksActionsTooltipUtils,
tooltipOnClickHandler,
} from '../utils';
export const DefaultCell = (props: TableCellProps) => {
@@ -88,9 +89,7 @@ export const DefaultCell = (props: TableCellProps) => {
{...rest}
className={cellStyle}
style={{ ...cellProps.style, cursor: hasMultipleLinksOrActions ? 'context-menu' : 'auto' }}
onClick={({ clientX, clientY }) => {
setTooltipCoords({ clientX, clientY });
}}
onClick={tooltipOnClickHandler(setTooltipCoords)}
>
{shouldShowLink ? (
renderSingleLink(links[0], value, getLinkStyle(tableStyles, cellOptions))
@@ -3,7 +3,12 @@ import { useState } from 'react';
import { getCellLinks } from '../../../utils/table';
import { DataLinksActionsTooltip, renderSingleLink } from '../DataLinksActionsTooltip';
import { TableCellDisplayMode, TableCellProps } from '../types';
import { DataLinksActionsTooltipCoords, getCellOptions, getDataLinksActionsTooltipUtils } from '../utils';
import {
tooltipOnClickHandler,
DataLinksActionsTooltipCoords,
getCellOptions,
getDataLinksActionsTooltipUtils,
} from '../utils';
const DATALINKS_HEIGHT_OFFSET = 10;
@@ -37,9 +42,7 @@ export const ImageCell = (props: TableCellProps) => {
{...cellProps}
className={tableStyles.cellContainer}
style={{ ...cellProps.style, cursor: hasMultipleLinksOrActions ? 'context-menu' : 'auto' }}
onClick={({ clientX, clientY }) => {
setTooltipCoords({ clientX, clientY });
}}
onClick={tooltipOnClickHandler(setTooltipCoords)}
>
{/* If there are data links/actions, we render them with image */}
{/* Otherwise we simply render the image */}
@@ -7,7 +7,7 @@ import { CellActions } from '../CellActions';
import { DataLinksActionsTooltip, renderSingleLink } from '../DataLinksActionsTooltip';
import { TableCellInspectorMode } from '../TableCellInspector';
import { TableCellProps } from '../types';
import { DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../utils';
import { tooltipOnClickHandler, DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../utils';
export function JSONViewCell(props: TableCellProps): JSX.Element {
const { cell, tableStyles, cellProps, field, row } = props;
@@ -37,10 +37,7 @@ export function JSONViewCell(props: TableCellProps): JSX.Element {
return (
<div {...cellProps} className={inspectEnabled ? tableStyles.cellContainerNoOverflow : tableStyles.cellContainer}>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<div
className={cx(tableStyles.cellText, txt)}
onClick={({ clientX, clientY }) => setTooltipCoords({ clientX, clientY })}
>
<div className={cx(tableStyles.cellText, txt)} onClick={tooltipOnClickHandler(setTooltipCoords)}>
{shouldShowLink ? (
renderSingleLink(links[0], displayValue)
) : shouldShowTooltip ? (
@@ -89,7 +89,7 @@ export const DataLinksActionsTooltip = ({ links, actions, value, coords, onToolt
<Portal>
<div
ref={refCallback}
{...getReferenceProps({ onClick: (e) => e.stopPropagation() })}
{...getReferenceProps()}
{...getFloatingProps()}
style={floatingStyles}
className={styles.tooltipWrapper}
@@ -8,7 +8,7 @@ import { selectors } from '@grafana/e2e-selectors';
import { useStyles2 } from '../../../../themes/ThemeContext';
import { DataLinksActionsTooltip, renderSingleLink } from '../../DataLinksActionsTooltip';
import { TableCellOptions, TableCellDisplayMode } from '../../types';
import { DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../../utils';
import { DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils, tooltipOnClickHandler } from '../../utils';
import { AutoCellProps } from '../types';
import { getCellLinks } from '../utils';
@@ -27,7 +27,7 @@ export default function AutoCell({ value, field, justifyContent, rowIdx, cellOpt
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
<div
className={styles.cell}
onClick={({ clientX, clientY }) => setTooltipCoords({ clientX, clientY })}
onClick={tooltipOnClickHandler(setTooltipCoords)}
style={{ cursor: hasMultipleLinksOrActions ? 'context-menu' : 'auto' }}
data-testid={selectors.components.TablePanel.autoCell}
>
@@ -5,7 +5,7 @@ import { BarGaugeDisplayMode, BarGaugeValueMode, TableCellDisplayMode } from '@g
import { BarGauge } from '../../../BarGauge/BarGauge';
import { DataLinksActionsTooltip, renderSingleLink } from '../../DataLinksActionsTooltip';
import { DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../../utils';
import { tooltipOnClickHandler, DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../../utils';
import { BarGaugeCellProps } from '../types';
import { extractPixelValue, getCellOptions, getAlignmentFactor, getCellLinks } from '../utils';
@@ -78,7 +78,7 @@ export const BarGaugeCell = ({ value, field, theme, height, width, rowIdx, actio
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
<div
style={{ cursor: hasMultipleLinksOrActions ? 'context-menu' : 'auto' }}
onClick={({ clientX, clientY }) => setTooltipCoords({ clientX, clientY })}
onClick={tooltipOnClickHandler(setTooltipCoords)}
>
{shouldShowLink ? (
renderSingleLink(links[0], renderComponent())
@@ -7,7 +7,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../../../themes/ThemeContext';
import { DataLinksActionsTooltip, renderSingleLink } from '../../DataLinksActionsTooltip';
import { TableCellDisplayMode } from '../../types';
import { DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../../utils';
import { DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils, tooltipOnClickHandler } from '../../utils';
import { ImageCellProps } from '../types';
import { getCellLinks } from '../utils';
@@ -33,9 +33,7 @@ export const ImageCell = ({ cellOptions, field, height, justifyContent, value, r
<div
className={styles.imageContainer}
style={{ cursor: hasMultipleLinksOrActions ? 'context-menu' : 'auto' }}
onClick={({ clientX, clientY }) => {
setTooltipCoords({ clientX, clientY });
}}
onClick={tooltipOnClickHandler(setTooltipCoords)}
>
{shouldShowLink ? (
renderSingleLink(links[0], img)
@@ -6,7 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../../../themes/ThemeContext';
import { DataLinksActionsTooltip, renderSingleLink } from '../../DataLinksActionsTooltip';
import { DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../../utils';
import { tooltipOnClickHandler, DataLinksActionsTooltipCoords, getDataLinksActionsTooltipUtils } from '../../utils';
import { JSONCellProps } from '../types';
import { getCellLinks } from '../utils';
@@ -43,7 +43,7 @@ export const JSONCell = ({ value, justifyContent, field, rowIdx, actions }: JSON
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
<div
className={styles.jsonText}
onClick={({ clientX, clientY }) => setTooltipCoords({ clientX, clientY })}
onClick={tooltipOnClickHandler(setTooltipCoords)}
style={{ cursor: hasMultipleLinksOrActions ? 'context-menu' : 'auto' }}
>
{shouldShowLink ? (
@@ -775,3 +775,21 @@ export const getDataLinksActionsTooltipUtils = (links: LinkModel[], actions?: Ac
return { shouldShowLink, hasMultipleLinksOrActions };
};
const shouldTriggerTooltip = (event: React.MouseEvent<HTMLElement>): boolean => {
return event.target === event.currentTarget;
};
/**
* Creates an onClick handler for table cells that only triggers tooltip when clicking directly on the cell
* @param setTooltipCoords - function to set tooltip coordinates
* @returns onClick handler
*/
export const tooltipOnClickHandler = (setTooltipCoords: (coords: DataLinksActionsTooltipCoords) => void) => {
return (event: React.MouseEvent<HTMLElement>) => {
if (shouldTriggerTooltip(event)) {
const { clientX, clientY } = event;
setTooltipCoords({ clientX, clientY });
}
};
};