Skip to content

Commit

Permalink
fix(BaseTable): calc aria-rowindex fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
DanisAvko committed Sep 12, 2024
1 parent 951b48c commit 4613810
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 4 deletions.
15 changes: 12 additions & 3 deletions src/components/BaseTable/BaseTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import React from 'react';
import type {Row, Table} from '@tanstack/react-table';
import type {VirtualItem, Virtualizer} from '@tanstack/react-virtual';

import {getAriaMultiselectable, getCellClassModes, shouldRenderFooterRow} from '../../utils';
import {
getAriaMultiselectable,
getAriaRowIndexMap,
getCellClassModes,
shouldRenderFooterRow,
} from '../../utils';
import {BaseDraggableRow} from '../BaseDraggableRow';
import type {BaseFooterRowProps} from '../BaseFooterRow';
import {BaseFooterRow} from '../BaseFooterRow';
Expand Down Expand Up @@ -145,12 +150,16 @@ export const BaseTable = React.forwardRef(

const {rows} = table.getRowModel();

const ariaRowIndexMap = React.useMemo(() => {
return getAriaRowIndexMap(rows);
}, [rows]);

const headerGroups = withHeader && table.getHeaderGroups();
const footerGroups = withFooter && table.getFooterGroups();

const colCount = table.getVisibleLeafColumns().length;
const headerRowCount = headerGroups ? headerGroups.length : 0;
const bodyRowCount = rows.length;
const bodyRowCount = Object.keys(ariaRowIndexMap).length;
const footerRowCount = footerGroups ? footerGroups.length : 0;
const rowCount = bodyRowCount + headerRowCount + footerRowCount;

Expand Down Expand Up @@ -195,7 +204,7 @@ export const BaseTable = React.forwardRef(
rowVirtualizer,
table,
virtualItem: rowVirtualizer ? (virtualItemOrRow as VirtualItem) : undefined,
'aria-rowindex': headerRowCount + row.index + 1,
'aria-rowindex': headerRowCount + ariaRowIndexMap[row.id],
'aria-selected': table.options.enableRowSelection
? row.getIsSelected()
: undefined,
Expand Down
5 changes: 5 additions & 0 deletions src/components/BaseTable/__stories__/BaseTable.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {EmptyContentStory} from './stories/EmptyContentStory';
import {GroupingStory} from './stories/GroupingStory';
import {GroupingStory2} from './stories/GroupingStory2';
import {GroupingWithSelectionStory} from './stories/GroupingWithSelectionStory';
import {GroupingWithVirtualizationStory} from './stories/GroupingWithVirtualizationStory';
import {HeaderGroupsStory} from './stories/HeaderGroupsStory';
import {ReorderingStory} from './stories/ReorderingStory';
import {ReorderingTreeStory} from './stories/ReorderingTreeStory';
Expand Down Expand Up @@ -85,6 +86,10 @@ export const WindowVirtualization: StoryObj<typeof WindowVirtualizationStory> =
render: WindowVirtualizationStory,
};

export const GroupingWithVirtualization: StoryObj<typeof GroupingWithVirtualizationStory> = {
render: GroupingWithVirtualizationStory,
};

export const ReorderingWithVirtualization: StoryObj<typeof ReorderingWithVirtualizationStory> = {
render: ReorderingWithVirtualizationStory,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';

import type {ExpandedState, Row} from '@tanstack/react-table';

import {useTable, useWindowRowVirtualizer} from '../../../../hooks';
import {BaseTable} from '../../BaseTable';
import {columns} from '../constants/columns';
import type {Item} from '../types';
import {generateData} from '../utils';

import {cnVirtualizationStory} from './VirtualizationStory.classname';

const data = generateData(300);
const grouping: Array<keyof Item> = ['status', 'age'];

import './VirtualizationStory.scss';

const getGroupTitle = (row: Row<Item>) => row.getValue<string>('name');
const getIsGroupHeaderRow = (row: Row<Item>) => row.getIsGrouped();

export const GroupingWithVirtualizationStory = () => {
const [expanded, setExpanded] = React.useState<ExpandedState>({});

const table = useTable({
columns,
data,
getRowId: (item) => item.id,
enableExpanding: true,
enableGrouping: true,
onExpandedChange: setExpanded,
state: {
expanded,
grouping,
},
});

const rowVirtualizer = useWindowRowVirtualizer({
count: table.getRowModel().rows.length,
estimateSize: () => 20,
overscan: 5,
});

return (
<BaseTable
table={table}
rowVirtualizer={rowVirtualizer}
getGroupTitle={getGroupTitle}
getIsGroupHeaderRow={getIsGroupHeaderRow}
className={cnVirtualizationStory()}
headerClassName={cnVirtualizationStory('header')}
stickyHeader
/>
);
};
20 changes: 20 additions & 0 deletions src/utils/getAriaRowIndexMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type {Row} from '@tanstack/react-table';

export const getAriaRowIndexMap = <TData>(rows: Row<TData>[]) => {
let rowIndex = 1;

return rows.reduce<Record<string, number>>((acc, row, index, arr) => {
const newMap = {
...acc,
[row.id]: rowIndex,
};

const nextRow = arr[index + 1];
if (nextRow?.parentId !== row.id) {
rowIndex += row.getLeafRows().length;
}
rowIndex++;

return newMap;
}, {});
};
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './cn';
export * from './getAriaMultiselectable';
export * from './getAriaRowIndexMap';
export * from './getAriaSort';
export * from './getCellClassModes';
export * from './getCellStyles';
Expand Down
2 changes: 1 addition & 1 deletion src/utils/shouldRenderFooterRow.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {HeaderGroup} from '@tanstack/react-table';

export const shouldRenderFooterRow = <TData>(footerGroup: HeaderGroup<TData>) => {
return footerGroup.headers.every((header) => !header.column.columnDef.footer);
return footerGroup.headers.some((header) => header.column.columnDef.footer);
};

0 comments on commit 4613810

Please sign in to comment.