Skip to content

Commit 64479cf

Browse files
author
Glen Davies
committed
Add style engine handling of spacing presets
1 parent 6eecad6 commit 64479cf

File tree

5 files changed

+107
-28
lines changed

5 files changed

+107
-28
lines changed

lib/block-supports/border.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) {
119119

120120
// Collect classes and styles.
121121
$attributes = array();
122-
$styles = gutenberg_style_engine_generate( array( 'border' => $border_block_styles ) );
122+
$styles = gutenberg_style_engine_generate( array( 'border' => $border_block_styles ), array( 'css_vars' => true ) );
123123

124124
if ( ! empty( $styles['classnames'] ) ) {
125125
$attributes['class'] = $styles['classnames'];

lib/block-supports/spacing.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ function gutenberg_apply_spacing_support( $block_type, $block_attributes ) {
5858
$spacing_block_styles['padding'] = $has_padding_support && ! $skip_padding ? _wp_array_get( $block_styles, array( 'spacing', 'padding' ), null ) : null;
5959
$spacing_block_styles['margin'] = $has_margin_support && ! $skip_margin ? _wp_array_get( $block_styles, array( 'spacing', 'margin' ), null ) : null;
6060
$styles = gutenberg_style_engine_generate(
61-
array( 'spacing' => $spacing_block_styles )
61+
array( 'spacing' => $spacing_block_styles ),
62+
array( 'css_vars' => true )
6263
);
6364

6465
if ( ! empty( $styles['css'] ) ) {

packages/style-engine/class-wp-style-engine.php

+46-23
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class WP_Style_Engine {
5151
),
5252
'path' => array( 'color', 'text' ),
5353
'css_vars' => array(
54-
'--wp--preset--color--$slug' => 'color',
54+
'color' => '--wp--preset--color--$slug',
5555
),
5656
'classnames' => array(
5757
'has-text-color' => true,
@@ -148,13 +148,19 @@ class WP_Style_Engine {
148148
'individual' => 'padding-%s',
149149
),
150150
'path' => array( 'spacing', 'padding' ),
151+
'css_vars' => array(
152+
'spacing' => '--wp--preset--spacing--$slug',
153+
),
151154
),
152155
'margin' => array(
153156
'property_keys' => array(
154157
'default' => 'margin',
155158
'individual' => 'margin-%s',
156159
),
157160
'path' => array( 'spacing', 'margin' ),
161+
'css_vars' => array(
162+
'spacing' => '--wp--preset--spacing--$slug',
163+
),
158164
),
159165
),
160166
'typography' => array(
@@ -246,6 +252,28 @@ protected static function get_slug_from_preset_value( $style_value, $property_ke
246252
return null;
247253
}
248254

255+
/**
256+
* Generates a css var string, eg var(--wp--preset--color--background) from a preset string, eg. `var:preset|space|50`.
257+
*
258+
* @param string $style_value A single css preset value.
259+
* @param array $css_vars The css var patterns used to generate the var string.
260+
*
261+
* @return string|null The css var, or null if no match for slug found.
262+
*/
263+
protected static function get_css_var_value( $style_value, $css_vars ) {
264+
foreach ( $css_vars as $property_key => $css_var_pattern ) {
265+
$slug = static::get_slug_from_preset_value( $style_value, $property_key );
266+
if ( $slug ) {
267+
$var = strtr(
268+
$css_var_pattern,
269+
array( '$slug' => $slug )
270+
);
271+
return "var($var)";
272+
}
273+
}
274+
return null;
275+
}
276+
249277
/**
250278
* Checks whether an incoming block style value is valid.
251279
*
@@ -315,7 +343,7 @@ protected static function get_css_declarations( $style_value, $style_definition,
315343
isset( $style_definition['value_func'] ) &&
316344
is_callable( $style_definition['value_func'] )
317345
) {
318-
return call_user_func( $style_definition['value_func'], $style_value, $style_definition );
346+
return call_user_func( $style_definition['value_func'], $style_value, $style_definition, $should_return_css_vars );
319347
}
320348

321349
$css_declarations = array();
@@ -325,15 +353,9 @@ protected static function get_css_declarations( $style_value, $style_definition,
325353
// Check if the value is a CSS preset and there's a corresponding css_var pattern in the style definition.
326354
if ( is_string( $style_value ) && strpos( $style_value, 'var:' ) !== false ) {
327355
if ( $should_return_css_vars && ! empty( $style_definition['css_vars'] ) ) {
328-
foreach ( $style_definition['css_vars'] as $css_var_pattern => $property_key ) {
329-
$slug = static::get_slug_from_preset_value( $style_value, $property_key );
330-
if ( $slug ) {
331-
$css_var = strtr(
332-
$css_var_pattern,
333-
array( '$slug' => $slug )
334-
);
335-
$css_declarations[ $style_property_keys['default'] ] = "var($css_var)";
336-
}
356+
$css_var = static::get_css_var_value( $style_value, $style_definition['css_vars'] );
357+
if ( $css_var ) {
358+
$css_declarations[ $style_property_keys['default'] ] = $css_var;
337359
}
338360
}
339361
return $css_declarations;
@@ -344,8 +366,13 @@ protected static function get_css_declarations( $style_value, $style_definition,
344366
// for styles such as margins and padding.
345367
if ( is_array( $style_value ) ) {
346368
foreach ( $style_value as $key => $value ) {
347-
$individual_property = sprintf( $style_property_keys['individual'], _wp_to_kebab_case( $key ) );
348-
$css_declarations[ $individual_property ] = $value;
369+
if ( is_string( $value ) && strpos( $value, 'var:' ) !== false && $should_return_css_vars && ! empty( $style_definition['css_vars'] ) ) {
370+
$value = static::get_css_var_value( $value, $style_definition['css_vars'] );
371+
}
372+
$individual_property = sprintf( $style_property_keys['individual'], _wp_to_kebab_case( $key ) );
373+
if ( $value ) {
374+
$css_declarations[ $individual_property ] = $value;
375+
}
349376
}
350377
} else {
351378
$css_declarations[ $style_property_keys['default'] ] = $style_value;
@@ -441,12 +468,13 @@ public function generate( $block_styles, $options ) {
441468
* "border-{top|right|bottom|left}-{color|width|style}: {value};" or,
442469
* "border-image-{outset|source|width|repeat|slice}: {value};"
443470
*
444-
* @param array $style_value A single raw Gutenberg style attributes value for a CSS property.
445-
* @param array $individual_property_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
471+
* @param array $style_value A single raw Gutenberg style attributes value for a CSS property.
472+
* @param array $individual_property_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
473+
* @param boolean $should_return_css_vars Whether to try to build and return CSS var values.
446474
*
447475
* @return array An array of CSS definitions, e.g., array( "$property" => "$value" ).
448476
*/
449-
protected static function get_individual_property_css_declarations( $style_value, $individual_property_definition ) {
477+
protected static function get_individual_property_css_declarations( $style_value, $individual_property_definition, $should_return_css_vars ) {
450478
$css_declarations = array();
451479

452480
if ( ! is_array( $style_value ) || empty( $style_value ) || empty( $individual_property_definition['path'] ) ) {
@@ -470,13 +498,8 @@ protected static function get_individual_property_css_declarations( $style_value
470498

471499
if ( $style_definition && isset( $style_definition['property_keys']['individual'] ) ) {
472500
// Set a CSS var if there is a valid preset value.
473-
$slug = isset( $individual_property_definition['css_vars'][ $css_property ] ) ? static::get_slug_from_preset_value( $value, $css_property ) : null;
474-
if ( $slug ) {
475-
$css_var = strtr(
476-
$individual_property_definition['css_vars'][ $css_property ],
477-
array( '$slug' => $slug )
478-
);
479-
$value = "var($css_var)";
501+
if ( is_string( $value ) && strpos( $value, 'var:' ) !== false && $should_return_css_vars && ! empty( $individual_property_definition['css_vars'] ) ) {
502+
$value = static::get_css_var_value( $value, $individual_property_definition['css_vars'] );
480503
}
481504
$individual_css_property = sprintf( $style_definition['property_keys']['individual'], $individual_property_key );
482505
$css_declarations[ $individual_css_property ] = $value;

packages/style-engine/phpunit/class-wp-style-engine-test.php

+55-2
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,59 @@ public function data_generate_styles_fixtures() {
246246
),
247247
),
248248

249+
'valid_spacing_single_preset_values' => array(
250+
'block_styles' => array(
251+
'spacing' => array(
252+
'margin' => 'var:preset|spacing|10',
253+
'padding' => 'var:preset|spacing|20',
254+
),
255+
),
256+
'options' => array( 'css_vars' => true ),
257+
'expected_output' => array(
258+
'css' => 'padding: var(--wp--preset--spacing--20); margin: var(--wp--preset--spacing--10);',
259+
),
260+
),
261+
262+
'valid_spacing_multi_preset_values' => array(
263+
'block_styles' => array(
264+
'spacing' => array(
265+
'margin' => array(
266+
'left' => 'var:preset|spacing|10',
267+
'right' => 'var:preset|spacing|20',
268+
'top' => '1rem',
269+
'bottom' => '1rem',
270+
),
271+
'padding' => array(
272+
'left' => 'var:preset|spacing|30',
273+
'right' => 'var:preset|spacing|40',
274+
'top' => '14px',
275+
'bottom' => '14px',
276+
),
277+
),
278+
),
279+
'options' => array( 'css_vars' => true ),
280+
'expected_output' => array(
281+
'css' => 'padding-left: var(--wp--preset--spacing--30); padding-right: var(--wp--preset--spacing--40); padding-top: 14px; padding-bottom: 14px; margin-left: var(--wp--preset--spacing--10); margin-right: var(--wp--preset--spacing--20); margin-top: 1rem; margin-bottom: 1rem;',
282+
),
283+
),
284+
285+
'invalid_spacing_multi_preset_values' => array(
286+
'block_styles' => array(
287+
'spacing' => array(
288+
'margin' => array(
289+
'left' => 'var:preset|spaceman|10',
290+
'right' => 'var:preset|spaceman|20',
291+
'top' => '1rem',
292+
'bottom' => '1rem',
293+
),
294+
),
295+
),
296+
'options' => array( 'css_vars' => true ),
297+
'expected_output' => array(
298+
'css' => 'margin-top: 1rem; margin-bottom: 1rem;',
299+
),
300+
),
301+
249302
'invalid_classnames_options' => array(
250303
'block_styles' => array(
251304
'typography' => array(
@@ -285,7 +338,7 @@ public function data_generate_styles_fixtures() {
285338
),
286339
),
287340
),
288-
'options' => array(),
341+
'options' => array( 'css_vars' => true ),
289342
'expected_output' => array(
290343
'css' => 'border-top-color: #fe1; border-top-width: 1.5rem; border-top-style: dashed; border-right-color: #fe2; border-right-width: 1.4rem; border-right-style: solid; border-bottom-color: #fe3; border-bottom-width: 1.3rem; border-left-color: var(--wp--preset--color--swampy-yellow); border-left-width: 0.5rem; border-left-style: dotted;',
291344
),
@@ -315,7 +368,7 @@ public function data_generate_styles_fixtures() {
315368
),
316369
),
317370
),
318-
'options' => array(),
371+
'options' => array( 'css_vars' => true ),
319372
'expected_output' => array(
320373
'css' => 'border-bottom-color: var(--wp--preset--color--terrible-lizard);',
321374
),

packages/style-engine/src/styles/utils.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ export function generateBoxRules(
8181
} else {
8282
const sideRules = individualProperties.reduce(
8383
( acc: GeneratedCSSRule[], side: string ) => {
84-
const value: string | undefined = get( boxStyle, [ side ] );
84+
const value: string | undefined = getCSSVarFromStyleValue(
85+
get( boxStyle, [ side ] )
86+
);
8587
if ( value ) {
8688
acc.push( {
8789
selector: options?.selector,

0 commit comments

Comments
 (0)