Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor shadowdom #77

Merged
merged 10 commits into from
Feb 16, 2024
Merged

Refactor shadowdom #77

merged 10 commits into from
Feb 16, 2024

Conversation

keithamus
Copy link
Member

This refactors tab container to make extensive use of the shadowdom.

Each commit describes the benefits and features of this refactor so it's best to read each commit.

This refactors tab container to make extensive use of the shadowdom.
This allows us to be smarter about a few things:

 - The `role=tablist` can be omitted, and the component will simply provide it.
   This makes it easier to author a tablist that is accessible because the
   only required markup is some `<button role=tab>` with some
   `<button role=panel>`.
 - The `role=panel` gets manually assigned which means it's far harder
   to show two tab-panels at once. With the current implementation it
   can sometimes get into states where more than the current panel is
   visible. With assignedSlot this is close to impossible.
 - Much of the required aria markup can be hidden away in the shadowdom
   which means consumers are less able to influence it, allowing us to
   keep tighter control of it.
If the root `<tab-container>` element is given aria-label or
aria-description this often results in a slightly weird accessibility
tree because the root container is a generic role. The label/description
_should_ be on the tablist role. This makes that happen by detecting
the aria-* attributes on tablist and moving them appropriately.
This enables `<tab-container vertical>` for a much more ergonomic way to
create & style tab containers. This also automatically handles the
necessary aria markup for the tablist.
The current `<tab-container>` is generic role, which is fine except for
it makes for a messier AT than necessary. The `<tab-container>` itself
_is_ a presentational element (the real AT relevant elements are the
tablist, tabs, and panels), so this change makes that explicit by
setting role=presentation to the tab-container.
By default tabListSlot is `display:contents` which can cause a couple of
issues:

 1. Some browsers don't expose role information for elements that are
    display:contents, and so this makes an inaccessible component.
 2. Depending on how the tabs are styled, they can end up in weird
    orientations due to the tablist having no layout. Making it have a
    layout with display:block fixes this.
Prior to using shadowdom, the tab container allowed for elements
interspersed between the tabs and panels. This re-introduces that using
Slots for more precise markup. This works well wrt elements that are
before or after tabs given that a tablist can only have tab role
children.
@keithamus keithamus requested a review from a team as a code owner February 16, 2024 15:50
Copy link
Member

@owenniblock owenniblock left a comment

Choose a reason for hiding this comment

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

Love it! A few non-blocking thoughts.

src/tab-container-element.ts Outdated Show resolved Hide resolved
src/tab-container-element.ts Outdated Show resolved Hide resolved
src/tab-container-element.ts Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
@owenniblock
Copy link
Member

Also, thanks for breaking up the PR so nicely!

@keithamus keithamus merged commit 3a0377f into main Feb 16, 2024
1 check passed
@keithamus keithamus deleted the refactor-shadowdom branch February 16, 2024 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants