Add textShadow typography support and UI#79584
Conversation
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>
e0ef726 to
6dbb05d
Compare
`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>
There was a problem hiding this comment.
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, andtypography.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.textShadowblock support and wires up serialization viahas-{slug}-text-shadowclasses, 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. |
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>
|
Size Change: +4.33 kB (+0.06%) Total Size: 7.5 MB 📦 View Changed
|
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>
| "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)" | ||
| } | ||
| ], |
|
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 Unlinked AccountsThe 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. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
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>



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
textShadow,defaultTextShadowPresets, andtextShadowPresetsis being added undersettings.typography. These settings can be defined viatheme.json.var(--wp--preset--text-shadow--{slug}). Presets can be applied site-wide or at the block level.Blocks
supports.typography.textShadowblock support.textShadowsupport to the Paragraph and Heading blocks.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
{ "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:
Preset list:
Edit preset:
Block
This design is based on #47904 (comment).
If the total number of presets is 7 or more
Use of AI Tools
I initially had AI implement the code, and then I reviewed all of it myself.