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

Duotone: Make it possible to define duotone settings in theme.json #34073

Closed
wants to merge 16 commits into from

Conversation

scruffian
Copy link
Contributor

@scruffian scruffian commented Aug 13, 2021

Description

This allows users to apply a duotone filter to all image blocks. To make this possible, we need to output CSS variables and SVG filters for all the duotone filters in the theme.json file. Many of the changes in this PR are simply refactoring the duotone.php library into smaller reusable functions.

This is a fix for #33642

How has this been tested?

Screenshots

Top section - duotone applied directly to the image.
Bottom section - duotone applied by the theme.
Screenshot 2021-08-13 at 15 17 57

Types of changes

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).

@scruffian scruffian added the Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json label Aug 13, 2021
@scruffian scruffian self-assigned this Aug 13, 2021
$stylesheet = gutenberg_experimental_global_styles_get_stylesheet( $all );
if ( empty( $stylesheet ) ) {
return;
}

do_action( 'gutenberg_experimental_global_styles', $all );
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 action probably needs a better name.

Copy link
Member

Choose a reason for hiding this comment

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

We don't want to add specific filters for global styles. Can we use the existing filters for editor and front? Given that the intention is for this SVG to be embedded with the global stylesheet is makes sense that it's called directly by the theme json generator. Example of how we're doing this for other properties https://github.com/WordPress/gutenberg/pull/33812/files#diff-b03597cc3da199e5aa5a94950e8241135904853e7c3b82d758e42744878afae7R841

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 removed this and hooked directly to enqueue_block_assets instead. The problem is some of the code from gutenberg_experimental_global_styles_enqueue_assets is duplicated.

Copy link
Member

Choose a reason for hiding this comment

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

Can you explore how it'd look like to do this in the theme json generator instead?

We've already added there some rules for the block gap to work, perhaps in can serve of inspiration. I wonder if we can do a similar thing for duotone. Something along these lines:

  • while processing the block style nodes, we somehow collect the duotone filters in use
  • we add a new step that takes those duotone filters in use and create the necessary SVG

Alternatively, instead of enqueueing the duotones in use, we could enqueue all of them by inspecting the settings.color.duotones for core and theme.

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 did this in b95ebb6

@@ -16,13 +16,13 @@
*/
function gutenberg_experimental_global_styles_get_stylesheet( $tree, $type = 'all' ) {
// Check if we can use cached.
$can_use_cached = (
$can_use_cached = false; /*(
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 just for testing

@@ -83,7 +83,8 @@
},
"__experimentalBorder": {
"radius": true
}
},
"__experimentalSelector": ".wp-block-image img"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure if this is a good idea?

Copy link
Member

@oandregal oandregal Aug 17, 2021

Choose a reason for hiding this comment

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

Do the other block supports still work? If they don't, we'd need to implement "selectors per property" first, which we talked about at #28913

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 think the only one that would be affected would be border radius, which seems to still work fine.

Copy link
Member

Choose a reason for hiding this comment

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

This is problematic.

These are the testing steps:

  • Using the empty theme, set the border-radius for the image block to 0px in the theme.json
  • Create a post and add an image. Set its border-radius to any value.

I expected the image to change the border but it didn't. The theme style rule has higher specificity than the block's.

The border-radius rules were added in https://github.com/WordPress/gutenberg/pull/27667/files#r699061648 I'm going to pull @aaronrobertshaw thoughts on this. I'd think the fix for this would be to serialize the border-radius directly to the img element, using __experimentalSkipSerialization. Once we have fixed that in a separate PR, we could continue with this one.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the ping.

__experimentalSkipSerialization didn't exist yet when border-radius support was originally added to the image block. Now that it does, there's no reason we can't move the application of the border styles to the inner image element.

In fact, there is already an open PR that does this as part of adopting border color and width for the image block.

'path' => array( 'color', 'duotone' ),
'value_key' => 'slug',
'css_var_infix' => 'duotone',
'value_wrapper' => 'url(#wp-duotone-filter-$s)',
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 needed so that we can modify the output of value. The problem is how can we connect the CSS variable to the SVG filter in a way that doesn't require the user to understand what's going on under the hood.

if( ! empty( $theme_json_settings['color'] ) && ! empty( $theme_json_settings['color']['duotone'] ) && ! empty( $theme_json_settings['color']['duotone']['theme'] ) ) {
foreach( $theme_json_settings['color']['duotone']['theme'] as $duotone_setting ) {
$duotone_values = get_duotone_color_values( $duotone_setting['colors'] );
$duotone_id = 'wp-duotone-filter-' . $duotone_setting['slug'];
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 duplicating what's on lib/class-wp-theme-json-gutenberg.php line 188.

* @param array $block Block object.
* @return string Filtered block content.
*/
function gutenberg_render_duotone_support( $block_content, $block ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Github is confused. None of this code is new, it's just broken into smaller functions.

@ajlende
Copy link
Contributor

ajlende commented Aug 13, 2021

With the TT1 theme I get this error upon opening the duotone toolbar:

Uncaught TypeError: duotonePalette.map is not a function
    DuotonePicker duotone-picker.js:36
    React 54
    initializeEditor index.js:139
    _wpLoadBlockEditor post.php:2101
    domReady index.js:44
    _wpLoadBlockEditor post.php:2100
    <anonymous> post.php:2099
    <anonymous> post.php:2104

EDIT: Also still had the issue when I switched to skatepark on the branch from the description.

Seems like it can be fixed by adding 'color.duotone' to PATHS_WITH_MERGE in useSetting.

@oandregal
Copy link
Member

Took a look at this and this is what I see:

  • With this PR we add the following CSS/HTML for each duotone filter:
<style>
// CSS for each duotone filter in the global stylesheet.
:root { --wp--preset--duotone--blue-red: url(#wp-duotone-filter-blue-red); }
.has-blue-red-duotone { filter: var(--wp--preset--duotone--blue-red) !important; }
</style>

// SVG for each duotone filter in the footer.
<svg ><filter id="wp-duotone-filter-blue-red" /></svg>

// If the theme uses the duotone style in `theme.json`
.wp-block-image img { filter: var(--wp--preset--duotone--blue-red); }

(Enqueueing the SVG didn't work for me but that's what I understand this PR is trying to achieve.)

When a user interacts with duotone we do this instead:

  • Attach an auto-generated class to the specific block, such as .wp-duotone-filter-UUID.
  • Append the styles and the filter:
<style> .wp-duotone-filter-UUID img { filter: url( #wp-duotone-filter-611b7a6b4efc5 ); } <style>

<svg ><filter id="wp-duotone-filter-UUID" /></svg>

The theme-generated duotone and user-generated duotone work differently and I wonder if we can consolidate them into a single mechanism:

  • Themes: why do we need to use intermediate CSS Custom Properties? Can we make it so that themes do duotone: blue-red and that generates filter: url(#wp-duotone-filter-blue-red)? So we ship less CSS to the browser.

  • Users: using dynamic classes (.wp-duotone-filter-UUID) instead of per-preset (.wp-duotone-filter-blue-red) makes it so that using the same filter (blue-red) in two different images adds the styles and the SVG twice. This is: the amount of CSS/HTML shipped by duotone is linear, it grows with the content. I wonder if we can revisit this choice and use preset classes instead.

Note that we don't use the duotone classes output by this PR (has-blue-red-duotone). If we can use them in the user-generated presets that'd be great, otherwise, we shouldn't enqueue them.

@oandregal
Copy link
Member

I've struggled to test this with the PR provided (I don't know how to build the skatepark theme). It'd be great to provide easier instructions for testing in the PR. This is what I've done: I've used the empty theme and added this is its theme.json;

"styles": {
  "blocks": {
    "core/image": {
      "color": {
        "duotone": "var(--wp--preset--duotone--blue-red)"
      }
    }
  }
}

I've also experienced a weird thing:

  • In trunk, using empty theme, created a post with 3 images. I attached the same duotone preset to 2 of them (purple & yellow) and published the post. Everything works as expected in both the editor & front.
  • Switched to this branch.
  • The image that doesn't have the user-generated duotone is not visible, both in the editor and front. It seems that the SVG that this PR adds are not working.
  • One of the images that has the user-generated duotone is not visible in the editor either.

@ajlende
Copy link
Contributor

ajlende commented Aug 26, 2021

I was thinking about how we can change duotone to better fit how global styles currently are implemented so that we don't have to modify global styles as much to make this work.

First thing we could do is inline the SVG in the CSS so we don't have two different render steps. This would make duotone work a lot more like the colors/gradients.

Inlining the SVG could make duotone theme.json settings work exactly like the other settings with no modification. In the example below, we could grab the value_key as 'filter' and everything would probably work.

{
	"settings": {
		"color": {
			"duotone": [
				{
					"filter": "url('data:image/svg+xml,<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\"><defs><filter id=\"wp-duotone-filter-default-filter\"><feColorMatrix type=\"matrix\" values=\".299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 0 0 0 1 0\"></feColorMatrix><feComponentTransfer color-interpolation-filters=\"sRGB\"><feFuncR type=\"table\" tableValues=\"0 0.72549019607843\"></feFuncR><feFuncG type=\"table\" tableValues=\"0 0.9843137254902\"></feFuncG><feFuncB type=\"table\" tableValues=\"0 0.61176470588235\"></feFuncB></feComponentTransfer></filter></defs></svg>#wp-duotone-filter-default-filter')",
					"slug": "default-filter",
					"name": "Default filter"
				}
			]
		}
	}
}

However, this isn't very friendly to theme developers (and we already have another method of specifying duotone values as a list of colors). Having this conversion step from the list colors to the filter value seems like an unavoidable change we'll need to make in global styles. This could be done with a filter hook returning the computed value instead of using $preset[ $value_key ].

Since this seems like it would require the addition of a filter hook for global styles, it might be a dead end. But I figured it worth sharing in case it spurs any other ideas if we're still unsure about value_format and vsprintf.

@github-actions
Copy link

github-actions bot commented Aug 30, 2021

Size Change: +65 B (0%)

Total Size: 1.04 MB

Filename Size Change
build/block-editor/index.min.js 119 kB +52 B (0%)
build/block-library/index.min.js 150 kB +6 B (0%)
build/blocks/index.min.js 46.9 kB +7 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 931 B
build/admin-manifest/index.min.js 1.09 kB
build/annotations/index.min.js 2.7 kB
build/api-fetch/index.min.js 2.19 kB
build/autop/index.min.js 2.08 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.2 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/style-rtl.css 13.8 kB
build/block-editor/style.css 13.8 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 58 B
build/block-library/blocks/audio/editor.css 58 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 474 B
build/block-library/blocks/button/editor.css 474 B
build/block-library/blocks/button/style-rtl.css 600 B
build/block-library/blocks/button/style.css 600 B
build/block-library/blocks/buttons/editor-rtl.css 315 B
build/block-library/blocks/buttons/editor.css 315 B
build/block-library/blocks/buttons/style-rtl.css 370 B
build/block-library/blocks/buttons/style.css 370 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 194 B
build/block-library/blocks/columns/editor.css 193 B
build/block-library/blocks/columns/style-rtl.css 474 B
build/block-library/blocks/columns/style.css 475 B
build/block-library/blocks/cover/editor-rtl.css 666 B
build/block-library/blocks/cover/editor.css 670 B
build/block-library/blocks/cover/style-rtl.css 1.23 kB
build/block-library/blocks/cover/style.css 1.23 kB
build/block-library/blocks/embed/editor-rtl.css 488 B
build/block-library/blocks/embed/editor.css 488 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 879 B
build/block-library/blocks/gallery/editor.css 876 B
build/block-library/blocks/gallery/style-rtl.css 1.61 kB
build/block-library/blocks/gallery/style.css 1.61 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 70 B
build/block-library/blocks/group/theme.css 70 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/home-link/style-rtl.css 247 B
build/block-library/blocks/home-link/style.css 247 B
build/block-library/blocks/html/editor-rtl.css 283 B
build/block-library/blocks/html/editor.css 284 B
build/block-library/blocks/image/editor-rtl.css 728 B
build/block-library/blocks/image/editor.css 728 B
build/block-library/blocks/image/style-rtl.css 482 B
build/block-library/blocks/image/style.css 487 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B
build/block-library/blocks/latest-posts/editor.css 137 B
build/block-library/blocks/latest-posts/style-rtl.css 528 B
build/block-library/blocks/latest-posts/style.css 527 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 488 B
build/block-library/blocks/media-text/style.css 485 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 489 B
build/block-library/blocks/navigation-link/editor.css 488 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation/editor-rtl.css 1.72 kB
build/block-library/blocks/navigation/editor.css 1.72 kB
build/block-library/blocks/navigation/style-rtl.css 1.42 kB
build/block-library/blocks/navigation/style.css 1.41 kB
build/block-library/blocks/navigation/view.min.js 2.52 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 310 B
build/block-library/blocks/page-list/editor.css 310 B
build/block-library/blocks/page-list/style-rtl.css 241 B
build/block-library/blocks/page-list/style.css 241 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 261 B
build/block-library/blocks/paragraph/style.css 261 B
build/block-library/blocks/post-author/editor-rtl.css 210 B
build/block-library/blocks/post-author/editor.css 210 B
build/block-library/blocks/post-author/style-rtl.css 182 B
build/block-library/blocks/post-author/style.css 181 B
build/block-library/blocks/post-comments-form/style-rtl.css 140 B
build/block-library/blocks/post-comments-form/style.css 140 B
build/block-library/blocks/post-comments/style-rtl.css 360 B
build/block-library/blocks/post-comments/style.css 359 B
build/block-library/blocks/post-content/editor-rtl.css 138 B
build/block-library/blocks/post-content/editor.css 138 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 398 B
build/block-library/blocks/post-featured-image/editor.css 398 B
build/block-library/blocks/post-featured-image/style-rtl.css 143 B
build/block-library/blocks/post-featured-image/style.css 143 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 378 B
build/block-library/blocks/post-template/style.css 379 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 60 B
build/block-library/blocks/post-title/style.css 60 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 378 B
build/block-library/blocks/pullquote/style.css 378 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 270 B
build/block-library/blocks/query-pagination/editor.css 262 B
build/block-library/blocks/query-pagination/style-rtl.css 168 B
build/block-library/blocks/query-pagination/style.css 168 B
build/block-library/blocks/query-title/editor-rtl.css 85 B
build/block-library/blocks/query-title/editor.css 85 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 187 B
build/block-library/blocks/quote/style.css 187 B
build/block-library/blocks/quote/theme-rtl.css 220 B
build/block-library/blocks/quote/theme.css 222 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 374 B
build/block-library/blocks/search/style.css 375 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 250 B
build/block-library/blocks/separator/style.css 250 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 462 B
build/block-library/blocks/site-logo/editor.css 464 B
build/block-library/blocks/site-logo/style-rtl.css 153 B
build/block-library/blocks/site-logo/style.css 153 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 165 B
build/block-library/blocks/social-link/editor.css 165 B
build/block-library/blocks/social-links/editor-rtl.css 812 B
build/block-library/blocks/social-links/editor.css 811 B
build/block-library/blocks/social-links/style-rtl.css 1.33 kB
build/block-library/blocks/social-links/style.css 1.33 kB
build/block-library/blocks/spacer/editor-rtl.css 307 B
build/block-library/blocks/spacer/editor.css 307 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 146 B
build/block-library/blocks/tag-cloud/style.css 146 B
build/block-library/blocks/template-part/editor-rtl.css 636 B
build/block-library/blocks/template-part/editor.css 635 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/term-description/editor-rtl.css 90 B
build/block-library/blocks/term-description/editor.css 90 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 1.29 kB
build/block-library/common.css 1.29 kB
build/block-library/editor-rtl.css 9.93 kB
build/block-library/editor.css 9.92 kB
build/block-library/reset-rtl.css 527 B
build/block-library/reset.css 527 B
build/block-library/style-rtl.css 10.6 kB
build/block-library/style.css 10.6 kB
build/block-library/theme-rtl.css 658 B
build/block-library/theme.css 663 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/components/index.min.js 209 kB
build/components/style-rtl.css 15.8 kB
build/components/style.css 15.8 kB
build/compose/index.min.js 10.2 kB
build/core-data/index.min.js 12.4 kB
build/customize-widgets/index.min.js 11.1 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 614 B
build/data/index.min.js 7.1 kB
build/date/index.min.js 31.5 kB
build/deprecated/index.min.js 428 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.53 kB
build/edit-navigation/index.min.js 13.6 kB
build/edit-navigation/style-rtl.css 3.14 kB
build/edit-navigation/style.css 3.14 kB
build/edit-post/classic-rtl.css 492 B
build/edit-post/classic.css 494 B
build/edit-post/index.min.js 28.9 kB
build/edit-post/style-rtl.css 7.2 kB
build/edit-post/style.css 7.19 kB
build/edit-site/index.min.js 26.2 kB
build/edit-site/style-rtl.css 5.07 kB
build/edit-site/style.css 5.07 kB
build/edit-widgets/index.min.js 16 kB
build/edit-widgets/style-rtl.css 4.06 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 37.6 kB
build/editor/style-rtl.css 3.74 kB
build/editor/style.css 3.73 kB
build/element/index.min.js 3.17 kB
build/escape-html/index.min.js 517 B
build/format-library/index.min.js 5.36 kB
build/format-library/style-rtl.css 668 B
build/format-library/style.css 669 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.6 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.49 kB
build/keycodes/index.min.js 1.25 kB
build/list-reusable-blocks/index.min.js 1.85 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.88 kB
build/notices/index.min.js 845 B
build/nux/index.min.js 2.03 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.83 kB
build/primitives/index.min.js 921 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 B
build/redux-routine/index.min.js 2.63 kB
build/reusable-blocks/index.min.js 2.28 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.6 kB
build/server-side-render/index.min.js 1.32 kB
build/shortcode/index.min.js 1.48 kB
build/token-list/index.min.js 562 B
build/url/index.min.js 1.74 kB
build/viewport/index.min.js 1.02 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 6.37 kB
build/widgets/style-rtl.css 1.05 kB
build/widgets/style.css 1.05 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@scruffian
Copy link
Contributor Author

Uncaught TypeError: duotonePalette.map is not a function

Fixed!

@scruffian
Copy link
Contributor Author

Users: using dynamic classes (.wp-duotone-filter-UUID) instead of per-preset (.wp-duotone-filter-blue-red) makes it so that using the same filter (blue-red) in two different images adds the styles and the SVG twice. This is: the amount of CSS/HTML shipped by duotone is linear, it grows with the content. I wonder if we can revisit this choice and use preset classes instead.

Yes we definitely should do this. This feels like more of a follow up task to this PR which is already quite big.

@scruffian
Copy link
Contributor Author

Themes: why do we need to use intermediate CSS Custom Properties? Can we make it so that themes do duotone: blue-red and that generates filter: url(#wp-duotone-filter-blue-red)? So we ship less CSS to the browser.

The reason for this is that I was following precedent - when we reference colors in theme.json we always reference CSS variables which are defined elsewhere in the theme.json rather than a slug, for example. This level of decoupling might be useful, but I don't feel strongly about it.

@scruffian
Copy link
Contributor Author

I don't know how to build the skatepark theme

If you check out https://github.com/Automattic/themes/pull/4406/files there should be nothing to build.

Comment on lines 52 to 53
const PATHS_WITH_MERGE = {
'color.duotone': true,
Copy link
Contributor

Choose a reason for hiding this comment

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

When I was searching through the code, I found PATHS_WITH_MERGE in one other place. Not sure why it's in both places, but we can probably add it there too to be safe.

Copy link
Member

Choose a reason for hiding this comment

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

@scruffian
Copy link
Contributor Author

The filter is not loading in the editor when we add a new image to a post. The image is there but the duotone dropdown is not showing options either

I fixed this in d0ffc54 but the problem is that it doesn't get matched to a preset:

Screenshot 2021-09-02 at 21 56 35

Really what we want is for the duotone control to be aware that the theme is setting a filter... This needs more work...

@oandregal
Copy link
Member

Should a block be able to define the duotone colors as an array too?

I'm not really sure about this. So far we don't do any processing with any of the values themes provide via theme.json, they're just the value to output in the CSS. If we do something like this in the future, we'd need to consider how something like that can work for any other properties as well.

@oandregal
Copy link
Member

The duotone filter a theme sets won't be visible in the duotone control until #34178 lands. When it does, we can update the duotone control to take the theme data from the theme.json. That shouldn't block this from landing 🙂

it's important that we make sure that the user can "uncheck" the filter that we define at the theme.json level if they don't want it on a particular image for example.

I wonder if we can update the duotone control to have a value that is "clear duotone" and inlines filter: none.

cc @ajlende for thoughts and awareness.

@MaggieCabrera
Copy link
Contributor

I wonder if we can update the duotone control to have a value that is "clear duotone" and inlines filter: none.

cc @ajlende for thoughts and awareness.

That sounds like a good idea

@ajlende
Copy link
Contributor

ajlende commented Sep 3, 2021

I wonder if we can update the duotone control to have a value that is "clear duotone" and inlines filter: none.

Yeah, that seems like the best move for now.

This is too far out for this PR, but I've also been thinking about how multiple filters could interact. The filter CSS property is a list, so if we thought about it that way, we'd need to do more than just inline a filter: none—we'd have to remove the duotone filter instead which will be a bit more complicated when we get there.

@jasmussen
Copy link
Contributor

Correct me if I'm wrong, but wouldn't the filter: none; solution just mean two filters are applied, the initial one and a second one to unset it? It seems like a hack. Would it need deprecations if we find a better solution down the road?

@ajlende
Copy link
Contributor

ajlende commented Sep 3, 2021

Correct me if I'm wrong, but wouldn't the filter: none; solution just mean two filters are applied, the initial one and a second one to unset it? It seems like a hack.

We're trying to allow themes to set default filters for blocks (Automattic/themes#4406), so some CSS gets generated for our presets.

.wp-block-cover {
	filter: url(#wp-duotone-red-filter);
}

We want to allow someone to clear the duotone filter even when the default is to have a filter applied, so we have to use filter: none to override the new default behavior.

@jasmussen
Copy link
Contributor

No, I understand, but it seems like clearing a duotone filter should clear it fully, and not just override-to-none. It's not a strong opinion and I'll defer. I was hoping for some theme.json magic where the default is set there, and then unset on a per-block basis.

@ajlende
Copy link
Contributor

ajlende commented Sep 3, 2021

There's a difference between hitting the clear button which would reset to the default filter and having a "swatch" that unsets the duotone filter. Maybe I still don't follow?

@jasmussen
Copy link
Contributor

It's also very possible I'm missing nuance. Maybe not the best comparison, but as an example I could imagine a group where a default margin of 10px has been set by the theme, and I then select that group in my post and set the margin to 0. In the rendered markup, I would then expect it to say someting along the lines of style="margin: 0px;", not style="margin: 10px; margin: 0px;.

@ajlende
Copy link
Contributor

ajlende commented Sep 3, 2021

The default styles are written to a stylesheet, not the inline style attribute, so it's more like saying

<style>
.wp-block-cover {
	filter: url(#wp-duotone-red-filter);
}
</style>

<style>
.wp-block-cover.wp-duotone-none {
	filter: none;
}
</style>

@jasmussen
Copy link
Contributor

Thanks for the clarification. I'll trust you all on this one 👍

@scruffian
Copy link
Contributor Author

I made it possible to "disable" a duotone filter that comes from theme.json:

Screenshot 2021-09-03 at 22 22 05

It probably need some polish but it works at least :)

@jasmussen
Copy link
Contributor

It probably need some polish but it works at least :)

Based on the global styles work by @pablohoneyhoney, can we use the following disabled and active style instead?

Screenshot 2021-09-06 at 12 04 58

Here, the dark black and white preset is selected, but the first option in the preset row is a "none".

@scruffian
Copy link
Contributor Author

Great idea, thanks @jasmussen. I've added this:

Screenshot 2021-09-07 at 12 43 43

Screenshot 2021-09-07 at 12 43 38

aria-label={ __( 'Disable duotone' ) }
tooltipText={ __( 'Disable duotone' ) }
style={ {
background: '#FFF url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\'><path d=\'M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zM3 12c0-5 4-9 9-9 2.2 0 4.3.8 5.8 2.2L5.2 17.8C3.8 16.3 3 14.2 3 12zm9 9c-2.4 0-4.5-.9-6.2-2.4L18.6 5.8C20.1 7.5 21 9.6 21 12c0 5-4 9-9 9z\' fill-rule=\'evenodd\' clip-rule=\'evenodd\' /></svg>" )',
Copy link
Contributor

Choose a reason for hiding this comment

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

We'll likely want to extract this one and make it either a reusable component to be used by the Global Styles system (whose mockups the icon came from), or put it in the Icon library and publish it with the others, even though it doesn't specifically match the icon grid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I think that will require quite a significant reworking of how this component works though :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with @jasmussen here. I can see this added as a special option of CircularOptionPicker. It would be useful for other components that use the picker like the regular gradient and color pickers.

As far as I'm aware, right now there isn't a way to unset a gradient or color background either (on the cover block, for example). So having an unset value doesn't seem essential to me for this PR, and may be something worth moving into a follow-up PR instead of this one. There we could discuss a unified way that will work for those other cases as well without holding this PR up.

@jasmussen
Copy link
Contributor

Nice work, thanks for trying that. The icon does highlight that the checkmark overlay to indicate selected swatch is problematic (I feel like I've seen a separate ticket for problems with that check as well). Should we try adopting the new active-swatch style as well? This one:

Screenshot 2021-09-07 at 13 57 43

That's a 1.5px outset $gray-900 box-shadow.

The "none" icon should be $gray-600.

@ajlende
Copy link
Contributor

ajlende commented Sep 8, 2021

I opened a new PR #34667 that scopes things down to just rendering SVGs and creating block classes for duotone. It changes how styles selectors are generated for duotone filters and seems like a good first step from which we can open follow-up PRs for the additional things.

@ajlende
Copy link
Contributor

ajlende commented Dec 10, 2021

With #34667 merged, I think this can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants