From 78a0e6f773314a2ef8179102c83bf521f48c99f9 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 5 Apr 2023 13:40:56 +0300 Subject: [PATCH 01/23] WIP --- lib/client-assets.php | 9 ++ ...ass-gutenberg-rest-patterns-controller.php | 92 +++++++++++ lib/compat/wordpress-6.3/post.php | 74 +++++++++ lib/load.php | 2 + package-lock.json | 18 +++ package.json | 1 + packages/base-styles/_z-index.scss | 1 + packages/edit-post/package.json | 1 + packages/edit-post/src/plugins/index.js | 8 + packages/edit-site/package.json | 1 + .../src/components/block-editor/index.js | 2 + packages/editor/package.json | 1 + .../editor/src/components/provider/index.js | 2 + packages/patterns/.npmrc | 1 + packages/patterns/package.json | 49 ++++++ packages/patterns/src/components/index.js | 1 + .../components/patterns-menu-items/index.js | 28 ++++ .../patterns-menu-items/index.native.js | 1 + .../pattern-convert-button.js | 116 ++++++++++++++ .../components/patterns-menu-items/style.scss | 3 + packages/patterns/src/index.js | 2 + packages/patterns/src/index.native.js | 7 + packages/patterns/src/store/actions.js | 30 ++++ packages/patterns/src/store/index.js | 22 +++ .../store/test/__snapshots__/actions.js.snap | 14 ++ packages/patterns/src/store/test/actions.js | 147 ++++++++++++++++++ packages/patterns/src/store/test/selectors.js | 27 ++++ packages/patterns/src/style.scss | 1 + 28 files changed, 661 insertions(+) create mode 100644 lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php create mode 100644 lib/compat/wordpress-6.3/post.php create mode 100644 packages/patterns/.npmrc create mode 100644 packages/patterns/package.json create mode 100644 packages/patterns/src/components/index.js create mode 100644 packages/patterns/src/components/patterns-menu-items/index.js create mode 100644 packages/patterns/src/components/patterns-menu-items/index.native.js create mode 100644 packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js create mode 100644 packages/patterns/src/components/patterns-menu-items/style.scss create mode 100644 packages/patterns/src/index.js create mode 100644 packages/patterns/src/index.native.js create mode 100644 packages/patterns/src/store/actions.js create mode 100644 packages/patterns/src/store/index.js create mode 100644 packages/patterns/src/store/test/__snapshots__/actions.js.snap create mode 100644 packages/patterns/src/store/test/actions.js create mode 100644 packages/patterns/src/store/test/selectors.js create mode 100644 packages/patterns/src/style.scss diff --git a/lib/client-assets.php b/lib/client-assets.php index 9c0483ea539b93..2dd64a1e82a768 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -442,6 +442,15 @@ function gutenberg_register_packages_styles( $styles ) { ); $styles->add_data( 'wp-reusable-blocks', 'rtl', 'replace' ); + gutenberg_override_style( + $styles, + 'wp-patterns', + gutenberg_url( 'build/patterns/style.css' ), + array( 'wp-components' ), + $version + ); + $styles->add_data( 'wp-patterns', 'rtl', 'replace' ); + gutenberg_override_style( $styles, 'wp-widgets', diff --git a/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php b/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php new file mode 100644 index 00000000000000..0c3137d52a621e --- /dev/null +++ b/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php @@ -0,0 +1,92 @@ +ID ) ) { + return false; + } + + return parent::check_read_permission( $post ); + } + + /** + * Filters a response based on the context defined in the schema. + * + * @since 5.0.0 + * + * @param array $data Response data to filter. + * @param string $context Context defined in the schema. + * @return array Filtered response. + */ + public function filter_response_by_context( $data, $context ) { + $data = parent::filter_response_by_context( $data, $context ); + + /* + * Remove `title.rendered` and `content.rendered` from the response. It + * doesn't make sense for a reusable block to have rendered content on its + * own, since rendering a block requires it to be inside a post or a page. + */ + unset( $data['title']['rendered'] ); + unset( $data['content']['rendered'] ); + + return $data; + } + + /** + * Retrieves the block's schema, conforming to JSON Schema. + * + * @since 5.0.0 + * + * @return array Item schema data. + */ + public function get_item_schema() { + // Do not cache this schema because all properties are derived from parent controller. + $schema = parent::get_item_schema(); + + /* + * Allow all contexts to access `title.raw` and `content.raw`. Clients always + * need the raw markup of a reusable block to do anything useful, e.g. parse + * it or display it in an editor. + */ + $schema['properties']['title']['properties']['raw']['context'] = array( 'view', 'edit' ); + $schema['properties']['content']['properties']['raw']['context'] = array( 'view', 'edit' ); + + /* + * Remove `title.rendered` and `content.rendered` from the schema. It doesn’t + * make sense for a reusable block to have rendered content on its own, since + * rendering a block requires it to be inside a post or a page. + */ + unset( $schema['properties']['title']['properties']['rendered'] ); + unset( $schema['properties']['content']['properties']['rendered'] ); + + return $schema; + } + +} diff --git a/lib/compat/wordpress-6.3/post.php b/lib/compat/wordpress-6.3/post.php new file mode 100644 index 00000000000000..384c38fa067e41 --- /dev/null +++ b/lib/compat/wordpress-6.3/post.php @@ -0,0 +1,74 @@ + array( + 'name' => _x( 'Patterns', 'post type general name' ), + 'singular_name' => _x( 'Pattern', 'post type singular name' ), + 'add_new' => _x( 'Add New', 'Pattern' ), + 'add_new_item' => __( 'Add new Pattern' ), + 'new_item' => __( 'New Pattern' ), + 'edit_item' => __( 'Edit Pattern' ), + 'view_item' => __( 'View Pattern' ), + 'all_items' => __( 'All Patterns' ), + 'search_items' => __( 'Search Patterns' ), + 'not_found' => __( 'No pattern found.' ), + 'not_found_in_trash' => __( 'No pattern found in Trash.' ), + 'filter_items_list' => __( 'Filter pattern list' ), + 'items_list_navigation' => __( 'Patterns list navigation' ), + 'items_list' => __( 'Patterns list' ), + 'item_published' => __( 'Pattern published.' ), + 'item_published_privately' => __( 'Pattern published privately.' ), + 'item_reverted_to_draft' => __( 'Pattern reverted to draft.' ), + 'item_scheduled' => __( 'Pattern scheduled.' ), + 'item_updated' => __( 'Pattern updated.' ), + ), + 'public' => true, + '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ + 'show_ui' => true, + 'show_in_menu' => true, + 'rewrite' => false, + 'show_in_rest' => true, + 'rest_base' => 'patterns', + 'rest_controller_class' => 'Gutenberg_REST_Patterns_Controller', + 'capability_type' => 'block', + 'capabilities' => array( + // You need to be able to edit posts, in order to read blocks in their raw form. + 'read' => 'edit_posts', + // You need to be able to publish posts, in order to create blocks. + 'create_posts' => 'publish_posts', + 'edit_posts' => 'edit_posts', + 'edit_published_posts' => 'edit_published_posts', + 'delete_published_posts' => 'delete_published_posts', + 'edit_others_posts' => 'edit_others_posts', + 'delete_others_posts' => 'delete_others_posts', + ), + 'map_meta_cap' => true, + 'supports' => array( + 'title', + 'editor', + 'revisions', + ), + ) + ); +} +add_action( 'init', 'gutenberg_create_initial_post_types' ); diff --git a/lib/load.php b/lib/load.php index a322e8af03a9de..a8b39bd2ee6387 100644 --- a/lib/load.php +++ b/lib/load.php @@ -49,6 +49,8 @@ function gutenberg_is_experiment_enabled( $name ) { require_once __DIR__ . '/compat/wordpress-6.3/class-gutenberg-rest-global-styles-controller-6-3.php'; require_once __DIR__ . '/compat/wordpress-6.3/rest-api.php'; require_once __DIR__ . '/compat/wordpress-6.3/theme-previews.php'; + require_once __DIR__ . '/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php'; + require_once __DIR__ . '/compat/wordpress-6.3/post.php'; // Experimental. if ( ! class_exists( 'WP_Rest_Customizer_Nonces' ) ) { diff --git a/package-lock.json b/package-lock.json index 5154297bb17116..67ac303a6b5ca6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17330,6 +17330,7 @@ "@wordpress/keycodes": "file:packages/keycodes", "@wordpress/media-utils": "file:packages/media-utils", "@wordpress/notices": "file:packages/notices", + "@wordpress/patterns": "file:packages/patterns", "@wordpress/plugins": "file:packages/plugins", "@wordpress/preferences": "file:packages/preferences", "@wordpress/private-apis": "file:packages/private-apis", @@ -17400,6 +17401,7 @@ "@wordpress/keycodes": "file:packages/keycodes", "@wordpress/media-utils": "file:packages/media-utils", "@wordpress/notices": "file:packages/notices", + "@wordpress/patterns": "file:packages/patterns", "@wordpress/plugins": "file:packages/plugins", "@wordpress/preferences": "file:packages/preferences", "@wordpress/private-apis": "file:packages/private-apis", @@ -17483,6 +17485,7 @@ "@wordpress/keycodes": "file:packages/keycodes", "@wordpress/media-utils": "file:packages/media-utils", "@wordpress/notices": "file:packages/notices", + "@wordpress/patterns": "file:packages/patterns", "@wordpress/preferences": "file:packages/preferences", "@wordpress/private-apis": "file:packages/private-apis", "@wordpress/reusable-blocks": "file:packages/reusable-blocks", @@ -17849,6 +17852,21 @@ "version": "file:packages/npm-package-json-lint-config", "dev": true }, + "@wordpress/patterns": { + "version": "file:packages/patterns", + "requires": { + "@wordpress/block-editor": "file:packages/block-editor", + "@wordpress/blocks": "file:packages/blocks", + "@wordpress/components": "file:packages/components", + "@wordpress/core-data": "file:packages/core-data", + "@wordpress/data": "file:packages/data", + "@wordpress/element": "file:packages/element", + "@wordpress/i18n": "file:packages/i18n", + "@wordpress/icons": "file:packages/icons", + "@wordpress/notices": "file:packages/notices", + "@wordpress/url": "file:packages/url" + } + }, "@wordpress/plugins": { "version": "file:packages/plugins", "requires": { diff --git a/package.json b/package.json index 45b1e5ef319d25..3346c5785ceb52 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "@wordpress/list-reusable-blocks": "file:packages/list-reusable-blocks", "@wordpress/media-utils": "file:packages/media-utils", "@wordpress/notices": "file:packages/notices", + "@wordpress/patterns": "file:packages/patterns", "@wordpress/plugins": "file:packages/plugins", "@wordpress/preferences": "file:packages/preferences", "@wordpress/preferences-persistence": "file:packages/preferences-persistence", diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index bdc9ed6aa9ba6d..1e299774ebadcb 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -121,6 +121,7 @@ $z-layers: ( // Should be above the popover (dropdown) ".reusable-blocks-menu-items__convert-modal": 1000001, + ".patterns-menu-items__convert-modal": 1000001, ".edit-site-create-template-part-modal": 1000001, ".block-editor-block-lock-modal": 1000001, ".block-editor-template-part__selection-modal": 1000001, diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 1df3f566ab9d54..97a6b1f8a42058 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -50,6 +50,7 @@ "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", "@wordpress/notices": "file:../notices", + "@wordpress/patterns": "file:../patterns", "@wordpress/plugins": "file:../plugins", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", diff --git a/packages/edit-post/src/plugins/index.js b/packages/edit-post/src/plugins/index.js index b065f618912be2..f13d39f8b0d95c 100644 --- a/packages/edit-post/src/plugins/index.js +++ b/packages/edit-post/src/plugins/index.js @@ -30,6 +30,14 @@ registerPlugin( 'edit-post', { > { __( 'Manage Reusable blocks' ) } + + { __( 'Manage Patterns' ) } + diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index ba3586301830c1..a79911efc1aa03 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -51,6 +51,7 @@ "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", "@wordpress/notices": "file:../notices", + "@wordpress/patterns": "file:../patterns", "@wordpress/plugins": "file:../plugins", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js index 4957beee030f2b..af10d27d5820ac 100644 --- a/packages/edit-site/src/components/block-editor/index.js +++ b/packages/edit-site/src/components/block-editor/index.js @@ -25,6 +25,7 @@ import { useResizeObserver, } from '@wordpress/compose'; import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks'; +import { PatternsMenuItems } from '@wordpress/patterns'; /** * Internal dependencies @@ -213,6 +214,7 @@ export default function BlockEditor() { } + ); } diff --git a/packages/editor/package.json b/packages/editor/package.json index 078a6587b35b2a..59cfc4d7961a37 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -52,6 +52,7 @@ "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", "@wordpress/notices": "file:../notices", + "@wordpress/patterns": "file:../patterns", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", "@wordpress/reusable-blocks": "file:../reusable-blocks", diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index 1cff19c7daae7f..0f13ce2090a53d 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -11,6 +11,7 @@ import { privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks'; +import { PatternsMenuItems } from '@wordpress/patterns'; import { store as noticesStore } from '@wordpress/notices'; /** @@ -131,6 +132,7 @@ export const ExperimentalEditorProvider = withRegistryProvider( > { children } + diff --git a/packages/patterns/.npmrc b/packages/patterns/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/patterns/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/patterns/package.json b/packages/patterns/package.json new file mode 100644 index 00000000000000..f3206f7eaa7739 --- /dev/null +++ b/packages/patterns/package.json @@ -0,0 +1,49 @@ +{ + "name": "@wordpress/patterns", + "version": "4.7.0", + "description": "Patterns utilities.", + "author": "The WordPress Contributors", + "license": "GPL-2.0-or-later", + "keywords": [ + "wordpress", + "gutenberg", + "patterns" + ], + "homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/packages/patterns/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/patterns" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "engines": { + "node": ">=12" + }, + "main": "build/index.js", + "module": "build-module/index.js", + "react-native": "src/index", + "sideEffects": [ + "{src,build,build-module}/{index.js,store/index.js}" + ], + "dependencies": { + "@wordpress/block-editor": "file:../block-editor", + "@wordpress/blocks": "file:../blocks", + "@wordpress/components": "file:../components", + "@wordpress/core-data": "file:../core-data", + "@wordpress/data": "file:../data", + "@wordpress/element": "file:../element", + "@wordpress/i18n": "file:../i18n", + "@wordpress/icons": "file:../icons", + "@wordpress/notices": "file:../notices", + "@wordpress/url": "file:../url" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/patterns/src/components/index.js b/packages/patterns/src/components/index.js new file mode 100644 index 00000000000000..9daf89003d2d8e --- /dev/null +++ b/packages/patterns/src/components/index.js @@ -0,0 +1 @@ +export { default as PatternsMenuItems } from './patterns-menu-items'; diff --git a/packages/patterns/src/components/patterns-menu-items/index.js b/packages/patterns/src/components/patterns-menu-items/index.js new file mode 100644 index 00000000000000..6719092c23e79f --- /dev/null +++ b/packages/patterns/src/components/patterns-menu-items/index.js @@ -0,0 +1,28 @@ +/** + * WordPress dependencies + */ +import { withSelect } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import PatternConvertButton from './pattern-convert-button'; + +function PatternsMenuItems( { clientIds, rootClientId } ) { + return ( + <> + + + ); +} + +export default withSelect( ( select ) => { + const { getSelectedBlockClientIds } = select( blockEditorStore ); + return { + clientIds: getSelectedBlockClientIds(), + }; +} )( PatternsMenuItems ); diff --git a/packages/patterns/src/components/patterns-menu-items/index.native.js b/packages/patterns/src/components/patterns-menu-items/index.native.js new file mode 100644 index 00000000000000..461f67a0a4bcbe --- /dev/null +++ b/packages/patterns/src/components/patterns-menu-items/index.native.js @@ -0,0 +1 @@ +export default () => null; diff --git a/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js b/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js new file mode 100644 index 00000000000000..ec542f1e74ac92 --- /dev/null +++ b/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js @@ -0,0 +1,116 @@ +/** + * WordPress dependencies + */ +import { BlockSettingsMenuControls } from '@wordpress/block-editor'; +import { useCallback, useState } from '@wordpress/element'; +import { + MenuItem, + Modal, + Button, + TextControl, + __experimentalHStack as HStack, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import { symbol } from '@wordpress/icons'; +import { useDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { store as noticesStore } from '@wordpress/notices'; + +/** + * Internal dependencies + */ +import { store } from '../../store'; + +/** + * Menu control to convert block(s) to patterns. + * + * @param {Object} props Component props. + * @param {string[]} props.clientIds Client ids of selected blocks. + * @return {import('@wordpress/element').WPComponent} The menu control or null. + */ +export default function PatternConvertButton( { clientIds } ) { + const [ isModalOpen, setIsModalOpen ] = useState( false ); + const [ title, setTitle ] = useState( '' ); + + const { __experimentalConvertBlocksToPattern: convertBlocksToPattern } = + useDispatch( store ); + + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + const onConvert = useCallback( + async function ( patternTitle ) { + try { + await convertBlocksToPattern( clientIds, patternTitle ); + createSuccessNotice( __( 'Pattern created.' ), { + type: 'snackbar', + } ); + } catch ( error ) { + createErrorNotice( error.message, { + type: 'snackbar', + } ); + } + }, + [ clientIds ] + ); + + return ( + + { ( { onClose } ) => ( + <> + { + setIsModalOpen( true ); + } } + > + { __( 'Create Pattern' ) } + + { isModalOpen && ( + { + setIsModalOpen( false ); + setTitle( '' ); + } } + overlayClassName="patterns-menu-items__convert-modal" + > +
{ + event.preventDefault(); + onConvert( title ); + setIsModalOpen( false ); + setTitle( '' ); + onClose(); + } } + > + + + + + + + + +
+
+ ) } + + ) } +
+ ); +} diff --git a/packages/patterns/src/components/patterns-menu-items/style.scss b/packages/patterns/src/components/patterns-menu-items/style.scss new file mode 100644 index 00000000000000..ddd2656dc7d41d --- /dev/null +++ b/packages/patterns/src/components/patterns-menu-items/style.scss @@ -0,0 +1,3 @@ +.patterns-menu-items__convert-modal { + z-index: z-index(".patterns-menu-items__convert-modal"); +} diff --git a/packages/patterns/src/index.js b/packages/patterns/src/index.js new file mode 100644 index 00000000000000..cf6bfc074cc058 --- /dev/null +++ b/packages/patterns/src/index.js @@ -0,0 +1,2 @@ +export { store } from './store'; +export * from './components'; diff --git a/packages/patterns/src/index.native.js b/packages/patterns/src/index.native.js new file mode 100644 index 00000000000000..2e29e8c63d8969 --- /dev/null +++ b/packages/patterns/src/index.native.js @@ -0,0 +1,7 @@ +/** + * WordPress dependencies + */ +import '@wordpress/core-data'; + +export { store } from './store'; +export * from './components'; diff --git a/packages/patterns/src/store/actions.js b/packages/patterns/src/store/actions.js new file mode 100644 index 00000000000000..5d49b402416967 --- /dev/null +++ b/packages/patterns/src/store/actions.js @@ -0,0 +1,30 @@ +/** + * WordPress dependencies + */ +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { serialize } from '@wordpress/blocks'; +import { __ } from '@wordpress/i18n'; + +/** + * Returns a generator converting one or more static blocks into a pattern. + * + * @param {string[]} clientIds The client IDs of the block to detach. + * @param {string} title Pattern title. + */ +export const __experimentalConvertBlocksToPattern = + ( clientIds, title ) => + async ( { registry } ) => { + const pattern = { + title: title || __( 'Untitled Pattern' ), + content: serialize( + registry + .select( blockEditorStore ) + .getBlocksByClientId( clientIds ) + ), + status: 'publish', + }; + + await registry + .dispatch( 'core' ) + .saveEntityRecord( 'postType', 'wp_block_pattern', pattern ); + }; diff --git a/packages/patterns/src/store/index.js b/packages/patterns/src/store/index.js new file mode 100644 index 00000000000000..b5463076465a11 --- /dev/null +++ b/packages/patterns/src/store/index.js @@ -0,0 +1,22 @@ +/** + * WordPress dependencies + */ +import { createReduxStore, register } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import * as actions from './actions'; + +const STORE_NAME = 'core/patterns'; + +/** + * Store definition for the patterns namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { actions } ); + +register( store ); diff --git a/packages/patterns/src/store/test/__snapshots__/actions.js.snap b/packages/patterns/src/store/test/__snapshots__/actions.js.snap new file mode 100644 index 00000000000000..b1a96d6c8aad13 --- /dev/null +++ b/packages/patterns/src/store/test/__snapshots__/actions.js.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Actions __experimentalConvertBlocksToPattern should convert a static block into a reusable block 1`] = ` +[ + { + "attributes": { + "ref": "new-id", + }, + "innerBlocks": [], + "isValid": true, + "name": "core/block", + }, +] +`; diff --git a/packages/patterns/src/store/test/actions.js b/packages/patterns/src/store/test/actions.js new file mode 100644 index 00000000000000..bc393209b29448 --- /dev/null +++ b/packages/patterns/src/store/test/actions.js @@ -0,0 +1,147 @@ +/** + * WordPress dependencies + */ +import { createRegistry } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { + store as blocksStore, + createBlock, + registerBlockType, + unregisterBlockType, +} from '@wordpress/blocks'; + +import { store as coreStore } from '@wordpress/core-data'; +import apiFetch from '@wordpress/api-fetch'; + +/** + * Internal dependencies + */ +import { store as patternsStore } from '../index'; + +jest.mock( '@wordpress/api-fetch', () => ( { + __esModule: true, + default: jest.fn(), +} ) ); + +function createRegistryWithStores() { + // Create a registry and register stores. + const registry = createRegistry(); + + registry.register( coreStore ); + registry.register( blockEditorStore ); + registry.register( patternsStore ); + registry.register( blocksStore ); + + // Register entity here instead of mocking API handlers for loadPostTypeEntities() + registry.dispatch( coreStore ).addEntities( [ + { + baseURL: '/wp/v2/reusable-blocks', + kind: 'postType', + name: 'wp_block', + label: 'Reusable blocks', + }, + ] ); + + return registry; +} + +describe( 'Actions', () => { + beforeAll( () => { + registerBlockType( 'core/test-block', { + title: 'Test block', + category: 'text', + save: () => null, + attributes: { + name: { type: 'string' }, + }, + } ); + + registerBlockType( 'core/block', { + title: 'Reusable block', + category: 'text', + save: () => null, + attributes: { + ref: { type: 'string' }, + }, + } ); + } ); + + afterAll( () => { + unregisterBlockType( 'core/test-block' ); + unregisterBlockType( 'core/block' ); + } ); + + describe( '__experimentalSetEditingReusableBlock', () => { + it( 'should flip the editing state', () => { + const registry = createRegistryWithStores(); + + registry + .dispatch( patternsStore ) + .__experimentalSetEditingReusableBlock( 3, true ); + expect( + registry + .select( patternsStore ) + .__experimentalIsEditingReusableBlock( 3 ) + ).toBe( true ); + + registry + .dispatch( patternsStore ) + .__experimentalSetEditingReusableBlock( 3, false ); + expect( + registry + .select( patternsStore ) + .__experimentalIsEditingReusableBlock( 3 ) + ).toBe( false ); + } ); + } ); + + describe( '__experimentalConvertBlocksToPattern', () => { + it( 'should convert a static block into a reusable block', async () => { + const staticBlock = createBlock( 'core/test-block', { + name: 'Big Bird', + } ); + + const registry = createRegistryWithStores(); + // Mock the api-fetch. + apiFetch.mockImplementation( async ( args ) => { + const { path, data } = args; + switch ( path ) { + case '/wp/v2/reusable-blocks': + return { + id: 'new-id', + ...data, + }; + default: + throw new Error( `unexpected API endpoint: ${ path }` ); + } + } ); + + registry.dispatch( blockEditorStore ).insertBlock( staticBlock ); + + await registry + .dispatch( patternsStore ) + .__experimentalConvertBlocksToPattern( [ + staticBlock.clientId, + ] ); + + // Check that blocks were converted to reusable. + const updatedBlocks = registry + .select( blockEditorStore ) + .getBlocks(); + + const newClientId = updatedBlocks[ 0 ].clientId; + + expect( updatedBlocks ).toHaveLength( 1 ); + + // Delete random clientId before matching with snapshot. + delete updatedBlocks[ 0 ].clientId; + expect( updatedBlocks ).toMatchSnapshot(); + + expect( + registry + .select( patternsStore ) + .__experimentalIsEditingReusableBlock( newClientId ) + ).toBe( true ); + } ); + } ); +} ); diff --git a/packages/patterns/src/store/test/selectors.js b/packages/patterns/src/store/test/selectors.js new file mode 100644 index 00000000000000..1e0dc01df63f9d --- /dev/null +++ b/packages/patterns/src/store/test/selectors.js @@ -0,0 +1,27 @@ +/** + * Internal dependencies + */ +import { __experimentalIsEditingReusableBlock } from '../selectors'; + +describe( '__experimentalIsEditingReusableBlock', () => { + it( 'gets the value for clientId', () => { + expect( + __experimentalIsEditingReusableBlock( + { isEditingReusableBlock: { 1: true } }, + 1 + ) + ).toBe( true ); + expect( + __experimentalIsEditingReusableBlock( + { isEditingReusableBlock: { 2: false } }, + 2 + ) + ).toBe( false ); + expect( + __experimentalIsEditingReusableBlock( + { isEditingReusableBlock: { 2: false } }, + 3 + ) + ).toBe( undefined ); + } ); +} ); diff --git a/packages/patterns/src/style.scss b/packages/patterns/src/style.scss new file mode 100644 index 00000000000000..e802c88215ae72 --- /dev/null +++ b/packages/patterns/src/style.scss @@ -0,0 +1 @@ +@import "./components/patterns-menu-items/style.scss" From 3930cb30c192098c15cfc5be9b4427a07b814c59 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 5 Apr 2023 14:18:22 +0300 Subject: [PATCH 02/23] Why not --- packages/block-directory/package.json | 1 + packages/block-library/package.json | 1 + packages/customize-widgets/package.json | 1 + packages/edit-widgets/package.json | 1 + packages/format-library/package.json | 1 + packages/react-native-editor/package.json | 1 + packages/reusable-blocks/package.json | 1 + packages/widgets/package.json | 1 + 8 files changed, 8 insertions(+) diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index fb2f88ca521190..0c79fb9d60a5c8 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -42,6 +42,7 @@ "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/notices": "file:../notices", + "@wordpress/patterns": "file:../pattern", "@wordpress/plugins": "file:../plugins", "@wordpress/url": "file:../url", "change-case": "^4.1.2" diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 9a34e8ae084fa7..63f75893d9d23c 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -52,6 +52,7 @@ "@wordpress/icons": "file:../icons", "@wordpress/keycodes": "file:../keycodes", "@wordpress/notices": "file:../notices", + "@wordpress/patterns": "file:../patterns", "@wordpress/primitives": "file:../primitives", "@wordpress/private-apis": "file:../private-apis", "@wordpress/reusable-blocks": "file:../reusable-blocks", diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index 67d871308c7712..12722518c209e1 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -41,6 +41,7 @@ "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts", "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", + "@wordpress/patterns": "file:../pattern", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", "@wordpress/widgets": "file:../widgets", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index ab89de70cdd2a8..21a9de7d61b4db 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -46,6 +46,7 @@ "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", "@wordpress/notices": "file:../notices", + "@wordpress/patterns": "file:../pattern", "@wordpress/plugins": "file:../plugins", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index d83e4fa214759d..03e4606ffffad1 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -35,6 +35,7 @@ "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", + "@wordpress/patterns": "file:../pattern", "@wordpress/rich-text": "file:../rich-text", "@wordpress/url": "file:../url" }, diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index a926ef425d07b6..a6e2a6039ca2c7 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -48,6 +48,7 @@ "@wordpress/element": "file:../element", "@wordpress/hooks": "file:../hooks", "@wordpress/i18n": "file:../i18n", + "@wordpress/patterns": "file:../pattern", "@wordpress/react-native-aztec": "file:../react-native-aztec", "@wordpress/react-native-bridge": "file:../react-native-bridge", "core-js": "^3.19.1", diff --git a/packages/reusable-blocks/package.json b/packages/reusable-blocks/package.json index d2b8dfadaec2e6..c5a5b7abf23341 100644 --- a/packages/reusable-blocks/package.json +++ b/packages/reusable-blocks/package.json @@ -37,6 +37,7 @@ "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/notices": "file:../notices", + "@wordpress/patterns": "file:../pattern", "@wordpress/url": "file:../url" }, "peerDependencies": { diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 0ef47d99473b2b..fa4631c770f465 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -32,6 +32,7 @@ "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/notices": "file:../notices", + "@wordpress/patterns": "file:../pattern", "classnames": "^2.3.1" }, "peerDependencies": { From cc20beb3370aee4f02caf99c93b5edbce92ae887 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 5 Apr 2023 15:27:23 +0300 Subject: [PATCH 03/23] Fixes from Enrico --- .../pattern-convert-button.js | 30 +++- packages/patterns/src/index.js | 1 - packages/patterns/src/store/actions.js | 30 ---- packages/patterns/src/store/index.js | 22 --- .../store/test/__snapshots__/actions.js.snap | 14 -- packages/patterns/src/store/test/actions.js | 147 ------------------ packages/patterns/src/store/test/selectors.js | 27 ---- 7 files changed, 22 insertions(+), 249 deletions(-) delete mode 100644 packages/patterns/src/store/actions.js delete mode 100644 packages/patterns/src/store/index.js delete mode 100644 packages/patterns/src/store/test/__snapshots__/actions.js.snap delete mode 100644 packages/patterns/src/store/test/actions.js delete mode 100644 packages/patterns/src/store/test/selectors.js diff --git a/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js b/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js index ec542f1e74ac92..ff9d4745cc4183 100644 --- a/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js +++ b/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js @@ -1,7 +1,11 @@ /** * WordPress dependencies */ -import { BlockSettingsMenuControls } from '@wordpress/block-editor'; +import { + BlockSettingsMenuControls, + store as blockEditorStore, +} from '@wordpress/block-editor'; +import { serialize } from '@wordpress/blocks'; import { useCallback, useState } from '@wordpress/element'; import { MenuItem, @@ -16,11 +20,6 @@ import { useDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; -/** - * Internal dependencies - */ -import { store } from '../../store'; - /** * Menu control to convert block(s) to patterns. * @@ -32,8 +31,23 @@ export default function PatternConvertButton( { clientIds } ) { const [ isModalOpen, setIsModalOpen ] = useState( false ); const [ title, setTitle ] = useState( '' ); - const { __experimentalConvertBlocksToPattern: convertBlocksToPattern } = - useDispatch( store ); + const convertBlocksToPattern = + ( clientIDs, _title ) => + async ( { registry } ) => { + const pattern = { + title: _title || __( 'Untitled Pattern' ), + content: serialize( + registry + .select( blockEditorStore ) + .getBlocksByClientId( clientIDs ) + ), + status: 'publish', + }; + + await registry + .dispatch( 'core' ) + .saveEntityRecord( 'postType', 'wp_block_pattern', pattern ); + }; const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); diff --git a/packages/patterns/src/index.js b/packages/patterns/src/index.js index cf6bfc074cc058..07635cbbc8e7a2 100644 --- a/packages/patterns/src/index.js +++ b/packages/patterns/src/index.js @@ -1,2 +1 @@ -export { store } from './store'; export * from './components'; diff --git a/packages/patterns/src/store/actions.js b/packages/patterns/src/store/actions.js deleted file mode 100644 index 5d49b402416967..00000000000000 --- a/packages/patterns/src/store/actions.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * WordPress dependencies - */ -import { store as blockEditorStore } from '@wordpress/block-editor'; -import { serialize } from '@wordpress/blocks'; -import { __ } from '@wordpress/i18n'; - -/** - * Returns a generator converting one or more static blocks into a pattern. - * - * @param {string[]} clientIds The client IDs of the block to detach. - * @param {string} title Pattern title. - */ -export const __experimentalConvertBlocksToPattern = - ( clientIds, title ) => - async ( { registry } ) => { - const pattern = { - title: title || __( 'Untitled Pattern' ), - content: serialize( - registry - .select( blockEditorStore ) - .getBlocksByClientId( clientIds ) - ), - status: 'publish', - }; - - await registry - .dispatch( 'core' ) - .saveEntityRecord( 'postType', 'wp_block_pattern', pattern ); - }; diff --git a/packages/patterns/src/store/index.js b/packages/patterns/src/store/index.js deleted file mode 100644 index b5463076465a11..00000000000000 --- a/packages/patterns/src/store/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * WordPress dependencies - */ -import { createReduxStore, register } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import * as actions from './actions'; - -const STORE_NAME = 'core/patterns'; - -/** - * Store definition for the patterns namespace. - * - * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore - * - * @type {Object} - */ -export const store = createReduxStore( STORE_NAME, { actions } ); - -register( store ); diff --git a/packages/patterns/src/store/test/__snapshots__/actions.js.snap b/packages/patterns/src/store/test/__snapshots__/actions.js.snap deleted file mode 100644 index b1a96d6c8aad13..00000000000000 --- a/packages/patterns/src/store/test/__snapshots__/actions.js.snap +++ /dev/null @@ -1,14 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Actions __experimentalConvertBlocksToPattern should convert a static block into a reusable block 1`] = ` -[ - { - "attributes": { - "ref": "new-id", - }, - "innerBlocks": [], - "isValid": true, - "name": "core/block", - }, -] -`; diff --git a/packages/patterns/src/store/test/actions.js b/packages/patterns/src/store/test/actions.js deleted file mode 100644 index bc393209b29448..00000000000000 --- a/packages/patterns/src/store/test/actions.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * WordPress dependencies - */ -import { createRegistry } from '@wordpress/data'; -import { store as blockEditorStore } from '@wordpress/block-editor'; -import { - store as blocksStore, - createBlock, - registerBlockType, - unregisterBlockType, -} from '@wordpress/blocks'; - -import { store as coreStore } from '@wordpress/core-data'; -import apiFetch from '@wordpress/api-fetch'; - -/** - * Internal dependencies - */ -import { store as patternsStore } from '../index'; - -jest.mock( '@wordpress/api-fetch', () => ( { - __esModule: true, - default: jest.fn(), -} ) ); - -function createRegistryWithStores() { - // Create a registry and register stores. - const registry = createRegistry(); - - registry.register( coreStore ); - registry.register( blockEditorStore ); - registry.register( patternsStore ); - registry.register( blocksStore ); - - // Register entity here instead of mocking API handlers for loadPostTypeEntities() - registry.dispatch( coreStore ).addEntities( [ - { - baseURL: '/wp/v2/reusable-blocks', - kind: 'postType', - name: 'wp_block', - label: 'Reusable blocks', - }, - ] ); - - return registry; -} - -describe( 'Actions', () => { - beforeAll( () => { - registerBlockType( 'core/test-block', { - title: 'Test block', - category: 'text', - save: () => null, - attributes: { - name: { type: 'string' }, - }, - } ); - - registerBlockType( 'core/block', { - title: 'Reusable block', - category: 'text', - save: () => null, - attributes: { - ref: { type: 'string' }, - }, - } ); - } ); - - afterAll( () => { - unregisterBlockType( 'core/test-block' ); - unregisterBlockType( 'core/block' ); - } ); - - describe( '__experimentalSetEditingReusableBlock', () => { - it( 'should flip the editing state', () => { - const registry = createRegistryWithStores(); - - registry - .dispatch( patternsStore ) - .__experimentalSetEditingReusableBlock( 3, true ); - expect( - registry - .select( patternsStore ) - .__experimentalIsEditingReusableBlock( 3 ) - ).toBe( true ); - - registry - .dispatch( patternsStore ) - .__experimentalSetEditingReusableBlock( 3, false ); - expect( - registry - .select( patternsStore ) - .__experimentalIsEditingReusableBlock( 3 ) - ).toBe( false ); - } ); - } ); - - describe( '__experimentalConvertBlocksToPattern', () => { - it( 'should convert a static block into a reusable block', async () => { - const staticBlock = createBlock( 'core/test-block', { - name: 'Big Bird', - } ); - - const registry = createRegistryWithStores(); - // Mock the api-fetch. - apiFetch.mockImplementation( async ( args ) => { - const { path, data } = args; - switch ( path ) { - case '/wp/v2/reusable-blocks': - return { - id: 'new-id', - ...data, - }; - default: - throw new Error( `unexpected API endpoint: ${ path }` ); - } - } ); - - registry.dispatch( blockEditorStore ).insertBlock( staticBlock ); - - await registry - .dispatch( patternsStore ) - .__experimentalConvertBlocksToPattern( [ - staticBlock.clientId, - ] ); - - // Check that blocks were converted to reusable. - const updatedBlocks = registry - .select( blockEditorStore ) - .getBlocks(); - - const newClientId = updatedBlocks[ 0 ].clientId; - - expect( updatedBlocks ).toHaveLength( 1 ); - - // Delete random clientId before matching with snapshot. - delete updatedBlocks[ 0 ].clientId; - expect( updatedBlocks ).toMatchSnapshot(); - - expect( - registry - .select( patternsStore ) - .__experimentalIsEditingReusableBlock( newClientId ) - ).toBe( true ); - } ); - } ); -} ); diff --git a/packages/patterns/src/store/test/selectors.js b/packages/patterns/src/store/test/selectors.js deleted file mode 100644 index 1e0dc01df63f9d..00000000000000 --- a/packages/patterns/src/store/test/selectors.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Internal dependencies - */ -import { __experimentalIsEditingReusableBlock } from '../selectors'; - -describe( '__experimentalIsEditingReusableBlock', () => { - it( 'gets the value for clientId', () => { - expect( - __experimentalIsEditingReusableBlock( - { isEditingReusableBlock: { 1: true } }, - 1 - ) - ).toBe( true ); - expect( - __experimentalIsEditingReusableBlock( - { isEditingReusableBlock: { 2: false } }, - 2 - ) - ).toBe( false ); - expect( - __experimentalIsEditingReusableBlock( - { isEditingReusableBlock: { 2: false } }, - 3 - ) - ).toBe( undefined ); - } ); -} ); From ca49767c0d9fb2e520ee47d6b6721a916824105e Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 5 Apr 2023 15:27:23 +0300 Subject: [PATCH 04/23] Revert "Fixes from Enrico" This reverts commit 355b4f369c158e7bb0a634528bd033298d07818a. --- .../pattern-convert-button.js | 30 +--- packages/patterns/src/index.js | 1 + packages/patterns/src/store/actions.js | 30 ++++ packages/patterns/src/store/index.js | 22 +++ .../store/test/__snapshots__/actions.js.snap | 14 ++ packages/patterns/src/store/test/actions.js | 147 ++++++++++++++++++ packages/patterns/src/store/test/selectors.js | 27 ++++ 7 files changed, 249 insertions(+), 22 deletions(-) create mode 100644 packages/patterns/src/store/actions.js create mode 100644 packages/patterns/src/store/index.js create mode 100644 packages/patterns/src/store/test/__snapshots__/actions.js.snap create mode 100644 packages/patterns/src/store/test/actions.js create mode 100644 packages/patterns/src/store/test/selectors.js diff --git a/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js b/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js index ff9d4745cc4183..ec542f1e74ac92 100644 --- a/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js +++ b/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js @@ -1,11 +1,7 @@ /** * WordPress dependencies */ -import { - BlockSettingsMenuControls, - store as blockEditorStore, -} from '@wordpress/block-editor'; -import { serialize } from '@wordpress/blocks'; +import { BlockSettingsMenuControls } from '@wordpress/block-editor'; import { useCallback, useState } from '@wordpress/element'; import { MenuItem, @@ -20,6 +16,11 @@ import { useDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; +/** + * Internal dependencies + */ +import { store } from '../../store'; + /** * Menu control to convert block(s) to patterns. * @@ -31,23 +32,8 @@ export default function PatternConvertButton( { clientIds } ) { const [ isModalOpen, setIsModalOpen ] = useState( false ); const [ title, setTitle ] = useState( '' ); - const convertBlocksToPattern = - ( clientIDs, _title ) => - async ( { registry } ) => { - const pattern = { - title: _title || __( 'Untitled Pattern' ), - content: serialize( - registry - .select( blockEditorStore ) - .getBlocksByClientId( clientIDs ) - ), - status: 'publish', - }; - - await registry - .dispatch( 'core' ) - .saveEntityRecord( 'postType', 'wp_block_pattern', pattern ); - }; + const { __experimentalConvertBlocksToPattern: convertBlocksToPattern } = + useDispatch( store ); const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); diff --git a/packages/patterns/src/index.js b/packages/patterns/src/index.js index 07635cbbc8e7a2..cf6bfc074cc058 100644 --- a/packages/patterns/src/index.js +++ b/packages/patterns/src/index.js @@ -1 +1,2 @@ +export { store } from './store'; export * from './components'; diff --git a/packages/patterns/src/store/actions.js b/packages/patterns/src/store/actions.js new file mode 100644 index 00000000000000..5d49b402416967 --- /dev/null +++ b/packages/patterns/src/store/actions.js @@ -0,0 +1,30 @@ +/** + * WordPress dependencies + */ +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { serialize } from '@wordpress/blocks'; +import { __ } from '@wordpress/i18n'; + +/** + * Returns a generator converting one or more static blocks into a pattern. + * + * @param {string[]} clientIds The client IDs of the block to detach. + * @param {string} title Pattern title. + */ +export const __experimentalConvertBlocksToPattern = + ( clientIds, title ) => + async ( { registry } ) => { + const pattern = { + title: title || __( 'Untitled Pattern' ), + content: serialize( + registry + .select( blockEditorStore ) + .getBlocksByClientId( clientIds ) + ), + status: 'publish', + }; + + await registry + .dispatch( 'core' ) + .saveEntityRecord( 'postType', 'wp_block_pattern', pattern ); + }; diff --git a/packages/patterns/src/store/index.js b/packages/patterns/src/store/index.js new file mode 100644 index 00000000000000..b5463076465a11 --- /dev/null +++ b/packages/patterns/src/store/index.js @@ -0,0 +1,22 @@ +/** + * WordPress dependencies + */ +import { createReduxStore, register } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import * as actions from './actions'; + +const STORE_NAME = 'core/patterns'; + +/** + * Store definition for the patterns namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { actions } ); + +register( store ); diff --git a/packages/patterns/src/store/test/__snapshots__/actions.js.snap b/packages/patterns/src/store/test/__snapshots__/actions.js.snap new file mode 100644 index 00000000000000..b1a96d6c8aad13 --- /dev/null +++ b/packages/patterns/src/store/test/__snapshots__/actions.js.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Actions __experimentalConvertBlocksToPattern should convert a static block into a reusable block 1`] = ` +[ + { + "attributes": { + "ref": "new-id", + }, + "innerBlocks": [], + "isValid": true, + "name": "core/block", + }, +] +`; diff --git a/packages/patterns/src/store/test/actions.js b/packages/patterns/src/store/test/actions.js new file mode 100644 index 00000000000000..bc393209b29448 --- /dev/null +++ b/packages/patterns/src/store/test/actions.js @@ -0,0 +1,147 @@ +/** + * WordPress dependencies + */ +import { createRegistry } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { + store as blocksStore, + createBlock, + registerBlockType, + unregisterBlockType, +} from '@wordpress/blocks'; + +import { store as coreStore } from '@wordpress/core-data'; +import apiFetch from '@wordpress/api-fetch'; + +/** + * Internal dependencies + */ +import { store as patternsStore } from '../index'; + +jest.mock( '@wordpress/api-fetch', () => ( { + __esModule: true, + default: jest.fn(), +} ) ); + +function createRegistryWithStores() { + // Create a registry and register stores. + const registry = createRegistry(); + + registry.register( coreStore ); + registry.register( blockEditorStore ); + registry.register( patternsStore ); + registry.register( blocksStore ); + + // Register entity here instead of mocking API handlers for loadPostTypeEntities() + registry.dispatch( coreStore ).addEntities( [ + { + baseURL: '/wp/v2/reusable-blocks', + kind: 'postType', + name: 'wp_block', + label: 'Reusable blocks', + }, + ] ); + + return registry; +} + +describe( 'Actions', () => { + beforeAll( () => { + registerBlockType( 'core/test-block', { + title: 'Test block', + category: 'text', + save: () => null, + attributes: { + name: { type: 'string' }, + }, + } ); + + registerBlockType( 'core/block', { + title: 'Reusable block', + category: 'text', + save: () => null, + attributes: { + ref: { type: 'string' }, + }, + } ); + } ); + + afterAll( () => { + unregisterBlockType( 'core/test-block' ); + unregisterBlockType( 'core/block' ); + } ); + + describe( '__experimentalSetEditingReusableBlock', () => { + it( 'should flip the editing state', () => { + const registry = createRegistryWithStores(); + + registry + .dispatch( patternsStore ) + .__experimentalSetEditingReusableBlock( 3, true ); + expect( + registry + .select( patternsStore ) + .__experimentalIsEditingReusableBlock( 3 ) + ).toBe( true ); + + registry + .dispatch( patternsStore ) + .__experimentalSetEditingReusableBlock( 3, false ); + expect( + registry + .select( patternsStore ) + .__experimentalIsEditingReusableBlock( 3 ) + ).toBe( false ); + } ); + } ); + + describe( '__experimentalConvertBlocksToPattern', () => { + it( 'should convert a static block into a reusable block', async () => { + const staticBlock = createBlock( 'core/test-block', { + name: 'Big Bird', + } ); + + const registry = createRegistryWithStores(); + // Mock the api-fetch. + apiFetch.mockImplementation( async ( args ) => { + const { path, data } = args; + switch ( path ) { + case '/wp/v2/reusable-blocks': + return { + id: 'new-id', + ...data, + }; + default: + throw new Error( `unexpected API endpoint: ${ path }` ); + } + } ); + + registry.dispatch( blockEditorStore ).insertBlock( staticBlock ); + + await registry + .dispatch( patternsStore ) + .__experimentalConvertBlocksToPattern( [ + staticBlock.clientId, + ] ); + + // Check that blocks were converted to reusable. + const updatedBlocks = registry + .select( blockEditorStore ) + .getBlocks(); + + const newClientId = updatedBlocks[ 0 ].clientId; + + expect( updatedBlocks ).toHaveLength( 1 ); + + // Delete random clientId before matching with snapshot. + delete updatedBlocks[ 0 ].clientId; + expect( updatedBlocks ).toMatchSnapshot(); + + expect( + registry + .select( patternsStore ) + .__experimentalIsEditingReusableBlock( newClientId ) + ).toBe( true ); + } ); + } ); +} ); diff --git a/packages/patterns/src/store/test/selectors.js b/packages/patterns/src/store/test/selectors.js new file mode 100644 index 00000000000000..1e0dc01df63f9d --- /dev/null +++ b/packages/patterns/src/store/test/selectors.js @@ -0,0 +1,27 @@ +/** + * Internal dependencies + */ +import { __experimentalIsEditingReusableBlock } from '../selectors'; + +describe( '__experimentalIsEditingReusableBlock', () => { + it( 'gets the value for clientId', () => { + expect( + __experimentalIsEditingReusableBlock( + { isEditingReusableBlock: { 1: true } }, + 1 + ) + ).toBe( true ); + expect( + __experimentalIsEditingReusableBlock( + { isEditingReusableBlock: { 2: false } }, + 2 + ) + ).toBe( false ); + expect( + __experimentalIsEditingReusableBlock( + { isEditingReusableBlock: { 2: false } }, + 3 + ) + ).toBe( undefined ); + } ); +} ); From 47d264e2e72859ce307f3d9184433579dbad8263 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 5 Apr 2023 15:40:29 +0300 Subject: [PATCH 05/23] Props @mykola --- packages/patterns/src/store/index.js | 10 +- packages/patterns/src/store/reducer.js | 19 +++ packages/patterns/src/store/selectors.js | 10 ++ .../store/test/__snapshots__/actions.js.snap | 14 -- packages/patterns/src/store/test/actions.js | 147 ------------------ packages/patterns/src/store/test/selectors.js | 27 ---- 6 files changed, 37 insertions(+), 190 deletions(-) create mode 100644 packages/patterns/src/store/reducer.js create mode 100644 packages/patterns/src/store/selectors.js delete mode 100644 packages/patterns/src/store/test/__snapshots__/actions.js.snap delete mode 100644 packages/patterns/src/store/test/actions.js delete mode 100644 packages/patterns/src/store/test/selectors.js diff --git a/packages/patterns/src/store/index.js b/packages/patterns/src/store/index.js index b5463076465a11..0d3f8c37184a0c 100644 --- a/packages/patterns/src/store/index.js +++ b/packages/patterns/src/store/index.js @@ -7,16 +7,22 @@ import { createReduxStore, register } from '@wordpress/data'; * Internal dependencies */ import * as actions from './actions'; +import reducer from './reducer'; +import * as selectors from './selectors'; const STORE_NAME = 'core/patterns'; /** - * Store definition for the patterns namespace. + * Store definition for the reusable blocks namespace. * * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore * * @type {Object} */ -export const store = createReduxStore( STORE_NAME, { actions } ); +export const store = createReduxStore( STORE_NAME, { + actions, + reducer, + selectors, +} ); register( store ); diff --git a/packages/patterns/src/store/reducer.js b/packages/patterns/src/store/reducer.js new file mode 100644 index 00000000000000..b74cd29f55dc4d --- /dev/null +++ b/packages/patterns/src/store/reducer.js @@ -0,0 +1,19 @@ +/** + * WordPress dependencies + */ +import { combineReducers } from '@wordpress/data'; + +export function isEditingPattern( state = {}, action ) { + if ( action?.type === 'SET_EDITING_PATTERN' ) { + return { + ...state, + [ action.clientId ]: action.isEditing, + }; + } + + return state; +} + +export default combineReducers( { + isEditingPattern, +} ); diff --git a/packages/patterns/src/store/selectors.js b/packages/patterns/src/store/selectors.js new file mode 100644 index 00000000000000..f105cba589ea46 --- /dev/null +++ b/packages/patterns/src/store/selectors.js @@ -0,0 +1,10 @@ +/** + * Returns true if reusable block is in the editing state. + * + * @param {Object} state Global application state. + * @param {number} clientId the clientID of the block. + * @return {boolean} Whether the reusable block is in the editing state. + */ +export function __experimentalIsEditingPatterns( state, clientId ) { + return state.isEditingPatterns[ clientId ]; +} diff --git a/packages/patterns/src/store/test/__snapshots__/actions.js.snap b/packages/patterns/src/store/test/__snapshots__/actions.js.snap deleted file mode 100644 index b1a96d6c8aad13..00000000000000 --- a/packages/patterns/src/store/test/__snapshots__/actions.js.snap +++ /dev/null @@ -1,14 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Actions __experimentalConvertBlocksToPattern should convert a static block into a reusable block 1`] = ` -[ - { - "attributes": { - "ref": "new-id", - }, - "innerBlocks": [], - "isValid": true, - "name": "core/block", - }, -] -`; diff --git a/packages/patterns/src/store/test/actions.js b/packages/patterns/src/store/test/actions.js deleted file mode 100644 index bc393209b29448..00000000000000 --- a/packages/patterns/src/store/test/actions.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * WordPress dependencies - */ -import { createRegistry } from '@wordpress/data'; -import { store as blockEditorStore } from '@wordpress/block-editor'; -import { - store as blocksStore, - createBlock, - registerBlockType, - unregisterBlockType, -} from '@wordpress/blocks'; - -import { store as coreStore } from '@wordpress/core-data'; -import apiFetch from '@wordpress/api-fetch'; - -/** - * Internal dependencies - */ -import { store as patternsStore } from '../index'; - -jest.mock( '@wordpress/api-fetch', () => ( { - __esModule: true, - default: jest.fn(), -} ) ); - -function createRegistryWithStores() { - // Create a registry and register stores. - const registry = createRegistry(); - - registry.register( coreStore ); - registry.register( blockEditorStore ); - registry.register( patternsStore ); - registry.register( blocksStore ); - - // Register entity here instead of mocking API handlers for loadPostTypeEntities() - registry.dispatch( coreStore ).addEntities( [ - { - baseURL: '/wp/v2/reusable-blocks', - kind: 'postType', - name: 'wp_block', - label: 'Reusable blocks', - }, - ] ); - - return registry; -} - -describe( 'Actions', () => { - beforeAll( () => { - registerBlockType( 'core/test-block', { - title: 'Test block', - category: 'text', - save: () => null, - attributes: { - name: { type: 'string' }, - }, - } ); - - registerBlockType( 'core/block', { - title: 'Reusable block', - category: 'text', - save: () => null, - attributes: { - ref: { type: 'string' }, - }, - } ); - } ); - - afterAll( () => { - unregisterBlockType( 'core/test-block' ); - unregisterBlockType( 'core/block' ); - } ); - - describe( '__experimentalSetEditingReusableBlock', () => { - it( 'should flip the editing state', () => { - const registry = createRegistryWithStores(); - - registry - .dispatch( patternsStore ) - .__experimentalSetEditingReusableBlock( 3, true ); - expect( - registry - .select( patternsStore ) - .__experimentalIsEditingReusableBlock( 3 ) - ).toBe( true ); - - registry - .dispatch( patternsStore ) - .__experimentalSetEditingReusableBlock( 3, false ); - expect( - registry - .select( patternsStore ) - .__experimentalIsEditingReusableBlock( 3 ) - ).toBe( false ); - } ); - } ); - - describe( '__experimentalConvertBlocksToPattern', () => { - it( 'should convert a static block into a reusable block', async () => { - const staticBlock = createBlock( 'core/test-block', { - name: 'Big Bird', - } ); - - const registry = createRegistryWithStores(); - // Mock the api-fetch. - apiFetch.mockImplementation( async ( args ) => { - const { path, data } = args; - switch ( path ) { - case '/wp/v2/reusable-blocks': - return { - id: 'new-id', - ...data, - }; - default: - throw new Error( `unexpected API endpoint: ${ path }` ); - } - } ); - - registry.dispatch( blockEditorStore ).insertBlock( staticBlock ); - - await registry - .dispatch( patternsStore ) - .__experimentalConvertBlocksToPattern( [ - staticBlock.clientId, - ] ); - - // Check that blocks were converted to reusable. - const updatedBlocks = registry - .select( blockEditorStore ) - .getBlocks(); - - const newClientId = updatedBlocks[ 0 ].clientId; - - expect( updatedBlocks ).toHaveLength( 1 ); - - // Delete random clientId before matching with snapshot. - delete updatedBlocks[ 0 ].clientId; - expect( updatedBlocks ).toMatchSnapshot(); - - expect( - registry - .select( patternsStore ) - .__experimentalIsEditingReusableBlock( newClientId ) - ).toBe( true ); - } ); - } ); -} ); diff --git a/packages/patterns/src/store/test/selectors.js b/packages/patterns/src/store/test/selectors.js deleted file mode 100644 index 1e0dc01df63f9d..00000000000000 --- a/packages/patterns/src/store/test/selectors.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Internal dependencies - */ -import { __experimentalIsEditingReusableBlock } from '../selectors'; - -describe( '__experimentalIsEditingReusableBlock', () => { - it( 'gets the value for clientId', () => { - expect( - __experimentalIsEditingReusableBlock( - { isEditingReusableBlock: { 1: true } }, - 1 - ) - ).toBe( true ); - expect( - __experimentalIsEditingReusableBlock( - { isEditingReusableBlock: { 2: false } }, - 2 - ) - ).toBe( false ); - expect( - __experimentalIsEditingReusableBlock( - { isEditingReusableBlock: { 2: false } }, - 3 - ) - ).toBe( undefined ); - } ); -} ); From b78ed57595b9d6afd488c387d83dd9d410a13244 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 5 Apr 2023 15:46:59 +0300 Subject: [PATCH 06/23] reducer should be empty --- packages/patterns/src/store/reducer.js | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/packages/patterns/src/store/reducer.js b/packages/patterns/src/store/reducer.js index b74cd29f55dc4d..841b6140ba2ed8 100644 --- a/packages/patterns/src/store/reducer.js +++ b/packages/patterns/src/store/reducer.js @@ -3,17 +3,4 @@ */ import { combineReducers } from '@wordpress/data'; -export function isEditingPattern( state = {}, action ) { - if ( action?.type === 'SET_EDITING_PATTERN' ) { - return { - ...state, - [ action.clientId ]: action.isEditing, - }; - } - - return state; -} - -export default combineReducers( { - isEditingPattern, -} ); +export default combineReducers( {} ); From 16742724357a8f0d7d22bd96d9928fa3d6ba0c18 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Wed, 5 Apr 2023 15:18:30 +0200 Subject: [PATCH 07/23] Fix stylesheet dependency. --- lib/client-assets.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/client-assets.php b/lib/client-assets.php index 2dd64a1e82a768..d02c968614f206 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -277,7 +277,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-editor', gutenberg_url( 'build/editor/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-reusable-blocks' ), + array( 'wp-components', 'wp-block-editor', 'wp-reusable-blocks', 'wp-patterns' ), $version ); $styles->add_data( 'wp-editor', 'rtl', 'replace' ); @@ -327,6 +327,7 @@ function gutenberg_register_packages_styles( $styles ) { 'wp-reset-editor-styles', 'wp-block-library', 'wp-reusable-blocks', + 'wp-patterns', // Until #37466, we can't specifically add them as editor styles yet, // so we must hard-code it here as a dependency. 'wp-block-editor-content', From 8a06aa28ce46f00121d5a914bf9e0b0caded89c7 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 09:34:42 +0300 Subject: [PATCH 08/23] rename file --- lib/compat/wordpress-6.3/{post.php => user-block-patterns.php} | 0 lib/load.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/compat/wordpress-6.3/{post.php => user-block-patterns.php} (100%) diff --git a/lib/compat/wordpress-6.3/post.php b/lib/compat/wordpress-6.3/user-block-patterns.php similarity index 100% rename from lib/compat/wordpress-6.3/post.php rename to lib/compat/wordpress-6.3/user-block-patterns.php diff --git a/lib/load.php b/lib/load.php index a8b39bd2ee6387..a6a2d33d435ed7 100644 --- a/lib/load.php +++ b/lib/load.php @@ -50,7 +50,7 @@ function gutenberg_is_experiment_enabled( $name ) { require_once __DIR__ . '/compat/wordpress-6.3/rest-api.php'; require_once __DIR__ . '/compat/wordpress-6.3/theme-previews.php'; require_once __DIR__ . '/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php'; - require_once __DIR__ . '/compat/wordpress-6.3/post.php'; + require_once __DIR__ . '/compat/wordpress-6.3/user-block-patterns.php'; // Experimental. if ( ! class_exists( 'WP_Rest_Customizer_Nonces' ) ) { From 0a1f672709e9edf74829fa38f46d5cb4a9101de5 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 09:49:11 +0300 Subject: [PATCH 09/23] Register user-created patterns --- .../wordpress-6.3/user-block-patterns.php | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/lib/compat/wordpress-6.3/user-block-patterns.php b/lib/compat/wordpress-6.3/user-block-patterns.php index 384c38fa067e41..56cccc88be9472 100644 --- a/lib/compat/wordpress-6.3/user-block-patterns.php +++ b/lib/compat/wordpress-6.3/user-block-patterns.php @@ -72,3 +72,43 @@ function gutenberg_create_initial_post_types() { ); } add_action( 'init', 'gutenberg_create_initial_post_types' ); + +/** + * Registers user-created block patterns. + */ +function gutenberg_register_user_block_patterns() { + // Get posts from the wp_block_pattern post type. + $posts = get_posts( + array( + 'post_type' => 'wp_block_pattern', + 'post_status' => 'publish', + 'posts_per_page' => -1, + ) + ); + + if ( empty( $posts ) ) { + return; + } + + register_block_pattern_category( + 'user', + array( + 'label' => _x( 'User patterns', 'Block pattern category' ), + 'description' => __( 'Patterns that were created by users on this site.' ), + ) + ); + + // Register each post as a block pattern. + foreach ( $posts as $post ) { + register_block_pattern( + 'wp-block-pattern/' . $post->post_name, + array( + 'title' => $post->post_title, + 'description' => $post->post_excerpt, + 'content' => $post->post_content, + 'categories' => array( 'user' ), + ) + ); + } +} +add_action( 'init', 'gutenberg_register_user_block_patterns' ); From df8695a6b7c94a8d3ed4bb5a65195976fde67b5e Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 09:57:02 +0300 Subject: [PATCH 10/23] PHP cleanup --- ...ass-gutenberg-rest-patterns-controller.php | 34 +++++++------------ .../wordpress-6.3/user-block-patterns.php | 25 +++++--------- 2 files changed, 21 insertions(+), 38 deletions(-) diff --git a/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php b/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php index 0c3137d52a621e..09a30f88797d55 100644 --- a/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php +++ b/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php @@ -1,31 +1,25 @@ __( 'Pattern scheduled.' ), 'item_updated' => __( 'Pattern updated.' ), ), - 'public' => true, + 'public' => false, '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ 'show_ui' => true, - 'show_in_menu' => true, + 'show_in_menu' => false, 'rewrite' => false, 'show_in_rest' => true, 'rest_base' => 'patterns', @@ -71,7 +62,7 @@ function gutenberg_create_initial_post_types() { ) ); } -add_action( 'init', 'gutenberg_create_initial_post_types' ); +add_action( 'init', 'gutenberg_create_wp_block_pattern_post_type' ); /** * Registers user-created block patterns. @@ -86,10 +77,12 @@ function gutenberg_register_user_block_patterns() { ) ); + // Bail if there are no posts. if ( empty( $posts ) ) { return; } + // Register the user category. register_block_pattern_category( 'user', array( From 9a500cbc1dcd550b5a574791316d48e2a709afec Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 10:13:29 +0300 Subject: [PATCH 11/23] cleanup package.json files --- packages/block-directory/package.json | 1 - packages/block-library/package.json | 1 - packages/customize-widgets/package.json | 1 - packages/edit-post/package.json | 1 - packages/edit-widgets/package.json | 1 - packages/format-library/package.json | 1 - packages/react-native-editor/package.json | 1 - packages/reusable-blocks/package.json | 1 - packages/widgets/package.json | 1 - 9 files changed, 9 deletions(-) diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index 0c79fb9d60a5c8..fb2f88ca521190 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -42,7 +42,6 @@ "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/notices": "file:../notices", - "@wordpress/patterns": "file:../pattern", "@wordpress/plugins": "file:../plugins", "@wordpress/url": "file:../url", "change-case": "^4.1.2" diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 63f75893d9d23c..9a34e8ae084fa7 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -52,7 +52,6 @@ "@wordpress/icons": "file:../icons", "@wordpress/keycodes": "file:../keycodes", "@wordpress/notices": "file:../notices", - "@wordpress/patterns": "file:../patterns", "@wordpress/primitives": "file:../primitives", "@wordpress/private-apis": "file:../private-apis", "@wordpress/reusable-blocks": "file:../reusable-blocks", diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index 12722518c209e1..67d871308c7712 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -41,7 +41,6 @@ "@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts", "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", - "@wordpress/patterns": "file:../pattern", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", "@wordpress/widgets": "file:../widgets", diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 97a6b1f8a42058..1df3f566ab9d54 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -50,7 +50,6 @@ "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", "@wordpress/notices": "file:../notices", - "@wordpress/patterns": "file:../patterns", "@wordpress/plugins": "file:../plugins", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index 21a9de7d61b4db..ab89de70cdd2a8 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -46,7 +46,6 @@ "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", "@wordpress/notices": "file:../notices", - "@wordpress/patterns": "file:../pattern", "@wordpress/plugins": "file:../plugins", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index 03e4606ffffad1..d83e4fa214759d 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -35,7 +35,6 @@ "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", - "@wordpress/patterns": "file:../pattern", "@wordpress/rich-text": "file:../rich-text", "@wordpress/url": "file:../url" }, diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index a6e2a6039ca2c7..a926ef425d07b6 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -48,7 +48,6 @@ "@wordpress/element": "file:../element", "@wordpress/hooks": "file:../hooks", "@wordpress/i18n": "file:../i18n", - "@wordpress/patterns": "file:../pattern", "@wordpress/react-native-aztec": "file:../react-native-aztec", "@wordpress/react-native-bridge": "file:../react-native-bridge", "core-js": "^3.19.1", diff --git a/packages/reusable-blocks/package.json b/packages/reusable-blocks/package.json index c5a5b7abf23341..d2b8dfadaec2e6 100644 --- a/packages/reusable-blocks/package.json +++ b/packages/reusable-blocks/package.json @@ -37,7 +37,6 @@ "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/notices": "file:../notices", - "@wordpress/patterns": "file:../pattern", "@wordpress/url": "file:../url" }, "peerDependencies": { diff --git a/packages/widgets/package.json b/packages/widgets/package.json index fa4631c770f465..0ef47d99473b2b 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -32,7 +32,6 @@ "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/notices": "file:../notices", - "@wordpress/patterns": "file:../pattern", "classnames": "^2.3.1" }, "peerDependencies": { From b2bfe782bd6f8cf9f5d7de7854af4e12e390dfbc Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 10:29:32 +0300 Subject: [PATCH 12/23] Rename package from "patterns" to "user-patterns" --- lib/client-assets.php | 2 +- package-lock.json | 35 +++++++++---------- package.json | 2 +- packages/edit-site/package.json | 2 +- .../src/components/block-editor/index.js | 2 +- packages/editor/package.json | 2 +- .../editor/src/components/provider/index.js | 2 +- packages/{patterns => user-patterns}/.npmrc | 0 .../{patterns => user-patterns}/package.json | 6 ++-- .../src/components/index.js | 0 .../components/patterns-menu-items/index.js | 0 .../patterns-menu-items/index.native.js | 0 .../pattern-convert-button.js | 0 .../components/patterns-menu-items/style.scss | 0 .../{patterns => user-patterns}/src/index.js | 0 .../src/index.native.js | 0 .../src/store/actions.js | 0 .../src/store/index.js | 2 +- .../src/store/reducer.js | 0 .../src/store/selectors.js | 0 .../src/style.scss | 0 21 files changed, 27 insertions(+), 28 deletions(-) rename packages/{patterns => user-patterns}/.npmrc (100%) rename packages/{patterns => user-patterns}/package.json (91%) rename packages/{patterns => user-patterns}/src/components/index.js (100%) rename packages/{patterns => user-patterns}/src/components/patterns-menu-items/index.js (100%) rename packages/{patterns => user-patterns}/src/components/patterns-menu-items/index.native.js (100%) rename packages/{patterns => user-patterns}/src/components/patterns-menu-items/pattern-convert-button.js (100%) rename packages/{patterns => user-patterns}/src/components/patterns-menu-items/style.scss (100%) rename packages/{patterns => user-patterns}/src/index.js (100%) rename packages/{patterns => user-patterns}/src/index.native.js (100%) rename packages/{patterns => user-patterns}/src/store/actions.js (100%) rename packages/{patterns => user-patterns}/src/store/index.js (92%) rename packages/{patterns => user-patterns}/src/store/reducer.js (100%) rename packages/{patterns => user-patterns}/src/store/selectors.js (100%) rename packages/{patterns => user-patterns}/src/style.scss (100%) diff --git a/lib/client-assets.php b/lib/client-assets.php index d02c968614f206..e1e9e36be47e33 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -446,7 +446,7 @@ function gutenberg_register_packages_styles( $styles ) { gutenberg_override_style( $styles, 'wp-patterns', - gutenberg_url( 'build/patterns/style.css' ), + gutenberg_url( 'build/user-patterns/style.css' ), array( 'wp-components' ), $version ); diff --git a/package-lock.json b/package-lock.json index 67ac303a6b5ca6..d84c5b35e043f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17330,7 +17330,6 @@ "@wordpress/keycodes": "file:packages/keycodes", "@wordpress/media-utils": "file:packages/media-utils", "@wordpress/notices": "file:packages/notices", - "@wordpress/patterns": "file:packages/patterns", "@wordpress/plugins": "file:packages/plugins", "@wordpress/preferences": "file:packages/preferences", "@wordpress/private-apis": "file:packages/private-apis", @@ -17401,7 +17400,6 @@ "@wordpress/keycodes": "file:packages/keycodes", "@wordpress/media-utils": "file:packages/media-utils", "@wordpress/notices": "file:packages/notices", - "@wordpress/patterns": "file:packages/patterns", "@wordpress/plugins": "file:packages/plugins", "@wordpress/preferences": "file:packages/preferences", "@wordpress/private-apis": "file:packages/private-apis", @@ -17409,6 +17407,7 @@ "@wordpress/router": "file:packages/router", "@wordpress/style-engine": "file:packages/style-engine", "@wordpress/url": "file:packages/url", + "@wordpress/user-patterns": "file:packages/user-patterns", "@wordpress/viewport": "file:packages/viewport", "@wordpress/widgets": "file:packages/widgets", "classnames": "^2.3.1", @@ -17485,13 +17484,13 @@ "@wordpress/keycodes": "file:packages/keycodes", "@wordpress/media-utils": "file:packages/media-utils", "@wordpress/notices": "file:packages/notices", - "@wordpress/patterns": "file:packages/patterns", "@wordpress/preferences": "file:packages/preferences", "@wordpress/private-apis": "file:packages/private-apis", "@wordpress/reusable-blocks": "file:packages/reusable-blocks", "@wordpress/rich-text": "file:packages/rich-text", "@wordpress/server-side-render": "file:packages/server-side-render", "@wordpress/url": "file:packages/url", + "@wordpress/user-patterns": "file:packages/user-patterns", "@wordpress/wordcount": "file:packages/wordcount", "classnames": "^2.3.1", "date-fns": "^2.28.0", @@ -17852,21 +17851,6 @@ "version": "file:packages/npm-package-json-lint-config", "dev": true }, - "@wordpress/patterns": { - "version": "file:packages/patterns", - "requires": { - "@wordpress/block-editor": "file:packages/block-editor", - "@wordpress/blocks": "file:packages/blocks", - "@wordpress/components": "file:packages/components", - "@wordpress/core-data": "file:packages/core-data", - "@wordpress/data": "file:packages/data", - "@wordpress/element": "file:packages/element", - "@wordpress/i18n": "file:packages/i18n", - "@wordpress/icons": "file:packages/icons", - "@wordpress/notices": "file:packages/notices", - "@wordpress/url": "file:packages/url" - } - }, "@wordpress/plugins": { "version": "file:packages/plugins", "requires": { @@ -18323,6 +18307,21 @@ "remove-accents": "^0.4.2" } }, + "@wordpress/user-patterns": { + "version": "file:packages/user-patterns", + "requires": { + "@wordpress/block-editor": "file:packages/block-editor", + "@wordpress/blocks": "file:packages/blocks", + "@wordpress/components": "file:packages/components", + "@wordpress/core-data": "file:packages/core-data", + "@wordpress/data": "file:packages/data", + "@wordpress/element": "file:packages/element", + "@wordpress/i18n": "file:packages/i18n", + "@wordpress/icons": "file:packages/icons", + "@wordpress/notices": "file:packages/notices", + "@wordpress/url": "file:packages/url" + } + }, "@wordpress/viewport": { "version": "file:packages/viewport", "requires": { diff --git a/package.json b/package.json index 3346c5785ceb52..2eda9dd0ba0825 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ "@wordpress/list-reusable-blocks": "file:packages/list-reusable-blocks", "@wordpress/media-utils": "file:packages/media-utils", "@wordpress/notices": "file:packages/notices", - "@wordpress/patterns": "file:packages/patterns", "@wordpress/plugins": "file:packages/plugins", "@wordpress/preferences": "file:packages/preferences", "@wordpress/preferences-persistence": "file:packages/preferences-persistence", @@ -84,6 +83,7 @@ "@wordpress/style-engine": "file:packages/style-engine", "@wordpress/token-list": "file:packages/token-list", "@wordpress/url": "file:packages/url", + "@wordpress/user-patterns": "file:packages/user-patterns", "@wordpress/viewport": "file:packages/viewport", "@wordpress/warning": "file:packages/warning", "@wordpress/widgets": "file:packages/widgets", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index a79911efc1aa03..d85d77ca79de24 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -51,7 +51,6 @@ "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", "@wordpress/notices": "file:../notices", - "@wordpress/patterns": "file:../patterns", "@wordpress/plugins": "file:../plugins", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", @@ -59,6 +58,7 @@ "@wordpress/router": "file:../router", "@wordpress/style-engine": "file:../style-engine", "@wordpress/url": "file:../url", + "@wordpress/user-patterns": "file:../user-patterns", "@wordpress/viewport": "file:../viewport", "@wordpress/widgets": "file:../widgets", "classnames": "^2.3.1", diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js index af10d27d5820ac..1e8998d7935e90 100644 --- a/packages/edit-site/src/components/block-editor/index.js +++ b/packages/edit-site/src/components/block-editor/index.js @@ -25,7 +25,7 @@ import { useResizeObserver, } from '@wordpress/compose'; import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks'; -import { PatternsMenuItems } from '@wordpress/patterns'; +import { PatternsMenuItems } from '@wordpress/user-patterns'; /** * Internal dependencies diff --git a/packages/editor/package.json b/packages/editor/package.json index 59cfc4d7961a37..4e8bba2c9ce8d3 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -52,13 +52,13 @@ "@wordpress/keycodes": "file:../keycodes", "@wordpress/media-utils": "file:../media-utils", "@wordpress/notices": "file:../notices", - "@wordpress/patterns": "file:../patterns", "@wordpress/preferences": "file:../preferences", "@wordpress/private-apis": "file:../private-apis", "@wordpress/reusable-blocks": "file:../reusable-blocks", "@wordpress/rich-text": "file:../rich-text", "@wordpress/server-side-render": "file:../server-side-render", "@wordpress/url": "file:../url", + "@wordpress/user-patterns": "file:../user-patterns", "@wordpress/wordcount": "file:../wordcount", "classnames": "^2.3.1", "date-fns": "^2.28.0", diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index 0f13ce2090a53d..5c7368e78916d7 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -11,7 +11,7 @@ import { privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks'; -import { PatternsMenuItems } from '@wordpress/patterns'; +import { PatternsMenuItems } from '@wordpress/user-patterns'; import { store as noticesStore } from '@wordpress/notices'; /** diff --git a/packages/patterns/.npmrc b/packages/user-patterns/.npmrc similarity index 100% rename from packages/patterns/.npmrc rename to packages/user-patterns/.npmrc diff --git a/packages/patterns/package.json b/packages/user-patterns/package.json similarity index 91% rename from packages/patterns/package.json rename to packages/user-patterns/package.json index f3206f7eaa7739..f9779569af873b 100644 --- a/packages/patterns/package.json +++ b/packages/user-patterns/package.json @@ -1,5 +1,5 @@ { - "name": "@wordpress/patterns", + "name": "@wordpress/user-patterns", "version": "4.7.0", "description": "Patterns utilities.", "author": "The WordPress Contributors", @@ -9,11 +9,11 @@ "gutenberg", "patterns" ], - "homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/packages/patterns/README.md", + "homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/packages/user-patterns/README.md", "repository": { "type": "git", "url": "https://github.com/WordPress/gutenberg.git", - "directory": "packages/patterns" + "directory": "packages/user-patterns" }, "bugs": { "url": "https://github.com/WordPress/gutenberg/issues" diff --git a/packages/patterns/src/components/index.js b/packages/user-patterns/src/components/index.js similarity index 100% rename from packages/patterns/src/components/index.js rename to packages/user-patterns/src/components/index.js diff --git a/packages/patterns/src/components/patterns-menu-items/index.js b/packages/user-patterns/src/components/patterns-menu-items/index.js similarity index 100% rename from packages/patterns/src/components/patterns-menu-items/index.js rename to packages/user-patterns/src/components/patterns-menu-items/index.js diff --git a/packages/patterns/src/components/patterns-menu-items/index.native.js b/packages/user-patterns/src/components/patterns-menu-items/index.native.js similarity index 100% rename from packages/patterns/src/components/patterns-menu-items/index.native.js rename to packages/user-patterns/src/components/patterns-menu-items/index.native.js diff --git a/packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js b/packages/user-patterns/src/components/patterns-menu-items/pattern-convert-button.js similarity index 100% rename from packages/patterns/src/components/patterns-menu-items/pattern-convert-button.js rename to packages/user-patterns/src/components/patterns-menu-items/pattern-convert-button.js diff --git a/packages/patterns/src/components/patterns-menu-items/style.scss b/packages/user-patterns/src/components/patterns-menu-items/style.scss similarity index 100% rename from packages/patterns/src/components/patterns-menu-items/style.scss rename to packages/user-patterns/src/components/patterns-menu-items/style.scss diff --git a/packages/patterns/src/index.js b/packages/user-patterns/src/index.js similarity index 100% rename from packages/patterns/src/index.js rename to packages/user-patterns/src/index.js diff --git a/packages/patterns/src/index.native.js b/packages/user-patterns/src/index.native.js similarity index 100% rename from packages/patterns/src/index.native.js rename to packages/user-patterns/src/index.native.js diff --git a/packages/patterns/src/store/actions.js b/packages/user-patterns/src/store/actions.js similarity index 100% rename from packages/patterns/src/store/actions.js rename to packages/user-patterns/src/store/actions.js diff --git a/packages/patterns/src/store/index.js b/packages/user-patterns/src/store/index.js similarity index 92% rename from packages/patterns/src/store/index.js rename to packages/user-patterns/src/store/index.js index 0d3f8c37184a0c..c6f0eaa7c4e223 100644 --- a/packages/patterns/src/store/index.js +++ b/packages/user-patterns/src/store/index.js @@ -10,7 +10,7 @@ import * as actions from './actions'; import reducer from './reducer'; import * as selectors from './selectors'; -const STORE_NAME = 'core/patterns'; +const STORE_NAME = 'core/user-patterns'; /** * Store definition for the reusable blocks namespace. diff --git a/packages/patterns/src/store/reducer.js b/packages/user-patterns/src/store/reducer.js similarity index 100% rename from packages/patterns/src/store/reducer.js rename to packages/user-patterns/src/store/reducer.js diff --git a/packages/patterns/src/store/selectors.js b/packages/user-patterns/src/store/selectors.js similarity index 100% rename from packages/patterns/src/store/selectors.js rename to packages/user-patterns/src/store/selectors.js diff --git a/packages/patterns/src/style.scss b/packages/user-patterns/src/style.scss similarity index 100% rename from packages/patterns/src/style.scss rename to packages/user-patterns/src/style.scss From c632bd7438f35680d1224f8d31d35fc3ae377668 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 10:31:53 +0300 Subject: [PATCH 13/23] Rename stylesheet handle to wp-user-patterns --- lib/client-assets.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/client-assets.php b/lib/client-assets.php index e1e9e36be47e33..3e2c83e0180223 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -277,7 +277,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-editor', gutenberg_url( 'build/editor/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-reusable-blocks', 'wp-patterns' ), + array( 'wp-components', 'wp-block-editor', 'wp-reusable-blocks', 'wp-user-patterns' ), $version ); $styles->add_data( 'wp-editor', 'rtl', 'replace' ); @@ -327,7 +327,7 @@ function gutenberg_register_packages_styles( $styles ) { 'wp-reset-editor-styles', 'wp-block-library', 'wp-reusable-blocks', - 'wp-patterns', + 'wp-user-patterns', // Until #37466, we can't specifically add them as editor styles yet, // so we must hard-code it here as a dependency. 'wp-block-editor-content', @@ -445,12 +445,12 @@ function gutenberg_register_packages_styles( $styles ) { gutenberg_override_style( $styles, - 'wp-patterns', + 'wp-user-patterns', gutenberg_url( 'build/user-patterns/style.css' ), array( 'wp-components' ), $version ); - $styles->add_data( 'wp-patterns', 'rtl', 'replace' ); + $styles->add_data( 'wp-user-patterns', 'rtl', 'replace' ); gutenberg_override_style( $styles, From bd6eeb95162fd4cc908a90b9f1cc041a2522eaef Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 10:48:13 +0300 Subject: [PATCH 14/23] change version number to 1.0.0 --- packages/user-patterns/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/user-patterns/package.json b/packages/user-patterns/package.json index f9779569af873b..ef34aa55c90b95 100644 --- a/packages/user-patterns/package.json +++ b/packages/user-patterns/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/user-patterns", - "version": "4.7.0", + "version": "1.0.0", "description": "Patterns utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 92deb04d59bf0da9de74c6df014a5fd7a4d5af21 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 10:50:03 +0300 Subject: [PATCH 15/23] no need for the extra wrapper --- .../src/components/patterns-menu-items/index.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/user-patterns/src/components/patterns-menu-items/index.js b/packages/user-patterns/src/components/patterns-menu-items/index.js index 6719092c23e79f..941f01b2ef7ac9 100644 --- a/packages/user-patterns/src/components/patterns-menu-items/index.js +++ b/packages/user-patterns/src/components/patterns-menu-items/index.js @@ -11,12 +11,10 @@ import PatternConvertButton from './pattern-convert-button'; function PatternsMenuItems( { clientIds, rootClientId } ) { return ( - <> - - + ); } From fc46519040ae2d777f19e33e2552fa8c067dd6a7 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 11:14:13 +0300 Subject: [PATCH 16/23] renaming stuff --- package-lock.json | 4 ++-- packages/base-styles/_z-index.scss | 2 +- packages/edit-site/src/components/block-editor/index.js | 4 ++-- packages/editor/src/components/provider/index.js | 4 ++-- packages/user-patterns/src/components/index.js | 2 +- .../src/components/patterns-menu-items/index.js | 8 ++++---- .../patterns-menu-items/pattern-convert-button.js | 4 ++-- .../src/components/patterns-menu-items/style.scss | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index d84c5b35e043f0..b8d2541168e027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30467,7 +30467,7 @@ "css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, "cssesc": { @@ -41018,7 +41018,7 @@ "lz-string": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", "dev": true }, "macos-release": { diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 1e299774ebadcb..197933a7350e49 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -121,7 +121,7 @@ $z-layers: ( // Should be above the popover (dropdown) ".reusable-blocks-menu-items__convert-modal": 1000001, - ".patterns-menu-items__convert-modal": 1000001, + ".user-patterns-menu-items__convert-modal": 1000001, ".edit-site-create-template-part-modal": 1000001, ".block-editor-block-lock-modal": 1000001, ".block-editor-template-part__selection-modal": 1000001, diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js index 1e8998d7935e90..18d7188b53e8b5 100644 --- a/packages/edit-site/src/components/block-editor/index.js +++ b/packages/edit-site/src/components/block-editor/index.js @@ -25,7 +25,7 @@ import { useResizeObserver, } from '@wordpress/compose'; import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks'; -import { PatternsMenuItems } from '@wordpress/user-patterns'; +import { UserPatternsMenuItems } from '@wordpress/user-patterns'; /** * Internal dependencies @@ -214,7 +214,7 @@ export default function BlockEditor() { } - + ); } diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index 5c7368e78916d7..95a498032b3a71 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -11,7 +11,7 @@ import { privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks'; -import { PatternsMenuItems } from '@wordpress/user-patterns'; +import { UserPatternsMenuItems } from '@wordpress/user-patterns'; import { store as noticesStore } from '@wordpress/notices'; /** @@ -132,7 +132,7 @@ export const ExperimentalEditorProvider = withRegistryProvider( > { children } - + diff --git a/packages/user-patterns/src/components/index.js b/packages/user-patterns/src/components/index.js index 9daf89003d2d8e..4c47944dadb28f 100644 --- a/packages/user-patterns/src/components/index.js +++ b/packages/user-patterns/src/components/index.js @@ -1 +1 @@ -export { default as PatternsMenuItems } from './patterns-menu-items'; +export { default as UserPatternsMenuItems } from './patterns-menu-items'; diff --git a/packages/user-patterns/src/components/patterns-menu-items/index.js b/packages/user-patterns/src/components/patterns-menu-items/index.js index 941f01b2ef7ac9..9c5260cf4a947d 100644 --- a/packages/user-patterns/src/components/patterns-menu-items/index.js +++ b/packages/user-patterns/src/components/patterns-menu-items/index.js @@ -7,11 +7,11 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; /** * Internal dependencies */ -import PatternConvertButton from './pattern-convert-button'; +import UserPatternConvertButton from './pattern-convert-button'; -function PatternsMenuItems( { clientIds, rootClientId } ) { +function UserPatternsMenuItems( { clientIds, rootClientId } ) { return ( - @@ -23,4 +23,4 @@ export default withSelect( ( select ) => { return { clientIds: getSelectedBlockClientIds(), }; -} )( PatternsMenuItems ); +} )( UserPatternsMenuItems ); diff --git a/packages/user-patterns/src/components/patterns-menu-items/pattern-convert-button.js b/packages/user-patterns/src/components/patterns-menu-items/pattern-convert-button.js index ec542f1e74ac92..71b7e99ef87bda 100644 --- a/packages/user-patterns/src/components/patterns-menu-items/pattern-convert-button.js +++ b/packages/user-patterns/src/components/patterns-menu-items/pattern-convert-button.js @@ -28,7 +28,7 @@ import { store } from '../../store'; * @param {string[]} props.clientIds Client ids of selected blocks. * @return {import('@wordpress/element').WPComponent} The menu control or null. */ -export default function PatternConvertButton( { clientIds } ) { +export default function UserPatternConvertButton( { clientIds } ) { const [ isModalOpen, setIsModalOpen ] = useState( false ); const [ title, setTitle ] = useState( '' ); @@ -72,7 +72,7 @@ export default function PatternConvertButton( { clientIds } ) { setIsModalOpen( false ); setTitle( '' ); } } - overlayClassName="patterns-menu-items__convert-modal" + overlayClassName="user-patterns-menu-items__convert-modal" >
{ diff --git a/packages/user-patterns/src/components/patterns-menu-items/style.scss b/packages/user-patterns/src/components/patterns-menu-items/style.scss index ddd2656dc7d41d..0180d126df816e 100644 --- a/packages/user-patterns/src/components/patterns-menu-items/style.scss +++ b/packages/user-patterns/src/components/patterns-menu-items/style.scss @@ -1,3 +1,3 @@ -.patterns-menu-items__convert-modal { - z-index: z-index(".patterns-menu-items__convert-modal"); +.user-patterns-menu-items__convert-modal { + z-index: z-index(".user-patterns-menu-items__convert-modal"); } From 5a761861aa6d41cc8f3c202b3d20e13f1e82b062 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 11:17:42 +0300 Subject: [PATCH 17/23] Basic README --- packages/user-patterns/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 packages/user-patterns/README.md diff --git a/packages/user-patterns/README.md b/packages/user-patterns/README.md new file mode 100644 index 00000000000000..9aab220632e8b8 --- /dev/null +++ b/packages/user-patterns/README.md @@ -0,0 +1,21 @@ +# User patterns + +User patterns components and logic. + +## Installation + +Install the module + +```bash +npm install @wordpress/user-patterns --save +``` + +_This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for such language features and APIs, you should include [the polyfill shipped in `@wordpress/babel-preset-default`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/babel-preset-default#polyfill) in your code._ + +## Contributing to this package + +This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects. + +To find out more about contributing to this package or Gutenberg as a whole, please read the project's main [contributor guide](https://github.com/WordPress/gutenberg/tree/HEAD/CONTRIBUTING.md). + +

Code is Poetry.

From 62c5d22b8d0fe488b845e0e202a94b5c178b6e56 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 11:28:42 +0300 Subject: [PATCH 18/23] Update the docs/manifest.json file --- docs/manifest.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/manifest.json b/docs/manifest.json index 304acd00a79eaf..1f67f30a4c6ba9 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1883,6 +1883,12 @@ "markdown_source": "../packages/url/README.md", "parent": "packages" }, + { + "title": "@wordpress/user-patterns", + "slug": "packages-user-patterns", + "markdown_source": "../packages/user-patterns/README.md", + "parent": "packages" + }, { "title": "@wordpress/viewport", "slug": "packages-viewport", From 536bad223e331bfed6016b02fb31ddce04594108 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 11:30:11 +0300 Subject: [PATCH 19/23] Manually revert some package-lock integrity hashes --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b8d2541168e027..d84c5b35e043f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30467,7 +30467,7 @@ "css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", "dev": true }, "cssesc": { @@ -41018,7 +41018,7 @@ "lz-string": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", "dev": true }, "macos-release": { From 1ef566115b7347b55cf34da57f2871f2a11dc744 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 11:41:38 +0300 Subject: [PATCH 20/23] Move PHP files from 6.3 to experimental --- .../class-wp-rest-user-patterns-controller.php} | 4 ++-- .../wordpress-6.3 => experimental}/user-block-patterns.php | 2 +- lib/load.php | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) rename lib/{compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php => experimental/class-wp-rest-user-patterns-controller.php} (94%) rename lib/{compat/wordpress-6.3 => experimental}/user-block-patterns.php (98%) diff --git a/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php b/lib/experimental/class-wp-rest-user-patterns-controller.php similarity index 94% rename from lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php rename to lib/experimental/class-wp-rest-user-patterns-controller.php index 09a30f88797d55..f9403e411d2fa8 100644 --- a/lib/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php +++ b/lib/experimental/class-wp-rest-user-patterns-controller.php @@ -1,6 +1,6 @@ false, 'show_in_rest' => true, 'rest_base' => 'patterns', - 'rest_controller_class' => 'Gutenberg_REST_Patterns_Controller', + 'rest_controller_class' => 'WP_REST_User_Patterns_Controller', 'capability_type' => 'block', 'capabilities' => array( // You need to be able to edit posts, in order to read blocks in their raw form. diff --git a/lib/load.php b/lib/load.php index a6a2d33d435ed7..a3232acde2365f 100644 --- a/lib/load.php +++ b/lib/load.php @@ -49,7 +49,6 @@ function gutenberg_is_experiment_enabled( $name ) { require_once __DIR__ . '/compat/wordpress-6.3/class-gutenberg-rest-global-styles-controller-6-3.php'; require_once __DIR__ . '/compat/wordpress-6.3/rest-api.php'; require_once __DIR__ . '/compat/wordpress-6.3/theme-previews.php'; - require_once __DIR__ . '/compat/wordpress-6.3/class-gutenberg-rest-patterns-controller.php'; require_once __DIR__ . '/compat/wordpress-6.3/user-block-patterns.php'; // Experimental. @@ -59,6 +58,10 @@ function gutenberg_is_experiment_enabled( $name ) { require_once __DIR__ . '/experimental/class-gutenberg-rest-global-styles-revisions-controller.php'; require_once __DIR__ . '/experimental/class-wp-rest-navigation-fallback-controller.php'; + if ( ! class_exists( 'WP_REST_User_Patterns_Controller' ) ) { + require_once __DIR__ . '/experimental/class-wp-rest-user-patterns-controller.php'; + } + require_once __DIR__ . '/experimental/rest-api.php'; } @@ -103,6 +106,7 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/experimental/navigation-theme-opt-in.php'; require __DIR__ . '/experimental/kses.php'; require __DIR__ . '/experimental/l10n.php'; +require __DIR__ . '/experimental/user-block-patterns.php'; // Fonts API. if ( ! class_exists( 'WP_Fonts' ) ) { From 2713643a3e277d6d1772495fa33271a0207a972c Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 6 Apr 2023 11:57:50 +0300 Subject: [PATCH 21/23] Add missing textdomain --- lib/experimental/user-block-patterns.php | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/experimental/user-block-patterns.php b/lib/experimental/user-block-patterns.php index c4bb73fe0f579d..9e8e10eb6351c7 100644 --- a/lib/experimental/user-block-patterns.php +++ b/lib/experimental/user-block-patterns.php @@ -13,25 +13,25 @@ function gutenberg_create_wp_block_pattern_post_type() { 'wp_block_pattern', array( 'labels' => array( - 'name' => _x( 'Patterns', 'post type general name' ), - 'singular_name' => _x( 'Pattern', 'post type singular name' ), - 'add_new' => _x( 'Add New', 'Pattern' ), - 'add_new_item' => __( 'Add new Pattern' ), - 'new_item' => __( 'New Pattern' ), - 'edit_item' => __( 'Edit Pattern' ), - 'view_item' => __( 'View Pattern' ), - 'all_items' => __( 'All Patterns' ), - 'search_items' => __( 'Search Patterns' ), - 'not_found' => __( 'No pattern found.' ), - 'not_found_in_trash' => __( 'No pattern found in Trash.' ), - 'filter_items_list' => __( 'Filter pattern list' ), - 'items_list_navigation' => __( 'Patterns list navigation' ), - 'items_list' => __( 'Patterns list' ), - 'item_published' => __( 'Pattern published.' ), - 'item_published_privately' => __( 'Pattern published privately.' ), - 'item_reverted_to_draft' => __( 'Pattern reverted to draft.' ), - 'item_scheduled' => __( 'Pattern scheduled.' ), - 'item_updated' => __( 'Pattern updated.' ), + 'name' => _x( 'Patterns', 'post type general name', 'gutenberg' ), + 'singular_name' => _x( 'Pattern', 'post type singular name', 'gutenberg' ), + 'add_new' => _x( 'Add New', 'Pattern', 'gutenberg' ), + 'add_new_item' => __( 'Add new Pattern', 'gutenberg' ), + 'new_item' => __( 'New Pattern', 'gutenberg' ), + 'edit_item' => __( 'Edit Pattern', 'gutenberg' ), + 'view_item' => __( 'View Pattern', 'gutenberg' ), + 'all_items' => __( 'All Patterns', 'gutenberg' ), + 'search_items' => __( 'Search Patterns', 'gutenberg' ), + 'not_found' => __( 'No pattern found.', 'gutenberg' ), + 'not_found_in_trash' => __( 'No pattern found in Trash.', 'gutenberg' ), + 'filter_items_list' => __( 'Filter pattern list', 'gutenberg' ), + 'items_list_navigation' => __( 'Patterns list navigation', 'gutenberg' ), + 'items_list' => __( 'Patterns list', 'gutenberg' ), + 'item_published' => __( 'Pattern published.', 'gutenberg' ), + 'item_published_privately' => __( 'Pattern published privately.', 'gutenberg' ), + 'item_reverted_to_draft' => __( 'Pattern reverted to draft.', 'gutenberg' ), + 'item_scheduled' => __( 'Pattern scheduled.', 'gutenberg' ), + 'item_updated' => __( 'Pattern updated.', 'gutenberg' ), ), 'public' => false, '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ From 7c300ac14700ad97508eade10364b0ea91324f07 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Fri, 7 Apr 2023 11:53:30 +0300 Subject: [PATCH 22/23] Add missing textdomain --- lib/experimental/user-block-patterns.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/experimental/user-block-patterns.php b/lib/experimental/user-block-patterns.php index 9e8e10eb6351c7..b024f322dfdb45 100644 --- a/lib/experimental/user-block-patterns.php +++ b/lib/experimental/user-block-patterns.php @@ -86,8 +86,8 @@ function gutenberg_register_user_block_patterns() { register_block_pattern_category( 'user', array( - 'label' => _x( 'User patterns', 'Block pattern category' ), - 'description' => __( 'Patterns that were created by users on this site.' ), + 'label' => _x( 'User patterns', 'Block pattern category', 'gutenberg' ), + 'description' => __( 'Patterns that were created by users on this site.', 'gutenberg' ), ) ); From 0f84edcd6bcc01c26c5c998c17431c906187723e Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 2 May 2023 14:31:17 +0300 Subject: [PATCH 23/23] Resolve rebase conflict --- lib/load.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/load.php b/lib/load.php index a3232acde2365f..8e680c2b1ace3b 100644 --- a/lib/load.php +++ b/lib/load.php @@ -49,7 +49,6 @@ function gutenberg_is_experiment_enabled( $name ) { require_once __DIR__ . '/compat/wordpress-6.3/class-gutenberg-rest-global-styles-controller-6-3.php'; require_once __DIR__ . '/compat/wordpress-6.3/rest-api.php'; require_once __DIR__ . '/compat/wordpress-6.3/theme-previews.php'; - require_once __DIR__ . '/compat/wordpress-6.3/user-block-patterns.php'; // Experimental. if ( ! class_exists( 'WP_Rest_Customizer_Nonces' ) ) {