- Do use a table when showing in-depth information to users who want to get into the details:
- Do use a table to show raw data in a table form, for example energy use data over a period of time
- Do use to provide a detailed comparison between similar products, for example Anytime EV charging plans tailored for casual, irregular, regular and high-mileage drivers
- Try to follow a progressive disclosure pattern and start with high-level information, offering detailed tables to users who want them.
Don't use a table to give users every available piece of information at the start of a journey, as it can overwhelm and be inaccessible.
Don't use for creating layouts or displaying information that is not strictly tabular.
Live example
In Figma, DataTable is designed to be used as a buildable block as opposed to one full component. It is responsive and can be stretched.
Availabile platforms
Platform |
Available |
---|---|
Figma |
v1+ |
Web (@ovotech/element) |
v1+ |
App (@ovotech/element-native) |
v1+ |
How to use it
Tables are made of a series of sub-componets:
Caption
Use a caption to give the table context. It helps accessibility as it will be read out by screenreaders. You can put a heading in a caption.
Table Heading
Use a table heading to describe the general content of the data table.
Row headers
- Use row headers to describe the data.
- Row headers can also be react elements, allowing greater customisation.
Separator rows
From versions 3.4.0 (web) and 3.5.0 (native), it is possible to add separator rows in order to break down data into groups as desired. These are added in as items as per the API described in the Properties below.
Striped rows
Striping is the background zebra-striping on rows, not the separating lines. You can enable or disable striping for the entire table. It is enabled by default.
Column width
On web you can optionally assign a fixed width to columns.
Native
Widths are required on Native. Passing auto for width on Native will set the flex property to 1, allowing it to stretch.
With children
Instead of using the props to generate the table, you can specify the caption, headers and body of the table as children.
Properties
These are the properties for anyone implementing this component and code.
DataTable
Name |
Values |
Default |
---|---|---|
items |
ReactNode[][] | SeparatorRow[][] |
|
columnHeadings |
ReactNode[] |
|
caption |
ReactNode |
|
rowHeadings |
Boolean |
false |
striped |
boolean |
true |
columnWidths |
string[] |
|
... |
JSX.IntrinsicElements["table"] |
|
SeparatorRow
Name |
Values |
Default |
---|---|---|
isSeparator |
Boolean |
|
content |
string |
|
TableCaption
Name |
Values |
Default |
---|---|---|
... |
JSX.IntrinsicElements["caption"] |
|
TableHead
Name |
Values |
Default |
---|---|---|
... |
JSX.IntrinsicElements["thead"] |
|
TableHeader
Name |
Values |
Default |
---|---|---|
cellWidth |
string |
|
... |
JSX.IntrinsicElements["th"] |
|
TableBody
Name |
Values |
Default |
---|---|---|
... |
JSX.IntrinsicElements["tbody"] |
|
TableRow
Name |
Values |
Default |
---|---|---|
stripe |
boolean |
false |
... |
JSX.IntrinsicElements["tr"] |
|
TableCell
Name |
Values |
Default |
---|---|---|
cellWidth |
string |
|
... |
JSX.IntrinsicElements["td"] |
|
TableRowHeader
Name |
Values |
Default |
---|---|---|
cellWidth |
string |
|
... |
JSX.IntrinsicElements["th"] |
|
Checking for accessibility
User stories
The following user stories can be used to understand when this component should be used, and how to know when it's been implemented correctly.
- As a keyboard-only user, only when scrolling is present, I want to be able to navigate to the table using Tab and scroll using the arrow keys.
- As a screen reader user, I want to be able to quickly understand the content contained within the table from the table's caption.
- As a screen reader user, I want to be able to understand the structure of the table, with information about headings present, and content announced in a meaningful order, matching the visual presentation.
- As a screen reader user, when scrolling is present, I want to be able to navigate to the table and have the name of it announced so that I know what I am interacting with.
Test steps
Use these steps to check that the data table component has been implemented correctly:
- Turn on a screen reader.
- Navigate to the table.
- If a caption is present, verify that it is announced correctly.
- Verify that headings are announced as such.
- As the screen reader announces the content in the table, verify it does such in a way that matches the visual presentation of the table, and that the meaning of the information is conveyed appropriately.
Known defects
We're aware of the following defects and have provided ways that these can be manually resolved, until this component is updated:
- When the viewport becomes small enough, the datatables allow for scrolling, but cannot be scrolled using only a keyboard. To resolve this, where possible, allow the table to receive focus by adding a tabindex="0" attribute to the scrollable container, update the role to be role="region" and provide it with a sensible accessible name (using the table's caption, if there is one). The accessible name can be added by providing an aria-label attribute to the scrollable container. When scrolling is not present as the viewport is large enough, the container should not receive focus as there is no longer any need. This behaviour can be managed using the ResizeObserver API, ensuring that the container can only be navigated to when it is small enough to require scrolling.
External resources