Make WordPress Core


Ignore:
Timestamp:
02/10/2026 03:19:36 PM (7 weeks ago)
Author:
scruffian
Message:

Editor: Add support for pseudo elements for the block and its variations on theme.json.

Adds support for pseudo elements on the core/button block for ( ':hover', ':focus', ':focus-visible', ':active' ) at the theme.json level. This is also allowing the block's variations to control the same pseudo elements, so now we can style hover for the outline variation too.

Example usage:

"styles": {
	"blocks": {
		"core/button": {
			"color": {
				"background": "blue"
			},
			":hover": {
				"color": {
					"background": "green"
				}
			},
			":focus": {
				"color": {
					"background": "purple"
				}
			},
			"variations": {
				"outline": {
					":hover": {
						"color": {
							"background": "pink"
						}
					}
				}
			}
		}
	}
}

Reviewed by palak678, getdave, MaggieCabrera.

Props MaggieCabrera, scruffian, palak678. joedolson, getdave, mikachan.
Fixes #64263.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/theme/wpThemeJson.php

    r61573 r61607  
    60706070     * @ticket 60613
    60716071     *
    6072      * @covers WP_Theme_JSON_Gutenberg::resolve_variables
    6073      * @covers WP_Theme_JSON_Gutenberg::convert_variables_to_value
     6072     * @covers WP_Theme_JSON::resolve_variables
     6073     * @covers WP_Theme_JSON::convert_variables_to_value
    60746074     */
    60756075    public function test_resolve_variables() {
     
    66946694        $this->assertEqualSetsWithIndex( $expected, $actual );
    66956695    }
     6696
     6697    /**
     6698     * Test that block pseudo selectors are processed correctly.
     6699     */
     6700    public function test_block_pseudo_selectors_are_processed() {
     6701        $theme_json = new WP_Theme_JSON(
     6702            array(
     6703                'version' => WP_Theme_JSON::LATEST_SCHEMA,
     6704                'styles'  => array(
     6705                    'blocks' => array(
     6706                        'core/button' => array(
     6707                            'color'  => array(
     6708                                'text'       => 'white',
     6709                                'background' => 'blue',
     6710                            ),
     6711                            ':hover' => array(
     6712                                'color' => array(
     6713                                    'text'       => 'blue',
     6714                                    'background' => 'white',
     6715                                ),
     6716                            ),
     6717                            ':focus' => array(
     6718                                'color' => array(
     6719                                    'text'       => 'red',
     6720                                    'background' => 'yellow',
     6721                                ),
     6722                            ),
     6723                        ),
     6724                    ),
     6725                ),
     6726            )
     6727        );
     6728
     6729        $expected = ':root :where(.wp-block-button .wp-block-button__link){background-color: blue;color: white;}:root :where(.wp-block-button .wp-block-button__link:hover){background-color: white;color: blue;}:root :where(.wp-block-button .wp-block-button__link:focus){background-color: yellow;color: red;}';
     6730        $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) );
     6731    }
     6732
     6733    /**
     6734     * Test that block pseudo selectors are processed correctly within variations.
     6735     */
     6736    public function test_block_variation_pseudo_selectors_are_processed() {
     6737        register_block_style(
     6738            'core/button',
     6739            array(
     6740                'name'  => 'outline',
     6741                'label' => 'Outline',
     6742            )
     6743        );
     6744
     6745        $theme_json = new WP_Theme_JSON(
     6746            array(
     6747                'version' => WP_Theme_JSON::LATEST_SCHEMA,
     6748                'styles'  => array(
     6749                    'blocks' => array(
     6750                        'core/button' => array(
     6751                            'color'      => array(
     6752                                'text'       => 'white',
     6753                                'background' => 'blue',
     6754                            ),
     6755                            'variations' => array(
     6756                                'outline' => array(
     6757                                    'color'  => array(
     6758                                        'text'       => 'currentColor',
     6759                                        'background' => 'transparent',
     6760                                    ),
     6761                                    'border' => array(
     6762                                        'color' => 'currentColor',
     6763                                        'width' => '1px',
     6764                                        'style' => 'solid',
     6765                                    ),
     6766                                    ':hover' => array(
     6767                                        'color' => array(
     6768                                            'text'       => 'white',
     6769                                            'background' => 'red',
     6770                                        ),
     6771                                    ),
     6772                                    ':focus' => array(
     6773                                        'color' => array(
     6774                                            'text'       => 'black',
     6775                                            'background' => 'yellow',
     6776                                        ),
     6777                                    ),
     6778                                ),
     6779                            ),
     6780                        ),
     6781                    ),
     6782                ),
     6783            )
     6784        );
     6785
     6786        $expected = ':root :where(.wp-block-button .wp-block-button__link){background-color: blue;color: white;}:root :where(.wp-block-button.is-style-outline .wp-block-button__link){background-color: transparent;border-color: currentColor;border-width: 1px;border-style: solid;color: currentColor;}:root :where(.wp-block-button.is-style-outline .wp-block-button__link:hover){background-color: red;color: white;}:root :where(.wp-block-button.is-style-outline .wp-block-button__link:focus){background-color: yellow;color: black;}';
     6787        $actual   = $theme_json->get_stylesheet(
     6788            array( 'styles' ),
     6789            null,
     6790            array(
     6791                'skip_root_layout_styles'        => true,
     6792                'include_block_style_variations' => true,
     6793            )
     6794        );
     6795
     6796        unregister_block_style( 'core/button', 'outline' );
     6797
     6798        $this->assertSame( $expected, $actual );
     6799    }
     6800
     6801    /**
     6802     * Test that non-whitelisted pseudo selectors are ignored for blocks.
     6803     */
     6804    public function test_block_pseudo_selectors_ignores_non_whitelisted() {
     6805        $theme_json = new WP_Theme_JSON(
     6806            array(
     6807                'version' => WP_Theme_JSON::LATEST_SCHEMA,
     6808                'styles'  => array(
     6809                    'blocks' => array(
     6810                        'core/button' => array(
     6811                            'color'     => array(
     6812                                'text'       => 'white',
     6813                                'background' => 'blue',
     6814                            ),
     6815                            ':hover'    => array(
     6816                                'color' => array(
     6817                                    'text'       => 'blue',
     6818                                    'background' => 'white',
     6819                                ),
     6820                            ),
     6821                            ':levitate' => array(
     6822                                'color' => array(
     6823                                    'text'       => 'yellow',
     6824                                    'background' => 'black',
     6825                                ),
     6826                            ),
     6827                        ),
     6828                    ),
     6829                ),
     6830            )
     6831        );
     6832
     6833        $expected = ':root :where(.wp-block-button .wp-block-button__link){background-color: blue;color: white;}:root :where(.wp-block-button .wp-block-button__link:hover){background-color: white;color: blue;}';
     6834        $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) );
     6835        $this->assertStringNotContainsString( '.wp-block-button .wp-block-button__link:levitate{', $theme_json->get_stylesheet( array( 'styles' ) ) );
     6836    }
     6837
     6838    /**
     6839     * Test that blocks without pseudo selector support ignore pseudo selectors.
     6840     */
     6841    public function test_blocks_without_pseudo_support_ignore_pseudo_selectors() {
     6842        $theme_json = new WP_Theme_JSON(
     6843            array(
     6844                'version' => WP_Theme_JSON::LATEST_SCHEMA,
     6845                'styles'  => array(
     6846                    'blocks' => array(
     6847                        'core/paragraph' => array(
     6848                            'color'  => array(
     6849                                'text' => 'black',
     6850                            ),
     6851                            ':hover' => array(
     6852                                'color' => array(
     6853                                    'text' => 'red',
     6854                                ),
     6855                            ),
     6856                        ),
     6857                    ),
     6858                ),
     6859            )
     6860        );
     6861
     6862        $expected = ':root :where(p){color: black;}';
     6863        $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) );
     6864        $this->assertStringNotContainsString( 'p:hover{', $theme_json->get_stylesheet( array( 'styles' ) ) );
     6865    }
     6866
     6867    /**
     6868     * Test that block pseudo selectors work with elements within blocks.
     6869     */
     6870    public function test_block_pseudo_selectors_with_elements() {
     6871        $theme_json = new WP_Theme_JSON(
     6872            array(
     6873                'version' => WP_Theme_JSON::LATEST_SCHEMA,
     6874                'styles'  => array(
     6875                    'blocks' => array(
     6876                        'core/button' => array(
     6877                            'color'    => array(
     6878                                'text'       => 'white',
     6879                                'background' => 'blue',
     6880                            ),
     6881                            ':hover'   => array(
     6882                                'color' => array(
     6883                                    'text'       => 'blue',
     6884                                    'background' => 'white',
     6885                                ),
     6886                            ),
     6887                            'elements' => array(
     6888                                'button' => array(
     6889                                    'color'  => array(
     6890                                        'text' => 'green',
     6891                                    ),
     6892                                    ':hover' => array(
     6893                                        'color' => array(
     6894                                            'text' => 'orange',
     6895                                        ),
     6896                                    ),
     6897                                ),
     6898                            ),
     6899                        ),
     6900                    ),
     6901                ),
     6902            )
     6903        );
     6904
     6905        $expected = ':root :where(.wp-block-button .wp-block-button__link){background-color: blue;color: white;}:root :where(.wp-block-button .wp-block-button__link:hover){background-color: white;color: blue;}:root :where(.wp-block-button .wp-block-button__link .wp-element-button,.wp-block-button .wp-block-button__link  .wp-block-button__link){color: green;}:root :where(.wp-block-button .wp-block-button__link .wp-element-button:hover,.wp-block-button .wp-block-button__link  .wp-block-button__link:hover){color: orange;}';
     6906        $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) );
     6907    }
    66966908}
Note: See TracChangeset for help on using the changeset viewer.