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

(Fix): Whitespace in Tab Labels #5284

Closed

Conversation

axelEandrews
Copy link
Contributor

@axelEandrews axelEandrews commented May 31, 2024

Description of changes

Generates ID without whitespace for each tab component.

Example: A tab declared with value="Tab 1" produces the following HTML output <button role="tab" id="Tab-1-tab" aria-selected="true" aria-controls="Tab-1-panel" class="amplify-tabs__item amplify-tabs__item--active">Tab 1</button>

Issue #, if available

Fixes #5220

Description of how you validated changes

Inspected elements in Tabs Docs, IDs now contain no whitespace and are unique.

Checklist

  • Have read the Pull Request Guidelines
  • PR description included
  • Relevant documentation is changed or added (and PR referenced)
  • yarn test passes and tests are updated/added
  • No side effects or sideEffects field updated

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@axelEandrews axelEandrews requested a review from a team as a code owner May 31, 2024 19:06
Copy link

changeset-bot bot commented May 31, 2024

⚠️ No Changeset found

Latest commit: 6009122

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@esauerbo esauerbo added the run-tests Adding this label will trigger tests to run label May 31, 2024
Copy link
Contributor

@zchenwei zchenwei left a comment

Choose a reason for hiding this comment

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

This looks good. Could we add unit tests for the updates? You probably want to reference how spyOn works in jest https://jestjs.io/docs/jest-object#jestspyonobject-methodname. Then you are able to test the call to useStableId and mock its return value.

@axelEandrews
Copy link
Contributor Author

@zchenwei I added tests to confirm that the IDs are unique and that they follow the naming convention to end in '-tab'.

@reesscot
Copy link
Member

reesscot commented Jun 1, 2024

Can you please add an HTML output example in the description to show the full id that's generated?

id={`${value}-panel`}
aria-labelledby={`${value}-tab`}
id={`${idValue}-panel`}
aria-labelledby={`${idValue}-tab`}
Copy link
Contributor

Choose a reason for hiding this comment

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

If we are using useStableId in 2 different components, wouldn't that generate 2 different IDs? We need aria-labelledby in this component to be the id of the TabItem and vice-versa with aria-controls and this id

Copy link
Contributor

Choose a reason for hiding this comment

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

oh, thats true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I switched it back to using the given value, with spaces replaced with - to ensure the all of the labels work cohesively. This relies on the user giving each tab a unique value.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we think of another solution to providing a unique id? Maybe passing a React.useId or useStableId down through context so it is shared? @zchenwei any thoughts on that?

I think it creates sort of a "hidden" requirement that each value has to be unique because it is also happens to be used to generate the ID. It also creates a scenario where the developer has to track down the cause of duplicate IDs or potentially inaccessible markup. This should be something we can safely back into the component. An example is if you inspect that markup and usage of the Radix Tabs component https://www.radix-ui.com/primitives/docs/components/tabs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking at the Radix implementation, they still rely on the user-inputed value to create their full IDs. They feed the value into functions to create the trigger ID and the content ID, both based off of one baseID for the entire tab group. In their implementation, so if the user chose to input the same value for multiple tabs in the same group they'd run into the same issue. What their solution does address is having multiple tab groups on the same page, because the baseID will be different, and thus two tabs with value "Tab 1" will result in trigger ids: {baseID}-trigger-Tab 1, where the baseID will be different.

Essentially, it looks they are guaranteeing that so long as you declare unique values for each tab in a tab list, you won't run into any issues, but I believe that there is still that dependance on the user entering unique values.

Screenshot 2024-06-04 at 12 16 54 PM

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, the issue is not so much with tabs within the same tab group, but for multiple Tab components in the DOM at the same time that use the same tab names. Within the same tab group, I think it's reasonable that users should specify unique tab names. But for multiple sets of the same tab names on a page, that should be something we can build into this component by generating a unique ID (like the baseId that Radix generates) that is used to build out the ID string.

An example of this is our Docs site that sometimes uses multiple tab components on a page, like the docs for adding Facebook login, Google login, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
run-tests Adding this label will trigger tests to run
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug(react/a11y): Tabs primitive uses malformed id values with spaces in them
6 participants