diff --git a/packages/block-editor/src/components/block-lock/index.js b/packages/block-editor/src/components/block-lock/index.js index a935e52673eb2..7578a611980b3 100644 --- a/packages/block-editor/src/components/block-lock/index.js +++ b/packages/block-editor/src/components/block-lock/index.js @@ -1,3 +1,4 @@ export { default as BlockLockMenuItem } from './menu-item'; export { default as BlockLockModal } from './modal'; export { default as BlockLockToolbar } from './toolbar'; +export { default as useBlockLock } from './use-block-lock'; diff --git a/packages/block-editor/src/components/block-lock/menu-item.js b/packages/block-editor/src/components/block-lock/menu-item.js index fb860c2f48239..7c66038beb6f6 100644 --- a/packages/block-editor/src/components/block-lock/menu-item.js +++ b/packages/block-editor/src/components/block-lock/menu-item.js @@ -4,43 +4,24 @@ import { __ } from '@wordpress/i18n'; import { useReducer } from '@wordpress/element'; import { MenuItem } from '@wordpress/components'; -import { useSelect } from '@wordpress/data'; import { lock, unlock } from '@wordpress/icons'; /** * Internal dependencies */ +import useBlockLock from './use-block-lock'; import BlockLockModal from './modal'; -import { store as blockEditorStore } from '../../store'; export default function BlockLockMenuItem( { clientId } ) { - const { canLockBlock, isLocked } = useSelect( - ( select ) => { - const { - canMoveBlock, - canRemoveBlock, - canLockBlockType, - getBlockName, - getBlockRootClientId, - } = select( blockEditorStore ); - const rootClientId = getBlockRootClientId( clientId ); - - return { - canLockBlock: canLockBlockType( getBlockName( clientId ) ), - isLocked: - ! canMoveBlock( clientId, rootClientId ) || - ! canRemoveBlock( clientId, rootClientId ), - }; - }, - [ clientId ] - ); + const { canMove, canRemove, canLock } = useBlockLock( clientId, true ); + const isLocked = ! canMove || ! canRemove; const [ isModalOpen, toggleModal ] = useReducer( ( isActive ) => ! isActive, false ); - if ( ! canLockBlock ) { + if ( ! canLock ) { return null; } diff --git a/packages/block-editor/src/components/block-lock/modal.js b/packages/block-editor/src/components/block-lock/modal.js index 77c9d7388d584..99ff8f7c55ba9 100644 --- a/packages/block-editor/src/components/block-lock/modal.js +++ b/packages/block-editor/src/components/block-lock/modal.js @@ -13,32 +13,18 @@ import { } from '@wordpress/components'; import { lock as lockIcon, unlock as unlockIcon } from '@wordpress/icons'; import { useInstanceId } from '@wordpress/compose'; -import { useDispatch, useSelect } from '@wordpress/data'; +import { useDispatch } from '@wordpress/data'; /** * Internal dependencies */ +import useBlockLock from './use-block-lock'; import useBlockDisplayInformation from '../use-block-display-information'; import { store as blockEditorStore } from '../../store'; export default function BlockLockModal( { clientId, onClose } ) { const [ lock, setLock ] = useState( { move: false, remove: false } ); - const { canMove, canRemove } = useSelect( - ( select ) => { - const { - canMoveBlock, - canRemoveBlock, - getBlockRootClientId, - } = select( blockEditorStore ); - const rootClientId = getBlockRootClientId( clientId ); - - return { - canMove: canMoveBlock( clientId, rootClientId ), - canRemove: canRemoveBlock( clientId, rootClientId ), - }; - }, - [ clientId ] - ); + const { canMove, canRemove } = useBlockLock( clientId, true ); const { updateBlockAttributes } = useDispatch( blockEditorStore ); const blockInformation = useBlockDisplayInformation( clientId ); const instanceId = useInstanceId( diff --git a/packages/block-editor/src/components/block-lock/toolbar.js b/packages/block-editor/src/components/block-lock/toolbar.js index 1011138279783..f8b6cfd48cc9c 100644 --- a/packages/block-editor/src/components/block-lock/toolbar.js +++ b/packages/block-editor/src/components/block-lock/toolbar.js @@ -5,41 +5,24 @@ import { __, sprintf } from '@wordpress/i18n'; import { ToolbarButton, ToolbarGroup } from '@wordpress/components'; import { useReducer } from '@wordpress/element'; import { lock } from '@wordpress/icons'; -import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import BlockLockModal from './modal'; +import useBlockLock from './use-block-lock'; import useBlockDisplayInformation from '../use-block-display-information'; -import { store as blockEditorStore } from '../../store'; export default function BlockLockToolbar( { clientId } ) { const blockInformation = useBlockDisplayInformation( clientId ); - const { canMove, canRemove, canLockBlock } = useSelect( - ( select ) => { - const { - canMoveBlock, - canRemoveBlock, - canLockBlockType, - getBlockName, - } = select( blockEditorStore ); - - return { - canMove: canMoveBlock( clientId ), - canRemove: canRemoveBlock( clientId ), - canLockBlock: canLockBlockType( getBlockName( clientId ) ), - }; - }, - [ clientId ] - ); + const { canMove, canRemove, canLock } = useBlockLock( clientId ); const [ isModalOpen, toggleModal ] = useReducer( ( isActive ) => ! isActive, false ); - if ( ! canLockBlock ) { + if ( ! canLock ) { return null; } diff --git a/packages/block-editor/src/components/block-lock/use-block-lock.js b/packages/block-editor/src/components/block-lock/use-block-lock.js new file mode 100644 index 0000000000000..86b1e24564587 --- /dev/null +++ b/packages/block-editor/src/components/block-lock/use-block-lock.js @@ -0,0 +1,41 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; + +/** + * Return details about the block lock status. + * + * @param {string} clientId The block client Id. + * @param {boolean} checkRoot Optional. Use root client ID when checking lock status. + * + * @return {Object} Block lock status + */ +export default function useBlockLock( clientId, checkRoot = false ) { + return useSelect( + ( select ) => { + const { + canMoveBlock, + canRemoveBlock, + canLockBlockType, + getBlockName, + getBlockRootClientId, + } = select( blockEditorStore ); + const rootClientId = checkRoot + ? getBlockRootClientId( clientId ) + : null; + + return { + canMove: canMoveBlock( clientId, rootClientId ), + canRemove: canRemoveBlock( clientId, rootClientId ), + canLock: canLockBlockType( getBlockName( clientId ) ), + }; + }, + [ clientId, checkRoot ] + ); +} diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index b15b7631f46d8..27ca4bff483f6 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -8,7 +8,6 @@ import classnames from 'classnames'; */ import { Button } from '@wordpress/components'; import { forwardRef } from '@wordpress/element'; -import { useSelect } from '@wordpress/data'; import { Icon, lock } from '@wordpress/icons'; import { SPACE, ENTER } from '@wordpress/keycodes'; @@ -19,7 +18,7 @@ import BlockIcon from '../block-icon'; import useBlockDisplayInformation from '../use-block-display-information'; import BlockTitle from '../block-title'; import ListViewExpander from './expander'; -import { store as blockEditorStore } from '../../store'; +import { useBlockLock } from '../block-lock'; function ListViewBlockSelectButton( { @@ -36,14 +35,8 @@ function ListViewBlockSelectButton( ref ) { const blockInformation = useBlockDisplayInformation( clientId ); - const isLocked = useSelect( - ( select ) => { - const { canMoveBlock, canRemoveBlock } = select( blockEditorStore ); - - return ! canMoveBlock( clientId ) || ! canRemoveBlock( clientId ); - }, - [ clientId ] - ); + const { canMove, canRemove } = useBlockLock( clientId ); + const isLocked = ! canMove || ! canRemove; // The `href` attribute triggers the browser's native HTML drag operations. // When the link is dragged, the element's outerHTML is set in DataTransfer object as text/html.