TableNG: Scrollbar width handling (#107994)

* TableNG: Scrollbar width handling

* slight cleanup

* fix types

* fixie

---------

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
Paul Marbach
2025-07-11 08:50:25 -04:00
committed by GitHub
co-authored by Leon Sorokin
parent 9d0a23e1f5
commit 73ab088804
2 changed files with 24 additions and 5 deletions
@@ -1,11 +1,12 @@
import 'react-data-grid/lib/styles.css';
import { css, cx } from '@emotion/css';
import { Property } from 'csstype';
import { Key, ReactNode, useCallback, useLayoutEffect, useMemo, useState } from 'react';
import { Key, ReactNode, useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
import {
Cell,
CellRendererProps,
DataGrid,
DataGridHandle,
DataGridProps,
RenderCellProps,
RenderRowProps,
@@ -39,6 +40,7 @@ import {
useHeaderHeight,
usePaginatedRows,
useRowHeight,
useScrollbarWidth,
useSortedRows,
useTypographyCtx,
} from './hooks';
@@ -151,9 +153,11 @@ export function TableNG(props: TableNGProps) {
// vt scrollbar accounting for column auto-sizing
const visibleFields = useMemo(() => getVisibleFields(data.fields), [data.fields]);
const gridRef = useRef<DataGridHandle>(null);
const scrollbarWidth = useScrollbarWidth(gridRef, height, sortedRows);
const availableWidth = useMemo(
() => (hasNestedFrames ? width - COLUMN.EXPANDER_WIDTH : width),
[width, hasNestedFrames]
() => (hasNestedFrames ? width - COLUMN.EXPANDER_WIDTH : width) - scrollbarWidth,
[width, hasNestedFrames, scrollbarWidth]
);
const typographyCtx = useTypographyCtx();
const widths = useMemo(() => computeColWidths(visibleFields, availableWidth), [visibleFields, availableWidth]);
@@ -549,6 +553,7 @@ export function TableNG(props: TableNGProps) {
<>
<DataGrid<TableRow, TableSummaryRow>
{...commonDataGridProps}
ref={gridRef}
className={styles.grid}
columns={structureRevColumns}
rows={paginatedRows}
@@ -1,5 +1,5 @@
import { useState, useMemo, useEffect, useCallback, useRef, useLayoutEffect } from 'react';
import { Column, DataGridProps, SortColumn } from 'react-data-grid';
import { useState, useMemo, useEffect, useCallback, useRef, useLayoutEffect, RefObject } from 'react';
import { Column, DataGridHandle, DataGridProps, SortColumn } from 'react-data-grid';
import { varPreLine } from 'uwrap';
import { Field, fieldReducers, FieldType, formattedValueToString, LinkModel, reduceField } from '@grafana/data';
@@ -608,3 +608,17 @@ export function useSingleLink(field: Field, rowIdx: number): LinkModel | undefin
const shouldShowLink = linksCount === 1 && actionsCount === 0;
return useMemo(() => (shouldShowLink ? (getCellLinks(field, rowIdx) ?? []) : [])[0], [field, shouldShowLink, rowIdx]);
}
export function useScrollbarWidth(ref: RefObject<DataGridHandle>, height: number, renderedRows: TableRow[]) {
const [scrollbarWidth, setScrollbarWidth] = useState(0);
useLayoutEffect(() => {
const el = ref.current?.element;
if (el) {
setScrollbarWidth(el.offsetWidth - el.clientWidth);
}
}, [ref, height, renderedRows]);
return scrollbarWidth;
}