diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index 20d6ebfe5291a..8b0f24e60fb7b 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -538,7 +538,6 @@ _Parameters_ - _state_ `Object`: Editor state. - _rootClientId_ `?string`: Optional root client ID of block list. -- _syncStatus_ `?string`: Optional sync status to filter pattern blocks by. _Returns_ diff --git a/docs/reference-guides/data/data-core.md b/docs/reference-guides/data/data-core.md index 8db3a26dd0977..a66c0991e3d27 100644 --- a/docs/reference-guides/data/data-core.md +++ b/docs/reference-guides/data/data-core.md @@ -329,18 +329,6 @@ _Returns_ - `any`: The entity record's save error. -### getNavigationFallbackId - -Retrieve the fallback Navigation. - -_Parameters_ - -- _state_ `State`: Data state. - -_Returns_ - -- `EntityRecordKey | undefined`: The ID for the fallback Navigation post. - ### getRawEntityRecord Returns the entity's record object by key, with its attributes mapped to their raw values. diff --git a/lib/compat/wordpress-6.3/block-template-utils.php b/lib/compat/wordpress-6.3/block-template-utils.php index cdd870db2d081..cc367f66dd42d 100644 --- a/lib/compat/wordpress-6.3/block-template-utils.php +++ b/lib/compat/wordpress-6.3/block-template-utils.php @@ -29,7 +29,7 @@ function gutenberg_get_default_block_template_types( $default_template_types ) { } if ( isset( $default_template_types['home'] ) ) { $default_template_types['home'] = array( - 'title' => _x( 'Home', 'Template name', 'gutenberg' ), + 'title' => _x( 'Blog Home', 'Template name', 'gutenberg' ), 'description' => __( 'Displays the latest posts as either the site homepage or as the "Posts page" as defined under reading settings. If it exists, the Front Page template overrides this template when posts are shown on the homepage.', 'gutenberg' diff --git a/packages/block-editor/src/components/block-mobile-toolbar/block-actions-menu.native.js b/packages/block-editor/src/components/block-mobile-toolbar/block-actions-menu.native.js index e896d6054a8ff..48be5cb8a9c00 100644 --- a/packages/block-editor/src/components/block-mobile-toolbar/block-actions-menu.native.js +++ b/packages/block-editor/src/components/block-mobile-toolbar/block-actions-menu.native.js @@ -213,16 +213,12 @@ const BlockActionsMenu = ( { id: 'convertToRegularBlocksOption', label: innerBlockCount > 1 - ? __( 'Convert to regular blocks' ) - : __( 'Convert to regular block' ), + ? __( 'Detach patterns' ) + : __( 'Detach pattern' ), value: 'convertToRegularBlocksOption', onSelect: () => { - const successNotice = - innerBlockCount > 1 - ? /* translators: %s: name of the reusable block */ - __( '%s converted to regular blocks' ) - : /* translators: %s: name of the reusable block */ - __( '%s converted to regular block' ); + /* translators: %s: name of the synced block */ + const successNotice = __( '%s detached' ); createSuccessNotice( sprintf( successNotice, diff --git a/packages/block-editor/src/components/block-removal-warning-modal/index.js b/packages/block-editor/src/components/block-removal-warning-modal/index.js index 2e16d2834d2ce..2ed65481f6895 100644 --- a/packages/block-editor/src/components/block-removal-warning-modal/index.js +++ b/packages/block-editor/src/components/block-removal-warning-modal/index.js @@ -8,7 +8,7 @@ import { Button, __experimentalHStack as HStack, } from '@wordpress/components'; -import { __, _n } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -75,11 +75,9 @@ export function BlockRemovalWarningModal() { ) }

- { _n( - 'Removing this block is not advised.', - 'Removing these blocks is not advised.', - blockNamesForPrompt.length - ) } + { blockNamesForPrompt.length > 1 + ? __( 'Removing these blocks is not advised.' ) + : __( 'Removing this block is not advised.' ) }

diff --git a/packages/block-editor/src/components/list-view/style.scss b/packages/block-editor/src/components/list-view/style.scss index 0924e98b3f5d4..ab041af51aa1e 100644 --- a/packages/block-editor/src/components/list-view/style.scss +++ b/packages/block-editor/src/components/list-view/style.scss @@ -408,8 +408,7 @@ $block-navigation-max-indent: 8; .block-editor-list-view-drop-indicator__line { background: var(--wp-admin-theme-color); - height: 6px; - border: 1px solid $white; + height: 4px; border-radius: 4px; } } diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 05d00f65b1fd3..fc314636d1195 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1945,7 +1945,6 @@ const buildBlockTypeItem = * * @param {Object} state Editor state. * @param {?string} rootClientId Optional root client ID of block list. - * @param {?string} syncStatus Optional sync status to filter pattern blocks by. * * @return {WPEditorInserterItem[]} Items that appear in inserter. * @@ -1962,11 +1961,7 @@ const buildBlockTypeItem = * @property {number} frecency Heuristic that combines frequency and recency. */ export const getInserterItems = createSelector( - ( state, rootClientId = null, syncStatus ) => { - const buildBlockTypeInserterItem = buildBlockTypeItem( state, { - buildScope: 'inserter', - } ); - + ( state, rootClientId = null ) => { /* * Matches block comment delimiters amid serialized content. * @@ -2031,13 +2026,7 @@ export const getInserterItems = createSelector( }; }; - const blockTypeInserterItems = getBlockTypes() - .filter( ( blockType ) => - canIncludeBlockTypeInInserter( state, blockType, rootClientId ) - ) - .map( buildBlockTypeInserterItem ); - - const reusableBlockInserterItems = canInsertBlockTypeUnmemoized( + const syncedPatternInserterItems = canInsertBlockTypeUnmemoized( state, 'core/block', rootClientId @@ -2045,13 +2034,25 @@ export const getInserterItems = createSelector( ? getReusableBlocks( state ) .filter( ( reusableBlock ) => - syncStatus === reusableBlock.meta?.sync_status || - ( ! syncStatus && - reusableBlock.meta?.sync_status === '' ) + // Filter to either fully synced patterns (sync_status === 'fully'), + // or old school reusable blocks (sync_status === ''). + reusableBlock.meta?.sync_status === 'fully' || + reusableBlock.meta?.sync_status === '' || + ! reusableBlock.meta?.sync_status ) .map( buildReusableBlockInserterItem ) : []; + const buildBlockTypeInserterItem = buildBlockTypeItem( state, { + buildScope: 'inserter', + } ); + + const blockTypeInserterItems = getBlockTypes() + .filter( ( blockType ) => + canIncludeBlockTypeInInserter( state, blockType, rootClientId ) + ) + .map( buildBlockTypeInserterItem ); + const items = blockTypeInserterItems.reduce( ( accumulator, item ) => { const { variations = [] } = item; // Exclude any block type item that is to be replaced by a default variation. @@ -2082,7 +2083,7 @@ export const getInserterItems = createSelector( { core: [], noncore: [] } ); const sortedBlockTypes = [ ...coreItems, ...nonCoreItems ]; - return [ ...sortedBlockTypes, ...reusableBlockInserterItems ]; + return [ ...sortedBlockTypes, ...syncedPatternInserterItems ]; }, ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ], @@ -2306,10 +2307,32 @@ const checkAllowListRecursive = ( blocks, allowedBlockTypes ) => { return true; }; +function getUnsyncedPatterns( state ) { + const reusableBlocks = + state?.settings?.__experimentalReusableBlocks ?? EMPTY_ARRAY; + + return reusableBlocks + .filter( + ( reusableBlock ) => reusableBlock.meta?.sync_status === 'unsynced' + ) + .map( ( reusableBlock ) => { + return { + name: `core/block/${ reusableBlock.id }`, + title: reusableBlock.title.raw, + categories: [ 'custom' ], + content: reusableBlock.content.raw, + }; + } ); +} + export const __experimentalGetParsedPattern = createSelector( ( state, patternName ) => { const patterns = state.settings.__experimentalBlockPatterns; - const pattern = patterns.find( ( { name } ) => name === patternName ); + const unsyncedPatterns = getUnsyncedPatterns( state ); + + const pattern = [ ...patterns, ...unsyncedPatterns ].find( + ( { name } ) => name === patternName + ); if ( ! pattern ) { return null; } @@ -2320,14 +2343,20 @@ export const __experimentalGetParsedPattern = createSelector( } ), }; }, - ( state ) => [ state.settings.__experimentalBlockPatterns ] + ( state ) => [ + state.settings.__experimentalBlockPatterns, + state.settings.__experimentalReusableBlocks, + ] ); const getAllAllowedPatterns = createSelector( ( state ) => { const patterns = state.settings.__experimentalBlockPatterns; + const unsyncedPatterns = getUnsyncedPatterns( state ); + const { allowedBlockTypes } = getSettings( state ); - const parsedPatterns = patterns + + const parsedPatterns = [ ...patterns, ...unsyncedPatterns ] .filter( ( { inserter = true } ) => !! inserter ) .map( ( { name } ) => __experimentalGetParsedPattern( state, name ) @@ -2339,6 +2368,7 @@ const getAllAllowedPatterns = createSelector( }, ( state ) => [ state.settings.__experimentalBlockPatterns, + state.settings.__experimentalReusableBlocks, state.settings.allowedBlockTypes, ] ); @@ -2365,6 +2395,7 @@ export const __experimentalGetAllowedPatterns = createSelector( }, ( state, rootClientId ) => [ state.settings.__experimentalBlockPatterns, + state.settings.__experimentalReusableBlocks, state.settings.allowedBlockTypes, state.settings.templateLock, state.blockListSettings[ rootClientId ], diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index cc1ec16aeedc2..0b1f3b01b75b9 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -119,8 +119,8 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { onClick={ () => convertBlockToStatic( clientId ) } label={ innerBlockCount > 1 - ? __( 'Convert to regular blocks' ) - : __( 'Convert to regular block' ) + ? __( 'Detach patterns' ) + : __( 'Detach pattern' ) } icon={ ungroup } showTooltip diff --git a/packages/block-library/src/block/edit.native.js b/packages/block-library/src/block/edit.native.js index e72aee3858eaf..3466baa6bad71 100644 --- a/packages/block-library/src/block/edit.native.js +++ b/packages/block-library/src/block/edit.native.js @@ -132,12 +132,8 @@ export default function ReusableBlockEdit( { } const onConvertToRegularBlocks = useCallback( () => { - const successNotice = - innerBlockCount > 1 - ? /* translators: %s: name of the reusable block */ - __( '%s converted to regular blocks' ) - : /* translators: %s: name of the reusable block */ - __( '%s converted to regular block' ); + /* translators: %s: name of the synced block */ + const successNotice = __( '%s detached' ); createSuccessNotice( sprintf( successNotice, title ) ); clearSelectedBlock(); @@ -182,17 +178,17 @@ export default function ReusableBlockEdit( { { innerBlockCount > 1 ? __( - 'Alternatively, you can detach and edit these blocks separately by tapping “Convert to regular blocks”.' + 'Alternatively, you can detach and edit these blocks separately by tapping “Detach patterns”.' ) : __( - 'Alternatively, you can detach and edit this block separately by tapping “Convert to regular block”.' + 'Alternatively, you can detach and edit this block separately by tapping “Detach pattern”.' ) } 1 - ? __( 'Convert to regular blocks' ) - : __( 'Convert to regular block' ) + ? __( 'Detach patterns' ) + : __( 'Detach pattern' ) } separatorType="topFullWidth" onPress={ onConvertToRegularBlocks } diff --git a/packages/block-library/src/footnotes/index.php b/packages/block-library/src/footnotes/index.php index b7be0542d7a0f..e4bd8dcdeaac2 100644 --- a/packages/block-library/src/footnotes/index.php +++ b/packages/block-library/src/footnotes/index.php @@ -59,15 +59,17 @@ function render_block_core_footnotes( $attributes, $content, $block ) { * Registers the `core/footnotes` block on the server. */ function register_block_core_footnotes() { - register_post_meta( - 'post', - 'footnotes', - array( - 'show_in_rest' => true, - 'single' => true, - 'type' => 'string', - ) - ); + foreach ( array( 'post', 'page' ) as $post_type ) { + register_post_meta( + $post_type, + 'footnotes', + array( + 'show_in_rest' => true, + 'single' => true, + 'type' => 'string', + ) + ); + } register_block_type_from_metadata( __DIR__ . '/footnotes', array( diff --git a/packages/block-library/src/footnotes/style.scss b/packages/block-library/src/footnotes/style.scss index b5540b70e6f0f..4debba0560f17 100644 --- a/packages/block-library/src/footnotes/style.scss +++ b/packages/block-library/src/footnotes/style.scss @@ -3,7 +3,7 @@ counter-reset: footnotes; } -.fn { +[data-fn].fn { vertical-align: super; font-size: smaller; counter-increment: footnotes; @@ -11,7 +11,7 @@ text-indent: -9999999px; } -.fn::after { +[data-fn].fn::after { content: "[" counter(footnotes) "]"; text-indent: 0; float: left; diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index 539e1c6d92a98..b91015313f403 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -35,10 +35,7 @@ import { } from '@wordpress/dom'; import { decodeEntities } from '@wordpress/html-entities'; import { link as linkIcon, addSubmenu } from '@wordpress/icons'; -import { - store as coreStore, - useResourcePermissions, -} from '@wordpress/core-data'; +import { store as coreStore } from '@wordpress/core-data'; import { useMergeRefs } from '@wordpress/compose'; /** @@ -184,9 +181,6 @@ export default function NavigationLinkEdit( { const itemLabelPlaceholder = __( 'Add label…' ); const ref = useRef(); - const pagesPermissions = useResourcePermissions( 'pages' ); - const postsPermissions = useResourcePermissions( 'posts' ); - const { innerBlocks, isAtMaxNesting, @@ -322,13 +316,6 @@ export default function NavigationLinkEdit( { setIsLinkOpen( false ); } - let userCanCreate = false; - if ( ! type || type === 'page' ) { - userCanCreate = pagesPermissions.canCreate; - } else if ( type === 'post' ) { - userCanCreate = postsPermissions.canCreate; - } - const { textColor, customTextColor, @@ -589,7 +576,6 @@ export default function NavigationLinkEdit( { link={ attributes } onClose={ () => setIsLinkOpen( false ) } anchor={ popoverAnchor } - hasCreateSuggestion={ userCanCreate } onRemove={ removeLink } onChange={ ( updatedValue ) => { updateAttributes( diff --git a/packages/block-library/src/navigation-link/link-ui.js b/packages/block-library/src/navigation-link/link-ui.js index 782d1fff4a01b..950cac9cfb87b 100644 --- a/packages/block-library/src/navigation-link/link-ui.js +++ b/packages/block-library/src/navigation-link/link-ui.js @@ -10,7 +10,10 @@ import { store as blockEditorStore, } from '@wordpress/block-editor'; import { createInterpolateElement, useMemo } from '@wordpress/element'; -import { store as coreStore } from '@wordpress/core-data'; +import { + store as coreStore, + useResourcePermissions, +} from '@wordpress/core-data'; import { decodeEntities } from '@wordpress/html-entities'; import { switchToBlockType } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; @@ -125,6 +128,8 @@ function LinkControlTransforms( { clientId } ) { export function LinkUI( props ) { const { saveEntityRecord } = useDispatch( coreStore ); + const pagesPermissions = useResourcePermissions( 'pages' ); + const postsPermissions = useResourcePermissions( 'posts' ); async function handleCreate( pageTitle ) { const postType = props.link.type || 'page'; @@ -155,6 +160,13 @@ export function LinkUI( props ) { const { label, url, opensInNewTab, type, kind } = props.link; + let userCanCreate = false; + if ( ! type || type === 'page' ) { + userCanCreate = pagesPermissions.canCreate; + } else if ( type === 'post' ) { + userCanCreate = postsPermissions.canCreate; + } + // Memoize link value to avoid overriding the LinkControl's internal state. // This is a temporary fix. See https://github.com/WordPress/gutenberg/issues/50976#issuecomment-1568226407. const link = useMemo( @@ -179,7 +191,7 @@ export function LinkUI( props ) { className={ props.className } value={ link } showInitialSuggestions={ true } - withCreateSuggestion={ props.hasCreateSuggestion } + withCreateSuggestion={ userCanCreate } createSuggestion={ handleCreate } createSuggestionButtonText={ ( searchTerm ) => { let format; diff --git a/packages/block-library/src/navigation/edit/index.js b/packages/block-library/src/navigation/edit/index.js index 2fe86825bb6b1..7ec990d5b7389 100644 --- a/packages/block-library/src/navigation/edit/index.js +++ b/packages/block-library/src/navigation/edit/index.js @@ -69,7 +69,6 @@ import ManageMenusButton from './manage-menus-button'; import MenuInspectorControls from './menu-inspector-controls'; import DeletedNavigationWarning from './deleted-navigation-warning'; import { unlock } from '../../lock-unlock'; - const { useBlockEditingMode } = unlock( blockEditorPrivateApis ); function Navigation( { @@ -224,7 +223,7 @@ function Navigation( { // that automatically saves the menu as an entity when changes are made to the inner blocks. const hasUnsavedBlocks = hasUncontrolledInnerBlocks && ! isEntityAvailable; - const { getNavigationFallbackId } = useSelect( coreStore ); + const { getNavigationFallbackId } = unlock( useSelect( coreStore ) ); const navigationFallbackId = ! ( ref || hasUnsavedBlocks ) ? getNavigationFallbackId() diff --git a/packages/block-library/src/navigation/edit/menu-inspector-controls.js b/packages/block-library/src/navigation/edit/menu-inspector-controls.js index 8743b51fc6720..9fd4bc3e33d41 100644 --- a/packages/block-library/src/navigation/edit/menu-inspector-controls.js +++ b/packages/block-library/src/navigation/edit/menu-inspector-controls.js @@ -60,7 +60,6 @@ function AdditionalBlockContent( { block, insertedBlock, setInsertedBlock } ) { onClose={ () => { setInsertedBlock( null ); } } - hasCreateSuggestion={ false } onChange={ ( updatedValue ) => { updateAttributes( updatedValue, diff --git a/packages/block-library/src/social-link/index.php b/packages/block-library/src/social-link/index.php index 1e5c4cf5de6fb..51ed9374c9bcd 100644 --- a/packages/block-library/src/social-link/index.php +++ b/packages/block-library/src/social-link/index.php @@ -47,8 +47,8 @@ function render_block_core_social_link( $attributes, $content, $block ) { $icon = block_core_social_link_get_icon( $service ); $wrapper_attributes = get_block_wrapper_attributes( array( - 'class' => esc_attr( 'wp-social-link wp-social-link-' . $service . block_core_social_link_get_color_classes( $block->context ) ), - 'style' => esc_attr( block_core_social_link_get_color_styles( $block->context ) ), + 'class' => 'wp-social-link wp-social-link-' . $service . block_core_social_link_get_color_classes( $block->context ), + 'style' => block_core_social_link_get_color_styles( $block->context ), ) ); diff --git a/packages/components/src/guide/icons.tsx b/packages/components/src/guide/icons.tsx index 1c47180ae0b11..36146611dc299 100644 --- a/packages/components/src/guide/icons.tsx +++ b/packages/components/src/guide/icons.tsx @@ -3,13 +3,8 @@ */ import { SVG, Circle } from '@wordpress/primitives'; -export const PageControlIcon = ( { isSelected }: { isSelected: boolean } ) => ( +export const PageControlIcon = () => ( - + ); diff --git a/packages/components/src/guide/index.tsx b/packages/components/src/guide/index.tsx index 38f8d07d8c0ef..e6a2d4c1252eb 100644 --- a/packages/components/src/guide/index.tsx +++ b/packages/components/src/guide/index.tsx @@ -111,6 +111,7 @@ function Guide( { 1 } onRequestClose={ onFinish } onKeyDown={ ( event ) => { if ( event.code === 'ArrowLeft' ) { @@ -144,6 +145,7 @@ function Guide( { { canGoBack && (