diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 6a8f3255297c46..f3b647e14c11cf 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -342,7 +342,7 @@ Display multiple images in a rich gallery. ([Source](https://github.com/WordPres - **Category:** media - **Allowed Blocks:** core/image - **Supports:** align, anchor, color (background, gradients, ~~text~~), interactivity (clientNavigation), layout (default, ~~allowEditing~~, ~~allowInheriting~~, ~~allowSwitching~~), spacing (blockGap, margin, padding), units (em, px, rem, vh, vw), ~~html~~ -- **Attributes:** allowResize, caption, columns, fixedHeight, ids, imageCrop, images, linkTarget, linkTo, randomOrder, shortCodeTransforms, sizeSlug +- **Attributes:** allowResize, caption, columns, fixedHeight, ids, imageCrop, images, lightBoxNavigation, linkTarget, linkTo, randomOrder, shortCodeTransforms, sizeSlug ## Group diff --git a/packages/block-library/src/gallery/block.json b/packages/block-library/src/gallery/block.json index 6a2129ec1e056f..f411b61c706cf3 100644 --- a/packages/block-library/src/gallery/block.json +++ b/packages/block-library/src/gallery/block.json @@ -4,6 +4,7 @@ "name": "core/gallery", "title": "Gallery", "category": "media", + "usesContext": [ "galleryId" ], "allowedBlocks": [ "core/image" ], "description": "Display multiple images in a rich gallery.", "keywords": [ "images", "photos" ], @@ -102,6 +103,10 @@ "allowResize": { "type": "boolean", "default": false + }, + "lightBoxNavigation": { + "type": "boolean", + "default": true } }, "providesContext": { diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 1936c02c468189..e253947dfb7946 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -125,8 +125,15 @@ export default function GalleryEdit( props ) { ) : LINK_OPTIONS; - const { columns, imageCrop, randomOrder, linkTarget, linkTo, sizeSlug } = - attributes; + const { + columns, + imageCrop, + randomOrder, + linkTarget, + linkTo, + sizeSlug, + lightBoxNavigation, + } = attributes; const { __unstableMarkNextChangeAsNotPersistent, @@ -442,6 +449,12 @@ export default function GalleryEdit( props ) { } ); } + function toggleLightboxNavigation() { + setAttributes( { + lightBoxNavigation: ! attributes.lightBoxNavigation, + } ); + } + function updateImagesSize( newSizeSlug ) { setAttributes( { sizeSlug: newSizeSlug } ); const changedAttributes = {}; @@ -623,6 +636,15 @@ export default function GalleryEdit( props ) { onChange={ toggleOpenInNewTab } /> ) } + { Platform.isWeb && ! imageSizeOptions && hasImageIds && ( 'block-supports', - ) + array( 'context' => 'block-supports' ) ); + if ( $attributes['lightBoxNavigation'] ) { + // Gets all image IDs from the state that match this gallery's ID. + $state = wp_interactivity_state( 'core/image' ); + $gallery_id = $block->context['galleryId'] ?? null; + $image_ids = array(); + if ( isset( $gallery_id ) && isset( $state['metadata'] ) ) { + foreach ( $state['metadata'] as $image_id => $metadata ) { + if ( isset( $metadata['galleryId'] ) && $metadata['galleryId'] === $gallery_id ) { + $image_ids[] = $image_id; + } + } + } + + $processed_content->set_attribute( 'data-wp-interactive', 'core/gallery' ); + $processed_content->set_attribute( + 'data-wp-context', + wp_json_encode( + array( 'galleryId' => $gallery_id ), + JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP + ) + ); + + // Populates the aria label for each image in the gallery. + if ( ! empty( $image_ids ) ) { + if ( 1 <= count( $image_ids ) ) { + for ( $i = 0; $i < count( $image_ids ); $i++ ) { + $image_id = $image_ids[ $i ]; + $alt = $state['metadata'][ $image_id ]['alt']; + wp_interactivity_state( + 'core/image', + array( + 'metadata' => array( + $image_id => array( + 'customAriaLabel' => empty( $alt ) + /* translators: %1$s: current image index, %2$s: total number of images */ + ? sprintf( __( 'Enlarged image %1$s of %2$s' ), $i + 1, count( $image_ids ) ) + /* translators: %1$s: current image index, %2$s: total number of images, %3$s: Image alt text */ + : sprintf( __( 'Enlarged image %1$s of %2$s: %3$s' ), $i + 1, count( $image_ids ), $alt ), + ), + ), + ) + ); + } + } + } + } + // The WP_HTML_Tag_Processor class calls get_updated_html() internally // when the instance is treated as a string, but here we explicitly // convert it to a string. @@ -166,6 +230,7 @@ static function () use ( $image_blocks, &$i ) { return $content; } + /** * Registers the `core/gallery` block on server. * diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 26835df9e856cd..b5d12b048f0112 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -10,7 +10,8 @@ "fixedHeight", "postId", "postType", - "queryId" + "queryId", + "galleryId" ], "description": "Insert an image to make a visual statement.", "keywords": [ "img", "photo", "picture" ], diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index 697f67a927fc87..2c8b4ef7012c92 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -80,7 +80,7 @@ function render_block_core_image( $attributes, $content, $block ) { * if the way the blocks are rendered changes, or if a new kind of filter is * introduced. */ - add_filter( 'render_block_core/image', 'block_core_image_render_lightbox', 15, 2 ); + add_filter( 'render_block_core/image', 'block_core_image_render_lightbox', 15, 3 ); } else { /* * Remove the filter if previously added by other Image blocks. @@ -130,18 +130,20 @@ function block_core_image_get_lightbox_settings( $block ) { * * @since 6.4.0 * - * @param string $block_content Rendered block content. - * @param array $block Block object. + * @param string $block_content Rendered block content. + * @param array $block Block object. + * @param array $block_instance Block instance. * * @return string Filtered block content. */ -function block_core_image_render_lightbox( $block_content, $block ) { +function block_core_image_render_lightbox( $block_content, $block, $block_instance ) { /* * If there's no IMG tag in the block then return the given block content * as-is. There's nothing that this code can knowingly modify to add the * lightbox behavior. */ $p = new WP_HTML_Tag_Processor( $block_content ); + if ( $p->next_tag( 'figure' ) ) { $p->set_bookmark( 'figure' ); } @@ -149,14 +151,22 @@ function block_core_image_render_lightbox( $block_content, $block ) { return $block_content; } - $alt = $p->get_attribute( 'alt' ); - $img_uploaded_src = $p->get_attribute( 'src' ); - $img_class_names = $p->get_attribute( 'class' ); - $img_styles = $p->get_attribute( 'style' ); - $img_width = 'none'; - $img_height = 'none'; - $aria_label = __( 'Enlarge' ); - $dialog_aria_label = __( 'Enlarged image' ); + $alt = $p->get_attribute( 'alt' ); + $img_uploaded_src = $p->get_attribute( 'src' ); + $img_class_names = $p->get_attribute( 'class' ); + $img_styles = $p->get_attribute( 'style' ); + $img_width = 'none'; + $img_height = 'none'; + + wp_interactivity_config( + 'core/image', + array( 'defaultAriaLabel' => __( 'Enlarged image' ) ) + ); + + if ( $alt ) { + /* translators: %s: Image alt text. */ + $custom_aria_label = sprintf( __( 'Enlarged image: %s' ), $alt ); + } if ( isset( $block['attrs']['id'] ) ) { $img_uploaded_src = wp_get_attachment_url( $block['attrs']['id'] ); @@ -172,7 +182,6 @@ function block_core_image_render_lightbox( $block_content, $block ) { // Create unique id and set the image metadata in the state. $unique_image_id = uniqid(); - wp_interactivity_state( 'core/image', array( @@ -186,8 +195,9 @@ function block_core_image_render_lightbox( $block_content, $block ) { 'targetWidth' => $img_width, 'targetHeight' => $img_height, 'scaleAttr' => $block['attrs']['scale'] ?? false, - 'ariaLabel' => $dialog_aria_label, 'alt' => $alt, + 'galleryId' => $block_instance->context['galleryId'] ?? null, + 'customAriaLabel' => $custom_aria_label ?? null, ), ), ) @@ -198,9 +208,7 @@ function block_core_image_render_lightbox( $block_content, $block ) { $p->set_attribute( 'data-wp-context', wp_json_encode( - array( - 'imageId' => $unique_image_id, - ), + array( 'imageId' => $unique_image_id ), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) ); @@ -229,11 +237,11 @@ function block_core_image_render_lightbox( $block_content, $block ) { class="lightbox-trigger" type="button" aria-haspopup="dialog" - aria-label="' . esc_attr( $aria_label ) . '" + aria-label="' . esc_attr( __( 'Enlarge' ) ) . '" data-wp-init="callbacks.initTriggerButton" data-wp-on-async--click="actions.showLightbox" - data-wp-style--right="state.imageButtonRight" - data-wp-style--top="state.imageButtonTop" + data-wp-style--right="state.thisImage.buttonRight" + data-wp-style--top="state.thisImage.buttonTop" > @@ -252,6 +260,9 @@ class="lightbox-trigger" */ function block_core_image_print_lightbox_overlay() { $close_button_label = esc_attr__( 'Close' ); + $dialog_label = esc_attr__( 'Enlarged images' ); + $prev_button_label = esc_attr__( 'Previous' ); + $next_button_label = esc_attr__( 'Next' ); // If the current theme does NOT have a `theme.json`, or the colors are not // defined, it needs to set the background color & close button color to some @@ -271,14 +282,16 @@ function block_core_image_print_lightbox_overlay() { echo << - + +
HTML; diff --git a/packages/block-library/src/image/style.scss b/packages/block-library/src/image/style.scss index 117045f7dce627..eb0d67a1113f55 100644 --- a/packages/block-library/src/image/style.scss +++ b/packages/block-library/src/image/style.scss @@ -207,7 +207,7 @@ visibility: hidden; cursor: zoom-out; - .close-button { + .wp-lightbox-close-button { position: absolute; top: calc(env(safe-area-inset-top) + 16px); // equivalent to $grid-unit-20 right: calc(env(safe-area-inset-right) + 16px); // equivalent to $grid-unit-20 @@ -228,6 +228,78 @@ } } + .wp-lightbox-navigation-container-prev, + .wp-lightbox-navigation-container-next { + display: none; + position: absolute; + top: 50%; + transform: translateY(-50%); + padding: 0; + cursor: pointer; + z-index: 2000002; + + &[hidden] { + display: none; + } + + @include break-mobile() { + display: block; + } + } + + .wp-lightbox-navigation-button { + min-width: 40px; // equivalent to $button-size-next-default-40px + min-height: 40px; // equivalent to $button-size-next-default-40px; + display: flex; + cursor: pointer; + align-items: center; + justify-content: center; + + &[aria-disabled="true"] svg { + opacity: 0.3; + } + + &:hover, + &:focus { + background: none; + border: none; + + + .wp-lightbox-navigation-tooltip { + display: block; + } + } + } + + .wp-lightbox-navigation-tooltip { + display: none; + background: #000; + border-radius: 2px; + color: #fff; + text-align: center; + line-height: 1.4; + font-size: 12px; + padding: 4px 8px; + margin: 0; + position: absolute; + top: calc(100% + 8px); + } + + .wp-lightbox-navigation-container-prev { + left: calc(env(safe-area-inset-left) + 16px); + + .wp-lightbox-navigation-tooltip { + left: 0; + } + } + + .wp-lightbox-navigation-container-next { + right: calc(env(safe-area-inset-right) + 16px); + + .wp-lightbox-navigation-tooltip { + right: 0; + } + } + .lightbox-image-container { position: absolute; overflow: hidden; @@ -237,7 +309,7 @@ transform: translate(-50%, -50%); width: var(--wp--lightbox-container-width); height: var(--wp--lightbox-container-height); - z-index: 9999999999; + z-index: 2000001; } .wp-block-image { diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 71a492a570b2ae..fb2eeedfc3d058 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -5,6 +5,7 @@ import { store, getContext, getElement, + getConfig, withSyncEvent, } from '@wordpress/interactivity'; @@ -24,16 +25,52 @@ let isTouching = false; */ let lastTouchTime = 0; +const focusableSelectors = [ + '.wp-lightbox-close-button', + '.wp-lightbox-navigation-button', +]; + const { state, actions, callbacks } = store( 'core/image', { state: { - currentImageId: null, - get currentImage() { - return state.metadata[ state.currentImageId ]; + selectedImageId: null, + selectedGalleryId: null, + get galleryImages() { + return state.selectedGalleryId + ? Object.entries( state.metadata ) + .filter( + ( [ , value ] ) => + value.galleryId === state.selectedGalleryId + ) + .map( ( [ key ] ) => key ) + : [ state.selectedImageId ]; + }, + get selectedImageIndex() { + return state.galleryImages.findIndex( + ( id ) => id === state.selectedImageId + ); + }, + get selectedImage() { + return state.metadata[ state.selectedImageId ]; + }, + get thisImage() { + const { imageId } = getContext(); + return state.metadata[ imageId ]; + }, + get hasNavigation() { + return state.galleryImages.length > 1; + }, + get hasNextImage() { + return ( + state.selectedImageIndex + 1 < state.galleryImages.length + ); + }, + get hasPreviousImage() { + return state.selectedImageIndex - 1 >= 0; }, get overlayOpened() { - return state.currentImageId !== null; + return state.selectedImageId !== null; }, get roleAttribute() { return state.overlayOpened ? 'dialog' : null; @@ -41,16 +78,22 @@ const { state, actions, callbacks } = store( get ariaModal() { return state.overlayOpened ? 'true' : null; }, + get ariaLabel() { + return ( + state.selectedImage.customAriaLabel || + getConfig().defaultAriaLabel + ); + }, get enlargedSrc() { return ( - state.currentImage.uploadedSrc || + state.selectedImage.uploadedSrc || 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' ); }, get figureStyles() { return ( state.overlayOpened && - `${ state.currentImage.figureStyles?.replace( + `${ state.selectedImage.figureStyles?.replace( /margin[^;]*;?/g, '' ) };` @@ -59,31 +102,24 @@ const { state, actions, callbacks } = store( get imgStyles() { return ( state.overlayOpened && - `${ state.currentImage.imgStyles?.replace( + `${ state.selectedImage.imgStyles?.replace( /;$/, '' ) }; object-fit:cover;` ); }, - get imageButtonRight() { - const { imageId } = getContext(); - return state.metadata[ imageId ].imageButtonRight; - }, - get imageButtonTop() { - const { imageId } = getContext(); - return state.metadata[ imageId ].imageButtonTop; - }, get isContentHidden() { const ctx = getContext(); return ( - state.overlayEnabled && state.currentImageId === ctx.imageId + state.overlayEnabled && + state.selectedImageId === ctx.imageId ); }, get isContentVisible() { const ctx = getContext(); return ( ! state.overlayEnabled && - state.currentImageId === ctx.imageId + state.selectedImageId === ctx.imageId ); }, }, @@ -101,9 +137,11 @@ const { state, actions, callbacks } = store( state.scrollTopReset = document.documentElement.scrollTop; state.scrollLeftReset = document.documentElement.scrollLeft; - // Sets the current expanded image in the state and enables the overlay. + // Sets the selected image and gallery and enables the overlay. + state.selectedImageId = imageId; + const { galleryId } = getContext( 'core/gallery' ) || {}; + state.selectedGalleryId = galleryId || null; state.overlayEnabled = true; - state.currentImageId = imageId; // Computes the styles of the overlay for the animation. callbacks.setOverlayStyles(); @@ -124,26 +162,61 @@ const { state, actions, callbacks } = store( // Delays before changing the focus. Otherwise the focus ring will // appear on Firefox before the image has finished animating, which // looks broken. - state.currentImage.buttonRef.focus( { + state.selectedImage.buttonRef.focus( { preventScroll: true, } ); - // Resets the current image id to mark the overlay as closed. - state.currentImageId = null; + // Resets the selected image and gallery ids. + state.selectedImageId = null; + state.selectedGalleryId = null; }, 450 ); } }, + showPreviousImage: withSyncEvent( ( event ) => { + event.stopPropagation(); + if ( state.hasPreviousImage ) { + state.selectedImageId = + state.galleryImages[ state.selectedImageIndex - 1 ]; + callbacks.setOverlayStyles(); + } + } ), + showNextImage: withSyncEvent( ( event ) => { + event.stopPropagation(); + if ( state.hasNextImage ) { + state.selectedImageId = + state.galleryImages[ state.selectedImageIndex + 1 ]; + callbacks.setOverlayStyles(); + } + } ), handleKeydown: withSyncEvent( ( event ) => { if ( state.overlayEnabled ) { - // Focuses the close button when the user presses the tab key. - if ( event.key === 'Tab' ) { - event.preventDefault(); - const { ref } = getElement(); - ref.querySelector( 'button' ).focus(); - } - // Closes the lightbox when the user presses the escape key. if ( event.key === 'Escape' ) { actions.hideLightbox(); + } else if ( event.key === 'ArrowLeft' ) { + actions.showPreviousImage( event ); + } else if ( event.key === 'ArrowRight' ) { + actions.showNextImage( event ); + } else if ( event.key === 'Tab' ) { + // Traps focus within the overlay. + const focusableElements = Array.from( + document.querySelectorAll( focusableSelectors ) + ); + const firstFocusableElement = focusableElements[ 0 ]; + const lastFocusableElement = + focusableElements[ focusableElements.length - 1 ]; + if ( + event.shiftKey && + event.target === firstFocusableElement + ) { + event.preventDefault(); + lastFocusableElement.focus(); + } else if ( + ! event.shiftKey && + event.target === lastFocusableElement + ) { + event.preventDefault(); + firstFocusableElement.focus(); + } } } } ), @@ -202,9 +275,9 @@ const { state, actions, callbacks } = store( naturalHeight, offsetWidth: originalWidth, offsetHeight: originalHeight, - } = state.currentImage.imageRef; + } = state.selectedImage.imageRef; let { x: screenPosX, y: screenPosY } = - state.currentImage.imageRef.getBoundingClientRect(); + state.selectedImage.imageRef.getBoundingClientRect(); // Natural ratio of the image clicked to open the lightbox. const naturalRatio = naturalWidth / naturalHeight; @@ -213,7 +286,7 @@ const { state, actions, callbacks } = store( // If it has object-fit: contain, recalculates the original sizes // and the screen position without the blank spaces. - if ( state.currentImage.scaleAttr === 'contain' ) { + if ( state.selectedImage.scaleAttr === 'contain' ) { if ( naturalRatio > originalRatio ) { const heightWithoutSpace = originalWidth / naturalRatio; // Recalculates screen position without the top space. @@ -234,13 +307,15 @@ const { state, actions, callbacks } = store( // size), the image's dimensions in the lightbox are the same // as those of the image in the content. let imgMaxWidth = parseFloat( - state.currentImage.targetWidth !== 'none' - ? state.currentImage.targetWidth + state.selectedImage.targetWidth && + state.selectedImage.targetWidth !== 'none' + ? state.selectedImage.targetWidth : naturalWidth ); let imgMaxHeight = parseFloat( - state.currentImage.targetHeight !== 'none' - ? state.currentImage.targetHeight + state.selectedImage.targetHeight && + state.selectedImage.targetHeight !== 'none' + ? state.selectedImage.targetHeight : naturalHeight ); @@ -307,7 +382,7 @@ const { state, actions, callbacks } = store( // the image resolution. let horizontalPadding = 0; if ( window.innerWidth > 480 ) { - horizontalPadding = 80; + horizontalPadding = state.hasNavigation ? 140 : 80; } else if ( window.innerWidth > 1920 ) { horizontalPadding = 160; } @@ -406,8 +481,8 @@ const { state, actions, callbacks } = store( const buttonOffsetTop = figureHeight - offsetHeight; const buttonOffsetRight = figureWidth - offsetWidth; - let imageButtonTop = buttonOffsetTop + 16; - let imageButtonRight = buttonOffsetRight + 16; + let buttonTop = buttonOffsetTop + 16; + let buttonRight = buttonOffsetRight + 16; // In the case of an image with object-fit: contain, the size of the // element can be larger than the image itself, so it needs to @@ -422,25 +497,25 @@ const { state, actions, callbacks } = store( // If it reaches the width first, it keeps the width and compute the // height. const referenceHeight = offsetWidth / naturalRatio; - imageButtonTop = + buttonTop = ( offsetHeight - referenceHeight ) / 2 + buttonOffsetTop + 16; - imageButtonRight = buttonOffsetRight + 16; + buttonRight = buttonOffsetRight + 16; } else { // If it reaches the height first, it keeps the height and compute // the width. const referenceWidth = offsetHeight * naturalRatio; - imageButtonTop = buttonOffsetTop + 16; - imageButtonRight = + buttonTop = buttonOffsetTop + 16; + buttonRight = ( offsetWidth - referenceWidth ) / 2 + buttonOffsetRight + 16; } } - state.metadata[ imageId ].imageButtonTop = imageButtonTop; - state.metadata[ imageId ].imageButtonRight = imageButtonRight; + state.metadata[ imageId ].buttonTop = buttonTop; + state.metadata[ imageId ].buttonRight = buttonRight; }, setOverlayFocus() { if ( state.overlayEnabled ) { @@ -449,6 +524,18 @@ const { state, actions, callbacks } = store( ref.focus(); } }, + setInertElements() { + // Makes all children of the document inert exempt .wp-lightbox-overlay. + document + .querySelectorAll( 'body > :not(.wp-lightbox-overlay)' ) + .forEach( ( el ) => { + if ( state.overlayEnabled ) { + el.setAttribute( 'inert', '' ); + } else { + el.removeAttribute( 'inert' ); + } + } ); + }, initTriggerButton() { const { imageId } = getContext(); const { ref } = getElement(); diff --git a/test/integration/fixtures/blocks/core__gallery-with-caption.json b/test/integration/fixtures/blocks/core__gallery-with-caption.json index 1106c8ccb64b2a..041475047de51d 100644 --- a/test/integration/fixtures/blocks/core__gallery-with-caption.json +++ b/test/integration/fixtures/blocks/core__gallery-with-caption.json @@ -13,6 +13,7 @@ "linkTo": "none", "sizeSlug": "large", "allowResize": false, + "lightBoxNavigation": true, "className": "columns-2" }, "innerBlocks": [ diff --git a/test/integration/fixtures/blocks/core__gallery.json b/test/integration/fixtures/blocks/core__gallery.json index 27fc4c75dc8dc0..53765394f5ce8e 100644 --- a/test/integration/fixtures/blocks/core__gallery.json +++ b/test/integration/fixtures/blocks/core__gallery.json @@ -13,6 +13,7 @@ "linkTo": "none", "sizeSlug": "large", "allowResize": false, + "lightBoxNavigation": true, "className": "columns-2" }, "innerBlocks": [ diff --git a/test/integration/fixtures/blocks/core__gallery__columns.json b/test/integration/fixtures/blocks/core__gallery__columns.json index beb97c3ac50802..6f08ccad7a355b 100644 --- a/test/integration/fixtures/blocks/core__gallery__columns.json +++ b/test/integration/fixtures/blocks/core__gallery__columns.json @@ -13,7 +13,8 @@ "fixedHeight": true, "linkTo": "none", "sizeSlug": "large", - "allowResize": false + "allowResize": false, + "lightBoxNavigation": true }, "innerBlocks": [ { diff --git a/test/integration/fixtures/blocks/core__gallery__deprecated-7.json b/test/integration/fixtures/blocks/core__gallery__deprecated-7.json index 05a630370f9b09..82b4dbf74976dc 100644 --- a/test/integration/fixtures/blocks/core__gallery__deprecated-7.json +++ b/test/integration/fixtures/blocks/core__gallery__deprecated-7.json @@ -12,7 +12,8 @@ "fixedHeight": true, "linkTo": "media", "sizeSlug": "large", - "allowResize": false + "allowResize": false, + "lightBoxNavigation": true }, "innerBlocks": [ {