diff --git a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx index c45a44eac8d..3b87798c3e7 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx +++ b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx @@ -97,6 +97,7 @@ import { withDataLinksActionsTooltip, getSummaryCellTextAlign, parseStyleJson, + IS_SAFARI_26, } from './utils'; const EXPANDED_COLUMN_KEY = 'expanded'; @@ -287,7 +288,7 @@ export function TableNG(props: TableNGProps) { const commonDataGridProps = useMemo( () => ({ - enableVirtualization: enableVirtualization !== false && rowHeight !== 'auto', + enableVirtualization: !IS_SAFARI_26 && enableVirtualization !== false && rowHeight !== 'auto', defaultColumnOptions: { minWidth: 50, resizable: true, @@ -460,7 +461,8 @@ export function TableNG(props: TableNGProps) { ? clsx('table-cell-actions', getCellActionStyles(theme, textAlign)) : undefined; - const shouldOverflow = rowHeight !== 'auto' && (shouldTextOverflow(field) || Boolean(maxRowHeight)); + const shouldOverflow = + !IS_SAFARI_26 && rowHeight !== 'auto' && (shouldTextOverflow(field) || Boolean(maxRowHeight)); const textWrap = rowHeight === 'auto' || shouldTextWrap(field); const withTooltip = withDataLinksActionsTooltip(field, cellType); const canBeColorized = canFieldBeColorized(cellType, applyToRowBgFn); diff --git a/packages/grafana-ui/src/components/Table/TableNG/hooks.ts b/packages/grafana-ui/src/components/Table/TableNG/hooks.ts index cc648af019a..83c320dacbf 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/hooks.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/hooks.ts @@ -16,6 +16,7 @@ import { computeColWidths, buildHeaderHeightMeasurers, buildCellHeightMeasurers, + IS_SAFARI_26, } from './utils'; // Helper function to get displayed value @@ -468,7 +469,7 @@ export function useScrollbarWidth(ref: RefObject, height: number useLayoutEffect(() => { const el = ref.current?.element; - if (!el) { + if (!el || IS_SAFARI_26) { return; } diff --git a/packages/grafana-ui/src/components/Table/TableNG/styles.ts b/packages/grafana-ui/src/components/Table/TableNG/styles.ts index feb5e650d90..09076724b20 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/styles.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/styles.ts @@ -1,11 +1,12 @@ import { css } from '@emotion/css'; import { Property } from 'csstype'; +import memoize from 'micro-memoize'; import { GrafanaTheme2, colorManipulator } from '@grafana/data'; import { COLUMN, TABLE } from './constants'; import { TableCellStyles } from './types'; -import { getJustifyContent, TextAlign } from './utils'; +import { getJustifyContent, IS_SAFARI_26, TextAlign } from './utils'; export const getGridStyles = (theme: GrafanaTheme2, enablePagination?: boolean, transparent?: boolean) => { const bgColor = transparent ? theme.colors.background.canvas : theme.colors.background.primary; @@ -51,14 +52,14 @@ export const getGridStyles = (theme: GrafanaTheme2, enablePagination?: boolean, '& > :not(.rdg-summary-row, .rdg-header-row) > .rdg-cell': { [getActiveCellSelector()]: { boxShadow: theme.shadows.z2 }, // selected cells should appear below hovered cells. - '&:hover': { zIndex: theme.zIndex.tooltip - 7 }, + ...(!IS_SAFARI_26 && { '&:hover': { zIndex: theme.zIndex.tooltip - 7 } }), '&[aria-selected=true]': { zIndex: theme.zIndex.tooltip - 6 }, }, '.rdg-cell.rdg-cell-frozen': { - backgroundColor: '--rdg-row-background-color', + backgroundColor: 'var(--rdg-row-background-color)', zIndex: theme.zIndex.tooltip - 4, - '&:hover': { zIndex: theme.zIndex.tooltip - 2 }, + ...(!IS_SAFARI_26 && { '&:hover': { zIndex: theme.zIndex.tooltip - 2 } }), '&[aria-selected=true]': { zIndex: theme.zIndex.tooltip - 3 }, }, @@ -70,7 +71,6 @@ export const getGridStyles = (theme: GrafanaTheme2, enablePagination?: boolean, }, }, }, - '.rdg-summary-row >': { '.rdg-cell': { // 0.75 padding causes "jumping" on hover. @@ -232,5 +232,22 @@ export const getTooltipStyles = (theme: GrafanaTheme2, textAlign: TextAlign) => }), }); -export const getActiveCellSelector = (isNested?: boolean) => - isNested ? '.rdg-cell:hover &, [aria-selected=true] &' : '&:hover, &[aria-selected=true]'; +const ACTIVE_CELL_SELECTORS = { + hover: { + nested: '.rdg-cell:hover &', + normal: '&:hover', + }, + selected: { + nested: '[aria-selected=true] &', + normal: '&[aria-selected=true]', + }, +} as const; + +export const getActiveCellSelector = memoize((isNested?: boolean) => { + const selectors = []; + selectors.push(ACTIVE_CELL_SELECTORS.selected[isNested ? 'nested' : 'normal']); + if (!IS_SAFARI_26) { + selectors.push(ACTIVE_CELL_SELECTORS.hover[isNested ? 'nested' : 'normal']); + } + return selectors.join(', '); +}); diff --git a/packages/grafana-ui/src/components/Table/TableNG/utils.ts b/packages/grafana-ui/src/components/Table/TableNG/utils.ts index a133fe883b0..848f21957b0 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/utils.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/utils.ts @@ -1029,3 +1029,13 @@ export function parseStyleJson(rawValue: unknown): CSSProperties | void { } } } + +// Safari 26 introduced rendering bugs which require us to disable several features of the table. +export const IS_SAFARI_26 = (() => { + if (navigator == null) { + return false; + } + const userAgent = navigator.userAgent; + const safariVersionMatch = userAgent.match(/Version\/(\d+)\./); + return safariVersionMatch && parseInt(safariVersionMatch[1], 10) === 26; +})();