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

Introduce a support key for support global style colors in blocks #21021

Merged
merged 17 commits into from
Mar 24, 2020

Conversation

youknowriad
Copy link
Contributor

Yes I know I know, I've been an opponent of "support" keys for blocks for a long time but we can change our minds right? The simplicity they allow for block authors is IMO good, especially for generic features that should be consistent across blocks.

One of these consistent features could be "colors" and it would include things like:

1- Applying a background color (custom or palette)
2- Applying a text color (custom or palette)
3- Contrast checking
4- Applying gradients (custom or palette) as backgrounds

Some very small changes could be possible between blocks, like enabling/disabling gradients, backgrounds, choosing whether to put the controls in the inspector or toolbar, but ultimately these could be provided by the support key too.

In addition to the factorization benefits, this PR is also based on some ideas:

5- Adding support for colors also means adding support for global styles colors (configurable from theme.json files)
6- Support custom colors is not different from supporting say lineHeight, customFontSize... All these options could be considered global styles support and persisted similarly in a unique style attribute.

The current PR solves 1, 2, 3, 5, 6 and applies a refactor to the Group block to make use of this new support flag.

I also know this makes useColors kind of redundant but since it's experimental, that's fine and if we find value in this approach we can decide to go with one or the other.

@youknowriad youknowriad added [Feature] Block API API that allows to express the block paradigm. [Feature] Extensibility The ability to extend blocks or the editing experience [Block] Group Affects the Group Block [Feature] Full Site Editing [Type] New API New API to be used by plugin developers or package users. Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Mar 19, 2020
@youknowriad youknowriad self-assigned this Mar 19, 2020
@github-actions
Copy link

github-actions bot commented Mar 19, 2020

Size Change: +912 B (0%)

Total Size: 859 kB

Filename Size Change
build/autop/index.js 2.58 kB +1 B
build/block-editor/index.js 102 kB +1.06 kB (1%)
build/block-library/index.js 110 kB -179 B (0%)
build/block-library/style-rtl.css 7.43 kB +20 B (0%)
build/block-library/style.css 7.44 kB +20 B (0%)
build/blocks/index.js 57.5 kB +1 B
build/components/index.js 191 kB -7 B (0%)
build/compose/index.js 6.21 kB -2 B (0%)
build/core-data/index.js 10.6 kB +1 B
build/data/index.js 8.25 kB -1 B
build/edit-post/index.js 91.2 kB -1 B
build/edit-site/index.js 6.72 kB -1 B
build/edit-widgets/index.js 4.43 kB -4 B (0%)
build/editor/index.js 43.8 kB +2 B (0%)
build/element/index.js 4.44 kB +2 B (0%)
build/format-library/index.js 6.95 kB -6 B (0%)
build/keyboard-shortcuts/index.js 2.3 kB +1 B
build/list-reusable-blocks/index.js 2.99 kB +1 B
build/media-utils/index.js 4.84 kB +1 B
build/nux/index.js 3.01 kB +1 B
build/rich-text/index.js 14.4 kB -1 B
build/server-side-render/index.js 2.55 kB -1 B
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 998 B 0 B
build/annotations/index.js 3.43 kB 0 B
build/api-fetch/index.js 3.39 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/index.js 6.02 kB 0 B
build/block-directory/style-rtl.css 760 B 0 B
build/block-directory/style.css 760 B 0 B
build/block-editor/style-rtl.css 11 kB 0 B
build/block-editor/style.css 11 kB 0 B
build/block-library/editor-rtl.css 7.24 kB 0 B
build/block-library/editor.css 7.24 kB 0 B
build/block-library/theme-rtl.css 669 B 0 B
build/block-library/theme.css 671 B 0 B
build/block-serialization-default-parser/index.js 1.65 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/components/style-rtl.css 15.8 kB 0 B
build/components/style.css 15.7 kB 0 B
build/data-controls/index.js 1.04 kB 0 B
build/date/index.js 5.37 kB 0 B
build/deprecated/index.js 771 B 0 B
build/dom-ready/index.js 568 B 0 B
build/dom/index.js 3.06 kB 0 B
build/edit-post/style-rtl.css 8.47 kB 0 B
build/edit-post/style.css 8.46 kB 0 B
build/edit-site/style-rtl.css 2.88 kB 0 B
build/edit-site/style.css 2.88 kB 0 B
build/edit-widgets/style-rtl.css 2.58 kB 0 B
build/edit-widgets/style.css 2.58 kB 0 B
build/editor/editor-styles-rtl.css 381 B 0 B
build/editor/editor-styles.css 382 B 0 B
build/editor/style-rtl.css 4 kB 0 B
build/editor/style.css 3.98 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/style-rtl.css 502 B 0 B
build/format-library/style.css 502 B 0 B
build/hooks/index.js 1.93 kB 0 B
build/html-entities/index.js 622 B 0 B
build/i18n/index.js 3.49 kB 0 B
build/is-shallow-equal/index.js 710 B 0 B
build/keycodes/index.js 1.69 kB 0 B
build/list-reusable-blocks/style-rtl.css 226 B 0 B
build/list-reusable-blocks/style.css 226 B 0 B
build/notices/index.js 1.57 kB 0 B
build/nux/style-rtl.css 616 B 0 B
build/nux/style.css 613 B 0 B
build/plugins/index.js 2.54 kB 0 B
build/primitives/index.js 1.5 kB 0 B
build/priority-queue/index.js 781 B 0 B
build/redux-routine/index.js 2.84 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/url/index.js 4.01 kB 0 B
build/viewport/index.js 1.61 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.18 kB 0 B

compressed-size-action

<ColorPanel
key="colors"
clientId={ props.clientId }
colorSettings={ [
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had trouble understanding the API of the PanelColorSettings. I believe it should be documented properly.

packages/block-editor/src/hooks/color.js Outdated Show resolved Hide resolved
packages/block-editor/src/hooks/color.js Outdated Show resolved Hide resolved
packages/block-editor/src/hooks/color.js Outdated Show resolved Hide resolved
packages/block-editor/src/hooks/color.js Outdated Show resolved Hide resolved
packages/block-editor/src/hooks/style.js Outdated Show resolved Hide resolved
packages/block-editor/src/hooks/style.js Outdated Show resolved Hide resolved

/**
* Filters registered block settings, extending attributes to include
* `backgroundColor` and `textColor` attribute.
Copy link
Member

Choose a reason for hiding this comment

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

Should we try to have a "style" attribute that blocks and global styles can use to store global styles related information, instead of using the hook to register a new attribute?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's already the case in this PR. These extra attributes are needed for the color palette classNames unless there's a way to define these with global styles that I'm not aware of?

Copy link
Member

Choose a reason for hiding this comment

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

I think @mtias suggested that instead of using classes for predefined colors we should still use CSS vars anyway but the CSS vars would reference another vars.

Copy link
Member

Choose a reason for hiding this comment

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

I guess we may have a way to store things in style that indicates another variable is being referenced.
Global styles may have a mechanism where themes structurally set the variables, and we can say colors variables should reference some set, so when we set a color to a value equal to the variable part of a set instead of storing the value we reference the variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can I have an example of CSS for named colors using variables?

Copy link
Member

@jorgefilipecosta jorgefilipecosta Mar 20, 2020

Choose a reason for hiding this comment

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

So in theme.json a theme may provide something like:

colors: [
	{	name: "Red", slug: "red", color: "#f00" },
	{	name: "Blue", slug: "blue", color: "#00f" },
]

This would generate the following vars during the compilation:

--wp--colors--red: #f00;
--wp--colors--blue: #00f;

When storing a color attribute if the value is equal to one of the color variables instead of storing the value we would store a reference to the variable: --wp--background-color: var(--wp--colors--red);

In the style attribute, we may use the var directly {"style":{"backgroundColor":"var(--wp--colors--red)"}} or we may use a special reference mechanism syntax {"style":{"backgroundColor":"ref:red"}}

This solution has some disadvantages when compared with class usage:

  • A theme can not automatically apply a text color when a specific background color is used, and a text color is not explicitly selected.
  • A theme can not apply a hover color depending on the text color.
  • A theme can not define the colors of links in a block, depending on the text color selected.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is an interesting proposal and I can be onboard with that. Though, that's a bigger separate project. If we do this, we need to do it across blocks by measuring the pros and cons and communicating the changes properly.

For this PR, I think we can keep the existing behavior and it can still be adapted in the future if we use CSS variables for palettes too.

Copy link
Member

Choose a reason for hiding this comment

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

If we would use CSS variables for registered theme colors, we could avoid having all those class names stored in HTML content generated by the save method altogether.

I think it feels like the very next step to explore. In theory, it could also open doors for having only one attribute used per color type as you could use CSS syntax for values.

youknowriad and others added 2 commits March 24, 2020 09:28
Co-Authored-By: Zebulan Stanphill <zebulanstanphill@protonmail.com>
@youknowriad
Copy link
Contributor Author

@aduth Good thoughts.

I think the current implementation in this PR has several benefits that can't be achieved using inline styles:

  • It supports the global styles config (theme.json)
  • Like raised by @gziolo there's no inline style and the variables can be generated automatically for any style, there's nothing specific to colors compared to line-height for instance...
  • Block authors can decide to apply the variables to any nested element, not just a specific wrapper.
  • IE11 can be seen as a progressive enhancement.

@youknowriad
Copy link
Contributor Author

I think this is ready to land as a v1. It's experimental for now, which means we can still decide to change/revert later if needed and we'd have a full plugin release cycle before the next release.

Anyone willing to ✅

@youknowriad youknowriad added the Needs Dev Note Requires a developer note for a major WordPress release cycle label Mar 24, 2020
@gziolo
Copy link
Member

gziolo commented Mar 24, 2020

The logic that set styles as attributes needs some better filtering:

Screen Shot 2020-03-24 at 10 47 27

In my testing, I figured out it gets added when changing the background color.

Other than that it works perfectly fine and it's ready to go. Great work Riad! 👏

As discussed, we should verify how it plays in action and based on that take the next steps.

@@ -29,8 +29,10 @@ export const settings = {
],
example: {
attributes: {
customBackgroundColor: '#ffffff',
customTextColor: '#000000',
style: {
Copy link
Member

Choose a reason for hiding this comment

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

Do you know why this example differs from the actual usage?:
Screen Shot 2020-03-24 at 11 00 00

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Outdated example :)

import { getCSSVariables } from '../style';

describe( 'getCSSVariables', () => {
it( 'should return an empty object when called with undefined', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Should there be a test that handle falsy values:

it( 'should omit CSS variables when the provided value is falsy', () => {
	expect( getCSSVariables( { color: undefined } ) ).toEqual( {} );
} );

const attributeName = name + 'Color';
const newStyle = {
...style,
color: {
Copy link
Member

Choose a reason for hiding this comment

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

It looks like here we should filter out keys that were set to undefined

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not easy since it's nested and we should filter out the ones that are not coming from this particular hook.

Copy link
Member

Choose a reason for hiding this comment

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

It isn't the end of the world if those values are stored as empty, it's just nice optimization to have in place as it is technically not necessary.

@youknowriad
Copy link
Contributor Author

Just adding that this should be included in the dev note #21428 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Group Affects the Group Block [Feature] Block API API that allows to express the block paradigm. [Feature] Extensibility The ability to extend blocks or the editing experience Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Type] New API New API to be used by plugin developers or package users.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants