Accessibility: Require Alt key for arrow navigation in theme and media modals - #11560
Accessibility: Require Alt key for arrow navigation in theme and media modals#11560Sukhendu2002 wants to merge 22 commits into
Conversation
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
joedolson
left a comment
There was a problem hiding this comment.
In addition to the comment on media modal navigation, I think both keyboard navigations should trigger a wp.a11y.speak() notification telling the user what media item/theme they're now viewing. Otherwise, the feedback for screen reader users is not very good.
| */ | ||
| keyEvent: function( event ) { | ||
| if ( ( 'INPUT' === event.target.nodeName || 'TEXTAREA' === event.target.nodeName ) && ! event.target.disabled ) { | ||
| if ( ( 'INPUT' === event.target.nodeName || 'TEXTAREA' === event.target.nodeName || 'SELECT' === event.target.nodeName || 'BUTTON' === event.target.nodeName || 'A' === event.target.nodeName ) && ! event.target.disabled ) { |
There was a problem hiding this comment.
This change breaks repeated use of keyboard navigation to switch, because focus is moved to the prev/next buttons after triggering navigation.
Preventing these events while on interactive elements was specifically necessary because the key event was triggered on single arrows, but with a combination key event, that's not so relevant.
There was a problem hiding this comment.
Thanks for the review. I updated the patch to add wp.a11y.speak() feedback for both media and theme Alt+arrow navigation, so screen reader users hear what item they are now viewing. I also removed the BUTTON and A exclusions so repeated navigation still works after focus moves to the prev/next buttons. I kept SELECT treated as a form field, but can remove that too if preferred.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
There was a problem hiding this comment.
Pull request overview
This PR updates keyboard navigation in the Themes and Media modals to require the Alt modifier when using left/right arrow keys, and adds new localized strings to announce the newly shown theme/media item via wp.a11y.speak() for improved screen reader feedback.
Changes:
- Require Alt + Left/Right Arrow for previous/next navigation in the theme preview/overlay and the media edit-attachments modal.
- Add
wp.a11y.speak()announcements when navigating to a new theme/media item. - Add new i18n strings (
themeViewed,mediaItemViewed) to support the announcements.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/wp-includes/media.php |
Adds a localized announcement string for the media modal (“Viewing media item: %s”). |
src/wp-admin/themes.php |
Adds a localized announcement string for themes browsing (“Viewing theme: %s”). |
src/wp-admin/theme-install.php |
Adds the same localized announcement string for the theme installer context. |
src/js/media/views/frame/edit-attachments.js |
Requires Alt+Arrow navigation and announces the current media item after navigation. |
src/js/_enqueues/wp/theme.js |
Requires Alt+Arrow navigation in theme overlays/previews and announces the current theme after navigation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Three changes: use |
afercia
left a comment
There was a problem hiding this comment.
Thank you for the PR, I think it is going in the right direction.
I will add some consideration points in a following comment.
|
A few considerations: In the Media Library, the usage of Personally, I liked the previous behavior because it allows a very quick navigation. Now, this is no longer possible. We should make a decision on whether to preserve the 'press and hold' behavior. If so, I think it should be used also in the theme browser, for consistency. The The message of the announcement for the themes is slightly different. I would suggest to make them consistent:
Ideally, the shorter the better. However, I'm not sure 'Viewing theme' is accurate. Actually, the modal dialogs don't show the theme. They show the theme details. In the theme browser there's no help to inform users they can use alt / option + the left or right arrow keys or at least I couldn't find any. If we think Alt + arrow keys is the best option, we should create a new ticket to evaluate whether there are other places in Core and Gutenberg where this pattern should be implemented. This pattern should be consistent everywhere. |
|
| $( which ).trigger( 'focus' ); | ||
| }, | ||
|
|
||
| announceMediaItem: function( model ) { |
|
I went ahead and changed the |
I stand partially corrected. The underscore.js We should test the scenario where users may close the modal dialog before the 500ms interval, to avoid an undesired announcement when the modal dialog is already closed. If the announcement is triggered, we should cancel the debounce. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (3)
src/js/_enqueues/wp/theme.js:40
- Using String.prototype.replace('%s', …) to fill a translatable string can break for locales that use numbered placeholders (e.g. "%1$s"). Using wp.i18n.sprintf() supports both numbered and unnumbered placeholders.
name = model.get( 'name' ) || model.get( 'id' );
if ( ! name ) {
return;
}
wp.a11y.speak( l10n.themeViewed.replace( '%s', name ) );
}, 500 );
src/js/media/views/frame/edit-attachments.js:58
- Using String.prototype.replace('%s', …) to fill a translatable string can break for locales that use numbered placeholders (e.g. "%1$s"). Using wp.i18n.sprintf() supports both numbered and unnumbered placeholders.
title = model.get( 'title' ) || model.get( 'filename' ) || model.get( 'id' );
if ( ! title ) {
return;
}
wp.a11y.speak( l10n.mediaItemViewed.replace( '%s', title ) );
}, 500 ),
src/js/_enqueues/wp/customize/controls.js:1733
- Using String.prototype.replace('%s', …) to fill a translatable string can break for locales that use numbered placeholders (e.g. "%1$s"). Using wp.i18n.sprintf() supports both numbered and unnumbered placeholders.
section.announceThemeDebounced = _.debounce( function( name ) {
if ( ! name ) {
return;
}
wp.a11y.speak( api.settings.l10n.announceThemeDetails.replace( '%s', name ) );
}, 500 );
|
I updated the PR to my best. All the related announcement are now debounced. When closing the modal dialogs, the pending announcement are canceled. This behavior should be tested in the following 4 places: Installed themes: Theme installer: Customizer theme preview (click the 'Change' button and then previwe the themes): Media grid: |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
src/js/_enqueues/wp/theme.js:1152
themes.announceThemeDebouncedcan still fire after the theme details overlay is closed via the routertheme:closepath (triggered inroute:themes). The close handler currently callsself.overlay.closeOverlay()but does not cancel the pending debounced announcement, so a queued screen-reader message may be spoken after the modal is gone.
$( 'body' ).on( 'keydown.wp-themes', function( event ) {
if ( ! self.overlay ) {
return;
}
tests/qunit/wp-admin/js/theme.js:96
- This test includes a leftover comment (“This test would need…”) that is now inaccurate, and the block’s spacing is inconsistent with nearby QUnit tests (e.g.,
} ) );/} );). This makes the test harder to read and may trip style checks.
QUnit.test( 'PreventDefault is called for arrow keys with Alt', function( assert ) {
// This test would need to check if preventDefault was called
var event = $.Event( 'keydown', {
keyCode: 39,
altKey: true,
|
Latest commit improves the Help text:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
src/js/media/views/frame/edit-attachments.js:49
announceMediaItemDebouncedis created on the prototype via_.debounce(...), which means the debounce timer/state (and.cancel()) can be shared across multiple EditAttachments frame instances. If more than one frame is ever instantiated, announcements can cancel/override each other unexpectedly. Prefer creating the debounced function per instance ininitialize()and keeping the prototype property asnull.
announceMediaItemDebounced: _.debounce( function( model ) {
var title;
if ( ! model ) {
return;
tests/qunit/wp-admin/js/theme.js:96
- The comment in this test is misleading (“would need to check if preventDefault was called”) even though the test does check it. Also, the new block deviates from the spacing used in the surrounding tests (e.g.
} );), which makes the file inconsistent.
QUnit.test( 'PreventDefault is called for arrow keys with Alt', function( assert ) {
// This test would need to check if preventDefault was called
var event = $.Event( 'keydown', {
keyCode: 39,
altKey: true,
joedolson
left a comment
There was a problem hiding this comment.
This looks good to me. I tested with VoiceOver, NVDA, and JAWS, and all three worked as expected with all browsers tested.
The theme browsers and the media attachment browser supported left and right arrow keys to trigger navigation. These interfered with screen reader reading commands, which also use the left and right arrow keys, forcing navigation instead of allowing the screen reader user to read additional content. Require that the `alt` key is also pressed to trigger navigation. Also add debounced screen reader announcements to notify users of the new modal context. Developed in #11560 Props joedolson, sukhendu2002, afercia. Fixes #63760. git-svn-id: https://develop.svn.wordpress.org/trunk@62878 602fd350-edb4-49c9-b593-d223f7449a82
The theme browsers and the media attachment browser supported left and right arrow keys to trigger navigation. These interfered with screen reader reading commands, which also use the left and right arrow keys, forcing navigation instead of allowing the screen reader user to read additional content. Require that the `alt` key is also pressed to trigger navigation. Also add debounced screen reader announcements to notify users of the new modal context. Developed in WordPress/wordpress-develop#11560 Props joedolson, sukhendu2002, afercia. Fixes #63760. Built from https://develop.svn.wordpress.org/trunk@62878 git-svn-id: http://core.svn.wordpress.org/trunk@62156 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Trac ticket: https://core.trac.wordpress.org/ticket/63760
Use of AI Tools
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.