Closed oandregal closed 3 years ago
I've started working on this as per https://github.com/WordPress/gutenberg/pull/29142 Also added an initial list of tasks to implement.
@mkaz @jasmussen I think you were involved in the social links block. Wanted to give you a heads-up that I've started to work on this issue and I'm targeting the colors of the social links block as a demo for this, so expect some PRs for that block soon.
I'd be very happy to review that! Awesome.
Landed #29142 (to skip serialization) and #29155 is ready for review (take labels for controls from block supports).
Using __experimentalSelector
as the mechanism for determining which child block the supports should apply to might be a bit limiting. For example, in Social Links we want to apply the colors to the child block, but the alignment would apply to the parent block. What do you think about declaring a selector per supports e.g:
"supports": {
"align": [
"left",
"center",
"right"
],
"anchor": true,
"color": {
"background": true,
"__experimentalSkipSerialization": true,
"__experimentalSelector": ".wp-social-link"
},
"font-family: {
"__experimentalSelector": ".wp-social-link a"
}
}
@scruffian yes! That's what I meant with: There are cases in which block selectors will need to be bounded to the support properties instead of bounded to the block, given that they may apply to different inner elements. :sweat_smile: Happy you all were thinking along the same lines. I've already started working on this so expect to have something in your review queues in the coming days.
Update on this task: __skipSerialization
is now deployed to the buttons block and the color hook. The core of the task is done, although there are related tasks to complete (see "misc" and "fixing specificity" sections).
I added an initial list of blocks that could benefit from this and also the hooks for which __skipSerialization
remains to be implemented. cc @aaronrobertshaw @apeatling @aristath @scruffian as you've worked in this area and have related PRs for this, in case you can spare some time to help to implement the rest of the hooks and blocks.
My next step is to fix https://github.com/WordPress/gutenberg/issues/29381
I've updated the issue with the ongoing tasks and their owners. Please, feel free to add yourself/edit/etc as things evolve (also leaving a comment so subscribers of the task know there are changes).
@ockham has landed https://github.com/WordPress/gutenberg/pull/30035 (skip serialization for border)
There's two ongoing PRs to use skip serialization for border: search block by @aaronrobertshaw #30227 and button block https://github.com/WordPress/gutenberg/pull/30194 by @ockham
Labels for UI controls: closed https://github.com/WordPress/gutenberg/pull/29155#issuecomment-806583346 in favor of https://github.com/WordPress/gutenberg/pull/30075
Re-sharing a comment on https://github.com/WordPress/gutenberg/pull/30879#pullrequestreview-641302448 here for better visibility as this issue seems to include other support mechanism changes:
Our block.json supports API right now has inconsistencies in how we handle typography vs colors:
"color": {
"gradients": true,
"link": true
},
"fontSize": true,
"lineHeight": true,
It is also inconsistent with theme.json given that there we have:
"typography": {
"fontSize": "value",
"lineHeight": "value",
}
I guess we can change the shape of block.json and be back-compatible. We can have a back-compatibility layer that checks if things like fontSize and lineHeight are present in the data structure and if yes nests them under typography. Our code excluding the back-compatibility layer would only rely on the new structure. The shape change would be done in another PR. I'm not sure if a change like this would require a new "apiVersion", I guess it is something minor that does not requires it, but I'm cc'ing @gziolo in case he has some thoughts.
Re-sharing from https://github.com/WordPress/gutenberg/pull/30879#issuecomment-824615316 my response to the question from @jorgefilipecosta:
The shape change would be done in another PR. I'm not sure if a change like this would require a new "apiVersion", I guess it is something minor that does not requires it, but I'm cc'ing @gziolo in case he has some thoughts.
It's already documented at https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/, but it would be good to validate whether it was released in the previous major version of WordPress. If not then we can simply change it and keep the backward compatibility layer only in the plugin for a few more releases.
In general, the question goes to @oandregal how much supports
in block.json
should align with theme.json
as it doesn't necessarily translate one to one. Conceptually, I would be in favor of using the same naming and grouping in both places to make it consistent. If they are also grouped in the UI in the same way, then it adds another reason to make the extra efforts to bring harmony how all that fits together.
Concluding, if this is only a simple mapping layer that would have to map some properties from their deprecated names, then we should definitely go for it. In the documentation, we should simply remove old variants in favor of the refined approach.
I think we should either group those things together as in theme.json or have them all unnested (do not have the color
intermediate key) ― the in-between state we have now is confusing. For context https://github.com/WordPress/gutenberg/issues/22887 https://github.com/WordPress/gutenberg/pull/24320
A question I have (that's why I'm posting here instead of in the font-size PR) is whether __experimentalSkipSerialization
should be a top-level key of supports
and not having one per "area" (color, typography). This is: whether a block opts out from serialization entirely of per property. Per property is more flexible but I'm curious about what people think about doing it per block and so avoiding all those skip flags everywhere ― case in point: the button
block is the first that has support for many properties and needs to skip serialization and, as a result, what happens is that it needs to use that flag in multiple places.
I think we should either group those things together as in theme.json or have them all unnested
I tend to prefer the idea of grouping theme together as per theme.json. If nothing else it's neater and allows opting into a set of features via a single support flag e.g. "__experimentalBorder": true
.
A question I have (that's why I'm posting here instead of in the font-size PR) is whether __experimentalSkipSerialization should be a top-level key of supports and not having one per "area" (color, typography).
Skipping serialization per "feature set" or "area" would get my vote.
As more blocks adopt the various block support features, I think the extra flexibility will pay off. It will cut down on the manual retrieval and application of classes and styles. In a lot of cases, applying the block classes and styles on the wrapper combined with a CSS style to inherit values if needed, gets the job done cleanly. That leaves only the cases that truly need to skip serialization to manually apply things to the inner elements.
If the idea is to reduce the number of flags in the config in certain cases, could we get the best of both worlds by supporting a top level __experimentalSkipAllSerialization
flag in addition to the "per property" ones?
In a block that wants to skip all serialization it is one simple flag. For one that needs to keep its border styles on the wrapper element but apply colors selectively to an inner element, it can skip the colors serialization and manage only those manually.
The initial switch to block support colors for the Table block has been merged and a follow up issue created to track the requested iterations
Skipping serialization per "feature set" or "area" would get my vote.
Yes, I think serialization per area is a good tradeoff in what it allows to do and the effort required to disable each serialization.
I'm not sure if experimentalSkipSerialization is the right name for the flag that disables the output of the styles. On server-side rendered blocks, there is no serialization, so one may think this flag does nothing, but that's not the case; the flag disables the dynamic server-side mechanism that outputs the styles. During a chat with @mcsf, he referred experimentalUIOnly as a possible name I agree experimentalUIOnly may be a good option, and experimentalSkipStylesOutput could also be another option.
I checked the "Color for navigation" task because it seems the navigation block is already using the color supports mechanism.
I'm not sure if experimentalSkipSerialization is the right name for the flag that disables the output of the styles. On server-side rendered blocks there is no serialization so one may think this flag does nothing but that's not the case the flag disables the dynamic server-side mechanism that outputs the styles. During a chat with @mcsf he referred experimentalUIOnly as a possible name I agree experimentalUIOnly may be a good option and experimentalSkipStylesOutput could also be another option.
__experimentalUIOnly
reads a bit confusing to me -- while I know that the __experimental
is the prefix (and I thus need to read it as "experimental flag 'UI only'"), it's possible to read it as "'experimental UI' only" -- only show the experimental UI (but not the non-experimental one?).
__experimentalSkipStylesOutput
sounds better to me (tho in the font size case, we also have a class
output).
Personally, I find the __experimentalUIOnly
option more confusing and possibly inaccurate than __experimentalSkipSerialization
. Once the styles and classes are applied to inner elements, it's no longer just the UI.
I agree with the point regarding there being no serialization on the server-side rendered blocks though.
__experimentalSkipStylesOutput sounds better to me (tho in the font size case, we also have a class output).
The same goes for background, text and border colors.
The flag name is getting rather long but maybe something along the lines of __experimentalSkipPresentationOutput
?
__experimentalUnstyled
? I think that's general enough it could be expected to cover class
output as well.
All properties have gotten the _skipSerialization
flag, so I'm going to close this one. We can still migrate blocks iteratively, do follow-ups, etc ― but for the purpose of tracking this work, we're done.
Inspired by the discussion with @luisherranz and @c4rl0sbr4v0 in #35473, I wanted to summarize my understanding of how the experimental flag __experimentalSkipSerialization
helps to control which class names and styles should get injected into the block wrapper.
Code examples from the Button block present how you can use __experimentalSkipSerialization
flag to tell that a given feature shouldn't be applied to the block wrapper:
There are corresponding hooks that let you read those skipped features and apply them to any other nested HTML element:
They need to be mapped to class names and styles:
I'm not sure how it could be translated to code in render_callback
on PHP side though.
Inspired by the discussion with @luisherranz and @c4rl0sbr4v0 in #35473, I wanted to summarize my understanding of how the experimental flag __experimentalSkipSerialization helps to control which class names and styles should get injected into the block wrapper.
Thank you @gziolo that helped me understand it quickly after looking around the various issues without success!
Here we have an interation of applying different styles to different components both in JS and in PHP.
Part of https://github.com/WordPress/gutenberg/issues/20331 Implementing this would enable some interactions expressed in https://github.com/WordPress/gutenberg/issues/26313 Kudos to @mtias @youknowriad for helping to identify the next steps for this.
What we have now
The block support mechanism allows block authors to easily make their blocks customizable via adding support for style properties: font size, color, etc.
Under the hood, this mechanism does three things:
There are some use cases that aren't absorbed by this mechanism, including:
The struggle boils down to the third point above: cast the implicit attribute to some DOM characteristic to the root node.
Next steps
A path to explore is allowing block authors a finer-grained control of how block supports work. We want to retain the bounding of UI controls to specific attributes so that block authors don't need to fiddle with controls and attribute flow. Hence, we'd allow declaring support in a way that the framework will handle rendering the UI and keeping the attribute in sync (1 and 2 in the list above) but the block author is responsible for casting the attribute on the right element (3).
Related to this fits into the global styles mechanism. Currently, blocks declare a single selector for all their style properties, so when theme authors do:
this is transformed to:
There are cases in which block selectors will need to be bounded to the support properties instead of bounded to the block, given that they may apply to different inner elements. If we have the selector bounded to a block support, the framework could also try to absorb the casting (3 in the list above) client-side.
Tasks
Adapt a single property and make one block use it: update how colors work in the social links block.
Framework implementation
Migrate these blocks & properties to the block supports system: