WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
9.99k stars 4.02k forks source link

color-palette-panel - add possibility to "group" colors #47837

Open Chrico opened 1 year ago

Chrico commented 1 year ago

What problem does this address?

Right now the ColorPalettePanel groups colors via PaletteEdit into the hardcoded 2 groups "Theme" and "Default", but it is not possible to introduce custom grouping. This could become handy when having many custom colors and starting to group them by branding or usage.

Theme

Code: https://github.com/WordPress/gutenberg/blob/v15.0.1/packages/edit-site/src/components/global-styles/color-palette-panel.js#L49-L55

Those are comming from the theme.json via settings.color.palette in following format:

{
    "settings": {
        "color": {
            "palette": [
                {
                    "slug": "primary",
                    "color": "#7c027c",
                    "name": "Purple"
                }
            ]
        }
    }
}

Defaults

Code: https://github.com/WordPress/gutenberg/blob/v15.0.1/packages/edit-site/src/components/global-styles/color-palette-panel.js#L57-L67

Those are default colors which can also be deactivated via theme.json via settings.color.defaultPalette: false

What is your proposed solution?

We could simply extend the settings.color.palette by introducing a new "group"-key to the color settings. This way we were able to add some grouping on the ColorPalettePanel to have better seperation:

{
    "settings": {
        "color": {
            "palette": [
                {
                    "slug": "purple",
                    "color": "#7c027c",
                    "name": "Purple"
                    "group": "Product XYZ Branding"
                },
                {
                    "slug": "lavender",
                    "color": "#E6E6FA",
                    "name": "A different purple"
                    "group": "Product ABC Branding"
                },
                {
                    "slug": "fuchsia",
                    "color": "#FF00FF",
                    "name": "Default purpleish"
                }
            ]
        }
    }
}

The output would looks like following:

We have 3 groups: The 2 custom ones "Product XYZ Branding" and "Product ABC Branding" and additonally the 1 color which has no group defaults to "Theme":

image

Chrico commented 1 year ago

Any feedback? @kathrynwp πŸ‘€

kathrynwp commented 1 year ago

@Chrico I'm part of the triage team helping test bugs and label issues, but for enhancements we'll need to wait for a developer to provide some input. :)

Chrico commented 1 year ago

@bph or @ndiego maybe? πŸ™ƒ

karmatosed commented 1 year ago

Hi @Chrico one thing this has me thinking is whether this is something to add or whether having styles where it's clearer the entire brand changes is easier. I say this because changing a styling is easy and has more of a visual component than a pallette. I, therefore, wonder when thinking of branding colors like your example if using style changes would be better than loading multiple palettes.

That said, if there are already two palettes, having more than those restrictions doesn't seem a huge issue. It does to me feel like over a certain point scaling of that interface would need some consideration. That's why I feel the styling/style book interface might be a better way to lead people to for branding.

Chrico commented 1 year ago

@karmatosed The "branding" was just an example for possible grouping of colors. πŸ™ƒ You could also choose "primary, secondary, the rest" or "grey, gray, another grey, blue" as groups. It doesn't matter, but it would allow more "clarity" for the color platette vs the current 2 groups "Default" and "Theme".

bhubbard commented 11 months ago

I love this idea, for the site I am working on now, we would have 3 "groups":

Without groups, some users would see the ADA colors next to the brand colors, not understanding which is for what. They could hover and see the name, but that is not as obvious to all users.

jdamner commented 5 months ago

Related: #34741

jdamner commented 5 months ago

I'm happy to take this on and produce a PR, but I guess the needs-discussion on this is around determining the best way to allow theme & plugin developers to define palette groupings.

In the interests of keeping this simple, I'd suggest that initially the best approach would be to allow the palettes returned by the settings api to be passed through a filter that returns as many palettes as necessary. It would make the feature initially only available via JS, but would pave the way for more robust colour-palette management.

At the moment it's somewhat achievable to modify the palette data using blockEditor.useSetting.before hook.


/* Assume these imports define colour-palettes in the right format */
import defaultPaletteOverride from './palette-default.json'
import themePaletteOverride from './palette-theme.json'

const replaceColorPalette = ( settings, key, clientId, blockName ) => {

    if ( key === 'color.palette.default' ) {
        return defaultPaletteOverride
    }

    if ( key === 'color.palette.theme' ) {
        return themePaletteOverride;
    }

    return settings;
};

The main issue I see here is that the main colour selection component is hard-coded to pull data from three palettes - default, theme and custom - the colour-component itself is actually very capable of rendering as many palettes as you like.

~My initial instinct would be to add a filter around https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/components/colors/with-colors.js#L67 to allow plugin and theme developers to modify the palettes to include additional or modify/remove existing. If there's compatibility risks, we could also only allow additional palettes to be added this way, and the three existing palettes could remain untouched.~ See note below, this isn't a simple filter task.

The larger scope of work would be to allow theme.json to be defined with an array of palettes each with a unique name and label, somewhat like below. I'd suggest this format over the json format from @Chrico since the slug only does not provide a UI label. The existing colour component already differentiates between a single colour and a palette of colours based on if the object has a colors key vs a color key. Replicating this structure to the theme.json schema seems like the most sensible approach also:

{
    "settings": { 
        "color": {
            "palettes": [
                { "label": "Palette One", "slug": "palette-one", "colors": [ {} ] },
                { "label": "Palette Two", "slug": "palette-two", "colors": [ {} ] },
                { "label": "Palette Three", "slug": "palette-three", "colors": [ {} ] },
            ]
        }
    }
}

The colour objects would be the same as the existing colour definitions, but we would construct the class names to be .has-{palette.slug}--{color.slug}-color to avoid name conflicts.


If we can agree that the JS solution is a good first step I can do the work to get this running and tested. The filter solution feels like a much more manageable scope of work, for a feature that may be utilised only by advanced theme developers.

If we want to consider the larger effort to add support in the theme.json I can look to take this on also, just looking for guidance before starting.

jdamner commented 4 months ago

I see now why this has been on the back-burner for a while and why more discussion is needed! I was naΓ―ve to think this wouldn't be a particularly large task!

It seems to me that it would be truly beneficial for colour palettes to be refactored to a couple of single hooks used across all components that need them. Right now there's a few instances where hooks are used (useColorsPerOrigin and useGradientsPerOrigin), other instances where colour settings are retrieved directly using useSettings.

I think a good initial scope of work would be to aim to consolidate all areas where colour and gradient palettes are used to a single hook (or a few hooks). This will be a foundation of allowing further development allowing multiple palettes to be defined by theme and plugin authors.

jdamner commented 4 months ago

Further thoughts on this, the ability to edit the theme colour palette exists within the site editor, so any solution will require a suitable design to support this.

This may create an opportunity for plugin and theme developers to offer palettes to the user that are user controlled/managed, simplifying changes of colors used within plugins.

If I install a plugin that offers a colour palette that's used by all the components that plugin offers, it's currently difficult to achieve colour changes that are applied to all blocks through the colour picker in the block editor.

As an example, I might offer an ecommerce plugin with lots of blocks, but would like each block to follow a consistent them. Right now, each instance of that block would need its colour defined, and any server side code (such as an email template) would require separate configuration. Potentially if the plugin registered its colour palette the user could change it globally in the site editor for all blocks by the plugin vendor. I could see scenario where the plugin vendor may wish to opt-out of having the palettes modified though, such as where brand colours exist and shouldn't be changed.

A registered palette would have the CSS vars generated from the style engine, so overridable much like how the theme palette functions today, and a registered palette would have data persisted and available server side, or fallback to the plugin provided default.

This might tie in to the talks around colour ways/grouped palettes too.

fabiankaegy commented 3 months ago

@WordPress/gutenberg-design I'd love to get your thoughts on this. We discussed this in a recent Gutenberg Extensibility triage session and thought it would be something the design team would have thoughts/opinions about :)

jasmussen commented 2 months ago

Seems like this could work as a theme.json affordance πŸ‘ πŸ‘

What design does it need? The initial instinct with subheadings seems like it could work. We might need to eventually consider a scrollbar for the flyout, and/or smaller swatches, for when a lot of colors are added. But that seems a separate issue that's valid for trunk as it exists today as well.

aurooba commented 1 month ago

I'd love to see some attention around this! In large and complicated sites, for example, you often have primary brand colours, secondary colours, neutrals, etc. Being able to group, categorize, and specify which groups are available to what blocks, would be awesome.