From ade2ebd01edd63b20f3a1ff631b1ceed6b83b65f Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Thu, 13 Aug 2026 20:43:46 +0900 Subject: [PATCH] Block Supports: Add text shadow support for typography. Co-Authored-By: Claude --- src/wp-includes/block-supports/typography.php | 16 +++++++ src/wp-includes/class-wp-theme-json.php | 47 ++++++++++++------- .../style-engine/class-wp-style-engine.php | 13 +++++ .../tests/block-supports/typography.php | 33 +++++++++++++ 4 files changed, 93 insertions(+), 16 deletions(-) diff --git a/src/wp-includes/block-supports/typography.php b/src/wp-includes/block-supports/typography.php index 6573119933721..e1767ca0d8964 100644 --- a/src/wp-includes/block-supports/typography.php +++ b/src/wp-includes/block-supports/typography.php @@ -37,6 +37,7 @@ function wp_register_typography_support( $block_type ) { $has_text_decoration_support = $typography_supports['__experimentalTextDecoration'] ?? false; $has_text_transform_support = $typography_supports['__experimentalTextTransform'] ?? false; $has_text_indent_support = $typography_supports['textIndent'] ?? false; + $has_text_shadow_support = $typography_supports['textShadow'] ?? false; $has_writing_mode_support = $typography_supports['__experimentalWritingMode'] ?? false; $has_typography_support = $has_font_family_support @@ -50,6 +51,7 @@ function wp_register_typography_support( $block_type ) { || $has_text_decoration_support || $has_text_transform_support || $has_text_indent_support + || $has_text_shadow_support || $has_writing_mode_support; if ( ! $block_type->attributes ) { @@ -73,6 +75,12 @@ function wp_register_typography_support( $block_type ) { 'type' => 'string', ); } + + if ( $has_text_shadow_support && ! array_key_exists( 'textShadow', $block_type->attributes ) ) { + $block_type->attributes['textShadow'] = array( + 'type' => 'string', + ); + } } /** @@ -115,6 +123,7 @@ function wp_apply_typography_support( $block_type, $block_attributes ) { $has_text_decoration_support = $typography_supports['__experimentalTextDecoration'] ?? false; $has_text_transform_support = $typography_supports['__experimentalTextTransform'] ?? false; $has_text_indent_support = $typography_supports['textIndent'] ?? false; + $has_text_shadow_support = $typography_supports['textShadow'] ?? false; $has_writing_mode_support = $typography_supports['__experimentalWritingMode'] ?? false; // Whether to skip individual block support features. @@ -129,6 +138,7 @@ function wp_apply_typography_support( $block_type, $block_attributes ) { $should_skip_text_transform = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textTransform' ); $should_skip_letter_spacing = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'letterSpacing' ); $should_skip_text_indent = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textIndent' ); + $should_skip_text_shadow = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textShadow' ); $should_skip_writing_mode = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'writingMode' ); $typography_block_styles = array(); @@ -232,6 +242,12 @@ function wp_apply_typography_support( $block_type, $block_attributes ) { $typography_block_styles['textIndent'] = $block_attributes['style']['typography']['textIndent'] ?? null; } + if ( $has_text_shadow_support && ! $should_skip_text_shadow ) { + $preset_text_shadow = array_key_exists( 'textShadow', $block_attributes ) ? "var:preset|text-shadow|{$block_attributes['textShadow']}" : null; + $custom_text_shadow = $block_attributes['style']['typography']['textShadow'] ?? null; + $typography_block_styles['textShadow'] = $preset_text_shadow ? $preset_text_shadow : $custom_text_shadow; + } + $attributes = array(); $classnames = array(); $styles = wp_style_engine_get_styles( diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 7175d7a88747d..59793d0ddb5ee 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -127,6 +127,7 @@ class WP_Theme_JSON { * Updated the 'prevent_override' value for font size presets to use 'typography.defaultFontSizes' * and spacing size presets to use `spacing.defaultSpacingSizes`. * @since 6.9.0 Added `border.radiusSizes`. + * @since 7.2.0 Added `typography.textShadowPresets`. * @var array */ const PRESETS_METADATA = array( @@ -188,6 +189,15 @@ class WP_Theme_JSON { 'classes' => array( '.has-$slug-font-family' => 'font-family' ), 'properties' => array( 'font-family' ), ), + array( + 'path' => array( 'typography', 'textShadowPresets' ), + 'prevent_override' => array( 'typography', 'defaultTextShadowPresets' ), + 'use_default_names' => false, + 'value_key' => 'textShadow', + 'css_vars' => '--wp--preset--text-shadow--$slug', + 'classes' => array( '.has-$slug-text-shadow' => 'text-shadow' ), + 'properties' => array( 'text-shadow' ), + ), array( 'path' => array( 'spacing', 'spacingSizes' ), 'prevent_override' => array( 'spacing', 'defaultSpacingSizes' ), @@ -419,6 +429,8 @@ class WP_Theme_JSON { * Added support for `typography.textIndent`. * @since 7.1.0 Added `viewport` property. * Added support for `background.gradient`, `dimensions.minWidth` and `blockVisibility.allowEditing`. + * @since 7.2.0 Added support for `typography.textShadow`, `typography.textShadowPresets`, + * and `typography.defaultTextShadowPresets`. * @var array */ const VALID_SETTINGS = array( @@ -496,22 +508,25 @@ class WP_Theme_JSON { 'defaultPresets' => null, ), 'typography' => array( - 'fluid' => null, - 'customFontSize' => null, - 'defaultFontSizes' => null, - 'dropCap' => null, - 'fontFamilies' => null, - 'fontSizes' => null, - 'fontStyle' => null, - 'fontWeight' => null, - 'letterSpacing' => null, - 'lineHeight' => null, - 'textAlign' => null, - 'textColumns' => null, - 'textDecoration' => null, - 'textIndent' => null, - 'textTransform' => null, - 'writingMode' => null, + 'fluid' => null, + 'customFontSize' => null, + 'defaultFontSizes' => null, + 'dropCap' => null, + 'fontFamilies' => null, + 'fontSizes' => null, + 'fontStyle' => null, + 'fontWeight' => null, + 'letterSpacing' => null, + 'lineHeight' => null, + 'textAlign' => null, + 'textColumns' => null, + 'textDecoration' => null, + 'textIndent' => null, + 'textTransform' => null, + 'textShadow' => null, + 'defaultTextShadowPresets' => null, + 'textShadowPresets' => null, + 'writingMode' => null, ), 'viewport' => array( 'mobile' => null, diff --git a/src/wp-includes/style-engine/class-wp-style-engine.php b/src/wp-includes/style-engine/class-wp-style-engine.php index 21dea5ea65978..46f99f02937b0 100644 --- a/src/wp-includes/style-engine/class-wp-style-engine.php +++ b/src/wp-includes/style-engine/class-wp-style-engine.php @@ -27,6 +27,7 @@ * background.backgroundRepeat and dimensions.aspectRatio. * @since 6.7.0 Added support for typography.writingMode. * @since 7.0.0 Added support for typography.textIndent. + * @since 7.2.0 Added support for typography.textShadow. */ #[AllowDynamicProperties] final class WP_Style_Engine { @@ -350,6 +351,18 @@ final class WP_Style_Engine { ), 'path' => array( 'typography', 'textIndent' ), ), + 'textShadow' => array( + 'property_keys' => array( + 'default' => 'text-shadow', + ), + 'css_vars' => array( + 'text-shadow' => '--wp--preset--text-shadow--$slug', + ), + 'path' => array( 'typography', 'textShadow' ), + 'classnames' => array( + 'has-$slug-text-shadow' => 'text-shadow', + ), + ), 'textTransform' => array( 'property_keys' => array( 'default' => 'text-transform', diff --git a/tests/phpunit/tests/block-supports/typography.php b/tests/phpunit/tests/block-supports/typography.php index 59c47516caa2d..fda7a9edf7c63 100644 --- a/tests/phpunit/tests/block-supports/typography.php +++ b/tests/phpunit/tests/block-supports/typography.php @@ -288,6 +288,39 @@ public function test_should_generate_classname_for_font_family() { $this->assertSame( $expected, $actual ); } + /** + * Tests that a classname is generated for a text shadow preset. + * + * @covers ::wp_apply_typography_support + */ + public function test_should_generate_classname_for_text_shadow() { + $this->test_block_name = 'test/text-shadow-with-class'; + register_block_type( + $this->test_block_name, + array( + 'api_version' => 3, + 'attributes' => array( + 'style' => array( + 'type' => 'object', + ), + ), + 'supports' => array( + 'typography' => array( + 'textShadow' => true, + ), + ), + ) + ); + $registry = WP_Block_Type_Registry::get_instance(); + $block_type = $registry->get_registered( $this->test_block_name ); + $block_atts = array( 'textShadow' => 'light' ); + + $actual = wp_apply_typography_support( $block_type, $block_atts ); + $expected = array( 'class' => 'has-light-text-shadow' ); + + $this->assertSame( $expected, $actual ); + } + /** * Tests generating font size values, including fluid formulae, from fontSizes preset. *