diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index ed17b00f037df..2e475d2cae4d5 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -191,17 +191,78 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { return $content; } +/* +* Add CSS classes and inline styles for layouts to the incoming attributes array. +* This will be applied to the block markup in the front-end. +* +* @param WP_Block_Type $block_type Block type. +* @param array $block_attributes Block attributes. +* +* @return array layouts CSS classes and inline styles. +*/ +function gutenberg_apply_layout_support( $block_type, $block_attributes ) { + $layout_support = _wp_array_get( $block_type->supports, array( '__experimentalLayout' ), false ); + + if ( + is_array( $layout_support ) && + array_key_exists( '__experimentalSkipSerialization', $layout_support ) && + $layout_support['__experimentalSkipSerialization'] + ) { + return array(); + } + + $layout = isset( $block_attributes['layout'] ) ? $block_attributes['layout'] : null; + + $has_flex_layout_support = isset($layout['type']) && $layout['type'] === 'flex'; + + $classes = array(); + $styles = array(); + + // flex layouts. + if ( $has_flex_layout_support ) { + $classes[] = 'has-layout-flex'; + + $justify_content = isset( $layout['justifyContent'] ) ? $layout['justifyContent'] : 'left'; + $orientation = isset( $layout['orientation'] ) ? $layout['orientation'] : 'horizontal'; + $flex_wrap = isset( $layout['flexWrap'] ) ? $layout['flexWrap'] : 'wrap'; + + $classes[] = sprintf( 'has-layout-%s', _wp_to_kebab_case( $flex_wrap ) ); + + if ( $orientation === 'horizontal' ) { + $classes[] = 'has-layout-horizontal'; + $classes[] = sprintf( 'has-layout-horizontal-%s', _wp_to_kebab_case( $justify_content ) ); + } else { + $classes[] = 'has-layout-vertical'; + // Space-between doesn't work on vertical layouts so use default. + if ( $justify_content === 'space-between') { + $classes[] = 'has-layout-vertical-left'; + } else { + $classes[] = sprintf( 'has-layout-vertical-%s', _wp_to_kebab_case( $justify_content ) ); + } + + } + } + + $attributes = array(); + if ( ! empty( $classes ) ) { + $attributes['class'] = implode( ' ', $classes ); + } + + return $attributes; +} + // Register the block support. (overrides core one). WP_Block_Supports::get_instance()->register( 'layout', array( 'register_attribute' => 'gutenberg_register_layout_support', + 'apply' => 'gutenberg_apply_layout_support', ) ); if ( function_exists( 'wp_render_layout_support_flag' ) ) { remove_filter( 'render_block', 'wp_render_layout_support_flag' ); } -add_filter( 'render_block', 'gutenberg_render_layout_support_flag', 10, 2 ); +// add_filter( 'render_block', 'gutenberg_render_layout_support_flag', 10, 2 ); /** * For themes without theme.json file, make sure diff --git a/lib/compat/wordpress-5.9/class-wp-theme-json-5-9.php b/lib/compat/wordpress-5.9/class-wp-theme-json-5-9.php index 5ad476b7d13bb..ff199d49c504e 100644 --- a/lib/compat/wordpress-5.9/class-wp-theme-json-5-9.php +++ b/lib/compat/wordpress-5.9/class-wp-theme-json-5-9.php @@ -157,6 +157,66 @@ class WP_Theme_JSON_5_9 { 'classes' => array( '.has-$slug-font-family' => 'font-family' ), 'properties' => array( 'font-family' ), ), + array( + 'path' => array( 'layout', 'flex' ), + 'prevent_override' => false, + 'use_default_presets' => true, + 'use_default_names' => false, + 'value_key' => 'value', + 'css_vars' => '--wp--preset--layout--$slug', + 'classes' => array( + '.has-layout-$slug' => 'display', + ), + 'properties' => array( 'display' ), + ), + array( + 'path' => array( 'layout', 'flexWrap' ), + 'prevent_override' => false, + 'use_default_presets' => true, + 'use_default_names' => false, + 'value_key' => 'value', + 'css_vars' => '--wp--preset--layout--$slug', + 'classes' => array( + '.has-layout-$slug' => 'flex-wrap', + ), + 'properties' => array( 'flex-wrap' ), + ), + array( + 'path' => array( 'layout', 'flexDirection' ), + 'prevent_override' => false, + 'use_default_presets' => true, + 'use_default_names' => false, + 'value_key' => 'value', + 'css_vars' => '--wp--preset--layout--$slug', + 'classes' => array( + '.has-layout-$slug' => 'flex-direction', + ), + 'properties' => array( 'flex-direction' ), + ), + array( + 'path' => array( 'layout', 'flexJustify' ), + 'prevent_override' => false, + 'use_default_presets' => true, + 'use_default_names' => false, + 'value_key' => 'value', + 'css_vars' => '--wp--preset--layout--$slug', + 'classes' => array( + '.has-layout-$slug' => 'justify-content', + ), + 'properties' => array( 'justify-content' ), + ), + array( + 'path' => array( 'layout', 'flexAlign' ), + 'prevent_override' => false, + 'use_default_presets' => true, + 'use_default_names' => false, + 'value_key' => 'value', + 'css_vars' => '--wp--preset--layout--$slug', + 'classes' => array( + '.has-layout-$slug' => 'align-items', + ), + 'properties' => array( 'align-items' ), + ), ); /** @@ -256,6 +316,11 @@ class WP_Theme_JSON_5_9 { 'layout' => array( 'contentSize' => null, 'wideSize' => null, + 'flex' => null, + 'flexWrap' => null, + 'flexDirection' => null, + 'flexJustify' => null, + 'flexAlign' => null, ), 'spacing' => array( 'blockGap' => null, @@ -312,6 +377,13 @@ class WP_Theme_JSON_5_9 { 'textDecoration' => null, 'textTransform' => null, ), + 'layout' => array( + 'display' => null, + 'flex-wrap' => null, + 'flex-direction' => null, + 'justify-content' => null, + 'align-items' => null, + ), ); /** diff --git a/lib/compat/wordpress-5.9/theme.json b/lib/compat/wordpress-5.9/theme.json index 7691aa4a64e6a..668e554605d3a 100644 --- a/lib/compat/wordpress-5.9/theme.json +++ b/lib/compat/wordpress-5.9/theme.json @@ -185,6 +185,79 @@ ], "text": true }, + "layout": { + "flow": [], + "flex":[ + { + "name": "Flexbox", + "slug": "flex", + "value": "flex" + } + ], + "flexWrap": [ + { + "name": "Wrap", + "slug": "wrap", + "value": "wrap" + }, + { + "name": "Nowrap", + "slug": "nowrap", + "value": "nowrap" + } + ], + "flexDirection": [ + { + "name": "Horizontal", + "slug": "horizontal", + "value": "row" + }, + { + "name": "Vertical", + "slug": "vertical", + "value": "column" + } + ], + "flexJustify": [ + { + "name": "Justify left", + "slug": "horizontal-left", + "value": "flex-start" + }, + { + "name": "Justify center", + "slug": "horizontal-center", + "value": "center" + }, + { + "name": "Justify right", + "slug": "horizontal-right", + "value": "flex-end" + }, + { + "name": "Justify space between", + "slug": "horizontal-space-between", + "value": "space-between" + } + ], + "flexAlign": [ + { + "name": "Align left", + "slug": "vertical-left", + "value": "flex-start" + }, + { + "name": "Align center", + "slug": "vertical-center", + "value": "center" + }, + { + "name": "Align right", + "slug": "vertical-right", + "value": "flex-end" + } + ] + }, "spacing": { "blockGap": null, "margin": false,