From df890f8bdb8cffa498c7d34d87bce27c5837f7a9 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 7 Aug 2020 14:38:05 -0700 Subject: [PATCH 01/15] Add template part label --- .../src/template-part/edit/index.js | 25 +++++++++++++---- .../src/template-part/edit/label.js | 27 ++++++++++++++++++ .../src/template-part/editor.scss | 28 +++++++++++++++++++ 3 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 packages/block-library/src/template-part/edit/label.js diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 891bd30b53b70..fa9f8c0679b96 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -10,6 +10,7 @@ import { BlockControls } from '@wordpress/block-editor'; */ import useTemplatePartPost from './use-template-part-post'; import TemplatePartNamePanel from './name-panel'; +import TemplatePartLabel from './label'; import TemplatePartInnerBlocks from './inner-blocks'; import TemplatePartPlaceholder from './placeholder'; @@ -29,11 +30,18 @@ export default function TemplatePartEdit( { // but wait until the third inner blocks change, // because the first 2 are just the template part // content loading. - const { innerBlocks } = useSelect( + const { innerBlocks, hasSelectedInnerBlock } = useSelect( ( select ) => { - const { getBlocks } = select( 'core/block-editor' ); + const { + getBlocks, + hasSelectedInnerBlock: getHasSelectedInnerBlock, + } = select( 'core/block-editor' ); return { innerBlocks: getBlocks( clientId ), + hasSelectedInnerBlock: getHasSelectedInnerBlock( + clientId, + true + ), }; }, [ clientId ] @@ -67,10 +75,15 @@ export default function TemplatePartEdit( { setAttributes={ setAttributes } /> - 0 } - /> +
+ { hasSelectedInnerBlock && ( + + ) } + 0 } + /> +
); } diff --git a/packages/block-library/src/template-part/edit/label.js b/packages/block-library/src/template-part/edit/label.js new file mode 100644 index 0000000000000..f854f11d4ea2a --- /dev/null +++ b/packages/block-library/src/template-part/edit/label.js @@ -0,0 +1,27 @@ +/** + * WordPress dependencies + */ +import { useEntityProp } from '@wordpress/core-data'; +import { Icon } from '@wordpress/components'; + +export default function TemplatePartLabel( { postId, slug } ) { + const [ title ] = useEntityProp( + 'postType', + 'wp_template_part', + 'title', + postId + ); + + return ( +
+
+
+ + + { title || slug } + +
+
+
+ ); +} diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index 87e9a5dbb4f58..af2726c51a2c9 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -77,6 +77,34 @@ } } +.wp-block-template-part__label-container { + position: absolute; + bottom: 100%; + width: 100%; + + .wp-block-template-part__label-layout { + display: flex; + justify-content: flex-start; + } + + .wp-block-template-part__label-content { + display: flex; + align-items: center; + border: 1px solid $gray-600; + border-bottom: none; + border-top-right-radius: 2px; + border-top-left-radius: 2px; + padding: 2px 6px; + } + + .wp-block-template-part__label-text { + color: $black; + font-size: 10px; + text-transform: uppercase; + padding-left: 4px; + } +} + .is-navigate-mode .is-selected .wp-block-template-part__name-panel { box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color); From aba1d5906889bdad6e0b285bf2aee56330d306d0 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Thu, 13 Aug 2020 15:09:37 -0700 Subject: [PATCH 02/15] Update label border styling --- packages/block-library/src/template-part/editor.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index af2726c51a2c9..6606ae53aac19 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -92,9 +92,9 @@ align-items: center; border: 1px solid $gray-600; border-bottom: none; - border-top-right-radius: 2px; - border-top-left-radius: 2px; - padding: 2px 6px; + border-top-right-radius: $radius-block-ui; + border-top-left-radius: $radius-block-ui; + padding: 0 6px; } .wp-block-template-part__label-text { From 765c441bc9d01a46a2c86e415cf8a2c0c0c1b7a6 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 14 Aug 2020 12:05:55 -0700 Subject: [PATCH 03/15] Use default font sizes --- packages/block-library/src/template-part/edit/label.js | 2 +- packages/block-library/src/template-part/editor.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/template-part/edit/label.js b/packages/block-library/src/template-part/edit/label.js index f854f11d4ea2a..e9825fa962244 100644 --- a/packages/block-library/src/template-part/edit/label.js +++ b/packages/block-library/src/template-part/edit/label.js @@ -16,7 +16,7 @@ export default function TemplatePartLabel( { postId, slug } ) {
- + { title || slug } diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index 6606ae53aac19..590af075f7438 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -99,7 +99,7 @@ .wp-block-template-part__label-text { color: $black; - font-size: 10px; + font-size: $default-font-size; text-transform: uppercase; padding-left: 4px; } From 265a487cc4df8c8cea591118681e3ddfbb9dea22 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 14 Aug 2020 12:08:32 -0700 Subject: [PATCH 04/15] Use predefined border width --- packages/block-library/src/template-part/editor.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index 590af075f7438..eb48d29eae5aa 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -90,7 +90,7 @@ .wp-block-template-part__label-content { display: flex; align-items: center; - border: 1px solid $gray-600; + border: $border-width solid $gray-600; border-bottom: none; border-top-right-radius: $radius-block-ui; border-top-left-radius: $radius-block-ui; From 3dcb166c6de686fbbf2e2f1560cb5d85fc9df10c Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 14 Aug 2020 13:40:41 -0700 Subject: [PATCH 05/15] Remove inline position relative styling --- packages/block-library/src/template-part/edit/index.js | 2 +- packages/block-library/src/template-part/editor.scss | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index fa9f8c0679b96..6fcdbb20e32ee 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -75,7 +75,7 @@ export default function TemplatePartEdit( { setAttributes={ setAttributes } /> -
+
{ hasSelectedInnerBlock && ( ) } diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index eb48d29eae5aa..289dcc26129ae 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -1,3 +1,6 @@ +.wp-block-template-part__container { + position: "relative"; +} .wp-block-template-part__placeholder-preview-dropdown-content { .components-popover__content { From 99c6daa2eda8e6b6eb68f6fea88a856dad1b9ae8 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 14 Aug 2020 13:42:54 -0700 Subject: [PATCH 06/15] Remove explicit color style for label text --- packages/block-library/src/template-part/editor.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index 289dcc26129ae..96459d8ef9441 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -101,7 +101,6 @@ } .wp-block-template-part__label-text { - color: $black; font-size: $default-font-size; text-transform: uppercase; padding-left: 4px; From b381994ba25acd3be55bf1d4802ef0bc361bc470 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Mon, 17 Aug 2020 09:41:54 -0700 Subject: [PATCH 07/15] Fix template part container classname Co-authored-by: Nik Tsekouras --- packages/block-library/src/template-part/edit/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 6fcdbb20e32ee..aa0b2fd665c38 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -75,7 +75,7 @@ export default function TemplatePartEdit( { setAttributes={ setAttributes } /> -
+
{ hasSelectedInnerBlock && ( ) } From 8502f49fe2d987b80cb7ca334e59f834719c9673 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Mon, 17 Aug 2020 11:05:33 -0700 Subject: [PATCH 08/15] Disable labels in navigation mode --- packages/block-library/src/template-part/edit/index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index aa0b2fd665c38..46e4a398e269f 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -30,14 +30,16 @@ export default function TemplatePartEdit( { // but wait until the third inner blocks change, // because the first 2 are just the template part // content loading. - const { innerBlocks, hasSelectedInnerBlock } = useSelect( + const { isNavigationMode, innerBlocks, hasSelectedInnerBlock } = useSelect( ( select ) => { const { getBlocks, hasSelectedInnerBlock: getHasSelectedInnerBlock, + isNavigationMode: _isNavigationMode, } = select( 'core/block-editor' ); return { innerBlocks: getBlocks( clientId ), + isNavigationMode: _isNavigationMode, hasSelectedInnerBlock: getHasSelectedInnerBlock( clientId, true @@ -65,6 +67,8 @@ export default function TemplatePartEdit( { } }, [ innerBlocks ] ); + const shouldDisplayLabel = ! isNavigationMode() && hasSelectedInnerBlock; + if ( postId ) { // Part of a template file, post ID already resolved. return ( @@ -76,7 +80,7 @@ export default function TemplatePartEdit( { />
- { hasSelectedInnerBlock && ( + { shouldDisplayLabel && ( ) } Date: Wed, 19 Aug 2020 11:10:59 -0700 Subject: [PATCH 09/15] Only display labels on parent, and not ancestor, template parts In a scenario where a template part with content is nested within another template part, only the direct parent's label should be displayed because only the direct parent has it's data modified from a technical point of view. --- .../developers/data/data-core-block-editor.md | 13 +++++++++++++ packages/block-editor/src/store/selectors.js | 15 +++++++++++++++ .../src/template-part/edit/index.js | 16 +++++++++------- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index 0010e906d0531..2c12526a8dc37 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -232,6 +232,19 @@ _Returns_ - `Array`: Ordered client IDs of editor blocks. +# **getBlockParent** + +Given a block client ID, returns the direct parent. + +_Parameters_ + +- _state_ `Object`: Editor state. +- _clientId_ `string`: Block from which to find root client ID. + +_Returns_ + +- `string`: ClientID of the parent block. + # **getBlockParents** Given a block client ID, returns the list of all its parents from top to bottom. diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index e923580b30d11..ebebfa5789f32 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -481,6 +481,21 @@ export const getBlockParents = createSelector( ( state ) => [ state.blocks.parents ] ); +/** + * Given a block client ID, returns the direct parent. + * + * @param {Object} state Editor state. + * @param {string} clientId Block from which to find root client ID. + * + * @return {string} ClientID of the parent block. + */ +export const getBlockParent = createSelector( + ( state, clientId ) => { + return state.blocks.parents[ clientId ]; + }, + ( state ) => [ state.blocks.parents ] +); + /** * Given a block client ID and a block name, * returns the list of all its parents from top to bottom, diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 46e4a398e269f..3895285543f02 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -30,20 +30,21 @@ export default function TemplatePartEdit( { // but wait until the third inner blocks change, // because the first 2 are just the template part // content loading. - const { isNavigationMode, innerBlocks, hasSelectedInnerBlock } = useSelect( + const { isNavigationMode, directParentId, innerBlocks } = useSelect( ( select ) => { const { getBlocks, - hasSelectedInnerBlock: getHasSelectedInnerBlock, + getSelectedBlockClientId, isNavigationMode: _isNavigationMode, + getBlockParent, } = select( 'core/block-editor' ); + + const selectedBlockClientId = getSelectedBlockClientId(); + return { innerBlocks: getBlocks( clientId ), isNavigationMode: _isNavigationMode, - hasSelectedInnerBlock: getHasSelectedInnerBlock( - clientId, - true - ), + directParentId: getBlockParent( selectedBlockClientId ), }; }, [ clientId ] @@ -67,7 +68,8 @@ export default function TemplatePartEdit( { } }, [ innerBlocks ] ); - const shouldDisplayLabel = ! isNavigationMode() && hasSelectedInnerBlock; + const isParentOfSelectedBlock = directParentId === clientId; + const shouldDisplayLabel = ! isNavigationMode() && isParentOfSelectedBlock; if ( postId ) { // Part of a template file, post ID already resolved. From c5cb850519ee91306118599aae637511c1f69ac9 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Thu, 20 Aug 2020 14:41:33 -0700 Subject: [PATCH 10/15] Title case the label --- packages/block-library/src/template-part/edit/label.js | 8 +++++++- packages/block-library/src/template-part/editor.scss | 4 ---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/template-part/edit/label.js b/packages/block-library/src/template-part/edit/label.js index e9825fa962244..386bb6268fa44 100644 --- a/packages/block-library/src/template-part/edit/label.js +++ b/packages/block-library/src/template-part/edit/label.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { capitalize } from 'lodash'; + /** * WordPress dependencies */ @@ -12,13 +17,14 @@ export default function TemplatePartLabel( { postId, slug } ) { postId ); + const label = capitalize( title || slug ); return (
- { title || slug } + { label }
diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index 96459d8ef9441..813b498677e14 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -1,6 +1,3 @@ -.wp-block-template-part__container { - position: "relative"; -} .wp-block-template-part__placeholder-preview-dropdown-content { .components-popover__content { @@ -102,7 +99,6 @@ .wp-block-template-part__label-text { font-size: $default-font-size; - text-transform: uppercase; padding-left: 4px; } } From e02db488fd27dc1c3983e949d4d64f8a87a70680 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Thu, 20 Aug 2020 15:06:50 -0700 Subject: [PATCH 11/15] Modify temporary template part label icon --- packages/block-library/src/template-part/edit/label.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/template-part/edit/label.js b/packages/block-library/src/template-part/edit/label.js index 386bb6268fa44..2a39f168285da 100644 --- a/packages/block-library/src/template-part/edit/label.js +++ b/packages/block-library/src/template-part/edit/label.js @@ -18,11 +18,12 @@ export default function TemplatePartLabel( { postId, slug } ) { ); const label = capitalize( title || slug ); + return (
- + { label } From 9c220720818a82a504ac034ca967350427b42c9e Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Thu, 20 Aug 2020 16:22:22 -0700 Subject: [PATCH 12/15] Display the label, even when children are multi selected --- .../block-library/src/template-part/edit/index.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 3895285543f02..5f1bc65ed757a 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -30,21 +30,25 @@ export default function TemplatePartEdit( { // but wait until the third inner blocks change, // because the first 2 are just the template part // content loading. - const { isNavigationMode, directParentId, innerBlocks } = useSelect( + const { isNavigationMode, parentId, innerBlocks } = useSelect( ( select ) => { const { getBlocks, - getSelectedBlockClientId, + getSelectionStart, isNavigationMode: _isNavigationMode, getBlockParent, } = select( 'core/block-editor' ); - const selectedBlockClientId = getSelectedBlockClientId(); + // Only sibling blocks can be multi-selected. This + // means that the parent should be the same for all + // multi-selected blocks. We arbitrarily select the first + // multi-selected block. + const selectedBlockClientId = getSelectionStart()?.clientId; return { innerBlocks: getBlocks( clientId ), isNavigationMode: _isNavigationMode, - directParentId: getBlockParent( selectedBlockClientId ), + parentId: getBlockParent( selectedBlockClientId ), }; }, [ clientId ] @@ -68,7 +72,7 @@ export default function TemplatePartEdit( { } }, [ innerBlocks ] ); - const isParentOfSelectedBlock = directParentId === clientId; + const isParentOfSelectedBlock = parentId === clientId; const shouldDisplayLabel = ! isNavigationMode() && isParentOfSelectedBlock; if ( postId ) { From 791e11058aa87c1e49d5c896fbae701f8d614b77 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 21 Aug 2020 11:21:14 -0700 Subject: [PATCH 13/15] Render label at bottom when colliding with block toolbar --- .../src/template-part/edit/index.js | 18 +++++-- .../src/template-part/edit/label.js | 54 ++++++++++++++++++- .../src/template-part/editor.scss | 18 ++++++- 3 files changed, 83 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 5f1bc65ed757a..8121034a20546 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -30,7 +30,12 @@ export default function TemplatePartEdit( { // but wait until the third inner blocks change, // because the first 2 are just the template part // content loading. - const { isNavigationMode, parentId, innerBlocks } = useSelect( + const { + isNavigationMode, + parentId, + innerBlocks, + selectedBlockClientId, + } = useSelect( ( select ) => { const { getBlocks, @@ -43,12 +48,13 @@ export default function TemplatePartEdit( { // means that the parent should be the same for all // multi-selected blocks. We arbitrarily select the first // multi-selected block. - const selectedBlockClientId = getSelectionStart()?.clientId; + const _selectedBlockClientId = getSelectionStart()?.clientId; return { innerBlocks: getBlocks( clientId ), isNavigationMode: _isNavigationMode, - parentId: getBlockParent( selectedBlockClientId ), + parentId: getBlockParent( _selectedBlockClientId ), + selectedBlockClientId: _selectedBlockClientId, }; }, [ clientId ] @@ -87,7 +93,11 @@ export default function TemplatePartEdit( {
{ shouldDisplayLabel && ( - + ) } rect2.right || + rect1.bottom < rect2.top || + rect1.top > rect2.bottom + ); + return overlap; + } +} + +function useOverlapDetection( + firstElement, + secondElement, + selectedBlockClientId +) { + const [ isOverlapped, setIsOverlapped ] = useState( false ); + + useEffect( () => { + setIsOverlapped( detectOverlap( firstElement.current, secondElement ) ); + }, [ selectedBlockClientId ] ); + + return isOverlapped; +} + +export default function TemplatePartLabel( { + postId, + slug, + selectedBlockClientId, +} ) { const [ title ] = useEntityProp( 'postType', 'wp_template_part', 'title', postId ); + const labelElement = useRef( null ); + const toolbarElement = document.getElementsByClassName( + 'block-editor-block-contextual-toolbar-wrapper' + )[ 0 ]; + const isOverlapped = useOverlapDetection( + labelElement, + toolbarElement, + selectedBlockClientId + ); const label = capitalize( title || slug ); return ( -
+
diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index 813b498677e14..d0e7affccb7c5 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -90,7 +90,7 @@ .wp-block-template-part__label-content { display: flex; align-items: center; - border: $border-width solid $gray-600; + border: $border-width solid $gray-200; border-bottom: none; border-top-right-radius: $radius-block-ui; border-top-left-radius: $radius-block-ui; @@ -101,6 +101,22 @@ font-size: $default-font-size; padding-left: 4px; } + + &.overlapped { + top: 100%; + + .wp-block-template-part__label-content { + display: flex; + align-items: center; + border: $border-width solid $gray-200; + border-top: none; + border-top-right-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: $radius-block-ui; + border-bottom-left-radius: $radius-block-ui; + padding: 0 6px; + } + } } .is-navigate-mode .is-selected .wp-block-template-part__name-panel { From 062cb353db1f6bc9b84b2cccb0b60f3b0d007e72 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 21 Aug 2020 12:17:29 -0700 Subject: [PATCH 14/15] Only detect collision between label content and block toolbar --- packages/block-library/src/template-part/edit/label.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/template-part/edit/label.js b/packages/block-library/src/template-part/edit/label.js index c5a44d74007d8..8680019717fcc 100644 --- a/packages/block-library/src/template-part/edit/label.js +++ b/packages/block-library/src/template-part/edit/label.js @@ -12,8 +12,8 @@ import { useEntityProp } from '@wordpress/core-data'; import { Icon } from '@wordpress/components'; function detectOverlap( e1, e2 ) { - const rect1 = e1.getBoundingClientRect(); - const rect2 = e2.getBoundingClientRect(); + const rect1 = e1 && e1.getBoundingClientRect(); + const rect2 = e2 && e2.getBoundingClientRect(); let overlap = null; if ( rect1 && rect2 ) { @@ -69,10 +69,12 @@ export default function TemplatePartLabel( { className={ cx( 'wp-block-template-part__label-container', { overlapped: isOverlapped, } ) } - ref={ labelElement } >
-
+
{ label } From 56b8e36d526f267ba80f70686d0cc9498983b571 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Mon, 24 Aug 2020 13:08:04 -0700 Subject: [PATCH 15/15] Refactor label overlap detection We want to compare the template part label and block toolbar for overlap. Previously, we did so by selecting the block toolbar by classname. In some cases, however, the selector would be executed before the DOM was updated, returning an undefined reference. We now handle selection of the block toolbar element differently. The block toolbar id is updated on every new block selection. Because of this, we, instead, save the programatically generated block toolbar id in the redux store. We then wait until the id is updated before reevaluating block toolbar overlap with the template part label. --- .../developers/data/data-core-block-editor.md | 20 +++++++++ .../src/components/navigable-toolbar/index.js | 8 ++++ packages/block-editor/src/store/actions.js | 12 ++++++ packages/block-editor/src/store/reducer.js | 20 +++++++++ packages/block-editor/src/store/selectors.js | 14 +++++++ .../src/template-part/edit/label.js | 42 +++++++------------ 6 files changed, 90 insertions(+), 26 deletions(-) diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index 2c12526a8dc37..3d0c0c0a551b0 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -694,6 +694,18 @@ _Returns_ - `?string`: Block Template Lock +# **getToolbarId** + +Returns the current id of the Block toolbar + +_Parameters_ + +- _state_ `Object`: Editor state. + +_Returns_ + +- `string`: Id of the currently focused block toolbar. + # **hasBlockMovingClientId** Returns whether block moving mode is enabled. @@ -1314,6 +1326,14 @@ _Parameters_ - _hasBlockMovingClientId_ `(string|null)`: Enable/Disable block moving mode. +# **setBlockToolbarId** + +Returns an action object that sets whether the block has controlled innerblocks. + +_Parameters_ + +- _id_ `string`: The current block toolbar's id. + # **setHasControlledInnerBlocks** Returns an action object that sets whether the block has controlled innerblocks. diff --git a/packages/block-editor/src/components/navigable-toolbar/index.js b/packages/block-editor/src/components/navigable-toolbar/index.js index 931932b7ab6da..1d086f5ca33f3 100644 --- a/packages/block-editor/src/components/navigable-toolbar/index.js +++ b/packages/block-editor/src/components/navigable-toolbar/index.js @@ -9,6 +9,7 @@ import { useEffect, useCallback, } from '@wordpress/element'; +import { useDispatch } from '@wordpress/data'; import deprecated from '@wordpress/deprecated'; import { focus } from '@wordpress/dom'; import { useShortcut } from '@wordpress/keyboard-shortcuts'; @@ -108,6 +109,13 @@ function useToolbarFocus( ref, focusOnMount, isAccessibleToolbar ) { function NavigableToolbar( { children, focusOnMount, ...props } ) { const wrapper = useRef(); + + const { setBlockToolbarId } = useDispatch( 'core/block-editor' ); + + useEffect( () => { + setBlockToolbarId( wrapper.current.id ); + }, [ wrapper.current ] ); + const isAccessibleToolbar = useIsAccessibleToolbar( wrapper ); useToolbarFocus( wrapper, focusOnMount, isAccessibleToolbar ); diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index fa1b6db198c59..b8dfe2662444e 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -1100,3 +1100,15 @@ export function setHasControlledInnerBlocks( clientId, }; } + +/** + * Returns an action object that sets whether the block has controlled innerblocks. + * + * @param {string} id The current block toolbar's id. + */ +export function setBlockToolbarId( id ) { + return { + type: 'SET_BLOCK_TOOLBAR_ID', + id, + }; +} diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index 529cd32036434..ba327db07d5ef 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1650,6 +1650,25 @@ export function highlightedBlock( state, action ) { return state; } +/** + * Reducer returning current the currently selected block toolbar id. + * + * @param {boolean} state Current state. + * @param {Object} action Dispatched action. + * + * @return {string} Current block toolbar id. + */ +export function toolbarId( state, action ) { + switch ( action.type ) { + case 'SET_BLOCK_TOOLBAR_ID': + const { id } = action; + + return id; + } + + return state; +} + export default combineReducers( { blocks, isTyping, @@ -1671,4 +1690,5 @@ export default combineReducers( { hasBlockMovingClientId, automaticChangeStatus, highlightedBlock, + toolbarId, } ); diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index ebebfa5789f32..3313527b5f1a7 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -496,6 +496,20 @@ export const getBlockParent = createSelector( ( state ) => [ state.blocks.parents ] ); +/** + * Returns the current id of the Block toolbar + * + * @param {Object} state Editor state. + * + * @return {string} Id of the currently focused block toolbar. + */ +export const getToolbarId = createSelector( + ( state ) => { + return state.toolbarId; + }, + ( state ) => [ state.toolbarId ] +); + /** * Given a block client ID and a block name, * returns the list of all its parents from top to bottom, diff --git a/packages/block-library/src/template-part/edit/label.js b/packages/block-library/src/template-part/edit/label.js index 8680019717fcc..9c6a2acf4ccaf 100644 --- a/packages/block-library/src/template-part/edit/label.js +++ b/packages/block-library/src/template-part/edit/label.js @@ -8,6 +8,7 @@ import cx from 'classnames'; * WordPress dependencies */ import { useRef, useState, useEffect } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; import { useEntityProp } from '@wordpress/core-data'; import { Icon } from '@wordpress/components'; @@ -25,43 +26,32 @@ function detectOverlap( e1, e2 ) { ); return overlap; } -} - -function useOverlapDetection( - firstElement, - secondElement, - selectedBlockClientId -) { - const [ isOverlapped, setIsOverlapped ] = useState( false ); - useEffect( () => { - setIsOverlapped( detectOverlap( firstElement.current, secondElement ) ); - }, [ selectedBlockClientId ] ); - - return isOverlapped; + return false; } -export default function TemplatePartLabel( { - postId, - slug, - selectedBlockClientId, -} ) { +export default function TemplatePartLabel( { postId, slug } ) { const [ title ] = useEntityProp( 'postType', 'wp_template_part', 'title', postId ); + + const { toolbarId } = useSelect( ( select ) => { + const { getToolbarId } = select( 'core/block-editor' ); + return { toolbarId: getToolbarId() }; + } ); + const labelElement = useRef( null ); - const toolbarElement = document.getElementsByClassName( - 'block-editor-block-contextual-toolbar-wrapper' - )[ 0 ]; + const [ toolbarElement, setToolbarElement ] = useState( null ); - const isOverlapped = useOverlapDetection( - labelElement, - toolbarElement, - selectedBlockClientId - ); + useEffect( () => { + const toolbar = document.getElementById( toolbarId ); + setToolbarElement( toolbar ); + }, [ toolbarId ] ); + + const isOverlapped = detectOverlap( labelElement.current, toolbarElement ); const label = capitalize( title || slug ); return (