Skip to content

Conversation

@marissahuysentruyt
Copy link
Collaborator

@marissahuysentruyt marissahuysentruyt commented Nov 13, 2025

Description

This PR removes the menu examples found on the tray documentation page. The menu examples are partial and unrealistically used within the tray, so removing them resolves the accessibility concerns regarding aria-current/aria-checked.

Motivation and context

Screen readers were not announcing the selected state for menu items with role="menuitem", causing confusion for users relying on assistive technology. But because our examples were not realistic examples, (menus are usually children of popovers instead), removing the menu examples from the tray docs is most accurate.

Related issue(s)

  • Fixes SWC-1108

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed the Accessibility Practices for this feature, see: Aria Practices
  • I have added automated tests to cover my changes.
  • I have included a well-written changeset if my change needs to be published.
  • I have included updated documentation if my change required it.

Reviewer's checklist

  • Includes a Github Issue with appropriate flag or Jira ticket number without a link
  • Includes thoughtfully written changeset if changes suggested include patch, minor, or major features
  • Automated tests cover all use cases and follow best practices for writing
  • Validated on all supported browsers
  • All VRTs are approved before the author can update Golden Hash

Manual review test cases

  • Tray docs no longer have menu examples

    1. Go to sp-tray documentation.
    2. Navigate to the 'Anatomy' section.
    3. Verify the tabs are no longer present, and only the dialog example remains.
    4. The new documentation is technically and grammatically accurate and follows Spectrum content standards.
    5. Navigate to the 'Accessibility' section.
    6. Validate the behavior of the tray in the "Content has no buttons" tab remains unchanged (i.e. the visually hidden dismiss buttons are still keyboard navigable and get announced properly by a screen reader).
      i. Verify the accessibility of the select element. It is implicitly associated to the label as a child of the label, and all options have value attributes.
  • Screen reader announces selected state for menuitem

    1. Go to sp-tray documentation
    2. Navigate to the 'Anatomy' section, 'Dialog' tab, and select the 'Menu' tab
    3. Activate the "Toggle menu" button and navigate to a selected menu item using a screen reader (NVDA, JAWS, or VoiceOver)
      i. ~~In the bug ticket, they are specifically using NVDA on a Windows machine, so I was using AssitivLabs during development. ~~
    4. Expect the screen reader to announce the selected/current state (e.g., "Deselect, current, 1 of 6")
  • aria-current attribute is correctly applied

    1. Inspect a selected sp-menu-item with role="menuitem" in browser DevTools
    2. Verify it has aria-current="true" attribute
    3. Inspect a non-selected sp-menu-item with role="menuitem"
    4. Verify it does NOT have an aria-current attribute (not set to "false")
    5. Manually remove the selected attribute from the first item.
    6. Verify the corresponding aria-current attribute is removed.
  • Other menu item roles are unaffected

    1. Test menu items with role="menuitemradio" and role="menuitemcheckbox"
    2. Verify they still use aria-checked (not aria-current)
    3. Test menu items with role="option" in a listbox context
    4. Verify they still use aria-selected (not aria-current)
  • New unit tests pass in CI.

    1. "sets aria-current to true if the item has selected property"
    2. "removes aria-current if the item is deselected"
    3. "updates aria-current when the selected item changes"~~
  • New documentation for menu item is technically and grammatically accurate and follows Spectrum content standards.

Device review

  • Did it pass in Desktop?
  • Did it pass in (emulated) Mobile?
  • Did it pass in (emulated) iPad?

@changeset-bot
Copy link

changeset-bot bot commented Nov 13, 2025

⚠️ No Changeset found

Latest commit: b26aa22

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

@marissahuysentruyt marissahuysentruyt changed the title fix(menuitem): add aria-current logic fix(menuitem): improve a11y of selected items with aria-current Nov 13, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 13, 2025

📚 Branch Preview

🔍 Visual Regression Test Results

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:

Deployed to Azure Blob Storage: pr-5888

If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.

@marissahuysentruyt marissahuysentruyt self-assigned this Nov 13, 2025
@marissahuysentruyt marissahuysentruyt added 1.0.0 Issues that should be addressed for a 1.0 release! a11y Issues or PRs related to accessibility SEV 2 significant problem re: design, usability, or functionality of the system/components for some users labels Nov 13, 2025
@marissahuysentruyt marissahuysentruyt marked this pull request as ready for review November 13, 2025 22:51
@marissahuysentruyt marissahuysentruyt requested a review from a team as a code owner November 13, 2025 22:51
Copy link
Contributor

@caseyisonit caseyisonit left a comment

Choose a reason for hiding this comment

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

Gorg

Copy link
Contributor

@Rajdeepc Rajdeepc left a comment

Choose a reason for hiding this comment

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

Good fix!! One thing was to test that updateAriaSelected() is also called whenever the selected property changes which I see it is happening on

if (changes.has('selected')) {
    this.updateAriaSelected();
}

@Rajdeepc Rajdeepc added the Status: Ready for merge PR has 2 approvals, all tests pass, and is ready to merge label Nov 14, 2025

#### Roles and ARIA attributes

When a menu item with `role="menuitem"` is selected, the `aria-current="true"` attribute is automatically applied to indicate the current item to screen reader users. This ensures assistive technology properly announces the selected state of menu items.
Copy link
Contributor

Choose a reason for hiding this comment

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

The appropriate way to indicate a selected state for an item in a menu is to use either role="menuitemcheckbox" for multi-selectable items, or role="menuitemradio" for mutually exclusive selection, with the aria-checked attribute to indicate the selected state. An element with role="menuitem" does not support the aria-checked or aria-selected property. See the supported states and properties for a menu item: https://w3c.github.io/aria/#menuitem.

An menuitem can support aria-current, but only in an appropriate context. See https://w3c.github.io/aria/#aria-current, which explains appropriate usage of aria-current:

aria-current state
Indicates the element that represents the current item within a container or set of related elements.

The aria-current attribute is a token type. Any value not included in the list of allowed values SHOULD be treated by assistive technologies as if the value true had been provided. If the attribute is not present or its value is the empty string or undefined, the default value of false applies and the aria-current state MUST NOT be exposed by user agents or assistive technologies.

The aria-current attribute is used when an element within a set of related elements is visually styled to indicate it is the current item in the set. For example:

  • A page token used to indicate a page within a set of pages, where the element is visually styled to represent the current page.
  • A step token used to indicate a step within a step-based process, where the element is visually styled to represent the current step.
  • A location token used to indicate the element that is visually styled as the current component, such as within a flow chart.
  • A date token used to indicate the current date within a calendar or other date collection.
  • A time token used to indicate the current time within a timetable or other time collection.
    Authors SHOULD only mark one element in a set of elements as current with aria-current.

Authors SHOULD NOT use the aria-current attribute as a substitute for aria-selected in widgets where aria-selected has the same meaning. For example, in a tablist, aria-selected is used on a tab to indicate the currently-displayed tabpanel.

Note how the WAI-ARIA spec explicitly states that "Authors SHOULD NOT use the aria-current attribute as a substitute for aria-selected in widgets where aria-selected has the same meaning."

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Let me rework this to come up with a solution that better fits how you're seeing the solution!

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this an issue with the menu component or the docs themselves?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Menu already correctly assigns aria-selected (for role="option" menu items) and aria-checked (for role="menuitemcheckbox" or role="menuitemradio").

However, if the selects property is not defined, the default role for our menu items is menuitem, which doesn't support aria-checked/aria-selected. I think that because those menu examples on the tray docs didn't have the selects property (and therefore assigned menuitem roles to the sp-menu-items), we weren't announcing the selected state of the menu items correctly (because they don't hook into aria-checked).

I'm understanding Michael's comment below to be asking that question- if selects isn't on an sp-menu, how do we appropriately mark role="menuitem" elements as selectable (without using aria-current incorrectly).

This is what I'm imagining we would research in a separate ticket.

Comment on lines 722 to 728
if (role === 'menuitem') {
if (this.selected) {
this.setAttribute('aria-current', 'true');
} else {
this.removeAttribute('aria-current');
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer to keep aria-current as a separate concern from selection.

role is determined by either the role on the containing sp-menu or the selects property on the parent sp-menu or sp-menu-group. If the selected state is indicated on a menuitem without selects="multiple", selects="single" or selects="inherit" on the parent sp-menu or sp-menu-group, we should maybe change the role for the sp-menu-item to menuitemcheckbox. This gets messy though, because then the question becomes, what then is the role for the unselected state, and how do we indicate that an unselected item is selectable?

Copy link
Collaborator Author

@marissahuysentruyt marissahuysentruyt Nov 14, 2025

Choose a reason for hiding this comment

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

@majornista ah- thank you! I did see the note in the W3C docs about not substituting aria-current for aria-selected, but the ticket specifically called out aria-current as the solution, which is why I went this route.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@majornista To immediately solve the issue, can I make sure that the menu as display in this tray has the selects property? Then we can hook into the existing aria-checked logic, I can remove the aria-current logic I added, and the screen reader announces the selected item properly (which I think was the underlying complaint in the ticket).

I could also add more documentation guidelines around ensuring the selects property is added to the parent sp-menu, and describe the accessibility errors/failures that happen regarding sp-menu-items when selects is missing.

I'm going to bring this up with our team this morning as well to chat about a solution!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Update: these examples with a menu in a tray don't really make sense since they're only partial examples anyways. The team's preference is to remove the menu examples instead, resolving the ticket with documentation only 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be a separate issue for menu instead of the scope of a tray docs PR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I can make a new ticket! I have a local branch that should still have some of this previous work.

@marissahuysentruyt marissahuysentruyt force-pushed the marissahuysentruyt/swc-1108-aria-current-on-selected-menu-item branch 2 times, most recently from 7b19176 to ae793d0 Compare November 17, 2025 18:23
Comment on lines -54 to -62
<sp-menu style="width: 100%">
<sp-menu-item selected>Deselect</sp-menu-item>
<sp-menu-item>Select Inverse</sp-menu-item>
<sp-menu-item focused>Feather...</sp-menu-item>
<sp-menu-item>Select and Mask...</sp-menu-item>
<sp-menu-divider></sp-menu-divider>
<sp-menu-item>Save Selection</sp-menu-item>
<sp-menu-item disabled>Make Work Path</sp-menu-item>
</sp-menu>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In context, this menu doesn't really make- it's only a partial implementation and would normally be rendered within a popover instead.

After discussing with the team, we decided to leave out the tray examples with menus in favor of other content.

</sp-button>
<sp-tray slot="click-content" has-keyboard-dismiss>
<p>
<p style="margin: 16px;">
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added this solely to make it look a little nicer inside the tray.

@marissahuysentruyt marissahuysentruyt marked this pull request as draft November 17, 2025 18:27
@marissahuysentruyt marissahuysentruyt removed the Status: Ready for merge PR has 2 approvals, all tests pass, and is ready to merge label Nov 17, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 17, 2025

📚 Branch Preview Links

🔍 First Generation Visual Regression Test Results

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:

Deployed to Azure Blob Storage: pr-5888

If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.

@marissahuysentruyt marissahuysentruyt force-pushed the marissahuysentruyt/swc-1108-aria-current-on-selected-menu-item branch 2 times, most recently from ec8ab7b to 8538ccd Compare November 17, 2025 18:55
@marissahuysentruyt marissahuysentruyt added the Status: Ready for review PR ready for review or re-review. label Nov 17, 2025
@marissahuysentruyt marissahuysentruyt marked this pull request as ready for review November 17, 2025 19:16
@marissahuysentruyt marissahuysentruyt changed the title fix(menuitem): improve a11y of selected items with aria-current docs(tray): improve a11y of tray docs examples Nov 17, 2025
<sp-tabs selected="dialog" auto label="Using tray's slot">
<sp-tab value="dialog">Dialog</sp-tab>
<sp-tab-panel value="dialog">
A tray has a single default `slot`. Expected content typically includes dialogs and their content, plain text, forms and/or form elements, and some native HTML elements. Always ensure that your tray's content is accessible according to WCAG standards.
Copy link
Contributor

Choose a reason for hiding this comment

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

Clean language, love it

<div style="display: flex; flex-direction: column; margin: 16px;">
<p style="margin-block-start: 0;">
Custom content that doesn't have dismiss functionality, so the
tray detects it needs the visually-hidden dismiss buttons.
Copy link
Contributor

@caseyisonit caseyisonit Nov 17, 2025

Choose a reason for hiding this comment

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

yessss kween to incorporating contextual documentation in the example!! we should flag this as a good practice to continue!

Copy link
Contributor

@caseyisonit caseyisonit left a comment

Choose a reason for hiding this comment

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

GLORIOUS 🔥

@marissahuysentruyt marissahuysentruyt force-pushed the marissahuysentruyt/swc-1108-aria-current-on-selected-menu-item branch from 8538ccd to 56a68e3 Compare November 19, 2025 16:56
@marissahuysentruyt marissahuysentruyt force-pushed the marissahuysentruyt/swc-1108-aria-current-on-selected-menu-item branch from 56a68e3 to b26aa22 Compare November 19, 2025 17:09
@marissahuysentruyt marissahuysentruyt merged commit 8a00f23 into main Nov 19, 2025
21 checks passed
@marissahuysentruyt marissahuysentruyt deleted the marissahuysentruyt/swc-1108-aria-current-on-selected-menu-item branch November 19, 2025 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.0.0 Issues that should be addressed for a 1.0 release! a11y Issues or PRs related to accessibility SEV 2 significant problem re: design, usability, or functionality of the system/components for some users Status: Ready for review PR ready for review or re-review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants