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

WB-1671: Dropdown: use combobox role in all openers #2345

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

jandrade
Copy link
Member

Summary:

Addreses an issue in WB dropdowns where we were using the button role in the
opener, which was causing issues with screen readers. This change updates the
role to combobox that is more appropriate for the dropdown opener.

Issue: https://khanacademy.atlassian.net/browse/WB-1671

Test plan:

Navigate to the dropdowns in the Storybook and verify that the role of the
opener is combobox.

More details TBD

@jandrade jandrade self-assigned this Oct 15, 2024
Copy link

changeset-bot bot commented Oct 15, 2024

🦋 Changeset detected

Latest commit: f90f127

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@khanacademy/wonder-blocks-dropdown Patch
@khanacademy/wonder-blocks-birthday-picker Patch

Not sure what this means? Click here to learn what changesets are.

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

@khan-actions-bot khan-actions-bot requested a review from a team October 15, 2024 15:21
@khan-actions-bot
Copy link
Contributor

khan-actions-bot commented Oct 15, 2024

Gerald

Required Reviewers
  • @Khan/wonder-blocks for changes to .changeset/tasty-rockets-mix.md, packages/wonder-blocks-dropdown/src/components/action-menu.tsx, packages/wonder-blocks-dropdown/src/components/dropdown-opener.tsx, packages/wonder-blocks-dropdown/src/components/multi-select.tsx, packages/wonder-blocks-dropdown/src/components/select-opener.tsx, packages/wonder-blocks-dropdown/src/components/single-select.tsx, packages/wonder-blocks-dropdown/src/components/__tests__/multi-select.test.tsx, packages/wonder-blocks-dropdown/src/components/__tests__/select-opener.test.tsx, packages/wonder-blocks-dropdown/src/components/__tests__/single-select.test.tsx

Don't want to be involved in this pull request? Comment #removeme and we won't notify you of further changes.

@jandrade jandrade removed the request for review from a team October 15, 2024 15:21
@jandrade
Copy link
Member Author

NOTE: unchecking the wonder-blocks team as I want to run some tests in webapp first.

Copy link
Contributor

github-actions bot commented Oct 15, 2024

npm Snapshot: Published

🎉 Good news!! We've packaged up the latest commit from this PR (f3a0de3) and published all packages with changesets to npm.

You can install the packages in webapp by running:

./services/static/dev/tools/deploy_wonder_blocks.js --tag="PR2345"

Packages can also be installed manually by running:

yarn add @khanacademy/wonder-blocks-<package-name>@PR2345

Copy link
Contributor

github-actions bot commented Oct 15, 2024

Size Change: +51 B (+0.05%)

Total Size: 96.4 kB

Filename Size Change
packages/wonder-blocks-dropdown/dist/es/index.js 19.2 kB +51 B (+0.27%)
ℹ️ View Unchanged
Filename Size
packages/wonder-blocks-accordion/dist/es/index.js 3.77 kB
packages/wonder-blocks-banner/dist/es/index.js 1.53 kB
packages/wonder-blocks-birthday-picker/dist/es/index.js 1.77 kB
packages/wonder-blocks-breadcrumbs/dist/es/index.js 887 B
packages/wonder-blocks-button/dist/es/index.js 4.04 kB
packages/wonder-blocks-cell/dist/es/index.js 2.01 kB
packages/wonder-blocks-clickable/dist/es/index.js 3.06 kB
packages/wonder-blocks-core/dist/es/index.js 2.9 kB
packages/wonder-blocks-data/dist/es/index.js 6.24 kB
packages/wonder-blocks-form/dist/es/index.js 6.2 kB
packages/wonder-blocks-grid/dist/es/index.js 1.36 kB
packages/wonder-blocks-icon-button/dist/es/index.js 2.95 kB
packages/wonder-blocks-icon/dist/es/index.js 871 B
packages/wonder-blocks-labeled-field/dist/es/index.js 72 B
packages/wonder-blocks-layout/dist/es/index.js 1.82 kB
packages/wonder-blocks-link/dist/es/index.js 2.28 kB
packages/wonder-blocks-modal/dist/es/index.js 5.42 kB
packages/wonder-blocks-pill/dist/es/index.js 1.65 kB
packages/wonder-blocks-popover/dist/es/index.js 4.85 kB
packages/wonder-blocks-progress-spinner/dist/es/index.js 1.52 kB
packages/wonder-blocks-search-field/dist/es/index.js 1.36 kB
packages/wonder-blocks-switch/dist/es/index.js 1.92 kB
packages/wonder-blocks-testing-core/dist/es/index.js 3.74 kB
packages/wonder-blocks-testing/dist/es/index.js 1.07 kB
packages/wonder-blocks-theming/dist/es/index.js 693 B
packages/wonder-blocks-timing/dist/es/index.js 1.8 kB
packages/wonder-blocks-tokens/dist/es/index.js 2.36 kB
packages/wonder-blocks-toolbar/dist/es/index.js 905 B
packages/wonder-blocks-tooltip/dist/es/index.js 6.99 kB
packages/wonder-blocks-typography/dist/es/index.js 1.23 kB

compressed-size-action

Copy link
Contributor

github-actions bot commented Oct 15, 2024

A new build was pushed to Chromatic! 🚀

https://5e1bf4b385e3fb0020b7073c-eokoapveme.chromatic.com/

Chromatic results:

Metric Total
Captured snapshots 0
Tests with visual changes 0
Total stories 507
Inherited (not captured) snapshots [TurboSnap] 372
Tests on the build 372

@khan-actions-bot khan-actions-bot requested a review from a team October 18, 2024 15:58
@jandrade jandrade removed the request for review from a team October 18, 2024 16:01
@khan-actions-bot khan-actions-bot requested a review from a team November 4, 2024 15:59
@jandrade jandrade changed the title WB-1671: Dropdown: use combobox role in all openers [DRAFT - DO NOT REVIEW YET] WB-1671: Dropdown: use combobox role in all openers Nov 4, 2024
@jandrade jandrade removed the request for review from a team November 15, 2024 14:59
@khan-actions-bot khan-actions-bot requested a review from a team November 25, 2024 16:37
@jandrade jandrade removed the request for review from a team November 25, 2024 16:45
@khan-actions-bot khan-actions-bot requested a review from a team December 16, 2024 15:29
@jandrade jandrade removed the request for review from a team December 16, 2024 16:25
@khan-actions-bot khan-actions-bot requested a review from a team December 16, 2024 17:18
@jandrade jandrade removed the request for review from a team December 16, 2024 17:23
@khan-actions-bot khan-actions-bot requested a review from a team January 8, 2025 23:36
@marcysutton marcysutton changed the title [DRAFT - DO NOT REVIEW YET] WB-1671: Dropdown: use combobox role in all openers WB-1671: Dropdown: use combobox role in all openers Jan 8, 2025
@marcysutton
Copy link
Member

I rebased this one to bring it up to date and I'm proposing we merge it to deal with a number of screen reader issues for Dropdowns. Essentially, we need the combobox role to specify both a label and a value for these components. The one caveat is that VoiceOver and Safari are very buggy with comboboxes in React. I plan to add additional screen reader support in a later PR using the new Announcer in #2362.

@jandrade jandrade removed their assignment Jan 9, 2025
Copy link
Member

@beaesguerra beaesguerra left a comment

Choose a reason for hiding this comment

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

Overall, looks great and improves the accessibility of our components :accessibility: 🎉
Had some comments and questions!

/**
* The role of the opener.
*/
role?: "combobox" | "button";
Copy link
Member

Choose a reason for hiding this comment

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

nit: What do you think about making the role not optional so it has to be explicitly set? "combobox" and "button" roles are quite different so making it mandatory would mean we would have to intentionally set it!

@@ -569,6 +569,7 @@ const MultiSelect = (props: Props) => {
disabled={isDisabled}
id={uniqueOpenerId}
aria-controls={dropdownId}
placeholder={noneSelected}
Copy link
Member

Choose a reason for hiding this comment

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

Should the placeholder be menuText so the aria-label changes when the selected values change? Otherwise, it'll always have an aria-label for no items selected. menuText isn't always a string though since it can be custom jsx! Or maybe the select opener wouldn't need an aria-label since the component should be used with a <label>? 🤔 What do you think!

Here's a screenshot that shows the aria-label with "0 items" while the component shows "3 items":
Screenshot 2025-01-09 at 4 05 35 PM

@@ -38,6 +38,8 @@ type SelectOpenerProps = AriaProps & {
* of this component. A placeholder has more faded text colors and styles.
*/
isPlaceholder: boolean;

placeholder?: string;
Copy link
Member

Choose a reason for hiding this comment

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

nit: What do you think about renaming the placeholder prop to ariaLabel so it is named after what it's used for? We also have the isPlaceholder prop so I was wondering how they were related (they're not 😅). Or adding prop jsdocs could help with understanding!

"@khanacademy/wonder-blocks-dropdown": patch
---

Update dropdown openers to use `role="combobox"` instead of `button`.
Copy link
Member

Choose a reason for hiding this comment

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

(very) nit: The ActionMenu also uses DropdownOpener and it still uses role="button"!

Suggested change
Update dropdown openers to use `role="combobox"` instead of `button`.
Update dropdown openers for SingleSelect and MultiSelect to use `role="combobox"` instead of `button`.

@@ -173,8 +176,9 @@ export default class SelectOpener extends React.Component<
aria-haspopup="listbox"
data-testid={testId}
id={id}
role="combobox"
Copy link
Member

Choose a reason for hiding this comment

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

Side note: Since our selects now use role=combobox, we'll be able to treat SingleSelect/MultiSelect more like fields! I created WB-1807 for applying aria-required on these components since it's only valid on role=combobox and not role=button 😄

@@ -77,7 +77,7 @@ describe("MultiSelect", () => {
const {userEvent} = doRender(uncontrolledMultiSelect);

// Act
await userEvent.click(await screen.findByRole("button"));
await userEvent.click(await screen.findByRole("combobox"));
Copy link
Member

Choose a reason for hiding this comment

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

When we make internal changes that break existing tests, do we consider it a major breaking change since it could break tests in consuming projects? In this case, I'm thinking it's not since the role isn't part of the external API of the component! I'm curious to hear what others think though!

(I might have asked this before but wanted to double check!)

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.

4 participants