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

Allow themes to provide empty values for color.duotone and spacing.units #33280

Merged
merged 6 commits into from Jul 8, 2021

Conversation

@oandregal
Copy link
Member

@oandregal oandregal commented Jul 8, 2021

This fixes an issue with the color.duotone & spacing.units in which empty values didn't override previous origins, resulting in that a theme couldn't provide an empty set for this via its theme.json.

How to test

Use the TT1-blocks theme.

Test empty units work as expected

  • Set to empty those presets in its theme.json:
{
  "settings": {
    "color": {
      "duotone": []
    },
    "spacing": {
       "units": []
    }
  }
}
  • Go to the editor and add an image. Select the duotone control. The expected result is that the duotone control doesn't show any color, but still shows the shadow and highlight options.

Captura de ecrã de 2021-07-08 11-38-45

  • Add a cover block, select it and go to its inspector. The cover height and the padding should only show px units.

Test filtered units work as expected

  • Set to empty those presets in its theme.json:
{
  "settings": {
    "color": {
      "duotone": [
        {
          "name":  "Dark grayscale" ,
          "colors": [ "#000000", "#7f7f7f" ],
          "slug": "dark-grayscale"
          }
      ]
    },
    "spacing": {
       "units": [ "px", "em" ]
    }
  }
}
  • Go to the editor and add an image. Select the duotone control. The expected result is that the duotone control only has the one we added.
  • Add a cover block, select it and go to its inspector. The cover height and the padding should only show the two units added by the theme (px, em).

Test no units work as expected

  • Remove color.duotone and spacing.units from the theme.json of TT1-blocks.
  • Check that the controls show a list of duotone colors and units in the cases above.

I've also tested passing an empty array to the other presets and this is how it should work: colors and gradients should still work as before: hide the list of preset values, but users still can add custom values. Font sizes should still work as before: hide the control.

@oandregal oandregal requested a review from spacedmonkey as a code owner Jul 8, 2021
@oandregal oandregal self-assigned this Jul 8, 2021
@oandregal oandregal added this to 🏗️ In progress in WordPress 5.8 Must Haves via automation Jul 8, 2021
@oandregal oandregal requested a review from ajlende Jul 8, 2021
@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

I've got curious about how one can prevent the color panel in the inspector and the duotone control from showing. Apparently we can't, and this is an issue that should be discussed in a different PR.

I've tried this in the theme.json:

{
"settings": {
  "color": {
    "link": false,
    "custom": false,
    "duotone": [],
    "palette": [],
    "gradients": []
  }
}

Resulting in (notice how the color panel and the duotone control are still accessible but are empty):

Captura de ecrã de 2021-07-08 11-44-53

Captura de ecrã de 2021-07-08 11-44-42

@oandregal oandregal changed the title Incoming presets in theme.json can be empty Duotone colors should not be present if the theme provides an empty set via theme.json Jul 8, 2021
@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

Updated the issue description with data about how this affects the other presets. TLDR: all work well except for units. The issue with units is that UI controls don't respect the empty array passed by the theme and should be fixed in a different PR.

@@ -1073,6 +1073,7 @@ public function merge( $incoming ) {
// For leaf values that are arrays it will use the numeric indexes for replacement.
// In those cases, we want to replace the existing with the incoming value, if it exists.
$to_replace = array();
$to_replace[] = array( 'layout', 'units' );

This comment has been minimized.

@oandregal

oandregal Jul 8, 2021
Author Member

@youknowriad would like confirmation about how layout.units should work. My understanding is that it should work this way:

  • if a theme doesn't provide any layout.units defaults are listed
  • themes can override these values via theme.json
  • if a theme provides an empty array in layout.units, the control only shows px
  • if a theme provides a limited set of units, such as [ 'px', 'em' ], those are the only units shown in the control

Is this behavior correct?

If so, we need to add layout.units to the list of things we merge ourselves.

This comment has been minimized.

@youknowriad

youknowriad Jul 8, 2021
Contributor

@aristath would know more here but it does sound right.

This comment has been minimized.

@youknowriad

youknowriad Jul 8, 2021
Contributor

Though that makes me wonder, is layout.units a thing? Why "units" are in "layout" I feel like that's an error?

This comment has been minimized.

@youknowriad

youknowriad Jul 8, 2021
Contributor

isn't it spacing.units ?

This comment has been minimized.

@oandregal

oandregal Jul 8, 2021
Author Member

Both exist and are used in different places:

  • layout.units: layout hook, letter-spacing component, border width hook, column width.
  • spacing.units: padding hook, margin hook, cover height, unit control.

I don't know if this is proper or we should only have one of them.

This comment has been minimized.

@aristath

aristath Jul 8, 2021
Member

I think replacing layout.units with spacing.units would be OK... Both implementations are sub-optimal, but until we figure out a proper way to differentiate these things we should probably keep things as they were 👍
If and when the time comes to differentiate them, a separate ticket should be opened and we can investigate the implementation separately. For now, let's replace things with spacing.units and keep it consistent ❤️

This comment has been minimized.

@oandregal

oandregal Jul 8, 2021
Author Member

spacing.units can be overridden by block, so I wonder if that's enough for now.

Another thing I've noticed is that the UnitControl uses spacing.units for availableUnits: it looks like these are the "allowed units" the control can use unless a consumer filters them via units. This means that what you pass as units can only be a subset of spacing.units: you can't have in layout.units things that are not part of spacing.units as well.

I'm also in favor of starting small and add things if we need them later. Remove things is hard/impossible.

This comment has been minimized.

@oandregal

oandregal Jul 8, 2021
Author Member

I haven't seen this in use by any theme and doesn't have documentation either, so I presume layout.units wasn't widely known/used in practice.

This comment has been minimized.

@oandregal

oandregal Jul 8, 2021
Author Member

For example, if you set spacing.units to an empty array, any content in layout.units would've been ignored. I think I'm going to commit this as it is. It's code, so we can always add more, should it be necessary.

This comment has been minimized.

@oandregal

oandregal Jul 8, 2021
Author Member

The other side effect here is that we shouldn't add any config to layout that is not about the "layout config" itself (content width, wide width, type of layout), because that config has a meaning holistically and it's not a discrete list of settings.

Prepared this #33303 to specify what settings can be part of layout, so we don't allow random things there.

@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

Ok, units seem to work as expected as well, except for the border-radius that doesn't allow filtering the units by the theme, so I've asked https://github.com/WordPress/gutenberg/pull/31585/files#r666080677 This can be done later as it's unrelated and doesn't affect WordPress 5.8.

@youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Jul 8, 2021

"duotone": [],

I think you could say "duotone": false to hide the button but maybe "duotone": [] should work similarly. @ajlende

@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

I think you could say "duotone": false to hide the button but maybe "duotone": [] should work similarly.

That raises an error in the translation code because it's expecting an array. We can update that code to allow booleans so this works, but I'm reluctant because it's very specific to duotone. Any other preset (colors, gradients) don't work that way.

@youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Jul 8, 2021

That raises an error in the translation code because it's expecting an array. We can update that code to allow booleans

Maybe it's null and not false but there's definitely something in the code to support that #32002 maybe it regressed with theme.json translation.

@Mamaduka
Copy link
Member

@Mamaduka Mamaduka commented Jul 8, 2021

We can update ! duotonePalette check to ! duotonePalette?.length and this should handle an empty array.

if ( ! duotonePalette ) {
return null;
}

@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

Maybe it's null and not false but there's definitely something in the code to support that #32002 maybe it regressed with theme.json translation.

No, it didn't. Tested that PR and it also fails with false, I guess that's why the workaround to use null. I've also noticed that setting the palette to null as suggested by that PR raised an error at the time and it gets a different one today :(

Ok, let's move forward: this PR should focus on fixing the ability to filter and pass empty units to color.duotone, spacing.units, layout.units.

In a different PR, we should address how panels are shown/hidden. I'd argue we should not use nulls and do this instead:

  • duotone is hidden when color.duotone is empty && color.palette is empty && color.custom is false
  • the color panel is hidden when color.palette is empty && color.gradients is empty && color.custom is false
  • etc

Essentially, the panels should be hidden when the presets they are empty && the other boolean style properties are false.

@@ -1086,8 +1087,8 @@ public function merge( $incoming ) {
foreach ( $nodes as $metadata ) {
foreach ( $to_replace as $property_path ) {
$path = array_merge( $metadata['path'], $property_path );
$node = _wp_array_get( $incoming_data, $path, array() );
if ( ! empty( $node ) ) {

This comment has been minimized.

@jorgefilipecosta

jorgefilipecosta Jul 8, 2021
Member

We already a similar bug before with using empty. I grepped for empty on this file to make sure we don't have additional issues. I found other suspicious case:

			if ( ! empty( $escaped_preset ) ) {
				gutenberg_experimental_set( $output, $preset_metadata['path'], $escaped_preset );
			}

It is related to user escaping does not affect 5.8 I will confirm if this is indeed another bug and if yes fix it in another PR.

@jorgefilipecosta
Copy link
Member

@jorgefilipecosta jorgefilipecosta commented Jul 8, 2021

the color panel is hidden when color.palette is empty && color.gradients is empty && color.custom is false

I think for the color panels that's already the case unless we had some regression.

@jorgefilipecosta
Copy link
Member

@jorgefilipecosta jorgefilipecosta commented Jul 8, 2021

That raises an error in the translation code because it's expecting an array. We can update that code to allow booleans

Maybe it's null and not false but there's definitely something in the code to support that #32002 maybe it regressed with theme.json translation.

I think duotone should be consistent with the other presets we can have duotone presets that are always an array, and a customDuotone flag. Duotone is not available at all if the presets are empty and customDuotone flag is false, exactly as it happens on color, grandients, font sizes.

@oandregal oandregal requested review from ajitbohra and ellatrix as code owners Jul 8, 2021
@youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Jul 8, 2021

Ok, let's move forward: this PR should focus on fixing the ability to filter and pass empty units to color.duotone, spacing.units, layout.units.

I'd love @aristath's input but I think layout.units was just a typo and this PR should focus on using spacing.units consistently (this is the documented config anyway)

nevermind @nosolosw just saw that you did already :)

@@ -899,10 +884,6 @@ public function test_merge_incoming_data_null_presets() {
),
),
),
'layout' => array(
'contentSize' => '610px',

This comment has been minimized.

@youknowriad

youknowriad Jul 8, 2021
Contributor

not sure what this test is about but this config is valid (contentSize) and maybe we could keep it.

This comment has been minimized.

@oandregal

oandregal Jul 8, 2021
Author Member

This commit is removing a previous commit in this PR: I had added this when I thought layout.units was a valid input and wanted to make sure the merge algorithm respected pre-existing data (layout.contentSize). If we want a test for this it should live in another method of this file. Can be done in a follow-up PR if necessary.

Copy link
Contributor

@youknowriad youknowriad left a comment

LGTM 👍

@oandregal oandregal changed the title Duotone colors should not be present if the theme provides an empty set via theme.json Allow themes to provide empty values for color.duotone and spacing.units Jul 8, 2021
@aristath
Copy link
Member

@aristath aristath commented Jul 8, 2021

I'd love @aristath's input but I think layout.units was just a typo and this PR should focus on using spacing.units consistently (this is the documented config anyway)

Thank you for the ping! Added comment on #33280 (comment) 👍

@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

This is ready in my testing as well. I'm waiting for the conversation at #33280 (comment) to settle before merging this.

@oandregal oandregal merged commit 8d5a38a into trunk Jul 8, 2021
20 checks passed
20 checks passed
@github-actions
Compute current and next stable release branches
Details
@github-actions
test
Details
@github-actions
Check (14)
Details
@github-actions
Checks (12)
Details
@github-actions
Admin - 1 Admin - 1
Details
@github-actions
Run performance tests
Details
@github-actions
pull-request-automation (14)
Details
@github-actions
test (12.2, gutenberg-editor-initial-html, 14)
Details
@github-actions
JavaScript (12)
Details
@github-actions
Checks (14)
Details
@github-actions
Admin - 2 Admin - 2
Details
@github-actions
JavaScript (14)
Details
@github-actions
Admin - 3 Admin - 3
Details
@github-actions
Admin - 4 Admin - 4
Details
@github-actions
Bump version
Details
@github-actions
Build Release Artifact
Details
@github-actions
Mobile
Details
@github-actions
Create Release Draft and Attach Asset
Details
WordPress 5.8 Must Haves automation moved this from 🏗️ In progress to ✅ Done Jul 8, 2021
@oandregal oandregal deleted the fix/incoming-presets-can-be-empty branch Jul 8, 2021
@github-actions github-actions bot added this to the Gutenberg 11.1 milestone Jul 8, 2021
@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

WordPress/wordpress-develop#1489 ports the PHP changes to core. The JS changes are related but don't need to land at the same time: I presume they are going to be part of the next package release for core?

@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

The JS changes are related but don't need to land at the same time: I presume they are going to be part of the next package release for core?

Or perhaps is best if I push the JS changes to the wp/5.8 branch?

@youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Jul 8, 2021

Yeah, next package update but we can include WordPress/wordpress-develop#1489 in the same commit if needed.

@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

#33295 updates the conditions under which the duotone control and its subcomponents are visible.

@oandregal
Copy link
Member Author

@oandregal oandregal commented Jul 8, 2021

Follow-up from #33280 (comment) I could reproduce the color panel issue: it seems that it requires all things to be disabled/empty, even if the block itself supports only some of them: #33304

youknowriad added a commit that referenced this pull request Jul 12, 2021
youknowriad added a commit that referenced this pull request Jul 13, 2021
sarayourfriend added a commit that referenced this pull request Jul 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants