diff --git a/packages/block-editor/src/components/block-card/index.js b/packages/block-editor/src/components/block-card/index.js index dab832861ae661..405a741125635f 100644 --- a/packages/block-editor/src/components/block-card/index.js +++ b/packages/block-editor/src/components/block-card/index.js @@ -30,9 +30,12 @@ function BlockCard( { title, icon, description, blockType, className } ) { const isOffCanvasNavigationEditorEnabled = window?.__experimentalEnableOffCanvasNavigationEditor === true; - const { parentNavBlockClientId } = useSelect( ( select ) => { - const { getSelectedBlockClientId, getBlockParentsByBlockName } = - select( blockEditorStore ); + const { parentNavBlockClientId, isSynced } = useSelect( ( select ) => { + const { + getSelectedBlockClientId, + getBlockParentsByBlockName, + areInnerBlocksControlled, + } = select( blockEditorStore ); const _selectedBlockClientId = getSelectedBlockClientId(); @@ -42,6 +45,7 @@ function BlockCard( { title, icon, description, blockType, className } ) { 'core/navigation', true )[ 0 ], + isSynced: areInnerBlocksControlled( _selectedBlockClientId ), }; }, [] ); @@ -65,6 +69,11 @@ function BlockCard( { title, icon, description, blockType, className } ) {

{ title }

+ { isSynced && ( + + Synced + + ) } { description } diff --git a/packages/block-editor/src/components/block-card/style.scss b/packages/block-editor/src/components/block-card/style.scss index 1b2156c19fa797..e0bad067299882 100644 --- a/packages/block-editor/src/components/block-card/style.scss +++ b/packages/block-editor/src/components/block-card/style.scss @@ -17,6 +17,18 @@ } } +.block-editor-block-card__sync-status { + margin-block-start: $grid-unit-05; + margin-block-end: $grid-unit-15; + display: block; + width: min-content; + color: #fff; + background-color: var(--wp-block-synced-color); + padding: 3px 6px; + font-size: 0.9em; + border-radius: $radius-block-ui; +} + .block-editor-block-card__description { font-size: $default-font-size; } diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 70456ac213fc3b..93920260c01e6b 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -103,6 +103,7 @@ function BlockListBlock( { isContentBlock, isContentLocking, isTemporarilyEditingAsBlocks, + isSyncedBlock, } = useSelect( ( select ) => { const { @@ -110,9 +111,13 @@ function BlockListBlock( { __unstableGetContentLockingParent, getTemplateLock, __unstableGetTemporarilyEditingAsBlocks, + areInnerBlocksControlled, } = select( blockEditorStore ); const _hasContentLockedParent = !! __unstableGetContentLockingParent( clientId ); + + const _isSyncedBlock = areInnerBlocksControlled( clientId ); + return { themeSupportsLayout: getSettings().supportsLayout, isContentBlock: @@ -125,6 +130,7 @@ function BlockListBlock( { ! _hasContentLockedParent, isTemporarilyEditingAsBlocks: __unstableGetTemporarilyEditingAsBlocks() === clientId, + isSyncedBlock: _isSyncedBlock, }; }, [ name, clientId ] @@ -153,6 +159,7 @@ function BlockListBlock( { toggleSelection={ toggleSelection } __unstableLayoutClassNames={ layoutClassNames } __unstableParentLayout={ parentLayout } + __unstableIsSyncedBlock={ isSyncedBlock } /> ); @@ -236,6 +243,7 @@ function BlockListBlock( { 'is-content-locked-temporarily-editing-as-blocks': isTemporarilyEditingAsBlocks, 'is-content-block': hasContentLockedParent && isContentBlock, + 'is-synced': isSyncedBlock, }, dataAlign && themeSupportsLayout && `align${ dataAlign }`, className diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss index 7219275196d8fb..9fde919e62ac65 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -435,3 +435,23 @@ transition: all 0.3s; transform-origin: top center; } + +// This needs moving to a generic file as it now applies to all blocks that are "synced". +.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block.is-synced { + + &.is-highlighted, + &.is-selected { + box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color); + } + + &.block-editor-block-list__block:not([contenteditable]):focus { + &::after { + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color); + + // Show a light color for dark themes. + .is-dark-theme & { + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $dark-theme-focus; + } + } + } +} diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index 6727851e1647bf..7868eb51df58aa 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -9,12 +9,7 @@ import classnames from 'classnames'; import { useSelect, useDispatch } from '@wordpress/data'; import { useRef } from '@wordpress/element'; import { useViewportMatch } from '@wordpress/compose'; -import { - getBlockType, - hasBlockSupport, - isReusableBlock, - isTemplatePart, -} from '@wordpress/blocks'; +import { getBlockType, hasBlockSupport } from '@wordpress/blocks'; import { ToolbarGroup } from '@wordpress/components'; /** @@ -43,6 +38,7 @@ const BlockToolbar = ( { hideDragHandle } ) => { isValid, isVisual, isContentLocked, + isSynced, } = useSelect( ( select ) => { const { getBlockName, @@ -52,6 +48,7 @@ const BlockToolbar = ( { hideDragHandle } ) => { getBlockRootClientId, getSettings, __unstableGetContentLockingParent, + areInnerBlocksControlled, } = select( blockEditorStore ); const selectedBlockClientIds = getSelectedBlockClientIds(); const selectedBlockClientId = selectedBlockClientIds[ 0 ]; @@ -76,6 +73,7 @@ const BlockToolbar = ( { hideDragHandle } ) => { isContentLocked: !! __unstableGetContentLockingParent( selectedBlockClientId ), + isSynced: areInnerBlocksControlled( selectedBlockClientId ), }; }, [] ); @@ -114,8 +112,6 @@ const BlockToolbar = ( { hideDragHandle } ) => { const shouldShowVisualToolbar = isValid && isVisual; const isMultiToolbar = blockClientIds.length > 1; - const isSynced = - isReusableBlock( blockType ) || isTemplatePart( blockType ); const classes = classnames( 'block-editor-block-toolbar', { 'is-showing-movers': shouldShowMovers, diff --git a/packages/block-editor/src/components/use-block-display-information/index.js b/packages/block-editor/src/components/use-block-display-information/index.js index e9b1e8865a05cf..2a6d2089e82872 100644 --- a/packages/block-editor/src/components/use-block-display-information/index.js +++ b/packages/block-editor/src/components/use-block-display-information/index.js @@ -2,11 +2,7 @@ * WordPress dependencies */ import { useSelect } from '@wordpress/data'; -import { - store as blocksStore, - isReusableBlock, - isTemplatePart, -} from '@wordpress/blocks'; +import { store as blocksStore } from '@wordpress/blocks'; /** * Internal dependencies @@ -20,7 +16,7 @@ import { store as blockEditorStore } from '../../store'; * * @typedef {Object} WPBlockDisplayInformation * - * @property {boolean} isSynced True if is a reusable block or template part + * @property {boolean} isSynced True if inner blocks are controlled. * @property {string} title Human-readable block type label. * @property {WPIcon} icon Block type icon. * @property {string} description A detailed block type description. @@ -46,8 +42,11 @@ export default function useBlockDisplayInformation( clientId ) { return useSelect( ( select ) => { if ( ! clientId ) return null; - const { getBlockName, getBlockAttributes } = - select( blockEditorStore ); + const { + getBlockName, + getBlockAttributes, + areInnerBlocksControlled, + } = select( blockEditorStore ); const { getBlockType, getActiveBlockVariation } = select( blocksStore ); const blockName = getBlockName( clientId ); @@ -55,8 +54,7 @@ export default function useBlockDisplayInformation( clientId ) { if ( ! blockType ) return null; const attributes = getBlockAttributes( clientId ); const match = getActiveBlockVariation( blockName, attributes ); - const isSynced = - isReusableBlock( blockType ) || isTemplatePart( blockType ); + const isSynced = areInnerBlocksControlled( clientId ); const blockTypeInfo = { isSynced, title: blockType.title, diff --git a/packages/block-library/src/template-part/editor.scss b/packages/block-library/src/template-part/editor.scss index a847ecec01f94d..4aaa788be3e942 100644 --- a/packages/block-library/src/template-part/editor.scss +++ b/packages/block-library/src/template-part/editor.scss @@ -24,21 +24,3 @@ padding: $grid-unit-20 0; z-index: z-index(".block-library-template-part__selection-search"); } - -.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part, -.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable { - &.is-highlighted, - &.is-selected { - box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color); - } - - &.block-editor-block-list__block:not([contenteditable]):focus { - &::after { - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color); - // Show a light color for dark themes. - .is-dark-theme & { - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $dark-theme-focus; - } - } - } -}