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

Add: API to allow blocks to access global styles. #34178

Closed

Conversation

jorgefilipecosta
Copy link
Member

This PR implements an experimental API that allows a block to know if a global style is being applied to it:
E.g:

const backgroundColor = useStyle( 'color.background' );
const lineHeight = useStyle( 'typography.lineHeight' );

This mechanism takes into account CSS variables. If a theme uses a custom CSS variable or a preset CSS variable the value of the variable is returned.

This mechanism is useful for the mobile APP as we can more easily apply the styles to a block that comes from theme.json cc: @hypest.

It is also useful for cases where when applying a local style we need context if there are global styles or not. E.g: when applying a border width we need to know if a global border style exists if not we apply a solid border style so the border width makes sense if a style already exists we leave what the theme defined. cc: @aaronrobertshaw, @mtias.

It will also allow the UI to properly reflect the styles of a block. Right now, I already did an improvement for testing purposes. The Line height placeholder reflects the true line-height value applied using theme.json. So if theme.json applies a 2 line-height we show 2 instead of the default 1.5.

This PR is still very simple and does not implement inheritance. Inheritance is complex and I guess we should see how far we go without it.

How has this been tested?

I verified on the site editor that I can still apply preset styles e.g: colors. And when I change the preset the styles relying on that preset also change. (existing edit site variable resolution still works).
I added the following data as theme.json styles:

			"core/paragraph": {
				"typography": {
					"lineHeight": "2"
				}
			}

I added a paragraph on the block editor and verified the paragraph line-height appeared with two as a placeholder.

I added the following data as theme.json styles:

			"core/paragraph": {
				"typography": {
					"lineHeight": "var(--wp--custom--line-height--test)"
				}
			}

I added a paragraph on the block editor and verified the paragraph line-height appeared with two as a placeholder.

I added the following custom variable to the settings of theme.json:

		"custom": {
			"line-height": {
				"test": 3
			},

I added the following data as theme.json styles:

			"core/paragraph": {
				"typography": {
					"lineHeight": "var(--wp--custom--line-height--test)"
				}
			}

I added a paragraph on the block editor and verified the paragraph line height appeared with 3 as a placeholder.

@jorgefilipecosta jorgefilipecosta added [Feature] Block API API that allows to express the block paradigm. Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Aug 19, 2021
@github-actions
Copy link

github-actions bot commented Aug 19, 2021

Size Change: -35 B (0%)

Total Size: 1.04 MB

Filename Size Change
build/block-editor/index.min.js 119 kB +614 B (+1%)
build/block-editor/style-rtl.css 13.8 kB -23 B (0%)
build/block-editor/style.css 13.8 kB -23 B (0%)
build/block-library/index.min.js 150 kB -7 B (0%)
build/blocks/index.min.js 47 kB -24 B (0%)
build/components/style-rtl.css 15.8 kB -10 B (0%)
build/components/style.css 15.8 kB -8 B (0%)
build/compose/index.min.js 10.2 kB +69 B (+1%)
build/core-data/index.min.js 12.4 kB -90 B (-1%)
build/edit-site/index.min.js 25.7 kB -544 B (-2%)
build/editor/index.min.js 37.6 kB +3 B (0%)
build/i18n/index.min.js 3.6 kB +8 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-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 605 B
build/block-library/blocks/button/style.css 604 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 400 B
build/block-library/blocks/embed/style.css 400 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 76 B
build/block-library/blocks/heading/style.css 76 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 63 B
build/block-library/blocks/list/style.css 63 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.7 kB
build/block-library/blocks/navigation/editor.css 1.71 kB
build/block-library/blocks/navigation/style-rtl.css 1.46 kB
build/block-library/blocks/navigation/style.css 1.46 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 248 B
build/block-library/blocks/paragraph/style.css 248 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 361 B
build/block-library/blocks/pullquote/style.css 360 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 169 B
build/block-library/blocks/quote/style.css 169 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.92 kB
build/block-library/editor.css 9.9 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/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/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/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/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

@aaronrobertshaw
Copy link
Contributor

cc/ @ramonjd your explorations in #34156 might mean you'll be interested in reviewing this PR as well.

if ( 'mobile' === $context ) {
$settings['__experimentalStyles'] = $consolidated->get_raw_data()['styles'];
}
$settings['__experimentalStyles'] = $consolidated->get_raw_data()['styles'];
Copy link
Member

Choose a reason for hiding this comment

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

Asking for my own benefit here :)

I was wondering, is there a use case for where we'd want to access __experimentalStyles in the site editor, or in other words, do any templates in the site editor need to know about user styles?

Or would it be okay to limit adding this object to editor/widget contexts?

Copy link
Member

Choose a reason for hiding this comment

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

Can the __experimentalStyles data be limited to the mobile and post-editor contexts? Perhaps also in the widgets editor if it uses the existing block-editor hooks (such as line-height), but I'm not sure how that works. The site-editor already has access to this data, so it wouldn't need it.

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 was wondering, is there a use case for where we'd want to access __experimentalStyles in the site editor

Yes on the site editor blocks still need to access the __experimentalStyles flag, as the hooks like line-height also run there. But as @oandregal said on the site editor we already have this information so we don't need to pass it again, I'm going to update the code. The setting will be available anyway on the block editor it will just be dynamically computed.

@@ -70,7 +74,7 @@ export default function LineHeightControl( { value: lineHeight, onChange } ) {
onKeyDown={ handleOnKeyDown }
onChange={ handleOnChange }
label={ __( 'Line height' ) }
placeholder={ BASE_DEFAULT_VALUE }
placeholder={ placeholder }
Copy link
Member

Choose a reason for hiding this comment

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

I like this way of doing things. ❤️ Having the default value as the placeholder works I think as I can still set numerical values to 0 for example, and the native appearance (greyed out) indicates that it's a default value.

Just noting a couple of things down, all of which are probably best for follow ups if this gets off the ground.

  • We'll have to parse unit values (px, vh etc) from the default values and reset them in the controls where units change
  • I tested a few controls, and I think there will be some work to ensure we can pass default values as placeholders to the rest of our controls hooks. For example, box-control will require a tweak to handle placeholders for top/right/bottom/left inputs. This is for spacing controls such as margin and padding. But anything importing <UnitControl /> directly such as border-width should just work 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point regarding the units @ramonjd. I guess we can deal with units a follow-up to avoid growing this PR.

@ramonjd
Copy link
Member

ramonjd commented Aug 20, 2021

Thank you for working on this feature, and I learned a lot by reading the code. It came right as we were discussing whether it would be good idea too (which I think it is!).

I tested according to test instructions, plus added defaults for various block controls hooks and all seem to work as expected, with css vars being parsed correctly.

I'm happy to help look at ensuring placeholders work for our controls as well if required.

Looking forward to the updates on this one! 🙇

@hypest
Copy link
Contributor

hypest commented Aug 24, 2021

This mechanism is useful for the mobile APP as we can more easily apply the styles to a block that comes from theme.json cc: @hypest.

Thanks for the ping Jorge! I've given the headsup to the mobile folks working closer to the GSS 👍 (cc @geriux , @enejb ).

@oandregal
Copy link
Member

While testing this I've missed the ability to reset the user value to the theme value in the line-height control so filed at issue for it at #34260

const setting = useSelect(
( select ) => {
const settings = select( blockEditorStore ).getSettings();
const settingsForBlock = get( settings, [
Copy link
Member

Choose a reason for hiding this comment

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

mmm, was looking at what sort of data this was using. Some braindump as to how / why inheritance would increase the complexity to take into account:

  • Some CSS properties are inherited, some other don't.
  • A block can be top-level but also can be nested within other blocks: to determine the value we'd need to traverse up the tree and consolidate all values of the chain.
  • CSS custom properties: if the theme uses them, this breaks the CSS inheritance model for the property.

I agree this PR should be limited to only take data from the specific block.

if ( ! variable || ! isString( variable ) ) {
return variable;
}
const INTERNAL_REFERENCE_PREFIX = 'var:';
Copy link
Member

Choose a reason for hiding this comment

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

What do you think of using explicit names to document where this data comes from? I'm thinking of something along these lines:

const USER_VALUE_PREFIX = 'var:';
const THEME_VALUE_PREFIX = 'var(--wp--';
const THEME_VALUE_SUFFIX = ')';

Copy link
Member

Choose a reason for hiding this comment

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

What do you think of substituting every use of context by blockName? We no longer use context anywhere, so I'd think it's more familiar for readers to follow along with blockName (our future selves included 😅 ).

return getResolvedStyleVariable( features, blockName, result );
}

export function getResolvedStyleVariable( features, context, variable ) {
Copy link
Member

@oandregal oandregal Aug 24, 2021

Choose a reason for hiding this comment

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

It wasn't clear to me what this function was for based on its name. What alternatives do we have to improve this? What about something along the lines of getValueFromStyle? It sits well with the other helper functions getValueFromPresetVariable, getValueFromCustomVariable

Copy link
Member

Choose a reason for hiding this comment

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

I've noticed that before moving it here it was called getValueFromVariable, that name also works for me.

features,
context,
presetPath,
presetProperty,
Copy link
Member

Choose a reason for hiding this comment

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

How about naming these two presetPropertyName, presetPropertyValue to communicate what they are?

Copy link
Member

Choose a reason for hiding this comment

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

It seems the role of findInPresetsBy is to find the preset object whose presetPropertyName matches the presetPropertyValue among all the available.

The complexity here is that it needs to take into account that 1) there may be a block and a global preset and 2) any of those may have core, theme, and user presets. This is the full list of candidate presets available, sorted by priority:

  1. block preset from user
  2. block preset from theme
  3. block preset from core
  4. global preset from user
  5. global preset from theme
  6. global preset from core

My understanding is that we should return the first candidate whose presetPropertyName matches presetPropertyValue. Wouldn't that be enough? I've looked at the PR that introduced this function #33149 and I don't understand why we need the recursion when the property to look up is not the slug.

Copy link
Member

Choose a reason for hiding this comment

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

I've updated in trunk the implementation of this function to this algorithm:

  1. Create a list of the available presets, sorted by priority.
  2. Return the first preset.

And it works as described at #33149

Code, for reference:

function findInPresetsBy(
	styles,
	blockName,
	presetPath,
	presetPropertyName,
	presetPropertyValue
) {
	const candidates = [];
	const origins = [ 'user', 'theme', 'user' ];

	const blockPresets = get( styles, [
		'settings',
		'blocks',
		blockName,
		...presetPath,
	] );
	origins.forEach( ( origin ) => {
		if ( blockPresets?.[ origin ] ) {
			blockPresets[ origin ].forEach( ( preset ) => {
				if ( preset[ presetPropertyName ] === presetPropertyValue ) {
					candidates.push( preset );
				}
			} );
		}
	} );

	const globalPresets = get( styles, [ 'settings', ...presetPath ] );
	origins.forEach( ( origin ) => {
		if ( globalPresets?.[ origin ] ) {
			globalPresets[ origin ].forEach( ( preset ) => {
				if ( preset[ presetPropertyName ] === presetPropertyValue ) {
					candidates.push( preset );
				}
			} );
		}
	} );

	return candidates.length >= 1 ? candidates[ 0 ] : undefined;
}

Copy link
Member Author

@jorgefilipecosta jorgefilipecosta Aug 31, 2021

Choose a reason for hiding this comment

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

Hi @oandregal,

My understanding is that we should return the first candidate whose presetPropertyName matches presetPropertyValue. Wouldn't that be enough?

I don't think it is enough.
Imagining user theme.json defines presets:

{
	color: "#000"
	slug: "black",
	name: "Black"
}

And theme defines:

{
	color: "#001"
	slug: "black",
	name: "Black"
}

If we search the color property value of "#1" without the recursion we would return the theme preset, but we should not return it because the variable was overwritten and now there is no variable with color "#1".
The recursion makes sure that when we find a preset, there is no other higher priority preset with the same slug and different property because if there is the preset should be ignored.

Copy link
Member

Choose a reason for hiding this comment

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

Nice one 👍 I've pushed some tests in c78a322 to make sure this behavior is documented and retained.

return variable;
}

export function getPresetVariableRepresentingAValue(
Copy link
Member

@oandregal oandregal Aug 24, 2021

Choose a reason for hiding this comment

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

More naming nitpicks 😅 Before moving it here, it was getPresetVariable. If we want to give it more context perhaps it can be getPresetVariableFromValue, which is also symmetrical to the other exported function in this file.

jorgefilipecosta and others added 4 commits August 31, 2021 17:29
@jorgefilipecosta jorgefilipecosta force-pushed the add/api-to-expose-global-styles-to-blocks branch from 7cb9f0c to 6773622 Compare August 31, 2021 17:25
@jorgefilipecosta
Copy link
Member Author

Hi @ramonjd, @oandregal, thank you for the reviews! Your feedback was applied/answred. Let me know if there are other possible improvements or if this is ready to ship.

@scruffian
Copy link
Contributor

What do you think of this PR which is attempting to do something similar? #41696

@TimothyBJacobs TimothyBJacobs removed their request for review June 22, 2022 16:39
@gziolo
Copy link
Member

gziolo commented Jul 11, 2022

What do you think of this PR which is attempting to do something similar? #41696

@jorgefilipecosta, is this PR something that is still necessary?

@tellthemachines
Copy link
Contributor

What do you think of this PR which is attempting to do something similar? #41696

@jorgefilipecosta, is this PR something that is still necessary?

We still need this PR or something like it in order to access global style values for specific blocks in the post editor. An important use case for this is reflecting current state in block controls. If a block type has padding set globally, and also has a padding control that allows setting custom values for specific blocks, it would make sense for that padding control to be set initially to whatever the global value is. This has been discussed a fair bit in #42173.

#41696 doesn't solve this problem; it only allows us to set global values to other global values in theme.json.

@jorgefilipecosta
Copy link
Member Author

When I try setting the line height of a paragraph to a custom variable, the placeholder looks like this: Screenshot 2021-09-03 at 12 27 03

Probably some issue during a rebase. If we want to review this PR, I can fix this.

What do you think of this PR which is attempting to do something similar? #41696

That PR makes sense it is something that affects just the engine. In this one we try to make the block inspector reflect what styles are applied to a block which right now is impossible. A block may have a very huge font size applied from global styles the user wants to decrease it a little on a specific case, but does not even knows what is the actual font size to begin with.

We still need this PR or something like it in order to access global style values for specific blocks in the post editor. An important use case for this is reflecting current state in block controls.

Exactly I still think reflecting the styles on the block inspector is something we want to do.

@tellthemachines
Copy link
Contributor

Probably some issue during a rebase. If we want to review this PR, I can fix this.

Thanks @jorgefilipecosta, I'm happy to help review if you'd like to resume work on this!

@tellthemachines
Copy link
Contributor

This branch is full of conflicts, so I'll get started copying over the changes to a new branch as that'll be easier 😅

@jorgefilipecosta
Copy link
Member Author

Closing this PR as a new branch will be started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block API API that allows to express the block paradigm. Framework Issues related to broader framework topics, especially as it relates to javascript 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.

10 participants