TableNG: Use Set for tracking expanded rows (#108198)

This commit is contained in:
Leon Sorokin
2025-07-16 19:11:28 -05:00
committed by GitHub
parent 6b266ebc50
commit c7aa83f8d3
3 changed files with 18 additions and 16 deletions
@@ -159,7 +159,7 @@ export function TableNG(props: TableNGProps) {
const defaultRowHeight = getDefaultRowHeight(theme, cellHeight); const defaultRowHeight = getDefaultRowHeight(theme, cellHeight);
const defaultHeaderHeight = getDefaultRowHeight(theme, TableCellHeight.Sm); const defaultHeaderHeight = getDefaultRowHeight(theme, TableCellHeight.Sm);
const [isInspecting, setIsInspecting] = useState(false); const [isInspecting, setIsInspecting] = useState(false);
const [expandedRows, setExpandedRows] = useState<Record<string, boolean>>({}); const [expandedRows, setExpandedRows] = useState(() => new Set<number>());
// vt scrollbar accounting for column auto-sizing // vt scrollbar accounting for column auto-sizing
const visibleFields = useMemo(() => getVisibleFields(data.fields), [data.fields]); const visibleFields = useMemo(() => getVisibleFields(data.fields), [data.fields]);
@@ -517,12 +517,19 @@ export function TableNG(props: TableNGProps) {
}, },
renderCell: ({ row }) => { renderCell: ({ row }) => {
if (row.__depth === 0) { if (row.__depth === 0) {
const rowIdx = row.__index;
return ( return (
<RowExpander <RowExpander
height={defaultRowHeight} height={defaultRowHeight}
isExpanded={expandedRows[row.__index] ?? false} isExpanded={expandedRows.has(rowIdx)}
onCellExpand={() => { onCellExpand={() => {
setExpandedRows({ ...expandedRows, [row.__index]: !expandedRows[row.__index] }); if (expandedRows.has(rowIdx)) {
expandedRows.delete(rowIdx);
} else {
expandedRows.add(rowIdx);
}
setExpandedRows(new Set(expandedRows));
}} }}
/> />
); );
@@ -710,16 +717,11 @@ export function TableNG(props: TableNGProps) {
* this is passed to the top-level `renderRow` prop on DataGrid. applies aria attributes and custom event handlers. * this is passed to the top-level `renderRow` prop on DataGrid. applies aria attributes and custom event handlers.
*/ */
const renderRowFactory = const renderRowFactory =
( (fields: Field[], panelContext: PanelContext, expandedRows: Set<number>, enableSharedCrosshair: boolean) =>
fields: Field[],
panelContext: PanelContext,
expandedRows: Record<string, boolean>,
enableSharedCrosshair: boolean
) =>
(key: React.Key, props: RenderRowProps<TableRow, TableSummaryRow>): React.ReactNode => { (key: React.Key, props: RenderRowProps<TableRow, TableSummaryRow>): React.ReactNode => {
const { row } = props; const { row } = props;
const rowIdx = row.__index; const rowIdx = row.__index;
const isExpanded = !!expandedRows[rowIdx]; const isExpanded = expandedRows.has(rowIdx);
// Don't render non expanded child rows // Don't render non expanded child rows
if (row.__depth === 1 && !isExpanded) { if (row.__depth === 1 && !isExpanded) {
@@ -441,7 +441,7 @@ interface UseRowHeightOptions {
hasNestedFrames: boolean; hasNestedFrames: boolean;
defaultHeight: number; defaultHeight: number;
headerHeight: number; headerHeight: number;
expandedRows: Record<string, boolean>; expandedRows: Set<number>;
typographyCtx: TypographyCtx; typographyCtx: TypographyCtx;
} }
@@ -497,9 +497,9 @@ export function useRowHeight({
return (row: TableRow) => { return (row: TableRow) => {
// nested rows // nested rows
if (Number(row.__depth) > 0) { if (row.__depth > 0) {
// if unexpanded, height === 0 // if unexpanded, height === 0
if (!expandedRows[row.__index]) { if (!expandedRows.has(row.__index)) {
return 0; return 0;
} }
@@ -512,10 +512,10 @@ export const processNestedTableRows = (
const childRows: Map<number, TableRow> = new Map(); const childRows: Map<number, TableRow> = new Map();
for (const row of rows) { for (const row of rows) {
if (Number(row.__depth) === 0) { if (row.__depth === 0) {
parentRows.push(row); parentRows.push(row);
} else { } else {
childRows.set(Number(row.__index), row); childRows.set(row.__index, row);
} }
} }
@@ -526,7 +526,7 @@ export const processNestedTableRows = (
const result: TableRow[] = []; const result: TableRow[] = [];
processedParents.forEach((row) => { processedParents.forEach((row) => {
result.push(row); result.push(row);
const childRow = childRows.get(Number(row.__index)); const childRow = childRows.get(row.__index);
if (childRow) { if (childRow) {
result.push(childRow); result.push(childRow);
} }