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 #54071

Merged
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
e613a5b
Add initial implementation of image settings panel
artemiomorales Aug 30, 2023
b0fb3b5
Remove unnecessary code and fix reset functionality
artemiomorales Aug 30, 2023
b76d56c
Add UI to image block inspector
artemiomorales Aug 30, 2023
1872f77
Add `lightbox` to the valid `theme.json` settings
michalczaplinski Aug 31, 2023
3cfcb15
Merge branch 'update/revise-lightbox-ui' into update/lightbox-setting…
michalczaplinski Aug 31, 2023
d2818af
Fix a bug with image selector and integrate with global styles
michalczaplinski Aug 31, 2023
a32d0f6
Update `theme.json` schema
michalczaplinski Sep 2, 2023
e67634e
Added the `@since`annotation
michalczaplinski Sep 2, 2023
3ddb1b1
Refactor image settings panel and screen block
michalczaplinski Sep 4, 2023
fae6f99
Add showUI option to lightbox settings
michalczaplinski Sep 4, 2023
df9f857
Add defaults for the `lightbox` to the GB `theme.json`
michalczaplinski Sep 4, 2023
df3f1c6
Change the falsy checks in image.js
michalczaplinski Sep 4, 2023
075535b
Add filters; add legacy support for behaviors syntax
artemiomorales Sep 5, 2023
c2a0b3f
Fix linter errors & add more expansive comments.
michalczaplinski Sep 5, 2023
91d130c
If no value is set for the lightbox in the Global Styles, then the bl…
michalczaplinski Sep 5, 2023
c58612c
Rename `showUI` to `allowEditing`
michalczaplinski Sep 5, 2023
c602139
Fix the `theme.json` schema
michalczaplinski Sep 5, 2023
339a715
Use the globalPath for the settings on the PHP side
michalczaplinski Sep 5, 2023
4b43b30
Add backwards support for enabling fade animation via the legacy syntax
artemiomorales Sep 6, 2023
ce3c338
Fix PHP linter errors
artemiomorales Sep 6, 2023
7fefb83
Merge branch 'update/revise-lightbox-ui' into update/lightbox-setting…
michalczaplinski Sep 6, 2023
03e60d7
Fix error when checking lightbox['enabled'] value in global settings
artemiomorales Sep 6, 2023
050c636
Empty commit
michalczaplinski Sep 6, 2023
521d950
Remove the default `false` value for `lightbox.enabled`attribute.
michalczaplinski Sep 7, 2023
1db73c5
Add deprecation notice for 'behaviors' in image block
artemiomorales Sep 7, 2023
715e32c
Merge branch 'update/revise-lightbox-ui' into update/lightbox-setting…
michalczaplinski Sep 7, 2023
41f251d
Merge branch 'update/revise-lightbox-ui' into update/lightbox-setting…
michalczaplinski Sep 7, 2023
79dad34
Add deprecation for attribute in image block
artemiomorales Sep 9, 2023
871ba45
Remove obsolete code now that block deprecation is in place
artemiomorales Sep 10, 2023
7f2f70f
Add support for 'lightbox: true' syntax
artemiomorales Sep 11, 2023
6da3545
Fix lightbox 'checked' attribute being read improperly
artemiomorales Sep 11, 2023
83bef30
Add conditional display for settings panel at image block level
artemiomorales Sep 11, 2023
52e358d
Fix an error with the theme.json schema.
michalczaplinski Sep 11, 2023
11e96e2
Update docs with `npm run build:docs`
michalczaplinski Sep 11, 2023
8809612
Merge branch 'update/revise-lightbox-ui' into update/lightbox-setting…
michalczaplinski Sep 11, 2023
59e0dbe
Copy `class-wp-theme-json-schema.php` from core
michalczaplinski Sep 11, 2023
3eeb1a7
Merge branch 'update/lightbox-settings-panels' of github.com:WordPres…
michalczaplinski Sep 11, 2023
443aa5b
Add a theme.json migration to v3 away from behaviors and to a new, si…
michalczaplinski Sep 11, 2023
6459d56
Remove the `null` value from lightbox.enabled in `lib/theme.json`
michalczaplinski Sep 11, 2023
203649d
Remove `behaviors` from VALID_TOP_LEVEL_KEYS & VALID_SETTINGS
michalczaplinski Sep 11, 2023
5a37499
Merge branch 'update/revise-lightbox-ui' into update/lightbox-setting…
artemiomorales Sep 11, 2023
0e63890
Revise backwards compatibility for behaviors; add deprecation to bloc…
artemiomorales Sep 11, 2023
8b721a7
Remove outdated comment
michalczaplinski Sep 12, 2023
8287c46
Update outdated comment
michalczaplinski Sep 12, 2023
a2c2b94
Update comment and shuffle the lines so the diff is easier on the eyes.
michalczaplinski Sep 12, 2023
4f0709b
Update comment to explain why we use userSettings in image-settings-p…
michalczaplinski Sep 12, 2023
7018ee7
Remove support for legacy fade configuration
artemiomorales Sep 12, 2023
7fd0801
Resolve lint error
artemiomorales Sep 12, 2023
5bb05bc
Add clarifying comment regarding lightbox markup
artemiomorales Sep 12, 2023
a02910c
Rename the migrate function to reflect that it's not a v3 migration
michalczaplinski Sep 12, 2023
b12d386
Add a `@since` in `gutenberg_should_render_lightbox` docblock
michalczaplinski Sep 12, 2023
2f5f122
Add support for reading top-level 'lightbox' setting in editor
artemiomorales Sep 12, 2023
a238d94
Revert "Add support for reading top-level 'lightbox' setting in editor"
artemiomorales Sep 13, 2023
0aba3c4
Add correct deprecation mentioning the Gutenberg version
michalczaplinski Sep 13, 2023
8fa991e
Move 'allowEditing' to top-level settings
artemiomorales Sep 13, 2023
65b173c
Fix top-level lightbox setting not being read properly
artemiomorales Sep 13, 2023
b5f8186
Fix 'false' values in theme.json not being stored in settings object
artemiomorales Sep 13, 2023
7e121da
Fix error wherein 'undefined' was being passed to input component
artemiomorales Sep 13, 2023
fb10384
Fix bug wherein lightbox UI would disappear if user value was set
artemiomorales Sep 13, 2023
ef8f43e
Remove inheritance when determining whether to enable lightbox
artemiomorales Sep 13, 2023
fc8fc47
Update comment
artemiomorales Sep 13, 2023
6ea39f8
Update whitespace in theme.json
michalczaplinski Sep 14, 2023
aaab1ef
Add docblocks to clarify that `class-wp-theme-json-schema-gutenberg.p…
michalczaplinski Sep 14, 2023
61bfb3d
Add comments to clarify that behaviors.php is temporarily added to GB…
michalczaplinski Sep 14, 2023
c18e283
Added integration fixtures for the lightbox
michalczaplinski Sep 14, 2023
7d30aa6
Merge branch 'update/revise-lightbox-ui' into update/lightbox-setting…
michalczaplinski Sep 14, 2023
dab7f5a
Fix incorrect reading of global lightbox settings
artemiomorales Sep 14, 2023
a5c2f0c
Clarify the comment getting the global lightbox settings
michalczaplinski Sep 14, 2023
485c197
Fix PHPCS parenthesis error 🤦‍♂️
michalczaplinski Sep 15, 2023
d1432bc
Move lightbox settings to the block level
artemiomorales Sep 15, 2023
ff1d2b5
Remove support for shorthand
artemiomorales Sep 15, 2023
ee1dd8c
Remove 'lightbox' from hooks.js and add `.enabled` & `.allowEditing` …
michalczaplinski Sep 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

This page lists the blocks included in the block-library package.

- Items marked with a strikeout (~~strikeout~~) are explicitly disabled.
- Blocks marked with **Experimental:** true are only available when Gutenberg is active.
- Blocks marked with **Experimental:** fse are only available in the Site Editor.

- Items marked with a strikeout (~~strikeout~~) are explicitly disabled.
- Blocks marked with **Experimental:** true are only available when Gutenberg is active.
- Blocks marked with **Experimental:** fse are only available in the Site Editor.

<!-- START TOKEN Autogenerated - DO NOT EDIT -->

Expand Down Expand Up @@ -340,7 +339,7 @@ Insert an image to make a visual statement. ([Source](https://github.com/WordPre
- **Name:** core/image
- **Category:** media
- **Supports:** anchor, color (~~background~~, ~~text~~), filter (duotone)
- **Attributes:** align, alt, aspectRatio, caption, height, href, id, linkClass, linkDestination, linkTarget, rel, scale, sizeSlug, title, url, width
- **Attributes:** align, alt, aspectRatio, behaviors, caption, height, href, id, lightbox, linkClass, linkDestination, linkTarget, rel, scale, sizeSlug, title, url, width
artemiomorales marked this conversation as resolved.
Show resolved Hide resolved

## Latest Comments

Expand Down
14 changes: 14 additions & 0 deletions docs/reference-guides/theme-json-reference/theme-json-living.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,20 @@ Settings related to typography.
Generate custom CSS custom properties of the form `--wp--custom--{key}--{nested-key}: {value};`. `camelCased` keys are transformed to `kebab-case` as to follow the CSS property naming schema. Keys at different depth levels are separated by `--`, so keys should not include `--` in the name.


---

### enabled

Defines whether the lightbox is enabled or not.


---

### allowEditing

Defines whether to show the Lightbox UI in the block editor. If set to `false`, the user won't be able to change the lightbox settings in the block editor.


artemiomorales marked this conversation as resolved.
Show resolved Hide resolved
---
## Styles

Expand Down
68 changes: 68 additions & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -431,4 +431,72 @@ function gutenberg_legacy_wp_block_post_meta( $value, $object_id, $meta_key, $si

return $value;
}

add_filter( 'default_post_metadata', 'gutenberg_legacy_wp_block_post_meta', 10, 4 );


/**
* Check if the lightbox should be rendered for a given block.
*
* This function is INTENTIONALLY left out of core as it only provides
* backwards compatibility for the legacy lightbox syntax that was only
* introduced in Gutenberg. The legacy syntax was using the `behaviors` key in
* the block attrbutes and the `theme.json` file.
*
* @param array $block The block to check.
* @return array The block with the lightboxEnabled flag set if the lightbox should be rendered.
*/
function gutenberg_should_render_lightbox( $block ) {
artemiomorales marked this conversation as resolved.
Show resolved Hide resolved

if ( 'core/image' !== $block['blockName'] ) {
return $block;
}

// Get the lightbox setting from the block attributes.
if ( isset( $block['attrs']['lightbox'] ) ) {
$lightbox_settings = $block['attrs']['lightbox'];
// If not present, check legacy syntax.
} elseif ( isset( $block['attrs']['behaviors']['lightbox'] ) ) {
$lightbox_settings = $block['attrs']['behaviors']['lightbox'];
}
artemiomorales marked this conversation as resolved.
Show resolved Hide resolved

// If not present in block attributes, check global settings.
if ( ! isset( $lightbox_settings ) ) {
$lightbox_settings = gutenberg_get_global_settings( array( 'lightbox' ), array( 'block_name' => 'core/image' ) );

// If not present in global settings, check the top-level global settings.
if ( ! isset( $lightbox_settings['enabled'] ) ) {
$lightbox_settings = gutenberg_get_global_settings( array( 'lightbox' ) );
}
}

// If not present in global settings, check legacy syntax.
if ( ! isset( $lightbox_settings['enabled'] ) ) {
$theme_data = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_data();
if ( isset( $theme_data['behaviors']['blocks'][ $block['blockName'] ]['lightbox'] ) ) {
$lightbox_settings = $theme_data['behaviors']['blocks'][ $block['blockName'] ]['lightbox'];
}
}
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved

$link_destination = isset( $block['attrs']['linkDestination'] ) ? $block['attrs']['linkDestination'] : 'none';

// If the lightbox is enabled, the image is not linked, flag the lightbox to be rendered.
if ( isset( $lightbox_settings['enabled'] ) &&
true === $lightbox_settings['enabled'] &&
'none' === $link_destination
) {
$block['lightboxEnabled'] = true;

// The legacy syntax allows setting the animation type.
if ( isset( $lightbox_settings['animation'] ) ) {
$block['lightboxAnimation'] = $lightbox_settings['animation'];
}
}

return $block;
}

// Run with a priority of 15 to ensure it runs after
// `block_core_image_should_render_lightbox` core filter (that has a
// priority of 10).
add_filter( 'render_block_data', 'gutenberg_should_render_lightbox', 15, 1 );
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved
7 changes: 7 additions & 0 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ class WP_Theme_JSON_Gutenberg {
'templateParts',
'title',
'version',
'behaviors',
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved
);

/**
Expand All @@ -346,6 +347,7 @@ class WP_Theme_JSON_Gutenberg {
* `position.fixed` and `position.sticky`.
* @since 6.3.0 Removed `layout.definitions`. Added `typography.writingMode`.
* @since 6.4.0 Added `layout.allowEditing`.
* @since 6.4.0 Added `lightbox.enabled` and `lightbox.allowEditing`.
* @var array
*/
const VALID_SETTINGS = array(
Expand Down Expand Up @@ -383,6 +385,10 @@ class WP_Theme_JSON_Gutenberg {
'wideSize' => null,
'allowEditing' => null,
),
'lightbox' => array(
'enabled' => null,
'allowEditing' => null,
),
'position' => array(
'fixed' => null,
'sticky' => null,
Expand Down Expand Up @@ -415,6 +421,7 @@ class WP_Theme_JSON_Gutenberg {
'textTransform' => null,
'writingMode' => null,
),
'behaviors' => null,
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved
);

/**
Expand Down
6 changes: 6 additions & 0 deletions lib/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@
"radius": true
}
},
"core/image": {
"lightbox": {
"enabled": null,
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved
"allowEditing": true
}
},
"core/pullquote": {
"border": {
"color": true,
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/components/global-styles/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ const VALID_SETTINGS = [
'layout.contentSize',
'layout.definitions',
'layout.wideSize',
'lightbox.enabled',
'lightbox.allowEditing',
'position.fixed',
'position.sticky',
'spacing.customSpacingSize',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* WordPress dependencies
*/
import {
__experimentalToolsPanel as ToolsPanel,
__experimentalToolsPanelItem as ToolsPanelItem,
ToggleControl,
} from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';

export function useHasImageSettingsPanel( name, settings ) {
return name === 'core/image' && settings?.lightbox?.allowEditing;
}

export default function ImageSettingsPanel( {
onChange,
userSettings,
settings,
panelId,
} ) {
const resetLightbox = () => {
onChange( undefined );
};

const onChangeLightbox = ( newSetting ) => {
onChange( {
enabled: newSetting,
} );
};

return (
<>
<ToolsPanel
label={ _x( 'Settings', 'Image settings' ) }
resetAll={ resetLightbox }
panelId={ panelId }
>
<ToolsPanelItem
hasValue={ () => !! userSettings?.lightbox }
Copy link
Contributor

@ajlende ajlende Sep 9, 2023

Choose a reason for hiding this comment

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

Wouldn't this be more accurate?

Suggested change
hasValue={ () => !! userSettings?.lightbox }
hasValue={ () => settings?.lightbox?.enabled }

If so, you could get rid of the second useGlobalSetting() in screen-block.js.

Copy link
Contributor

Choose a reason for hiding this comment

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

This was my first thougth as well, but it wouldn't work as expected!

The hasValue prop of the ToolsItemPanel controls whether the "RESET" button is enabled or not. We only want to enable it if there is a value in the userSettings, meaning that the user has set a value themselves in the Global Styles.

E.g.: If the default value is true, but the user hasn't set anything in the Global Styles the checkbox should be checked, but it shouldn't be possible to "RESET" it:

Screenshot 2023-09-12 at 15 34 20

I agree that it's not too intuitive though so I ll add a comment explaining the above 🙂

Copy link
Contributor

Choose a reason for hiding this comment

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

Added the code comment in 4f0709b

Copy link
Contributor

Choose a reason for hiding this comment

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

As I was testing things here, I found a bug related to this. It would be fixed by comparing the value with the theme.json origin default value instead of checking the user origin, but it's pretty minor, so I'm happy to leave this as a follow-up so we can get this merged before the feature freeze.

  1. Start with a clean wp_global_styles CPT either by deleting the one for the theme you're using in your database or using a new theme.
  2. See that it isn't possible to reset the image lightbox setting.
  3. Go to the layout settings and modify one of the values. Save the change.
  4. Go back to the image lightbox settings and see that the reset option is now available.
reset-layout-lightbox-settings.mp4

What happens when you try to change anything in the settings part of theme.json, the entire settings object is saved in the wp_global_styles CPT. In the code here, you're checking for the value from this saved object to be truthy, and because all defaults are written to the database, not just the ones changed, setting any of them will trigger all of them to have their default value in the user settings.

I see this as a side-effect of trying to store things that aren't Gutenberg UI settings (layout.contentWidth, layout.wideWidth, and lightbox.enabled) in the settings object. So I think it would be better to move these values out of the settings rather than updating the code to be more specific about which settings are saved.

label={ __( 'Expand on Click' ) }
onDeselect={ resetLightbox }
isShownByDefault={ true }
panelId={ panelId }
>
<ToggleControl
label={ __( 'Expand on Click' ) }
checked={ !! settings?.lightbox?.enabled }
onChange={ onChangeLightbox }
/>
</ToolsPanelItem>
</ToolsPanel>
</>
);
}
4 changes: 4 additions & 0 deletions packages/block-editor/src/components/global-styles/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,9 @@ export { default as BorderPanel, useHasBorderPanel } from './border-panel';
export { default as ColorPanel, useHasColorPanel } from './color-panel';
export { default as EffectsPanel, useHasEffectsPanel } from './effects-panel';
export { default as FiltersPanel, useHasFiltersPanel } from './filters-panel';
export {
default as ImageSettingsPanel,
useHasImageSettingsPanel,
} from './image-settings-panel';
export { default as AdvancedPanel } from './advanced-panel';
export { areGlobalStyleConfigsEqual } from './utils';
9 changes: 9 additions & 0 deletions packages/block-library/src/image/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@
"selector": "figcaption",
"__experimentalRole": "content"
},
"behaviors": {
"type": "object"
},
artemiomorales marked this conversation as resolved.
Show resolved Hide resolved
"lightbox": {
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved
"type": "object",
"enabled": {
"type": "boolean"
}
},
"title": {
"type": "string",
"source": "attribute",
Expand Down
52 changes: 52 additions & 0 deletions packages/block-library/src/image/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ResizableBox,
Spinner,
TextareaControl,
ToggleControl,
TextControl,
ToolbarButton,
ToolbarGroup,
Expand All @@ -23,6 +24,7 @@ import {
__experimentalImageURLInputUI as ImageURLInputUI,
MediaReplaceFlow,
store as blockEditorStore,
useSetting,
BlockAlignmentControl,
__experimentalImageEditor as ImageEditor,
__experimentalGetElementClassName,
Expand Down Expand Up @@ -65,6 +67,7 @@ import { isExternalImage } from './edit';
*/
import { MIN_SIZE, ALLOWED_MEDIA_TYPES } from './constants';
import { evalAspectRatio } from './utils';
import deprecated from '@wordpress/deprecated';

const { DimensionsTool, ResolutionTool } = unlock( blockEditorPrivateApis );

Expand Down Expand Up @@ -113,6 +116,7 @@ export default function Image( {
scale,
linkTarget,
sizeSlug,
lightbox,
} = attributes;

// The only supported unit is px, so we can parseInt to strip the px here.
Expand Down Expand Up @@ -171,6 +175,7 @@ export default function Image( {
},
[ clientId ]
);

const { replaceBlocks, toggleSelection } = useDispatch( blockEditorStore );
const { createErrorNotice, createSuccessNotice } =
useDispatch( noticesStore );
Expand Down Expand Up @@ -365,6 +370,18 @@ export default function Image( {
availableUnits: [ 'px' ],
} );

const lightboxSetting = useSetting( 'lightbox' );

const lightboxChecked = useMemo( () => {
// If the lightbox is set in the block attributes, use that.
if ( lightbox?.enabled ) return true;

// If the lightbox is NOT set in the block attributes AND it IS enabled in
// the settings, use that.
if ( ! lightbox && lightboxSetting?.enabled ) return true;
michalczaplinski marked this conversation as resolved.
Show resolved Hide resolved
return false;
}, [ lightbox, lightboxSetting ] );
Copy link
Contributor

Choose a reason for hiding this comment

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

useMemo is actually adding a lot of extra overhead here. It's just a boolean.

Suggested change
const lightboxChecked = useMemo( () => {
// If the lightbox is set in the block attributes, use that.
if ( lightbox?.enabled ) return true;
// If the lightbox is NOT set in the block attributes AND it IS enabled in
// the settings, use that.
if ( ! lightbox && lightboxSetting?.enabled ) return true;
return false;
}, [ lightbox, lightboxSetting ] );
const lightboxChecked =
lightbox?.enabled || ( ! lightbox && lightboxSetting?.enabled );

While the above matches your logic exactly, this conditional has some unexpected results in my opinion. My examples use the theme.json settings, but relate to the attribute as well.

Here's one example that I think is the flip side of what @youknowriad was saying in https://github.com/WordPress/gutenberg/pull/54071/files#r1317152387.

<!-- { "lightbox": true } -->

Unexpectedly, this does not enable the lightbox.

We often follow this sort of pattern for settings related things in Gutenberg:

  • A feature with options is fully disabled by default.
  • It has a set of default options that get set with { "appearanceTools": true }.
  • The feature can be enabled with default options by setting the feature as true (as above).
  • Or the options can be configured individually by passing the object.
  • Any missing options use the defaults.

These rules don't always hold—we have a lot of inconsistencies. However, this set of rules allows for you to only have to write the minimal set of things they want to override.

It can be enabled with default options:

<!-- { "lightbox": true } -->

It can be enabled with custom options:

<!-- { "lightbox": { "animation": "fade" } } -->

It can be disabled when enabled by default in theme.json:

<!-- { "lightbox": false } -->

It can use the default in theme.json:

<!-- {} -->
<!-- `undefined` values are stripped in block attributes, so this would be equivalent to -->
<!-- { "lightbox": undefined } -->

Moving on to theme.json settings. This example confuses me:

// theme.json
{
	"lightbox": {
		"enabled": false,
		"allowEditing": true
	}
}

If I had this in my theme.json settings. What does it mean? Is this a valid combination? At best it's ambiguous; at worst, invalid.

If it's invalid, we can use the set of rules above makes it impossible to type in an invalid state. In this case the .enabled option doesn't exist—passing an object or true implies that it is enabled.

// theme.json
{
	"lightbox": {
		"allowEditing": true
	}
}

is the same as (===)

// theme.json
{
	"lightbox": true
}

If .enabled is actually the initial state the lightbox value for all images, we should just name it .initial or .default and pass an attribute-shaped thing as the value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

<!-- { "lightbox": true } -->
Unexpectedly, this does not enable the lightbox.

This didn't enable the lightbox because I hadn't added support for that syntax yet. I wasn't sure how to do it last week and I determined with some other folks to add it later, but just took a look again and believe I got it working in this commit, with a follow up here.

Moving on to theme.json settings. This example confuses me:

// theme.json

{
  "lightbox": {
  	"enabled": false,
  	"allowEditing": true
  }
}

If I had this in my theme.json settings. What does it mean? Is this a valid combination? At best it's ambiguous; at worst, invalid.

This is indeed a valid combination. The intent here is for allowEditing to define whether the UI controls show up, and for enabled to determine whether the lightbox behavior should work or not.

If .enabled is actually the initial state the lightbox value for all images, we should just name it .initial or .default and pass an attribute-shaped thing as the value.

This sounds good to me, but I'll tag in @youknowriad @ramonjd @andrewserong, as they were part of a discussion to define the current structure.

The subtlety here, which I'm not sure is clear, is that we want the lightbox to be disabled by default, but we still want the UI to appear, and also be toggleable. I could see the following structure maybe working:

{
	"lightbox": {
		"allowEditing": true
		"default": {
			"enabled": false
		}
	}
}

We'll also likely eventually (probably sooner rather than later) need to add support for an animation property.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here I'm shooting a follow up on this. @ajlende, would you be alright with the proceeding with the structure as is with enabled and allowEditing? (Summarized below)

Note: Using lightbox: true will both show the lightbox in the UI and enable the lightbox functionality on the frontend by default. Setting lightbox: false will remove the lightbox from the UI and disable the lightbox functionality.

Block Level Settings Syntax

"settings": {
	"blocks": {
		"core/image": {
			"lightbox": {
				"enabled": boolean
				"allowEditing": boolean
			}
		}
	}
}
"settings": {
	"blocks": {
		"core/image": {
			"lightbox": boolean
		}
	}
}

Top Level Settings Syntax

"settings": {
	"lightbox": {
		"enabled": boolean
		"allowEditing": boolean
	}
}
"settings": {
	"lightbox": boolean
}


const controls = (
<>
<BlockControls group="block">
Expand Down Expand Up @@ -451,6 +468,7 @@ export default function Image( {
height: undefined,
scale: undefined,
aspectRatio: undefined,
lightbox: undefined,
} )
}
>
Expand Down Expand Up @@ -519,6 +537,24 @@ export default function Image( {
onChange={ updateImage }
options={ imageSizeOptions }
/>
<ToolsPanelItem
hasValue={ () => !! lightbox }
label={ __( 'Expand on Click' ) }
onDeselect={ () => {
setAttributes( { lightbox: undefined } );
} }
isShownByDefault={ true }
>
<ToggleControl
label={ __( 'Expand on Click' ) }
checked={ lightboxChecked }
onChange={ ( newValue ) => {
setAttributes( {
lightbox: { enabled: newValue },
} );
} }
/>
</ToolsPanelItem>
</ToolsPanel>
</InspectorControls>
<InspectorControls group="advanced">
Expand Down Expand Up @@ -726,6 +762,22 @@ export default function Image( {
);
}

const { behaviors } = attributes;

if ( behaviors ) {
deprecated( 'Lightbox using `behaviors` syntax', {
since: '16.7 on 2023.09.27',
version: '16.9 on 2023.10.11',
alternative: 'new lightbox syntax',
plugin: 'Gutenberg',
link: 'https://github.com/WordPress/gutenberg/pull/54071',
hint: `You can update your lightbox settings with the new syntax
by toggling the image block's Expand on Click setting in the global styles
or block settings, or by modifying settings in theme.json with
{ 'blocks': { 'core/image' : { 'lightbox' : { 'enabled': true | false } } } }`,
} );
}
artemiomorales marked this conversation as resolved.
Show resolved Hide resolved

return (
<>
{ /* Hide controls during upload to avoid component remount,
Expand Down
Loading