Skip to content

Shadow: Add a PHP helper for block support classes and styles - #84205

Merged
aaronrobertshaw merged 12 commits into
trunkfrom
update/shadow-classes-and-styles-php-helper
Nov 4, 2026
Merged

aaronrobertshaw merged 12 commits into
trunkfrom
update/shadow-classes-and-styles-php-helper

Conversation

@aaronrobertshaw

@aaronrobertshaw aaronrobertshaw commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Follows up on #83122.
Core backport: wordpress-develop#14094.

Related:

What?

Adds a PHP helper that turns a block's shadow into inline styles, like the JS getShadowClassesAndStyles().

wp_get_shadow_classes_and_styles( $block_attributes );
// array( 'style' => 'box-shadow:var(--wp--preset--shadow--natural);' )

The shadow block support and six blocks now use it.

Why?

Blocks that skip shadow serialization apply the shadow to an inner element, so they build the styles by hand. Six do, each with its own style engine call. A shared helper gives them one place to change.

How?

The helper only builds output. It doesn't check what a block supports. Each caller decides where the output goes.

  • Shadow block support: keeps its checks, then calls the helper
  • Avatar, Post Featured Image: shadow on the image
  • Navigation Submenu: shadow on the dropdown, not the menu item
  • Search: shadow on the same elements as the border
  • Post Navigation Link: splits its style engine call around the helper, keeping the same order
  • Icon: same split as Post Navigation Link
  • Build: added to prefixFunctions, so the plugin calls gutenberg_get_shadow_classes_and_styles()

No output changes.

PHPStan's WordPress stubs are built from Core trunk, which won't have this helper until wordpress-develop#14094 lands. So this PR adds a temporary baseline entry for it. PHPStan will flag the entry for removal once the stubs move to a Core trunk with the helper.

Testing Instructions

  1. Add an Avatar, a Post Featured Image with an overlay, and a Post Navigation Link.
  2. Add a Navigation block with a submenu, a Search block and an Icon block.
  3. Give each a shadow. Give Avatar, Post Featured Image and Post Navigation Link a border too.
  4. Compare the front end markup with trunk. It should match.
  5. Open the submenu. The shadow is on the dropdown, not on the menu item.

Use of AI Tools

Implemented and tested by a Claude Code agent from a predefined task.

@aaronrobertshaw aaronrobertshaw added [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Type] Enhancement A suggestion for improvement. [Package] Block library /packages/block-library Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Oct 8, 2026
@aaronrobertshaw aaronrobertshaw self-assigned this Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

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

Co-authored-by: aaronrobertshaw <aaronrobertshaw@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>

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


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

📦 Bundle size

Size Change: 0 B

Total Size: 8.61 MB

1a3c0e7 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric 4bd13e8 trunk % Change
timeToFirstByte 43.65 ms +15.01% -6.07% 42.55 ms +4.82% -4.94% 2.59%
largestContentfulPaint 76 ms +5.26% -10.53% 68 ms +8.82% -0% 11.76%
lcpMinusTtfb 27.7 ms +24.73% -3.25% 27.5 ms +1.64% -3.64% 0.73%
wpBeforeTemplate 22.98 ms +19.58% -5.27% 21.87 ms +7.09% -3.02% 5.08%
wpTemplate 17.1 ms +9.18% -4.09% 16.66 ms +4.68% -4.62% 2.64%
wpTotal 40.38 ms +14.61% -5.92% 39.22 ms +5.07% -5.43% 2.96%
wpMemoryUsage 7.72 MB +0% -0% 7.68 MB +0% -0% 0.43%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric 4bd13e8 trunk % Change
timeToFirstByte 32.4 ms +8.8% -2.62% 34.7 ms +5.33% -2.02% -6.63%
largestContentfulPaint 72 ms +5.56% -2.78% 76 ms +5.26% -0% -5.26%
lcpMinusTtfb 38.65 ms +4.01% -4.53% 42.5 ms +2% -2% -9.06%
wpBeforeTemplate 19.55 ms +10.23% -2.92% 18.86 ms +5.04% -0.95% 3.66%
wpTemplate 10.21 ms +1.86% -2.35% 12.88 ms +3.49% -5.12% -20.73%
wpTotal 29.7 ms +9.29% -1.92% 31.99 ms +5.16% -1.69% -7.16%
wpMemoryUsage 6.30 MB +0% -0% 6.37 MB +0% -0% -1.21%
wpDbQueries 9 +0% -0% 13 +0% -0% -30.77%

media-processing

Metric 4bd13e8 trunk % Change
mediaProcessingJpeg 325.95 ms +1.08% -1.47% 320.72 ms +1.16% -0.66% 1.63%
mediaProcessingAvif 4874.14 ms +0.32% -0.56% 4816.44 ms +0.49% -0.05% 1.2%
mediaProcessingJpegToAvif 3381.44 ms +0.17% -0.28% 3373.93 ms +0.17% -0.15% 0.22%

media-upload

Metric 4bd13e8 trunk % Change
jpegUploadProcessing 1418.33 ms +1.78% -0.28% 1423.11 ms +0.49% -0.96% -0.34%
pngUploadProcessing 212.82 ms +3.16% -1.93% 201.89 ms +6.65% -1.06% 5.41%
largeJpegUploadProcessing 1407.43 ms +0.69% -0.63% 1413.35 ms +0.35% -0.37% -0.42%
multipleImageUploadProcessing 1489.15 ms +1.06% -0.76% 1477.59 ms +1.41% -1.22% 0.78%

post-editor

Metric 4bd13e8 trunk % Change
serverResponse 488.88 ms +2.33% -9.95% 472.31 ms +7.6% -4.88% 3.51%
firstPaint 458.91 ms +7.86% -9.91% 346.27 ms +43.67% -6.02% 32.53%
domContentLoaded 847.66 ms +3.77% -1.3% 890.66 ms +2.79% -1.06% -4.83%
loaded 848.86 ms +3.76% -1.29% 891.64 ms +2.78% -1.04% -4.8%
firstContentfulPaint 495.42 ms +4.94% -2.38% 514.58 ms +3.59% -0.85% -3.72%
firstBlock 2195.08 ms +3.23% -0.68% 2284.9 ms +1.23% -2.89% -3.93%
type 17.39 ms +6.61% -9.32% 20.2 ms +0.74% -4.41% -13.91%
typeWithoutInspector 17.22 ms +7.14% -7.9% 19.42 ms +1.6% -15.09% -11.33%
typeWithTopToolbar 22.5 ms +13.6% -2.62% 26.52 ms +5.47% -7.84% -15.16%
typeContainer 8.48 ms +16.39% -9.08% 9.53 ms +2.41% -9.02% -11.02%
focus 126.39 ms +5.4% -4.03% 122.23 ms +5.51% -5.49% 3.4%
firstFocus 264.09 ms +0% -0% 256.52 ms +0% -0% 2.95%
selectAll 415.28 ms +1.11% -1.97% 418.75 ms +0.08% -0.04% -0.83%
undo 30.76 ms +3.71% -6.96% 31.6 ms +8.32% -5.09% -2.66%
listViewOpen 79.51 ms +13.63% -4.25% 79.29 ms +15.59% -2.16% 0.28%
inserterOpen 43.15 ms +17.5% -8.83% 43.21 ms +2.92% -7.85% -0.14%
inserterHover 12.5 ms +4.32% -20.56% 12.32 ms +10.88% -15.83% 1.46%
inserterSearch 8.67 ms +5.88% -8.19% 8.52 ms +7.98% -5.99% 1.76%
loadPatterns 659.54 ms +6.04% -4.38% 663.44 ms +4% -2.42% -0.59%
wpTotal 478.68 ms +2.22% -10.11% 462.48 ms +7.53% -5% 3.5%
wpMemoryUsage 14.76 MB +0% -0% 14.73 MB +0% -0% 0.24%
wpDbQueries 55 +0% -0% 55 +0% -0% 0%

site-editor

Metric 4bd13e8 trunk % Change
serverResponse 255.81 ms +1.5% -8.29% 261.62 ms +1.39% -7.74% -2.22%
firstPaint 247.8 ms +30.77% -10.48% 251.76 ms +16.06% -2.32% -1.57%
domContentLoaded 561.01 ms +3.16% -1.45% 590.98 ms +2.93% -1.41% -5.07%
loaded 561.68 ms +3.15% -1.45% 591.83 ms +2.92% -1.42% -5.09%
firstContentfulPaint 330.29 ms +5.15% -1.83% 342.1 ms +4.42% -0.98% -3.45%
firstBlock 1660.98 ms +0.57% -0.55% 1740.75 ms +1.27% -2.49% -4.58%
type 13.34 ms +3.75% -9.22% 13.53 ms +6.13% -8.72% -1.4%
navigate 74.61 ms +5.2% -6.46% 76.07 ms +9.46% -11.95% -1.92%
loadPatterns 1059.65 ms +8.2% -11.58% 896.03 ms +13.79% -12.79% 18.26%
loadPages 927.79 ms +1.3% -1.18% 943.49 ms +0.84% -0.51% -1.66%
wpTotal 249.42 ms +1.54% -8.39% 255.29 ms +1.3% -8.06% -2.3%
wpMemoryUsage 12.78 MB +0% -0% 12.74 MB +0% -0% 0.27%
wpDbQueries 45 +0% -0% 45 +0% -0% 0%

1a3c0e7 Run

🏁 Flaky tests

Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

Undo restores the post selection when another synced entity is loaded (RTC WebSocket) in /test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 2
+ Received  + 2

  Object {
    "attributeKey": "content",
    "blockIndex": 0,
    "content": "abcdef",
-   "endOffset": 3,
-   "offset": 3,
+   "endOffset": 6,
+   "offset": 6,
  }

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts:363:5
Undo restores the post selection when another synced entity is loaded in /test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 2
+ Received  + 2

  Object {
    "attributeKey": "content",
    "blockIndex": 0,
    "content": "abcdef",
-   "endOffset": 3,
-   "offset": 3,
+   "endOffset": 4,
+   "offset": 4,
  }

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts:363:5
User Mention: should cancel mention selection via `Escape` keypress event in /test/e2e/specs/editor/various/autocomplete-and-mentions.spec.js, passed after 2 failed attempts.
Error: apiRequestContext.fetch: socket hang up
Call log:
  - → DELETE http://localhost:8891/wp-json/wp/v2/users/23?force=true&reassign=1
    - user-agent: Playwright/1.63.0 (x64; ubuntu 24.04) node/24.20 CI/1
    - accept: */*
    - accept-encoding: gzip,deflate,br
    - X-WP-Nonce: 33bfe1cf3b
    - cookie: wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_da433b7faafd8180ebeb1624ceeeab7e=admin%7C1793971969%7Chsc89YRbmzN3Z5CvYRIeph6eoB5taChYleCd7uxO6Ip%7Cfd2536eaa0601e32afae2b7c0dd5ed25ea83be86d131f043e6dc4e650d5139b4; wp-settings-time-1=1793799477; wp-settings-1=editor%3Dtinymce

    at RequestUtils.rest (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/rest.ts:111:39)
    at RequestUtils.deleteUser (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/users.ts:91:30)
    at map (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/users.ts:116:51)
    at RequestUtils.deleteAllUsers (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/users.ts:116:5)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/autocomplete-and-mentions.spec.js:73:3

inserts a block should show a blue line indicator in /test/e2e/specs/editor/various/inserting-blocks.spec.js, passed after 1 failed attempt.
Error: expect(locator).toBeVisible() failed

Locator: locator('data-testid=block-list-insertion-point-indicator')
Expected: visible
Timeout: 5000ms
Error: element(s) not found

Call log:
  - Expect "toBeVisible" locator('data-testid=block-list-insertion-point-indicator') with timeout 5000ms
  - waiting for locator('data-testid=block-list-insertion-point-indicator')

    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/inserting-blocks.spec.js:674:50
should place the caret at the click position when clicking a block that is not selected in /test/e2e/specs/editor/various/writing-flow.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 1
+ Received  + 1

@@ -1,9 +1,9 @@
  Array [
    Object {
      "attributes": Object {
-       "content": "First!",
+       "content": "First",
      },
      "name": "core/paragraph",
    },
    Object {
      "attributes": Object {

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/writing-flow.spec.js:952:41

1a3c0e7 Run

@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch 2 times, most recently from 49710a1 to 4135ece Compare October 8, 2026 05:56
@aaronrobertshaw aaronrobertshaw added [Type] Code Quality Issues or PRs that relate to code quality and removed [Type] Enhancement A suggestion for improvement. Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Oct 8, 2026
@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch 2 times, most recently from 48b5f24 to ee2145e Compare October 13, 2026 04:40
@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch 3 times, most recently from 4f78f3f to d1bd21f Compare October 20, 2026 05:19
@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch from 2babf82 to 9258290 Compare October 21, 2026 12:41
@aaronrobertshaw
aaronrobertshaw marked this pull request as ready for review October 21, 2026 13:16
@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch from 9258290 to eee8034 Compare October 27, 2026 07:49
@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch from eee8034 to e46f67b Compare October 30, 2026 09:10

@ramonjd ramonjd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for keeping these alive.

Tested manually on the (now) 4 blocks. All manifestations of the search block. Added borders and shadows to all (except submenu, which only takes borders).

Editor Frontend
Image Image

Comment thread lib/block-supports/shadow.php Resolved
@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch from 8da29c5 to 8a69942 Compare November 2, 2026 02:59
@aaronrobertshaw

Copy link
Copy Markdown
Contributor Author

Thanks for the reviews and testing 👍

I've pushed a few final tweaks:

  • Icon and Post Navigation Link are back to trunk's shadow handling, with their new tests kept.
  • The helper now returns early if the attributes aren't an array, the same as the colour, border and background helpers.
  • Moved to 7.3, both the @since tag and the backport changelog entry.
  • Rebased on trunk.

PHPStan landed on trunk this week and doesn't know about the new helpers yet, since it isn't in Core until WordPress/wordpress-develop#14094. So I've added a temporary baseline entry for it.

@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch from 573170b to 376f301 Compare November 4, 2026 03:53
Comment thread tools/phpstan/baseline.neon Resolved
aaronrobertshaw and others added 12 commits November 4, 2026 21:17
Search and Icon now get their shadow from the helper, like the other
blocks in this PR, with the same output as trunk. Each gets one render
test.

The tests now cover the helper's own cases and one migration per block.
Cases that re-tested the style engine are dropped.
Matches the colour, border and background helpers, and names the helper test like theirs.
The block library calls wp_get_shadow_classes_and_styles(), which the
build prefixes to gutenberg_get_shadow_classes_and_styles() for the
plugin, but which PHPStan resolves from the WordPress stubs. The stubs
were generated from core trunk, which lacks the function, so its calls
were baselined as not found.

Generate the stubs from wordpress-develop PR 14094, which backports the
helper, and drop the four baselined errors. Regenerate them from trunk
once the backport is committed.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: cfcf15e8-ccc1-4d78-a7c9-51f73e8e4b92
This reverts commit bc651f0, which was a2fa893 before the rebase.
@aaronrobertshaw
aaronrobertshaw force-pushed the update/shadow-classes-and-styles-php-helper branch from a2fa893 to 1a3c0e7 Compare November 4, 2026 13:25
@aaronrobertshaw
aaronrobertshaw merged commit edd9a40 into trunk Nov 4, 2026
91 of 94 checks passed
@aaronrobertshaw
aaronrobertshaw deleted the update/shadow-classes-and-styles-php-helper branch November 4, 2026 14:13
@github-actions github-actions Bot added this to the Gutenberg 24.5 milestone Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Package] Block library /packages/block-library [Type] Code Quality Issues or PRs that relate to code quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants