Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ColorPalette: make component more resilient to color entries with same color value and/or name #43197

Open
Tracked by #57309
ciampo opened this issue Aug 12, 2022 · 2 comments
Labels
[Feature] Custom Editor Styles Functionality for adding custom editor styles Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Type] Bug An existing feature does not function as intended

Comments

@ciampo
Copy link
Contributor

ciampo commented Aug 12, 2022

What problem does this address?

Initially flagged and discussed in #43096

While working on separate issues, I noticed that the ColorPalette component can receive a list colors where two or more color entries can have the same value (e.g #ffffff).

When this happens, currently the ColorPalette component is not able to correctly highlight as "selected" the color that was actually picked by the user — instead, it highlights all color entries sharing that same value as "selected":

image

(image taken from this comment

Having different entries sharing the same color value (and potentially even the same color name) should be considered as a totally valid scenario:

  • Scenario n. 1: there's an entry named Text with value #000000, and another entry called ButtonText with value #000000
  • Scenario n. 2: The theme defines an entry with name Primary and value #ff0000. The user then also defines an entry with the same and same value

This means that the ColorPalette component should not attempt to introduce any logic to alter the list of color entries in order to mitigate this issue, as that could result in an unexpected behavior to the user.

What is your proposed solution?

While there isn't a commonly agreed solution yet, one way to look at this issue is to make sure that the data representing the color entries (passed to ColorPalette) is improved in a way that makes each color entry uniquely identifiable, even if it shares the same name and value as another entry (e.g. an id prop).

I can only imagine that this wouldn't be a trivial change, since it would involve potentially changing the schema of the data, and making sure that the id is generated correctly regardless of how the color is added to the list of available colors for a site (e.g. via the global styles UI, by editing theme.json...).

Since I'm not very knowledgeable about this part of the Gutenberg app, I'll let other folks chime in and discuss potential solutions (I'll keep an eye in case the conversation involves the ColorPalette component)

@ciampo
Copy link
Contributor Author

ciampo commented Aug 12, 2022

Tagging:

@ciampo ciampo added [Type] Bug An existing feature does not function as intended [Feature] Custom Editor Styles Functionality for adding custom editor styles Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Aug 12, 2022
@ramonjd
Copy link
Member

ramonjd commented Aug 15, 2022

I can only imagine that this wouldn't be a trivial change, since it would involve potentially changing the schema of the data, and making sure that the id is generated correctly regardless of how the color is added to the list of available colors for a site

It could be tricky 🤔🤔🤔🤔🤔🤔

I assume we only want to transform data in the editor JS so that the UI controls behave (?)

I'm just thinking aloud... we could add unique keys in global-styles/hooks, where we build the colors object, e..g,

		if (
			shouldDisplayDefaultColors &&
			defaultColors &&
			defaultColors.length
		) {
			result.push( {
				name: _x(
					'Default',
					'Indicates this palette comes from WordPress.'
				),
				// Add a unique id
				colors: defaultColors.map( ( item, index ) => ( {
					...item,
					key: `${ item.color }-${ index }`,
				} ) ),
			} );
		}

But then how would we determine whether the color is "selected" based on the value, when the only value we store is the raw color?

Maybe, at the same time we store the selected color value, store a separate stringified color object as the "selected" color {key: '#000-1', color: '#000', slug: 'Doug' }

I'm not sure this is a good idea, but if anything better occurs to me I'll repost.

vcanales added a commit that referenced this issue Sep 26, 2022
…ndicator (#44344)

* use slug as color indicator key in gs palette

In the global styles panel's palette component, the color's hex code is
used as a `key` for the ColorIndicatorWrapper, but the hex is not
necessarily a unique identifier, unlike the `slug` attribute, which could be
expected to be unique, at least by usage; discussion around improving 
handling of duplicate color in the palette [here](#43197).

Composing the color + index of the element in the array, using it as an index, keeps these error messages away:

> Warning: Encountered two children with the same key, `.$#040DE1`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.

with a palette that looks lilke this:

```json
[
	{
			"color": "#040DE1",
			"name": "Primary",
			"slug": "primary"
	},
	{
			"color": "#040DE1",
			"name": "Foreground",
			"slug": "foreground"
	},
]

```

* compose color, index as color indicator key
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Custom Editor Styles Functionality for adding custom editor styles Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

No branches or pull requests

2 participants