Skip to content

Commit

Permalink
Refactor generate to accept string CSS preset property values (for no…
Browse files Browse the repository at this point in the history
…n-array values).

Updated tests
  • Loading branch information
ramonjd committed Apr 19, 2022
1 parent 2dd2919 commit a369005
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 71 deletions.
74 changes: 38 additions & 36 deletions packages/style-engine/class-wp-style-engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,23 @@ class WP_Style_Engine {
'path' => array( 'color', 'text' ),
'classnames' => array(
'has-text-color' => true,
'has-%s-color' => 'slug',
'has-%s-color' => 'color',
),
),
'background' => array(
'property_key' => 'background-color',
'path' => array( 'color', 'background' ),
'classnames' => array(
'has-background' => true,
'has-%s-background-color' => 'slug',
'has-%s-background-color' => 'background-color',
),
),
'gradient' => array(
'property_key' => 'background',
'path' => array( 'color', 'gradient' ),
'classnames' => array(
'has-background' => true,
'has-%s-gradient-background' => 'slug',
'has-%s-gradient-background' => 'background',
),
),
),
Expand All @@ -77,14 +77,14 @@ class WP_Style_Engine {
'property_key' => 'font-size',
'path' => array( 'typography', 'fontSize' ),
'classnames' => array(
'has-%s-font-size' => 'slug',
'has-%s-font-size' => 'font-size',
),
),
'fontFamily' => array(
'property_key' => 'font-family',
'path' => array( 'typography', 'fontFamily' ),
'classnames' => array(
'has-%s-font-family' => 'slug',
'has-%s-font-family' => 'font-family',
),
),
'fontStyle' => array(
Expand Down Expand Up @@ -130,44 +130,53 @@ public static function get_instance() {
}

/**
* Returns a classname.
* Returns classnames, and generates classname(s) from a CSS preset property pattern, e.g., 'var:preset|color|heavenly-blue'.
*
* @param array $style A single raw style from the generate() $block_styles array.
* @param array $style_value A single raw style value or css preset property from the generate() $block_styles array.
* @param array<string> $style_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
*
* @return string A CSS classname.
* @return array An array of CSS classnames.
*/
protected static function get_classnames( $style, $style_definition ) {
protected static function get_classnames( $style_value, $style_definition ) {
$classnames = array();
// Classnames expect an array value for slug or other metadata required to build the classname.
if ( ! is_array( $style ) ) {
return $classnames;
}

$required_classnames = array();

if ( ! empty( $style_definition['classnames'] ) ) {
foreach ( $style_definition['classnames'] as $classname => $property ) {
if ( true === $property ) {
$required_classnames[] = $classname;
foreach ( $style_definition['classnames'] as $classname => $property_key ) {
if ( true === $property_key ) {
$classnames[] = $classname;
}

if ( isset( $style[ $property ] ) ) {
if ( is_string( $style_value ) && strpos( $style_value, "var:preset|{$property_key}|" ) !== false ) {
$index_to_splice = strrpos( $style_value, '|' ) + 1;
$slug = _wp_to_kebab_case( substr( $style_value, $index_to_splice ) );
// Right now we expect a classname pattern to be stored in BLOCK_STYLE_DEFINITIONS_METADATA.
// One day, if there are no stored schemata, we could allow custom patterns or
// generate classnames based on other properties
// such as a path or a value or a prefix passed in options.
$classnames[] = sprintf( $classname, _wp_to_kebab_case( $style[ $property ] ) );
$classnames[] = sprintf( $classname, $slug );
}
}
}

// Only add the required classnames if there's a valid style value or classname slug.
if ( ! empty( $required_classnames ) && ( $style['value'] || ! empty( $classnames ) ) ) {
$classnames = array_merge( $required_classnames, $classnames );
return $classnames;
}

/**
* Returns CSS rules based on valid block style values.
*
* @param array $style_value A single raw style value from the generate() $block_styles array.
* @param array<string> $style_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
*
* @return array An array of CSS rules.
*/
protected static function get_css( $style_value, $style_definition ) {
$css = array();
// Low-specificity check to see if the value is a CSS preset.
if ( is_string( $style_value ) && strpos( $style_value, 'var:' ) !== false ) {
return $css;
}

return $classnames;
// If required in the future, style definitions could define a callable `value_func` to generate custom CSS rules.
return static::get_css_rules( $style_value, $style_definition['property_key'] );
}

/**
Expand All @@ -193,21 +202,14 @@ public function generate( $block_styles ) {
// Collect CSS and classnames.
foreach ( self::BLOCK_STYLE_DEFINITIONS_METADATA as $definition_group ) {
foreach ( $definition_group as $style_definition ) {
$style = _wp_array_get( $block_styles, $style_definition['path'], null );
$style_value = _wp_array_get( $block_styles, $style_definition['path'], null );

if ( empty( $style ) ) {
if ( empty( $style_value ) ) {
continue;
}

// If there's no value property, we run with the assumption that $style _is_ the value.
$style_value = isset( $style['value'] ) ? $style['value'] : $style;

// If required in the future, style definitions could define a callable `value_func` to generate custom CSS rules.
if ( ! empty( $style_value ) ) {
$css_rules = array_merge( $css_rules, static::get_css_rules( $style_value, $style_definition['property_key'] ) );
}

$classnames = array_merge( $classnames, static::get_classnames( $style, $style_definition ) );
$classnames = array_merge( $classnames, static::get_classnames( $style_value, $style_definition ) );
$css_rules = array_merge( $css_rules, static::get_css( $style_value, $style_definition ) );
}
}

Expand Down
54 changes: 19 additions & 35 deletions packages/style-engine/phpunit/class-wp-style-engine-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ public function data_generate_styles_fixtures() {
'valid_inline_css_and_classnames' => array(
'block_styles' => array(
'color' => array(
'text' => array(
'slug' => 'texas-flood',
),
'text' => 'var:preset|color|texas-flood',
),
'spacing' => array(
'margin' => '111px',
Expand Down Expand Up @@ -122,23 +120,13 @@ public function data_generate_styles_fixtures() {
'valid_classnames_deduped' => array(
'block_styles' => array(
'color' => array(
'text' => array(
'slug' => 'copper-socks',
),
'background' => array(
'slug' => 'splendid-carrot',
),
'gradient' => array(
'slug' => 'like-wow-dude',
),
'text' => 'var:preset|color|copper-socks',
'background' => 'var:preset|background-color|splendid-carrot',
'gradient' => 'var:preset|background|like-wow-dude',
),
'typography' => array(
'fontSize' => array(
'slug' => 'fantastic',
),
'fontFamily' => array(
'slug' => 'totally-awesome',
),
'fontSize' => 'var:preset|font-size|fantastic',
'fontFamily' => 'var:preset|font-family|totally-awesome',
),
),
'expected_output' => array(
Expand All @@ -148,33 +136,29 @@ public function data_generate_styles_fixtures() {
'valid_classnames_with_null_style_values' => array(
'block_styles' => array(
'color' => array(
'text' => array(
'value' => '#fff',
'slug' => null,
),
'background' => array(
'value' => null,
'slug' => null,
),
'text' => '#fff',
'background' => null,
),
),
'expected_output' => array(
'css' => 'color: #fff;',
'classnames' => 'has-text-color',
),
),
'invalid_classnames_slug_key' => array(
'invalid_classnames_preset_value' => array(
'block_styles' => array(
'color' => array(
'text' => array(
'cheese' => 'pizza',
),
'background' => array(
'tomato' => 'sauce',
),
'color' => array(
'text' => 'var:cheese|color|fantastic',
'background' => 'var:preset|fromage|fantastic',
),
'spacing' => array(
'margin' => 'var:cheese|spacing|margin',
'padding' => 'var:preset|spacing|padding',
),
),
'expected_output' => array(),
'expected_output' => array(
'classnames' => 'has-text-color has-background',
),
),
'invalid_classnames_options' => array(
'block_styles' => array(
Expand Down

0 comments on commit a369005

Please sign in to comment.