diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 01ef8a348e5bc..c171b77e662de 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -1721,6 +1721,8 @@ function wp_default_styles( $styles ) { // Only add CONTENT styles here that should be enqueued in the iframe! $wp_edit_blocks_dependencies = array( + // Design tokens must load first so token-consuming styles resolve their values. + 'wp-theme', 'wp-base-styles', 'wp-components', /* @@ -1761,8 +1763,9 @@ function wp_default_styles( $styles ) { 'block-editor' => array( 'wp-components', 'wp-preferences' ), 'block-library' => array(), 'block-directory' => array(), + 'theme' => array(), 'base-styles' => array(), - 'components' => array(), + 'components' => array( 'wp-theme' ), 'commands' => array( 'wp-components' ), 'edit-post' => array( 'wp-components', @@ -1829,6 +1832,10 @@ function wp_default_styles( $styles ) { $path = "/wp-includes/css/dist/base-styles/admin-schemes$suffix.css"; } + if ( 'theme' === $package ) { + $path = "/wp-includes/css/dist/theme/design-tokens$suffix.css"; + } + $styles->add( $handle, $path, $dependencies ); $styles->add_data( $handle, 'path', ABSPATH . $path ); } @@ -1872,6 +1879,7 @@ function wp_default_styles( $styles ) { 'wp-reset-editor-styles', 'wp-editor-classic-layout-styles', 'wp-block-library-theme', + 'wp-theme', 'wp-edit-blocks', 'wp-block-editor', 'wp-block-library', diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index de6fefb94b5bb..b4c478eaf4cf0 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -557,6 +557,67 @@ public function test_block_styles_for_viewing_with_split_styles() { ); } + /** + * Tests that the wp-theme design tokens stylesheet is registered. + * + * @ticket 65646 + * + * @covers ::wp_default_styles + */ + public function test_wp_theme_design_tokens_style_is_registered() { + wp_default_styles( $GLOBALS['wp_styles'] ); + + $this->assertArrayHasKey( + 'wp-theme', + $GLOBALS['wp_styles']->registered, + 'The wp-theme style handle should be registered.' + ); + $this->assertSame( + '/' . WPINC . '/css/dist/theme/design-tokens.css', + $GLOBALS['wp_styles']->registered['wp-theme']->src, + 'The wp-theme style should point to the design tokens stylesheet.' + ); + } + + /** + * Tests that token-consuming package styles depend on wp-theme. + * + * Design tokens must be registered as a dependency so their values are + * defined before the consuming styles that reference them. + * + * @ticket 65646 + * + * @covers ::wp_default_styles + */ + public function test_wp_components_depends_on_wp_theme() { + wp_default_styles( $GLOBALS['wp_styles'] ); + + $this->assertContains( + 'wp-theme', + $GLOBALS['wp_styles']->registered['wp-components']->deps, + 'The wp-components style should depend on wp-theme.' + ); + } + + /** + * Tests that wp-theme is the first editor style dependency. + * + * Design tokens must load before any other editor styles so that + * token-consuming rules resolve to their intended values. + * + * @ticket 65646 + * + * @covers ::wp_default_styles + */ + public function test_wp_edit_blocks_loads_wp_theme_first() { + wp_default_styles( $GLOBALS['wp_styles'] ); + + $deps = $GLOBALS['wp_styles']->registered['wp-edit-blocks']->deps; + + $this->assertContains( 'wp-theme', $deps, 'The wp-edit-blocks style should depend on wp-theme.' ); + $this->assertSame( 'wp-theme', reset( $deps ), 'wp-theme should be the first wp-edit-blocks dependency.' ); + } + /** * @ticket 58394 * @ticket 63887