Skip to content
This repository has been archived by the owner on Jun 5, 2023. It is now read-only.

feat: New component SelectableTable, #143 #145

Merged
merged 16 commits into from
Aug 2, 2021
Merged

feat: New component SelectableTable, #143 #145

merged 16 commits into from
Aug 2, 2021

Conversation

diondiondion
Copy link
Member

@diondiondion diondiondion commented Jul 15, 2021

Adds a new SelectionTable component that supports a roving tab index, table row multi and range selection, and advanced keyboard navigation.

Feature-wise it should now be ready to replace the hub's admin main tables on any pages that don't require drag-and-drop table row ordering, subheaders/subsections, or table rows that are non-selectable.

This is a very large PR, and also includes tests for the component, as well as new supplementary components and hooks.

range-selection


Overview

The following is an excerpt from the revised Table readme, it should give a good overview of the new props and functionality.

Table row selection

You can make the rows of your table selectable. To do this, use the SelectionTable component instead of the regular Table component:

import {SelectionTable, Column, InteractiveTableContent} from 'base5-ui/Table';

SelectionTable props

The SelectionTable component is identical to the regular Table component, but has some extra props to facilitate selection. Its selection state is controlled, meaning that you have to pass in the selected items and a function to update it in response to changes. The keyboard navigation & highlighting state however is owned by SelectionTable and can't be controlled from the outside.

  • getItemLabel - func: A function that's called with a row object and must return a human-readable string that identifies the row.
  • selectedItems - string[] | number[]: An array of the keys/ids of all currently selected items. The keys must match those obtained using the keyBy prop (data.item[keyBy]).
  • onChangeSelectedItems - func: Function that's called whenever the table selection changes. It's called with an array of all selected items in the shape of the selectedItems prop.

The SelectionTable component also has additional accessibility labels. Those are detailed in the Customise accessibility labels section below.

SelectionTable navigation and keyboard shortcuts

You can click anywhere on a row to select it and de-select all other rows, or click the checkboxes to add or remove rows from the selection.

Hold Cmd (Mac) or Ctrl (Windows) while clicking anywhere on a row to select or deselect it. Hold Shift while clicking on a row to select all rows between the row you clicked and the one you clicked before.

SelectionTable also allows navigating the rows of your table via keyboard:

  • When the table is focused, press up or down to highlight the previous or next row. Press left or right to focus the previous or next table cell. If the cell contains interactive elements (buttons, links), focus will be placed on the first focusable element.
  • Press Home or End to highlight the first or last row of the table.
  • Hold Shift while navigating up and down to select the current and the previous or next row.
  • Press Ctrl + A to select or deselect all rows.

Interactive nested content

Because you can click anywhere on a table row to select it, you need to wrap any interactive elements that you want to render in the table with the InteractiveTableContent component. This will make sure that the nested elements can be interacted with without interfering with table selection.

Note how the "Open" button in the "Name" column below is wrapped with InteractiveTableContent, and clicking it will not change the selected table row.

@diondiondion diondiondion marked this pull request as ready for review July 21, 2021 16:22
@diondiondion diondiondion requested a review from a team July 21, 2021 16:23
@@ -66,6 +68,7 @@
"prop-types": "^15.7.2",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"regenerator-runtime": "^0.13.7",
Copy link
Member Author

@diondiondion diondiondion Jul 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to add this and babel-jest to be able to run async test functions (e.g. await screen.findByRole(...)). It seems like normally this shouldn't be necessary, but I couldn't find another way. Would be good to look into that later.

@diondiondion diondiondion merged commit 8403397 into master Aug 2, 2021
@diondiondion diondiondion deleted the grid-table branch August 2, 2021 14:32
@5app-Machine
Copy link
Contributor

🎉 This PR is included in version 13.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants