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

Image block: UI updates for the image lightbox (redo) #54509

Merged
merged 93 commits into from
Sep 15, 2023

Conversation

artemiomorales
Copy link
Contributor

@artemiomorales artemiomorales commented Sep 15, 2023

This is a redo of #54071, which was accidentally merged into its dependent branch #53851 before the dependent branch was merged to trunk.

What?

This PR updates the editor UI for the image lightbox in preparation for WP 6.4 and offers backwards compatibility for the behaviors syntax.

Why?

Address #53851

The lightbox was originally part of a proposed feature set called behaviors; however, we have since decided that the lightbox will instead exist as a just property of the image block for now, and we need to clarify the UI for end users as a result.

This PR is based off of #53851, which removes the behaviors syntax. Both of these PRs should be merged at the same time to ensure that the lightbox continues to function as expected.

How?

  • We've created a new Settings panel for the image block, where the lightbox is surfaced as a toggle in both the Global Styles and block settings. This design follows the discussion in Image block: Revise Lightbox UI to remove reference to Behaviors #53403 (comment).
  • We need to offer backwards support for folks who already enabled the lightbox using the old behaviors syntax, so we've set up an inheritance scheme across two filter functions — one to be included in WP Core as part of the image block, the other to remain as part of the Gutenberg plugin, where the legacy support will reside.
  • The panel is a ToolPanel, which means that the lightbox can be reset to default in the global styles or block settings.

How to enable

Via Global Styles

Open the global styles for the image block, then locate the Settings panel and enable the Expand on Click toggle.

lightbox-via-global-styles.mp4

Via Block Settings in Full Site Editor

Open the full site editor, add an image block, locate the Settings panel under the block's settings, and enable the Expand on Click toggle.

Lightbox.via.Block.Settings.in.Full.Site.Editing.mp4

Via Block Settings in Post Editor

Open the post editor, add an image block, locate the Settings panel under the block's settings, and enable the Expand on Click toggle.

ligthbox-via-block-settings.mp4

Via theme.json file

You can enable the lightbox in the theme.json by using either of the following syntaxes under settings:

Syntax 1:

"settings": {
	"blocks": {
		"core/image": {
			"lightbox": {
				"enabled": true
			}
		}
	}
}
lightbox-via-theme-json-block

Syntax 2

"settings": {
	"lightbox": {
		"enabled": true
	}
}
lightbox-via-theme-json-top-level

Legacy Syntax

To test backwards support for the legacy syntax, please enable the lightbox using both the theme.json and block attributes. Note that the old syntax allows for specifying the animation, either zoom or fade. If neither is specified, the lightbox defaults to zoom.

Via Theme.json

"behaviors": {
	"blocks": {
		"core/image": {
			"lightbox": {
				"enabled": true | false
				"animation": "" | "zoom" | "fade"
			}
		}
	}
}

256213365-0b8b53f9-c966-437c-8a1d-308e593f1701

256213813-d99364dd-35a9-4b60-aab6-808353d2d492

Via Block Attributes

"behaviors": {
	"lightbox": {
		"enabled": true | false
		"animation": "" | "zoom" | "fade"
	}
}
Screenshot 2023-09-05 at 10 56 04 PM

Resetting Values

You can reset the user-defined Expand on Click setting in the global styles or block settings using the Settings panel menu.

Lightbox.Reset.Settings.mp4

What to Test

  • Lightbox is applied, defined by theme.json.
  • In global styles, lightbox value inherits from theme.json, but this value can also be overridden so the global styles setting takes priority over the theme.json.
  • In the block settings, the lightbox value inherits first from the global styles if the lightbox value is present, if not, from the theme.json. In any case, the lightbox value can also be overridden so the setting at the block level takes priority over the theme.json and global styles config.
  • Lightbox user-defined settings can be reset at the global styles and block settings levels.
  • Lightbox is applied when using legacy syntax, defined by theme.json.
  • Lightbox is applied when using legacy syntax, defined by block attributes.
  • Lightbox legacy syntax is applied when the new syntax is not present.
  • When present, new syntax overrides legacy syntax.
  • Lightbox fade animation can be enabled via legacy syntax.

Testing Instructions for Keyboard

No special instructions here — the UI should be accessible as it was created using standard Gutenberg components.

artemiomorales and others added 30 commits August 21, 2023 10:30
Simplified the `__experimentalUseGlobalBehaviors` function by removing the 'source' parameter. Now, the function directly uses 'userConfig' for getting raw data and 'mergedConfig' for variable value.
Previously, the test was checking whether schema properties array had exactly 10 elements
We're now checking for exactly 9 elements instead.
Simplified the ImageSettingsPanel and ScreenBlock components. More specific changes:
 - Removed `name` and `settings` from the ImageSettingsPanel
 - Use `userSettings` instead of `settings` in the ImageSettingsPanel
 - Modified `onChangeLightbox` logic, it now takes a new setting instead of a boolean and directly passes to `onChange`
 - Updated the ScreenBlock component to account for this refactor
A new option has been added to the lightbox settings in the Theme JSON reference guide and Gutenberg class. This `showUI` option allows users to toggle whether the Lightbox UI is displayed in the block editor or not. Also, updated the JSON schema accordingly to reflect these changes in theme.json files.
I moved the logic to determine whether the lightbox should display
or not to two render_block_data filters.

One of these filters is inside of the index.php
so that itc can exist in WP core, the other inside of blocks.php
in order to offer legacy support for the Behaviors syntax in
the Gutenberg plugin.

Using the render_block_data instead of render_block allows us to
store a 'lightboxEnabled' value on the block, which we can use to
determine whether the lightbox should be rendered in these two
separate locations relatively cleanly without needing to touch
the markup.

I added behaviors back to the valid top-level keys so that we can
read it to offer legacy support.

Lastly, I set the lightbox.enabled attribute to NULL by default
so that we can determine whether the Behaviors syntax should override
it or not.
…ock editor UI should inherit the value from `theme.json`.

Likewise, if no value is set in the block attributes, the block editor UI should inherit the value from the Global Styles of the Image.
@artemiomorales artemiomorales merged commit 900439e into trunk Sep 15, 2023
50 checks passed
@artemiomorales artemiomorales deleted the update/lightbox-settings-panels branch September 15, 2023 22:17
@github-actions github-actions bot added this to the Gutenberg 16.7 milestone Sep 15, 2023
@@ -0,0 +1,3 @@
<!-- wp:image {"lightbox":{"enabled":true},"id":8,"sizeSlug":"large","linkDestination":"none"} -->
Copy link
Member

@gziolo gziolo Sep 18, 2023

Choose a reason for hiding this comment

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

It looks like this test isn't covering the deprecated behaviors, it should rather be:

<!-- wp:image {"behaviors":{"lightbox":{"enabled": true, "animation": "fade"}},"id":8,"sizeSlug":"large","linkDestination":"none"} -->

The file ending with .serialize.html should contain the migrated version like in this file.


It results in the following changes:

diff --git a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.html b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.html
index 9feeb10595..cdf5416f3b 100644
--- a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.html
+++ b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.html
@@ -1,3 +1,3 @@
-<!-- wp:image {"lightbox":{"enabled":true},"id":8,"sizeSlug":"large","linkDestination":"none"} -->
+<!-- wp:image {"behaviors":{"lightbox":{"enabled": true, "animation": "fade"}},"id":8,"sizeSlug":"large","linkDestination":"none"} -->
 <figure class="wp-block-image size-large"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==" alt="" class="wp-image-8"/></figure>
 <!-- /wp:image -->
diff --git a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.json b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.json
index a32f031dd3..73a483d911 100644
--- a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.json
+++ b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.json
@@ -6,12 +6,12 @@
 			"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==",
 			"alt": "",
 			"caption": "",
-			"lightbox": {
-				"enabled": true
-			},
 			"id": 8,
 			"sizeSlug": "large",
-			"linkDestination": "none"
+			"linkDestination": "none",
+			"lightbox": {
+				"enabled": true
+			}
 		},
 		"innerBlocks": []
 	}
diff --git a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.parsed.json b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.parsed.json
index 0ca652ff77..a582b93cab 100644
--- a/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.parsed.json
+++ b/test/integration/fixtures/blocks/core__image__deprecated-v8-deprecate-behaviors-lightbox.parsed.json
@@ -2,8 +2,11 @@
 	{
 		"blockName": "core/image",
 		"attrs": {
-			"lightbox": {
-				"enabled": true
+			"behaviors": {
+				"lightbox": {
+					"enabled": true,
+					"animation": "fade"
+				}
 			},
 			"id": 8,
 			"sizeSlug": "large",

Everything works as expected, but it's still worth updating the code.

Copy link
Contributor

@michalczaplinski michalczaplinski Sep 18, 2023

Choose a reason for hiding this comment

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

Good catch, I'll update the file.

Copy link
Contributor

Choose a reason for hiding this comment

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

done in #54570

export default function ImageSettingsPanel( {
onChange,
userSettings,
settings,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should these props be named value and inheritedValue instead of userSettings and settings. I understand that it's a bit different than the other components like TypographyPanel because this one updates the settings rather than the styles but there's a small precedent. The DimentionsPanel also updates the "layout" which is saved in "settings".

I like to think of the components in separation (regardless of where the value ends up saved). If a component has onChange ideally, it also has value. settings is used in general for things that configure the behavior of the component, not the thing that is changed by the component.

Copy link
Contributor

Choose a reason for hiding this comment

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

If a component has onChange ideally, it also has value.

I gotta acknowledge that it's a convention in React, but at the same time, having a value prop in this situation erases the meaning of the original prop (passed from the parent).

For example:

if ( settings?.lightbox?.enabled ) {
lightboxChecked = settings.lightbox.enabled;
}

When I look at this, I know it's dealing with the lightbox setting. If settings were renamed to inheritedValue I wouldn't know if it's a setting, a style, or something else. At least this is something that confused me when I looked at other panels initially 🙂

Copy link
Contributor

Choose a reason for hiding this comment

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

I understand that it might confuse you but I think consistency is better than personal opinion in this case. I value your opinion but if we adopt something I think we should adopt in all components and not just one. Also this has been discussed previously here #37064

Copy link
Contributor

Choose a reason for hiding this comment

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

I see! I don't feel very strongly about this, and indeed whether it's confusing or not is subjective/personal 🙂. I'll update it in a follow-up PR. Thanks Riad!

Copy link
Contributor

Choose a reason for hiding this comment

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

Done in #54593

Copy link

Choose a reason for hiding this comment

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

I am testing image light box with WP 6.4-beta1 without Gutenberg plugin. The image light box doesn't work when I create gallery but it works with normal image block.
Screenshot 2023-09-28 at 10 11 17 AM

Copy link
Contributor Author

@artemiomorales artemiomorales Sep 28, 2023

Choose a reason for hiding this comment

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

@lwangdu Thanks for taking a look! I just tested in the WP 6.4-beta1 and it's working for me. Note that we don't have full gallery support, so you won't be able to toggle between the images while the lightbox is open, though the zooming should work as expected.

What happens when you click on a gallery image on the front end? Does the image expand?

if ( ! isset( $lightbox_settings ) || 'none' !== $link_destination ) {
return $block_content;
if ( ! isset( $lightbox_settings ) ) {
$lightbox_settings = gutenberg_get_global_settings( array( 'lightbox' ), array( 'block_name' => 'core/image' ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

We can't use this function here because block PHP files are auto-generated in core from the package. Any gutenberg namespaced function is exclusive to the plugin so will error in core.

I thought we'd added a check for gutenberg namespaces in block-library? Cc @anton-vlasenko and @gziolo any idea how this might have slipped through?

Copy link
Member

Choose a reason for hiding this comment

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

The check for function names at the moment covers only definitions. Preventing the usage of functions prefixed with gutenberg_ could be the next step. The challenge though is that we still need to allow them when wrapped with:

if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {}

I know it's possible with ESLint for JavaScript, but I'm not sure about linting for PHP.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oooh I see, thanks for explaining!

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for the ping, @Mamaduka and @tellthemachines. I've created a new GitHub issue for this and hope to submit a PR soon: #54745

@tellthemachines tellthemachines removed the Needs PHP backport Needs PHP backport to Core label Sep 25, 2023
@michalczaplinski michalczaplinski added Needs Dev Note Requires a developer note for a major WordPress release cycle and removed Needs Dev Note Requires a developer note for a major WordPress release cycle labels Sep 25, 2023
@lwangdu
Copy link

lwangdu commented Sep 28, 2023 via email

@artemiomorales
Copy link
Contributor Author

@lwangdu Ok got it! Would you be able to file a bug report? That way we can continue the discussion, see if other folks can reproduce as well and hopefully resolve the issue 😄

@lwangdu
Copy link

lwangdu commented Sep 28, 2023 via email

@femkreations femkreations added the Needs User Documentation Needs new user documentation label Sep 29, 2023
@afercia
Copy link
Contributor

afercia commented Oct 6, 2023

@artemiomorales when you have a chance:
why the settings control label is Expand on click while on the front end the verb in use for the button is Enlarge? Even though Enlarge is for the aria-label and thus it's not visible, can we use a consistent terminology please?

I'm not a native English speaker but between Expand and Enlarge I'd opt for the latter.

@artemiomorales
Copy link
Contributor Author

artemiomorales commented Oct 6, 2023

why the settings control label is Expand on click while on the front end the verb in use for the button is Enlarge? Even though Enlarge is for the aria-label and thus it's not visible, can we use a consistent terminology please?

I'm not a native English speaker but between Expand and Enlarge I'd opt for the latter.

@afercia Expand for the editor UI was decided upon in this issue, and while Expand on Click sounds good in the editor UI, labeling the button in the content with "expand image" feels a bit odd, but I hadn't thought in depth on this and have no strong opinion.

Two options:
1.) We can rename the button in the content to be Expand image
2.) Alternatively, we can rename the button in the editor UI to be Enlarge on Click, which to your point may be clearer for non-native English speakers.

If the latter, we should bring it up in the issue and discuss with other folks who were involved with that decision. What do you think?

@afercia
Copy link
Contributor

afercia commented Oct 25, 2023

If the latter, we should bring it up in the issue and discuss with other folks who were involved with that decision. What do you think?

I will create a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Image Affects the Image Block [Feature] Interactivity API API to add frontend interactivity to blocks. Needs User Documentation Needs new user documentation [Type] Enhancement A suggestion for improvement.
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

10 participants