-
Notifications
You must be signed in to change notification settings - Fork 211
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(action menu): keyboard accessibility omnibus #5031
base: main
Are you sure you want to change the base?
Changes from 49 commits
91b72f7
adc0d26
97d88c3
d10ed4c
cb74cba
3876c36
350e9ba
b7c750f
68a298d
63e1dab
b6ee246
ef99ebb
eb7e539
36cc4a2
9f5f16c
01be995
c5a9514
a949c61
62147ea
8211077
66eb2d8
7f6b363
d4f7f93
291231f
3411413
645342d
ed63038
a6032bf
52b5340
9b41026
5d9391f
38d2600
78c4bb3
05a8bda
74860db
bc2fbf3
5d56b17
ae33752
b5ec45e
524f2b1
947104b
a56d711
46f5fb7
4aa538a
d4ab737
b764a9e
004a093
82406d5
8d56d22
ff9f716
5155cca
5d36670
b367419
5d81d96
c3582d5
dfc14ec
43a97b8
10428d1
6c7d3df
9f34dbb
e513273
94e7f49
b66d51e
13e4524
87f1045
bf0ea21
59d39a1
8634b69
d163634
1f40a14
eb7c0a2
0f73de8
538df46
dad24b7
87e1599
d257e7e
9809cd7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
'@spectrum-web-components/reactive-controllers': minor | ||
'@spectrum-web-components/action-menu': minor | ||
'@spectrum-web-components/picker': minor | ||
'@spectrum-web-components/menu': minor | ||
--- | ||
|
||
Used WAI ARIA Authoring Practices Guide (APG) to make accessibility improvements for `<sp-action-menu>`, `<sp-menu>`, and `<sp-picker>`, including: | ||
- Numpad keys now work with `<sp-picker>` and `<sp-action-menu>` | ||
-`<sp-action-menu>`'s `<sp-menu-item>` elements can now be read by a screen reader ([#4556](https://github.com/adobe/spectrum-web-components/issues/4556)) | ||
- `<sp-menu-item>` href can now be clicked by a screen reader ([#4997](https://github.com/adobe/spectrum-web-components/issues/4997)) | ||
- Opening a `<sp-action-menu>`, `<sp-menu>`, and `<sp-picker>` with a keyboard now sets focus on an item within the menu. ([#4557](https://github.com/adobe/spectrum-web-components/issues/4557)) | ||
|
||
See the following APG examples for more information: | ||
- [Navigation Menu Example](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/) | ||
- [Editor Menubar Example](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-editor/) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,11 +24,10 @@ describe('Action Menu - Groups', () => { | |
groupsWithSelects({ onChange: () => {} }) | ||
); | ||
|
||
const firstGroup = el.querySelector('sp-menu-group') as HTMLElement; | ||
const firstItem = el.querySelector('sp-menu-item') as MenuItem; | ||
|
||
expect(firstItem.focused).to.be.false; | ||
expect(document.activeElement === firstGroup).to.be.false; | ||
expect(document.activeElement === firstItem).to.be.false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Menus and Groups should delegate focus to their active item, so the active element should be the item, not the group. |
||
|
||
const opened = oneEvent(el, 'sp-opened'); | ||
el.focus(); | ||
|
@@ -39,7 +38,7 @@ describe('Action Menu - Groups', () => { | |
|
||
expect(firstItem.focused).to.be.true; | ||
expect( | ||
document.activeElement === firstGroup, | ||
document.activeElement === firstItem, | ||
document.activeElement?.localName | ||
).to.be.true; | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -436,56 +436,6 @@ export const testActionMenu = (mode: 'sync' | 'async'): void => { | |
|
||
expect(firstRect).to.deep.equal(secondRect); | ||
}); | ||
it('opens and selects in a single pointer button interaction', async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Menu hover was removed for better a11y experience, so this test is no longer needed |
||
const el = await actionMenuFixture(); | ||
const thirdItem = el.querySelector( | ||
'sp-menu-item:nth-of-type(3)' | ||
) as MenuItem; | ||
const boundingRect = el.button.getBoundingClientRect(); | ||
|
||
expect(el.value).to.not.equal(thirdItem.value); | ||
const opened = oneEvent(el, 'sp-opened'); | ||
await sendMouse({ | ||
steps: [ | ||
{ | ||
type: 'move', | ||
position: [ | ||
boundingRect.x + boundingRect.width / 2, | ||
boundingRect.y + boundingRect.height / 2, | ||
], | ||
}, | ||
{ | ||
type: 'down', | ||
}, | ||
], | ||
}); | ||
await opened; | ||
|
||
const thirdItemRect = thirdItem.getBoundingClientRect(); | ||
const closed = oneEvent(el, 'sp-closed'); | ||
let selected = ''; | ||
el.addEventListener('change', (event: Event) => { | ||
selected = (event.target as ActionMenu).value; | ||
}); | ||
await sendMouse({ | ||
steps: [ | ||
{ | ||
type: 'move', | ||
position: [ | ||
thirdItemRect.x + thirdItemRect.width / 2, | ||
thirdItemRect.y + thirdItemRect.height / 2, | ||
], | ||
}, | ||
{ | ||
type: 'up', | ||
}, | ||
], | ||
}); | ||
await closed; | ||
|
||
expect(el.open).to.be.false; | ||
expect(selected).to.equal(thirdItem.value); | ||
}); | ||
it('has attribute aria-describedby', async () => { | ||
const name = 'sp-picker'; | ||
const description = 'Rendering a Picker'; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,12 +95,35 @@ Content assigned to the `value` slot will be placed at the end of the `<sp-menu- | |
An `<sp-menu-item>` can also accept content addressed to its `submenu` slot. Using the `<sp-menu>` element with this slot name the options will be surfaced in flyout menu that can be activated by hovering over the root menu item with your pointer or focusing the menu item and pressing the appropriate `ArrowRight` or `ArrowLeft` key based on text direction to move into the submenu. | ||
|
||
```html | ||
<sp-menu style="width: 200px;"> | ||
<p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a more detailed example to docs to see menu item with submenus. |
||
Your favorite park in New York is: | ||
<span id="group-1-value"></span> | ||
<br /> | ||
<br /> | ||
Your favorite park in San Francisco is: | ||
<span id="group-2-value"></span> | ||
</p> | ||
<sp-menu | ||
style="width: 200px;" | ||
onchange="this.parentElement | ||
.previousElementSibling | ||
.querySelector(`#${arguments[0].target.id}-value`) | ||
.textContent = arguments[0].target.value" | ||
> | ||
<sp-menu-item> | ||
New York | ||
<sp-menu slot="submenu" selects="single"> | ||
<sp-menu-item>Central Park</sp-menu-item> | ||
<sp-menu-item>Flushing Meadows Corona Park</sp-menu-item> | ||
<sp-menu-item>Prospect Park</sp-menu-item> | ||
</sp-menu> | ||
</sp-menu-item> | ||
<sp-menu-item> | ||
Item with submenu | ||
<sp-menu slot="submenu"> | ||
<sp-menu-item>Additional options</sp-menu-item> | ||
<sp-menu-item>Available on request</sp-menu-item> | ||
San Francisco | ||
<sp-menu slot="submenu" selects="single"> | ||
<sp-menu-item>Golden Gate Park</sp-menu-item> | ||
<sp-menu-item>John McLaren Park</sp-menu-item> | ||
<sp-menu-item>Lake Merced Park</sp-menu-item> | ||
</sp-menu> | ||
</sp-menu-item> | ||
</sp-menu> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Action Menu was throwing the no label warning for a test that used the
label-only
slot, so I decided to override Picker's accessible label check and warning with a warning specific to action menu.