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

Components: Add themeable background color #45466

Merged
merged 26 commits into from
Nov 30, 2022
Merged

Components: Add themeable background color #45466

merged 26 commits into from
Nov 30, 2022

Conversation

mirka
Copy link
Member

@mirka mirka commented Nov 1, 2022

Part of #44116

What?

Extends the Theme component to support an arbitrary background color. We then generate the rest of the necessary foreground/grayscale colors based on that.

The Button component has been updated to support these new theme colors. (Except the disabled and isBusy states, which we will address later.

Why?

It is cumbersome and error-prone for a consumer to have to generate all of the necessary theme colors. If possible, we would prefer for automatic generation to work in the majority of cases.

How?

See theme/color-algorithms.ts for the logic.

Testing Instructions

  1. npm run storybook:dev and go to the stories for Button.

  2. Use the Theme add-on in the toolbar to switch between some preset themes.

    Theme add-on

Note that some styles are not theme-ready yet (disabled and isBusy states) and will be addressed separately.

Screenshots or screencast

Added a story for the Theme component to see the generated colors.

CleanShot.2022-11-10.at.06.37.21.mp4

Added a background underlay to the theme add-on in the toolbar.

CleanShot.2022-11-10.at.06.39.21.mp4

@mirka mirka added the [Package] Components /packages/components label Nov 1, 2022
@mirka mirka self-assigned this Nov 1, 2022
@codesandbox
Copy link

codesandbox bot commented Nov 1, 2022

CodeSandbox logoCodeSandbox logo  Open in CodeSandbox Web Editor | VS Code | VS Code Insiders

@github-actions
Copy link

github-actions bot commented Nov 7, 2022

Size Change: +725 B (0%)

Total Size: 1.32 MB

Filename Size Change
build/components/index.min.js 204 kB +585 B (0%)
build/components/style-rtl.css 11.7 kB +70 B (+1%)
build/components/style.css 11.7 kB +70 B (+1%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/annotations/index.min.js 2.78 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 487 B
build/block-directory/index.min.js 7.16 kB
build/block-directory/style-rtl.css 1.03 kB
build/block-directory/style.css 1.04 kB
build/block-editor/default-editor-styles-rtl.css 401 B
build/block-editor/default-editor-styles.css 401 B
build/block-editor/index.min.js 180 kB
build/block-editor/style-rtl.css 16.5 kB
build/block-editor/style.css 16.5 kB
build/block-library/blocks/archives/editor-rtl.css 107 B
build/block-library/blocks/archives/editor.css 106 B
build/block-library/blocks/archives/style-rtl.css 129 B
build/block-library/blocks/archives/style.css 129 B
build/block-library/blocks/audio/editor-rtl.css 185 B
build/block-library/blocks/audio/editor.css 185 B
build/block-library/blocks/audio/style-rtl.css 158 B
build/block-library/blocks/audio/style.css 158 B
build/block-library/blocks/audio/theme-rtl.css 172 B
build/block-library/blocks/audio/theme.css 172 B
build/block-library/blocks/avatar/editor-rtl.css 154 B
build/block-library/blocks/avatar/editor.css 154 B
build/block-library/blocks/avatar/style-rtl.css 126 B
build/block-library/blocks/avatar/style.css 126 B
build/block-library/blocks/block/editor-rtl.css 338 B
build/block-library/blocks/block/editor.css 338 B
build/block-library/blocks/button/editor-rtl.css 517 B
build/block-library/blocks/button/editor.css 517 B
build/block-library/blocks/button/style-rtl.css 566 B
build/block-library/blocks/button/style.css 566 B
build/block-library/blocks/buttons/editor-rtl.css 373 B
build/block-library/blocks/buttons/editor.css 373 B
build/block-library/blocks/buttons/style-rtl.css 368 B
build/block-library/blocks/buttons/style.css 368 B
build/block-library/blocks/calendar/style-rtl.css 270 B
build/block-library/blocks/calendar/style.css 270 B
build/block-library/blocks/categories/editor-rtl.css 125 B
build/block-library/blocks/categories/editor.css 124 B
build/block-library/blocks/categories/style-rtl.css 138 B
build/block-library/blocks/categories/style.css 138 B
build/block-library/blocks/code/editor-rtl.css 102 B
build/block-library/blocks/code/editor.css 102 B
build/block-library/blocks/code/style-rtl.css 159 B
build/block-library/blocks/code/style.css 159 B
build/block-library/blocks/code/theme-rtl.css 160 B
build/block-library/blocks/code/theme.css 160 B
build/block-library/blocks/columns/editor-rtl.css 147 B
build/block-library/blocks/columns/editor.css 147 B
build/block-library/blocks/columns/style-rtl.css 442 B
build/block-library/blocks/columns/style.css 442 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 163 B
build/block-library/blocks/comment-author-avatar/editor.css 163 B
build/block-library/blocks/comment-content/style-rtl.css 134 B
build/block-library/blocks/comment-content/style.css 134 B
build/block-library/blocks/comment-template/style-rtl.css 237 B
build/block-library/blocks/comment-template/style.css 236 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 159 B
build/block-library/blocks/comments-pagination-numbers/editor.css 157 B
build/block-library/blocks/comments-pagination/editor-rtl.css 258 B
build/block-library/blocks/comments-pagination/editor.css 249 B
build/block-library/blocks/comments-pagination/style-rtl.css 272 B
build/block-library/blocks/comments-pagination/style.css 268 B
build/block-library/blocks/comments-title/editor-rtl.css 118 B
build/block-library/blocks/comments-title/editor.css 118 B
build/block-library/blocks/comments/editor-rtl.css 875 B
build/block-library/blocks/comments/editor.css 874 B
build/block-library/blocks/comments/style-rtl.css 672 B
build/block-library/blocks/comments/style.css 671 B
build/block-library/blocks/cover/editor-rtl.css 646 B
build/block-library/blocks/cover/editor.css 647 B
build/block-library/blocks/cover/style-rtl.css 1.61 kB
build/block-library/blocks/cover/style.css 1.6 kB
build/block-library/blocks/embed/editor-rtl.css 327 B
build/block-library/blocks/embed/editor.css 327 B
build/block-library/blocks/embed/style-rtl.css 446 B
build/block-library/blocks/embed/style.css 446 B
build/block-library/blocks/embed/theme-rtl.css 172 B
build/block-library/blocks/embed/theme.css 172 B
build/block-library/blocks/file/editor-rtl.css 335 B
build/block-library/blocks/file/editor.css 335 B
build/block-library/blocks/file/style-rtl.css 288 B
build/block-library/blocks/file/style.css 288 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.47 kB
build/block-library/blocks/freeform/editor.css 2.47 kB
build/block-library/blocks/gallery/editor-rtl.css 987 B
build/block-library/blocks/gallery/editor.css 993 B
build/block-library/blocks/gallery/style-rtl.css 1.58 kB
build/block-library/blocks/gallery/style.css 1.58 kB
build/block-library/blocks/gallery/theme-rtl.css 157 B
build/block-library/blocks/gallery/theme.css 157 B
build/block-library/blocks/group/editor-rtl.css 687 B
build/block-library/blocks/group/editor.css 687 B
build/block-library/blocks/group/style-rtl.css 105 B
build/block-library/blocks/group/style.css 105 B
build/block-library/blocks/group/theme-rtl.css 125 B
build/block-library/blocks/group/theme.css 125 B
build/block-library/blocks/heading/style-rtl.css 128 B
build/block-library/blocks/heading/style.css 128 B
build/block-library/blocks/html/editor-rtl.css 365 B
build/block-library/blocks/html/editor.css 366 B
build/block-library/blocks/image/editor-rtl.css 912 B
build/block-library/blocks/image/editor.css 912 B
build/block-library/blocks/image/style-rtl.css 662 B
build/block-library/blocks/image/style.css 666 B
build/block-library/blocks/image/theme-rtl.css 172 B
build/block-library/blocks/image/theme.css 172 B
build/block-library/blocks/latest-comments/style-rtl.css 333 B
build/block-library/blocks/latest-comments/style.css 333 B
build/block-library/blocks/latest-posts/editor-rtl.css 250 B
build/block-library/blocks/latest-posts/editor.css 249 B
build/block-library/blocks/latest-posts/style-rtl.css 514 B
build/block-library/blocks/latest-posts/style.css 514 B
build/block-library/blocks/list/style-rtl.css 135 B
build/block-library/blocks/list/style.css 135 B
build/block-library/blocks/media-text/editor-rtl.css 300 B
build/block-library/blocks/media-text/editor.css 298 B
build/block-library/blocks/media-text/style-rtl.css 540 B
build/block-library/blocks/media-text/style.css 539 B
build/block-library/blocks/more/editor-rtl.css 465 B
build/block-library/blocks/more/editor.css 465 B
build/block-library/blocks/navigation-link/editor-rtl.css 746 B
build/block-library/blocks/navigation-link/editor.css 744 B
build/block-library/blocks/navigation-link/style-rtl.css 153 B
build/block-library/blocks/navigation-link/style.css 153 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 333 B
build/block-library/blocks/navigation-submenu/editor.css 333 B
build/block-library/blocks/navigation/editor-rtl.css 2.19 kB
build/block-library/blocks/navigation/editor.css 2.19 kB
build/block-library/blocks/navigation/style-rtl.css 2.26 kB
build/block-library/blocks/navigation/style.css 2.25 kB
build/block-library/blocks/navigation/view-modal.min.js 2.81 kB
build/block-library/blocks/navigation/view.min.js 447 B
build/block-library/blocks/nextpage/editor-rtl.css 428 B
build/block-library/blocks/nextpage/editor.css 428 B
build/block-library/blocks/page-list/editor-rtl.css 397 B
build/block-library/blocks/page-list/editor.css 398 B
build/block-library/blocks/page-list/style-rtl.css 212 B
build/block-library/blocks/page-list/style.css 212 B
build/block-library/blocks/paragraph/editor-rtl.css 214 B
build/block-library/blocks/paragraph/editor.css 214 B
build/block-library/blocks/paragraph/style-rtl.css 321 B
build/block-library/blocks/paragraph/style.css 321 B
build/block-library/blocks/post-author/style-rtl.css 212 B
build/block-library/blocks/post-author/style.css 212 B
build/block-library/blocks/post-comments-form/editor-rtl.css 137 B
build/block-library/blocks/post-comments-form/editor.css 137 B
build/block-library/blocks/post-comments-form/style-rtl.css 536 B
build/block-library/blocks/post-comments-form/style.css 537 B
build/block-library/blocks/post-date/style-rtl.css 107 B
build/block-library/blocks/post-date/style.css 107 B
build/block-library/blocks/post-excerpt/editor-rtl.css 119 B
build/block-library/blocks/post-excerpt/editor.css 119 B
build/block-library/blocks/post-excerpt/style-rtl.css 116 B
build/block-library/blocks/post-excerpt/style.css 116 B
build/block-library/blocks/post-featured-image/editor-rtl.css 620 B
build/block-library/blocks/post-featured-image/editor.css 618 B
build/block-library/blocks/post-featured-image/style-rtl.css 349 B
build/block-library/blocks/post-featured-image/style.css 349 B
build/block-library/blocks/post-navigation-link/style-rtl.css 190 B
build/block-library/blocks/post-navigation-link/style.css 189 B
build/block-library/blocks/post-template/editor-rtl.css 140 B
build/block-library/blocks/post-template/editor.css 139 B
build/block-library/blocks/post-template/style-rtl.css 317 B
build/block-library/blocks/post-template/style.css 317 B
build/block-library/blocks/post-terms/style-rtl.css 136 B
build/block-library/blocks/post-terms/style.css 136 B
build/block-library/blocks/post-title/style-rtl.css 138 B
build/block-library/blocks/post-title/style.css 138 B
build/block-library/blocks/preformatted/style-rtl.css 139 B
build/block-library/blocks/preformatted/style.css 139 B
build/block-library/blocks/pullquote/editor-rtl.css 170 B
build/block-library/blocks/pullquote/editor.css 170 B
build/block-library/blocks/pullquote/style-rtl.css 357 B
build/block-library/blocks/pullquote/style.css 357 B
build/block-library/blocks/pullquote/theme-rtl.css 201 B
build/block-library/blocks/pullquote/theme.css 201 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 158 B
build/block-library/blocks/query-pagination-numbers/editor.css 156 B
build/block-library/blocks/query-pagination/editor-rtl.css 258 B
build/block-library/blocks/query-pagination/editor.css 247 B
build/block-library/blocks/query-pagination/style-rtl.css 326 B
build/block-library/blocks/query-pagination/style.css 322 B
build/block-library/blocks/query-title/style-rtl.css 108 B
build/block-library/blocks/query-title/style.css 108 B
build/block-library/blocks/query/editor-rtl.css 475 B
build/block-library/blocks/query/editor.css 477 B
build/block-library/blocks/quote/style-rtl.css 253 B
build/block-library/blocks/quote/style.css 253 B
build/block-library/blocks/quote/theme-rtl.css 255 B
build/block-library/blocks/quote/theme.css 259 B
build/block-library/blocks/read-more/style-rtl.css 168 B
build/block-library/blocks/read-more/style.css 168 B
build/block-library/blocks/rss/editor-rtl.css 239 B
build/block-library/blocks/rss/editor.css 240 B
build/block-library/blocks/rss/style-rtl.css 323 B
build/block-library/blocks/rss/style.css 323 B
build/block-library/blocks/search/editor-rtl.css 205 B
build/block-library/blocks/search/editor.css 205 B
build/block-library/blocks/search/style-rtl.css 441 B
build/block-library/blocks/search/style.css 439 B
build/block-library/blocks/search/theme-rtl.css 149 B
build/block-library/blocks/search/theme.css 149 B
build/block-library/blocks/separator/editor-rtl.css 184 B
build/block-library/blocks/separator/editor.css 184 B
build/block-library/blocks/separator/style-rtl.css 269 B
build/block-library/blocks/separator/style.css 269 B
build/block-library/blocks/separator/theme-rtl.css 229 B
build/block-library/blocks/separator/theme.css 229 B
build/block-library/blocks/shortcode/editor-rtl.css 508 B
build/block-library/blocks/shortcode/editor.css 508 B
build/block-library/blocks/site-logo/editor-rtl.css 522 B
build/block-library/blocks/site-logo/editor.css 522 B
build/block-library/blocks/site-logo/style-rtl.css 238 B
build/block-library/blocks/site-logo/style.css 238 B
build/block-library/blocks/site-tagline/editor-rtl.css 129 B
build/block-library/blocks/site-tagline/editor.css 129 B
build/block-library/blocks/site-title/editor-rtl.css 155 B
build/block-library/blocks/site-title/editor.css 155 B
build/block-library/blocks/site-title/style-rtl.css 101 B
build/block-library/blocks/site-title/style.css 101 B
build/block-library/blocks/social-link/editor-rtl.css 219 B
build/block-library/blocks/social-link/editor.css 219 B
build/block-library/blocks/social-links/editor-rtl.css 709 B
build/block-library/blocks/social-links/editor.css 708 B
build/block-library/blocks/social-links/style-rtl.css 1.43 kB
build/block-library/blocks/social-links/style.css 1.43 kB
build/block-library/blocks/spacer/editor-rtl.css 372 B
build/block-library/blocks/spacer/editor.css 372 B
build/block-library/blocks/spacer/style-rtl.css 96 B
build/block-library/blocks/spacer/style.css 96 B
build/block-library/blocks/table/editor-rtl.css 547 B
build/block-library/blocks/table/editor.css 547 B
build/block-library/blocks/table/style-rtl.css 670 B
build/block-library/blocks/table/style.css 669 B
build/block-library/blocks/table/theme-rtl.css 220 B
build/block-library/blocks/table/theme.css 220 B
build/block-library/blocks/tag-cloud/style-rtl.css 287 B
build/block-library/blocks/tag-cloud/style.css 288 B
build/block-library/blocks/template-part/editor-rtl.css 436 B
build/block-library/blocks/template-part/editor.css 436 B
build/block-library/blocks/template-part/theme-rtl.css 139 B
build/block-library/blocks/template-part/theme.css 139 B
build/block-library/blocks/text-columns/editor-rtl.css 135 B
build/block-library/blocks/text-columns/editor.css 135 B
build/block-library/blocks/text-columns/style-rtl.css 198 B
build/block-library/blocks/text-columns/style.css 198 B
build/block-library/blocks/verse/style-rtl.css 130 B
build/block-library/blocks/verse/style.css 130 B
build/block-library/blocks/video/editor-rtl.css 720 B
build/block-library/blocks/video/editor.css 723 B
build/block-library/blocks/video/style-rtl.css 218 B
build/block-library/blocks/video/style.css 218 B
build/block-library/blocks/video/theme-rtl.css 171 B
build/block-library/blocks/video/theme.css 171 B
build/block-library/classic-rtl.css 193 B
build/block-library/classic.css 193 B
build/block-library/common-rtl.css 1.05 kB
build/block-library/common.css 1.05 kB
build/block-library/editor-elements-rtl.css 126 B
build/block-library/editor-elements.css 126 B
build/block-library/editor-rtl.css 11.7 kB
build/block-library/editor.css 11.7 kB
build/block-library/elements-rtl.css 105 B
build/block-library/elements.css 105 B
build/block-library/index.min.js 196 kB
build/block-library/reset-rtl.css 514 B
build/block-library/reset.css 514 B
build/block-library/style-rtl.css 12.4 kB
build/block-library/style.css 12.4 kB
build/block-library/theme-rtl.css 749 B
build/block-library/theme.css 753 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 50 kB
build/compose/index.min.js 12.3 kB
build/core-data/index.min.js 15.6 kB
build/customize-widgets/index.min.js 11.3 kB
build/customize-widgets/style-rtl.css 1.41 kB
build/customize-widgets/style.css 1.41 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 8.12 kB
build/date/index.min.js 32.1 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.74 kB
build/edit-navigation/index.min.js 16.2 kB
build/edit-navigation/style-rtl.css 4.1 kB
build/edit-navigation/style.css 4.1 kB
build/edit-post/classic-rtl.css 569 B
build/edit-post/classic.css 570 B
build/edit-post/index.min.js 34.5 kB
build/edit-post/style-rtl.css 7.45 kB
build/edit-post/style.css 7.44 kB
build/edit-site/index.min.js 61.2 kB
build/edit-site/style-rtl.css 8.52 kB
build/edit-site/style.css 8.51 kB
build/edit-widgets/index.min.js 16.8 kB
build/edit-widgets/style-rtl.css 4.46 kB
build/edit-widgets/style.css 4.46 kB
build/editor/index.min.js 44 kB
build/editor/style-rtl.css 3.65 kB
build/editor/style.css 3.64 kB
build/element/index.min.js 4.72 kB
build/escape-html/index.min.js 548 B
build/experiments/index.min.js 882 B
build/format-library/index.min.js 6.96 kB
build/format-library/style-rtl.css 596 B
build/format-library/style.css 596 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.79 kB
build/keycodes/index.min.js 1.86 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 858 B
build/list-reusable-blocks/style.css 857 B
build/media-utils/index.min.js 2.94 kB
build/notices/index.min.js 977 B
build/nux/index.min.js 2.07 kB
build/nux/style-rtl.css 772 B
build/nux/style.css 768 B
build/plugins/index.min.js 1.95 kB
build/preferences-persistence/index.min.js 2.23 kB
build/preferences/index.min.js 1.35 kB
build/primitives/index.min.js 960 B
build/priority-queue/index.min.js 1.59 kB
build/react-i18n/index.min.js 702 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.75 kB
build/reusable-blocks/index.min.js 2.22 kB
build/reusable-blocks/style-rtl.css 281 B
build/reusable-blocks/style.css 281 B
build/rich-text/index.min.js 10.7 kB
build/server-side-render/index.min.js 1.77 kB
build/shortcode/index.min.js 1.52 kB
build/style-engine/index.min.js 1.51 kB
build/token-list/index.min.js 650 B
build/url/index.min.js 3.7 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.09 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.23 kB
build/widgets/style-rtl.css 1.21 kB
build/widgets/style.css 1.21 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@@ -7,11 +7,11 @@
}

.components-tooltip .components-popover__content {
background: $gray-900;
background: $components-color-foreground; // TODO: Discuss with designers.
Copy link
Member Author

Choose a reason for hiding this comment

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

Tooltips could be a case where designers want a different shade when in dark mode.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes indeed, they can be much lighter. I don't think that needs to block anything here, though, as the white text inside a dark background will always be legible.

background,
...props
}: WordPressComponentProps< ThemeProps, 'div', true > ) {
const themeVariables = generateThemeVariables( { accent, background } );
Copy link
Member Author

Choose a reason for hiding this comment

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

The next thing we should do is to take these themeVariables values and make them available to descendant components via Context. This will allow us to resolve the remaining TODO comments in Button, where Button needs to access the color values directly and compute its non-standard colors in JS.

Copy link
Contributor

Choose a reason for hiding this comment

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

Here's a few considerations (almost a brainstorming sessions) that came to mind when thinking about using React Context:

  • are we ok exposing the variables both in React Context and as CSS variables ?
  • Which one is the source of truth?
  • Is there a scenario in which they could not be in sync ?
  • CSS vars will be accessible to DOM descendants, while React Content will be accessible to all react child components — which gives us the chance of using one or the other when styling Slot-Fill components (e.g Popover)

Copy link
Member Author

Choose a reason for hiding this comment

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

After ruminating on this, I'll backtrack — we shouldn't use React Context in combination with the original DOM-based scoping system 😅 It would cause a lot of complications like you mention.

So I guess we really need to avoid Sass color functions as much as possible, and maybe consider exposing HSL-split CSS vars (--h --s --l) for things that are absolutely necessary 😕

}

&:disabled,
&:disabled:active:enabled,
&[aria-disabled="true"],
&[aria-disabled="true"]:enabled, // This catches a situation where a Button is aria-disabled, but not disabled.
&[aria-disabled="true"]:active:enabled {
// TODO: This needs to be accent-inverted
Copy link
Member Author

Choose a reason for hiding this comment

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

The three TODO comments in this stylesheet flag the parts that rely on Sass functions, which will not work when the underlying values are CSS variables.

There are two ways we can address these:

  1. Work with designers and see if any of the Sass function parts can be replaced with the standard gray-100 etc. colors. This is the easiest and preferred way when designing themeable components.
  2. In the Button component, access the raw theme color values (not CSS variables) via Context, and calculate the necessary colors in JS.

Copy link
Contributor

Choose a reason for hiding this comment

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

Work with designers and see if any of the Sass function parts can be replaced with the standard gray-100 etc. colors. This is the easiest and preferred way when designing themeable components.

Agreed, this would be my preferred option too — it would simplify the code and its readability too.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you expand a bit on what the ask is here? Is it changing out of the main color?

I like to think that we can reach a point where we have a set of system colors with their known contrast properties in light and dark mode (the grays), and then provide a single accent color to a component, and whatever mode it's in defines what colors get applied. That is, ideally I should never have to feed more than a single color along with the dark or light mode prop to a component, and it handles the rest itself. Is that useful?

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you expand a bit on what the ask is here? Is it changing out of the main color?

To be clear, I'm not asking for anything specific yet in this PR 🙂 We'll make follow-up PRs with more detail, suggest some alternatives, and ping the design team there for discussion.

As an overview of the problem though, we can no longer easily use Sass functions like this, which require the color to be predetermined:

color: rgba($white, 0.4);

☝️ This button's text color needs to be either white or black depending on the arbitrary accent color. But we can't use CSS variables as inputs to Sass functions. Things like rgba(var(--my-color), 0.4) are not possible.

color: lighten($gray-700, 5%);
background: lighten($gray-300, 5%);

background-image: linear-gradient(
-45deg,
darken($white, 2%) 33%,
darken($white, 12%) 33%,
darken($white, 12%) 70%,
darken($white, 2%) 70%
);

☝️ Similarly in these two examples, we can't do things like lighten(var(--gray-700), 5%).

the dark or light mode prop

I'm using the term "dark mode" for convenience, but we are currently working toward a more generic solution which allows consumers to pick their own background color. In theory this means any color, but in practice it means consumers should be able to choose their own shade of "dark" when doing "dark mode". An app may want #0a0a0a, another may want #1d1f21, etc.

@mirka mirka changed the title [WIP] Components: Try themeable background color Components: Add themeable background color Nov 9, 2022
@mirka mirka marked this pull request as ready for review November 9, 2022 22:51
@mirka mirka requested a review from ajitbohra as a code owner November 9, 2022 22:51
@mirka mirka requested review from chad1008, ciampo and brookewp November 9, 2022 22:52
@SaxonF
Copy link
Contributor

SaxonF commented Nov 21, 2022

This is really really cool @mirka!

I haven't had time to dive too deep into this but if you haven't already I'd recommend checking out how https://linear.app/ handles themes as they take a similar approach that works really well in practice. There is also https://hihayk.github.io/shaper/ which takes a single hue to generate background and foreground scales including dark mode. By default the grey scales it generates are desaturated.

It would be nice to work towards a point where we can turn a single accent colour into a wheel of functional scales (like Radix) including neutral/grey that the community can latch on to.

@SaxonF
Copy link
Contributor

SaxonF commented Nov 21, 2022

By the way, there is probably some learnings we can take from this work and apply to themes in future. e.g. generate standardised, functional colour scales that patterns can reference and theme authors can lean on.

@ciampo
Copy link
Contributor

ciampo commented Nov 21, 2022

Thank you for the links, @SaxonF ! Your input / feedback can be really valuable here :)

there is probably some learnings we can take from this work and apply to themes in future. e.g. generate standardised, functional colour scales that patterns can reference and theme authors can lean on.

Absolutely! Although let's keep in mind that the work that we're currently doing is aimed exclusively at the @wordpress/component package, and not to the whole Gutenberg app (and is still in a very early stage)

@mirka
Copy link
Member Author

mirka commented Nov 24, 2022

Thanks @SaxonF, I took a look at your links. I really liked Shaper, it's a great way to visualize how design system variables interact! The "Specs" mode and the naming scheme are pretty good references too. Shaper's color system seems quite cohesive and flexible, largely thanks to the saturation parameter. I hadn't considered using saturation as a key variable.

We are currently working toward a little bit more low-level flexibility (i.e. arbitrary background color support), but if it turns out that we do need the predictability of a dark/light "boolean" background, Shaper's approach could be a good fallback plan.

@mirka mirka requested a review from ciampo November 29, 2022 13:54
@mirka
Copy link
Member Author

mirka commented Nov 29, 2022

@ciampo This is ready for another 👀

Copy link
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.

Great, great job. The color algorithm section is well written and already looks great, especially given it's a first iteration! And I couldn't spot any regressions when manually testing the Button Storybook examples.

I left a few new minor comments and replied to some older ones, but we're very close from being able to land this PR.

(could you also add a CHANGELOG entry?)

I also went ahead and added a few more points to the tracking issue so that we don't lose track of all the possible directions discussed.

// Darkness of COLORS.gray[ 900 ], relative to #fff
const limit = 0.884;

const direction = colord( background ).isDark() ? 'lighten' : 'darken';
Copy link
Contributor

Choose a reason for hiding this comment

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

Currently, gray-100 could be the brightest or the darkest color in the scale of grays, depending on whether the background color is classified as "dark" by colord.

Could this cause confusion in the consumers of the theme? My experience as a developer has taught me that usually 100 is always associated to a brighter color, and 900 to a darker.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't have an alternative for that problem specifically. Though, I'm expecting that most usages won't be using these gray colors directly, but instead through more semantically named variables (e.g. border, lightBorder, secondaryText, etc).

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok. Let's get a feeling for it and see if we need to make any adjustments (at most we could add a line to our docs ?)

400: 0.2,
600: 0.42,
700: 0.543,
800: 0.821,
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, any reason why we don't generate a gray-900 color?

Copy link
Member Author

Choose a reason for hiding this comment

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

In the context of our color system, gray-900 is always the same as foreground. So it was redundant.

Copy link
Contributor

Choose a reason for hiding this comment

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

Are these opacity values? Just curious on how the hex colors are calculated. This is cool stuff.

Copy link
Member Author

Choose a reason for hiding this comment

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

These are "darkness" values, i.e. the inverse of the Lightness value in HSL.

gray-100 #f0f0f0 is hsl(0, 0%, 94%) (1 - 0.94 = 0.06, etc)
gray-200 #e0e0e0 is hsl(0, 0%, 88%) and so on...

That said, we might eventually switch from HSL to LCH for internal calculations so the lightness differences are a bit more reliable than HSL.

Copy link
Contributor

@jasmussen jasmussen Dec 5, 2022

Choose a reason for hiding this comment

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

Very cool, thank you! I like the sound of that, in the past I explored HSL for component theming, and the opportunities are pretty cool. That's not to say the approach I explored there is the right one — just that it's nice to be able to feed a single hue value, and have the rest refer to that.

Edit: Especially useful if it means we can retire light/dark versions of the spot color, so we have just a single spot color.

packages/components/src/theme/test/index.tsx Show resolved Hide resolved
@mirka
Copy link
Member Author

mirka commented Nov 30, 2022

Thanks @ciampo for all the collab here! I've added the final tweaks and a changelog entry.

@mirka mirka requested a review from ciampo November 30, 2022 14:41
Copy link
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.

Great job!

Let's land this PR and iterate 🚀

Let's also make sure that these APIs can't be used outside of the components package for now — i've added a point in #44116 about it.

@mirka mirka merged commit b82058c into trunk Nov 30, 2022
@mirka mirka deleted the try/theme-bg branch November 30, 2022 16:43
@github-actions github-actions bot added this to the Gutenberg 14.7 milestone Nov 30, 2022
@DaisyOlsen DaisyOlsen added the [Type] Enhancement A suggestion for improvement. label Nov 30, 2022
mpkelly pushed a commit to mpkelly/gutenberg that referenced this pull request Dec 7, 2022
* WIP

* Tweak theme presets

* Check default accent color

* Fix math

* Refactor

* Fix props passing

* Simplify background switcher

* Allow undefined values in validation

* Add unit tests

* Add description

* Test more shade generation

* Check for background colors with no good foreground colors

* Test using color variables

* Add story for seeing generated colors

* Fix typo

* Memoize

* Fixup

* Add more contrast validation

* Show issues in stories

* Add tests

* Update readme

* Update TODO comments

* Fixup

* Fixup test

* Add changelog

* Disable toolbar addon for Theme stories
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Components /packages/components [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants