Skip to content

Add textShadow typography support and UI#79584

Open
t-hamano wants to merge 7 commits into
trunkfrom
text-shadow-support-ui
Open

Add textShadow typography support and UI#79584
t-hamano wants to merge 7 commits into
trunkfrom
text-shadow-support-ui

Conversation

@t-hamano

@t-hamano t-hamano commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Closes #47904

What?

This PR extends #73320 and adds full text-shadow support.

How?

The implementation largely follows Shadow UI, but the features realized in this PR are as follows:

Global Styles

  • New support for textShadow, defaultTextShadowPresets, and textShadowPresets is being added under settings.typography. These settings can be defined via theme.json.
  • Just like with shadows and font sizes, you can define custom presets in addition to the default ones. Each preset outputs a CSS variable in the format var(--wp--preset--text-shadow--{slug}). Presets can be applied site-wide or at the block level.
  • textShadow also supports elements.

Blocks

  • Adds the new supports.typography.textShadow block support.
  • Adds textShadow support to the Paragraph and Heading blocks.
  • The control is hidden by default.
  • Shadow styles are serialized and saved in a format like the following. The key difference from the shadow support is that styles are applied via CSS classes, not inline styles.
    <!-- wp:paragraph {"textShadow":"strong"} -->
    <p class="has-strong-text-shadow">Hello World</p>
    <!-- /wp:paragraph -->
  • Serialization skipping is also supported, though no blocks currently implement it.

Testing Instructions

Here are some representative settings for testing this feature.

Disable the feature completely

{
	"version": 3,
	"settings": {
		"appearanceTools": true,
		"layout": {
			"contentSize": "840px"
		},
		"typography": {
			"textShadow": false,
			"defaultTextShadowPresets": false,
			"textShadowPresets": []
		}
	}
}

Define custom presets

{
	"version": 3,
	"settings": {
		"appearanceTools": true,
		"layout": {
			"contentSize": "840px"
		},
		"typography": {
			"textShadowPresets": [
				{
					"name": "Soft",
					"slug": "soft",
					"textShadow": "1px 1px 2px rgba(0, 0, 0, 0.3)"
				},
				{
					"name": "Glow",
					"slug": "glow",
					"textShadow": "0 0 8px rgba(255, 215, 0, 0.8)"
				},
				{
					"name": "Retro",
					"slug": "retro",
					"textShadow": "3px 3px 0 rgba(255, 0, 128, 0.7)"
				}
			]
		}
	}
}

Define numerous custom presets

Define default style

  • This style should be overrideable via Global Styles > Blocks > Paragraph.
  • This style should be overrideable at the block instance level.
{
	"version": 3,
	"settings": {
		"appearanceTools": true,
		"layout": {
			"contentSize": "840px",
			"wideSize": "1100px"
		}
	},
	"styles": {
		"blocks": {
			"core/paragraph": {
				"typography": {
					"textShadow": "2px 2px 0 #ff0080, 4px 4px 0 #00d9ff"
				}
			}
		}
	}
}

Screenshots or screencast

Global Styles

There is a navigation button below the font size presets:

image

Preset list:

image

Edit preset:

image

Block

This design is based on #47904 (comment).

image

If the total number of presets is 7 or more

image

Use of AI Tools

I initially had AI implement the code, and then I reviewed all of it myself.

@github-actions github-actions Bot added [Package] Blocks /packages/blocks [Package] Block library /packages/block-library [Package] Block editor /packages/block-editor [Package] Style Engine /packages/style-engine labels Jun 26, 2026
Introduce a `typography.textShadow` block support backed by text shadow
presets, end to end:

- Register the `textShadow` typography support key and gate it per block;
  enable it on the paragraph and heading blocks.
- Add `settings.typography.textShadow` and `textShadowPresets` to
  theme.json (defaults, schema, PHP/JS registration) and reuse the
  box-shadow parser for text shadow values.
- Add the Global Styles preset management UI (preview, list, create,
  rename, delete, reset) under Typography, plus a text shadow control in
  the typography panel for both the block inspector and Global Styles.

Presets follow the same model as the other typography preset supports
(font size, font family) rather than the box-shadow inline model: the
chosen preset slug is stored in a dedicated top-level `textShadow`
attribute and emitted as a `has-{slug}-text-shadow` utility class, so
preset selection stays out of the inline style and the generated preset
stylesheet drives the value. Custom (non-preset) values still serialize
inline on `style.typography.textShadow`.

Co-Authored-By: Claude <noreply@anthropic.com>
@t-hamano t-hamano force-pushed the text-shadow-support-ui branch from e0ef726 to 6dbb05d Compare June 26, 2026 11:40
@t-hamano t-hamano requested a review from Copilot June 26, 2026 11:41
@t-hamano t-hamano added [Type] Enhancement A suggestion for improvement. [Feature] Block API API that allows to express the block paradigm. labels Jun 26, 2026
@github-project-automation github-project-automation Bot moved this to 🔎 Needs Review in WordPress 7.1 Editor Tasks Jun 26, 2026
`textShadow` was added to the global supported style list without an
element exclusion, so it is now reported for every element and the
global default. Update the expected lists in the getSupportedStyles
tests to include `textShadow`.

Co-Authored-By: Claude <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds end-to-end text-shadow typography support across theme.json settings, preset infrastructure, Global Styles UI, and block supports so themes/users can define, manage, and apply text shadow presets (including per-block preset application via classes).

Changes:

  • Extends theme.json settings/schema and preset metadata to support typography.textShadow, typography.textShadowPresets, and typography.defaultTextShadowPresets.
  • Adds Global Styles UI screens to browse/create/edit text shadow presets and exposes the entry point in the Typography screen when enabled.
  • Adds a new supports.typography.textShadow block support and wires up serialization via has-{slug}-text-shadow classes, enabling it for core Paragraph and Heading.

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tools/eslint/suppressions.json Removes an ESLint suppression no longer needed after Typography screen changes.
schemas/json/theme.json Adds settings.typography.textShadow* schema for enabling the control and defining presets.
schemas/json/block.json Adds supports.typography.textShadow to the block.json schema.
packages/style-engine/src/class-wp-style-engine.php Adds style-engine support to map preset textShadow to CSS vars and classes.
packages/global-styles-ui/src/text-shadows.tsx Adds Typography screen entry UI for navigating to text shadow presets.
packages/global-styles-ui/src/style.scss Adds/extends styles for text shadow preset UI and editor components.
packages/global-styles-ui/src/stories/index.story.jsx Adds text shadow settings/presets to Storybook base settings.
packages/global-styles-ui/src/shadow-utils.ts Adds text-shadow parsing/serialization helpers (reusing box-shadow parsing).
packages/global-styles-ui/src/screen-typography.tsx Conditionally shows Text Shadows entry based on useHasTextShadowControl.
packages/global-styles-ui/src/screen-text-shadows.tsx Adds preset list screen (Default/Theme/Custom) and reset flow.
packages/global-styles-ui/src/screen-text-shadows-edit.tsx Adds preset editor screen (preview + multi-shadow part editor).
packages/global-styles-ui/src/global-styles-ui.tsx Registers navigation routes for text shadow screens.
packages/global-styles-engine/src/utils/common.ts Registers text shadow preset metadata and CSS var infix mapping.
packages/global-styles-engine/src/types.ts Introduces TextShadowPreset and extends typography settings types.
packages/global-styles-engine/src/settings/get-setting.ts Allows retrieving new typography settings keys (textShadow*).
packages/blocks/src/store/private-selectors.ts Adds textShadow to supported-root typography supports list.
packages/blocks/src/api/constants.ts Adds textShadow to experimental style property mapping.
packages/block-library/src/paragraph/README.md Documents Paragraph supports now including typography.textShadow.
packages/block-library/src/paragraph/block.json Enables supports.typography.textShadow for Paragraph.
packages/block-library/src/heading/README.md Documents Heading supports now including typography.textShadow.
packages/block-library/src/heading/block.json Enables supports.typography.textShadow for Heading.
packages/block-editor/src/hooks/utils.js Plumbs textShadow + preset settings into computed block settings.
packages/block-editor/src/hooks/typography.js Adds attribute/style mapping for textShadow (preset slug vs literal).
packages/block-editor/src/hooks/text-shadow.js Implements block support: attribute registration + save-time class serialization.
packages/block-editor/src/hooks/index.js Registers the new text-shadow hook in edit/save filters.
packages/block-editor/src/components/global-styles/typography-panel.js Adds Text Shadow ToolsPanel item to the typography panel.
packages/block-editor/src/components/global-styles/text-shadow-panel.js Adds preset picker popover UI for text shadow selection/clearing.
packages/block-editor/src/components/global-styles/style.scss Styles the Text Shadow picker UI and preview.
packages/block-editor/src/components/global-styles/index.js Exports useHasTextShadowControl from global styles components.
packages/block-editor/src/components/global-styles/hooks.js Ensures textShadow settings are disabled when unsupported.
lib/theme.json Adds default text shadow settings and presets to the bundled theme.json.
lib/class-wp-theme-json-gutenberg.php Adds presets metadata and valid settings for text shadows in PHP theme.json handling.
lib/block-supports/typography.php Adds server-side typography support for text shadow (preset or custom style value).
docs/reference-guides/theme-json-reference/theme-json-living.md Documents new typography settings keys for text shadow.
docs/reference-guides/core-blocks/README.md Updates Heading/Paragraph support lists to include textShadow.
docs/reference-guides/block-api/block-supports.md Documents new typography.textShadow block support.
docs/how-to-guides/themes/global-settings-and-styles.md Documents typography.textShadowPresets as a preset-generating setting.

Comment thread packages/global-styles-engine/src/types.ts
Comment thread schemas/json/block.json
Comment thread docs/reference-guides/block-api/block-supports.md
t-hamano and others added 3 commits June 26, 2026 20:50
Record gutenberg PR #79584 against the wordpress-develop #12011 backport
so the text shadow support changes are tracked for Core backporting.

Co-Authored-By: Claude <noreply@anthropic.com>
Cover the server-side path that turns a `textShadow` preset attribute into
a `has-{slug}-text-shadow` class, mirroring the existing font family
classname test, so the class-based serialization stays protected.

Co-Authored-By: Claude <noreply@anthropic.com>
The `TypographySettings` type gained `textShadowPresets` and
`defaultTextShadowPresets` but not the `textShadow` boolean that gates the
control and exists in the theme.json schema and PHP valid settings, so the
type was internally inconsistent for the feature. Add it.

(The type predates this PR and is still missing several unrelated
typography settings; completing it is left to a separate cleanup.)

Co-Authored-By: Claude <noreply@anthropic.com>
@t-hamano t-hamano changed the title Block Supports: Add textShadow typography support and UI Add textShadow typography support and UI Jun 26, 2026
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown

Size Change: +4.33 kB (+0.06%)

Total Size: 7.5 MB

📦 View Changed
Filename Size Change
build/modules/lazy-editor/index.min.js 14.4 kB +41 B (+0.28%)
build/scripts/block-editor/index.min.js 384 kB +1.17 kB (+0.3%)
build/scripts/block-library/index.min.js 324 kB +14 B (0%)
build/scripts/blocks/index.min.js 44.8 kB +17 B (+0.04%)
build/scripts/edit-site/index.min.js 298 kB +127 B (+0.04%)
build/scripts/editor/index.min.js 477 kB +1.51 kB (+0.32%)
build/styles/block-editor/style-rtl.css 18.8 kB +172 B (+0.92%)
build/styles/block-editor/style-rtl.min.css 16.2 kB +164 B (+1.02%)
build/styles/block-editor/style.css 18.9 kB +184 B (+0.98%)
build/styles/block-editor/style.min.css 16.2 kB +164 B (+1.02%)
build/styles/edit-site/style-rtl.css 21.6 kB +117 B (+0.54%)
build/styles/edit-site/style-rtl.min.css 17.8 kB +83 B (+0.47%)
build/styles/edit-site/style.css 21.6 kB +116 B (+0.54%)
build/styles/edit-site/style.min.css 17.8 kB +81 B (+0.46%)
build/styles/editor/style-rtl.css 30.9 kB +98 B (+0.32%)
build/styles/editor/style-rtl.min.css 26.3 kB +90 B (+0.34%)
build/styles/editor/style.css 30.9 kB +97 B (+0.31%)
build/styles/editor/style.min.css 26.3 kB +88 B (+0.34%)

compressed-size-action

Register `typography.textShadowPresets[].name` in the theme i18n schema
(top level and per-block) so theme-defined text shadow preset names are
translatable, matching font sizes, font families, and shadow presets.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread lib/theme.json
Comment on lines +316 to +332
"textShadowPresets": [
{
"name": "Light",
"slug": "light",
"textShadow": "1px 1px 2px rgba(0, 0, 0, 0.3)"
},
{
"name": "Strong",
"slug": "strong",
"textShadow": "2px 2px 5px rgba(0, 0, 0, 0.5)"
},
{
"name": "Outlined",
"slug": "outlined",
"textShadow": "3px 3px 0px rgba(0, 0, 0, 0.3)"
}
],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WordPress/gutenberg-design, I welcome your ideas on what the default preset should be.

Preset name Preview
Light Image
Strong Image
Outlined Image

@t-hamano t-hamano marked this pull request as ready for review June 26, 2026 12:18
@t-hamano t-hamano requested a review from juanmaguitar as a code owner June 26, 2026 12:18
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @HatlerRyan, @UltimateByte, @jnweaver, @burnuser.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: HatlerRyan, UltimateByte, jnweaver, burnuser.

Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: annezazu <annezazu@git.wordpress.org>
Co-authored-by: ryanwelcher <welcher@git.wordpress.org>
Co-authored-by: hanneslsm <hanneslsm@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: karmatosed <karmatosed@git.wordpress.org>
Co-authored-by: USERSATOSHI <tusharbharti@git.wordpress.org>
Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
Co-authored-by: aaronrobertshaw <aaronrobertshaw@git.wordpress.org>
Co-authored-by: kedarjoyner <kjoyner@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@t-hamano t-hamano added the Needs Dev Note Requires a developer note for a major WordPress release cycle label Jun 26, 2026
When seven or more presets render the picker as a SelectControl, an unset
value showed the first preset as selected because no empty option existed.
Prepend a "Default" option so an unset text shadow is represented and
selecting it clears the value.

Co-Authored-By: Claude <noreply@anthropic.com>
@t-hamano t-hamano self-assigned this Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Block API API that allows to express the block paradigm. Needs Dev Note Requires a developer note for a major WordPress release cycle [Package] Block editor /packages/block-editor [Package] Block library /packages/block-library [Package] Blocks /packages/blocks [Package] Style Engine /packages/style-engine [Type] Enhancement A suggestion for improvement.

Projects

Status: 🔎 Needs Review

Development

Successfully merging this pull request may close these issues.

Typography: Add "Text shadow" support

2 participants