Skip to content

Block Editor: Integrate slug-based color selection in color panel#78048

Open
USERSATOSHI wants to merge 8 commits into
WordPress:trunkfrom
USERSATOSHI:try/fix-duplicate-colors-block-editor
Open

Block Editor: Integrate slug-based color selection in color panel#78048
USERSATOSHI wants to merge 8 commits into
WordPress:trunkfrom
USERSATOSHI:try/fix-duplicate-colors-block-editor

Conversation

@USERSATOSHI
Copy link
Copy Markdown
Contributor

What?

Closes #9357

Follow up PR for #78004

Integrate slug-based color selection from the ColorPalette component into the Global Styles color panel. This is a follow-up PR to the components package fix that enables proper handling of palette entries with identical color values.

The original PR was splitted into 2 PRs based on the review provided.

Why?

The ColorPalette component now supports slug-based selection (see PR #78004) to correctly distinguish palette entries that share the same color value. This PR completes the integration by connecting that improvement to the WordPress editor's global styles system, enabling:

  • End-to-end slug tracking from theme settings → block attribute → ColorPalette → back to theme.json
  • Correct slug persistence instead of ambiguous color-value lookups
  • Proper selection of duplicate colors without UI glitches or React warnings

How?

  • Added extractColorSlug() helper to parse slug from CSS variable format (var:preset|color|slug)
  • Updated encodeColorValue() to accept optional slug parameter and return the CSS variable directly when provided
  • Extended all color setter functions to accept and propagate the slug parameter
  • Threaded inheritedSlug through ColorPanelTab → ColorGradientControl → ColorPalette
  • Updated all color indicator sections (text, background, link, elements) to extract and pass slugs

Testing Instructions

  1. Create a test theme with duplicate palette colors (e.g., two entries both set to #000000 with different semantic names)
  2. Open a post/page in the WordPress editor and open global styles
  3. Switch between text, background, and link color selections
  4. Verify each duplicate color can be selected independently
  5. Inspect theme.json to confirm the correct slug is saved (not a raw color value)
  6. Verify no React console warnings about duplicate keys

Dependencies

This PR builds on #78004 (ColorPalette component changes). The components package establishes the slug-based selection mechanism; this PR integrates it end-to-end into the block editor's global styles workflow.

@github-actions github-actions Bot added [Package] Components /packages/components [Package] Block editor /packages/block-editor labels May 7, 2026
@USERSATOSHI USERSATOSHI closed this May 7, 2026
@USERSATOSHI USERSATOSHI force-pushed the try/fix-duplicate-colors-block-editor branch from 135da60 to 7134bc2 Compare May 7, 2026 06:48
@USERSATOSHI USERSATOSHI reopened this May 7, 2026
@github-actions github-actions Bot removed the [Package] Components /packages/components label May 7, 2026
@USERSATOSHI USERSATOSHI marked this pull request as ready for review May 7, 2026 07:53
@USERSATOSHI USERSATOSHI requested a review from ellatrix as a code owner May 7, 2026 07:53
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

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: @DesignerThan95, @metasaman, @timelsass.

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: DesignerThan95, metasaman, timelsass.

Co-authored-by: USERSATOSHI <tusharbharti@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: designsimply <designsimply@git.wordpress.org>
Co-authored-by: JiveDig <jivedig@git.wordpress.org>
Co-authored-by: timnicholson <timnicholson@git.wordpress.org>
Co-authored-by: nathanrodrigues2111 <nathanrbsf@git.wordpress.org>
Co-authored-by: acketon <acketon@git.wordpress.org>
Co-authored-by: SirLouen <sirlouen@git.wordpress.org>
Co-authored-by: ritoban23 <devrito@git.wordpress.org>
Co-authored-by: catthetech <catthetech@git.wordpress.org>

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

@ciampo
Copy link
Copy Markdown
Contributor

ciampo commented May 11, 2026

With #78004 merged, I will review this PR once it gets rebased to include the ColorPalette fix

@ciampo
Copy link
Copy Markdown
Contributor

ciampo commented May 11, 2026

cc @timelsass in case you want to confirm the fix, since you opened the original issue

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Integrates slug-based color selection into the Global Styles ColorPanel so preset colors with identical color values can be selected and persisted unambiguously (building on the ColorPalette slug-selection work).

Changes:

  • Thread preset color slugs through Global Styles color panel controls and setters (encode by slug when available).
  • Update ColorGradientControl to pass selectedSlug to ColorPalette and propagate the selected slug through onColorChange.
  • Add a Block Editor changelog entry documenting the duplicate-palette bug fix.

Reviewed changes

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

File Description
packages/block-editor/src/components/global-styles/color-panel.js Extracts/passes color slugs through Global Styles color tabs and encodes preset colors by slug.
packages/block-editor/src/components/colors-gradients/control.js Forwards selectedSlug to ColorPalette and propagates slugs in onColorChange.
packages/block-editor/CHANGELOG.md Notes the Global Styles duplicate-palette slug-selection fix under Unreleased bug fixes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/block-editor/src/components/global-styles/color-panel.js Outdated
Comment thread packages/block-editor/src/components/global-styles/color-panel.js
Comment on lines +63 to 76
const colorPaletteOnChange = canChooseAGradient
? ( newColor, _index, newSlug ) => {
onColorChange( newColor, newSlug );
onGradientChange();
}
: ( newColor, _index, newSlug ) => onColorChange( newColor, newSlug );

const tabPanels = {
[ TAB_IDS.color ]: (
<ColorPalette
value={ colorValue }
onChange={
canChooseAGradient
? ( newColor ) => {
onColorChange( newColor );
onGradientChange();
}
: onColorChange
}
selectedSlug={ colorSlug }
onChange={ colorPaletteOnChange }
{ ...{ colors, disableCustomColors } }
Copy link
Copy Markdown
Contributor

@ciampo ciampo left a comment

Choose a reason for hiding this comment

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

Mostly looking good! Left a few smaller comments.

Will do a final round of review + smoke tests once those are addressed 🙏

Comment on lines +196 to +200
onColorChange={
isGradient
? undefined
: ( newColor, newSlug ) => setValue( newColor, newSlug )
}
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.

Could this be simplified to onColorChange={ isGradient ? undefined : setValue } to avoid re-creating a new function every re-render?

Comment on lines +354 to +365
const extractColorSlug = ( rawValue ) => {
if ( typeof rawValue !== 'string' ) {
return undefined;
}
if ( rawValue.startsWith( 'var:preset|color|' ) ) {
return rawValue.slice( 'var:preset|color|'.length );
}
const themeFormatMatch = rawValue.match(
/^var\(--wp--preset--color--([^)]+)\)$/
);
return themeFormatMatch?.[ 1 ];
};
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.

Could we move this function outside of the component render, and hoist it alongside DEFAULT_CONTROLS and popoverProps ? It would avoid re-creating it on every re-render.

Potentially even better, we could move it to a shared util. I can see some partial overlap in packages/block-editor/src/hooks/color.js. Very optional for this PR, but we could de-deuplicate the logic and update hooks/color.js to also accept the theme format (I think the logic from this PR is more correct)

Comment on lines +491 to +500
// Compare raw encoded references, not decoded color values: two palette
// entries can share the same hex value but carry different slugs
// (e.g. var:preset|color|dark-text vs var:preset|color|dark-background).
// Comparing decoded values would incorrectly conflate them, forcing the
// link preset to follow the text preset even though the user chose
// independent palette slots.
if (
inheritedValue?.color?.text ===
inheritedValue?.elements?.link?.color?.text
) {
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.

Just highlight a small semantic change between the new check and the old textColor === linkColor that was flagged during a round of AI-assisted review.

Previously, text and link would sync when their resolved colors matched; now they sync only when their raw stored references are identical strings. Edge case: if text was stored as var:preset|color|primary and link as the resolved #0000ff, the old behavior would sync them; the new behavior won't. In practice this is unlikely, and the new behaviour is more correct for the duplicate slug problem, but we may want to call it out in the PR description (and potentially CHANGELOG?)

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.

Maybe we could add some tests to check the new behaviour? Something like a small smoke test asserting that setTextColor('#000', 'dark-text') writes var:preset|color|dark-text (not a value lookup result), and maybe that the text↔link sync no longer triggers when raw refs differ even if decoded values match?

@USERSATOSHI
Copy link
Copy Markdown
Contributor Author

image There is this warning that we can fix in a follow up PR or in this PR ( I think follow up since the size of changes are already big enough now )

@USERSATOSHI USERSATOSHI requested a review from ciampo May 13, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Block editor /packages/block-editor [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate colors in palette causes issues

3 participants