WordPress / gutenberg

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

Add basic theming to the `@wordpress/components` package #44116

Open ciampo opened 1 year ago

ciampo commented 1 year ago

What

Allow the components package to be themed by its consumers

How

The components package would allow theming by exposing a few CSS variables (e.g "primary color", "text color", "background color", "border radius"...). The package would have default values for each variable, but any consumer of the package would be able to override those values.

These variables would be applied to all components in the package, regardless of how they are used within the editor. But given the nature of CSS and CSS variables, different overrides could be applied in different DOM subtrees (e.g the sidebar wrapper could set a different background colors from the navigation panel, etc etc).

Having the package expose its own variables (instead of using gutenberg-specific variables) would help to decouple the package from the rest of the editor, and make it more reusable.

Things to discuss / refine:

Action plan

Context

mirka commented 1 year ago

I'm thinking of starting with something like (in order of priority):

  1. accent color
  2. background color
  3. foreground color

Very simple, three official variables. Everything else (borders, shadows, darkened accent colors, etc.) we can try and automatically generate internally based on the given colors. It might be possible that we can manage without even exposing the foreground color (i.e. text), because we could just infer a black or white scheme based on the background color contrast.

The approach diverges on how to handle the auto-generation. We could calculate everything in CSS only, by enforcing consumers to set the CSS variable in distinct RGB or HSL values (some variation on this technique). But I think it would be easier for everyone if we added a nestable theme provider component to handle the calculations in JS:

<ThemeProvider accent="#007cba" background="#1e1e1e">
  <MyHeader />
  <ThemeProvider background="#fff">
    <MyEditor />
  </ThemeProvider>
</ThemeProvider>

This way we can more easily do contrast-based manipulation with colord, and consumers can just provide hex colors if they want. The theme provider will calculate all the colors in the scheme and inject it as CSS variables.

I feel like this would cover most sensible use cases. And the very hardcore consumer could still override the generated CSS variables at the CSS level if they wanted to get more granular.

ciampo commented 1 year ago

I'm thinking of starting with something like [...] Very simple, three official variables

Agreed. The simpler we start, the better IMO.

the auto-generation

Based on personal experience with implementing a similar system, I'm a bit skeptical that we'll manage to find a formula that auto-generates colors in a way that is pleasing and well "proportioned" to the human eye for all possible colors — but we should definitely give it a shot, see where we get, and iterate.

We could calculate everything in CSS only [...] But I think it would be easier for everyone if we added a nestable theme provider component to handle the calculations in JS

I liked the idea of using vanilla CSS variables, since it feels cleaner and "closer to the metal" (i.e. using CSS APIs for styling components).

At the same time, I agree that using React context will give us extra flexibility in handling and transforming the values, while still preserving the same "cascade" mechanism that we would have with CSS

mirka commented 1 year ago

At the same time, I agree that using React context will give us extra flexibility in handling and transforming the values, while still preserving the same "cascade" mechanism that we would have with CSS

I was thinking we don't even need context, just render a ThemeProvider as <div class="asdf"> and inject the generated CSS variables as CSS .asdf { --color-foo: #eee; --color-bar: #fff; } etc.

ciampo commented 1 year ago

Edit: the plane of action originally written in this comment has been moved to the issue's description