Skip to content

Commit

Permalink
feat(Table): aria-(colcount,colindex,rowcount,rowindex) support added (
Browse files Browse the repository at this point in the history
  • Loading branch information
DanisAvko authored Aug 16, 2024
1 parent 81987fe commit e07d74a
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 7 deletions.
5 changes: 3 additions & 2 deletions src/components/FooterRow/FooterRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {FooterCellProps} from '../FooterCell';
import {FooterCell} from '../FooterCell';
import {b} from '../Table/Table.classname';

export interface FooterRowProps<TData, TValue> {
export interface FooterRowProps<TData, TValue> extends React.TdHTMLAttributes<HTMLTableRowElement> {
cellClassName: FooterCellProps<TData, TValue>['className'];
className?: string;
footerGroup: HeaderGroup<TData>;
Expand All @@ -16,6 +16,7 @@ export const FooterRow = <TData, TValue>({
cellClassName,
className,
footerGroup,
...restProps
}: FooterRowProps<TData, TValue>) => {
const isEmptyRow = footerGroup.headers.every((header) => !header.column.columnDef.footer);

Expand All @@ -24,7 +25,7 @@ export const FooterRow = <TData, TValue>({
}

return (
<tr className={b('footer-row', className)}>
<tr className={b('footer-row', className)} {...restProps}>
{footerGroup.headers.map((header) => (
<FooterCell key={header.column.id} className={cellClassName} header={header} />
))}
Expand Down
8 changes: 7 additions & 1 deletion src/components/HeaderCell/HeaderCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import React from 'react';
import type {Header} from '@tanstack/react-table';
import {flexRender} from '@tanstack/react-table';

import {getAriaSort, getCellStyles, getHeaderCellClassModes} from '../../utils';
import {
getAriaSort,
getCellStyles,
getHeaderCellAriaColIndex,
getHeaderCellClassModes,
} from '../../utils';
import type {ResizeHandleProps} from '../ResizeHandle';
import {ResizeHandle} from '../ResizeHandle';
import type {SortIndicatorProps} from '../SortIndicator';
Expand Down Expand Up @@ -73,6 +78,7 @@ export const HeaderCell = <TData, TValue>({
onClick={header.column.getToggleSortingHandler()}
style={getCellStyles(header)}
aria-sort={getAriaSort(header.column.getIsSorted())}
aria-colindex={getHeaderCellAriaColIndex(header)}
{...attributes}
>
{flexRender(header.column.columnDef.header, header.getContext())}{' '}
Expand Down
6 changes: 4 additions & 2 deletions src/components/HeaderRow/HeaderRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {HeaderCell} from '../HeaderCell';
import type {ResizeHandleProps} from '../ResizeHandle';
import {b} from '../Table/Table.classname';

export interface HeaderRowProps<TData, TValue> {
export interface HeaderRowProps<TData, TValue>
extends Omit<React.TdHTMLAttributes<HTMLTableRowElement>, 'className'> {
cellClassName?: HeaderCellProps<TData, TValue>['className'];
className?:
| string
Expand Down Expand Up @@ -38,6 +39,7 @@ export const HeaderRow = <TData, TValue>({
sortIndicatorClassName,
attributes: attributesProp,
cellAttributes,
...restProps
}: HeaderRowProps<TData, TValue>) => {
const className = React.useMemo(() => {
return typeof classNameProp === 'function'
Expand All @@ -51,7 +53,7 @@ export const HeaderRow = <TData, TValue>({
: attributesProp;

return (
<tr className={b('header-row', className)} {...attributes}>
<tr className={b('header-row', className)} {...restProps} {...attributes}>
{headerGroup.headers.map((header) => (
<HeaderCell
key={header.column.id}
Expand Down
7 changes: 6 additions & 1 deletion src/components/Row/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import type {GroupHeaderProps} from '../GroupHeader';
import {GroupHeader} from '../GroupHeader';
import {b} from '../Table/Table.classname';

export interface RowProps<TData, TScrollElement extends Element | Window = HTMLDivElement> {
export interface RowProps<TData, TScrollElement extends Element | Window = HTMLDivElement>
extends Omit<React.TdHTMLAttributes<HTMLTableRowElement>, 'className' | 'onClick'> {
cellClassName?: CellProps<TData>['className'];
className?: string | ((row: RowType<TData>) => string);
getGroupTitle?: (row: RowType<TData>) => React.ReactNode;
Expand Down Expand Up @@ -59,6 +60,7 @@ export const Row = React.forwardRef(
virtualItem,
attributes: attributesProp,
cellAttributes,
...restProps
}: RowProps<TData, TScrollElement>,
ref: React.Ref<HTMLTableRowElement>,
) => {
Expand Down Expand Up @@ -89,6 +91,7 @@ export const Row = React.forwardRef(
className={cellClassName}
colSpan={row.getVisibleCells().length}
attributes={cellAttributes}
aria-colindex={1}
>
{renderGroupHeader ? (
renderGroupHeader({
Expand Down Expand Up @@ -119,6 +122,7 @@ export const Row = React.forwardRef(
cell={cell}
className={cellClassName}
attributes={cellAttributes}
aria-colindex={cell.column.getIndex() + 1}
/>
));
};
Expand All @@ -143,6 +147,7 @@ export const Row = React.forwardRef(
)}
onClick={handleClick}
data-index={virtualItem?.index}
{...restProps}
{...attributes}
>
{renderRowContent()}
Expand Down
13 changes: 12 additions & 1 deletion src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,20 @@ export const Table = React.forwardRef(
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 footerRowCount = footerGroups ? footerGroups.length : 0;
const rowCount = bodyRowCount + headerRowCount + footerRowCount;

return (
<TableContextProvider getRowByIndex={getRowByIndex} enableNesting={enableNesting}>
<table
ref={ref}
className={b({'with-row-virtualization': Boolean(rowVirtualizer)}, className)}
data-dragging-row-index={draggingRowIndex > -1 ? draggingRowIndex : undefined}
aria-colcount={colCount > 0 ? colCount : undefined}
aria-rowcount={rowCount > 0 ? rowCount : undefined}
{...attributes}
>
{headerGroups && (
Expand All @@ -136,6 +144,7 @@ export const Table = React.forwardRef(
sortIndicatorClassName={sortIndicatorClassName}
attributes={headerRowAttributes}
cellAttributes={headerCellAttributes}
aria-rowindex={index + 1}
/>
))}
</thead>
Expand Down Expand Up @@ -167,6 +176,7 @@ export const Table = React.forwardRef(
virtualItem: rowVirtualizer
? (virtualItemOrRow as VirtualItem<HTMLTableRowElement>)
: undefined,
'aria-rowindex': headerRowCount + row.index + 1,
};

if (draggableContext) {
Expand All @@ -178,12 +188,13 @@ export const Table = React.forwardRef(
</tbody>
{footerGroups && (
<tfoot className={b('footer', {sticky: stickyFooter}, footerClassName)}>
{footerGroups.map((footerGroup) => (
{footerGroups.map((footerGroup, index) => (
<FooterRow
key={footerGroup.id}
cellClassName={footerCellClassName}
className={footerRowClassName}
footerGroup={footerGroup}
aria-rowindex={headerRowCount + bodyRowCount + index + 1}
/>
))}
</tfoot>
Expand Down
7 changes: 7 additions & 0 deletions src/utils/getHeaderCellAriaColIndex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type {Header} from '@tanstack/react-table';

export const getHeaderCellAriaColIndex = <TData>(header: Header<TData, unknown>): number => {
return header.headerGroup.headers
.slice(0, header.index)
.reduce((acc, value) => acc + value.colSpan, 1);
};
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export * from './getAriaSort';
export * from './getCellClassModes';
export * from './getCellStyles';
export * from './getColumnPinningClassModes';
export * from './getHeaderCellAriaColIndex';
export * from './getHeaderCellClassModes';
export * from './getVirtualRowRangeExtractor';

0 comments on commit e07d74a

Please sign in to comment.