Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try "constrained" content width as new layout type #42763

Merged
merged 29 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6fbc632
Try content width column as new layout type
tellthemachines Jul 28, 2022
81768a3
Consolidate root selector rules.
tellthemachines Jul 29, 2022
464139b
Undo rebase weirdness
tellthemachines Jul 29, 2022
5e8010d
Add deprecation and server-side legacy support
tellthemachines Jul 29, 2022
20499c0
Change group block approach
tellthemachines Aug 2, 2022
93a985a
Fix buggy align behaviour
tellthemachines Aug 3, 2022
f2fc2bb
Alignments should work for classic themes
tellthemachines Aug 4, 2022
f748fee
Set output to empty string.
tellthemachines Aug 4, 2022
f4e7d10
Add layout type fallback for alignments
tellthemachines Aug 4, 2022
f54f812
Regenerate fixtures
tellthemachines Aug 4, 2022
6af5ecd
Update snapshots
tellthemachines Aug 5, 2022
f52ba94
Change nested blocks to buttons
tellthemachines Aug 5, 2022
86f5ed9
Fix php test diffs
tellthemachines Aug 5, 2022
b6b2483
Fix rebase inconsistency in layout
tellthemachines Aug 5, 2022
454195f
Add test for content size variable output
tellthemachines Aug 5, 2022
47464ac
Add test for column layout.
tellthemachines Aug 5, 2022
7f5874b
Fix loss of layout attributes.
tellthemachines Aug 9, 2022
155885e
Make layout changes work for blocks without deprecation
tellthemachines Aug 9, 2022
5d3573f
Fix custom content size controls
tellthemachines Aug 9, 2022
6096d7d
Fix post title
tellthemachines Aug 12, 2022
de61635
Update new e2e snapshots
tellthemachines Aug 12, 2022
09756f3
Change layout type name to "constrained"
tellthemachines Aug 15, 2022
772906a
Update snapshots for new tests.
tellthemachines Aug 16, 2022
1f516f1
Content size variables should be output in the site editor.
tellthemachines Aug 17, 2022
17124fb
Fix custom content sizes in editor.
tellthemachines Aug 17, 2022
f22bee0
Tidy up PHP.
tellthemachines Aug 17, 2022
abd1baf
Add deprecation fixtures
tellthemachines Aug 17, 2022
78a3ed5
Fixed duplicated code after rebase hack job. Sorry!
ramonjd Aug 22, 2022
49b12fb
Increase block gap selector specificity.
tellthemachines Aug 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ Gather blocks in a layout container. ([Source](https://github.com/WordPress/gute
- **Name:** core/group
- **Category:** design
- **Supports:** align (full, wide), anchor, ariaLabel, color (background, gradients, link, text), spacing (blockGap, margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** tagName, templateLock
- **Attributes:** layout, tagName, templateLock

## Heading

Expand Down
32 changes: 31 additions & 1 deletion lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,31 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
$layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default';
$layout_styles = array();
if ( 'default' === $layout_type ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens to existing Group blocks with the default layout type, that set contentSize or wideSize?

if ( $has_block_gap_support ) {
if ( is_array( $gap_value ) ) {
$gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null;
}
if ( $gap_value && ! $should_skip_gap_serialization ) {
array_push(
$layout_styles,
array(
'selector' => "$selector > *",
'declarations' => array(
'margin-block-start' => '0',
'margin-block-end' => '0',
),
),
array(
'selector' => "$selector$selector > * + *",
'declarations' => array(
'margin-block-start' => $gap_value,
'margin-block-end' => '0',
),
)
);
}
}
} elseif ( 'constrained' === $layout_type ) {
$content_size = isset( $layout['contentSize'] ) ? $layout['contentSize'] : '';
$wide_size = isset( $layout['wideSize'] ) ? $layout['wideSize'] : '';

Expand Down Expand Up @@ -254,11 +279,11 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
$has_block_gap_support = isset( $block_gap ) ? null !== $block_gap : false;
$default_block_layout = _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );
$used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $default_block_layout;

if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) {
Copy link
Contributor

@glendaviesnz glendaviesnz Aug 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a nit, could this be moved up to just after the $used_layout declaration as it seems like the other declarations are not needed if this returns early?

	$global_layout_settings = gutenberg_get_global_settings( array( 'layout' ) );
	$default_block_layout    = _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );
	$used_layout                   = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $default_block_layout;

	if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) {
		if ( ! $global_layout_settings ) {
			return $block_content;
		}
	}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that makes sense!

if ( ! $global_layout_settings ) {
return $block_content;
}
$used_layout = $global_layout_settings;
}

$class_names = array();
Expand All @@ -268,6 +293,11 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
$layout_classname = '';
$use_global_padding = gutenberg_get_global_settings( array( 'useRootPaddingAwareAlignments' ) ) && ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] || isset( $used_layout['contentSize'] ) && $used_layout['contentSize'] );

// Set the correct layout type for blocks using legacy content width.
if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] || isset( $used_layout['contentSize'] ) && $used_layout['contentSize'] ) {
$used_layout['type'] = 'constrained';
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocks with contentSize or inherit are migrated to "column" layout on the front end.


if ( $use_global_padding ) {
$class_names[] = 'has-global-padding';
}
Expand Down
43 changes: 30 additions & 13 deletions lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php
Original file line number Diff line number Diff line change
Expand Up @@ -758,18 +758,6 @@ function( $pseudo_selector ) use ( $selector ) {
}
}

/*
* Reset default browser margin on the root body element.
* This is set on the root selector **before** generating the ruleset
* from the `theme.json`. This is to ensure that if the `theme.json` declares
* `margin` in its `spacing` declaration for the `body` element then these
* user-generated values take precedence in the CSS cascade.
* @link https://github.com/WordPress/gutenberg/issues/36147.
*/
if ( static::ROOT_BLOCK_SELECTOR === $selector ) {
$block_rules .= 'body { margin: 0; }';
}

// 2. Generate and append the rules that use the general selector.
$block_rules .= static::to_ruleset( $selector, $declarations );

Expand All @@ -793,6 +781,34 @@ function( $pseudo_selector ) use ( $selector ) {
}

if ( static::ROOT_BLOCK_SELECTOR === $selector ) {
/*
* Reset default browser margin on the root body element.
* This is set on the root selector **before** generating the ruleset
* from the `theme.json`. This is to ensure that if the `theme.json` declares
* `margin` in its `spacing` declaration for the `body` element then these
* user-generated values take precedence in the CSS cascade.
* @link https://github.com/WordPress/gutenberg/issues/36147.
*/
$block_rules .= 'body { margin: 0;';

/*
* If there are content and wide widths in theme.json, output them
* as custom properties on the body element so all blocks can use them.
*/
if ( isset( $settings['layout']['contentSize'] ) || isset( $settings['layout']['wideSize'] ) ) {
$content_size = isset( $settings['layout']['contentSize'] ) ? $settings['layout']['contentSize'] : $settings['layout']['wideSize'];
$content_size = static::is_safe_css_declaration( 'max-width', $content_size ) ? $content_size : 'initial';
$wide_size = isset( $settings['layout']['wideSize'] ) ? $settings['layout']['wideSize'] : $settings['layout']['contentSize'];
$wide_size = static::is_safe_css_declaration( 'max-width', $wide_size ) ? $wide_size : 'initial';
$block_rules .= '--wp--style--global--content-size: ' . $content_size . ';';
$block_rules .= '--wp--style--global--wide-size: ' . $wide_size . ';';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contentSize and wideSize values are added to root as custom properties. This is necessary so we can use them in the base styles declared in theme.json.

}

$block_rules .= '}';
}

if ( static::ROOT_BLOCK_SELECTOR === $selector ) {

if ( $use_root_padding ) {
$block_rules .= '.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }';
$block_rules .= '.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }';
Expand All @@ -804,6 +820,7 @@ function( $pseudo_selector ) use ( $selector ) {
$block_rules .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }';
$block_rules .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }';

$block_gap_value = _wp_array_get( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ), '0.5em' );
$has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null;
if ( $has_block_gap_support ) {
$block_gap_value = static::get_property_value( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ) );
Expand Down Expand Up @@ -1295,7 +1312,7 @@ protected function get_layout_styles( $block_metadata ) {
$has_fallback_gap_support = ! $has_block_gap_support; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback gap styles support.
$node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() );
$layout_definitions = _wp_array_get( $this->theme_json, array( 'settings', 'layout', 'definitions' ), array() );
$layout_selector_pattern = '/^[a-zA-Z0-9\-\.\ *+>]*$/'; // Allow alphanumeric classnames, spaces, wildcard, sibling, and child combinator selectors.
$layout_selector_pattern = '/^[a-zA-Z0-9\-\.\ *+>:\(\)]*$/'; // Allow alphanumeric classnames, spaces, wildcard, sibling, child combinator and pseudo class selectors.

// Gap styles will only be output if the theme has block gap support, or supports a fallback gap.
// Default layout gap styles will be skipped for themes that do not explicitly opt-in to blockGap with a `true` or `false` value.
Expand Down
60 changes: 60 additions & 0 deletions lib/compat/wordpress-6.1/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,66 @@
}
]
},
"constrained": {
"name": "constrained",
"slug": "constrained",
"className": "is-layout-constrained",
"baseStyles": [
{
"selector": " > .alignleft",
"rules": {
"float": "left",
"margin-inline-start": "0",
"margin-inline-end": "2em"
}
},
{
"selector": " > .alignright",
"rules": {
"float": "right",
"margin-inline-start": "2em",
"margin-inline-end": "0"
}
},
{
"selector": " > .aligncenter",
"rules": {
"margin-left": "auto !important",
"margin-right": "auto !important"
}
},
{
"selector": " > :where(:not(.alignleft):not(.alignright):not(.alignfull))",
"rules": {
"max-width": "var(--wp--style--global--content-size)",
"margin-left": "auto !important",
"margin-right": "auto !important"
}
},
{
"selector": " > .alignwide",
"rules": {
"max-width": "var(--wp--style--global--wide-size)"
}
}
],
"spacingStyles": [
{
"selector": " > *",
"rules": {
"margin-block-start": "0",
"margin-block-end": "0"
}
},
{
"selector": " > * + *",
"rules": {
"margin-block-start": null,
"margin-block-end": "0"
}
}
]
},
"flex": {
"name": "flex",
"slug": "flex",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function useAvailableAlignments( controls = DEFAULT_CONTROLS ) {
}

// Starting here, it's the fallback for themes not supporting the layout config.
if ( layoutType.name !== 'default' ) {
if ( layoutType.name !== 'default' && layoutType.name !== 'constrained' ) {
return [];
}
const { alignments: availableAlignments = DEFAULT_CONTROLS } = layout;
Expand Down
59 changes: 45 additions & 14 deletions packages/block-editor/src/hooks/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,25 +110,37 @@ function LayoutPanel( { setAttributes, attributes, name: blockName } ) {

// Only show the inherit toggle if it's supported,
// a default theme layout is set (e.g. one that provides `contentSize` and/or `wideSize` values),
// and that the default / flow layout type is in use, as this is the only one that supports inheritance.
// and either the default / flow or the constrained layout type is in use, as the toggle switches from one to the other.
const showInheritToggle = !! (
allowInheriting &&
!! defaultThemeLayout &&
( ! layout?.type || layout?.type === 'default' || layout?.inherit )
( ! layout?.type ||
layout?.type === 'default' ||
layout?.type === 'constrained' ||
layout?.inherit )
);

const usedLayout = layout || defaultBlockLayout || {};
const { inherit = false, type = 'default' } = usedLayout;
const {
inherit = false,
type = 'default',
contentSize = null,
} = usedLayout;
/**
* `themeSupportsLayout` is only relevant to the `default/flow`
* layout and it should not be taken into account when other
* `themeSupportsLayout` is only relevant to the `default/flow` or
* `constrained` layouts and it should not be taken into account when other
* `layout` types are used.
*/
if ( type === 'default' && ! themeSupportsLayout ) {
if (
( type === 'default' || type === 'constrained' ) &&
! themeSupportsLayout
) {
return null;
}
const layoutType = getLayoutType( type );

const constrainedType = getLayoutType( 'constrained' );

const onChangeType = ( newType ) =>
setAttributes( { layout: { type: newType } } );
const onChangeLayout = ( newLayout ) =>
Expand All @@ -141,18 +153,29 @@ function LayoutPanel( { setAttributes, attributes, name: blockName } ) {
{ showInheritToggle && (
<>
<ToggleControl
label={ __( 'Inner blocks use full width' ) }
checked={ ! inherit }
label={ __(
'Inner blocks respect content width'
) }
checked={
layoutType?.name === 'constrained' ||
!! inherit ||
!! contentSize
}
onChange={ () =>
setAttributes( {
layout: {
inherit: ! inherit,
type:
layoutType?.name ===
'constrained'
? 'default'
: 'constrained',
},
} )
}
/>
<p className="block-editor-hooks__layout-controls-helptext">
{ !! inherit
{ !! inherit ||
layoutType?.name === 'constrained'
? __(
'Nested blocks use theme content width with options for full and wide widths.'
)
Expand All @@ -170,13 +193,20 @@ function LayoutPanel( { setAttributes, attributes, name: blockName } ) {
/>
) }

{ ! inherit && layoutType && (
{ layoutType && layoutType.name !== 'default' && (
<layoutType.inspectorControls
layout={ usedLayout }
onChange={ onChangeLayout }
layoutBlockSupport={ layoutBlockSupport }
/>
) }
{ constrainedType && !! contentSize && (
<constrainedType.inspectorControls
layout={ usedLayout }
onChange={ onChangeLayout }
layoutBlockSupport={ layoutBlockSupport }
/>
) }
</PanelBody>
</InspectorControls>
{ ! inherit && layoutType && (
Expand Down Expand Up @@ -280,9 +310,10 @@ export const withLayoutStyles = createHigherOrderComponent(
const { layout } = attributes;
const { default: defaultBlockLayout } =
getBlockSupport( name, layoutBlockSupportKey ) || {};
const usedLayout = layout?.inherit
? defaultThemeLayout
: layout || defaultBlockLayout || {};
const usedLayout =
layout?.inherit || layout?.contentSize || layout?.wideSize
? { ...layout, type: 'constrained' }
: layout || defaultBlockLayout || {};
const layoutClasses = hasLayoutBlockSupport
? useLayoutClasses( usedLayout, defaultThemeLayout?.definitions )
: null;
Expand Down
Loading