From c7bb2b7f720ec34140ebf94bde83902fdc92c9aa Mon Sep 17 00:00:00 2001
From: Aki Hamano <54422211+t-hamano@users.noreply.github.com>
Date: Tue, 11 Jun 2024 11:25:50 +0900
Subject: [PATCH 01/17] DataViews: Fix unnecessary horizontal scrollbar in list
layout (#62448)
Co-authored-by: t-hamano
Co-authored-by: stokesman
---
packages/dataviews/src/style.scss | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/dataviews/src/style.scss b/packages/dataviews/src/style.scss
index 0390a360f66d27..5844e0c9133369 100644
--- a/packages/dataviews/src/style.scss
+++ b/packages/dataviews/src/style.scss
@@ -436,6 +436,7 @@
.components-button {
opacity: 0;
position: fixed;
+ right: 0;
}
}
From e78cb552a5c53b3b124d41d9fdcc6eea44711df6 Mon Sep 17 00:00:00 2001
From: Ramon
Date: Tue, 11 Jun 2024 13:28:25 +1000
Subject: [PATCH 02/17] List view: show context menu for content-only blocks in
posts (#62354)
* Ensure the Edit template context menu is shown in the post editor/site editor pages by checking only for a templateId.
Previously it was only shown for pages and there was no check if the user can edit template.
Show a not-very-pretty dialogue box where a user cannot edit a template.
* Check for an entity before showing the canUser message.
* Rename variable
Move canUser fallback component beneath existing entity check block
* Use existing component but disable the edit button and update the copy
* Check for content blocks
* Use `getContentLockingParent`
Co-authored-by: ramonjd
Co-authored-by: talldan
Co-authored-by: kevin940726
Co-authored-by: andrewserong
Co-authored-by: ellatrix
---
.../content-only-settings-menu.js | 38 +++++++++++++------
1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js
index 4683dd38593a59..8527dfff4f7523 100644
--- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js
+++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js
@@ -19,7 +19,7 @@ import { store as editorStore } from '../../store';
import { unlock } from '../../lock-unlock';
function ContentOnlySettingsMenuItems( { clientId, onClose } ) {
- const { entity, onNavigateToEntityRecord } = useSelect(
+ const { entity, onNavigateToEntityRecord, canEditTemplates } = useSelect(
( select ) => {
const {
getBlockEditingMode,
@@ -46,11 +46,12 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) {
getBlockAttributes( patternParent ).ref
);
} else {
- const { getCurrentPostType, getCurrentTemplateId } =
- select( editorStore );
- const currentPostType = getCurrentPostType();
+ const { getCurrentTemplateId } = select( editorStore );
const templateId = getCurrentTemplateId();
- if ( currentPostType === 'page' && templateId ) {
+ const { getContentLockingParent } = unlock(
+ select( blockEditorStore )
+ );
+ if ( ! getContentLockingParent( clientId ) && templateId ) {
record = select( coreStore ).getEntityRecord(
'postType',
'wp_template',
@@ -58,7 +59,12 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) {
);
}
}
+ const _canEditTemplates = select( coreStore ).canUser(
+ 'create',
+ 'templates'
+ );
return {
+ canEditTemplates: _canEditTemplates,
entity: record,
onNavigateToEntityRecord:
getSettings().onNavigateToEntityRecord,
@@ -77,6 +83,19 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) {
}
const isPattern = entity.type === 'wp_block';
+ let helpText = isPattern
+ ? __(
+ 'Edit the pattern to move, delete, or make further changes to this block.'
+ )
+ : __(
+ 'Edit the template to move, delete, or make further changes to this block.'
+ );
+
+ if ( ! canEditTemplates ) {
+ helpText = __(
+ 'Only users with permissions to edit the template can move or delete this block'
+ );
+ }
return (
<>
@@ -88,6 +107,7 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) {
postType: entity.type,
} );
} }
+ disabled={ ! canEditTemplates }
>
{ isPattern ? __( 'Edit pattern' ) : __( 'Edit template' ) }
@@ -97,13 +117,7 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) {
as="p"
className="editor-content-only-settings-menu__description"
>
- { isPattern
- ? __(
- 'Edit the pattern to move, delete, or make further changes to this block.'
- )
- : __(
- 'Edit the template to move, delete, or make further changes to this block.'
- ) }
+ { helpText }
>
);
From b7368c01d087578fe104d00765da2c4f2c123057 Mon Sep 17 00:00:00 2001
From: George Mamadashvili
Date: Tue, 11 Jun 2024 07:28:56 +0400
Subject: [PATCH 03/17] Fix flaky Site Editor command center e2e test (#62454)
Co-authored-by: Mamaduka
---
test/e2e/specs/site-editor/command-center.spec.js | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/test/e2e/specs/site-editor/command-center.spec.js b/test/e2e/specs/site-editor/command-center.spec.js
index 6608f37f1701b3..fce951ca767bed 100644
--- a/test/e2e/specs/site-editor/command-center.spec.js
+++ b/test/e2e/specs/site-editor/command-center.spec.js
@@ -43,9 +43,11 @@ test.describe( 'Site editor command palette', () => {
.click();
await page.keyboard.type( 'index' );
await page.getByRole( 'option', { name: 'index' } ).click();
- await expect( page.getByRole( 'heading', { level: 1 } ) ).toHaveText(
- 'Index'
- );
+ await expect(
+ page
+ .getByRole( 'region', { name: 'Editor top bar' } )
+ .getByRole( 'heading', { level: 1 } )
+ ).toHaveText( 'Index' );
} );
test( 'Open the command palette and navigate to Customize CSS', async ( {
From d2d7bf683bab94563a591e4e6abc3afe143ffcf1 Mon Sep 17 00:00:00 2001
From: Carolina Nymark
Date: Tue, 11 Jun 2024 06:08:20 +0200
Subject: [PATCH 04/17] Page creation and duplication: Decode HTML entities in
success notices (#62313)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Decode the page title when creating a new page from the Site Editor > Pages
* Decode the page title when a page is duplicated from the Data Views
* Decode the page title when you duplicate an item in the Edit Site > Editor component
* Decode the page title when a page or post is duplicated from the block editor
* Add ´@wordpress/html-entities´ to the edit post package.
Co-authored-by: carolinan
Co-authored-by: Mamaduka
Co-authored-by: ellatrix
---
package-lock.json | 2 ++
packages/edit-post/CHANGELOG.md | 4 ++++
packages/edit-post/package.json | 1 +
packages/edit-post/src/components/layout/index.js | 3 ++-
packages/edit-site/src/components/add-new-page/index.js | 3 ++-
packages/edit-site/src/components/editor/index.js | 3 ++-
packages/editor/src/components/post-actions/actions.js | 2 +-
7 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7e20ec0fa393dd..4f2901c8fe8bd5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -54118,6 +54118,7 @@
"@wordpress/editor": "file:../editor",
"@wordpress/element": "file:../element",
"@wordpress/hooks": "file:../hooks",
+ "@wordpress/html-entities": "file:../html-entities",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
@@ -69267,6 +69268,7 @@
"@wordpress/editor": "file:../editor",
"@wordpress/element": "file:../element",
"@wordpress/hooks": "file:../hooks",
+ "@wordpress/html-entities": "file:../html-entities",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md
index 3934ab8cda8848..5065e4b903040e 100644
--- a/packages/edit-post/CHANGELOG.md
+++ b/packages/edit-post/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+### Bug Fixes
+
+- Add ´@wordpress/html-entities´ package to the list of dependencies in package.json. ([#62313](https://github.com/WordPress/gutenberg/pull/62313))
+
## 8.0.0 (2024-05-31)
### Breaking Changes
diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json
index b3327218dfc873..e293e459b6ac0e 100644
--- a/packages/edit-post/package.json
+++ b/packages/edit-post/package.json
@@ -44,6 +44,7 @@
"@wordpress/editor": "file:../editor",
"@wordpress/element": "file:../element",
"@wordpress/hooks": "file:../hooks",
+ "@wordpress/html-entities": "file:../html-entities",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js
index e20732cb646bca..cfaaf810b41918 100644
--- a/packages/edit-post/src/components/layout/index.js
+++ b/packages/edit-post/src/components/layout/index.js
@@ -34,6 +34,7 @@ import {
import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands';
import { privateApis as blockLibraryPrivateApis } from '@wordpress/block-library';
import { addQueryArgs } from '@wordpress/url';
+import { decodeEntities } from '@wordpress/html-entities';
import { store as coreStore } from '@wordpress/core-data';
import { SlotFillProvider } from '@wordpress/components';
@@ -288,7 +289,7 @@ function Layout( {
sprintf(
// translators: %s: Title of the created post e.g: "Post 1".
__( '"%s" successfully created.' ),
- title
+ decodeEntities( title )
),
{
type: 'snackbar',
diff --git a/packages/edit-site/src/components/add-new-page/index.js b/packages/edit-site/src/components/add-new-page/index.js
index 56544c83f491bb..a1b19298a12433 100644
--- a/packages/edit-site/src/components/add-new-page/index.js
+++ b/packages/edit-site/src/components/add-new-page/index.js
@@ -13,6 +13,7 @@ import { useDispatch } from '@wordpress/data';
import { useState } from '@wordpress/element';
import { store as coreStore } from '@wordpress/core-data';
import { store as noticesStore } from '@wordpress/notices';
+import { decodeEntities } from '@wordpress/html-entities';
export default function AddNewPageModal( { onSave, onClose } ) {
const [ isCreatingPage, setIsCreatingPage ] = useState( false );
@@ -47,7 +48,7 @@ export default function AddNewPageModal( { onSave, onClose } ) {
sprintf(
// translators: %s: Title of the created template e.g: "Category".
__( '"%s" successfully created.' ),
- newPage.title?.rendered || title
+ decodeEntities( newPage.title?.rendered || title )
),
{
type: 'snackbar',
diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js
index 50fb05d8d841f8..96bf2fad4d6b68 100644
--- a/packages/edit-site/src/components/editor/index.js
+++ b/packages/edit-site/src/components/editor/index.js
@@ -21,6 +21,7 @@ import { useCallback, useMemo } from '@wordpress/element';
import { store as noticesStore } from '@wordpress/notices';
import { privateApis as routerPrivateApis } from '@wordpress/router';
import { store as preferencesStore } from '@wordpress/preferences';
+import { decodeEntities } from '@wordpress/html-entities';
/**
* Internal dependencies
@@ -146,7 +147,7 @@ export default function EditSiteEditor( { isLoading } ) {
sprintf(
// translators: %s: Title of the created post e.g: "Post 1".
__( '"%s" successfully created.' ),
- _title
+ decodeEntities( _title )
),
{
type: 'snackbar',
diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js
index 69337e181f5e55..f376d0e8f969ec 100644
--- a/packages/editor/src/components/post-actions/actions.js
+++ b/packages/editor/src/components/post-actions/actions.js
@@ -783,7 +783,7 @@ const duplicatePostAction = {
sprintf(
// translators: %s: Title of the created template e.g: "Category".
__( '"%s" successfully created.' ),
- newItem.title?.rendered || title
+ decodeEntities( newItem.title?.rendered || title )
),
{
id: 'duplicate-post-action',
From faf5cbaf651315f4a17076b26a6f3b034bd304a2 Mon Sep 17 00:00:00 2001
From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com>
Date: Tue, 11 Jun 2024 16:11:23 +1000
Subject: [PATCH 05/17] Section Styles: Register block style variations on
`init` (#62461)
Co-authored-by: aaronrobertshaw
Co-authored-by: oandregal
Co-authored-by: annezazu
---
backport-changelog/6.6/6756.md | 3 +
lib/block-supports/block-style-variations.php | 126 ++++++++++++++----
.../block-style-variations-test.php | 5 +
3 files changed, 111 insertions(+), 23 deletions(-)
create mode 100644 backport-changelog/6.6/6756.md
diff --git a/backport-changelog/6.6/6756.md b/backport-changelog/6.6/6756.md
new file mode 100644
index 00000000000000..e60e128bf45cb4
--- /dev/null
+++ b/backport-changelog/6.6/6756.md
@@ -0,0 +1,3 @@
+https://github.com/WordPress/wordpress-develop/pull/6756
+
+* https://github.com/WordPress/gutenberg/pull/62461
diff --git a/lib/block-supports/block-style-variations.php b/lib/block-supports/block-style-variations.php
index e09bd4ce90bf0e..bdda388bdcf61a 100644
--- a/lib/block-supports/block-style-variations.php
+++ b/lib/block-supports/block-style-variations.php
@@ -209,9 +209,6 @@ function gutenberg_render_block_style_variation_class_name( $block_content, $blo
/**
* Collects block style variation data for merging with theme.json data.
- * As each block style variation is processed it is registered if it hasn't
- * been already. This registration is required for later sanitization of
- * theme.json data.
*
* @since 6.6.0
*
@@ -219,14 +216,13 @@ function gutenberg_render_block_style_variation_class_name( $block_content, $blo
*
* @return array Block variations data to be merged under `styles.blocks`.
*/
-function gutenberg_resolve_and_register_block_style_variations( $variations ) {
+function gutenberg_resolve_block_style_variations( $variations ) {
$variations_data = array();
if ( empty( $variations ) ) {
return $variations_data;
}
- $registry = WP_Block_Styles_Registry::get_instance();
$have_named_variations = ! wp_is_numeric_array( $variations );
foreach ( $variations as $key => $variation ) {
@@ -248,23 +244,9 @@ function gutenberg_resolve_and_register_block_style_variations( $variations ) {
* Block style variations read in via standalone theme.json partials
* need to have their name set to the kebab case version of their title.
*/
- $variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] );
- $variation_label = $variation['title'] ?? $variation_name;
+ $variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] );
foreach ( $supported_blocks as $block_type ) {
- $registered_styles = $registry->get_registered_styles_for_block( $block_type );
-
- // Register block style variation if it hasn't already been registered.
- if ( ! array_key_exists( $variation_name, $registered_styles ) ) {
- gutenberg_register_block_style(
- $block_type,
- array(
- 'name' => $variation_name,
- 'label' => $variation_label,
- )
- );
- }
-
// Add block style variation data under current block type.
$path = array( $block_type, 'variations', $variation_name );
_wp_array_set( $variations_data, $path, $variation_data );
@@ -320,7 +302,7 @@ function gutenberg_merge_block_style_variations_data( $variations_data, $theme_j
function gutenberg_resolve_block_style_variations_from_theme_style_variation( $theme_json ) {
$theme_json_data = $theme_json->get_data();
$shared_variations = $theme_json_data['styles']['blocks']['variations'] ?? array();
- $variations_data = gutenberg_resolve_and_register_block_style_variations( $shared_variations );
+ $variations_data = gutenberg_resolve_block_style_variations( $shared_variations );
return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json, 'user' );
}
@@ -337,7 +319,7 @@ function gutenberg_resolve_block_style_variations_from_theme_style_variation( $t
*/
function gutenberg_resolve_block_style_variations_from_theme_json_partials( $theme_json ) {
$block_style_variations = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations( 'block' );
- $variations_data = gutenberg_resolve_and_register_block_style_variations( $block_style_variations );
+ $variations_data = gutenberg_resolve_block_style_variations( $block_style_variations );
return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json );
}
@@ -355,7 +337,7 @@ function gutenberg_resolve_block_style_variations_from_theme_json_partials( $the
function gutenberg_resolve_block_style_variations_from_primary_theme_json( $theme_json ) {
$theme_json_data = $theme_json->get_data();
$block_style_variations = $theme_json_data['styles']['blocks']['variations'] ?? array();
- $variations_data = gutenberg_resolve_and_register_block_style_variations( $block_style_variations );
+ $variations_data = gutenberg_resolve_block_style_variations( $block_style_variations );
return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json );
}
@@ -411,3 +393,101 @@ function gutenberg_enqueue_block_style_variation_styles() {
add_filter( 'wp_theme_json_data_theme', 'gutenberg_resolve_block_style_variations_from_styles_registry', 10, 1 );
add_filter( 'wp_theme_json_data_user', 'gutenberg_resolve_block_style_variations_from_theme_style_variation', 10, 1 );
+
+
+/**
+ * Registers any block style variations contained within the provided
+ * theme.json data.
+ *
+ * @access private
+ *
+ * @param array $variations Shared block style variations.
+ */
+function gutenberg_register_block_style_variations_from_theme_json_data( $variations ) {
+ if ( empty( $variations ) ) {
+ return;
+ }
+
+ $registry = WP_Block_Styles_Registry::get_instance();
+ $have_named_variations = ! wp_is_numeric_array( $variations );
+
+ foreach ( $variations as $key => $variation ) {
+ $supported_blocks = $variation['blockTypes'] ?? array();
+
+ /*
+ * Standalone theme.json partial files for block style variations
+ * will have their styles under a top-level property by the same name.
+ * Variations defined within an existing theme.json or theme style
+ * variation will themselves already be the required styles data.
+ */
+ $variation_data = $variation['styles'] ?? $variation;
+
+ if ( empty( $variation_data ) ) {
+ continue;
+ }
+
+ /*
+ * Block style variations read in via standalone theme.json partials
+ * need to have their name set to the kebab case version of their title.
+ */
+ $variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] );
+ $variation_label = $variation['title'] ?? $variation_name;
+
+ foreach ( $supported_blocks as $block_type ) {
+ $registered_styles = $registry->get_registered_styles_for_block( $block_type );
+
+ // Register block style variation if it hasn't already been registered.
+ if ( ! array_key_exists( $variation_name, $registered_styles ) ) {
+ register_block_style(
+ $block_type,
+ array(
+ 'name' => $variation_name,
+ 'label' => $variation_label,
+ )
+ );
+ }
+ }
+ }
+}
+
+/**
+ * Register shared block style variations defined by the theme.
+ *
+ * These can come in three forms:
+ * - the theme's theme.json
+ * - the theme's partials (standalone files in `/styles` that only define block style variations)
+ * - the user's theme.json (for example, theme style variations the user selected)
+ *
+ * @access private
+ */
+function gutenberg_register_block_style_variations_from_theme() {
+ // Partials from `/styles`.
+ $variations_partials = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations( 'block' );
+ gutenberg_register_block_style_variations_from_theme_json_data( $variations_partials );
+
+ /*
+ * Pull the data from the specific origin instead of the merged data.
+ * This is because, for 6.6, we only support registering block style variations
+ * for the 'theme' and 'custom' origins but not for 'default' (core theme.json)
+ * or 'custom' (theme.json in a block).
+ *
+ * When/If we add support for every origin, we should switch to using the public API
+ * instead, e.g.: wp_get_global_styles( array( 'blocks', 'variations' ) ).
+ */
+
+ // theme.json of the theme.
+ $theme_json_theme = WP_Theme_JSON_Resolver_Gutenberg::get_theme_data();
+ $variations_theme = $theme_json_theme->get_data()['styles']['blocks']['variations'] ?? array();
+ gutenberg_register_block_style_variations_from_theme_json_data( $variations_theme );
+
+ // User data linked for this theme.
+ $theme_json_user = WP_Theme_JSON_Resolver_Gutenberg::get_user_data();
+ $variations_user = $theme_json_user->get_data()['styles']['blocks']['variations'] ?? array();
+ gutenberg_register_block_style_variations_from_theme_json_data( $variations_user );
+}
+
+// Remove core init action registering variations.
+if ( function_exists( 'wp_register_block_style_variations_from_theme' ) ) {
+ remove_action( 'init', 'wp_register_block_style_variations_from_theme' );
+}
+add_action( 'init', 'gutenberg_register_block_style_variations_from_theme' );
diff --git a/phpunit/block-supports/block-style-variations-test.php b/phpunit/block-supports/block-style-variations-test.php
index b84267446330cc..870a76a4fb4a49 100644
--- a/phpunit/block-supports/block-style-variations-test.php
+++ b/phpunit/block-supports/block-style-variations-test.php
@@ -63,6 +63,11 @@ public function filter_set_theme_root() {
public function test_add_registered_block_styles_to_theme_data() {
switch_theme( 'block-theme' );
+ // Trigger block style registration that occurs on `init` action.
+ // do_action( 'init' ) could be used here however this direct call
+ // means only the updates being tested are performed.
+ gutenberg_register_block_style_variations_from_theme();
+
$variation_styles_data = array(
'color' => array(
'background' => 'darkslateblue',
From fd587da210b234364590db764219b2149c1d0789 Mon Sep 17 00:00:00 2001
From: Narendra Sishodiya <32844880+narenin@users.noreply.github.com>
Date: Tue, 11 Jun 2024 11:58:42 +0530
Subject: [PATCH 06/17] Fixed : Disambiguate "Cover" translatable string in the
context of background-panel.js (#62440)
* Fixed : Disambiguate 'Cover' translatable string in the context of background-panel.js
* Added context for Contain and Tile
* Implemented the suggestions
Co-authored-by: narenin
Co-authored-by: ramonjd
Co-authored-by: audrasjb
---
.../global-styles/background-panel.js | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/packages/block-editor/src/components/global-styles/background-panel.js b/packages/block-editor/src/components/global-styles/background-panel.js
index 7f3c3ed27e667f..307c742befafda 100644
--- a/packages/block-editor/src/components/global-styles/background-panel.js
+++ b/packages/block-editor/src/components/global-styles/background-panel.js
@@ -23,7 +23,7 @@ import {
__experimentalHStack as HStack,
__experimentalTruncate as Truncate,
} from '@wordpress/components';
-import { __, sprintf } from '@wordpress/i18n';
+import { __, _x, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { getFilename } from '@wordpress/url';
import { useCallback, Platform, useRef } from '@wordpress/element';
@@ -544,17 +544,26 @@ function BackgroundSizeToolsPanelItem( {
From 48d936421e09122cb1aa1e94f38f726665ffdbf8 Mon Sep 17 00:00:00 2001
From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com>
Date: Tue, 11 Jun 2024 16:58:55 +1000
Subject: [PATCH 07/17] Block Styles: Remove core block style variations
filters and action (#62090)
Co-authored-by: aaronrobertshaw
Co-authored-by: oandregal
---
lib/block-supports/block-style-variations.php | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/lib/block-supports/block-style-variations.php b/lib/block-supports/block-style-variations.php
index bdda388bdcf61a..f2bc6af92e9dec 100644
--- a/lib/block-supports/block-style-variations.php
+++ b/lib/block-supports/block-style-variations.php
@@ -383,6 +383,31 @@ function gutenberg_enqueue_block_style_variation_styles() {
// Register the block support.
WP_Block_Supports::get_instance()->register( 'block-style-variation', array() );
+// Remove core filters and action.
+if ( function_exists( 'wp_render_block_style_variation_support_styles' ) ) {
+ remove_filter( 'render_block_data', 'wp_render_block_style_variation_support_styles' );
+}
+if ( function_exists( 'wp_render_block_style_variation_class_name' ) ) {
+ remove_filter( 'render_block', 'wp_render_block_style_variation_class_name' );
+}
+if ( function_exists( 'wp_enqueue_block_style_variation_styles' ) ) {
+ remove_action( 'wp_enqueue_scripts', 'wp_enqueue_block_style_variation_styles' );
+}
+
+if ( function_exists( 'wp_resolve_block_style_variations_from_primary_theme_json' ) ) {
+ remove_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_primary_theme_json' );
+}
+if ( function_exists( 'wp_resolve_block_style_variations_from_theme_json_partials' ) ) {
+ remove_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_theme_json_partials' );
+}
+if ( function_exists( 'wp_resolve_block_style_variations_from_styles_registry' ) ) {
+ remove_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_styles_registry' );
+}
+if ( function_exists( 'wp_resolve_block_style_variations_from_theme_style_variation' ) ) {
+ remove_filter( 'wp_theme_json_data_user', 'wp_resolve_block_style_variations_from_theme_style_variation' );
+}
+
+// Add Gutenberg filters and action.
add_filter( 'render_block_data', 'gutenberg_render_block_style_variation_support_styles', 10, 2 );
add_filter( 'render_block', 'gutenberg_render_block_style_variation_class_name', 10, 2 );
add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_block_style_variation_styles', 1 );
From 3a20fb048ffa8500d3359c9e0a8d99fd2a514a72 Mon Sep 17 00:00:00 2001
From: Riad Benguella
Date: Tue, 11 Jun 2024 09:05:07 +0200
Subject: [PATCH 08/17] Site Editor: Remove editor specific classes from shell
wrapper. (#62389)
Co-authored-by: youknowriad
Co-authored-by: jasmussen
Co-authored-by: ntsekouras
---
.../block-library/src/navigation/editor.scss | 12 ----
.../edit-site/src/components/layout/index.js | 55 ++++++-------------
.../editor/src/components/post-title/index.js | 7 +--
.../components/post-title/post-title-raw.js | 7 +--
4 files changed, 22 insertions(+), 59 deletions(-)
diff --git a/packages/block-library/src/navigation/editor.scss b/packages/block-library/src/navigation/editor.scss
index 9f22262c53bd95..c62cbe9614c916 100644
--- a/packages/block-library/src/navigation/editor.scss
+++ b/packages/block-library/src/navigation/editor.scss
@@ -457,12 +457,6 @@ $color-control-label-height: 20px;
}
}
-.has-fixed-toolbar .wp-block-navigation__responsive-container.is-menu-open {
- @include break-medium() {
- top: $admin-bar-height + $header-height + $block-toolbar-height + $border-width;
- }
-}
-
.is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,
.is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open {
top: $admin-bar-height + $header-height + $block-toolbar-height + $border-width;
@@ -479,12 +473,6 @@ $color-control-label-height: 20px;
}
}
- .has-fixed-toolbar .wp-block-navigation__responsive-container.is-menu-open {
- @include break-medium() {
- top: $header-height + $block-toolbar-height + $border-width;
- }
- }
-
.is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,
.is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open {
top: $header-height + $block-toolbar-height + $border-width;
diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js
index 58de32d4b46878..45a2b79adca65c 100644
--- a/packages/edit-site/src/components/layout/index.js
+++ b/packages/edit-site/src/components/layout/index.js
@@ -25,7 +25,6 @@ import {
CommandMenu,
privateApis as commandsPrivateApis,
} from '@wordpress/commands';
-import { store as preferencesStore } from '@wordpress/preferences';
import {
privateApis as blockEditorPrivateApis,
store as blockEditorStore,
@@ -74,38 +73,24 @@ export default function Layout() {
const isMobileViewport = useViewportMatch( 'medium', '<' );
const toggleRef = useRef();
- const {
- isDistractionFree,
- hasFixedToolbar,
- hasBlockSelected,
- canvasMode,
- previousShortcut,
- nextShortcut,
- } = useSelect( ( select ) => {
- const { getAllShortcutKeyCombinations } = select(
- keyboardShortcutsStore
- );
- const { getCanvasMode } = unlock( select( editSiteStore ) );
- return {
- canvasMode: getCanvasMode(),
- previousShortcut: getAllShortcutKeyCombinations(
- 'core/editor/previous-region'
- ),
- nextShortcut: getAllShortcutKeyCombinations(
- 'core/editor/next-region'
- ),
- hasFixedToolbar: select( preferencesStore ).get(
- 'core',
- 'fixedToolbar'
- ),
- isDistractionFree: select( preferencesStore ).get(
- 'core',
- 'distractionFree'
- ),
- hasBlockSelected:
- select( blockEditorStore ).getBlockSelectionStart(),
- };
- }, [] );
+ const { hasBlockSelected, canvasMode, previousShortcut, nextShortcut } =
+ useSelect( ( select ) => {
+ const { getAllShortcutKeyCombinations } = select(
+ keyboardShortcutsStore
+ );
+ const { getCanvasMode } = unlock( select( editSiteStore ) );
+ return {
+ canvasMode: getCanvasMode(),
+ previousShortcut: getAllShortcutKeyCombinations(
+ 'core/editor/previous-region'
+ ),
+ nextShortcut: getAllShortcutKeyCombinations(
+ 'core/editor/next-region'
+ ),
+ hasBlockSelected:
+ select( blockEditorStore ).getBlockSelectionStart(),
+ };
+ }, [] );
const navigateRegionsProps = useNavigateRegions( {
previous: previousShortcut,
next: nextShortcut,
@@ -163,11 +148,7 @@ export default function Layout() {
'edit-site-layout',
navigateRegionsProps.className,
{
- 'is-distraction-free':
- isDistractionFree && canvasMode === 'edit',
'is-full-canvas': canvasMode === 'edit',
- 'has-fixed-toolbar': hasFixedToolbar,
- 'is-block-toolbar-visible': hasBlockSelected,
}
) }
>
diff --git a/packages/editor/src/components/post-title/index.js b/packages/editor/src/components/post-title/index.js
index 57ab39f0061615..08bd07f4b72dbe 100644
--- a/packages/editor/src/components/post-title/index.js
+++ b/packages/editor/src/components/post-title/index.js
@@ -30,14 +30,12 @@ import usePostTitle from './use-post-title';
import PostTypeSupportCheck from '../post-type-support-check';
function PostTitle( _, forwardedRef ) {
- const { placeholder, hasFixedToolbar } = useSelect( ( select ) => {
+ const { placeholder } = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
- const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } =
- getSettings();
+ const { titlePlaceholder } = getSettings();
return {
placeholder: titlePlaceholder,
- hasFixedToolbar: _hasFixedToolbar,
};
}, [] );
@@ -186,7 +184,6 @@ function PostTitle( _, forwardedRef ) {
// This same block is used in both the visual and the code editor.
const className = clsx( DEFAULT_CLASSNAMES, {
'is-selected': isSelected,
- 'has-fixed-toolbar': hasFixedToolbar,
} );
return (
diff --git a/packages/editor/src/components/post-title/post-title-raw.js b/packages/editor/src/components/post-title/post-title-raw.js
index a4c9713a094925..66c944b45871ab 100644
--- a/packages/editor/src/components/post-title/post-title-raw.js
+++ b/packages/editor/src/components/post-title/post-title-raw.js
@@ -29,14 +29,12 @@ import usePostTitle from './use-post-title';
* @return {Component} The rendered component.
*/
function PostTitleRaw( _, forwardedRef ) {
- const { placeholder, hasFixedToolbar } = useSelect( ( select ) => {
+ const { placeholder } = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
- const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } =
- getSettings();
+ const { titlePlaceholder } = getSettings();
return {
placeholder: titlePlaceholder,
- hasFixedToolbar: _hasFixedToolbar,
};
}, [] );
@@ -61,7 +59,6 @@ function PostTitleRaw( _, forwardedRef ) {
// This same block is used in both the visual and the code editor.
const className = clsx( DEFAULT_CLASSNAMES, {
'is-selected': isSelected,
- 'has-fixed-toolbar': hasFixedToolbar,
'is-raw-text': true,
} );
From edd5fa4c0d8107d151f8e890eaaeb8293983bd6d Mon Sep 17 00:00:00 2001
From: Ramon
Date: Tue, 11 Jun 2024 18:20:45 +1000
Subject: [PATCH 09/17] Block style variation: rename hook (#62464)
Co-authored-by: ramonjd
Co-authored-by: aaronrobertshaw
---
packages/block-editor/src/hooks/block-style-variation.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/block-editor/src/hooks/block-style-variation.js b/packages/block-editor/src/hooks/block-style-variation.js
index ee02b97d216704..311997d46f0ada 100644
--- a/packages/block-editor/src/hooks/block-style-variation.js
+++ b/packages/block-editor/src/hooks/block-style-variation.js
@@ -43,7 +43,7 @@ function getVariationNameFromClass( className, registeredStyles = [] ) {
return null;
}
-function useBlockSyleVariation( name, variation, clientId ) {
+function useBlockStyleVariation( name, variation, clientId ) {
// Prefer global styles data in GlobalStylesContext, which are available
// if in the site editor. Otherwise fall back to whatever is in the
// editor settings and available in the post editor.
@@ -96,7 +96,7 @@ function useBlockProps( { name, className, clientId } ) {
const variation = getVariationNameFromClass( className, registeredStyles );
const variationClass = `is-style-${ variation }-${ clientId }`;
- const { settings, styles } = useBlockSyleVariation(
+ const { settings, styles } = useBlockStyleVariation(
name,
variation,
clientId
From 2d34e2aaa56e52c379b01bed2df2344ba01c9bb4 Mon Sep 17 00:00:00 2001
From: Riad Benguella
Date: Tue, 11 Jun 2024 10:34:45 +0200
Subject: [PATCH 10/17] Bootstrap the dashboard layout (#62409)
Co-authored-by: youknowriad
Co-authored-by: ntsekouras
---
lib/experimental/posts/load.php | 2 +-
.../edit-site/src/components/app/index.js | 18 ++++++-
.../edit-site/src/components/layout/index.js | 49 +++++--------------
.../src/components/posts-app/index.js | 39 +++++++++++++++
.../hooks/commands/use-set-command-context.js | 37 ++++++++++++++
packages/edit-site/src/posts.js | 11 ++++-
packages/edit-site/src/posts.scss | 39 ++++++++++++---
7 files changed, 148 insertions(+), 47 deletions(-)
create mode 100644 packages/edit-site/src/components/posts-app/index.js
create mode 100644 packages/edit-site/src/hooks/commands/use-set-command-context.js
diff --git a/lib/experimental/posts/load.php b/lib/experimental/posts/load.php
index 56a600ab97c05d..3fff8a151dfefc 100644
--- a/lib/experimental/posts/load.php
+++ b/lib/experimental/posts/load.php
@@ -14,7 +14,7 @@ function gutenberg_posts_dashboard() {
wp_register_style(
'wp-gutenberg-posts-dashboard',
gutenberg_url( 'build/edit-site/posts.css', __FILE__ ),
- array()
+ array( 'wp-components', 'wp-commands' )
);
wp_enqueue_style( 'wp-gutenberg-posts-dashboard' );
wp_add_inline_script( 'wp-edit-site', 'window.wp.editSite.initializePostsDashboard( "gutenberg-posts-dashboard" );', 'after' );
diff --git a/packages/edit-site/src/components/app/index.js b/packages/edit-site/src/components/app/index.js
index 764b188acf6a53..452c36014f5db9 100644
--- a/packages/edit-site/src/components/app/index.js
+++ b/packages/edit-site/src/components/app/index.js
@@ -17,10 +17,26 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
*/
import Layout from '../layout';
import { unlock } from '../../lock-unlock';
+import { useCommonCommands } from '../../hooks/commands/use-common-commands';
+import { useEditModeCommands } from '../../hooks/commands/use-edit-mode-commands';
+import useInitEditedEntityFromURL from '../sync-state-with-url/use-init-edited-entity-from-url';
+import useLayoutAreas from '../layout/router';
+import useSetCommandContext from '../../hooks/commands/use-set-command-context';
const { RouterProvider } = unlock( routerPrivateApis );
const { GlobalStylesProvider } = unlock( editorPrivateApis );
+function AppLayout() {
+ // This ensures the edited entity id and type are initialized properly.
+ useInitEditedEntityFromURL();
+ useEditModeCommands();
+ useCommonCommands();
+ useSetCommandContext();
+ const route = useLayoutAreas();
+
+ return ;
+}
+
export default function App() {
const { createErrorNotice } = useDispatch( noticesStore );
@@ -41,7 +57,7 @@ export default function App() {
-
+
diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js
index 45a2b79adca65c..72d48122057ac9 100644
--- a/packages/edit-site/src/components/layout/index.js
+++ b/packages/edit-site/src/components/layout/index.js
@@ -21,60 +21,44 @@ import {
import { __ } from '@wordpress/i18n';
import { useState, useRef, useEffect } from '@wordpress/element';
import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts';
-import {
- CommandMenu,
- privateApis as commandsPrivateApis,
-} from '@wordpress/commands';
-import {
- privateApis as blockEditorPrivateApis,
- store as blockEditorStore,
-} from '@wordpress/block-editor';
-import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands';
+import { CommandMenu } from '@wordpress/commands';
+import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
import {
EditorSnackbars,
privateApis as editorPrivateApis,
} from '@wordpress/editor';
+import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands';
/**
* Internal dependencies
*/
import ErrorBoundary from '../error-boundary';
import { store as editSiteStore } from '../../store';
-import useInitEditedEntityFromURL from '../sync-state-with-url/use-init-edited-entity-from-url';
import SiteHub from '../site-hub';
import ResizableFrame from '../resizable-frame';
-import useSyncCanvasModeWithURL from '../sync-state-with-url/use-sync-canvas-mode-with-url';
import { unlock } from '../../lock-unlock';
import SavePanel from '../save-panel';
import KeyboardShortcutsRegister from '../keyboard-shortcuts/register';
import KeyboardShortcutsGlobal from '../keyboard-shortcuts/global';
-import { useCommonCommands } from '../../hooks/commands/use-common-commands';
-import { useEditModeCommands } from '../../hooks/commands/use-edit-mode-commands';
import { useIsSiteEditorLoading } from './hooks';
-import useLayoutAreas from './router';
import useMovingAnimation from './animation';
import SidebarContent from '../sidebar';
import SaveHub from '../save-hub';
+import useSyncCanvasModeWithURL from '../sync-state-with-url/use-sync-canvas-mode-with-url';
const { useCommands } = unlock( coreCommandsPrivateApis );
-const { useCommandContext } = unlock( commandsPrivateApis );
const { useGlobalStyle } = unlock( blockEditorPrivateApis );
const { NavigableRegion } = unlock( editorPrivateApis );
const ANIMATION_DURATION = 0.3;
-export default function Layout() {
- // This ensures the edited entity id and type are initialized properly.
- useInitEditedEntityFromURL();
+export default function Layout( { route } ) {
useSyncCanvasModeWithURL();
useCommands();
- useEditModeCommands();
- useCommonCommands();
-
const isMobileViewport = useViewportMatch( 'medium', '<' );
const toggleRef = useRef();
- const { hasBlockSelected, canvasMode, previousShortcut, nextShortcut } =
- useSelect( ( select ) => {
+ const { canvasMode, previousShortcut, nextShortcut } = useSelect(
+ ( select ) => {
const { getAllShortcutKeyCombinations } = select(
keyboardShortcutsStore
);
@@ -87,10 +71,10 @@ export default function Layout() {
nextShortcut: getAllShortcutKeyCombinations(
'core/editor/next-region'
),
- hasBlockSelected:
- select( blockEditorStore ).getBlockSelectionStart(),
};
- }, [] );
+ },
+ []
+ );
const navigateRegionsProps = useNavigateRegions( {
previous: previousShortcut,
next: nextShortcut,
@@ -101,22 +85,11 @@ export default function Layout() {
const isEditorLoading = useIsSiteEditorLoading();
const [ isResizableFrameOversized, setIsResizableFrameOversized ] =
useState( false );
- const { key: routeKey, areas, widths } = useLayoutAreas();
+ const { key: routeKey, areas, widths } = route;
const animationRef = useMovingAnimation( {
triggerAnimationOnChange: canvasMode + '__' + routeKey,
} );
- // Sets the right context for the command palette
- let commandContext = 'site-editor';
-
- if ( canvasMode === 'edit' ) {
- commandContext = 'entity-edit';
- }
- if ( hasBlockSelected ) {
- commandContext = 'block-selection-edit';
- }
- useCommandContext( commandContext );
-
const [ backgroundColor ] = useGlobalStyle( 'color.background' );
const [ gradientValue ] = useGlobalStyle( 'color.gradient' );
const previousCanvaMode = usePrevious( canvasMode );
diff --git a/packages/edit-site/src/components/posts-app/index.js b/packages/edit-site/src/components/posts-app/index.js
new file mode 100644
index 00000000000000..3d803f0241d78b
--- /dev/null
+++ b/packages/edit-site/src/components/posts-app/index.js
@@ -0,0 +1,39 @@
+/**
+ * WordPress dependencies
+ */
+import {
+ UnsavedChangesWarning,
+ privateApis as editorPrivateApis,
+} from '@wordpress/editor';
+import { privateApis as routerPrivateApis } from '@wordpress/router';
+
+/**
+ * Internal dependencies
+ */
+import Layout from '../layout';
+import Page from '../page';
+import { unlock } from '../../lock-unlock';
+
+const { RouterProvider } = unlock( routerPrivateApis );
+const { GlobalStylesProvider } = unlock( editorPrivateApis );
+
+const defaultRoute = {
+ key: 'index',
+ areas: {
+ sidebar: 'Empty Sidebar',
+ content: Welcome to Posts,
+ preview: undefined,
+ mobile: Welcome to Posts,
+ },
+};
+
+export default function PostsApp() {
+ return (
+
+
+
+
+
+
+ );
+}
diff --git a/packages/edit-site/src/hooks/commands/use-set-command-context.js b/packages/edit-site/src/hooks/commands/use-set-command-context.js
new file mode 100644
index 00000000000000..2824a6cc99f1c3
--- /dev/null
+++ b/packages/edit-site/src/hooks/commands/use-set-command-context.js
@@ -0,0 +1,37 @@
+/**
+ * WordPress dependencies
+ */
+import { useSelect } from '@wordpress/data';
+import { privateApis as commandsPrivateApis } from '@wordpress/commands';
+import { store as blockEditorStore } from '@wordpress/block-editor';
+
+/**
+ * Internal dependencies
+ */
+import { store as editSiteStore } from '../../store';
+import { unlock } from '../../lock-unlock';
+
+const { useCommandContext } = unlock( commandsPrivateApis );
+
+/**
+ * React hook used to set the correct command context based on the current state.
+ */
+export default function useSetCommandContext() {
+ const { hasBlockSelected, canvasMode } = useSelect( ( select ) => {
+ const { getCanvasMode } = unlock( select( editSiteStore ) );
+ const { getBlockSelectionStart } = select( blockEditorStore );
+ return {
+ canvasMode: getCanvasMode(),
+ hasBlockSelected: getBlockSelectionStart(),
+ };
+ }, [] );
+ // Sets the right context for the command palette
+ let commandContext = 'site-editor';
+ if ( canvasMode === 'edit' ) {
+ commandContext = 'entity-edit';
+ }
+ if ( hasBlockSelected ) {
+ commandContext = 'block-selection-edit';
+ }
+ useCommandContext( commandContext );
+}
diff --git a/packages/edit-site/src/posts.js b/packages/edit-site/src/posts.js
index ceee039806c9e7..19e787fff46305 100644
--- a/packages/edit-site/src/posts.js
+++ b/packages/edit-site/src/posts.js
@@ -3,6 +3,11 @@
*/
import { createRoot, StrictMode } from '@wordpress/element';
+/**
+ * Internal dependencies
+ */
+import PostsApp from './components/posts-app';
+
/**
* Initializes the "Posts Dashboard"
* @param {string} id DOM element id.
@@ -14,7 +19,11 @@ export function initializePostsDashboard( id ) {
const target = document.getElementById( id );
const root = createRoot( target );
- root.render( Welcome To Posts );
+ root.render(
+
+
+
+ );
return root;
}
diff --git a/packages/edit-site/src/posts.scss b/packages/edit-site/src/posts.scss
index 777ee3fa3412d5..4150634913cb7c 100644
--- a/packages/edit-site/src/posts.scss
+++ b/packages/edit-site/src/posts.scss
@@ -1,3 +1,14 @@
+@import "../../dataviews/src/style.scss";
+@import "./components/layout/style.scss";
+@import "./components/page/style.scss";
+@import "./components/save-hub/style.scss";
+@import "./components/save-panel/style.scss";
+@import "./components/sidebar/style.scss";
+@import "./components/site-hub/style.scss";
+@import "./components/site-icon/style.scss";
+@import "./components/editor-canvas-container/style.scss";
+@import "./components/resizable-frame/style.scss";
+
@include wordpress-admin-schemes();
#wpadminbar,
@@ -7,13 +18,29 @@
#wpcontent {
margin-left: 0;
}
+body.js #wpbody {
+ padding-top: 0;
+}
body {
@include wp-admin-reset("#gutenberg-posts-dashboard");
+}
+#gutenberg-posts-dashboard {
@include reset;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- min-height: 100vh;
+ height: 100vh;
+
+ // On mobile the main content area has to scroll, otherwise you can invoke
+ // the over-scroll bounce on the non-scrolling container, for a bad experience.
+ @include break-small {
+ bottom: 0;
+ left: 0;
+ min-height: 100vh;
+ position: fixed;
+ right: 0;
+ top: 0;
+ }
+
+ .no-js & {
+ min-height: 0;
+ position: static;
+ }
}
From 97ccc28eae5ac03acf282872c5267419b201e50d Mon Sep 17 00:00:00 2001
From: Riad Benguella
Date: Tue, 11 Jun 2024 15:36:13 +0200
Subject: [PATCH 11/17] DataViews: Bootstrap Actions Extensibility API (#62052)
Co-authored-by: youknowriad
Co-authored-by: ntsekouras
Co-authored-by: mcsf
Co-authored-by: fabiankaegy
Co-authored-by: Mamaduka
---
packages/dataviews/src/index.ts | 1 +
packages/editor/README.md | 24 ++++++++
.../src/components/post-actions/actions.js | 6 +-
packages/editor/src/dataviews/api.js | 55 +++++++++++++++++++
.../src/dataviews/store/private-actions.ts | 30 ++++++++++
.../src/dataviews/store/private-selectors.ts | 8 +++
.../editor/src/dataviews/store/reducer.ts | 44 +++++++++++++++
packages/editor/src/index.js | 1 +
packages/editor/src/store/private-actions.js | 1 +
.../editor/src/store/private-selectors.js | 5 ++
packages/editor/src/store/reducer.js | 2 +
packages/editor/tsconfig.json | 36 ++++++++++++
tsconfig.json | 1 +
13 files changed, 213 insertions(+), 1 deletion(-)
create mode 100644 packages/editor/src/dataviews/api.js
create mode 100644 packages/editor/src/dataviews/store/private-actions.ts
create mode 100644 packages/editor/src/dataviews/store/private-selectors.ts
create mode 100644 packages/editor/src/dataviews/store/reducer.ts
create mode 100644 packages/editor/tsconfig.json
diff --git a/packages/dataviews/src/index.ts b/packages/dataviews/src/index.ts
index 233ecd6864a5d5..31f44e5ed97502 100644
--- a/packages/dataviews/src/index.ts
+++ b/packages/dataviews/src/index.ts
@@ -1,3 +1,4 @@
export { default as DataViews } from './dataviews';
export { VIEW_LAYOUTS } from './layouts';
export { filterSortAndPaginate } from './filter-and-sort-data-view';
+export type * from './types';
diff --git a/packages/editor/README.md b/packages/editor/README.md
index b9106822272424..8279ec3e743605 100644
--- a/packages/editor/README.md
+++ b/packages/editor/README.md
@@ -1504,6 +1504,18 @@ _Returns_
Undocumented declaration.
+### registerEntityAction
+
+Registers a new DataViews action.
+
+This is an experimental API and is subject to change. it's only available in the Gutenberg plugin for now.
+
+_Parameters_
+
+- _kind_ `string`: Entity kind.
+- _name_ `string`: Entity name.
+- _config_ `Action`: Action configuration.
+
### RichText
> **Deprecated** since 5.3, use `wp.blockEditor.RichText` instead.
@@ -1589,6 +1601,18 @@ Undocumented declaration.
Undocumented declaration.
+### unregisterEntityAction
+
+Unregisters a DataViews action.
+
+This is an experimental API and is subject to change. it's only available in the Gutenberg plugin for now.
+
+_Parameters_
+
+- _kind_ `string`: Entity kind.
+- _name_ `string`: Entity name.
+- _actionId_ `string`: Action ID.
+
### UnsavedChangesWarning
Warns the user if there are unsaved changes before leaving the editor. Compatible with Post Editor and Site Editor.
diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js
index f376d0e8f969ec..6dcc7f6cb66708 100644
--- a/packages/editor/src/components/post-actions/actions.js
+++ b/packages/editor/src/components/post-actions/actions.js
@@ -1030,11 +1030,13 @@ export const duplicateTemplatePartAction = {
};
export function usePostActions( postType, onActionPerformed ) {
- const { postTypeObject } = useSelect(
+ const { defaultActions, postTypeObject } = useSelect(
( select ) => {
const { getPostType } = select( coreStore );
+ const { getEntityActions } = unlock( select( editorStore ) );
return {
postTypeObject: getPostType( postType ),
+ defaultActions: getEntityActions( 'postType', postType ),
};
},
[ postType ]
@@ -1072,6 +1074,7 @@ export function usePostActions( postType, onActionPerformed ) {
? deletePostAction
: trashPostAction,
! isTemplateOrTemplatePart && permanentlyDeletePostAction,
+ ...defaultActions,
].filter( Boolean );
if ( onActionPerformed ) {
@@ -1117,6 +1120,7 @@ export function usePostActions( postType, onActionPerformed ) {
return actions;
}, [
+ defaultActions,
isTemplateOrTemplatePart,
isPattern,
postTypeObject?.viewable,
diff --git a/packages/editor/src/dataviews/api.js b/packages/editor/src/dataviews/api.js
new file mode 100644
index 00000000000000..130a69bba754c7
--- /dev/null
+++ b/packages/editor/src/dataviews/api.js
@@ -0,0 +1,55 @@
+/**
+ * WordPress dependencies
+ */
+import { dispatch } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import { unlock } from '../lock-unlock';
+import { store as editorStore } from '../store';
+
+/**
+ * @typedef {import('@wordpress/dataviews').Action} Action
+ */
+
+/**
+ * Registers a new DataViews action.
+ *
+ * This is an experimental API and is subject to change.
+ * it's only available in the Gutenberg plugin for now.
+ *
+ * @param {string} kind Entity kind.
+ * @param {string} name Entity name.
+ * @param {Action} config Action configuration.
+ */
+
+export function registerEntityAction( kind, name, config ) {
+ const { registerEntityAction: _registerEntityAction } = unlock(
+ dispatch( editorStore )
+ );
+
+ if ( globalThis.IS_GUTENBERG_PLUGIN ) {
+ _registerEntityAction( kind, name, config );
+ }
+}
+
+/**
+ * Unregisters a DataViews action.
+ *
+ * This is an experimental API and is subject to change.
+ * it's only available in the Gutenberg plugin for now.
+ *
+ * @param {string} kind Entity kind.
+ * @param {string} name Entity name.
+ * @param {string} actionId Action ID.
+ */
+export function unregisterEntityAction( kind, name, actionId ) {
+ const { unregisterEntityAction: _unregisterEntityAction } = unlock(
+ dispatch( editorStore )
+ );
+
+ if ( globalThis.IS_GUTENBERG_PLUGIN ) {
+ _unregisterEntityAction( kind, name, actionId );
+ }
+}
diff --git a/packages/editor/src/dataviews/store/private-actions.ts b/packages/editor/src/dataviews/store/private-actions.ts
new file mode 100644
index 00000000000000..a74e1b5e79844a
--- /dev/null
+++ b/packages/editor/src/dataviews/store/private-actions.ts
@@ -0,0 +1,30 @@
+/**
+ * WordPress dependencies
+ */
+import type { Action, AnyItem } from '@wordpress/dataviews';
+
+export function registerEntityAction< Item extends AnyItem >(
+ kind: string,
+ name: string,
+ config: Action< Item >
+) {
+ return {
+ type: 'REGISTER_ENTITY_ACTION' as const,
+ kind,
+ name,
+ config,
+ };
+}
+
+export function unregisterEntityAction(
+ kind: string,
+ name: string,
+ actionId: string
+) {
+ return {
+ type: 'UNREGISTER_ENTITY_ACTION' as const,
+ kind,
+ name,
+ actionId,
+ };
+}
diff --git a/packages/editor/src/dataviews/store/private-selectors.ts b/packages/editor/src/dataviews/store/private-selectors.ts
new file mode 100644
index 00000000000000..938228ad97ed72
--- /dev/null
+++ b/packages/editor/src/dataviews/store/private-selectors.ts
@@ -0,0 +1,8 @@
+/**
+ * Internal dependencies
+ */
+import type { State } from './reducer';
+
+export function getEntityActions( state: State, kind: string, name: string ) {
+ return state.actions[ kind ]?.[ name ] ?? [];
+}
diff --git a/packages/editor/src/dataviews/store/reducer.ts b/packages/editor/src/dataviews/store/reducer.ts
new file mode 100644
index 00000000000000..e3b400faabe934
--- /dev/null
+++ b/packages/editor/src/dataviews/store/reducer.ts
@@ -0,0 +1,44 @@
+/**
+ * WordPress dependencies
+ */
+import { combineReducers } from '@wordpress/data';
+import { __ } from '@wordpress/i18n';
+import type { Action } from '@wordpress/dataviews';
+
+type ReduxAction =
+ | ReturnType< typeof import('./private-actions').registerEntityAction >
+ | ReturnType< typeof import('./private-actions').unregisterEntityAction >;
+
+export type ActionState = Record< string, Record< string, Action< any >[] > >;
+export type State = {
+ actions: ActionState;
+};
+
+function actions( state: ActionState = {}, action: ReduxAction ) {
+ switch ( action.type ) {
+ case 'REGISTER_ENTITY_ACTION':
+ return {
+ ...state,
+ [ action.kind ]: {
+ [ action.name ]: [
+ ...( state[ action.kind ]?.[ action.name ] ?? [] ),
+ action.config,
+ ],
+ },
+ };
+ case 'UNREGISTER_ENTITY_ACTION': {
+ return {
+ ...state,
+ [ action.kind ]: (
+ state[ action.kind ]?.[ action.name ] ?? []
+ ).filter( ( _action ) => _action.id !== action.actionId ),
+ };
+ }
+ }
+
+ return state;
+}
+
+export default combineReducers( {
+ actions,
+} );
diff --git a/packages/editor/src/index.js b/packages/editor/src/index.js
index 3f6d7a78d837c0..1f7bb7699c7040 100644
--- a/packages/editor/src/index.js
+++ b/packages/editor/src/index.js
@@ -8,6 +8,7 @@ export { storeConfig, store } from './store';
export * from './components';
export * from './utils';
export * from './private-apis';
+export * from './dataviews/api';
/*
* Backward compatibility
diff --git a/packages/editor/src/store/private-actions.js b/packages/editor/src/store/private-actions.js
index 9304a2fe2c0579..bde803962f5d3a 100644
--- a/packages/editor/src/store/private-actions.js
+++ b/packages/editor/src/store/private-actions.js
@@ -15,6 +15,7 @@ import { decodeEntities } from '@wordpress/html-entities';
* Internal dependencies
*/
import isTemplateRevertable from './utils/is-template-revertable';
+export * from '../dataviews/store/private-actions';
/**
* Returns an action object used to set which template is currently being used/edited.
diff --git a/packages/editor/src/store/private-selectors.js b/packages/editor/src/store/private-selectors.js
index 8a866b46a6cdd7..f56e1e8c9e81fb 100644
--- a/packages/editor/src/store/private-selectors.js
+++ b/packages/editor/src/store/private-selectors.js
@@ -27,6 +27,7 @@ import {
} from './selectors';
import { TEMPLATE_PART_POST_TYPE } from './constants';
import { getFilteredTemplatePartBlocks } from './utils/get-filtered-template-parts';
+import { getEntityActions as _getEntityActions } from '../dataviews/store/private-selectors';
const EMPTY_INSERTION_POINT = {
rootClientId: undefined,
@@ -180,3 +181,7 @@ export const hasPostMetaChanges = createRegistrySelector(
);
}
);
+
+export function getEntityActions( state, ...args ) {
+ return _getEntityActions( state.dataviews, ...args );
+}
diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js
index f9b4e05ffa8e5e..a165d90e296d6f 100644
--- a/packages/editor/src/store/reducer.js
+++ b/packages/editor/src/store/reducer.js
@@ -7,6 +7,7 @@ import { combineReducers } from '@wordpress/data';
* Internal dependencies
*/
import { EDITOR_SETTINGS_DEFAULTS } from './defaults';
+import dataviewsReducer from '../dataviews/store/reducer';
/**
* Returns a post attribute value, flattening nested rendered content using its
@@ -402,4 +403,5 @@ export default combineReducers( {
listViewPanel,
listViewToggleRef,
publishSidebarActive,
+ dataviews: dataviewsReducer,
} );
diff --git a/packages/editor/tsconfig.json b/packages/editor/tsconfig.json
new file mode 100644
index 00000000000000..1177a1040b117b
--- /dev/null
+++ b/packages/editor/tsconfig.json
@@ -0,0 +1,36 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig.json",
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "declarationDir": "build-types"
+ },
+ "references": [
+ { "path": "../a11y" },
+ { "path": "../api-fetch" },
+ { "path": "../blob" },
+ { "path": "../block-editor" },
+ { "path": "../components" },
+ { "path": "../compose" },
+ { "path": "../core-data" },
+ { "path": "../data" },
+ { "path": "../dataviews" },
+ { "path": "../date" },
+ { "path": "../deprecated" },
+ { "path": "../dom" },
+ { "path": "../element" },
+ { "path": "../hooks" },
+ { "path": "../html-entities" },
+ { "path": "../i18n" },
+ { "path": "../icons" },
+ { "path": "../keycodes" },
+ { "path": "../notices" },
+ { "path": "../plugins" },
+ { "path": "../private-apis" },
+ { "path": "../rich-text" },
+ { "path": "../url" },
+ { "path": "../warning" },
+ { "path": "../wordcount" }
+ ],
+ "include": [ "src/**/*.ts", "src/**/*.tsx" ]
+}
diff --git a/tsconfig.json b/tsconfig.json
index 4add5beed2f436..cf986ddbee72bf 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -21,6 +21,7 @@
{ "path": "packages/dom" },
{ "path": "packages/dom-ready" },
{ "path": "packages/e2e-test-utils-playwright" },
+ { "path": "packages/editor" },
{ "path": "packages/element" },
{ "path": "packages/escape-html" },
{ "path": "packages/eslint-plugin" },
From 7b177d9b887992f9e46e09fdec5ebc719516ddcc Mon Sep 17 00:00:00 2001
From: Jon Surrell
Date: Tue, 11 Jun 2024 16:06:17 +0200
Subject: [PATCH 12/17] Fix: (#62482)
Co-authored-by: sirreal
Co-authored-by: WunderBart
Co-authored-by: up1512001
---
bin/packages/check-build-type-declaration-files.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bin/packages/check-build-type-declaration-files.js b/bin/packages/check-build-type-declaration-files.js
index 74c7cfa5e3c2ac..3d70145ceb588e 100644
--- a/bin/packages/check-build-type-declaration-files.js
+++ b/bin/packages/check-build-type-declaration-files.js
@@ -70,7 +70,7 @@ async function getDecFile( packagePath ) {
async function typecheckDeclarations( file ) {
return new Promise( ( resolve, reject ) => {
exec(
- `npx tsc --target esnext --moduleResolution node --noEmit ${ file }`,
+ `npx tsc --target esnext --moduleResolution node --noEmit "${ file }"`,
( error, stdout, stderr ) => {
if ( error ) {
reject( { file, error, stderr, stdout } );
From 57b8b613d0507fd2c1ed0b441db09f76a43d579f Mon Sep 17 00:00:00 2001
From: Joe McGill <801097+joemcgill@users.noreply.github.com>
Date: Tue, 11 Jun 2024 11:15:27 -0500
Subject: [PATCH 13/17] Fix `@since` tag in docblock in
`WP_Theme_JSON_Data_Gutenberg`. (#62425)
The `get_theme_json` method was actually added in v18.5.0, not 18.3.0. This corrects the docblock reference.
Co-authored-by: joemcgill
Co-authored-by: fabiankaegy
---
lib/class-wp-theme-json-data-gutenberg.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/class-wp-theme-json-data-gutenberg.php b/lib/class-wp-theme-json-data-gutenberg.php
index 4ff7775f4b559c..2c7eec9d5dbf4a 100644
--- a/lib/class-wp-theme-json-data-gutenberg.php
+++ b/lib/class-wp-theme-json-data-gutenberg.php
@@ -72,7 +72,7 @@ public function get_data() {
/**
* Return theme JSON object.
*
- * @since 18.3.0
+ * @since 18.5.0
*
* @return WP_Theme_JSON
*/
From b8fd20a2422347461fd8f8e1b10cf6480b9de0b1 Mon Sep 17 00:00:00 2001
From: Kai Hao
Date: Wed, 12 Jun 2024 09:54:55 +0800
Subject: [PATCH 14/17] Fix showing double icons for connected blocks in
pattern editor (#62317)
Co-authored-by: kevin940726
Co-authored-by: talldan
Co-authored-by: SantosGuillamot
Co-authored-by: jasmussen
Co-authored-by: richtabor
Co-authored-by: ellatrix
* Fix showing double icons for connected blocks in pattern editor
* Fix post-meta
* Unify the experience
* Rename the component
---
.../style.scss | 12 ----
.../src/components/block-switcher/index.js | 26 +++++++-
.../src/components/block-switcher/style.scss | 5 ++
.../src/components/block-toolbar/index.js | 28 ++++++---
.../src/components/block-toolbar/style.scss | 15 +++--
.../index.js | 61 +++++++------------
.../style.scss | 12 ++++
packages/block-editor/src/style.scss | 2 +-
8 files changed, 94 insertions(+), 67 deletions(-)
delete mode 100644 packages/block-editor/src/components/block-bindings-toolbar-indicator/style.scss
rename packages/block-editor/src/components/{block-bindings-toolbar-indicator => pattern-overrides-toolbar-indicator}/index.js (62%)
create mode 100644 packages/block-editor/src/components/pattern-overrides-toolbar-indicator/style.scss
diff --git a/packages/block-editor/src/components/block-bindings-toolbar-indicator/style.scss b/packages/block-editor/src/components/block-bindings-toolbar-indicator/style.scss
deleted file mode 100644
index f37276290ca713..00000000000000
--- a/packages/block-editor/src/components/block-bindings-toolbar-indicator/style.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-.block-editor-block-bindings-toolbar-indicator__popover .components-popover__content {
- min-width: 260px;
- padding: $grid-unit-20;
-}
-
-.block-editor-block-bindings-toolbar-indicator .block-editor-block-bindings-toolbar-indicator-icon.has-colors svg {
- fill: var(--wp-block-synced-color);
-}
-
-.editor-collapsible-block-toolbar .block-editor-block-bindings-toolbar-indicator {
- height: 32px;
-}
diff --git a/packages/block-editor/src/components/block-switcher/index.js b/packages/block-editor/src/components/block-switcher/index.js
index 8b01907474d23a..87970d53c19f42 100644
--- a/packages/block-editor/src/components/block-switcher/index.js
+++ b/packages/block-editor/src/components/block-switcher/index.js
@@ -1,12 +1,14 @@
/**
* WordPress dependencies
*/
-import { __, _n, sprintf } from '@wordpress/i18n';
+import { __, _n, sprintf, _x } from '@wordpress/i18n';
import {
DropdownMenu,
ToolbarButton,
ToolbarGroup,
ToolbarItem,
+ __experimentalText as Text,
+ MenuGroup,
} from '@wordpress/components';
import {
switchToBlockType,
@@ -33,6 +35,7 @@ function BlockSwitcherDropdownMenuContents( {
clientIds,
hasBlockStyles,
canRemove,
+ isUsingBindings,
} ) {
const { replaceBlocks, multiSelect, updateBlockAttributes } =
useDispatch( blockEditorStore );
@@ -118,6 +121,17 @@ function BlockSwitcherDropdownMenuContents( {
);
}
+
+ const connectedBlockDescription = isSingleBlock
+ ? _x(
+ 'This block is connected.',
+ 'block toolbar button label and description'
+ )
+ : _x(
+ 'These blocks are connected.',
+ 'block toolbar button label and description'
+ );
+
return (
{ hasPatternTransformation && (
@@ -156,11 +170,18 @@ function BlockSwitcherDropdownMenuContents( {
onSwitch={ onClose }
/>
) }
+ { isUsingBindings && (
+
+
+ { connectedBlockDescription }
+
+
+ ) }
);
}
-export const BlockSwitcher = ( { clientIds, disabled } ) => {
+export const BlockSwitcher = ( { clientIds, disabled, isUsingBindings } ) => {
const {
canRemove,
hasBlockStyles,
@@ -303,6 +324,7 @@ export const BlockSwitcher = ( { clientIds, disabled } ) => {
clientIds={ clientIds }
hasBlockStyles={ hasBlockStyles }
canRemove={ canRemove }
+ isUsingBindings={ isUsingBindings }
/>
) }
diff --git a/packages/block-editor/src/components/block-switcher/style.scss b/packages/block-editor/src/components/block-switcher/style.scss
index 2072616f7fb0f7..5eaba08bf94ae2 100644
--- a/packages/block-editor/src/components/block-switcher/style.scss
+++ b/packages/block-editor/src/components/block-switcher/style.scss
@@ -203,3 +203,8 @@
padding: 6px $grid-unit;
margin: 0;
}
+
+.block-editor-block-switcher__binding-indicator {
+ display: block;
+ padding: $grid-unit;
+}
diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js
index 0e341d32163952..cffb46413c5bbb 100644
--- a/packages/block-editor/src/components/block-toolbar/index.js
+++ b/packages/block-editor/src/components/block-toolbar/index.js
@@ -35,7 +35,7 @@ import { store as blockEditorStore } from '../../store';
import __unstableBlockNameContext from './block-name-context';
import NavigableToolbar from '../navigable-toolbar';
import Shuffle from './shuffle';
-import BlockBindingsIndicator from '../block-bindings-toolbar-indicator';
+import PatternOverridesToolbarIndicator from '../pattern-overrides-toolbar-indicator';
import { useHasBlockToolbar } from './use-has-block-toolbar';
import { canBindBlock } from '../../hooks/use-bindings-attributes';
/**
@@ -67,11 +67,13 @@ export function PrivateBlockToolbar( {
shouldShowVisualToolbar,
showParentSelector,
isUsingBindings,
+ hasParentPattern,
} = useSelect( ( select ) => {
const {
getBlockName,
getBlockMode,
getBlockParents,
+ getBlockParentsByBlockName,
getSelectedBlockClientIds,
isBlockValid,
getBlockRootClientId,
@@ -94,8 +96,13 @@ export function PrivateBlockToolbar( {
const isVisual = selectedBlockClientIds.every(
( id ) => getBlockMode( id ) === 'visual'
);
- const _isUsingBindings = !! getBlockAttributes( selectedBlockClientId )
- ?.metadata?.bindings;
+ const bindings = getBlockAttributes( selectedBlockClientId )?.metadata
+ ?.bindings;
+ const parentPatternClientId = getBlockParentsByBlockName(
+ selectedBlockClientId,
+ 'core/block',
+ true
+ )[ 0 ];
return {
blockClientId: selectedBlockClientId,
blockClientIds: selectedBlockClientIds,
@@ -115,7 +122,8 @@ export function PrivateBlockToolbar( {
) &&
selectedBlockClientIds.length === 1 &&
_isDefaultEditingMode,
- isUsingBindings: _isUsingBindings,
+ isUsingBindings: !! bindings,
+ hasParentPattern: !! parentPatternClientId,
};
}, [] );
@@ -146,6 +154,7 @@ export function PrivateBlockToolbar( {
const innerClasses = clsx( 'block-editor-block-toolbar', {
'is-synced': isSynced,
+ 'is-connected': isUsingBindings,
} );
return (
@@ -167,9 +176,13 @@ export function PrivateBlockToolbar( {
{ ! isMultiToolbar &&
isLargeViewport &&
isDefaultEditingMode && }
- { isUsingBindings && canBindBlock( blockName ) && (
-
- ) }
+ { isUsingBindings &&
+ hasParentPattern &&
+ canBindBlock( blockName ) && (
+
+ ) }
{ ( shouldShowVisualToolbar || isMultiToolbar ) &&
( isDefaultEditingMode || isSynced ) && (
{ isDefaultEditingMode && (
<>
diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss
index 1854e440329647..6314f1a1e7ffd5 100644
--- a/packages/block-editor/src/components/block-toolbar/style.scss
+++ b/packages/block-editor/src/components/block-toolbar/style.scss
@@ -39,14 +39,17 @@
border-right: $border-width solid $gray-300;
}
- &.is-synced .block-editor-block-switcher .components-button .block-editor-block-icon {
- color: var(--wp-block-synced-color);
- }
-
- &.is-synced .components-toolbar-button.block-editor-block-switcher__no-switcher-icon {
- &:disabled .block-editor-block-icon.has-colors {
+ &.is-synced,
+ &.is-connected {
+ .block-editor-block-switcher .components-button .block-editor-block-icon {
color: var(--wp-block-synced-color);
}
+
+ .components-toolbar-button.block-editor-block-switcher__no-switcher-icon {
+ &:disabled .block-editor-block-icon.has-colors {
+ color: var(--wp-block-synced-color);
+ }
+ }
}
> :last-child,
diff --git a/packages/block-editor/src/components/block-bindings-toolbar-indicator/index.js b/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/index.js
similarity index 62%
rename from packages/block-editor/src/components/block-bindings-toolbar-indicator/index.js
rename to packages/block-editor/src/components/pattern-overrides-toolbar-indicator/index.js
index e25c489c1dbf91..af359da542d37a 100644
--- a/packages/block-editor/src/components/block-bindings-toolbar-indicator/index.js
+++ b/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/index.js
@@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { useId } from '@wordpress/element';
-import { __, sprintf, _x } from '@wordpress/i18n';
+import { __, sprintf } from '@wordpress/i18n';
import {
DropdownMenu,
ToolbarGroup,
@@ -20,15 +20,18 @@ import { store as blockEditorStore } from '../../store';
import BlockIcon from '../block-icon';
import useBlockDisplayTitle from '../block-title/use-block-display-title';
-export default function BlockBindingsToolbarIndicator( { clientIds } ) {
+/**
+ * This component is currently only for pattern overrides, which is a WP-only feature.
+ * Ideally, this should be moved to the `patterns` package once ready.
+ * @param {Object} props The component props.
+ * @param {Array} props.clientIds The client IDs of the selected blocks.
+ */
+export default function PatternOverridesToolbarIndicator( { clientIds } ) {
const isSingleBlockSelected = clientIds.length === 1;
- const { icon, firstBlockName, isConnectedToPatternOverrides } = useSelect(
+ const { icon, firstBlockName } = useSelect(
( select ) => {
- const {
- getBlockAttributes,
- getBlockNamesByClientId,
- getBlocksByClientId,
- } = select( blockEditorStore );
+ const { getBlockAttributes, getBlockNamesByClientId } =
+ select( blockEditorStore );
const { getBlockType, getActiveBlockVariation } =
select( blocksStore );
const blockTypeNames = getBlockNamesByClientId( clientIds );
@@ -54,16 +57,6 @@ export default function BlockBindingsToolbarIndicator( { clientIds } ) {
icon: _icon,
firstBlockName: getBlockAttributes( clientIds[ 0 ] ).metadata
.name,
- isConnectedToPatternOverrides: getBlocksByClientId(
- clientIds
- ).some( ( block ) =>
- Object.values(
- block?.attributes?.metadata?.bindings || {}
- ).some(
- ( binding ) =>
- binding.source === 'core/pattern-overrides'
- )
- ),
};
},
[ clientIds, isSingleBlockSelected ]
@@ -73,25 +66,15 @@ export default function BlockBindingsToolbarIndicator( { clientIds } ) {
maximumLength: 35,
} );
- let blockDescription = isSingleBlockSelected
- ? _x(
- 'This block is connected.',
- 'block toolbar button label and description'
+ const blockDescription = isSingleBlockSelected
+ ? sprintf(
+ /* translators: %1s: The block type's name; %2s: The block's user-provided name (the same as the override name). */
+ __( 'This %1$s is editable using the "%2$s" override.' ),
+ firstBlockTitle.toLowerCase(),
+ firstBlockName
)
- : _x(
- 'These blocks are connected.',
- 'block toolbar button label and description'
- );
- if ( isConnectedToPatternOverrides && firstBlockName ) {
- blockDescription = isSingleBlockSelected
- ? sprintf(
- /* translators: %1s: The block type's name; %2s: The block's user-provided name (the same as the override name). */
- __( 'This %1$s is editable using the "%2$s" override.' ),
- firstBlockTitle.toLowerCase(),
- firstBlockName
- )
- : __( 'These blocks are editable using overrides.' );
- }
+ : __( 'These blocks are editable using overrides.' );
+
const descriptionId = useId();
return (
@@ -99,18 +82,18 @@ export default function BlockBindingsToolbarIndicator( { clientIds } ) {
{ ( toggleProps ) => (
>
diff --git a/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/style.scss b/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/style.scss
new file mode 100644
index 00000000000000..90b2c1cdd79a5e
--- /dev/null
+++ b/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/style.scss
@@ -0,0 +1,12 @@
+.block-editor-pattern-overrides-toolbar-indicator__popover .components-popover__content {
+ min-width: 260px;
+ padding: $grid-unit-20;
+}
+
+.block-editor-pattern-overrides-toolbar-indicator .block-editor-pattern-overrides-toolbar-indicator-icon.has-colors svg {
+ fill: var(--wp-block-synced-color);
+}
+
+.editor-collapsible-block-toolbar .block-editor-pattern-overrides-toolbar-indicator {
+ height: 32px;
+}
diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss
index 484d79e8db9fa0..d22ea9b3d0a283 100644
--- a/packages/block-editor/src/style.scss
+++ b/packages/block-editor/src/style.scss
@@ -1,6 +1,6 @@
@import "./autocompleters/style.scss";
@import "./components/block-alignment-control/style.scss";
-@import "./components/block-bindings-toolbar-indicator/style.scss";
+@import "./components/pattern-overrides-toolbar-indicator/style.scss";
@import "./components/block-canvas/style.scss";
@import "./components/block-icon/style.scss";
@import "./components/block-inspector/style.scss";
From 24aeb3133507099286bc464a10f9821a0b47fc1f Mon Sep 17 00:00:00 2001
From: Aki Hamano <54422211+t-hamano@users.noreply.github.com>
Date: Wed, 12 Jun 2024 11:21:05 +0900
Subject: [PATCH 15/17] List View: Respect default shortcuts in modals (#62479)
Co-authored-by: t-hamano
Co-authored-by: Mamaduka
Co-authored-by: andrewserong
Co-authored-by: mcsf
Co-authored-by: colorful-tones
---
.../block-editor/src/components/list-view/block.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js
index f93ae2a63787c2..4db12c4d8b77c2 100644
--- a/packages/block-editor/src/components/list-view/block.js
+++ b/packages/block-editor/src/components/list-view/block.js
@@ -181,6 +181,12 @@ function ListViewBlock( {
return;
}
+ // Do not handle events if it comes from modals;
+ // retain the default behavior for these keys.
+ if ( event.target.closest( '[role=dialog]' ) ) {
+ return;
+ }
+
const isDeleteKey = [ BACKSPACE, DELETE ].includes( event.keyCode );
// If multiple blocks are selected, deselect all blocks when the user
@@ -196,12 +202,6 @@ function ListViewBlock( {
isDeleteKey ||
isMatch( 'core/block-editor/remove', event )
) {
- // Do not handle single-key block deletion shortcuts when events come from modals;
- // retain the default behavior for these keys.
- if ( isDeleteKey && event.target.closest( '[role=dialog]' ) ) {
- return;
- }
-
const {
blocksToUpdate: blocksToDelete,
firstBlockClientId,
From f1016e972ac189e4bbc0b9235cd4ebd0566f5532 Mon Sep 17 00:00:00 2001
From: Aki Hamano <54422211+t-hamano@users.noreply.github.com>
Date: Wed, 12 Jun 2024 12:31:22 +0900
Subject: [PATCH 16/17] Icons: Fix React warning error for offline icon
(#62353)
Co-authored-by: t-hamano
Co-authored-by: dcalhoun
---
packages/icons/src/library/offline.js | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/packages/icons/src/library/offline.js b/packages/icons/src/library/offline.js
index 444d3667f297e8..698a42aa4badb9 100644
--- a/packages/icons/src/library/offline.js
+++ b/packages/icons/src/library/offline.js
@@ -5,11 +5,7 @@ import { SVG, Path } from '@wordpress/primitives';
const offline = (
);
From 35ddbfb928c875ab8a1ca2fb523b8749b15bcd81 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Wed, 12 Jun 2024 14:52:39 +1000
Subject: [PATCH 17/17] List View: Fix home and end key behaviour in very long
lists (#62312)
* List View: Fix home and end key behaviour in very long lists
* Update e2e test
Co-authored-by: andrewserong
Co-authored-by: talldan
Co-authored-by: ellatrix
---
packages/block-editor/src/components/list-view/branch.js | 6 +++++-
test/e2e/specs/editor/various/list-view.spec.js | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/packages/block-editor/src/components/list-view/branch.js b/packages/block-editor/src/components/list-view/branch.js
index 16480927dc4665..ebd1d5a36f5700 100644
--- a/packages/block-editor/src/components/list-view/branch.js
+++ b/packages/block-editor/src/components/list-view/branch.js
@@ -194,10 +194,14 @@ function ListViewBranch( props ) {
// This prevents the entire tree from being rendered when a branch is
// selected, or a user selects all blocks, while still enabling scroll
// into view behavior when selecting a block or opening the list view.
+ // The first and last blocks of the list are always rendered, to ensure
+ // that Home and End keys work as expected.
const showBlock =
isDragged ||
blockInView ||
- ( isSelected && clientId === selectedClientIds[ 0 ] );
+ ( isSelected && clientId === selectedClientIds[ 0 ] ) ||
+ index === 0 ||
+ index === blockCount - 1;
return (
{ showBlock && (
diff --git a/test/e2e/specs/editor/various/list-view.spec.js b/test/e2e/specs/editor/various/list-view.spec.js
index 143fea43c09eef..531faa8bea049d 100644
--- a/test/e2e/specs/editor/various/list-view.spec.js
+++ b/test/e2e/specs/editor/various/list-view.spec.js
@@ -1120,7 +1120,7 @@ test.describe( 'List View', () => {
'Pressing keyboard shortcut should also work when the menu is opened and focused'
)
.toMatchObject( [
- { name: 'core/paragraph', selected: true, focused: false },
+ { name: 'core/paragraph', selected: true, focused: true },
{ name: 'core/file', selected: false, focused: false },
] );
await expect(