diff --git a/package-lock.json b/package-lock.json
index 98f12be61be582..68ee222ddb1be3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -53316,6 +53316,7 @@
"@wordpress/icons": "file:../icons",
"@wordpress/interactivity": "file:../interactivity",
"@wordpress/interactivity-router": "file:../interactivity-router",
+ "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/notices": "file:../notices",
"@wordpress/patterns": "file:../patterns",
@@ -68634,6 +68635,7 @@
"@wordpress/icons": "file:../icons",
"@wordpress/interactivity": "file:../interactivity",
"@wordpress/interactivity-router": "file:../interactivity-router",
+ "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/notices": "file:../notices",
"@wordpress/patterns": "file:../patterns",
diff --git a/packages/block-library/package.json b/packages/block-library/package.json
index 68b1695d388378..c4cded1866a731 100644
--- a/packages/block-library/package.json
+++ b/packages/block-library/package.json
@@ -52,6 +52,7 @@
"@wordpress/icons": "file:../icons",
"@wordpress/interactivity": "file:../interactivity",
"@wordpress/interactivity-router": "file:../interactivity-router",
+ "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/notices": "file:../notices",
"@wordpress/patterns": "file:../patterns",
diff --git a/packages/block-library/src/block-keyboard-shortcuts/index.js b/packages/block-library/src/block-keyboard-shortcuts/index.js
new file mode 100644
index 00000000000000..7f9429e376d79d
--- /dev/null
+++ b/packages/block-library/src/block-keyboard-shortcuts/index.js
@@ -0,0 +1,96 @@
+/**
+ * WordPress dependencies
+ */
+import { useEffect } from '@wordpress/element';
+import { useSelect, useDispatch } from '@wordpress/data';
+import {
+ useShortcut,
+ store as keyboardShortcutsStore,
+} from '@wordpress/keyboard-shortcuts';
+import { __ } from '@wordpress/i18n';
+import { createBlock } from '@wordpress/blocks';
+import { store as blockEditorStore } from '@wordpress/block-editor';
+
+function BlockKeyboardShortcuts() {
+ const { registerShortcut } = useDispatch( keyboardShortcutsStore );
+ const { replaceBlocks } = useDispatch( blockEditorStore );
+ const { getBlockName, getSelectedBlockClientId, getBlockAttributes } =
+ useSelect( blockEditorStore );
+
+ const handleTransformHeadingAndParagraph = ( event, level ) => {
+ event.preventDefault();
+ const destinationBlockName =
+ level === 0 ? 'core/paragraph' : 'core/heading';
+ const currentClientId = getSelectedBlockClientId();
+ if ( currentClientId === null ) {
+ return;
+ }
+ const blockName = getBlockName( currentClientId );
+ if ( blockName !== 'core/paragraph' && blockName !== 'core/heading' ) {
+ return;
+ }
+ const attributes = getBlockAttributes( currentClientId );
+ const textAlign =
+ blockName === 'core/paragraph' ? 'align' : 'textAlign';
+ const destinationTextAlign =
+ destinationBlockName === 'core/paragraph' ? 'align' : 'textAlign';
+
+ replaceBlocks(
+ currentClientId,
+ createBlock( destinationBlockName, {
+ level,
+ content: attributes.content,
+ ...{ [ destinationTextAlign ]: attributes[ textAlign ] },
+ } )
+ );
+ };
+
+ useEffect( () => {
+ registerShortcut( {
+ name: 'core/block-editor/transform-heading-to-paragraph',
+ category: 'block-library',
+ description: __( 'Transform heading to paragraph.' ),
+ keyCombination: {
+ modifier: 'access',
+ character: '0',
+ },
+ aliases: [
+ {
+ modifier: 'access',
+ character: '7',
+ },
+ ],
+ } );
+
+ [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
+ registerShortcut( {
+ name: `core/block-editor/transform-paragraph-to-heading-${ level }`,
+ category: 'block-library',
+ description: __( 'Transform paragraph to heading.' ),
+ keyCombination: {
+ modifier: 'access',
+ character: `${ level }`,
+ },
+ } );
+ } );
+ }, [] );
+
+ useShortcut(
+ 'core/block-editor/transform-heading-to-paragraph',
+ ( event ) => handleTransformHeadingAndParagraph( event, 0 )
+ );
+
+ [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
+ //the loop is based off on a constant therefore
+ //the hook will execute the same way every time
+ //eslint-disable-next-line react-hooks/rules-of-hooks
+ useShortcut(
+ `core/block-editor/transform-paragraph-to-heading-${ level }`,
+ ( event ) => handleTransformHeadingAndParagraph( event, level )
+ );
+ } );
+
+ return null;
+}
+
+export default BlockKeyboardShortcuts;
diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js
index e2e0fd9e414ef3..9cb2f44d05eb9b 100644
--- a/packages/block-library/src/index.js
+++ b/packages/block-library/src/index.js
@@ -330,3 +330,5 @@ export const __experimentalRegisterExperimentalCoreBlocks = process.env
.forEach( ( { init } ) => init() );
}
: undefined;
+
+export { privateApis } from './private-apis';
diff --git a/packages/block-library/src/private-apis.js b/packages/block-library/src/private-apis.js
new file mode 100644
index 00000000000000..3cee106895d6d7
--- /dev/null
+++ b/packages/block-library/src/private-apis.js
@@ -0,0 +1,13 @@
+/**
+ * Internal dependencies
+ */
+import { default as BlockKeyboardShortcuts } from './block-keyboard-shortcuts';
+import { lock } from './lock-unlock';
+
+/**
+ * @private
+ */
+export const privateApis = {};
+lock( privateApis, {
+ BlockKeyboardShortcuts,
+} );
diff --git a/packages/customize-widgets/src/components/keyboard-shortcut-help-modal/config.js b/packages/customize-widgets/src/components/keyboard-shortcut-help-modal/config.js
index 4edf46204c75ae..0380028aa100c0 100644
--- a/packages/customize-widgets/src/components/keyboard-shortcut-help-modal/config.js
+++ b/packages/customize-widgets/src/components/keyboard-shortcut-help-modal/config.js
@@ -37,7 +37,16 @@ export const textFormattingShortcuts = [
description: __( 'Make the selected text inline code.' ),
},
{
- keyCombination: { modifier: 'access', character: '0' },
+ keyCombination: {
+ modifier: 'access',
+ character: '0',
+ },
+ aliases: [
+ {
+ modifier: 'access',
+ character: '7',
+ },
+ ],
description: __( 'Convert the current heading to a paragraph.' ),
},
{
diff --git a/packages/customize-widgets/src/components/keyboard-shortcuts/index.js b/packages/customize-widgets/src/components/keyboard-shortcuts/index.js
index b7cdc1d42de863..5c5f3ea2bca832 100644
--- a/packages/customize-widgets/src/components/keyboard-shortcuts/index.js
+++ b/packages/customize-widgets/src/components/keyboard-shortcuts/index.js
@@ -7,44 +7,10 @@ import {
store as keyboardShortcutsStore,
} from '@wordpress/keyboard-shortcuts';
import { isAppleOS } from '@wordpress/keycodes';
-import { useDispatch, useSelect } from '@wordpress/data';
+import { useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
-import { store as blockEditorStore } from '@wordpress/block-editor';
-import { createBlock } from '@wordpress/blocks';
function KeyboardShortcuts( { undo, redo, save } ) {
- const { replaceBlocks } = useDispatch( blockEditorStore );
- const { getBlockName, getSelectedBlockClientId, getBlockAttributes } =
- useSelect( blockEditorStore );
-
- const handleTextLevelShortcut = ( event, level ) => {
- event.preventDefault();
- const destinationBlockName =
- level === 0 ? 'core/paragraph' : 'core/heading';
- const currentClientId = getSelectedBlockClientId();
- if ( currentClientId === null ) {
- return;
- }
- const blockName = getBlockName( currentClientId );
- if ( blockName !== 'core/paragraph' && blockName !== 'core/heading' ) {
- return;
- }
- const attributes = getBlockAttributes( currentClientId );
- const textAlign =
- blockName === 'core/paragraph' ? 'align' : 'textAlign';
- const destinationTextAlign =
- destinationBlockName === 'core/paragraph' ? 'align' : 'textAlign';
-
- replaceBlocks(
- currentClientId,
- createBlock( destinationBlockName, {
- level,
- content: attributes.content,
- ...{ [ destinationTextAlign ]: attributes[ textAlign ] },
- } )
- );
- };
-
useShortcut( 'core/customize-widgets/undo', ( event ) => {
undo();
event.preventDefault();
@@ -60,21 +26,6 @@ function KeyboardShortcuts( { undo, redo, save } ) {
save();
} );
- useShortcut(
- 'core/customize-widgets/transform-heading-to-paragraph',
- ( event ) => handleTextLevelShortcut( event, 0 )
- );
-
- [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
- //the loop is based off on a constant therefore
- //the hook will execute the same way every time
- //eslint-disable-next-line react-hooks/rules-of-hooks
- useShortcut(
- `core/customize-widgets/transform-paragraph-to-heading-${ level }`,
- ( event ) => handleTextLevelShortcut( event, level )
- );
- } );
-
return null;
}
@@ -126,28 +77,6 @@ function KeyboardShortcutsRegister() {
},
} );
- registerShortcut( {
- name: 'core/customize-widgets/transform-heading-to-paragraph',
- category: 'block-library',
- description: __( 'Transform heading to paragraph.' ),
- keyCombination: {
- modifier: 'access',
- character: `0`,
- },
- } );
-
- [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
- registerShortcut( {
- name: `core/customize-widgets/transform-paragraph-to-heading-${ level }`,
- category: 'block-library',
- description: __( 'Transform paragraph to heading.' ),
- keyCombination: {
- modifier: 'access',
- character: `${ level }`,
- },
- } );
- } );
-
return () => {
unregisterShortcut( 'core/customize-widgets/undo' );
unregisterShortcut( 'core/customize-widgets/redo' );
diff --git a/packages/customize-widgets/src/components/sidebar-block-editor/index.js b/packages/customize-widgets/src/components/sidebar-block-editor/index.js
index 80deb12dfcf74d..a42ec50097bcba 100644
--- a/packages/customize-widgets/src/components/sidebar-block-editor/index.js
+++ b/packages/customize-widgets/src/components/sidebar-block-editor/index.js
@@ -14,6 +14,7 @@ import {
} from '@wordpress/block-editor';
import { uploadMedia } from '@wordpress/media-utils';
import { store as preferencesStore } from '@wordpress/preferences';
+import { privateApis as blockLibraryPrivateApis } from '@wordpress/block-library';
/**
* Internal dependencies
@@ -31,6 +32,8 @@ const { ExperimentalBlockCanvas: BlockCanvas } = unlock(
blockEditorPrivateApis
);
+const { BlockKeyboardShortcuts } = unlock( blockLibraryPrivateApis );
+
export default function SidebarBlockEditor( {
blockEditorSettings,
sidebar,
@@ -99,6 +102,7 @@ export default function SidebarBlockEditor( {
return (
<>
+
{
- event.preventDefault();
- const destinationBlockName =
- level === 0 ? 'core/paragraph' : 'core/heading';
- const currentClientId = getSelectedBlockClientId();
- if ( currentClientId === null ) {
- return;
- }
- const blockName = getBlockName( currentClientId );
- if ( blockName !== 'core/paragraph' && blockName !== 'core/heading' ) {
- return;
- }
- const attributes = getBlockAttributes( currentClientId );
- const textAlign =
- blockName === 'core/paragraph' ? 'align' : 'textAlign';
- const destinationTextAlign =
- destinationBlockName === 'core/paragraph' ? 'align' : 'textAlign';
-
- replaceBlocks(
- currentClientId,
- createBlock( destinationBlockName, {
- level,
- content: attributes.content,
- ...{ [ destinationTextAlign ]: attributes[ textAlign ] },
- } )
- );
- };
useEffect( () => {
registerShortcut( {
@@ -97,48 +64,12 @@ function KeyboardShortcuts() {
},
],
} );
-
- registerShortcut( {
- name: 'core/edit-post/transform-heading-to-paragraph',
- category: 'block-library',
- description: __( 'Transform heading to paragraph.' ),
- keyCombination: {
- modifier: 'access',
- character: `0`,
- },
- } );
-
- [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
- registerShortcut( {
- name: `core/edit-post/transform-paragraph-to-heading-${ level }`,
- category: 'block-library',
- description: __( 'Transform paragraph to heading.' ),
- keyCombination: {
- modifier: 'access',
- character: `${ level }`,
- },
- } );
- } );
}, [] );
useShortcut( 'core/edit-post/toggle-fullscreen', () => {
toggleFeature( 'fullscreenMode' );
} );
- useShortcut( 'core/edit-post/transform-heading-to-paragraph', ( event ) =>
- handleTextLevelShortcut( event, 0 )
- );
-
- [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
- //the loop is based off on a constant therefore
- //the hook will execute the same way every time
- //eslint-disable-next-line react-hooks/rules-of-hooks
- useShortcut(
- `core/edit-post/transform-paragraph-to-heading-${ level }`,
- ( event ) => handleTextLevelShortcut( event, level )
- );
- } );
-
return null;
}
diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js
index 09a08da149ee03..6169e38122a0b2 100644
--- a/packages/edit-post/src/components/layout/index.js
+++ b/packages/edit-post/src/components/layout/index.js
@@ -34,6 +34,7 @@ import { store as noticesStore } from '@wordpress/notices';
import { store as preferencesStore } from '@wordpress/preferences';
import { privateApis as commandsPrivateApis } from '@wordpress/commands';
import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands';
+import { privateApis as blockLibraryPrivateApis } from '@wordpress/block-library';
/**
* Internal dependencies
@@ -64,6 +65,7 @@ const {
InterfaceSkeleton,
interfaceStore,
} = unlock( editorPrivateApis );
+const { BlockKeyboardShortcuts } = unlock( blockLibraryPrivateApis );
const interfaceLabels = {
/* translators: accessibility text for the editor top bar landmark region. */
@@ -286,6 +288,7 @@ function Layout( { initialPost } ) {
+
-
+
>
) }
>
diff --git a/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js b/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js
deleted file mode 100644
index 597cde29e9f272..00000000000000
--- a/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * WordPress dependencies
- */
-import { useShortcut } from '@wordpress/keyboard-shortcuts';
-import { useDispatch, useSelect } from '@wordpress/data';
-import { store as blockEditorStore } from '@wordpress/block-editor';
-import { createBlock } from '@wordpress/blocks';
-
-function KeyboardShortcutsEditMode() {
- const { replaceBlocks } = useDispatch( blockEditorStore );
- const { getBlockName, getSelectedBlockClientId, getBlockAttributes } =
- useSelect( blockEditorStore );
-
- const handleTextLevelShortcut = ( event, level ) => {
- event.preventDefault();
- const destinationBlockName =
- level === 0 ? 'core/paragraph' : 'core/heading';
- const currentClientId = getSelectedBlockClientId();
- if ( currentClientId === null ) {
- return;
- }
- const blockName = getBlockName( currentClientId );
- if ( blockName !== 'core/paragraph' && blockName !== 'core/heading' ) {
- return;
- }
- const attributes = getBlockAttributes( currentClientId );
- const textAlign =
- blockName === 'core/paragraph' ? 'align' : 'textAlign';
- const destinationTextAlign =
- destinationBlockName === 'core/paragraph' ? 'align' : 'textAlign';
-
- replaceBlocks(
- currentClientId,
- createBlock( destinationBlockName, {
- level,
- content: attributes.content,
- ...{ [ destinationTextAlign ]: attributes[ textAlign ] },
- } )
- );
- };
-
- useShortcut( 'core/edit-site/transform-heading-to-paragraph', ( event ) =>
- handleTextLevelShortcut( event, 0 )
- );
-
- [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
- //the loop is based off on a constant therefore
- //the hook will execute the same way every time
- //eslint-disable-next-line react-hooks/rules-of-hooks
- useShortcut(
- `core/edit-site/transform-paragraph-to-heading-${ level }`,
- ( event ) => handleTextLevelShortcut( event, level )
- );
- } );
-
- return null;
-}
-
-export default KeyboardShortcutsEditMode;
diff --git a/packages/edit-site/src/components/keyboard-shortcuts/register.js b/packages/edit-site/src/components/keyboard-shortcuts/register.js
index 6b4d9789a6f389..acbff4ab00846c 100644
--- a/packages/edit-site/src/components/keyboard-shortcuts/register.js
+++ b/packages/edit-site/src/components/keyboard-shortcuts/register.js
@@ -55,28 +55,6 @@ function KeyboardShortcutsRegister() {
},
],
} );
-
- registerShortcut( {
- name: 'core/edit-site/transform-heading-to-paragraph',
- category: 'block-library',
- description: __( 'Transform heading to paragraph.' ),
- keyCombination: {
- modifier: 'access',
- character: `0`,
- },
- } );
-
- [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
- registerShortcut( {
- name: `core/edit-site/transform-paragraph-to-heading-${ level }`,
- category: 'block-library',
- description: __( 'Transform paragraph to heading.' ),
- keyCombination: {
- modifier: 'access',
- character: `${ level }`,
- },
- } );
- } );
}, [ registerShortcut ] );
return null;
diff --git a/packages/edit-widgets/src/components/keyboard-shortcut-help-modal/config.js b/packages/edit-widgets/src/components/keyboard-shortcut-help-modal/config.js
index 4edf46204c75ae..0380028aa100c0 100644
--- a/packages/edit-widgets/src/components/keyboard-shortcut-help-modal/config.js
+++ b/packages/edit-widgets/src/components/keyboard-shortcut-help-modal/config.js
@@ -37,7 +37,16 @@ export const textFormattingShortcuts = [
description: __( 'Make the selected text inline code.' ),
},
{
- keyCombination: { modifier: 'access', character: '0' },
+ keyCombination: {
+ modifier: 'access',
+ character: '0',
+ },
+ aliases: [
+ {
+ modifier: 'access',
+ character: '7',
+ },
+ ],
description: __( 'Convert the current heading to a paragraph.' ),
},
{
diff --git a/packages/edit-widgets/src/components/keyboard-shortcuts/index.js b/packages/edit-widgets/src/components/keyboard-shortcuts/index.js
index dff0ac57f78c12..65ecceeb4aa8c1 100644
--- a/packages/edit-widgets/src/components/keyboard-shortcuts/index.js
+++ b/packages/edit-widgets/src/components/keyboard-shortcuts/index.js
@@ -7,11 +7,9 @@ import {
store as keyboardShortcutsStore,
} from '@wordpress/keyboard-shortcuts';
import { isAppleOS } from '@wordpress/keycodes';
-import { useDispatch, useSelect } from '@wordpress/data';
+import { useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { store as coreStore } from '@wordpress/core-data';
-import { store as blockEditorStore } from '@wordpress/block-editor';
-import { createBlock } from '@wordpress/blocks';
/**
* Internal dependencies
@@ -22,38 +20,6 @@ function KeyboardShortcuts() {
const { redo, undo } = useDispatch( coreStore );
const { saveEditedWidgetAreas } = useDispatch( editWidgetsStore );
- const { replaceBlocks } = useDispatch( blockEditorStore );
- const { getBlockName, getSelectedBlockClientId, getBlockAttributes } =
- useSelect( blockEditorStore );
-
- const handleTextLevelShortcut = ( event, level ) => {
- event.preventDefault();
- const destinationBlockName =
- level === 0 ? 'core/paragraph' : 'core/heading';
- const currentClientId = getSelectedBlockClientId();
- if ( currentClientId === null ) {
- return;
- }
- const blockName = getBlockName( currentClientId );
- if ( blockName !== 'core/paragraph' && blockName !== 'core/heading' ) {
- return;
- }
- const attributes = getBlockAttributes( currentClientId );
- const textAlign =
- blockName === 'core/paragraph' ? 'align' : 'textAlign';
- const destinationTextAlign =
- destinationBlockName === 'core/paragraph' ? 'align' : 'textAlign';
-
- replaceBlocks(
- currentClientId,
- createBlock( destinationBlockName, {
- level,
- content: attributes.content,
- ...{ [ destinationTextAlign ]: attributes[ textAlign ] },
- } )
- );
- };
-
useShortcut( 'core/edit-widgets/undo', ( event ) => {
undo();
event.preventDefault();
@@ -69,21 +35,6 @@ function KeyboardShortcuts() {
saveEditedWidgetAreas();
} );
- useShortcut(
- 'core/edit-widgets/transform-heading-to-paragraph',
- ( event ) => handleTextLevelShortcut( event, 0 )
- );
-
- [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
- //the loop is based off on a constant therefore
- //the hook will execute the same way every time
- //eslint-disable-next-line react-hooks/rules-of-hooks
- useShortcut(
- `core/edit-widgets/transform-paragraph-to-heading-${ level }`,
- ( event ) => handleTextLevelShortcut( event, level )
- );
- } );
-
return null;
}
@@ -178,28 +129,6 @@ function KeyboardShortcutsRegister() {
},
],
} );
-
- registerShortcut( {
- name: 'core/edit-widgets/transform-heading-to-paragraph',
- category: 'block-library',
- description: __( 'Transform heading to paragraph.' ),
- keyCombination: {
- modifier: 'access',
- character: `0`,
- },
- } );
-
- [ 1, 2, 3, 4, 5, 6 ].forEach( ( level ) => {
- registerShortcut( {
- name: `core/edit-widgets/transform-paragraph-to-heading-${ level }`,
- category: 'block-library',
- description: __( 'Transform paragraph to heading.' ),
- keyCombination: {
- modifier: 'access',
- character: `${ level }`,
- },
- } );
- } );
}, [ registerShortcut ] );
return null;
diff --git a/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js b/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
index 4abc420434cc44..55704bfc7680ff 100644
--- a/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
+++ b/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
@@ -14,6 +14,7 @@ import { useMemo } from '@wordpress/element';
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
import { privateApis as editPatternsPrivateApis } from '@wordpress/patterns';
import { store as preferencesStore } from '@wordpress/preferences';
+import { privateApis as blockLibraryPrivateApis } from '@wordpress/block-library';
/**
* Internal dependencies
@@ -27,6 +28,8 @@ import { unlock } from '../../lock-unlock';
const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis );
const { PatternsMenuItems } = unlock( editPatternsPrivateApis );
+const { BlockKeyboardShortcuts } = unlock( blockLibraryPrivateApis );
+
export default function WidgetAreasBlockEditorProvider( {
blockEditorSettings,
children,
@@ -111,6 +114,7 @@ export default function WidgetAreasBlockEditorProvider( {
return (
+