Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 24 additions & 6 deletions src/wp-includes/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -5565,6 +5565,7 @@ private static function compute_spacing_sizes( $spacing_scale ) {
* For example, `var:preset|color|vivid-green-cyan` becomes `var(--wp--preset--color--vivid-green-cyan)`.
*
* @since 6.3.0
* @since 7.2.0 Preset reference slugs are kebab-cased to match the generated custom properties.
*
* @param string $value The variable such as var:preset|color|vivid-green-cyan to convert.
* @return string The converted variable.
Expand All @@ -5575,12 +5576,29 @@ private static function convert_custom_properties( $value ) {
$token_in = '|';
$token_out = '--';
if ( str_starts_with( $value, $prefix ) ) {
$unwrapped_name = str_replace(
$token_in,
$token_out,
substr( $value, $prefix_len )
);
$value = "var(--wp--$unwrapped_name)";
$parts = explode( $token_in, substr( $value, $prefix_len ) );

/*
* The slug of a preset reference is kebab-cased so the resulting
* custom property matches the one generated from the preset,
* whose slug is also kebab-cased (see `get_settings_values_by_slug()`).
* For slugs that are not already kebab-cased (e.g. `n27`), a verbatim
* conversion produces a reference to a custom property that does
* not exist (`--wp--preset--font-family--n27` instead of the
* generated `--wp--preset--font-family--n-27`).
*
* Duotone is the exception: its custom properties are generated by
* `WP_Duotone` from the presets it registers in
* `get_all_global_styles_presets()`. Duotone references are
* kebab-cased all the same: the editor and the JS style engine
* kebab-case the references of every preset type, and
* `WP_Duotone` looks up presets by kebab-cased filter ID.
*/
if ( 3 === count( $parts ) && 'preset' === $parts[0] ) {
$parts[2] = _wp_to_kebab_case( $parts[2] );
}
Comment thread
jorgefilipecosta marked this conversation as resolved.

$value = 'var(--wp--' . implode( $token_out, $parts ) . ')';
}

return $value;
Expand Down
80 changes: 80 additions & 0 deletions tests/phpunit/tests/theme/wpThemeJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,86 @@ public function test_get_stylesheet_generates_proper_classes_and_css_vars_from_s
);
}

/**
* References to presets (`var:preset|type|slug`) are converted using the
* same kebab-cased slug as the custom properties generated from the
* presets, so both sides match for slugs that change when kebab-cased.
*/
public function test_get_stylesheet_kebab_cases_preset_reference_slugs() {
$theme_json = new WP_Theme_JSON(
array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'settings' => array(
'typography' => array(
'fontFamilies' => array(
array(
'name' => 'N27',
'slug' => 'n27',
'fontFamily' => 'N27, sans-serif',
),
),
),
'spacing' => array(
'spacingSizes' => array(
array(
'name' => 'Small 2',
'slug' => 'small2',
'size' => '8px',
),
),
),
'color' => array(
'duotone' => array(
array(
'colors' => array( '#000000', '#ffffff' ),
'name' => 'Blue Orange 2',
'slug' => 'blueOrange2',
),
),
),
),
'styles' => array(
'typography' => array(
'fontFamily' => 'var:preset|font-family|n27',
),
'spacing' => array(
'padding' => array(
'top' => 'var:preset|spacing|small2',
),
),
'blocks' => array(
'core/image' => array(
'filter' => array(
'duotone' => 'var:preset|duotone|blueOrange2',
),
),
),
),
)
);

$stylesheet = $theme_json->get_stylesheet();

// The custom properties generated from the presets kebab-case the slug.
$this->assertStringContainsString(
'--wp--preset--font-family--n-27: N27, sans-serif',
$stylesheet
);
// References resolve to the same kebab-cased custom property names.
$this->assertStringContainsString(
'font-family: var(--wp--preset--font-family--n-27)',
$stylesheet
);
$this->assertStringContainsString(
'padding-top: var(--wp--preset--spacing--small-2)',
$stylesheet
);
$this->assertStringContainsString(
'var(--wp--preset--duotone--blue-orange-2)',
$stylesheet
);
}

/**
* @ticket 56467
* @ticket 58550
Expand Down
Loading