(
+
+ ) }
+ renderContent={ () => (
+ <>
+
+
+ { editIcon }
+ { __( 'Edit' ) }
+ >
+ ),
+ },
+ {
+ value: 'select',
+ label: (
+ <>
+ { selectIcon }
+ { __( 'Select' ) }
+ >
+ ),
+ },
+ ] }
+ />
+
+
+ { __( 'Tools offer different interactions for block selection & editing. To select, press Escape, to go back to editing, press Enter.' ) }
+
+ >
+ ) }
+ />
+ );
+}
+
+export default ifViewportMatches( 'medium' )( ToolSelector );
diff --git a/packages/block-editor/src/components/tool-selector/style.scss b/packages/block-editor/src/components/tool-selector/style.scss
new file mode 100644
index 0000000000000..1f61a871dce89
--- /dev/null
+++ b/packages/block-editor/src/components/tool-selector/style.scss
@@ -0,0 +1,5 @@
+.block-editor-tool-selector__help {
+ padding: $grid-size-large;
+ border-top: 1px solid $light-gray-500;
+ color: $dark-gray-300;
+}
diff --git a/packages/block-editor/src/components/writing-flow/index.js b/packages/block-editor/src/components/writing-flow/index.js
index 37e45dd2680d0..cd9355bcf2a36 100644
--- a/packages/block-editor/src/components/writing-flow/index.js
+++ b/packages/block-editor/src/components/writing-flow/index.js
@@ -104,13 +104,6 @@ class WritingFlow extends Component {
onMouseDown() {
this.verticalRect = null;
- this.disableNavigationMode();
- }
-
- disableNavigationMode() {
- if ( this.props.isNavigationMode ) {
- this.props.disableNavigationMode();
- }
}
/**
@@ -377,7 +370,6 @@ class WritingFlow extends Component {
* Sets focus to the end of the last tabbable text field, if one exists.
*/
focusLastTextField() {
- this.disableNavigationMode();
const focusableNodes = focus.focusable.find( this.container );
const target = findLast( focusableNodes, isTabbableTextField );
if ( target ) {
@@ -445,11 +437,10 @@ export default compose( [
};
} ),
withDispatch( ( dispatch ) => {
- const { multiSelect, selectBlock, setNavigationMode, clearSelectedBlock } = dispatch( 'core/block-editor' );
+ const { multiSelect, selectBlock, clearSelectedBlock } = dispatch( 'core/block-editor' );
return {
onMultiSelect: multiSelect,
onSelectBlock: selectBlock,
- disableNavigationMode: () => setNavigationMode( false ),
clearSelectedBlock,
};
} ),
diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js
index 6e71703578346..06ef92914ab81 100644
--- a/packages/block-editor/src/store/actions.js
+++ b/packages/block-editor/src/store/actions.js
@@ -7,6 +7,8 @@ import { castArray, first, get, includes } from 'lodash';
* WordPress dependencies
*/
import { getDefaultBlockName, createBlock } from '@wordpress/blocks';
+import { speak } from '@wordpress/a11y';
+import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
@@ -793,15 +795,19 @@ export function __unstableMarkAutomaticChange() {
}
/**
- * Returns an action object used to enable or disable the navigation mode.
+ * Generators that triggers an action used to enable or disable the navigation mode.
*
* @param {string} isNavigationMode Enable/Disable navigation mode.
- *
- * @return {Object} Action object
*/
-export function setNavigationMode( isNavigationMode = true ) {
- return {
+export function * setNavigationMode( isNavigationMode = true ) {
+ yield {
type: 'SET_NAVIGATION_MODE',
isNavigationMode,
};
+
+ if ( isNavigationMode ) {
+ speak( __( 'You are currently in navigation mode. Navigate blocks using arrow keys. To exit navigation mode and edit the selected block, press Enter.' ) );
+ } else {
+ speak( __( 'You are currently in edit mode. To return to the navigation mode, press Escape.' ) );
+ }
}
diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js
index ac663d977e42b..d0e5d9e64dd02 100644
--- a/packages/block-editor/src/store/reducer.js
+++ b/packages/block-editor/src/store/reducer.js
@@ -1256,7 +1256,7 @@ export const blockListSettings = ( state = {}, action ) => {
*
* @return {string} Updated state.
*/
-export function isNavigationMode( state = true, action ) {
+export function isNavigationMode( state = false, action ) {
if ( action.type === 'SET_NAVIGATION_MODE' ) {
return action.isNavigationMode;
}
diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss
index 3169be962d3b3..de5698f91de48 100644
--- a/packages/block-editor/src/style.scss
+++ b/packages/block-editor/src/style.scss
@@ -32,6 +32,7 @@
@import "./components/rich-text/format-toolbar/style.scss";
@import "./components/rich-text/style.scss";
@import "./components/skip-to-selected-block/style.scss";
+@import "./components/tool-selector/style.scss";
@import "./components/url-input/style.scss";
@import "./components/url-popover/style.scss";
@import "./components/warning/style.scss";
diff --git a/packages/components/src/menu-items-choice/index.js b/packages/components/src/menu-items-choice/index.js
index 2311fd3a0435d..8412c64e4141f 100644
--- a/packages/components/src/menu-items-choice/index.js
+++ b/packages/components/src/menu-items-choice/index.js
@@ -17,6 +17,7 @@ export default function MenuItemsChoice( {
icon={ isSelected && 'yes' }
isSelected={ isSelected }
shortcut={ item.shortcut }
+ className="components-menu-items-choice"
onClick={ () => {
if ( ! isSelected ) {
onSelect( item.value );
diff --git a/packages/components/src/menu-items-choice/style.scss b/packages/components/src/menu-items-choice/style.scss
new file mode 100644
index 0000000000000..2d933a77a13a9
--- /dev/null
+++ b/packages/components/src/menu-items-choice/style.scss
@@ -0,0 +1,12 @@
+.components-menu-items-choice,
+.components-menu-items-choice.components-icon-button {
+ padding-left: 2rem;
+
+ &.has-icon {
+ padding-left: 0.5rem;
+ }
+
+ .dashicon {
+ margin-right: 4px;
+ }
+}
diff --git a/packages/components/src/style.scss b/packages/components/src/style.scss
index dbc80b743351f..a21839bd27b3f 100644
--- a/packages/components/src/style.scss
+++ b/packages/components/src/style.scss
@@ -26,6 +26,7 @@
@import "./icon-button/style.scss";
@import "./menu-group/style.scss";
@import "./menu-item/style.scss";
+@import "./menu-items-choice/style.scss";
@import "./modal/style.scss";
@import "./notice/style.scss";
@import "./panel/style.scss";
diff --git a/packages/e2e-test-utils/CHANGELOG.md b/packages/e2e-test-utils/CHANGELOG.md
index 8cbae26a2abc5..ccbbd0e96d218 100644
--- a/packages/e2e-test-utils/CHANGELOG.md
+++ b/packages/e2e-test-utils/CHANGELOG.md
@@ -1,3 +1,9 @@
+## master
+
+### Breaking Changes
+
+- The disableNavigationMode utility was removed. By default, the editor is in edit mode now.
+
## 3.0.0 (2019-11-14)
### Breaking Changes
diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md
index e01082057a82a..37d5f86d06cb9 100644
--- a/packages/e2e-test-utils/README.md
+++ b/packages/e2e-test-utils/README.md
@@ -137,14 +137,6 @@ _Parameters_
- _slug_ `string`: Plugin slug.
-# **disableNavigationMode**
-
-Triggers edit mode if not already active.
-
-_Returns_
-
-- `Promise`: Promise resolving after enabling the keyboard edit mode.
-
# **disablePrePublishChecks**
Disables Pre-publish checks.
diff --git a/packages/e2e-test-utils/src/create-new-post.js b/packages/e2e-test-utils/src/create-new-post.js
index ddc2ad64ea6c1..91a95bf5216a4 100644
--- a/packages/e2e-test-utils/src/create-new-post.js
+++ b/packages/e2e-test-utils/src/create-new-post.js
@@ -7,7 +7,6 @@ import { addQueryArgs } from '@wordpress/url';
* Internal dependencies
*/
import { visitAdminPage } from './visit-admin-page';
-import { disableNavigationMode } from './keyboard-mode';
/**
* Creates new post.
@@ -37,6 +36,4 @@ export async function createNewPost( {
if ( enableTips ) {
await page.reload();
}
-
- await disableNavigationMode();
}
diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js
index 40feec0101458..4d78447dec087 100644
--- a/packages/e2e-test-utils/src/index.js
+++ b/packages/e2e-test-utils/src/index.js
@@ -42,7 +42,6 @@ export { selectBlockByClientId } from './select-block-by-client-id';
export { setBrowserViewport } from './set-browser-viewport';
export { setPostContent } from './set-post-content';
export { switchEditorModeTo } from './switch-editor-mode-to';
-export { disableNavigationMode } from './keyboard-mode';
export { switchUserToAdmin } from './switch-user-to-admin';
export { switchUserToTest } from './switch-user-to-test';
export { toggleMoreMenu } from './toggle-more-menu';
diff --git a/packages/e2e-test-utils/src/keyboard-mode.js b/packages/e2e-test-utils/src/keyboard-mode.js
index 8928c220b28f6..8b137891791fe 100644
--- a/packages/e2e-test-utils/src/keyboard-mode.js
+++ b/packages/e2e-test-utils/src/keyboard-mode.js
@@ -1,12 +1 @@
-/**
- * Triggers edit mode if not already active.
- *
- * @return {Promise} Promise resolving after enabling the keyboard edit mode.
- */
-export async function disableNavigationMode() {
- const focusedElement = await page.$( ':focus' );
- await page.click( '.editor-post-title' );
- if ( focusedElement ) {
- await focusedElement.focus();
- }
-}
+
diff --git a/packages/e2e-tests/specs/editor/various/preview.test.js b/packages/e2e-tests/specs/editor/various/preview.test.js
index 505f8cca3ba3a..7467a9382ae48 100644
--- a/packages/e2e-tests/specs/editor/various/preview.test.js
+++ b/packages/e2e-tests/specs/editor/various/preview.test.js
@@ -15,7 +15,6 @@ import {
saveDraft,
clickOnMoreMenuItem,
pressKeyWithModifier,
- disableNavigationMode,
} from '@wordpress/e2e-test-utils';
async function openPreviewPage( editorPage ) {
@@ -206,7 +205,6 @@ describe( 'Preview with Custom Fields enabled', () => {
beforeEach( async () => {
await createNewPost();
await toggleCustomFieldsOption( true );
- await disableNavigationMode();
} );
afterEach( async () => {
diff --git a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js
index cfcd565254f2e..a160da7a4e789 100644
--- a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js
+++ b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js
@@ -118,6 +118,9 @@ describe( 'Reusable Blocks', () => {
// Tab three times to navigate to the block's content
await page.keyboard.press( 'Tab' );
await page.keyboard.press( 'Tab' );
+
+ // Quickly focus the paragraph block
+ await page.keyboard.press( 'Escape' ); // Enter navigation mode
await page.keyboard.press( 'Enter' ); // Enter edit mode
// Change the block's content
diff --git a/packages/e2e-tests/specs/editor/various/undo.test.js b/packages/e2e-tests/specs/editor/various/undo.test.js
index c8c1582eed989..7c1a2602d7bfe 100644
--- a/packages/e2e-tests/specs/editor/various/undo.test.js
+++ b/packages/e2e-tests/specs/editor/various/undo.test.js
@@ -10,7 +10,6 @@ import {
getAllBlocks,
saveDraft,
publishPost,
- disableNavigationMode,
} from '@wordpress/e2e-test-utils';
const getSelection = async () => {
@@ -331,7 +330,6 @@ describe( 'undo', () => {
await page.keyboard.type( 'original' );
await saveDraft();
await page.reload();
- await disableNavigationMode();
// Issue is demonstrated by forcing state merges (multiple inputs) on
// an existing text after a fresh reload.
diff --git a/packages/e2e-tests/specs/performance/performance.test.js b/packages/e2e-tests/specs/performance/performance.test.js
index 6246dfb4dc0d3..7f402dad605ca 100644
--- a/packages/e2e-tests/specs/performance/performance.test.js
+++ b/packages/e2e-tests/specs/performance/performance.test.js
@@ -11,7 +11,6 @@ import {
createNewPost,
saveDraft,
insertBlock,
- disableNavigationMode,
} from '@wordpress/e2e-test-utils';
function readFile( filePath ) {
@@ -54,7 +53,6 @@ describe( 'Performance', () => {
while ( i-- ) {
startTime = new Date();
await page.reload( { waitUntil: [ 'domcontentloaded', 'load' ] } );
- await disableNavigationMode();
}
await insertBlock( 'Paragraph' );
diff --git a/packages/edit-post/src/components/header/header-toolbar/index.js b/packages/edit-post/src/components/header/header-toolbar/index.js
index d02a82156fcfe..92b877e7626cf 100644
--- a/packages/edit-post/src/components/header/header-toolbar/index.js
+++ b/packages/edit-post/src/components/header/header-toolbar/index.js
@@ -11,6 +11,7 @@ import {
BlockToolbar,
NavigableToolbar,
BlockNavigationDropdown,
+ ToolSelector,
} from '@wordpress/block-editor';
import {
TableOfContents,
@@ -40,6 +41,7 @@ function HeaderToolbar( { hasFixedToolbar, isLargeViewport, showInserter, isText
+
{ hasFixedToolbar && isLargeViewport && (