diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index b0f60d9621d58..28e90fd7672e4 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -860,6 +860,20 @@ _Returns_ - `string`: Client Id of moving block. +### hasDraggedInnerBlock + +Returns true if one of the block's inner blocks is dragged. + +_Parameters_ + +- _state_ `Object`: Editor state. +- _clientId_ `string`: Block client ID. +- _deep_ `boolean`: Perform a deep check. + +_Returns_ + +- `boolean`: Whether the block has an inner block dragged + ### hasInserterItems Determines whether there are items to show in the inserter. @@ -909,7 +923,7 @@ _Parameters_ _Returns_ -- `boolean`: Whether the block as an inner block selected +- `boolean`: Whether the block has an inner block selected ### isAncestorBeingDragged diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 5ba407d14b608..17a2934227d7b 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1199,7 +1199,7 @@ export function isBlockSelected( state, clientId ) { * @param {string} clientId Block client ID. * @param {boolean} deep Perform a deep check. * - * @return {boolean} Whether the block as an inner block selected + * @return {boolean} Whether the block has an inner block selected */ export function hasSelectedInnerBlock( state, clientId, deep = false ) { return getBlockOrder( state, clientId ).some( @@ -1210,6 +1210,23 @@ export function hasSelectedInnerBlock( state, clientId, deep = false ) { ); } +/** + * Returns true if one of the block's inner blocks is dragged. + * + * @param {Object} state Editor state. + * @param {string} clientId Block client ID. + * @param {boolean} deep Perform a deep check. + * + * @return {boolean} Whether the block has an inner block dragged + */ +export function hasDraggedInnerBlock( state, clientId, deep = false ) { + return getBlockOrder( state, clientId ).some( + ( innerClientId ) => + isBlockBeingDragged( state, innerClientId ) || + ( deep && hasDraggedInnerBlock( state, innerClientId, deep ) ) + ); +} + /** * Returns true if the block corresponding to the specified client ID is * currently selected but isn't the last of the selected blocks. Here "last" diff --git a/packages/block-library/src/page-list-item/edit.js b/packages/block-library/src/page-list-item/edit.js index 2c9a6a69d5e4a..7e20cdc5ae2d2 100644 --- a/packages/block-library/src/page-list-item/edit.js +++ b/packages/block-library/src/page-list-item/edit.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; - /** * WordPress dependencies */ diff --git a/packages/block-library/src/page-list/edit.js b/packages/block-library/src/page-list/edit.js index 0bbfb8ba5c7e4..c145acf727d0e 100644 --- a/packages/block-library/src/page-list/edit.js +++ b/packages/block-library/src/page-list/edit.js @@ -25,9 +25,9 @@ import { Button, } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; -import { useMemo, useState, useEffect } from '@wordpress/element'; +import { useMemo, useState, useEffect, useCallback } from '@wordpress/element'; import { useEntityRecords } from '@wordpress/core-data'; -import { useSelect } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; /** * Internal dependencies @@ -113,29 +113,6 @@ function BlockContent( { } } -function ConvertToLinks( { onClick, disabled } ) { - const [ isOpen, setOpen ] = useState( false ); - const openModal = () => setOpen( true ); - const closeModal = () => setOpen( false ); - - return ( - <> - - - { __( 'Edit' ) } - - - { isOpen && ( - - ) } - - ); -} - export default function PageListEdit( { context, clientId, @@ -143,6 +120,9 @@ export default function PageListEdit( { setAttributes, } ) { const { parentPageID } = attributes; + const [ isOpen, setOpen ] = useState( false ); + const openModal = useCallback( () => setOpen( true ), [] ); + const closeModal = () => setOpen( false ); const { records: pages, hasResolved: hasResolvedPages } = useEntityRecords( 'postType', @@ -263,34 +243,69 @@ export default function PageListEdit( { parentPageID, ] ); - const innerBlocksProps = useInnerBlocksProps( blockProps, { - allowedBlocks: [ 'core/page-list-item' ], - renderAppender: false, - __unstableDisableDropZone: true, - templateLock: 'all', - onInput: NOOP, - onChange: NOOP, - value: blockList, - } ); - - const { isNested } = useSelect( + const { + isNested, + hasSelectedChild, + parentBlock, + hasDraggedChild, + isChildOfNavigation, + } = useSelect( ( select ) => { - const { getBlockParentsByBlockName } = select( blockEditorStore ); + const { + getBlockParentsByBlockName, + hasSelectedInnerBlock, + getBlockRootClientId, + hasDraggedInnerBlock, + } = select( blockEditorStore ); const blockParents = getBlockParentsByBlockName( clientId, 'core/navigation-submenu', true ); + const navigationBlockParents = getBlockParentsByBlockName( + clientId, + 'core/navigation', + true + ); return { isNested: blockParents.length > 0, + isChildOfNavigation: navigationBlockParents.length > 0, + hasSelectedChild: hasSelectedInnerBlock( clientId, true ), + hasDraggedChild: hasDraggedInnerBlock( clientId, true ), + parentBlock: getBlockRootClientId( clientId ), }; }, [ clientId ] ); + const innerBlocksProps = useInnerBlocksProps( blockProps, { + allowedBlocks: [ 'core/page-list-item' ], + renderAppender: false, + __unstableDisableDropZone: true, + templateLock: isChildOfNavigation ? false : 'all', + onInput: NOOP, + onChange: NOOP, + value: blockList, + } ); + + const { selectBlock } = useDispatch( blockEditorStore ); + + useEffect( () => { + if ( hasSelectedChild || hasDraggedChild ) { + openModal(); + selectBlock( parentBlock ); + } + }, [ + hasSelectedChild, + hasDraggedChild, + parentBlock, + selectBlock, + openModal, + ] ); + useEffect( () => { setAttributes( { isNested } ); - }, [ isNested ] ); + }, [ isNested, setAttributes ] ); return ( <> @@ -325,10 +340,23 @@ export default function PageListEdit( { ) } { allowConvertToLinks && ( - + <> + + + { __( 'Edit' ) } + + + { isOpen && ( + + ) } + ) }