Skip to content

Commit

Permalink
implement accessible grid, make scroll container elements overridable
Browse files Browse the repository at this point in the history
  • Loading branch information
priley86 committed May 17, 2019
1 parent a61d00f commit b0f2de1
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ const propTypes = {
throw new Error('Specify at least one of: header, caption, aria-label');
}
return null;
}
},
role: PropTypes.string
};

const defaultProps = {
Expand All @@ -158,7 +159,8 @@ const defaultProps = {
contentId: 'expanded-content',
dropdownPosition: DropdownPosition.right,
dropdownDirection: DropdownDirection.down,
gridBreakPoint: TableGridBreakpoint.gridMd
gridBreakPoint: TableGridBreakpoint.gridMd,
role: 'grid'
};

export const TableContext = React.createContext();
Expand Down Expand Up @@ -207,6 +209,7 @@ class Table extends React.Component {
bodyWrapper,
rowWrapper,
borders,
role,
...props
} = this.props;

Expand Down Expand Up @@ -249,7 +252,7 @@ class Table extends React.Component {
}
}}
columns={headerData}
role="grid"
role={role}
className={css(
styles.table,
gridBreakPoint && getModifier(stylesGrid, gridBreakPoint),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ exports[`Actions table 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -9207,6 +9208,7 @@ exports[`Cell header table 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -15276,6 +15278,7 @@ exports[`Collapsible nested table 1`] = `
gridBreakPoint="grid-md"
onCollapse={[Function]}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -22346,6 +22349,7 @@ exports[`Collapsible table 1`] = `
gridBreakPoint="grid-md"
onCollapse={[Function]}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -29362,6 +29366,7 @@ exports[`Compound Expandable table 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={[Function]}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -31285,6 +31290,7 @@ exports[`Header width table 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -37441,6 +37447,7 @@ exports[`Selectable table 1`] = `
onCollapse={null}
onExpand={null}
onSelect={[Function]}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -44421,6 +44428,7 @@ exports[`Simple Actions table 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -56086,6 +56094,7 @@ exports[`Simple table aria-label 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -62078,6 +62087,7 @@ exports[`Simple table caption 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -68075,6 +68085,7 @@ exports[`Simple table header 1`] = `
}
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -74072,6 +74083,7 @@ exports[`Sortable table 1`] = `
onCollapse={null}
onExpand={null}
onSort={[Function]}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -80124,6 +80136,7 @@ exports[`Table variants Breakpoint - grid 1`] = `
gridBreakPoint="grid"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -86175,6 +86188,7 @@ exports[`Table variants Breakpoint - grid-lg 1`] = `
gridBreakPoint="grid-lg"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -92226,6 +92240,7 @@ exports[`Table variants Breakpoint - grid-md 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -98277,6 +98292,7 @@ exports[`Table variants Breakpoint - grid-xl 1`] = `
gridBreakPoint="grid-xl"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -104328,6 +104344,7 @@ exports[`Table variants Breakpoint - null 1`] = `
gridBreakPoint={null}
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down Expand Up @@ -110379,6 +110396,7 @@ exports[`Table variants Size - compact 1`] = `
gridBreakPoint="grid-md"
onCollapse={null}
onExpand={null}
role="grid"
rowLabeledBy="simple-node"
rows={
Array [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type ScrollPosition = {
type Props = {
'aria-label': string,
'aria-readonly'?: boolean,
'aria-rowcount': number,

/**
* Set the width of the inner scrollable container to 'auto'.
Expand Down Expand Up @@ -217,7 +218,13 @@ type Props = {
tabIndex: ?number,

/** Width of VirtualGrid; this property determines the number of visible (vs virtualized) columns. */
width: number
width: number,

/** Scroll Container element to render */
scrollContainerComponent: string | React.ComponentType<any>,

/** Inner Scroll Container element to render */
innerScrollContainerComponent: string | React.ComponentType<any>
};

type InstanceProps = {
Expand Down Expand Up @@ -256,6 +263,7 @@ type State = {
*/
class VirtualGrid extends React.PureComponent<Props, State> {
static defaultProps = {
'aria-rowcount': 0,
'aria-label': 'grid',
'aria-readonly': true,
autoContainerWidth: false,
Expand All @@ -281,7 +289,9 @@ class VirtualGrid extends React.PureComponent<Props, State> {
scrollToRow: -1,
style: {},
tabIndex: 0,
isScrollingOptOut: false
isScrollingOptOut: false,
scrollContainerComponent: 'div',
innerScrollContainerComponent: 'div'
};

// Invokes onSectionRendered callback only when start/stop row or column indices change
Expand Down Expand Up @@ -900,7 +910,9 @@ class VirtualGrid extends React.PureComponent<Props, State> {
role,
style,
tabIndex,
width
width,
scrollContainerComponent,
innerScrollContainerComponent
} = this.props;
const { instanceProps, needToResetStyleCache } = this.state;

Expand Down Expand Up @@ -961,44 +973,50 @@ class VirtualGrid extends React.PureComponent<Props, State> {

const showNoContentRenderer = childrenToDisplay.length === 0 && height > 0 && width > 0;

return (
<table
ref={this._setScrollingContainerRef}
{...containerProps}
aria-label={this.props['aria-label']}
aria-readonly={this.props['aria-readonly']}
className={clsx('ReactVirtualized__VirtualGrid', className)}
id={id}
onScroll={this._onScroll}
role={role}
style={{
...gridStyle,
...style
}}
tabIndex={tabIndex}
>
{childrenToDisplay.length > 0 && (
<tbody
className="ReactVirtualized__VirtualGrid__innerScrollContainer"
role={containerRole}
style={{
width: autoContainerWidth ? 'auto' : totalColumnsWidth,
height: totalRowsHeight,
maxWidth: totalColumnsWidth,
maxHeight: totalRowsHeight,
overflow: 'hidden',
pointerEvents: isScrolling ? 'none' : '',
position: 'relative',
display: 'block',
...containerStyle
}}
>
{childrenToDisplay}
</tbody>
)}
{showNoContentRenderer && noContentRenderer()}
</table>
);
const scrollContainerProps = {
...containerProps,
ref: this._setScrollingContainerRef,
'aria-label': this.props['aria-label'],
'aria-rowcount': this.props['aria-rowcount'],
'aria-readonly': this.props['aria-readonly'],
className: clsx('ReactVirtualized__VirtualGrid', className),
id,
onScroll: this._onScroll,
role,
style: {
...gridStyle,
...style
},
tabIndex
};

let innerScrollContainer = null;
if (childrenToDisplay.length > 0) {
const innerScrollContainerProps = {
className: 'ReactVirtualized__VirtualGrid__innerScrollContainer',
role: containerRole,
style: {
width: autoContainerWidth ? 'auto' : totalColumnsWidth,
height: totalRowsHeight,
maxWidth: totalColumnsWidth,
maxHeight: totalRowsHeight,
overflow: 'hidden',
pointerEvents: isScrolling ? 'none' : '',
position: 'relative',
display: 'block',
...containerStyle
}
};
innerScrollContainer = React.createElement(
innerScrollContainerComponent,
innerScrollContainerProps,
childrenToDisplay
);
}
return React.createElement(scrollContainerComponent, scrollContainerProps, [
innerScrollContainer,
showNoContentRenderer && noContentRenderer()
]);
}

/* ---------------------------- Helper methods ---------------------------- */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import clsx from 'clsx';

type Props = {
'aria-label'?: string,
'aria-rowcount?': number,

/**
* Removes fixed height from the scrollingContainer so that the total height
Expand Down Expand Up @@ -194,13 +195,21 @@ export default class VirtualTableBody extends React.PureComponent<Props> {
}

render() {
const { className, noRowsRenderer, scrollToIndex, width, columns, rows } = this.props;
const { className, noRowsRenderer, scrollToIndex, width, columns, rows, tabIndex } = this.props;

const classNames = clsx('ReactVirtualized__List', className);

return (
// note: these aria props if rendered will break a11y for role="presentation"
// this approach attempts to fix non standard table grids
// see: https://www.html5accessibility.com/tests/aria-table-fix.html
<VirtualGrid
{...this.props}
aria-label={null}
aria-readonly={null}
aria-rowcount={null}
tabIndex={null}
role="presentation"
autoContainerWidth
cellRenderer={this._cellRenderer}
className={classNames}
Expand All @@ -213,6 +222,8 @@ export default class VirtualTableBody extends React.PureComponent<Props> {
scrollToRow={scrollToIndex}
columns={columns}
rows={rows}
scrollContainerComponent="table"
innerScrollContainerComponent="tbody"
/>
);
}
Expand Down
Loading

0 comments on commit b0f2de1

Please sign in to comment.