From bb5048c3931ae6f8607679f23d4b1f59fd4e8db7 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 20 Oct 2017 12:41:10 +0100 Subject: [PATCH] Accessibility: Adding Keyboard Shorcuts to navigate the editor regions --- editor/header/index.js | 1 + editor/layout/index.js | 93 ++++++++++++++++++++++------- editor/layout/style.scss | 11 ++++ editor/modes/text-editor/index.js | 1 + editor/modes/visual-editor/index.js | 1 + editor/sidebar/index.js | 7 ++- 6 files changed, 91 insertions(+), 23 deletions(-) diff --git a/editor/header/index.js b/editor/header/index.js index e4bf0addfb351..d6a3e7baf43e2 100644 --- a/editor/header/index.js +++ b/editor/header/index.js @@ -34,6 +34,7 @@ function Header( { role="region" aria-label={ __( 'Editor toolbar' ) } className="editor-header" + tabIndex="-1" >
diff --git a/editor/layout/index.js b/editor/layout/index.js index 3f6eb13ded988..d13287f0d962e 100644 --- a/editor/layout/index.js +++ b/editor/layout/index.js @@ -7,7 +7,8 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { NoticeList, Popover } from '@wordpress/components'; +import { Component } from '@wordpress/element'; +import { NoticeList, Popover, KeyboardShortcuts } from '@wordpress/components'; /** * Internal dependencies @@ -28,29 +29,77 @@ import { getNotices, } from '../selectors'; -function Layout( { mode, isSidebarOpened, notices, ...props } ) { - const className = classnames( 'editor-layout', { - 'is-sidebar-opened': isSidebarOpened, - } ); - - return ( -
- - - - -
-
-
- { mode === 'text' && } - { mode === 'visual' && } +class Layout extends Component { + constructor() { + super( ...arguments ); + this.bindContainer = this.bindContainer.bind( this ); + this.focusNextRegion = this.focusRegion.bind( this, 1 ); + this.focusPreviousRegion = this.focusRegion.bind( this, -1 ); + this.onClick = this.onClick.bind( this ); + this.state = { + isFocusingRegions: false, + }; + } + + bindContainer( ref ) { + this.container = ref; + } + + focusRegion( offset ) { + const regions = [ ...this.container.querySelectorAll( '[role="region"]' ) ]; + if ( ! regions.length ) { + return; + } + let nextRegion = regions[ 0 ]; + const selectedIndex = regions.indexOf( document.activeElement ); + if ( selectedIndex !== -1 ) { + let nextIndex = selectedIndex + offset; + nextIndex = nextIndex === -1 ? regions.length - 1 : nextIndex; + nextIndex = nextIndex === regions.length ? 0 : nextIndex; + nextRegion = regions[ nextIndex ]; + } + + nextRegion.focus(); + this.setState( { isFocusingRegions: true } ); + } + + onClick() { + this.setState( { isFocusingRegions: false } ); + } + + render() { + const { mode, isSidebarOpened, notices, ...props } = this.props; + const className = classnames( 'editor-layout', { + 'is-sidebar-opened': isSidebarOpened, + 'is-focusing-regions': this.state.isFocusingRegions, + } ); + + // Disable reason: Clicking the editor should dismiss the regions focus style + /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */ + return ( +
+ + + + +
+
+
+ { mode === 'text' && } + { mode === 'visual' && } +
+
- + { isSidebarOpened && } + +
- { isSidebarOpened && } - -
- ); + /* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */ + ); + } } export default connect( diff --git a/editor/layout/style.scss b/editor/layout/style.scss index e9bd55965acc1..1ff701e33456a 100644 --- a/editor/layout/style.scss +++ b/editor/layout/style.scss @@ -5,6 +5,17 @@ .editor-layout { position: relative; + + &.is-focusing-regions [role="region"]:focus:after { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + pointer-events: none; + border: 2px solid $blue-medium-400; + } } .editor-layout__content { diff --git a/editor/modes/text-editor/index.js b/editor/modes/text-editor/index.js index 846efa57c71f9..8ce0888b11e7e 100644 --- a/editor/modes/text-editor/index.js +++ b/editor/modes/text-editor/index.js @@ -54,6 +54,7 @@ class TextEditor extends Component { role="region" aria-label={ __( 'Editor content' ) } className="editor-text-editor" + tabIndex="-1" >
diff --git a/editor/modes/visual-editor/index.js b/editor/modes/visual-editor/index.js index fbafded4aceb8..74f6c9fcaedbb 100644 --- a/editor/modes/visual-editor/index.js +++ b/editor/modes/visual-editor/index.js @@ -84,6 +84,7 @@ class VisualEditor extends Component { onMouseDown={ this.onClick } onTouchStart={ this.onClick } ref={ this.bindContainer } + tabIndex="-1" > { return ( -
+
{ panel === 'document' && } { panel === 'block' && }