From 0d5c3108708266b1cb139087529556027a664a27 Mon Sep 17 00:00:00 2001 From: Yogesh Bhutkar Date: Fri, 28 Feb 2025 15:59:00 +0530 Subject: [PATCH] Block Action: Implement cut functionality in block actions and settings menu. (#68554) Co-authored-by: yogeshbhutkar Co-authored-by: t-hamano Co-authored-by: carolinan Co-authored-by: afercia Co-authored-by: Mamaduka Co-authored-by: fabiankaegy --- .../block-settings-dropdown.js | 33 +++++++++++++++---- .../components/keyboard-shortcuts/index.js | 30 +++++++++++++++++ .../editor/various/write-design-mode.spec.js | 4 +-- test/e2e/specs/site-editor/zoom-out.spec.js | 6 ++-- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js b/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js index 43922c28a668e2..7fa9e1d1a21963 100644 --- a/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js +++ b/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js @@ -11,7 +11,6 @@ import { useDispatch, useSelect } from '@wordpress/data'; import { moreVertical } from '@wordpress/icons'; import { Children, cloneElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -import { displayShortcut } from '@wordpress/keycodes'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; import { pipe, useCopyToClipboard } from '@wordpress/compose'; @@ -39,16 +38,27 @@ function CopyMenuItem( { label, shortcut, eventType = 'copy', + __experimentalUpdateSelection: updateSelection = false, } ) { const { getBlocksByClientId } = useSelect( blockEditorStore ); + const { removeBlocks } = useDispatch( blockEditorStore ); const notifyCopy = useNotifyCopy(); const ref = useCopyToClipboard( () => serialize( getBlocksByClientId( clientIds ) ), () => { - if ( onCopy && eventType === 'copy' ) { - onCopy(); + switch ( eventType ) { + case 'copy': + case 'copyStyles': + onCopy(); + notifyCopy( eventType, clientIds ); + break; + case 'cut': + notifyCopy( eventType, clientIds ); + removeBlocks( clientIds, updateSelection ); + break; + default: + break; } - notifyCopy( eventType, clientIds ); } ); const copyMenuItemLabel = label ? label : __( 'Copy' ); @@ -127,6 +137,8 @@ export function BlockSettingsDropdown( { const shortcuts = useSelect( ( select ) => { const { getShortcutRepresentation } = select( keyboardShortcutsStore ); return { + copy: getShortcutRepresentation( 'core/block-editor/copy' ), + cut: getShortcutRepresentation( 'core/block-editor/cut' ), duplicate: getShortcutRepresentation( 'core/block-editor/duplicate' ), @@ -266,9 +278,16 @@ export function BlockSettingsDropdown( { + { canDuplicate && ( { + registerShortcut( { + name: 'core/block-editor/copy', + category: 'block', + description: __( 'Copy the selected block(s).' ), + keyCombination: { + modifier: 'primary', + character: 'c', + }, + } ); + + registerShortcut( { + name: 'core/block-editor/cut', + category: 'block', + description: __( 'Cut the selected block(s).' ), + keyCombination: { + modifier: 'primary', + character: 'x', + }, + } ); + + registerShortcut( { + name: 'core/block-editor/paste', + category: 'block', + description: __( 'Paste the selected block(s).' ), + keyCombination: { + modifier: 'primary', + character: 'v', + }, + } ); + registerShortcut( { name: 'core/block-editor/duplicate', category: 'block', diff --git a/test/e2e/specs/editor/various/write-design-mode.spec.js b/test/e2e/specs/editor/various/write-design-mode.spec.js index fb3e231e6fff60..7f5c28c168f59c 100644 --- a/test/e2e/specs/editor/various/write-design-mode.spec.js +++ b/test/e2e/specs/editor/various/write-design-mode.spec.js @@ -108,8 +108,8 @@ test.describe( 'Write/Design mode', () => { .getByRole( 'menu', { name: 'Options' } ) .getByRole( 'menuitem' ); - // we expect 3 items in the options menu - await expect( optionsMenu ).toHaveCount( 3 ); + // we expect 4 items in the options menu + await expect( optionsMenu ).toHaveCount( 4 ); // We should be able to select the paragraph block and write in it. await paragraph.click(); diff --git a/test/e2e/specs/site-editor/zoom-out.spec.js b/test/e2e/specs/site-editor/zoom-out.spec.js index 493b566671f8be..8986215e0b222b 100644 --- a/test/e2e/specs/site-editor/zoom-out.spec.js +++ b/test/e2e/specs/site-editor/zoom-out.spec.js @@ -234,7 +234,7 @@ test.describe( 'Zoom Out', () => { await expect( fourthSectionStart ).not.toBeInViewport(); } ); - test( 'Zoom out selected section has three items in options menu', async ( { + test( 'Zoom out selected section has four items in options menu', async ( { page, } ) => { // open the inserter @@ -263,8 +263,8 @@ test.describe( 'Zoom Out', () => { .getByRole( 'menu', { name: 'Options' } ) .getByRole( 'menuitem' ); - // we expect 3 items in the options menu - await expect( optionsMenu ).toHaveCount( 3 ); + // we expect 4 items in the options menu + await expect( optionsMenu ).toHaveCount( 4 ); } ); test( 'Zoom Out cannot be activated when the section root is missing', async ( {