freeCodeCamp icon indicating copy to clipboard operation
freeCodeCamp copied to clipboard

Implement Table component

Open JordanMooree opened this issue 2 years ago • 3 comments

Current specs

  • Variants:
    • Dark
    • Light
  • Types of tables:
    • Condensed
    • Striped
    • Bordered
    • Borderless
  • Sizes (for responsive mode):
    • Large (lg)
    • Medium (md) (default)
    • Small (sm)
  • a11y best practices for tables?

Screenshots

Usage Light theme Dark theme
Timeline on user profile image image
User settings under certifications image image

Table component is only used in the timeline and in the user settings

Implementation plan

Use the bootstrap v3.3.7 stylesheet for styling references and the react bootstrap table component source for implementation reference.

Props interface

Prop Type Required Default Note
variant 'light' | 'dark'
size 'large' | 'medium' | 'small' 'medium'
bordered boolean
borderless boolean
hover boolean Hover state on table rows within a <tbody>.
responsive boolean
striped boolean
className string

Table layout

We should just use Tailwind's table-auto utility class for the Table component as the default since according to Tailwind:

...it will allow the table to automatically size columns to fit the contents of the cell.

Reference:

Delivery plan (Will add more as needed)

  • [x] Remove Table Component with new basic one (variant, sizes, etc.) - #47263
  • [ ] Create tests for a11y - #48823

JordanMooree avatar Aug 09 '22 21:08 JordanMooree

Regarding accessibility for tables, if the table is rather simple then there is really not a lot you need to do to make it accessible other than using the native table elements properly. The link you have to table best practices above is a description of the different roles that are assigned to the various table elements, which is helpful for when you aren't using the native HTML elements. But you should always use the native HTML elements, so I would just ignore that link :smile:

Some accessibility considerations for tables:

  • Providing a caption is a good accessibility practice but it is not a requirement.
  • Although it seems like they would be helpful, the thead, tfoot and tbody elements provide no accessibility functionality at all. For sure there are other reasons to include them, but accessibility is not one of them.
  • Very simple tables do not really need any further help, but as your tables get more complex, especially the header structure, then you may need to use the scope attribute on the headers. And for very complex tables you will need to use the headers attribute on the data cells, which will require adding ids to the headers. You can get examples of all of these levels of complexity at W3C Tables Tutorial.
  • As for navigating the tables with screen readers, there is nothing that needs to be done to assist with this. Screen readers have their own built in key commands for navigating tables. You do not need to add tabindex attributes or anything else to help screen reader users.
  • While it is great to try and make tables responsive, it is not a requirement. Tables are allowed to scroll horizontally if needed. They are considered to be "two-dimensional data" elements and thus are exempt from the reflow requirements dictated under WCAG 1.4.10.
  • Regarding horizontal scroll, while all browsers will automatically add a scroll bar for tables if you narrow the browser skinnier than the table, unfortunately only Firefox makes that scroll bar keyboard accessible at the moment. So if there is a chance your table will scroll, then to be really accessible you need to wrap the table in a div, give it a role of region, and assign it an accessible name (most people use the table caption). A good description of how to do this can be found at Under-Engineered Responsive Tables.

bbsmooth avatar Aug 12 '22 23:08 bbsmooth

For the props, we should only implement the props that are used in learn such as striped, condensed, etc. The aim for the first sprint of the component library is to create only what we use. In the upcoming sprints, we will improve those components and make them more usable.

ahmaxed avatar Aug 15 '22 09:08 ahmaxed

A few issues I've encountered while implementing the table:

I saw the following bootstrap CSS code for the table:

.table > thead > tr > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {
  padding: 8px;
  line-height: 1.42857143;
  vertical-align: top;
  border-top: 1px solid #ddd;
}

Notice this would require multiple tailwind variants to work. Then if I were to want my table condensed, it would require the following CSS:

.table-condensed > thead > tr > th,
.table-condensed > tbody > tr > th,
.table-condensed > tfoot > tr > th,
.table-condensed > thead > tr > td,
.table-condensed > tbody > tr > td,
.table-condensed > tfoot > tr > td {
  padding: 5px;
}

I tried adding a variant with the following code(tried with * and without it):

addVariant('table-children', '& * > thead > tr > th, * > tbody > tr > th, * > tfoot > tr > th, * > thead > tr > td, * > tbody > tr > td, * > tfoot > tr > td');

but it doesn't work. It will get messy quickly if I add multiple tailwind variants.

JordanMooree avatar Aug 30 '22 21:08 JordanMooree