Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ Settings related to typography.
| textAlign | Allow users to set the text align. | `boolean` | `true` |
| textColumns | Allow users to set the number of text columns. | `boolean` | `false` |
| textDecoration | Allow users to set custom text decorations. | `boolean` | `true` |
| textShadow | Allow users to set custom text shadows. | `boolean` | `true` |
| writingMode | Allow users to set the writing mode. | `boolean` | `false` |
| textTransform | Allow users to set custom text transforms. | `boolean` | `true` |
| dropCap | Enable drop cap. | `boolean` | `true` |
Expand Down Expand Up @@ -327,6 +328,7 @@ Typography styles.
| textAlign | Sets the `text-align` CSS property. | `string`, `{ ref }` |
| textColumns | Sets the `column-count` CSS property. | `string`, `{ ref }` |
| textDecoration | Sets the `text-decoration` CSS property. | `string`, `{ ref }` |
| textShadow | Sets the `text-shadow` CSS property. | `string`, `{ ref }` |
| writingMode | Sets the `writing-mode` CSS property. | `string`, `{ ref }` |
| textTransform | Sets the `text-transform` CSS property. | `string`, `{ ref }` |

Expand Down
9 changes: 9 additions & 0 deletions lib/block-supports/typography.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ function gutenberg_register_typography_support( $block_type ) {
$has_text_columns_support = $typography_supports['textColumns'] ?? false;
$has_text_decoration_support = $typography_supports['__experimentalTextDecoration'] ?? false;
$has_text_transform_support = $typography_supports['__experimentalTextTransform'] ?? false;
$has_text_shadow_support = $typography_supports['__experimentalTextShadow'] ?? false;
$has_writing_mode_support = $typography_supports['__experimentalWritingMode'] ?? false;

$has_typography_support = $has_font_family_support
Expand All @@ -42,6 +43,7 @@ function gutenberg_register_typography_support( $block_type ) {
|| $has_text_columns_support
|| $has_text_decoration_support
|| $has_text_transform_support
|| $has_text_shadow_support
|| $has_writing_mode_support;

if ( ! $block_type->attributes ) {
Expand Down Expand Up @@ -101,6 +103,7 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
$has_text_columns_support = $typography_supports['textColumns'] ?? false;
$has_text_decoration_support = $typography_supports['__experimentalTextDecoration'] ?? false;
$has_text_transform_support = $typography_supports['__experimentalTextTransform'] ?? false;
$has_text_shadow_support = $typography_supports['__experimentalTextShadow'] ?? false;
$has_writing_mode_support = $typography_supports['__experimentalWritingMode'] ?? false;

// Whether to skip individual block support features.
Expand All @@ -114,6 +117,7 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
$should_skip_text_decoration = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textDecoration' );
$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_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();
Expand Down Expand Up @@ -170,6 +174,11 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
gutenberg_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['letterSpacing'], 'letter-spacing' );
}

if ( $has_text_shadow_support && ! $should_skip_text_shadow && isset( $block_attributes['style']['typography']['textShadow'] ) ) {
$typography_block_styles['textShadow'] =
gutenberg_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['textShadow'], 'text-shadow' );
}

if ( $has_writing_mode_support && ! $should_skip_writing_mode && isset( $block_attributes['style']['typography']['writingMode'] ) ) {
$typography_block_styles['writingMode'] = $block_attributes['style']['typography']['writingMode'] ?? null;
}
Expand Down
3 changes: 3 additions & 0 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ class WP_Theme_JSON_Gutenberg {
'--wp--style--root--padding-bottom' => array( 'spacing', 'padding', 'bottom' ),
'--wp--style--root--padding-left' => array( 'spacing', 'padding', 'left' ),
'text-decoration' => array( 'typography', 'textDecoration' ),
'text-shadow' => array( 'typography', 'textShadow' ),
'text-transform' => array( 'typography', 'textTransform' ),
'filter' => array( 'filter', 'duotone' ),
'box-shadow' => array( 'shadow' ),
Expand Down Expand Up @@ -467,6 +468,7 @@ class WP_Theme_JSON_Gutenberg {
'textAlign' => null,
'textColumns' => null,
'textDecoration' => null,
'textShadow' => null,
'textTransform' => null,
'writingMode' => null,
),
Expand Down Expand Up @@ -564,6 +566,7 @@ class WP_Theme_JSON_Gutenberg {
'textAlign' => null,
'textColumns' => null,
'textDecoration' => null,
'textShadow' => null,
'textTransform' => null,
'writingMode' => null,
),
Expand Down
1 change: 1 addition & 0 deletions lib/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@
"textAlign": true,
"textColumns": false,
"textDecoration": true,
"textShadow": true,
"textTransform": true,
"writingMode": false
},
Expand Down
3 changes: 3 additions & 0 deletions packages/block-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

### Enhancement

- `TextShadowControl`: Add support for text shadow styles in the block editor.
## 15.3.0 (2025-09-03)

## 15.2.0 (2025-08-20)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const VALID_SETTINGS = [
'typography.textAlign',
'typography.textColumns',
'typography.textDecoration',
'typography.textShadow',
'typography.textTransform',
'typography.writingMode',
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import LetterSpacingControl from '../letter-spacing-control';
import TextAlignmentControl from '../text-alignment-control';
import TextTransformControl from '../text-transform-control';
import TextDecorationControl from '../text-decoration-control';
import TextShadowControl from '../text-shadow-control';
import WritingModeControl from '../writing-mode-control';
import { getValueFromVariable, useToolsPanelDropdownMenuProps } from './utils';
import { setImmutably } from '../../utils/object';
Expand All @@ -39,6 +40,7 @@ export function useHasTypographyPanel( settings ) {
const hasTextAlign = useHasTextAlignmentControl( settings );
const hasTextTransform = useHasTextTransformControl( settings );
const hasTextDecoration = useHasTextDecorationControl( settings );
const hasTextShadow = useHasTextShadowControl( settings );
const hasWritingMode = useHasWritingModeControl( settings );
const hasTextColumns = useHasTextColumnsControl( settings );
const hasFontSize = useHasFontSizeControl( settings );
Expand All @@ -52,6 +54,7 @@ export function useHasTypographyPanel( settings ) {
hasTextTransform ||
hasFontSize ||
hasTextDecoration ||
hasTextShadow ||
hasWritingMode ||
hasTextColumns
);
Expand Down Expand Up @@ -107,6 +110,10 @@ function useHasTextDecorationControl( settings ) {
return settings?.typography?.textDecoration;
}

function useHasTextShadowControl( settings ) {
return settings?.typography?.textShadow;
}

function useHasWritingModeControl( settings ) {
return settings?.typography?.writingMode;
}
Expand Down Expand Up @@ -166,6 +173,7 @@ const DEFAULT_CONTROLS = {
textAlign: true,
textTransform: true,
textDecoration: true,
textShadow: true,
writingMode: true,
textColumns: true,
};
Expand Down Expand Up @@ -376,6 +384,21 @@ export default function TypographyPanel( {
const hasWritingMode = () => !! value?.typography?.writingMode;
const resetWritingMode = () => setWritingMode( undefined );

// Text Shadow
const hasTextShadowControl = useHasTextShadowControl( settings );
const textShadow = decodeValue( inheritedValue?.typography?.textShadow );
const setTextShadow = ( newValue ) => {
onChange(
setImmutably(
value,
[ 'typography', 'textShadow' ],
newValue || undefined
)
);
};
const hasTextShadow = () => !! value?.typography?.textShadow;
const resetTextShadow = () => setTextShadow( undefined );

// Text Alignment
const hasTextAlignmentControl = useHasTextAlignmentControl( settings );

Expand Down Expand Up @@ -587,6 +610,22 @@ export default function TypographyPanel( {
/>
</ToolsPanelItem>
) }
{ hasTextShadowControl && (
<ToolsPanelItem
label={ __( 'Shadow' ) }
hasValue={ hasTextShadow }
onDeselect={ resetTextShadow }
isShownByDefault={ defaultControls.textShadow }
panelId={ panelId }
>
<TextShadowControl
value={ textShadow }
onChange={ setTextShadow }
__next40pxDefaultSize
__nextHasNoMarginBottom
/>
</ToolsPanelItem>
) }
</Wrapper>
);
}
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export { default as __experimentalFontAppearanceControl } from './font-appearanc
export { default as __experimentalFontFamilyControl } from './font-family';
export { default as __experimentalLetterSpacingControl } from './letter-spacing-control';
export { default as __experimentalTextDecorationControl } from './text-decoration-control';
export { default as __experimentalTextShadowControl } from './text-shadow-control';
export { default as __experimentalTextTransformControl } from './text-transform-control';
export { default as __experimentalWritingModeControl } from './writing-mode-control';
export { default as __experimentalColorGradientControl } from './colors-gradients/control';
Expand Down
174 changes: 174 additions & 0 deletions packages/block-editor/src/components/text-shadow-control/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# TextShadowControl

A control component for managing text shadow styles in typography settings.

## Description

TextShadowControl provides a user interface for setting the CSS `text-shadow` property, which adds shadow effects to text. The control allows users to adjust horizontal offset, vertical offset, blur radius, and shadow color.

## Usage

```jsx
import { __experimentalTextShadowControl as TextShadowControl } from '@wordpress/block-editor';

function MyComponent() {
const [ textShadow, setTextShadow ] = useState( 'none' );

return (
<TextShadowControl
value={ textShadow }
onChange={ setTextShadow }
__next40pxDefaultSize
__nextHasNoMarginBottom
/>
);
}
```

## Props

### `value`
- **Type:** `string`
- **Required:** No
- **Default:** `''`

The current text shadow value in CSS format. Examples:
- `'none'` - No shadow
- `'2px 2px 4px #000000'` - 2px horizontal, 2px vertical, 4px blur, black color
- `'0px 0px 10px rgba(255, 0, 0, 0.5)'` - Glow effect with red color

### `onChange`
- **Type:** `Function`
- **Required:** Yes

Callback function called when the text shadow value changes. Receives the new CSS text-shadow string.

### `__next40pxDefaultSize`
- **Type:** `boolean`
- **Required:** No
- **Default:** `false`

Whether to use the larger 40px default size that will become the default in a future version.

### `__nextHasNoMarginBottom`
- **Type:** `boolean`
- **Required:** No
- **Default:** `false`

Whether to remove the bottom margin from the control (new margin-free styles for future versions).

### `className`
- **Type:** `string`
- **Required:** No

Additional CSS class name to apply to the control.

## Text Shadow Parameters

### Horizontal Offset
Controls the horizontal distance of the shadow from the text. Positive values move the shadow to the right, negative values to the left.
- **Range:** -20px to 20px
- **Default:** 0px

### Vertical Offset
Controls the vertical distance of the shadow from the text. Positive values move the shadow down, negative values up.
- **Range:** -20px to 20px
- **Default:** 0px

### Blur Radius
Controls how blurred the shadow appears. Higher values create more diffused shadows.
- **Range:** 0px to 20px
- **Default:** 0px (sharp shadow)

### Shadow Color
The color of the shadow. Supports all CSS color formats including hex, RGB, RGBA, HSL, and named colors.
- **Default:** #000000 (black)

## Block Support

To enable text shadow support in a block, add the following to your block's `supports` configuration:

```json
{
"supports": {
"typography": {
"__experimentalTextShadow": true
}
}
}
```

## Global Settings

Text shadow can be enabled/disabled globally via theme.json:

```json
{
"settings": {
"typography": {
"textShadow": true
}
}
}
```

## Styling

You can apply custom text shadow values via theme.json styles:

```json
{
"styles": {
"typography": {
"textShadow": "2px 2px 4px #000000"
},
"elements": {
"h1": {
"typography": {
"textShadow": "0px 0px 10px rgba(255, 255, 255, 0.8)"
}
}
}
}
}
```

## CSS Output

The control generates the following CSS:

```css
.wp-block-example {
text-shadow: 2px 2px 4px #000000;
}
```

## Examples

### Drop Shadow
```css
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
```

### Glow Effect
```css
text-shadow: 0px 0px 10px #00ff00;
```

### Multiple Shadows
```css
text-shadow: 1px 1px 2px #000, 0 0 10px #0ff;
```

### Embossed Effect
```css
text-shadow: 1px 1px 0px #fff, -1px -1px 0px #000;
```

## Accessibility

The TextShadowControl component includes proper ARIA labels and follows WordPress accessibility guidelines. The color picker is keyboard accessible and provides clear visual feedback for all interactive elements.

## Browser Support

Text shadow is supported in all modern browsers. For older browsers that don't support text-shadow, the text will simply appear without the shadow effect.
Loading
Loading