From 732726bad7bab9d74a167fd6b22a33a8fd47b4df Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 25 Feb 2021 10:21:03 +0100 Subject: [PATCH 01/24] Rethink FSE alignments --- lib/class-wp-theme-json.php | 1 + package-lock.json | 3 +- .../components/block-alignment-control/ui.js | 5 +- packages/block-library/package.json | 3 +- packages/block-library/src/group/block.json | 3 + packages/block-library/src/group/edit.js | 139 +++++++++++++++++- packages/block-library/src/group/editor.scss | 60 +------- packages/block-library/src/group/save.js | 32 +++- packages/edit-site/src/style.scss | 2 +- 9 files changed, 177 insertions(+), 71 deletions(-) diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index d967e1681acf1..fa75edaaef049 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -166,6 +166,7 @@ class WP_Theme_JSON { 'customTextTransforms' => null, ), 'custom' => null, + 'layout' => null, ), ); diff --git a/package-lock.json b/package-lock.json index 1fa02b13a4921..c144efe2776d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12364,7 +12364,8 @@ "memize": "^1.1.0", "moment": "^2.22.1", "react-easy-crop": "^3.0.0", - "tinycolor2": "^1.4.2" + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" } }, "@wordpress/block-serialization-default-parser": { diff --git a/packages/block-editor/src/components/block-alignment-control/ui.js b/packages/block-editor/src/components/block-alignment-control/ui.js index 0ac3f4345e8e7..2e7a430e84d61 100644 --- a/packages/block-editor/src/components/block-alignment-control/ui.js +++ b/packages/block-editor/src/components/block-alignment-control/ui.js @@ -70,11 +70,12 @@ function BlockAlignmentUI( { if ( ! supportsAlignments ) { return null; } - const { alignments: availableAlignments = DEFAULT_CONTROLS } = layout; const enabledControls = controls.filter( ( control ) => - ( wideControlsEnabled || ! WIDE_CONTROLS.includes( control ) ) && + ( layout.alignments || // Ignore the global wideAlignment check if the layout explicitely defines alignments. + wideControlsEnabled || + ! WIDE_CONTROLS.includes( control ) ) && availableAlignments.includes( control ) ); diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 4ad7953877975..81162851f76b7 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -61,7 +61,8 @@ "memize": "^1.1.0", "moment": "^2.22.1", "react-easy-crop": "^3.0.0", - "tinycolor2": "^1.4.2" + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" }, "publishConfig": { "access": "public" diff --git a/packages/block-library/src/group/block.json b/packages/block-library/src/group/block.json index 913194728559b..9f164fddd31d9 100644 --- a/packages/block-library/src/group/block.json +++ b/packages/block-library/src/group/block.json @@ -9,6 +9,9 @@ }, "templateLock": { "type": "string" + }, + "layout": { + "type": "object" } }, "supports": { diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 55de289edbd42..a3ec02d8d221e 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -1,46 +1,156 @@ +/** + * External dependencies + */ +import { v4 as uuid } from 'uuid'; +import classnames from 'classnames'; + /** * WordPress dependencies */ +import { Platform } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { InnerBlocks, useBlockProps, InspectorAdvancedControls, + InspectorControls, __experimentalUseInnerBlocksProps as useInnerBlocksProps, store as blockEditorStore, } from '@wordpress/block-editor'; import { SelectControl, + PanelBody, __experimentalBoxControl as BoxControl, + __experimentalUnitControl as UnitControl, + Button, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; const { __Visualizer: BoxControlVisualizer } = BoxControl; +const isWeb = Platform.OS === 'web'; + +export const CSS_UNITS = [ + { + value: '%', + label: isWeb ? '%' : __( 'Percentage (%)' ), + default: '', + }, + { + value: 'px', + label: isWeb ? 'px' : __( 'Pixels (px)' ), + default: '', + }, + { + value: 'em', + label: isWeb ? 'em' : __( 'Relative to parent font size (em)' ), + default: '', + }, + { + value: 'rem', + label: isWeb ? 'rem' : __( 'Relative to root font size (rem)' ), + default: '', + }, + { + value: 'vw', + label: isWeb ? 'vw' : __( 'Viewport width (vw)' ), + default: '', + }, +]; + function GroupEdit( { attributes, setAttributes, clientId } ) { - const hasInnerBlocks = useSelect( + const { defaultLayout, hasInnerBlocks } = useSelect( ( select ) => { - const { getBlock } = select( blockEditorStore ); + const { getBlock, getSettings } = select( blockEditorStore ); const block = getBlock( clientId ); - return !! ( block && block.innerBlocks.length ); + return { + defaultLayout: getSettings().__experimentalFeatures?.defaults + ?.layout, + hasInnerBlocks: !! ( block && block.innerBlocks.length ), + }; }, [ clientId ] ); const blockProps = useBlockProps(); - const { tagName: TagName = 'div', templateLock } = attributes; + const { tagName: TagName = 'div', templateLock, layout = {} } = attributes; + const { contentSize, wideSize } = layout; const innerBlocksProps = useInnerBlocksProps( { - className: 'wp-block-group__inner-container', + className: classnames( 'wp-block-group__inner-container', { + [ `wp-container-${ layout.id }` ]: !! layout.id, + } ), }, { templateLock, renderAppender: hasInnerBlocks ? undefined : InnerBlocks.ButtonBlockAppender, + __experimentalLayout: { + type: 'default', + alignments: + contentSize || wideSize + ? [ 'wide', 'full' ] + : [ 'left', 'center', 'right' ], + }, } ); return ( <> + + + { !! defaultLayout && ( + + ) } + { + nextWidth = + 0 > parseFloat( nextWidth ) ? '0' : nextWidth; + setAttributes( { + layout: { + ...layout, + contentSize: nextWidth, + id: layout.id ?? uuid(), + }, + } ); + } } + units={ CSS_UNITS } + /> + { + nextWidth = + 0 > parseFloat( nextWidth ) ? '0' : nextWidth; + setAttributes( { + layout: { + ...layout, + wideSize: nextWidth, + id: layout.id ?? uuid(), + }, + } ); + } } + units={ CSS_UNITS } + /> + + + { ( wideSize || contentSize ) && ( + + ) } .wp-block-group__inner-container > [data-align="full"] { - margin-left: auto; - margin-right: auto; - } - - // Full Width Blocks with a background (ie: has padding) - &.has-background > .wp-block-group__inner-container > [data-align="full"] { - // note: using position `left` causes hoz scrollbars so - // we opt to use margin instead - // the 30px matches the hoz padding applied in `theme.scss` - // added when the Block has a background set - margin-left: -30px; - - // 60px here is x2 the hoz padding from `theme.scss` added when - // the Block has a background set - // note: also duplicated below for full width Groups - width: calc(100% + 60px); - } -} - -/** - * Group: Full Width Alignment - */ -[data-align="full"] .wp-block-group { - - // Non-full Width Blocks - // specificity required to only target immediate child Blocks of Group - > .wp-block-group__inner-container > .wp-block { - padding-left: $block-padding; - padding-right: $block-padding; - - @include break-small() { - padding-left: 0; - padding-right: 0; - } - } - - // Full Width Blocks - // specificity required to only target immediate child Blocks of Group - > .wp-block-group__inner-container > [data-align="full"] { - padding-right: 0; - padding-left: 0; - left: 0; - width: 100%; - max-width: none; - } - - // Full Width Blocks with a background (ie: has padding) - // note: also duplicated above for all Group widths - &.has-background > .wp-block-group__inner-container > [data-align="full"] { - width: calc(100% + 60px); - } } // Place block list appender in the same place content will appear. -[data-type="core/group"].is-selected { - +[data-type='core/group'].is-selected { .block-list-appender { margin-left: 0; margin-right: 0; diff --git a/packages/block-library/src/group/save.js b/packages/block-library/src/group/save.js index 0a5f4b87ec708..de904a78232ed 100644 --- a/packages/block-library/src/group/save.js +++ b/packages/block-library/src/group/save.js @@ -1,14 +1,42 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ import { InnerBlocks, useBlockProps } from '@wordpress/block-editor'; export default function save( { attributes } ) { - const { tagName: Tag } = attributes; + const { tagName: Tag, layout = {} } = attributes; + const { contentSize, wideSize } = layout; + const className = classnames( 'wp-block-group__inner-container', { + [ `wp-container-${ layout.id }` ]: !! layout.id, + } ); return ( -
+ { ( contentSize || wideSize ) && ( + + ) } +
diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 9dff7eb78b998..2cd9607737d4a 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -76,4 +76,4 @@ body.toplevel_page_gutenberg-edit-site { } @include wordpress-admin-schemes(); -@include default-block-widths(); +// @include default-block-widths(); From 8efe71055ebcb8d2b83fb8ab01599c8f70ae5c96 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 26 Feb 2021 14:36:07 +0100 Subject: [PATCH 02/24] Move the style application to the server to keep the markup pure --- .../themes/block-based-themes.md | 76 +++++++++--------- lib/blocks.php | 2 +- package-lock.json | 3 +- packages/block-library/package.json | 3 +- .../block-library/src/group/deprecated.js | 46 ++++++++++- packages/block-library/src/group/edit.js | 77 +++++++++---------- packages/block-library/src/group/index.php | 67 ++++++++++++++++ packages/block-library/src/group/save.js | 35 +-------- packages/blocks/src/api/test/parser.js | 11 ++- 9 files changed, 196 insertions(+), 124 deletions(-) create mode 100644 packages/block-library/src/group/index.php diff --git a/docs/how-to-guides/themes/block-based-themes.md b/docs/how-to-guides/themes/block-based-themes.md index dc931cc203b11..3368d80fcfff3 100644 --- a/docs/how-to-guides/themes/block-based-themes.md +++ b/docs/how-to-guides/themes/block-based-themes.md @@ -31,7 +31,7 @@ theme |__ ... ``` -The difference with existing WordPress themes is that the different templates in the template hierarchy, and template parts, are block templates instead of php files. In addition, this example includes an [`experimental-theme.json`](/docs/how-to-guides/themes/theme-json.md) file for some styles. +The difference with existing WordPress themes is that the different templates in the template hierarchy, and template parts, are block templates instead of php files. In addition, this example includes an [`experimental-theme.json`](/docs/how-to-guides/themes/theme-json.md) file for some styles. ## What is a block template? @@ -50,20 +50,16 @@ Here's an example of a block template:
-
- - -
+ +
-
- -

Footer

- -
+ +

Footer

+
``` @@ -72,23 +68,23 @@ Here's an example of a block template: Ultimately, any WordPress user with the correct capabilities (example: `administrator` WordPress role) will be able to access these templates in the WordPress admin, edit them in dedicated views and potentially export them as a theme. -As of Gutenberg 8.5, there are two ways to create and edit templates within Gutenberg. +As of Gutenberg 8.5, there are two ways to create and edit templates within Gutenberg. ### Edit templates within The "Appearance" section of WP-Admin You can navigate to the temporary "Templates" admin menu under "Appearance" `wp-admin/edit.php?post_type=wp_template` and use this as a playground to edit your templates. Add blocks here and switch to the code editor mode to grab the HTML of the template when you are done. Afterwards, you can paste that markup into a file in your theme directory. -Please note that the "Templates" admin menu under "Appearance" will _not_ list templates that are bundled with your theme. It only lists new templates created by the specific WordPress site you're working on. +Please note that the "Templates" admin menu under "Appearance" will _not_ list templates that are bundled with your theme. It only lists new templates created by the specific WordPress site you're working on. ### Edit Templates within the Full-site Editor -To begin, create a blank template file within your theme. For example: `mytheme/block-templates/index.html`. Afterwards, open the Full-site editor. Your new template should appear as the active template, and should be blank. Add blocks as you normally would using Gutenberg. You can add and create template parts directly using the "Template Parts" block. +To begin, create a blank template file within your theme. For example: `mytheme/block-templates/index.html`. Afterwards, open the Full-site editor. Your new template should appear as the active template, and should be blank. Add blocks as you normally would using Gutenberg. You can add and create template parts directly using the "Template Parts" block. -Repeat for any additional templates you'd like to bundle with your theme. +Repeat for any additional templates you'd like to bundle with your theme. -When you're done, click the "Export Theme" option in the "Tools" (ellipsis) menu of the site editor. This will provide you with a ZIP download of all the templates and template parts you've created in the site editor. These new HTML files can be placed directly into your theme. +When you're done, click the "Export Theme" option in the "Tools" (ellipsis) menu of the site editor. This will provide you with a ZIP download of all the templates and template parts you've created in the site editor. These new HTML files can be placed directly into your theme. -Note that when you export template parts this way, the template part block markup will include a `postID` attribute that can be safely removed when distributing your theme. +Note that when you export template parts this way, the template part block markup will include a `postID` attribute that can be safely removed when distributing your theme. ## Templates CPT @@ -102,33 +98,33 @@ Note that it won't take precedence over any of your theme's templates with highe Some blocks have been made specifically for block-based themes. For example, you'll most likely use the **Site Title** block in your site's header while your **single** block template will most likely include a **Post Title** and a **Post Content** block. -As we're still early in the process, the number of blocks specifically dedicated to these block templates is relatively small but more will be added as we move forward with the project. As of Gutenberg 8.5, the following blocks are currently available: - -- Site Title -- Template Part -- Query -- Query Loop -- Query Pagination -- Post Title -- Post Content -- Post Author -- Post Comment -- Post Comment Author -- Post Comment Date -- Post Comments -- Post Comments Count -- Post Comments Form -- Post Date -- Post Excerpt -- Post Featured Image -- Post Hierarchical Terms -- Post Tags +As we're still early in the process, the number of blocks specifically dedicated to these block templates is relatively small but more will be added as we move forward with the project. As of Gutenberg 8.5, the following blocks are currently available: + +- Site Title +- Template Part +- Query +- Query Loop +- Query Pagination +- Post Title +- Post Content +- Post Author +- Post Comment +- Post Comment Author +- Post Comment Date +- Post Comments +- Post Comments Count +- Post Comments Form +- Post Date +- Post Excerpt +- Post Featured Image +- Post Hierarchical Terms +- Post Tags ## Styling -One of the most important aspects of themes (if not the most important) is the styling. While initially you'll be able to provide styles and enqueue them using the same hooks themes have always used, the [Global Styles](/docs/how-to-guides/themes/theme-json.md) effort will provide a scaffolding for adding many theme styles in the future. +One of the most important aspects of themes (if not the most important) is the styling. While initially you'll be able to provide styles and enqueue them using the same hooks themes have always used, the [Global Styles](/docs/how-to-guides/themes/theme-json.md) effort will provide a scaffolding for adding many theme styles in the future. ## Resources -- [Full Site Editing](https://github.com/WordPress/gutenberg/labels/%5BFeature%5D%20Full%20Site%20Editing) label. -- [Theme Experiments](https://github.com/WordPress/theme-experiments) repository, full of block-based theme examples created by the WordPress community. +- [Full Site Editing](https://github.com/WordPress/gutenberg/labels/%5BFeature%5D%20Full%20Site%20Editing) label. +- [Theme Experiments](https://github.com/WordPress/theme-experiments) repository, full of block-based theme examples created by the WordPress community. diff --git a/lib/blocks.php b/lib/blocks.php index 70f9ec44cb32e..0d12270b2bfa0 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -23,7 +23,6 @@ function gutenberg_reregister_core_block_types() { 'columns', 'file', 'gallery', - 'group', 'heading', 'html', 'image', @@ -54,6 +53,7 @@ function gutenberg_reregister_core_block_types() { 'calendar.php' => 'core/calendar', 'categories.php' => 'core/categories', 'cover.php' => 'core/cover', + 'group.php' => 'core/group', 'latest-comments.php' => 'core/latest-comments', 'latest-posts.php' => 'core/latest-posts', 'navigation.php' => 'core/navigation', diff --git a/package-lock.json b/package-lock.json index c144efe2776d4..1fa02b13a4921 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12364,8 +12364,7 @@ "memize": "^1.1.0", "moment": "^2.22.1", "react-easy-crop": "^3.0.0", - "tinycolor2": "^1.4.2", - "uuid": "^8.3.0" + "tinycolor2": "^1.4.2" } }, "@wordpress/block-serialization-default-parser": { diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 81162851f76b7..4ad7953877975 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -61,8 +61,7 @@ "memize": "^1.1.0", "moment": "^2.22.1", "react-easy-crop": "^3.0.0", - "tinycolor2": "^1.4.2", - "uuid": "^8.3.0" + "tinycolor2": "^1.4.2" }, "publishConfig": { "access": "public" diff --git a/packages/block-library/src/group/deprecated.js b/packages/block-library/src/group/deprecated.js index 3e6d394197ffd..9e97089f791a1 100644 --- a/packages/block-library/src/group/deprecated.js +++ b/packages/block-library/src/group/deprecated.js @@ -7,7 +7,11 @@ import { omit } from 'lodash'; /** * WordPress dependencies */ -import { InnerBlocks, getColorClassName } from '@wordpress/block-editor'; +import { + InnerBlocks, + getColorClassName, + useBlockProps, +} from '@wordpress/block-editor'; const migrateAttributes = ( attributes ) => { if ( ! attributes.tagName ) { @@ -34,6 +38,46 @@ const migrateAttributes = ( attributes ) => { }; const deprecated = [ + // Version of the block with the double dif + { + attributes: { + tagName: { + type: 'string', + default: 'div', + }, + templateLock: { + type: 'string', + }, + layout: { + type: 'object', + }, + }, + supports: { + align: [ 'wide', 'full' ], + anchor: true, + color: { + gradients: true, + link: true, + }, + spacing: { + padding: true, + }, + __experimentalBorder: { + radius: true, + }, + }, + save( { attributes } ) { + const { tagName: Tag } = attributes; + + return ( + +
+ +
+
+ ); + }, + }, // Version of the block without global styles support { attributes: { diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index a3ec02d8d221e..164142b495340 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import { v4 as uuid } from 'uuid'; import classnames from 'classnames'; /** @@ -25,6 +24,7 @@ import { Button, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { useInstanceId } from '@wordpress/compose'; const { __Visualizer: BoxControlVisualizer } = BoxControl; const isWeb = Platform.OS === 'web'; @@ -58,6 +58,7 @@ export const CSS_UNITS = [ ]; function GroupEdit( { attributes, setAttributes, clientId } ) { + const id = useInstanceId( GroupEdit ); const { defaultLayout, hasInnerBlocks } = useSelect( ( select ) => { const { getBlock, getSettings } = select( blockEditorStore ); @@ -70,29 +71,36 @@ function GroupEdit( { attributes, setAttributes, clientId } ) { }, [ clientId ] ); - const blockProps = useBlockProps(); const { tagName: TagName = 'div', templateLock, layout = {} } = attributes; const { contentSize, wideSize } = layout; - const innerBlocksProps = useInnerBlocksProps( - { - className: classnames( 'wp-block-group__inner-container', { - [ `wp-container-${ layout.id }` ]: !! layout.id, - } ), - }, - { - templateLock, - renderAppender: hasInnerBlocks - ? undefined - : InnerBlocks.ButtonBlockAppender, - __experimentalLayout: { - type: 'default', - alignments: - contentSize || wideSize - ? [ 'wide', 'full' ] - : [ 'left', 'center', 'right' ], - }, - } + const blockProps = useBlockProps( { + className: classnames( { + [ `wp-container-${ id }` ]: contentSize || wideSize, + } ), + } ); + /* TODO: find a way to render this extra div as a child of the inner block wrapper + const extraChildren = ( + ); + */ + const innerBlocksProps = useInnerBlocksProps( blockProps, { + templateLock, + renderAppender: hasInnerBlocks + ? undefined + : InnerBlocks.ButtonBlockAppender, + __experimentalLayout: { + type: 'default', + // TODO: only pass this if the theme supports the new alignments. + // otherwise make all alignments avaiable. + alignments: + contentSize || wideSize + ? [ 'wide', 'full' ] + : [ 'left', 'center', 'right' ], + }, + } ); return ( <> @@ -105,7 +113,6 @@ function GroupEdit( { attributes, setAttributes, clientId } ) { setAttributes( { layout: { ...defaultLayout, - id: layout.id ?? uuid(), }, } ); } } @@ -125,7 +132,6 @@ function GroupEdit( { attributes, setAttributes, clientId } ) { layout: { ...layout, contentSize: nextWidth, - id: layout.id ?? uuid(), }, } ); } } @@ -143,7 +149,6 @@ function GroupEdit( { attributes, setAttributes, clientId } ) { layout: { ...layout, wideSize: nextWidth, - id: layout.id ?? uuid(), }, } ); } } @@ -169,32 +174,26 @@ function GroupEdit( { attributes, setAttributes, clientId } ) { } /> - - { ( wideSize || contentSize ) && ( - - ) } - -
- + + ) } + ); } diff --git a/packages/block-library/src/group/index.php b/packages/block-library/src/group/index.php new file mode 100644 index 0000000000000..66a3fc327bb52 --- /dev/null +++ b/packages/block-library/src/group/index.php @@ -0,0 +1,67 @@ + + + 'render_block_core_group', + ) + ); +} +add_action( 'init', 'register_block_core_group' ); diff --git a/packages/block-library/src/group/save.js b/packages/block-library/src/group/save.js index de904a78232ed..60e4dbd30a8f5 100644 --- a/packages/block-library/src/group/save.js +++ b/packages/block-library/src/group/save.js @@ -1,44 +1,13 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ import { InnerBlocks, useBlockProps } from '@wordpress/block-editor'; export default function save( { attributes } ) { - const { tagName: Tag, layout = {} } = attributes; - const { contentSize, wideSize } = layout; - const className = classnames( 'wp-block-group__inner-container', { - [ `wp-container-${ layout.id }` ]: !! layout.id, - } ); - + const { tagName: Tag } = attributes; return ( - { ( contentSize || wideSize ) && ( - - ) } -
- -
+
); } diff --git a/packages/blocks/src/api/test/parser.js b/packages/blocks/src/api/test/parser.js index add399395072b..cba52a0f33d6a 100644 --- a/packages/blocks/src/api/test/parser.js +++ b/packages/blocks/src/api/test/parser.js @@ -777,14 +777,14 @@ describe( 'block parser', () => {
-
+
  • B
  • C

D

-
+
@@ -839,14 +839,13 @@ describe( 'block parser', () => { innerContent: [ '

D

' ], }, ], - innerHTML: - '
', + innerHTML: '
', innerContent: [ - '
', + '
', null, '', null, - '
', + '
', ], }, ], From 69945a7281786d792590d18d64c4550cad57eefa Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 1 Mar 2021 10:23:25 +0100 Subject: [PATCH 03/24] Implement the layout addition to the group block as a support flag --- lib/block-supports/layout.php | 93 ++++++++ lib/blocks.php | 2 +- lib/load.php | 1 + packages/block-editor/src/hooks/index.js | 1 + packages/block-editor/src/hooks/layout.js | 231 ++++++++++++++++++++ packages/block-library/src/group/block.json | 13 +- packages/block-library/src/group/edit.js | 99 +-------- packages/block-library/src/group/index.php | 67 ------ 8 files changed, 336 insertions(+), 171 deletions(-) create mode 100644 lib/block-supports/layout.php create mode 100644 packages/block-editor/src/hooks/layout.js delete mode 100644 packages/block-library/src/group/index.php diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php new file mode 100644 index 0000000000000..59ef8ec93c49b --- /dev/null +++ b/lib/block-supports/layout.php @@ -0,0 +1,93 @@ +supports, array( '__experimentalLayout' ), false ); + } + if ( $support_layout ) { + if ( ! $block_type->attributes ) { + $block_type->attributes = array(); + } + + if ( ! array_key_exists( 'layout', $block_type->attributes ) ) { + $block_type->attributes['layout'] = array( + 'type' => 'object', + ); + } + } +} + +/** + * Renders the layout config to the block wrapper. + * + * @param string $block_content Rendered block content. + * @param array $block Block object. + * @return string Filtered block content. + */ +function gutenberg_render_layout_support_flag( $block_content, $block ) { + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); + $support_layout = false; + if ( $block_type && property_exists( $block_type, 'supports' ) ) { + $support_layout = gutenberg_experimental_get( $block_type->supports, array( '__experimentalLayout' ), false ); + } + if ( ! $support_layout || ! isset( $block['attrs']['layout'] ) ) { + return $block_content; + } + + $attributes = $block['attrs']; + $id = uniqid(); + $content_size = isset( $attributes['layout']['contentSize'] ) ? $attributes['layout']['contentSize'] : null; + $wide_size = isset( $attributes['layout']['wideSize'] ) ? $attributes['layout']['wideSize'] : null; + if ( ! $content_size && ! $wide_size ) { + return $block_content; + } + ob_start(); + ?> + + register( + 'layout', + array( + 'register_attribute' => 'gutenberg_register_layout_support', + ) +); +add_filter( 'render_block', 'gutenberg_render_layout_support_flag', 10, 2 ); diff --git a/lib/blocks.php b/lib/blocks.php index 0d12270b2bfa0..70f9ec44cb32e 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -23,6 +23,7 @@ function gutenberg_reregister_core_block_types() { 'columns', 'file', 'gallery', + 'group', 'heading', 'html', 'image', @@ -53,7 +54,6 @@ function gutenberg_reregister_core_block_types() { 'calendar.php' => 'core/calendar', 'categories.php' => 'core/categories', 'cover.php' => 'core/cover', - 'group.php' => 'core/group', 'latest-comments.php' => 'core/latest-comments', 'latest-posts.php' => 'core/latest-posts', 'navigation.php' => 'core/navigation', diff --git a/lib/load.php b/lib/load.php index 0ac067e9d8166..86478a886327f 100644 --- a/lib/load.php +++ b/lib/load.php @@ -120,3 +120,4 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/block-supports/typography.php'; require __DIR__ . '/block-supports/custom-classname.php'; require __DIR__ . '/block-supports/border.php'; +require __DIR__ . '/block-supports/layout.php'; diff --git a/packages/block-editor/src/hooks/index.js b/packages/block-editor/src/hooks/index.js index 6aa2b76fc1d1f..c087e994ba9eb 100644 --- a/packages/block-editor/src/hooks/index.js +++ b/packages/block-editor/src/hooks/index.js @@ -8,3 +8,4 @@ import './generated-class-name'; import './style'; import './color'; import './font-size'; +import './layout'; diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js new file mode 100644 index 0000000000000..412cf22a9b41a --- /dev/null +++ b/packages/block-editor/src/hooks/layout.js @@ -0,0 +1,231 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { has } from 'lodash'; + +/** + * WordPress dependencies + */ +import { Platform } from '@wordpress/element'; +import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose'; +import { addFilter } from '@wordpress/hooks'; +import { hasBlockSupport } from '@wordpress/blocks'; +import { useSelect } from '@wordpress/data'; +import { + PanelBody, + __experimentalUnitControl as UnitControl, + Button, +} from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../store'; +import { InspectorControls } from '../components'; + +const isWeb = Platform.OS === 'web'; +const CSS_UNITS = [ + { + value: '%', + label: isWeb ? '%' : __( 'Percentage (%)' ), + default: '', + }, + { + value: 'px', + label: isWeb ? 'px' : __( 'Pixels (px)' ), + default: '', + }, + { + value: 'em', + label: isWeb ? 'em' : __( 'Relative to parent font size (em)' ), + default: '', + }, + { + value: 'rem', + label: isWeb ? 'rem' : __( 'Relative to root font size (rem)' ), + default: '', + }, + { + value: 'vw', + label: isWeb ? 'vw' : __( 'Viewport width (vw)' ), + default: '', + }, +]; + +function LayoutPanel( { setAttributes, attributes } ) { + const { layout = {} } = attributes; + const { wideSize, contentSize } = layout; + const defaultLayout = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + return getSettings().__experimentalFeatures?.defaults?.layout; + }, [] ); + return ( + + + { !! defaultLayout && ( + + ) } + { + nextWidth = + 0 > parseFloat( nextWidth ) ? '0' : nextWidth; + setAttributes( { + layout: { + ...layout, + contentSize: nextWidth, + }, + } ); + } } + units={ CSS_UNITS } + /> + { + nextWidth = + 0 > parseFloat( nextWidth ) ? '0' : nextWidth; + setAttributes( { + layout: { + ...layout, + wideSize: nextWidth, + }, + } ); + } } + units={ CSS_UNITS } + /> + + + ); +} + +/** + * Filters registered block settings, extending attributes to include `layout`. + * + * @param {Object} settings Original block settings + * @return {Object} Filtered block settings + */ +export function addAttribute( settings ) { + if ( has( settings.attributes, [ 'layout', 'type' ] ) ) { + return settings; + } + if ( hasBlockSupport( settings, '__experimentalLayout' ) ) { + settings.attributes = { + ...settings.attributes, + layout: { + type: 'object', + }, + }; + } + + return settings; +} + +/** + * Override the default edit UI to include layout controls + * + * @param {Function} BlockEdit Original component + * @return {Function} Wrapped component + */ +export const withInspectorControls = createHigherOrderComponent( + ( BlockEdit ) => ( props ) => { + const { name: blockName } = props; + const supportLayout = hasBlockSupport( + blockName, + '__experimentalLayout' + ); + + return [ + supportLayout && , + , + ]; + }, + 'withInspectorControls' +); + +/** + * Override the default block element to add the layout styles. + * + * @param {Function} BlockListBlock Original component + * @return {Function} Wrapped component + */ +export const withLayoutStyles = createHigherOrderComponent( + ( BlockListBlock ) => ( props ) => { + const { name, attributes } = props; + const supportLayout = hasBlockSupport( name, '__experimentalLayout' ); + const id = useInstanceId( BlockListBlock ); + if ( ! supportLayout === undefined ) { + return ; + } + const { layout = {} } = attributes; + const { wideSize, contentSize } = layout; + if ( ! wideSize && ! contentSize ) { + return ; + } + + const wrapperProps = { + ...props.wrapperProps, + className: classnames( + wrapperProps?.className, + `wp-container-${ id }` + ), + }; + + return ( + <> + + + + ); + } +); + +addFilter( + 'blocks.registerBlockType', + 'core/layout/addAttribute', + addAttribute +); +addFilter( + 'editor.BlockListBlock', + 'core/editor/layout/with-layout-styles', + withLayoutStyles +); +addFilter( + 'editor.BlockEdit', + 'core/editor/layout/with-inspector-controls', + withInspectorControls +); diff --git a/packages/block-library/src/group/block.json b/packages/block-library/src/group/block.json index 9f164fddd31d9..2cbf1613e3450 100644 --- a/packages/block-library/src/group/block.json +++ b/packages/block-library/src/group/block.json @@ -9,16 +9,10 @@ }, "templateLock": { "type": "string" - }, - "layout": { - "type": "object" - } + }, "supports": { - "align": [ - "wide", - "full" - ], + "align": [ "wide", "full" ], "anchor": true, "html": false, "color": { @@ -33,7 +27,8 @@ "radius": true, "style": true, "width": true - } + }, + "__experimentalLayout": true }, "editorStyle": "wp-block-group-editor", "style": "wp-block-group" diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 164142b495340..436dc67db1956 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ @@ -12,19 +7,14 @@ import { InnerBlocks, useBlockProps, InspectorAdvancedControls, - InspectorControls, __experimentalUseInnerBlocksProps as useInnerBlocksProps, store as blockEditorStore, } from '@wordpress/block-editor'; import { SelectControl, - PanelBody, __experimentalBoxControl as BoxControl, - __experimentalUnitControl as UnitControl, - Button, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useInstanceId } from '@wordpress/compose'; const { __Visualizer: BoxControlVisualizer } = BoxControl; const isWeb = Platform.OS === 'web'; @@ -58,26 +48,17 @@ export const CSS_UNITS = [ ]; function GroupEdit( { attributes, setAttributes, clientId } ) { - const id = useInstanceId( GroupEdit ); - const { defaultLayout, hasInnerBlocks } = useSelect( + const hasInnerBlocks = useSelect( ( select ) => { - const { getBlock, getSettings } = select( blockEditorStore ); + const { getBlock } = select( blockEditorStore ); const block = getBlock( clientId ); - return { - defaultLayout: getSettings().__experimentalFeatures?.defaults - ?.layout, - hasInnerBlocks: !! ( block && block.innerBlocks.length ), - }; + return !! ( block && block.innerBlocks.length ); }, [ clientId ] ); const { tagName: TagName = 'div', templateLock, layout = {} } = attributes; const { contentSize, wideSize } = layout; - const blockProps = useBlockProps( { - className: classnames( { - [ `wp-container-${ id }` ]: contentSize || wideSize, - } ), - } ); + const blockProps = useBlockProps(); /* TODO: find a way to render this extra div as a child of the inner block wrapper const extraChildren = ( - - - { !! defaultLayout && ( - - ) } - { - nextWidth = - 0 > parseFloat( nextWidth ) ? '0' : nextWidth; - setAttributes( { - layout: { - ...layout, - contentSize: nextWidth, - }, - } ); - } } - units={ CSS_UNITS } - /> - { - nextWidth = - 0 > parseFloat( nextWidth ) ? '0' : nextWidth; - setAttributes( { - layout: { - ...layout, - wideSize: nextWidth, - }, - } ); - } } - units={ CSS_UNITS } - /> - - - { ( wideSize || contentSize ) && ( - - ) } ); diff --git a/packages/block-library/src/group/index.php b/packages/block-library/src/group/index.php deleted file mode 100644 index 66a3fc327bb52..0000000000000 --- a/packages/block-library/src/group/index.php +++ /dev/null @@ -1,67 +0,0 @@ - - - 'render_block_core_group', - ) - ); -} -add_action( 'init', 'register_block_core_group' ); From 6ede44f7e92e1acda5fb5ec5a1fc65431b61b447 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 1 Mar 2021 14:56:23 +0100 Subject: [PATCH 04/24] Only enable layouts for themes with theme.json --- lib/client-assets.php | 4 ++ packages/base-styles/_mixins.scss | 18 ----- packages/block-editor/src/hooks/layout.js | 25 ++++--- packages/block-editor/src/store/defaults.js | 3 + packages/block-library/src/group/edit.js | 22 +++--- .../edit-post/src/components/layout/index.js | 7 +- .../src/components/layout/style.scss | 70 +++++++++++++++++++ packages/edit-post/src/style.scss | 1 - packages/edit-site/src/style.scss | 1 - .../provider/use-block-editor-settings.js | 1 + packages/editor/src/store/defaults.js | 2 + 11 files changed, 112 insertions(+), 42 deletions(-) diff --git a/lib/client-assets.php b/lib/client-assets.php index ef74ce9e02512..efa5aa79814d9 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -688,6 +688,10 @@ function gutenberg_extend_block_editor_settings_with_default_editor_styles( $set */ function gutenberg_extend_block_editor_settings_with_fse_theme_flag( $settings ) { $settings['isFSETheme'] = gutenberg_is_fse_theme(); + + // Enable the new layout options for themes with a theme.json file. + $settings['supportsLayout'] = WP_Theme_JSON_Resolver::theme_has_support(); + return $settings; } add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_settings_with_fse_theme_flag' ); diff --git a/packages/base-styles/_mixins.scss b/packages/base-styles/_mixins.scss index b38d37c505e48..2b01b965b4d30 100644 --- a/packages/base-styles/_mixins.scss +++ b/packages/base-styles/_mixins.scss @@ -694,21 +694,3 @@ } /* stylelint-enable function-comma-space-after */ } - -/** - * These are default block editor widths in case the theme doesn't provide them. - */ -@mixin default-block-widths { - - .wp-block { - max-width: $content-width; - - &[data-align="wide"] { - max-width: $wide-content-width; - } - - &[data-align="full"] { - max-width: none; - } - } -} diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 412cf22a9b41a..c4b070b4761e0 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -57,10 +57,18 @@ const CSS_UNITS = [ function LayoutPanel( { setAttributes, attributes } ) { const { layout = {} } = attributes; const { wideSize, contentSize } = layout; - const defaultLayout = useSelect( ( select ) => { + const { defaultLayout, themeSupportsLayout } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); - return getSettings().__experimentalFeatures?.defaults?.layout; + const settings = getSettings(); + return { + defaultLayout: settings.__experimentalFeatures?.defaults?.layout, + themeSupportsLayout: settings?.supportsLayout, + }; }, [] ); + + if ( ! themeSupportsLayout ) { + return null; + } return ( @@ -181,13 +189,10 @@ export const withLayoutStyles = createHigherOrderComponent( return ; } - const wrapperProps = { - ...props.wrapperProps, - className: classnames( - wrapperProps?.className, - `wp-container-${ id }` - ), - }; + const className = classnames( + props?.className, + `wp-container-${ id }` + ); return ( <> @@ -208,7 +213,7 @@ export const withLayoutStyles = createHigherOrderComponent( } ` } - + ); } diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index ba608d34a35f8..0056a89f2ef17 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -12,6 +12,7 @@ export const PREFERENCES_DEFAULTS = { * * @typedef {Object} SETTINGS_DEFAULT * @property {boolean} alignWide Enable/Disable Wide/Full Alignments + * @property {boolean} supportsLayout Enable/disable layouts support in container blocks. * @property {Array} availableLegacyWidgets Array of objects representing the legacy widgets available. * @property {boolean} imageEditing Image Editing settings set to false to disable. * @property {Array} imageSizes Available image sizes @@ -31,6 +32,8 @@ export const PREFERENCES_DEFAULTS = { */ export const SETTINGS_DEFAULTS = { alignWide: false, + supportsLayout: true, + // colors setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults. // The setting is only kept for backward compatibility purposes. colors: [ diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 436dc67db1956..9e8f0d9ded846 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -48,16 +48,23 @@ export const CSS_UNITS = [ ]; function GroupEdit( { attributes, setAttributes, clientId } ) { - const hasInnerBlocks = useSelect( + const { hasInnerBlocks, themeSupportsLayout } = useSelect( ( select ) => { - const { getBlock } = select( blockEditorStore ); + const { getBlock, getSettings } = select( blockEditorStore ); const block = getBlock( clientId ); - return !! ( block && block.innerBlocks.length ); + return { + hasInnerBlocks: !! ( block && block.innerBlocks.length ), + themeSupportsLayout: getSettings()?.supportsLayout, + }; }, [ clientId ] ); const { tagName: TagName = 'div', templateLock, layout = {} } = attributes; const { contentSize, wideSize } = layout; + const alignments = + contentSize || wideSize + ? [ 'wide', 'full' ] + : [ 'left', 'center', 'right' ]; const blockProps = useBlockProps(); /* TODO: find a way to render this extra div as a child of the inner block wrapper const extraChildren = ( @@ -74,13 +81,8 @@ function GroupEdit( { attributes, setAttributes, clientId } ) { : InnerBlocks.ButtonBlockAppender, __experimentalLayout: { type: 'default', - // TODO: only pass this if the theme supports the new alignments. - // otherwise make all alignments avaiable. - // Find a way to inject this using the support flag. - alignments: - contentSize || wideSize - ? [ 'wide', 'full' ] - : [ 'left', 'center', 'right' ], + // Find a way to inject this in the support flag code (hooks). + alignments: themeSupportsLayout ? alignments : undefined, }, } ); diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index f2acd3ac38735..0c9da0ae76a82 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -94,7 +94,9 @@ function Layout( { styles } ) { showIconLabels, hasReducedUI, showBlockBreadcrumbs, + supportsLayout, } = useSelect( ( select ) => { + const editorSettings = select( 'core/editor' ).getEditorSettings(); return { hasFixedToolbar: select( editPostStore ).isFeatureActive( 'fixedToolbar' @@ -112,8 +114,8 @@ function Layout( { styles } ) { ), isInserterOpened: select( editPostStore ).isInserterOpened(), mode: select( editPostStore ).getEditorMode(), - isRichEditingEnabled: select( 'core/editor' ).getEditorSettings() - .richEditingEnabled, + isRichEditingEnabled: editorSettings.richEditingEnabled, + supportsLayout: editorSettings.supportsLayout, hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), previousShortcut: select( keyboardShortcutsStore @@ -139,6 +141,7 @@ function Layout( { styles } ) { 'has-fixed-toolbar': hasFixedToolbar, 'has-metaboxes': hasActiveMetaboxes, 'show-icon-labels': showIconLabels, + 'supports-layout': supportsLayout, } ); const openSidebarPanel = () => openGeneralSidebar( diff --git a/packages/edit-post/src/components/layout/style.scss b/packages/edit-post/src/components/layout/style.scss index e2c3a144674b5..9a672704fac3a 100644 --- a/packages/edit-post/src/components/layout/style.scss +++ b/packages/edit-post/src/components/layout/style.scss @@ -115,3 +115,73 @@ height: 100%; } } + +// Depreacted style needed for the block widths and alignments. +.edit-post-layout:not(.supports-layout) { + .wp-block { + max-width: $content-width; + + &[data-align="wide"] { + max-width: $wide-content-width; + } + + &[data-align="full"] { + max-width: none; + } + } + + // Full Width Blocks + // specificity required to only target immediate child Blocks of a Group + .wp-block-group > [data-align="full"] { + margin-left: auto; + margin-right: auto; + } + + // Full Width Blocks with a background (ie: has padding) + .wp-block-group.has-background > [data-align="full"] { + // note: using position `left` causes hoz scrollbars so + // we opt to use margin instead + // the 30px matches the hoz padding applied in `theme.scss` + // added when the Block has a background set + margin-left: -30px; + + // 60px here is x2 the hoz padding from `theme.scss` added when + // the Block has a background set + // note: also duplicated below for full width Groups + width: calc(100% + 60px); + } + + /** + * Group: Full Width Alignment + */ + [data-align="full"] .wp-block-group { + + // Non-full Width Blocks + // specificity required to only target immediate child Blocks of Group + > .wp-block { + padding-left: $block-padding; + padding-right: $block-padding; + + @include break-small() { + padding-left: 0; + padding-right: 0; + } + } + + // Full Width Blocks + // specificity required to only target immediate child Blocks of Group + > [data-align="full"] { + padding-right: 0; + padding-left: 0; + left: 0; + width: 100%; + max-width: none; + } + + // Full Width Blocks with a background (ie: has padding) + // note: also duplicated above for all Group widths + &.has-background > [data-align="full"] { + width: calc(100% + 60px); + } + } +} diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index 6c13a6a8d4ad2..22ed97d362d86 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -100,5 +100,4 @@ body.block-editor-page { } } -@include default-block-widths(); @include wordpress-admin-schemes(); diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 2cd9607737d4a..42894cd6e4ecf 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -76,4 +76,3 @@ body.toplevel_page_gutenberg-edit-site { } @include wordpress-admin-schemes(); -// @include default-block-widths(); diff --git a/packages/editor/src/components/provider/use-block-editor-settings.js b/packages/editor/src/components/provider/use-block-editor-settings.js index 67546ff6710cd..4198af22591d3 100644 --- a/packages/editor/src/components/provider/use-block-editor-settings.js +++ b/packages/editor/src/components/provider/use-block-editor-settings.js @@ -186,6 +186,7 @@ function useBlockEditorSettings( settings, hasTemplate ) { 'template', 'templateLock', 'titlePlaceholder', + 'supportsLayout', ] ), mediaUpload: hasUploadPermissions ? mediaUpload : undefined, __experimentalReusableBlocks: reusableBlocks, diff --git a/packages/editor/src/store/defaults.js b/packages/editor/src/store/defaults.js index 5399999001d42..94125a58f1392 100644 --- a/packages/editor/src/store/defaults.js +++ b/packages/editor/src/store/defaults.js @@ -20,6 +20,7 @@ export const PREFERENCES_DEFAULTS = { * disablePostFormats boolean Whether or not the post formats are disabled * allowedMimeTypes array? List of allowed mime types and file extensions * maxUploadFileSize number Maximum upload file size + * supportsLayout boolean Whether the editor supports layouts. */ export const EDITOR_SETTINGS_DEFAULTS = { ...SETTINGS_DEFAULTS, @@ -27,4 +28,5 @@ export const EDITOR_SETTINGS_DEFAULTS = { richEditingEnabled: true, codeEditingEnabled: true, enableCustomFields: false, + supportsLayout: true, }; From 192f0695fe0401fa31a4297d61987b8ec751e5b7 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 2 Mar 2021 13:01:59 +0100 Subject: [PATCH 05/24] Support post content layout --- packages/block-editor/README.md | 1 + .../components/block-alignment-control/ui.js | 2 +- .../src/components/block-list/index.js | 13 +++-- .../src/components/block-list/layout.js | 54 +++++++++++++++++++ packages/block-editor/src/components/index.js | 1 + .../src/components/inner-blocks/index.js | 26 ++++----- .../components/inner-blocks/index.native.js | 2 +- .../src/components/inner-blocks/layout.js | 20 ------- .../components/use-editor-feature/index.js | 14 +++-- packages/block-editor/src/hooks/layout.js | 32 ++++------- packages/block-library/src/group/block.json | 2 +- .../src/components/visual-editor/index.js | 33 +++++++++++- 12 files changed, 130 insertions(+), 70 deletions(-) create mode 100644 packages/block-editor/src/components/block-list/layout.js delete mode 100644 packages/block-editor/src/components/inner-blocks/layout.js diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 55653a083dd7c..6d2dc9a0d94de 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -490,6 +490,7 @@ _Type Definition_ _Properties_ - _alignWide_ `boolean`: Enable/Disable Wide/Full Alignments +- _supportsLayout_ `boolean`: Enable/disable layouts support in container blocks. - _availableLegacyWidgets_ `Array`: Array of objects representing the legacy widgets available. - _imageEditing_ `boolean`: Image Editing settings set to false to disable. - _imageSizes_ `Array`: Available image sizes diff --git a/packages/block-editor/src/components/block-alignment-control/ui.js b/packages/block-editor/src/components/block-alignment-control/ui.js index 2e7a430e84d61..33682e7bfcee7 100644 --- a/packages/block-editor/src/components/block-alignment-control/ui.js +++ b/packages/block-editor/src/components/block-alignment-control/ui.js @@ -15,7 +15,7 @@ import { /** * Internal dependencies */ -import { useLayout } from '../inner-blocks/layout'; +import { useLayout } from '../block-list/layout'; import { store as blockEditorStore } from '../../store'; const BLOCK_ALIGNMENTS_CONTROLS = { diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index f1da838a8c752..7047e0163d5dc 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -19,11 +19,12 @@ import useInsertionPoint from './insertion-point'; import BlockPopover from './block-popover'; import { store as blockEditorStore } from '../../store'; import { useScrollSelectionIntoView } from '../selection-scroll-into-view'; +import { LayoutProvider, defaultLayout } from './layout'; export const BlockNodes = createContext(); export const SetBlockNodes = createContext(); -export default function BlockList( { className } ) { +export default function BlockList( { className, __experimentalLayout } ) { const ref = useRef(); const [ blockNodes, setBlockNodes ] = useState( {} ); const insertionPoint = useInsertionPoint( ref ); @@ -41,7 +42,10 @@ export default function BlockList( { className } ) { ) } > - +
@@ -53,6 +57,7 @@ function Items( { rootClientId, renderAppender, __experimentalAppenderTagName, + __experimentalLayout: layout = defaultLayout, wrapperRef, } ) { function selector( select ) { @@ -88,7 +93,7 @@ function Items( { const isAppenderDropTarget = dropTargetIndex === blockClientIds.length; return ( - <> + { blockClientIds.map( ( clientId, index ) => { const isBlockInSelection = hasMultiSelection ? multiSelectedBlockClientIds.includes( clientId ) @@ -129,7 +134,7 @@ function Items( { isAppenderDropTarget && orientation === 'horizontal', } ) } /> - + ); } diff --git a/packages/block-editor/src/components/block-list/layout.js b/packages/block-editor/src/components/block-list/layout.js new file mode 100644 index 0000000000000..286b04c8f14dd --- /dev/null +++ b/packages/block-editor/src/components/block-list/layout.js @@ -0,0 +1,54 @@ +/** + * WordPress dependencies + */ +import { createContext, useContext } from '@wordpress/element'; + +export const defaultLayout = { type: 'default' }; + +const Layout = createContext( defaultLayout ); + +function appendSelectors( selectors, append ) { + return selectors + .split( ',' ) + .map( ( subselector ) => subselector + ' ' + append ) + .join( ',' ); +} + +/** + * Allows to define the layout. + */ +export const LayoutProvider = Layout.Provider; + +/** + * React hook used to retrieve the layout config. + */ +export function useLayout() { + return useContext( Layout ); +} + +export function LayoutStyle( { selector, layout = {} } ) { + const { contentSize, wideSize } = layout; + if ( ! contentSize && ! wideSize ) { + return null; + } + + return ( + + ); +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 16977e34af497..a77da2f752377 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -84,6 +84,7 @@ export { default as BlockInspector } from './block-inspector'; export { default as BlockList } from './block-list'; export { useBlockProps } from './block-list/use-block-props'; export { Block as __experimentalBlock } from './block-list/block-wrapper'; +export { LayoutStyle as __experimentalLayoutStyle } from './block-list/layout'; export { default as BlockMover } from './block-mover'; export { default as BlockPreview } from './block-preview'; export { diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index 7d8db1f019e86..e826f3f9a1c52 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -23,7 +23,6 @@ import { BlockListItems } from '../block-list'; import { BlockContextProvider } from '../block-context'; import { useBlockEditContext } from '../block-edit/context'; import useBlockSync from '../provider/use-block-sync'; -import { defaultLayout, LayoutProvider } from './layout'; import { store as blockEditorStore } from '../../store'; /** @@ -47,7 +46,7 @@ function UncontrolledInnerBlocks( props ) { renderAppender, orientation, placeholder, - __experimentalLayout: layout = defaultLayout, + __experimentalLayout, } = props; useNestedSettingsUpdate( @@ -82,19 +81,16 @@ function UncontrolledInnerBlocks( props ) { // This component needs to always be synchronous as it's the one changing // the async mode depending on the block selection. return ( - - - - - + + + ); } diff --git a/packages/block-editor/src/components/inner-blocks/index.native.js b/packages/block-editor/src/components/inner-blocks/index.native.js index 4681b5e6f9ff3..d866fc5f6402c 100644 --- a/packages/block-editor/src/components/inner-blocks/index.native.js +++ b/packages/block-editor/src/components/inner-blocks/index.native.js @@ -20,7 +20,7 @@ import BlockList from '../block-list'; import { useBlockEditContext } from '../block-edit/context'; import useBlockSync from '../provider/use-block-sync'; import { BlockContextProvider } from '../block-context'; -import { defaultLayout, LayoutProvider } from './layout'; +import { defaultLayout, LayoutProvider } from './block-list/layout'; import { store as blockEditorStore } from '../../store'; /** diff --git a/packages/block-editor/src/components/inner-blocks/layout.js b/packages/block-editor/src/components/inner-blocks/layout.js deleted file mode 100644 index 745b59945ea61..0000000000000 --- a/packages/block-editor/src/components/inner-blocks/layout.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * WordPress dependencies - */ -import { createContext, useContext } from '@wordpress/element'; - -export const defaultLayout = { type: 'default' }; - -const Layout = createContext( defaultLayout ); - -/** - * Allows to define the layout. - */ -export const LayoutProvider = Layout.Provider; - -/** - * React hook used to retrieve the layout config. - */ -export function useLayout() { - return useContext( Layout ); -} diff --git a/packages/block-editor/src/components/use-editor-feature/index.js b/packages/block-editor/src/components/use-editor-feature/index.js index 68f6e9e0cd8f2..485161681b365 100644 --- a/packages/block-editor/src/components/use-editor-feature/index.js +++ b/packages/block-editor/src/components/use-editor-feature/index.js @@ -63,7 +63,8 @@ function blockAttributesMatch( blockAttributes, attributes ) { * Hook that retrieves the setting for the given editor feature. * It works with nested objects using by finding the value at path. * - * @param {string} featurePath The path to the feature. + * @param {string} featurePath The path to the feature. + * @param {Object?} options Options. * * @return {any} Returns the value defined for the setting. * @@ -72,8 +73,13 @@ function blockAttributesMatch( blockAttributes, attributes ) { * const isEnabled = useEditorFeature( 'typography.dropCap' ); * ``` */ -export default function useEditorFeature( featurePath ) { - const { name: blockName, clientId } = useBlockEditContext(); +export default function useEditorFeature( + featurePath, + { __unstableForceContext } = {} +) { + const blockEditContext = useBlockEditContext(); + const { name: blockName, clientId } = + __unstableForceContext ?? blockEditContext; const setting = useSelect( ( select ) => { @@ -88,7 +94,7 @@ export default function useEditorFeature( featurePath ) { 'supports', '__experimentalSelector', ] ); - if ( isObject( selectors ) ) { + if ( clientId && isObject( selectors ) ) { const blockAttributes = getBlockAttributes( clientId ) || {}; for ( const contextSelector in selectors ) { const { attributes } = selectors[ contextSelector ]; diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index c4b070b4761e0..f151b18a5254e 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -24,6 +24,8 @@ import { __ } from '@wordpress/i18n'; */ import { store as blockEditorStore } from '../store'; import { InspectorControls } from '../components'; +import useEditorFeature from '../components/use-editor-feature'; +import { LayoutStyle } from '../components/block-list/layout'; const isWeb = Platform.OS === 'web'; const CSS_UNITS = [ @@ -57,13 +59,10 @@ const CSS_UNITS = [ function LayoutPanel( { setAttributes, attributes } ) { const { layout = {} } = attributes; const { wideSize, contentSize } = layout; - const { defaultLayout, themeSupportsLayout } = useSelect( ( select ) => { + const defaultLayout = useEditorFeature( 'layout' ); + const themeSupportsLayout = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); - const settings = getSettings(); - return { - defaultLayout: settings.__experimentalFeatures?.defaults?.layout, - themeSupportsLayout: settings?.supportsLayout, - }; + return getSettings().supportsLayout; }, [] ); if ( ! themeSupportsLayout ) { @@ -196,23 +195,10 @@ export const withLayoutStyles = createHigherOrderComponent( return ( <> - + ); diff --git a/packages/block-library/src/group/block.json b/packages/block-library/src/group/block.json index 2cbf1613e3450..ad4cc62fc68a7 100644 --- a/packages/block-library/src/group/block.json +++ b/packages/block-library/src/group/block.json @@ -9,7 +9,7 @@ }, "templateLock": { "type": "string" - + } }, "supports": { "align": [ "wide", "full" ], diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 76891cd8449b9..8f7207b19c4fe 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -8,6 +8,7 @@ import { import { WritingFlow, BlockList, + store as blockEditorStore, __unstableUseBlockSelectionClearer as useBlockSelectionClearer, __unstableUseTypewriter as useTypewriter, __unstableUseClipboardHandler as useClipboardHandler, @@ -16,6 +17,8 @@ import { __experimentalUseResizeCanvas as useResizeCanvas, __unstableUseCanvasClickRedirect as useCanvasClickRedirect, __unstableEditorStyles as EditorStyles, + __experimentalUseEditorFeature as useEditorFeature, + __experimentalLayoutStyle as LayoutStyle, } from '@wordpress/block-editor'; import { Popover } from '@wordpress/components'; import { useRef } from '@wordpress/element'; @@ -44,6 +47,10 @@ export default function VisualEditor( { styles } ) { ( select ) => select( editPostStore ).hasMetaBoxes(), [] ); + const themeSupportsLayout = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + return getSettings().supportsLayout; + }, [] ); const desktopCanvasStyles = { height: '100%', // Add a constant padding for the typewritter effect. When typing at the @@ -51,6 +58,14 @@ export default function VisualEditor( { styles } ) { paddingBottom: hasMetaBoxes ? null : '40vh', }; const resizedCanvasStyles = useResizeCanvas( deviceType ); + const defaultLayout = useEditorFeature( 'layout', { + __unstableForceContext: { name: 'post/content' }, + } ); + const { contentSize, wideSize } = defaultLayout || {}; + const alignments = + contentSize || wideSize + ? [ 'wide', 'full' ] + : [ 'left', 'center', 'right' ]; const mergedRefs = useMergeRefs( [ ref, @@ -63,6 +78,10 @@ export default function VisualEditor( { styles } ) { return (
+ @@ -77,7 +96,19 @@ export default function VisualEditor( { styles } ) {
) } - +
<__experimentalBlockSettingsMenuFirstItem> From 21da8d4132b50356d720d3bf83717d34e4c7cda6 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 2 Mar 2021 13:11:40 +0100 Subject: [PATCH 06/24] Fix block name --- packages/edit-post/src/components/visual-editor/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 8f7207b19c4fe..390e6f5667ec4 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -59,7 +59,7 @@ export default function VisualEditor( { styles } ) { }; const resizedCanvasStyles = useResizeCanvas( deviceType ); const defaultLayout = useEditorFeature( 'layout', { - __unstableForceContext: { name: 'post/content' }, + __unstableForceContext: { name: 'core/post-content' }, } ); const { contentSize, wideSize } = defaultLayout || {}; const alignments = From 67f481c98da90450ea938522c77463428d4ddc6e Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 3 Mar 2021 10:40:48 +0100 Subject: [PATCH 07/24] Fix linting and unit tests --- .../components/inner-blocks/index.native.js | 2 +- packages/block-library/src/group/editor.scss | 2 +- .../fixtures/blocks/core__group.html | 15 +++--- .../fixtures/blocks/core__group.json | 2 +- .../fixtures/blocks/core__group.parsed.json | 16 +++---- .../blocks/core__group.serialized.html | 4 +- .../core__group__deprecated-2.serialized.html | 4 +- ...re__group__deprecated-inner-container.html | 13 ++++++ ...re__group__deprecated-inner-container.json | 37 +++++++++++++++ ...up__deprecated-inner-container.parsed.json | 46 +++++++++++++++++++ ...deprecated-inner-container.serialized.html | 9 ++++ .../blocks/core__group__deprecated.json | 4 +- .../core__group__deprecated.serialized.html | 4 +- 13 files changed, 130 insertions(+), 28 deletions(-) create mode 100644 packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.serialized.html diff --git a/packages/block-editor/src/components/inner-blocks/index.native.js b/packages/block-editor/src/components/inner-blocks/index.native.js index d866fc5f6402c..0b9401425e864 100644 --- a/packages/block-editor/src/components/inner-blocks/index.native.js +++ b/packages/block-editor/src/components/inner-blocks/index.native.js @@ -20,7 +20,7 @@ import BlockList from '../block-list'; import { useBlockEditContext } from '../block-edit/context'; import useBlockSync from '../provider/use-block-sync'; import { BlockContextProvider } from '../block-context'; -import { defaultLayout, LayoutProvider } from './block-list/layout'; +import { defaultLayout, LayoutProvider } from '../block-list/layout'; import { store as blockEditorStore } from '../../store'; /** diff --git a/packages/block-library/src/group/editor.scss b/packages/block-library/src/group/editor.scss index 5cda01e8df617..92103665aa8c8 100644 --- a/packages/block-library/src/group/editor.scss +++ b/packages/block-library/src/group/editor.scss @@ -11,7 +11,7 @@ } // Place block list appender in the same place content will appear. -[data-type='core/group'].is-selected { +[data-type="core/group"].is-selected { .block-list-appender { margin-left: 0; margin-right: 0; diff --git a/packages/e2e-tests/fixtures/blocks/core__group.html b/packages/e2e-tests/fixtures/blocks/core__group.html index e5df0f2fce926..df7eef39e3898 100644 --- a/packages/e2e-tests/fixtures/blocks/core__group.html +++ b/packages/e2e-tests/fixtures/blocks/core__group.html @@ -1,12 +1,9 @@ -
-
- -

This is a group block.

- +
+

This is a group block.

+ - -

Group block content.

-
-
+ +

Group block content.

+
diff --git a/packages/e2e-tests/fixtures/blocks/core__group.json b/packages/e2e-tests/fixtures/blocks/core__group.json index 526a8d70fbcdf..7fd0b5d60ba11 100644 --- a/packages/e2e-tests/fixtures/blocks/core__group.json +++ b/packages/e2e-tests/fixtures/blocks/core__group.json @@ -32,6 +32,6 @@ "originalContent": "

Group block content.

" } ], - "originalContent": "
\n\t
\n\t\t\n\n\t\t
\n\t
" + "originalContent": "
\n\n
" } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__group.parsed.json b/packages/e2e-tests/fixtures/blocks/core__group.parsed.json index ba86ac5a02d6b..a82a138ba4741 100644 --- a/packages/e2e-tests/fixtures/blocks/core__group.parsed.json +++ b/packages/e2e-tests/fixtures/blocks/core__group.parsed.json @@ -10,28 +10,28 @@ "blockName": "core/paragraph", "attrs": {}, "innerBlocks": [], - "innerHTML": "\n\t\t

This is a group block.

\n\t\t", + "innerHTML": "\n

This is a group block.

\n", "innerContent": [ - "\n\t\t

This is a group block.

\n\t\t" + "\n

This is a group block.

\n" ] }, { "blockName": "core/paragraph", "attrs": {}, "innerBlocks": [], - "innerHTML": "\n\t\t

Group block content.

\n\t\t", + "innerHTML": "\n

Group block content.

\n", "innerContent": [ - "\n\t\t

Group block content.

\n\t\t" + "\n

Group block content.

\n" ] } ], - "innerHTML": "\n
\n\t
\n\t\t\n\n\t\t
\n\t
\n", + "innerHTML": "\n
\n\n
\n", "innerContent": [ - "\n
\n\t
\n\t\t", + "\n
", null, - "\n\n\t\t", + "\n\n", null, - "
\n\t
\n" + "
\n" ] }, { diff --git a/packages/e2e-tests/fixtures/blocks/core__group.serialized.html b/packages/e2e-tests/fixtures/blocks/core__group.serialized.html index 8ac236255f9f6..df7eef39e3898 100644 --- a/packages/e2e-tests/fixtures/blocks/core__group.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__group.serialized.html @@ -1,9 +1,9 @@ -
+

This is a group block.

Group block content.

-
+
diff --git a/packages/e2e-tests/fixtures/blocks/core__group__deprecated-2.serialized.html b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-2.serialized.html index cf7ebe4f5a05e..1e25d657b8106 100644 --- a/packages/e2e-tests/fixtures/blocks/core__group__deprecated-2.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-2.serialized.html @@ -1,5 +1,5 @@ -
+

My paragraph

-
+
diff --git a/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.html b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.html new file mode 100644 index 0000000000000..9702e29ed52d6 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.html @@ -0,0 +1,13 @@ + +
+
+ +

This is a group block.

+ + + +

Group block content.

+ +
+
+ diff --git a/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.json b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.json new file mode 100644 index 0000000000000..2ca0de07bbb39 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.json @@ -0,0 +1,37 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/group", + "isValid": true, + "attributes": { + "tagName": "div", + "align": "full", + "backgroundColor": "secondary" + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/paragraph", + "isValid": true, + "attributes": { + "content": "This is a group block.", + "dropCap": false + }, + "innerBlocks": [], + "originalContent": "

This is a group block.

" + }, + { + "clientId": "_clientId_1", + "name": "core/paragraph", + "isValid": true, + "attributes": { + "content": "Group block content.", + "dropCap": false + }, + "innerBlocks": [], + "originalContent": "

Group block content.

" + } + ], + "originalContent": "
\n\t
\n\t\t\n\n\t\t\n\t
\n
" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.parsed.json b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.parsed.json new file mode 100644 index 0000000000000..9da531aefe611 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.parsed.json @@ -0,0 +1,46 @@ +[ + { + "blockName": "core/group", + "attrs": { + "align": "full", + "backgroundColor": "secondary" + }, + "innerBlocks": [ + { + "blockName": "core/paragraph", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n\t\t

This is a group block.

\n\t\t", + "innerContent": [ + "\n\t\t

This is a group block.

\n\t\t" + ] + }, + { + "blockName": "core/paragraph", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n\t\t

Group block content.

\n\t\t", + "innerContent": [ + "\n\t\t

Group block content.

\n\t\t" + ] + } + ], + "innerHTML": "\n
\n\t
\n\t\t\n\n\t\t\n\t
\n
\n", + "innerContent": [ + "\n
\n\t
\n\t\t", + null, + "\n\n\t\t", + null, + "\n\t
\n
\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.serialized.html b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.serialized.html new file mode 100644 index 0000000000000..df7eef39e3898 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__group__deprecated-inner-container.serialized.html @@ -0,0 +1,9 @@ + +
+

This is a group block.

+ + + +

Group block content.

+
+ diff --git a/packages/e2e-tests/fixtures/blocks/core__group__deprecated.json b/packages/e2e-tests/fixtures/blocks/core__group__deprecated.json index 7f1f51c3644e4..c67c67fc51cd8 100644 --- a/packages/e2e-tests/fixtures/blocks/core__group__deprecated.json +++ b/packages/e2e-tests/fixtures/blocks/core__group__deprecated.json @@ -4,10 +4,10 @@ "name": "core/group", "isValid": true, "attributes": { - "backgroundColor": "lighter-blue", + "tagName": "div", "align": "full", "anchor": "test-id", - "tagName": "div" + "backgroundColor": "lighter-blue" }, "innerBlocks": [ { diff --git a/packages/e2e-tests/fixtures/blocks/core__group__deprecated.serialized.html b/packages/e2e-tests/fixtures/blocks/core__group__deprecated.serialized.html index b9f1dc3ba37e1..b36427bb86764 100644 --- a/packages/e2e-tests/fixtures/blocks/core__group__deprecated.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__group__deprecated.serialized.html @@ -1,5 +1,5 @@ -
+

test

-
+
From 8fdebe11f3643974dd4ea390240c0445599befd4 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 3 Mar 2021 11:37:44 +0100 Subject: [PATCH 08/24] Update e2e tests snapshots --- .../blocks/__snapshots__/group.test.js.snap | 8 ++++---- .../__snapshots__/cpt-locking.test.js.snap | 8 ++++---- .../__snapshots__/adding-blocks.test.js.snap | 4 ++-- .../__snapshots__/block-grouping.test.js.snap | 20 +++++++++---------- .../block-hierarchy-navigation.test.js.snap | 4 ++-- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap index 49ddf4c41946d..df7b3f6419f15 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap @@ -2,20 +2,20 @@ exports[`Group can be created using the block inserter 1`] = ` " -
+
" `; exports[`Group can be created using the slash inserter 1`] = ` " -
+
" `; exports[`Group can have other blocks appended to it using the button appender 1`] = ` " -
+

Group Block with a Paragraph

-
+
" `; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap index bec98aa082055..a7d34618db0de 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap @@ -38,21 +38,21 @@ exports[`cpt locking template_lock all should not error when deleting the cotent exports[`cpt locking template_lock all unlocked group should allow blocks to be moved 1`] = ` " -
+

p1

-
+
" `; exports[`cpt locking template_lock all unlocked group should allow blocks to be removed 1`] = ` " -
+

-
+
" `; diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap index 9870b5be306fa..b83df123f6a4d 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap @@ -55,9 +55,9 @@ lines preserved[/myshortcode] exports[`adding blocks inserts a block in proper place after having clicked \`Browse All\` from block appender 1`] = ` " -
+

Paragraph inside group

-
+
diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap index 4b786e99fdb23..f3c24c200b971 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap @@ -2,7 +2,7 @@ exports[`Block Grouping Group creation creates a group from multiple blocks of different types via block transforms 1`] = ` " -
+

Group Heading

@@ -12,13 +12,13 @@ exports[`Block Grouping Group creation creates a group from multiple blocks of d

Some paragraph

-
+
" `; exports[`Block Grouping Group creation creates a group from multiple blocks of the same type via block transforms 1`] = ` " -
+

First Paragraph

@@ -28,13 +28,13 @@ exports[`Block Grouping Group creation creates a group from multiple blocks of t

Third Paragraph

-
+
" `; exports[`Block Grouping Group creation creates a group from multiple blocks of the same type via options toolbar 1`] = ` " -
+

First Paragraph

@@ -44,13 +44,13 @@ exports[`Block Grouping Group creation creates a group from multiple blocks of t

Third Paragraph

-
+
" `; exports[`Block Grouping Group creation groups and ungroups multiple blocks of different types via options toolbar 1`] = ` " -
+

Group Heading

@@ -60,7 +60,7 @@ exports[`Block Grouping Group creation groups and ungroups multiple blocks of di

Some paragraph

-
+
" `; @@ -80,7 +80,7 @@ exports[`Block Grouping Group creation groups and ungroups multiple blocks of di exports[`Block Grouping Preserving selected blocks attributes preserves width alignment settings of selected blocks 1`] = ` " -
+

Group Heading

@@ -94,7 +94,7 @@ exports[`Block Grouping Preserving selected blocks attributes preserves width al

Some paragraph

-
+
" `; diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap index 7904000d8aad2..406e1be99232c 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap @@ -52,12 +52,12 @@ exports[`Navigating the block hierarchy should navigate using the block hierarch exports[`Navigating the block hierarchy should select the wrapper div for a group 1`] = ` " -
+

just a paragraph


-
+
" `; From 2e59ef1ad3e82c2c9a5e976a94981b57fd1ff1e4 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 4 Mar 2021 09:49:23 +0100 Subject: [PATCH 09/24] Document the default layout configuration --- docs/how-to-guides/themes/theme-json.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/how-to-guides/themes/theme-json.md b/docs/how-to-guides/themes/theme-json.md index 74831234b7f54..e7480ec606bed 100644 --- a/docs/how-to-guides/themes/theme-json.md +++ b/docs/how-to-guides/themes/theme-json.md @@ -25,9 +25,17 @@ The Block Editor API has evolved at different velocities and there are some grow This describes the current efforts to consolidate the various APIs related to styles into a single point – a `experimental-theme.json` file that should be located inside the root of the theme directory. +### Global settings for the block editor + +Instead of the proliferation of theme support flags or alternative methods, the `experimental-theme.json` files provides a canonical way to define the settings of the block editor. These settings includes things like: + + - What customization options should be made available or hidden from the user. + - What are the default colors, font sizes... available to the user. + - Defines the default layout of the editor. (widths and available alignments). + - ... ### Settings can be controlled per block -The Block Editor already allows the control of specific settings such as alignment, drop cap, presets available, etc. All of these work at the block level. By using the `experimental-theme.json` we aim to allow themes to control these at a block level. +For more granularity, these settings also work at the block level in `experimental-theme.json`. Examples of what can be achieved are: @@ -156,7 +164,11 @@ The settings section has the following structure and default values: ``` { "settings": { - "some/block": { + "defaults": { + "layout": { /* Default layout to be used in the post editor */ + "contentSize": "800px", + "wideSize": "1000px", + } "border": { "customRadius": false /* true to opt-in */ }, From e266b7c5f5a105691eb8babc6e93e9ca039069a1 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 4 Mar 2021 09:50:59 +0100 Subject: [PATCH 10/24] Do not allow specific core/post-content layout config --- .../src/components/use-editor-feature/index.js | 9 ++------- packages/edit-post/src/components/visual-editor/index.js | 4 +--- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/block-editor/src/components/use-editor-feature/index.js b/packages/block-editor/src/components/use-editor-feature/index.js index 485161681b365..60c19ea508de4 100644 --- a/packages/block-editor/src/components/use-editor-feature/index.js +++ b/packages/block-editor/src/components/use-editor-feature/index.js @@ -64,7 +64,6 @@ function blockAttributesMatch( blockAttributes, attributes ) { * It works with nested objects using by finding the value at path. * * @param {string} featurePath The path to the feature. - * @param {Object?} options Options. * * @return {any} Returns the value defined for the setting. * @@ -73,13 +72,9 @@ function blockAttributesMatch( blockAttributes, attributes ) { * const isEnabled = useEditorFeature( 'typography.dropCap' ); * ``` */ -export default function useEditorFeature( - featurePath, - { __unstableForceContext } = {} -) { +export default function useEditorFeature( featurePath ) { const blockEditContext = useBlockEditContext(); - const { name: blockName, clientId } = - __unstableForceContext ?? blockEditContext; + const { name: blockName, clientId } = blockEditContext; const setting = useSelect( ( select ) => { diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 390e6f5667ec4..d5e7340f62dcb 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -58,9 +58,7 @@ export default function VisualEditor( { styles } ) { paddingBottom: hasMetaBoxes ? null : '40vh', }; const resizedCanvasStyles = useResizeCanvas( deviceType ); - const defaultLayout = useEditorFeature( 'layout', { - __unstableForceContext: { name: 'core/post-content' }, - } ); + const defaultLayout = useEditorFeature( 'layout' ); const { contentSize, wideSize } = defaultLayout || {}; const alignments = contentSize || wideSize From 8565497d1ec64c2d6d666b6810753e7e3eb86395 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 4 Mar 2021 10:42:35 +0100 Subject: [PATCH 11/24] More stable multi-selection test --- .../various/multi-block-selection.test.js | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js b/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js index 029a224eaab2f..8a595a436d9b2 100644 --- a/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js +++ b/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js @@ -16,17 +16,17 @@ async function getSelectedFlatIndices() { const indices = []; let single; - Array.from( document.querySelectorAll( '.wp-block' ) ).forEach( - ( node, index ) => { - if ( node.classList.contains( 'is-selected' ) ) { - single = index; - } - - if ( node.classList.contains( 'is-multi-selected' ) ) { - indices.push( index ); - } + Array.from( + document.querySelectorAll( '.wp-block:not(.editor-post-title)' ) + ).forEach( ( node, index ) => { + if ( node.classList.contains( 'is-selected' ) ) { + single = index + 1; } - ); + + if ( node.classList.contains( 'is-multi-selected' ) ) { + indices.push( index + 1 ); + } + } ); return single !== undefined ? single : indices; } ); @@ -489,7 +489,6 @@ describe( 'Multi-block selection', () => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( '2' ); await pressKeyWithModifier( 'shift', 'ArrowUp' ); - await testNativeSelection(); expect( await getSelectedFlatIndices() ).toEqual( [ 1, 2 ] ); From f546bb50871cf8b309e0191d0ea5cd74aa8dcc11 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 9 Mar 2021 09:52:37 +0100 Subject: [PATCH 12/24] Restore the group block inner container server side --- lib/block-supports/layout.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 59ef8ec93c49b..b1e49d06e3a04 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -91,3 +91,37 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { ) ); add_filter( 'render_block', 'gutenberg_render_layout_support_flag', 10, 2 ); + +/** + * For themes without theme.json file, make sure + * to restore the inner div for the group block + * to avoid breaking styles relying on that div. + * + * @param string $block_content Rendered block content. + * @param array $block Block object. + * @return string Filtered block content. + */ +function gutenberg_restore_group_inner_container( $block_content, $block ) { + $group_with_inner_container_regex = '/(^(\s|\S)*]*wp-block-group(\s|")[^>]*>)(([\s]|\S)*]*wp-block-group__inner-container(\s|")[^>]*>)((.|\S|\s)*)/'; + + if ( + 'core/group' !== $block['blockName'] || + WP_Theme_JSON_Resolver::theme_has_support() || + 1 === preg_match( $group_with_inner_container_regex, $block_content ) + ) { + return $block_content; + } + + $replace_regex = '/(^(\s|\S)*]*wp-block-group[^>]*>)((.|\S|\s)*)(<\/div>(\s|\S)*$)/m'; + $updated_content = preg_replace_callback( + $replace_regex, + function( $matches ) { + return $matches[1] . '
' . $matches[3] . '
' . $matches[5]; + }, + $block_content + ); + + return $updated_content; +} + +add_filter( 'render_block', 'gutenberg_restore_group_inner_container', 10, 2 ); From 427c603ae0ff1c2a3108281b34ea8ec43f83d0f3 Mon Sep 17 00:00:00 2001 From: jasmussen Date: Tue, 9 Mar 2021 15:22:52 +0100 Subject: [PATCH 13/24] Tweak some verbiage. --- packages/block-editor/src/hooks/layout.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index f151b18a5254e..b251fea6c0061 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -70,7 +70,7 @@ function LayoutPanel( { setAttributes, attributes } ) { } return ( - + { !! defaultLayout && ( ) } +

+ { __( + 'The content and wide sizes determine the behavior of block alignments.' + ) } +

); From e34a2e172e09c60cad4942f9fb99ca20c30823d6 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 9 Mar 2021 10:20:51 +0100 Subject: [PATCH 14/24] Support inheriting global layout in the editor --- lib/block-supports/layout.php | 15 +++- packages/block-editor/src/hooks/layout.js | 105 +++++++++++----------- packages/block-library/src/group/edit.js | 5 +- 3 files changed, 71 insertions(+), 54 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index b1e49d06e3a04..ea1e5d5d09e0d 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -45,10 +45,19 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { return $block_content; } - $attributes = $block['attrs']; + $used_layout = $block['attrs']['layout']; + if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) { + $tree = WP_Theme_JSON_Resolver::get_merged_data( array(), 'theme' ); + $default_layout = _wp_array_get( $tree->get_settings(), array( 'defaults', 'layout' ) ); + if ( ! $default_layout ) { + return $block_content; + } + $used_layout = $default_layout; + } + $id = uniqid(); - $content_size = isset( $attributes['layout']['contentSize'] ) ? $attributes['layout']['contentSize'] : null; - $wide_size = isset( $attributes['layout']['wideSize'] ) ? $attributes['layout']['wideSize'] : null; + $content_size = isset( $used_layout['contentSize'] ) ? $used_layout['contentSize'] : null; + $wide_size = isset( $used_layout['wideSize'] ) ? $used_layout['wideSize'] : null; if ( ! $content_size && ! $wide_size ) { return $block_content; } diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index b251fea6c0061..4e4483944396b 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -13,9 +13,9 @@ import { addFilter } from '@wordpress/hooks'; import { hasBlockSupport } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; import { + ToggleControl, PanelBody, __experimentalUnitControl as UnitControl, - Button, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; @@ -58,7 +58,7 @@ const CSS_UNITS = [ function LayoutPanel( { setAttributes, attributes } ) { const { layout = {} } = attributes; - const { wideSize, contentSize } = layout; + const { wideSize, contentSize, inherit = false } = layout; const defaultLayout = useEditorFeature( 'layout' ); const themeSupportsLayout = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); @@ -72,53 +72,56 @@ function LayoutPanel( { setAttributes, attributes } ) { { !! defaultLayout && ( - + + setAttributes( { layout: { inherit: ! inherit } } ) + } + /> + ) } + { ! inherit && ( + <> + { + nextWidth = + 0 > parseFloat( nextWidth ) + ? '0' + : nextWidth; + setAttributes( { + layout: { + ...layout, + contentSize: nextWidth, + }, + } ); + } } + units={ CSS_UNITS } + /> + { + nextWidth = + 0 > parseFloat( nextWidth ) + ? '0' + : nextWidth; + setAttributes( { + layout: { + ...layout, + wideSize: nextWidth, + }, + } ); + } } + units={ CSS_UNITS } + /> + ) } - { - nextWidth = - 0 > parseFloat( nextWidth ) ? '0' : nextWidth; - setAttributes( { - layout: { - ...layout, - contentSize: nextWidth, - }, - } ); - } } - units={ CSS_UNITS } - /> - { - nextWidth = - 0 > parseFloat( nextWidth ) ? '0' : nextWidth; - setAttributes( { - layout: { - ...layout, - wideSize: nextWidth, - }, - } ); - } } - units={ CSS_UNITS } - />

{ __( 'The content and wide sizes determine the behavior of block alignments.' @@ -184,11 +187,13 @@ export const withLayoutStyles = createHigherOrderComponent( const { name, attributes } = props; const supportLayout = hasBlockSupport( name, '__experimentalLayout' ); const id = useInstanceId( BlockListBlock ); + const defaultLayout = useEditorFeature( 'layout' ); if ( ! supportLayout === undefined ) { return ; } const { layout = {} } = attributes; - const { wideSize, contentSize } = layout; + const usedLayout = !! layout && layout.inherit ? defaultLayout : layout; + const { wideSize, contentSize } = usedLayout; if ( ! wideSize && ! contentSize ) { return ; } @@ -202,7 +207,7 @@ export const withLayoutStyles = createHigherOrderComponent( <> diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 9e8f0d9ded846..4d233f52fac46 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -8,6 +8,7 @@ import { useBlockProps, InspectorAdvancedControls, __experimentalUseInnerBlocksProps as useInnerBlocksProps, + __experimentalUseEditorFeature as useEditorFeature, store as blockEditorStore, } from '@wordpress/block-editor'; import { @@ -59,8 +60,10 @@ function GroupEdit( { attributes, setAttributes, clientId } ) { }, [ clientId ] ); + const defaultLayout = useEditorFeature( 'layout' ); const { tagName: TagName = 'div', templateLock, layout = {} } = attributes; - const { contentSize, wideSize } = layout; + const usedLayout = !! layout && layout.inherit ? defaultLayout : layout; + const { contentSize, wideSize } = usedLayout; const alignments = contentSize || wideSize ? [ 'wide', 'full' ] From 8957d68302aae9628276f6fffb88eae31d3298e0 Mon Sep 17 00:00:00 2001 From: jasmussen Date: Wed, 10 Mar 2021 11:09:27 +0100 Subject: [PATCH 15/24] Polish to match mockup. --- packages/block-editor/src/hooks/layout.js | 89 +++++++++++---------- packages/block-editor/src/hooks/layout.scss | 17 ++++ packages/block-editor/src/style.scss | 1 + 3 files changed, 66 insertions(+), 41 deletions(-) create mode 100644 packages/block-editor/src/hooks/layout.scss diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 4e4483944396b..f259405820888 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -18,6 +18,7 @@ import { __experimentalUnitControl as UnitControl, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { Icon, positionCenter, stretchWide } from '@wordpress/icons'; /** * Internal dependencies @@ -81,48 +82,54 @@ function LayoutPanel( { setAttributes, attributes } ) { /> ) } { ! inherit && ( - <> - { - nextWidth = - 0 > parseFloat( nextWidth ) - ? '0' - : nextWidth; - setAttributes( { - layout: { - ...layout, - contentSize: nextWidth, - }, - } ); - } } - units={ CSS_UNITS } - /> - { - nextWidth = - 0 > parseFloat( nextWidth ) - ? '0' - : nextWidth; - setAttributes( { - layout: { - ...layout, - wideSize: nextWidth, - }, - } ); - } } - units={ CSS_UNITS } - /> - +

+
+ { + nextWidth = + 0 > parseFloat( nextWidth ) + ? '0' + : nextWidth; + setAttributes( { + layout: { + ...layout, + contentSize: nextWidth, + }, + } ); + } } + units={ CSS_UNITS } + /> + +
+
+ { + nextWidth = + 0 > parseFloat( nextWidth ) + ? '0' + : nextWidth; + setAttributes( { + layout: { + ...layout, + wideSize: nextWidth, + }, + } ); + } } + units={ CSS_UNITS } + /> + +
+
) } -

+

{ __( 'The content and wide sizes determine the behavior of block alignments.' ) } diff --git a/packages/block-editor/src/hooks/layout.scss b/packages/block-editor/src/hooks/layout.scss new file mode 100644 index 0000000000000..aa86aa0a00ce0 --- /dev/null +++ b/packages/block-editor/src/hooks/layout.scss @@ -0,0 +1,17 @@ +.alignment__controls { + display: flex; + margin-bottom: $grid-unit-30; + + .alignment__controls__unit-control-wrapper { + display: flex; + margin-right: $grid-unit-30; + + svg { + margin: auto 0 $grid-unit-05 $grid-unit-10; + } + } +} + +.alignment__helptext { + font-size: $helptext-font-size; +} diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 9469ed8cdf909..fffa4c55e3867 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -54,6 +54,7 @@ @import "./components/url-popover/style.scss"; @import "./components/warning/style.scss"; @import "./hooks/anchor.scss"; +@import "./hooks/layout.scss"; // This tag marks the end of the styles that apply to editing canvas contents and need to be manipulated when we resize the editor. #end-resizable-editor-section { From 8ec5cc677ea77f8de4caf95d9255ba78fb22b50a Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 11 Mar 2021 09:28:26 +0100 Subject: [PATCH 16/24] Prevent focus loss --- packages/block-editor/src/hooks/layout.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index f259405820888..65e4e49babfd5 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -201,21 +201,19 @@ export const withLayoutStyles = createHigherOrderComponent( const { layout = {} } = attributes; const usedLayout = !! layout && layout.inherit ? defaultLayout : layout; const { wideSize, contentSize } = usedLayout; - if ( ! wideSize && ! contentSize ) { - return ; - } - - const className = classnames( - props?.className, - `wp-container-${ id }` - ); + const hasLayout = !! wideSize || !! contentSize; + const className = classnames( props?.className, { + [ `wp-container-${ id }` ]: hasLayout, + } ); return ( <> - + { hasLayout && ( + + ) } ); From 8d05994a9cace655cca59223cfd4c10f5f526a42 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 11 Mar 2021 09:47:29 +0100 Subject: [PATCH 17/24] Rename some classnames --- lib/block-supports/layout.php | 4 ++-- packages/block-editor/src/hooks/layout.js | 8 ++++---- packages/block-editor/src/hooks/layout.scss | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index ea1e5d5d09e0d..71a9746276135 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -13,7 +13,7 @@ function gutenberg_register_layout_support( $block_type ) { $support_layout = false; if ( property_exists( $block_type, 'supports' ) ) { - $support_layout = gutenberg_experimental_get( $block_type->supports, array( '__experimentalLayout' ), false ); + $support_layout = _wp_array_get( $block_type->supports, array( '__experimentalLayout' ), false ); } if ( $support_layout ) { if ( ! $block_type->attributes ) { @@ -39,7 +39,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $support_layout = false; if ( $block_type && property_exists( $block_type, 'supports' ) ) { - $support_layout = gutenberg_experimental_get( $block_type->supports, array( '__experimentalLayout' ), false ); + $support_layout = _wp_array_get( $block_type->supports, array( '__experimentalLayout' ), false ); } if ( ! $support_layout || ! isset( $block['attrs']['layout'] ) ) { return $block_content; diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 65e4e49babfd5..f952840fc2ad1 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -82,8 +82,8 @@ function LayoutPanel( { setAttributes, attributes } ) { /> ) } { ! inherit && ( -

-
+
+
-
+
) } -

+

{ __( 'The content and wide sizes determine the behavior of block alignments.' ) } diff --git a/packages/block-editor/src/hooks/layout.scss b/packages/block-editor/src/hooks/layout.scss index aa86aa0a00ce0..1c4773a8889ec 100644 --- a/packages/block-editor/src/hooks/layout.scss +++ b/packages/block-editor/src/hooks/layout.scss @@ -1,8 +1,8 @@ -.alignment__controls { +.block-editor-hooks__layout-controls { display: flex; margin-bottom: $grid-unit-30; - .alignment__controls__unit-control-wrapper { + .block-editor-hooks__layout-controls-unit { display: flex; margin-right: $grid-unit-30; @@ -12,6 +12,6 @@ } } -.alignment__helptext { +.block-editor-hooks__layout-controls-helptext { font-size: $helptext-font-size; } From f4caae088d36e0329e21bdc9ad432bdab51d9a03 Mon Sep 17 00:00:00 2001 From: jasmussen Date: Thu, 11 Mar 2021 10:51:34 +0100 Subject: [PATCH 18/24] Tweak the verbiage. --- packages/block-editor/src/hooks/layout.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index f952840fc2ad1..b68e0034f3156 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -71,7 +71,7 @@ function LayoutPanel( { setAttributes, attributes } ) { } return ( - + { !! defaultLayout && ( { __( - 'The content and wide sizes determine the behavior of block alignments.' + 'The content and wide sizes determine the width of centered and wide columns inside.' ) }

From 4499d1b44fa1357cfd5ac2e30a21c3da918a49fc Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 16 Mar 2021 10:19:05 +0100 Subject: [PATCH 19/24] Remove BoxVisualizer from the group block --- packages/block-library/src/group/edit.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 4d233f52fac46..52d66198bf51d 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -11,12 +11,8 @@ import { __experimentalUseEditorFeature as useEditorFeature, store as blockEditorStore, } from '@wordpress/block-editor'; -import { - SelectControl, - __experimentalBoxControl as BoxControl, -} from '@wordpress/components'; +import { SelectControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -const { __Visualizer: BoxControlVisualizer } = BoxControl; const isWeb = Platform.OS === 'web'; @@ -69,14 +65,6 @@ function GroupEdit( { attributes, setAttributes, clientId } ) { ? [ 'wide', 'full' ] : [ 'left', 'center', 'right' ]; const blockProps = useBlockProps(); - /* TODO: find a way to render this extra div as a child of the inner block wrapper - const extraChildren = ( - - ); - */ const innerBlocksProps = useInnerBlocksProps( blockProps, { templateLock, renderAppender: hasInnerBlocks From a8000c78a96641f4f6d52a67a07bf11576ed9b78 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 16 Mar 2021 10:19:24 +0100 Subject: [PATCH 20/24] Add floated block supports --- lib/block-supports/layout.php | 30 +++++++---- .../src/components/block-list/layout.js | 30 +++++++---- .../src/components/block-list/style.scss | 52 ++----------------- packages/block-editor/src/hooks/layout.js | 19 +++---- .../src/components/layout/style.scss | 39 ++++++++++++++ .../src/components/visual-editor/index.js | 10 ++-- 6 files changed, 97 insertions(+), 83 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 71a9746276135..c09bbe3b6561f 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -58,12 +58,11 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { $id = uniqid(); $content_size = isset( $used_layout['contentSize'] ) ? $used_layout['contentSize'] : null; $wide_size = isset( $used_layout['wideSize'] ) ? $used_layout['wideSize'] : null; - if ( ! $content_size && ! $wide_size ) { - return $block_content; - } - ob_start(); - ?> - + + .alignleft { + float: left; + } + + .alignright { + float: right; + } ' . $style . ''; } // Register the block support. diff --git a/packages/block-editor/src/components/block-list/layout.js b/packages/block-editor/src/components/block-list/layout.js index 286b04c8f14dd..541e2e83eb710 100644 --- a/packages/block-editor/src/components/block-list/layout.js +++ b/packages/block-editor/src/components/block-list/layout.js @@ -28,27 +28,35 @@ export function useLayout() { export function LayoutStyle( { selector, layout = {} } ) { const { contentSize, wideSize } = layout; - if ( ! contentSize && ! wideSize ) { - return null; - } - return ( - - ); + ` + : ''; + + style += ` + ${ appendSelectors( selector, '> [data-align="left"]' ) } { + float: left; + } + + ${ appendSelectors( selector, '> [data-align="right"]' ) } { + float: right; + } + `; + + return ; } diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index eff5c20457da5..ee4ac11b1c7d1 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -341,56 +341,12 @@ } } -// Extra specificity needed to override default element margins like lists (ul). -.block-editor-block-list__layout .wp-block { - margin-left: auto; - margin-right: auto; +.wp-block[data-align="left"] > *, +.wp-block[data-align="right"] > * { + // Without z-index, won't be clickable as "above" adjacent content. + z-index: z-index("{core/image aligned left or right} .wp-block"); } -.wp-block { - // Alignments. - &[data-align="left"], - &[data-align="right"] { - width: 100%; - - // When images are floated, the block itself should collapse to zero height. - height: 0; - - &::before { - content: none; - } - } - - &[data-align="left"] > *, - &[data-align="right"] > * { - // Without z-index, won't be clickable as "above" adjacent content. - z-index: z-index("{core/image aligned left or right} .wp-block"); - } - - // Left. - &[data-align="left"] > * { - // This is in the editor only; the image should be floated on the frontend. - /*!rtl:begin:ignore*/ - float: left; - margin-right: 2em; - /*!rtl:end:ignore*/ - } - - // Right. - &[data-align="right"] > * { - // Right: This is in the editor only; the image should be floated on the frontend. - /*!rtl:begin:ignore*/ - float: right; - margin-left: 2em; - /*!rtl:end:ignore*/ - } - - // Wide and full-wide. - &[data-align="full"], - &[data-align="wide"] { - clear: both; - } -} /** * In-Canvas Inserter diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index b68e0034f3156..47b9166e21be1 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -200,20 +200,17 @@ export const withLayoutStyles = createHigherOrderComponent( } const { layout = {} } = attributes; const usedLayout = !! layout && layout.inherit ? defaultLayout : layout; - const { wideSize, contentSize } = usedLayout; - const hasLayout = !! wideSize || !! contentSize; - const className = classnames( props?.className, { - [ `wp-container-${ id }` ]: hasLayout, - } ); + const className = classnames( + props?.className, + `wp-container-${ id }` + ); return ( <> - { hasLayout && ( - - ) } + ); diff --git a/packages/edit-post/src/components/layout/style.scss b/packages/edit-post/src/components/layout/style.scss index 9a672704fac3a..9a9c033b55b0c 100644 --- a/packages/edit-post/src/components/layout/style.scss +++ b/packages/edit-post/src/components/layout/style.scss @@ -117,9 +117,12 @@ } // Depreacted style needed for the block widths and alignments. +// for themes that don't support the new layout (theme.json) .edit-post-layout:not(.supports-layout) { .wp-block { max-width: $content-width; + margin-left: auto; + margin-right: auto; &[data-align="wide"] { max-width: $wide-content-width; @@ -128,6 +131,42 @@ &[data-align="full"] { max-width: none; } + + // Alignments. + &[data-align="left"], + &[data-align="right"] { + width: 100%; + + // When images are floated, the block itself should collapse to zero height. + height: 0; + + &::before { + content: none; + } + } + + // Left. + &[data-align="left"] > * { + /*!rtl:begin:ignore*/ + float: left; + margin-right: 2em; + /*!rtl:end:ignore*/ + } + + // Right. + &[data-align="right"] > * { + /*!rtl:begin:ignore*/ + float: right; + margin-left: 2em; + /*!rtl:end:ignore*/ + } + + // Wide and full-wide. + &[data-align="full"], + &[data-align="wide"] { + clear: both; + } + } // Full Width Blocks diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index d5e7340f62dcb..5302be09db319 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -76,10 +76,12 @@ export default function VisualEditor( { styles } ) { return (
- + { themeSupportsLayout && ( + + ) } From a457f79736b5ade2f1a635a3c03f390a047277a1 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 16 Mar 2021 11:38:28 +0100 Subject: [PATCH 21/24] Fix e2e tests --- .../src/components/block-list/insertion-point.js | 6 ++++-- packages/block-editor/src/hooks/layout.js | 2 +- packages/e2e-tests/specs/editor/blocks/paragraph.test.js | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/block-list/insertion-point.js b/packages/block-editor/src/components/block-list/insertion-point.js index a4f33a80bd8da..f2842aa5b11d5 100644 --- a/packages/block-editor/src/components/block-list/insertion-point.js +++ b/packages/block-editor/src/components/block-list/insertion-point.js @@ -306,9 +306,11 @@ export default function useInsertionPoint( ref ) { const children = Array.from( event.target.children ); const nextElement = children.find( ( blockEl ) => { return ( - ( orientation === 'vertical' && + ( blockEl.classList.contains( 'wp-block' ) && + orientation === 'vertical' && blockEl.offsetTop > offsetTop ) || - ( orientation === 'horizontal' && + ( blockEl.classList.contains( 'wp-block' ) && + orientation === 'horizontal' && blockEl.offsetLeft > offsetLeft ) ); } ); diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index 47b9166e21be1..c564f720e3679 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -195,7 +195,7 @@ export const withLayoutStyles = createHigherOrderComponent( const supportLayout = hasBlockSupport( name, '__experimentalLayout' ); const id = useInstanceId( BlockListBlock ); const defaultLayout = useEditorFeature( 'layout' ); - if ( ! supportLayout === undefined ) { + if ( ! supportLayout ) { return ; } const { layout = {} } = attributes; diff --git a/packages/e2e-tests/specs/editor/blocks/paragraph.test.js b/packages/e2e-tests/specs/editor/blocks/paragraph.test.js index d998ae32387c3..74f3f7f8cb98f 100644 --- a/packages/e2e-tests/specs/editor/blocks/paragraph.test.js +++ b/packages/e2e-tests/specs/editor/blocks/paragraph.test.js @@ -13,8 +13,9 @@ describe( 'Paragraph', () => { await page.keyboard.type( '1' ); const firstBlockTagName = await page.evaluate( () => { - return document.querySelector( '.block-editor-block-list__layout' ) - .firstChild.tagName; + return document.querySelector( + '.block-editor-block-list__layout .wp-block' + ).tagName; } ); // The outer element should be a paragraph. Blocks should never have any From f15a746bce0472c43be661ad51536cbab23445ee Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 16 Mar 2021 12:17:53 +0100 Subject: [PATCH 22/24] Add default margins for floated blocks --- lib/block-supports/layout.php | 2 ++ packages/block-editor/src/components/block-list/layout.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index c09bbe3b6561f..1abc69c7362da 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -84,10 +84,12 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { ?> .alignleft { float: left; + margin-right: 2em; } .alignright { float: right; + margin-left: 2em; } [data-align="left"]' ) } { float: left; + margin-right: 2em; } ${ appendSelectors( selector, '> [data-align="right"]' ) } { float: right; + margin-left: 2em; } `; From 01e434d1076ac63515f8a7c9ad7230c6e0143027 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 16 Mar 2021 16:05:19 +0100 Subject: [PATCH 23/24] Fix failing image e2e test --- packages/e2e-test-utils/src/click-block-toolbar-button.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-test-utils/src/click-block-toolbar-button.js b/packages/e2e-test-utils/src/click-block-toolbar-button.js index 3aa431bfe29ff..e73888f068138 100644 --- a/packages/e2e-test-utils/src/click-block-toolbar-button.js +++ b/packages/e2e-test-utils/src/click-block-toolbar-button.js @@ -22,7 +22,7 @@ export async function clickBlockToolbarButton( label, type = 'ariaLabel' ) { if ( type === 'content' ) { button = await page.waitForXPath( - `//*[@class='${ BLOCK_TOOLBAR_SELECTOR }']//button[contains(text(), '${ label }')]` + `//*[contains(concat(' ', normalize-space(@class), ' '), ' ${ BLOCK_TOOLBAR_SELECTOR } ')]//button[contains(text(), '${ label }')]` ); } From 93f5e84e262615dc6814be54b61d9534b209ce9f Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 18 Mar 2021 08:37:46 +0100 Subject: [PATCH 24/24] Cleanup per review --- docs/how-to-guides/themes/theme-json.md | 1 - .../components/use-editor-feature/index.js | 3 +- .../block-library/src/group/deprecated.js | 5 +-- packages/block-library/src/group/edit.js | 31 ------------------- 4 files changed, 2 insertions(+), 38 deletions(-) diff --git a/docs/how-to-guides/themes/theme-json.md b/docs/how-to-guides/themes/theme-json.md index e7480ec606bed..42b8c950d736d 100644 --- a/docs/how-to-guides/themes/theme-json.md +++ b/docs/how-to-guides/themes/theme-json.md @@ -32,7 +32,6 @@ Instead of the proliferation of theme support flags or alternative methods, the - What customization options should be made available or hidden from the user. - What are the default colors, font sizes... available to the user. - Defines the default layout of the editor. (widths and available alignments). - - ... ### Settings can be controlled per block For more granularity, these settings also work at the block level in `experimental-theme.json`. diff --git a/packages/block-editor/src/components/use-editor-feature/index.js b/packages/block-editor/src/components/use-editor-feature/index.js index 60c19ea508de4..81ab094ec7f6c 100644 --- a/packages/block-editor/src/components/use-editor-feature/index.js +++ b/packages/block-editor/src/components/use-editor-feature/index.js @@ -73,8 +73,7 @@ function blockAttributesMatch( blockAttributes, attributes ) { * ``` */ export default function useEditorFeature( featurePath ) { - const blockEditContext = useBlockEditContext(); - const { name: blockName, clientId } = blockEditContext; + const { name: blockName, clientId } = useBlockEditContext(); const setting = useSelect( ( select ) => { diff --git a/packages/block-library/src/group/deprecated.js b/packages/block-library/src/group/deprecated.js index 9e97089f791a1..337e498b0bded 100644 --- a/packages/block-library/src/group/deprecated.js +++ b/packages/block-library/src/group/deprecated.js @@ -38,7 +38,7 @@ const migrateAttributes = ( attributes ) => { }; const deprecated = [ - // Version of the block with the double dif + // Version of the block with the double div. { attributes: { tagName: { @@ -48,9 +48,6 @@ const deprecated = [ templateLock: { type: 'string', }, - layout: { - type: 'object', - }, }, supports: { align: [ 'wide', 'full' ], diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 52d66198bf51d..9a27a481dfb30 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -1,7 +1,6 @@ /** * WordPress dependencies */ -import { Platform } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { InnerBlocks, @@ -14,36 +13,6 @@ import { import { SelectControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -const isWeb = Platform.OS === 'web'; - -export const CSS_UNITS = [ - { - value: '%', - label: isWeb ? '%' : __( 'Percentage (%)' ), - default: '', - }, - { - value: 'px', - label: isWeb ? 'px' : __( 'Pixels (px)' ), - default: '', - }, - { - value: 'em', - label: isWeb ? 'em' : __( 'Relative to parent font size (em)' ), - default: '', - }, - { - value: 'rem', - label: isWeb ? 'rem' : __( 'Relative to root font size (rem)' ), - default: '', - }, - { - value: 'vw', - label: isWeb ? 'vw' : __( 'Viewport width (vw)' ), - default: '', - }, -]; - function GroupEdit( { attributes, setAttributes, clientId } ) { const { hasInnerBlocks, themeSupportsLayout } = useSelect( ( select ) => {