Skip to content

ColorPicker: Don't drop hex/RGB edits when the picker closes - #85734

Merged
Mamaduka merged 1 commit into
trunkfrom
fix/color-picker-lost-hex-edit
Oct 27, 2026
Merged

Mamaduka merged 1 commit into
trunkfrom
fix/color-picker-lost-hex-edit

Conversation

@Mamaduka

Copy link
Copy Markdown
Member

What?

ColorPicker now calls onChange right away for hex and RGB input instead of through a debounce. Before, typing a hex value in a gradient control point and pressing Escape right after could keep the old color, which made the "can apply custom gradient background color" e2e test flaky.

Why?

Hex and RGB edits were committed through useDebounce( setColor ) with a 0ms wait, and useDebounce cancels pending calls on unmount, so closing the popover dropped the edit. The debounce came from #36941 to stop a loop while dragging the picker in the gradient control point. Since #75493, picker drag goes through handleHSLAChange and calls setColor directly, and for discrete input events a 0ms debounce merged nothing.

Testing Instructions

  1. Open a post or page.
  2. Insert a Buttons block and type some text.
  3. In the block settings, open Background and select the Gradient tab.
  4. Click the 0% gradient control point, type ff0000 in the Hex field and press Escape. The control point and button background turn red.
  5. Reopen the control point, drag the color surface and hue bar, then switch to RGB and drag the sliders. The color follows the drag with no console errors.

buttons.spec.js now checks the control point's accessible name after each edit. Before the fix, trunk's version of the test failed 10 of 10 runs locally with --trace off; after it, 10 of 10 pass.

Testing Instructions for Keyboard

Same as above, using Tab to reach the control point and Enter to open it.

Use of AI Tools

Assisted by Claude.

@Mamaduka Mamaduka self-assigned this Oct 27, 2026
@Mamaduka
Mamaduka requested a review from a team as a code owner October 27, 2026 09:03
@Mamaduka Mamaduka added the [Type] Bug An existing feature does not function as intended label Oct 27, 2026
@github-actions github-actions Bot added the [Package] Components /packages/components label Oct 27, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

Preview in WordPress Playground

🎉 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: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: ciampo <mciampini@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: -13 B (0%)

Total Size: 8.55 MB

📦 View Changed
Filename Size Change
build/scripts/components/index.min.js 329 kB -13 B (0%)

a433cf2 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric d7cf26e trunk % Change
timeToFirstByte 54.35 ms +18.03% -2.39% 53.45 ms +10.2% -2.43% 1.68%
largestContentfulPaint 96 ms +4.17% -8.33% 94 ms +8.51% -8.51% 2.13%
lcpMinusTtfb 37.95 ms +13.31% -8.7% 37.05 ms +13.77% -9.18% 2.43%
wpBeforeTemplate 28.79 ms +17.85% -1.01% 28.85 ms +13.86% -1.59% -0.21%
wpTemplate 21.09 ms +6.78% -3.75% 20.94 ms +8.21% -4.01% 0.72%
wpTotal 50.64 ms +16.71% -2.63% 49.76 ms +10.95% -3.07% 1.77%
wpMemoryUsage 7.70 MB +0% -0% 7.67 MB +0% -0% 0.43%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric d7cf26e trunk % Change
timeToFirstByte 41.55 ms +7.46% -0.96% 46.3 ms +4% -1.73% -10.26%
largestContentfulPaint 92 ms +0% -4.35% 100 ms +4% -0% -8%
lcpMinusTtfb 47.55 ms +5.47% -0.84% 54.5 ms +2.02% -0.92% -12.75%
wpBeforeTemplate 27 ms +2.59% -2.33% 26.8 ms +3.51% -1.01% 0.75%
wpTemplate 12.01 ms +2.58% -2% 16.21 ms +1.91% -1.23% -25.91%
wpTotal 38.87 ms +7.72% -0.8% 43.1 ms +4.48% -1.53% -9.81%
wpMemoryUsage 6.28 MB +0% -0% 6.36 MB +0% -0% -1.22%
wpDbQueries 9 +0% -0% 13 +0% -0% -30.77%

media-processing

Metric d7cf26e trunk % Change
mediaProcessingJpeg 403.87 ms +1.3% -0.49% 398.01 ms +1.03% -0.14% 1.47%
mediaProcessingAvif 6073.31 ms +0.32% -0.18% 6058.34 ms +0.25% -0.11% 0.25%
mediaProcessingJpegToAvif 4193.92 ms +0.07% -0.25% 4203.48 ms +0.08% -0.37% -0.23%

media-upload

Metric d7cf26e trunk % Change
jpegUploadProcessing 1433.32 ms +3.01% -0.58% 1429.4 ms +0.87% -0.79% 0.27%
pngUploadProcessing 230.94 ms +7.64% -18.85% 220.26 ms +10.98% -15.7% 4.85%
largeJpegUploadProcessing 1430.91 ms +0.24% -0.38% 1419.63 ms +1.9% -0.79% 0.79%
multipleImageUploadProcessing 1520.5 ms +1.24% -0.9% 1507.68 ms +0.99% -1.4% 0.85%

post-editor

Metric d7cf26e trunk % Change
serverResponse 515.67 ms +3.01% -3.94% 540.37 ms +4.38% -3.58% -4.57%
firstPaint 546.01 ms +1.43% -7.94% 420.04 ms +26.4% -28.36% 29.99%
domContentLoaded 940.67 ms +2.29% -1.14% 916.4 ms +2.41% -3.39% 2.65%
loaded 941.95 ms +2.29% -1.15% 917.61 ms +2.41% -3.37% 2.65%
firstContentfulPaint 546.01 ms +1.43% -2.56% 527.92 ms +5.44% -7.3% 3.43%
firstBlock 3222.55 ms +1.12% -0.88% 3174.75 ms +1.19% -0.54% 1.51%
type 19.65 ms +6.82% -5.5% 20.02 ms +3.6% -6.74% -1.85%
typeWithoutInspector 20.29 ms +7.54% -4.48% 19.45 ms +5.86% -4.16% 4.32%
typeWithTopToolbar 27.31 ms +2.53% -8.06% 24.94 ms +6.13% -2.17% 9.5%
typeContainer 9.11 ms +4.61% -12.62% 8.22 ms +13.5% -10.71% 10.83%
focus 132.06 ms +4.16% -5.76% 127.84 ms +12.59% -2.38% 3.3%
firstFocus 263.76 ms +0% -0% 247.65 ms +0% -0% 6.51%
selectAll 543.6 ms +4.31% -1.86% 517.48 ms +1.33% -1.17% 5.05%
listViewOpen 88.66 ms +10.64% -9.71% 83.84 ms +10.58% -3.71% 5.75%
inserterOpen 45.77 ms +11.08% -2.23% 45.42 ms +19.66% -13.87% 0.77%
inserterHover 12.9 ms +7.83% -8.76% 12.91 ms +10.61% -10.61% -0.08%
inserterSearch 9.16 ms +5.9% -5.68% 9.12 ms +6.58% -3.51% 0.44%
loadPatterns 688.17 ms +11.29% -1.43% 692.52 ms +6.28% -1.25% -0.63%
wpTotal 505.57 ms +3.03% -4% 530.2 ms +4.45% -3.62% -4.65%
wpMemoryUsage 14.75 MB +0% -0% 14.71 MB +0% -0% 0.24%
wpDbQueries 55 +0% -1.82% 55 +0% -1.82% 0%

site-editor

Metric d7cf26e trunk % Change
serverResponse 293.84 ms +8.25% -6.47% 322.87 ms +1.04% -9.67% -8.99%
firstPaint 215.49 ms +7.71% -4.19% 221.23 ms +22.93% -4.21% -2.59%
domContentLoaded 683.26 ms +1.94% -0.75% 707.1 ms +2.59% -1.61% -3.37%
loaded 684.04 ms +1.98% -0.71% 707.97 ms +2.58% -1.62% -3.38%
firstContentfulPaint 392.77 ms +3.91% -0.3% 396.63 ms +2.99% -15.31% -0.97%
firstBlock 3130.43 ms +0.88% -0.65% 3194.58 ms +0.76% -0.9% -2.01%
type 15.36 ms +5.01% -5.79% 15.62 ms +3.01% -3.52% -1.66%
navigate 90.57 ms +13.66% -2.4% 95.5 ms +8.21% -5.74% -5.16%
loadPatterns 953.52 ms +20.31% -9.36% 1037.06 ms +8.98% -11.84% -8.06%
loadPages 1022.3 ms +1.72% -3.12% 1016.36 ms +4.24% -1.34% 0.58%
wpTotal 285.79 ms +8.46% -6.53% 314.75 ms +1.02% -9.95% -9.2%
wpMemoryUsage 12.77 MB +0% -0% 12.73 MB +0% -0% 0.24%
wpDbQueries 44 +2.27% -0% 44 +2.27% -0% 0%

a433cf2 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.

As a user I want to be able to add multiple close buttons so that users can close the overlay from different positions in /test/e2e/specs/site-editor/navigation-overlay-template-part.spec.js, passed after 1 failed attempt.
Error: expect(locator).toHaveCount(expected) failed

Locator:  getByRole('button', { name: 'Close' })
Expected: 2
Received: 1
Timeout:  5000ms

Call log:
  - Expect "toHaveCount" getByRole('button', { name: 'Close' }) with timeout 5000ms
  - waiting for getByRole('button', { name: 'Close' })
    14 × locator resolved to 1 element
       - unexpected value "1"

    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/site-editor/navigation-overlay-template-part.spec.js:228:33
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": 2,
+   "offset": 2,
  }

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
should change the indented list type in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
TimeoutError: locator.click: Timeout 10000ms exceeded.
Call log:
  - waiting for locator('role=toolbar[name="Block tools"i]').locator('role=button[name="Indent"]')

    at Editor.clickBlockToolbarButton (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/editor/click-block-toolbar-button.ts:17:15)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:727:3
should cut and paste individual blocks with collapsed selection in /test/e2e/specs/editor/various/copy-cut-paste.spec.js, passed after 1 failed attempt.
Error: expect(string).toMatchSnapshot(expected) failed

  @@ -1,3 +1,3 @@
   <!-- wp:paragraph -->
  -<p>2Cut - collapsed selection</p>
  +<p>2</p>
   <!-- /wp:paragraph -->


    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/copy-cut-paste.spec.js:45:49
should format text across blocks in /test/e2e/specs/editor/various/multi-block-selection.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": "ab",
+       "content": "b",
      },
      "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/multi-block-selection.spec.js:2219:41
should leave nested list intact when deleting the parent item in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  -  1
+ Received  + 19

@@ -1,19 +1,36 @@
  Array [
    Object {
+     "attributes": Object {
+       "content": "1",
+       "dropCap": false,
+     },
+     "innerBlocks": Array [],
+     "name": "core/paragraph",
+   },
+   Object {
+     "attributes": Object {
+       "ordered": false,
+       "values": "",
+     },
      "innerBlocks": Array [
        Object {
          "attributes": Object {
-           "content": "1",
+           "content": "",
          },
          "innerBlocks": Array [
            Object {
+             "attributes": Object {
+               "ordered": false,
+               "values": "",
+             },
              "innerBlocks": Array [
                Object {
                  "attributes": Object {
                    "content": "a",
                  },
+                 "innerBlocks": Array [],
                  "name": "core/list-item",
                },
              ],
              "name": "core/list",
            },
@@ -22,10 +39,11 @@
        },
        Object {
          "attributes": Object {
            "content": "3",
          },
+         "innerBlocks": Array [],
          "name": "core/list-item",
        },
      ],
      "name": "core/list",
    },
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:3017:38
should merge a following sibling list into the outermost list with Delete from a nested item (#77245) in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 2
+ Received  + 2

@@ -8,11 +8,11 @@
          "innerBlocks": Array [
            Object {
              "innerBlocks": Array [
                Object {
                  "attributes": Object {
-                   "content": "b‸",
+                   "content": "b",
                  },
                  "name": "core/list-item",
                },
              ],
              "name": "core/list",
@@ -25,11 +25,11 @@
    },
    Object {
      "innerBlocks": Array [
        Object {
          "attributes": Object {
-           "content": "1",
+           "content": "‸1",
          },
          "innerBlocks": Array [
            Object {
              "innerBlocks": Array [
                Object {

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:2854:41
should replace selected non-breaking spaces from the toolbar in /test/e2e/specs/editor/various/rich-text.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 1
+ Received  + 1

  Array [
    Object {
      "attributes": Object {
-       "content": "one two three",
+       "content": "ne two three",
      },
      "name": "core/paragraph",
    },
  ]

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/rich-text.spec.js:1050:41
should select by dragging into nested block in /test/e2e/specs/editor/various/multi-block-selection.spec.js, passed after 1 failed attempt.
Error: expect(received).toEqual(expected) // deep equality

- Expected  - 2
+ Received  + 1

  Array [
-   1,
-   2,
+   3,
  ]

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/multi-block-selection.spec.js:568:5
should split indented list item in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 1
+ Received  + 1

@@ -1,8 +1,8 @@
  <!-- wp:list -->
  <ul class="wp-block-list"><!-- wp:list-item -->
- <li>one<!-- wp:list -->
+ <li>ne<!-- wp:list -->
  <ul class="wp-block-list"><!-- wp:list-item -->
  <li>two</li>
  <!-- /wp:list-item -->

  <!-- wp:list-item -->

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:668:52
should update the URL from the last navigation if only varies in the URL fragment in /test/e2e/specs/interactivity/router-navigate.spec.ts, passed after 1 failed attempt.
Error: expect(locator).toHaveText(expected) failed

Locator:  getByTestId('title')
Expected: "Link 1"
Received: "Main"
Timeout:  5000ms

Call log:
  - Expect "toHaveText" getByTestId('title') with timeout 5000ms
  - waiting for getByTestId('title')
    14 × locator resolved to <h2 data-testid="title">Main</h2>
       - unexpected value "Main"

    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/interactivity/router-navigate.spec.ts:160:25

a433cf2 Run

@Mamaduka
Mamaduka force-pushed the fix/color-picker-lost-hex-edit branch from f4f44df to a433cf2 Compare October 27, 2026 09:04

@ciampo ciampo 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.

LGTM 🚀

@Mamaduka
Mamaduka merged commit 9bbf97c into trunk Oct 27, 2026
85 checks passed
@Mamaduka
Mamaduka deleted the fix/color-picker-lost-hex-edit branch October 27, 2026 10:43
@github-actions github-actions Bot added this to the Gutenberg 24.4 milestone Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Components /packages/components [Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants