Skip to content

Commit

Permalink
Accessibility: Adding Keyboard Shorcuts to navigate the editor regions
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed Oct 20, 2017
1 parent e187494 commit bb5048c
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 23 deletions.
1 change: 1 addition & 0 deletions editor/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function Header( {
role="region"
aria-label={ __( 'Editor toolbar' ) }
className="editor-header"
tabIndex="-1"
>
<div className="editor-header__content-tools">
<Inserter position="bottom right" />
Expand Down
93 changes: 71 additions & 22 deletions editor/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,29 +29,77 @@ import {
getNotices,
} from '../selectors';

function Layout( { mode, isSidebarOpened, notices, ...props } ) {
const className = classnames( 'editor-layout', {
'is-sidebar-opened': isSidebarOpened,
} );

return (
<div key="editor" className={ className }>
<DocumentTitle />
<NoticeList onRemove={ props.removeNotice } notices={ notices } />
<UnsavedChangesWarning />
<AutosaveMonitor />
<Header />
<div className="editor-layout__content">
<div className="editor-layout__editor">
{ mode === 'text' && <TextEditor /> }
{ mode === 'visual' && <VisualEditor /> }
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 (
<div key="editor" className={ className } ref={ this.bindContainer } onClick={ this.onClick }>
<DocumentTitle />
<NoticeList onRemove={ props.removeNotice } notices={ notices } />
<UnsavedChangesWarning />
<AutosaveMonitor />
<Header />
<div className="editor-layout__content">
<div className="editor-layout__editor">
{ mode === 'text' && <TextEditor /> }
{ mode === 'visual' && <VisualEditor /> }
</div>
<MetaBoxes location="normal" />
</div>
<MetaBoxes location="normal" />
{ isSidebarOpened && <Sidebar /> }
<Popover.Slot />
<KeyboardShortcuts shortcuts={ {
'ctrl+r': this.focusNextRegion,
'ctrl+shift+r': this.focusPreviousRegion,
} } />
</div>
{ isSidebarOpened && <Sidebar /> }
<Popover.Slot />
</div>
);
/* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */
);
}
}

export default connect(
Expand Down
11 changes: 11 additions & 0 deletions editor/layout/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions editor/modes/text-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class TextEditor extends Component {
role="region"
aria-label={ __( 'Editor content' ) }
className="editor-text-editor"
tabIndex="-1"
>
<div className="editor-text-editor__formatting">
<div className="editor-text-editor__formatting-group">
Expand Down
1 change: 1 addition & 0 deletions editor/modes/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class VisualEditor extends Component {
onMouseDown={ this.onClick }
onTouchStart={ this.onClick }
ref={ this.bindContainer }
tabIndex="-1"
>
<KeyboardShortcuts shortcuts={ {
'mod+a': this.selectAll,
Expand Down
7 changes: 6 additions & 1 deletion editor/sidebar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ import { getActivePanel } from '../selectors';

const Sidebar = ( { panel } ) => {
return (
<div className="editor-sidebar" role="region" aria-label={ __( 'Editor settings' ) }>
<div
className="editor-sidebar"
role="region"
aria-label={ __( 'Editor settings' ) }
tabIndex="-1"
>
<Header />
{ panel === 'document' && <PostSettings key="settings" /> }
{ panel === 'block' && <BlockInspector /> }
Expand Down

0 comments on commit bb5048c

Please sign in to comment.