From 231787a47f26e3688fc69373e4a287e0aab7e5e0 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 7 Jul 2022 13:00:41 +0400 Subject: [PATCH 1/5] Template Part: Swap block action places --- packages/block-editor/README.md | 20 +++++ packages/block-editor/src/components/index.js | 1 + .../src/template-part/edit/index.js | 42 +++++----- .../src/components/block-editor/index.js | 2 - .../edit-template-part-menu-button/index.js | 82 ------------------- packages/edit-site/src/hooks/index.js | 1 + packages/edit-site/src/hooks/template-part.js | 82 +++++++++++++++++++ 7 files changed, 127 insertions(+), 103 deletions(-) delete mode 100644 packages/edit-site/src/components/edit-template-part-menu-button/index.js create mode 100644 packages/edit-site/src/hooks/template-part.js diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 305c32f9d5d7d..e422c2b24bc58 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -691,6 +691,26 @@ _Returns_ - `?WPBlockDisplayInformation`: Block's display information, or `null` when the block or its type not found. +### useBlockDisplayTitle + +Returns the block's configured title as a string, or empty if the title +cannot be determined. + +_Usage_ + +```js +useBlockDisplayTitle( 'afd1cb17-2c08-4e7a-91be-007ba7ddc3a1', 17 ); +``` + +_Parameters_ + +- _clientId_ `string`: Client ID of block. +- _maximumLength_ `number|undefined`: The maximum length that the block title string may be before truncated. + +_Returns_ + +- `?string`: Block title. + ### useBlockEditContext The `useBlockEditContext` hook provides information about the block this hook is being used in. diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index cf1967e429cbf..b7aba6e4679fa 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -120,6 +120,7 @@ export { export { default as BlockSettingsMenu } from './block-settings-menu'; export { default as BlockSettingsMenuControls } from './block-settings-menu-controls'; export { default as BlockTitle } from './block-title'; +export { default as useBlockDisplayTitle } from './block-title/use-block-display-title'; export { default as BlockToolbar } from './block-toolbar'; export { default as BlockTools } from './block-tools'; export { diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 9d2df62a47cfd..418fc2390af6c 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -8,19 +8,15 @@ import { isEmpty } from 'lodash'; */ import { useSelect } from '@wordpress/data'; import { - BlockControls, + BlockSettingsMenuControls, useBlockProps, - __experimentalUseNoRecursiveRenders as useNoRecursiveRenders, + useBlockDisplayTitle, Warning, store as blockEditorStore, + __experimentalUseNoRecursiveRenders as useNoRecursiveRenders, __experimentalUseBlockOverlayActive as useBlockOverlayActive, } from '@wordpress/block-editor'; -import { - ToolbarGroup, - ToolbarButton, - Spinner, - Modal, -} from '@wordpress/components'; +import { Spinner, Modal, MenuItem } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import { store as coreStore } from '@wordpress/core-data'; import { useState } from '@wordpress/element'; @@ -43,6 +39,7 @@ export default function TemplatePartEdit( { attributes, setAttributes, clientId, + isSelected, } ) { const { slug, theme, tagName, layout = {} } = attributes; const templatePartId = createTemplatePartId( theme, slug ); @@ -85,6 +82,7 @@ export default function TemplatePartEdit( { }, [ templatePartId, clientId ] ); + const blockTitle = useBlockDisplayTitle( clientId, 25 ); const { templateParts } = useAlternativeTemplateParts( area, templatePartId @@ -158,20 +156,26 @@ export default function TemplatePartEdit( { /> ) } - { isEntityAvailable && + { isSelected && + isEntityAvailable && hasReplacements && ( area === 'header' || area === 'footer' ) && ( - - - - setIsTemplatePartSelectionOpen( true ) - } + + { ( { onClose } ) => ( + { + onClose(); + setIsTemplatePartSelectionOpen( true ); + } } > - { __( 'Replace' ) } - - - + { sprintf( + /* translators: %s: block name */ + __( 'Replace %s' ), + blockTitle + ) } + + ) } + ) } { isEntityAvailable && ( - <__experimentalLinkControl.ViewerFill> { useCallback( diff --git a/packages/edit-site/src/components/edit-template-part-menu-button/index.js b/packages/edit-site/src/components/edit-template-part-menu-button/index.js deleted file mode 100644 index 83a0308b1ad1e..0000000000000 --- a/packages/edit-site/src/components/edit-template-part-menu-button/index.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * WordPress dependencies - */ -import { useSelect } from '@wordpress/data'; -import { - store as blockEditorStore, - BlockSettingsMenuControls, -} from '@wordpress/block-editor'; -import { store as coreStore } from '@wordpress/core-data'; -import { MenuItem } from '@wordpress/components'; -import { isTemplatePart } from '@wordpress/blocks'; -import { __, sprintf } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import { useLocation } from '../routes'; -import { useLink } from '../routes/link'; - -export default function EditTemplatePartMenuButton() { - return ( - - { ( { selectedClientIds, onClose } ) => ( - - ) } - - ); -} - -function EditTemplatePartMenuItem( { selectedClientId, onClose } ) { - const { params } = useLocation(); - const selectedTemplatePart = useSelect( - ( select ) => { - const block = - select( blockEditorStore ).getBlock( selectedClientId ); - - if ( block && isTemplatePart( block ) ) { - const { theme, slug } = block.attributes; - - return select( coreStore ).getEntityRecord( - 'postType', - 'wp_template_part', - // Ideally this should be an official public API. - `${ theme }//${ slug }` - ); - } - }, - [ selectedClientId ] - ); - - const linkProps = useLink( - { - postId: selectedTemplatePart?.id, - postType: selectedTemplatePart?.type, - }, - { - fromTemplateId: params.postId, - } - ); - - if ( ! selectedTemplatePart ) { - return null; - } - - return ( - { - linkProps.onClick( event ); - onClose(); - } } - > - { - /* translators: %s: template part title */ - sprintf( __( 'Edit %s' ), selectedTemplatePart.slug ) - } - - ); -} diff --git a/packages/edit-site/src/hooks/index.js b/packages/edit-site/src/hooks/index.js index c6cbc1d173e86..2eb6bf4b16c4a 100644 --- a/packages/edit-site/src/hooks/index.js +++ b/packages/edit-site/src/hooks/index.js @@ -2,3 +2,4 @@ * Internal dependencies */ import './components'; +import './template-part'; diff --git a/packages/edit-site/src/hooks/template-part.js b/packages/edit-site/src/hooks/template-part.js new file mode 100644 index 0000000000000..d28530dcdc4b8 --- /dev/null +++ b/packages/edit-site/src/hooks/template-part.js @@ -0,0 +1,82 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; +import { BlockControls } from '@wordpress/block-editor'; +import { store as coreStore } from '@wordpress/core-data'; +import { ToolbarButton } from '@wordpress/components'; +import { addFilter } from '@wordpress/hooks'; +import { createHigherOrderComponent } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import { useLocation } from '../components/routes'; +import { useLink } from '../components/routes/link'; + +function EditTemplatePartMenuItem( { attributes } ) { + const { theme, slug } = attributes; + const { params } = useLocation(); + const templatePart = useSelect( + ( select ) => { + return select( coreStore ).getEntityRecord( + 'postType', + 'wp_template_part', + // Ideally this should be an official public API. + `${ theme }//${ slug }` + ); + }, + [ theme, slug ] + ); + + const linkProps = useLink( + { + postId: templatePart?.id, + postType: templatePart?.type, + }, + { + fromTemplateId: params.postId, + } + ); + + if ( ! templatePart ) { + return null; + } + + return ( + + { + linkProps.onClick( event ); + } } + > + { __( 'Edit' ) } + + + ); +} + +export const withEditBlockControls = createHigherOrderComponent( + ( BlockEdit ) => ( props ) => { + const { attributes, name } = props; + const isDisplayed = name === 'core/template-part' && attributes.slug; + + return ( + <> + + { isDisplayed && ( + + ) } + + ); + }, + 'withEditBlockControls' +); + +addFilter( + 'editor.BlockEdit', + 'core/edit-site/template-part-edit-button', + withEditBlockControls +); From b6789ee920824a6f8d9c4da8c5a143ff3cb60ea2 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 7 Jul 2022 13:21:51 +0400 Subject: [PATCH 2/5] Keep modal above dropdowns --- packages/base-styles/_z-index.scss | 1 + .../src/template-part/edit/index.js | 48 ++++++++++--------- .../src/template-part/editor.scss | 22 +++++---- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 07c4b1d2ba175..76cfad0b424a1 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -139,6 +139,7 @@ $z-layers: ( ".reusable-blocks-menu-items__convert-modal": 1000001, ".edit-site-create-template-part-modal": 1000001, ".block-editor-block-lock-modal": 1000001, + ".block-editor-template-part__selection-modal": 1000001, // Note: The ConfirmDialog component's z-index is being set to 1000001 in packages/components/src/confirm-dialog/styles.ts // because it uses emotion and not sass. We need it to render on top its parent popover. diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 418fc2390af6c..20137abd54b5c 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -103,6 +103,14 @@ export default function TemplatePartEdit( { const isEntityAvailable = ! isPlaceholder && ! isMissing && isResolved; const TagName = tagName || areaObject.tagName; + // The `isSelected` check ensures the `BlockSettingsMenuControls` fill + // doesn't render multiple times. The block controls has similar internal check. + const canReplace = + isSelected && + isEntityAvailable && + hasReplacements && + ( area === 'header' || area === 'footer' ); + // We don't want to render a missing state if we have any inner blocks. // A new template part is automatically created if we have any inner blocks but no entity. if ( @@ -156,27 +164,23 @@ export default function TemplatePartEdit( { /> ) } - { isSelected && - isEntityAvailable && - hasReplacements && - ( area === 'header' || area === 'footer' ) && ( - - { ( { onClose } ) => ( - { - onClose(); - setIsTemplatePartSelectionOpen( true ); - } } - > - { sprintf( - /* translators: %s: block name */ - __( 'Replace %s' ), - blockTitle - ) } - - ) } - - ) } + { canReplace && ( + + { () => ( + { + setIsTemplatePartSelectionOpen( true ); + } } + > + { sprintf( + /* translators: %s: block name */ + __( 'Replace %s' ), + blockTitle + ) } + + ) } + + ) } { isEntityAvailable && ( Date: Thu, 7 Jul 2022 15:09:36 +0400 Subject: [PATCH 3/5] Better name for hook file --- packages/edit-site/src/hooks/index.js | 2 +- .../src/hooks/{template-part.js => template-part-edit.js} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/edit-site/src/hooks/{template-part.js => template-part-edit.js} (100%) diff --git a/packages/edit-site/src/hooks/index.js b/packages/edit-site/src/hooks/index.js index 2eb6bf4b16c4a..1f7196dd2256c 100644 --- a/packages/edit-site/src/hooks/index.js +++ b/packages/edit-site/src/hooks/index.js @@ -2,4 +2,4 @@ * Internal dependencies */ import './components'; -import './template-part'; +import './template-part-edit'; diff --git a/packages/edit-site/src/hooks/template-part.js b/packages/edit-site/src/hooks/template-part-edit.js similarity index 100% rename from packages/edit-site/src/hooks/template-part.js rename to packages/edit-site/src/hooks/template-part-edit.js From a5ced2b34e6224279a9afb6dc6dcae92a0dc61c8 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 12 Jul 2022 15:04:50 +0400 Subject: [PATCH 4/5] Export useBlockDisplayTitle as experimental --- packages/block-editor/README.md | 20 ------------------- packages/block-editor/src/components/index.js | 2 +- .../src/template-part/edit/index.js | 4 ++-- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index e422c2b24bc58..305c32f9d5d7d 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -691,26 +691,6 @@ _Returns_ - `?WPBlockDisplayInformation`: Block's display information, or `null` when the block or its type not found. -### useBlockDisplayTitle - -Returns the block's configured title as a string, or empty if the title -cannot be determined. - -_Usage_ - -```js -useBlockDisplayTitle( 'afd1cb17-2c08-4e7a-91be-007ba7ddc3a1', 17 ); -``` - -_Parameters_ - -- _clientId_ `string`: Client ID of block. -- _maximumLength_ `number|undefined`: The maximum length that the block title string may be before truncated. - -_Returns_ - -- `?string`: Block title. - ### useBlockEditContext The `useBlockEditContext` hook provides information about the block this hook is being used in. diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index b7aba6e4679fa..03f69740775f2 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -120,7 +120,7 @@ export { export { default as BlockSettingsMenu } from './block-settings-menu'; export { default as BlockSettingsMenuControls } from './block-settings-menu-controls'; export { default as BlockTitle } from './block-title'; -export { default as useBlockDisplayTitle } from './block-title/use-block-display-title'; +export { default as __experimentalUseBlockDisplayTitle } from './block-title/use-block-display-title'; export { default as BlockToolbar } from './block-toolbar'; export { default as BlockTools } from './block-tools'; export { diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 20137abd54b5c..6a01720ef927e 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -10,9 +10,9 @@ import { useSelect } from '@wordpress/data'; import { BlockSettingsMenuControls, useBlockProps, - useBlockDisplayTitle, Warning, store as blockEditorStore, + __experimentalUseBlockDisplayTitle as useBlockDisplayTitle, __experimentalUseNoRecursiveRenders as useNoRecursiveRenders, __experimentalUseBlockOverlayActive as useBlockOverlayActive, } from '@wordpress/block-editor'; @@ -82,7 +82,7 @@ export default function TemplatePartEdit( { }, [ templatePartId, clientId ] ); - const blockTitle = useBlockDisplayTitle( clientId, 25 ); + const blockTitle = useBlockDisplayTitle( { clientId, maximumLength: 25 } ); const { templateParts } = useAlternativeTemplateParts( area, templatePartId From ad9add33a79298063a02f9d1f697fd3f521273b2 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 14 Jul 2022 13:32:45 +0400 Subject: [PATCH 5/5] Use BlockTitle and don't export title hook --- packages/block-editor/src/components/index.js | 1 - .../src/template-part/edit/index.js | 19 ++++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 03f69740775f2..cf1967e429cbf 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -120,7 +120,6 @@ export { export { default as BlockSettingsMenu } from './block-settings-menu'; export { default as BlockSettingsMenuControls } from './block-settings-menu-controls'; export { default as BlockTitle } from './block-title'; -export { default as __experimentalUseBlockDisplayTitle } from './block-title/use-block-display-title'; export { default as BlockToolbar } from './block-toolbar'; export { default as BlockTools } from './block-tools'; export { diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 6a01720ef927e..213dca72e1a4a 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -9,17 +9,17 @@ import { isEmpty } from 'lodash'; import { useSelect } from '@wordpress/data'; import { BlockSettingsMenuControls, + BlockTitle, useBlockProps, Warning, store as blockEditorStore, - __experimentalUseBlockDisplayTitle as useBlockDisplayTitle, __experimentalUseNoRecursiveRenders as useNoRecursiveRenders, __experimentalUseBlockOverlayActive as useBlockOverlayActive, } from '@wordpress/block-editor'; import { Spinner, Modal, MenuItem } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import { store as coreStore } from '@wordpress/core-data'; -import { useState } from '@wordpress/element'; +import { useState, createInterpolateElement } from '@wordpress/element'; /** * Internal dependencies @@ -82,7 +82,6 @@ export default function TemplatePartEdit( { }, [ templatePartId, clientId ] ); - const blockTitle = useBlockDisplayTitle( { clientId, maximumLength: 25 } ); const { templateParts } = useAlternativeTemplateParts( area, templatePartId @@ -172,10 +171,16 @@ export default function TemplatePartEdit( { setIsTemplatePartSelectionOpen( true ); } } > - { sprintf( - /* translators: %s: block name */ - __( 'Replace %s' ), - blockTitle + { createInterpolateElement( + __( 'Replace ' ), + { + BlockTitle: ( + + ), + } ) } ) }