From 5c8340d9132b78a7fed50818786a3fcee29af666 Mon Sep 17 00:00:00 2001 From: Alexandre Lara Date: Thu, 5 Oct 2023 13:55:52 -0300 Subject: [PATCH] Product Gallery > Next/Previous Buttons block: Add support to Interactivity API (#10938) * Add interactivity API to the Pager block * Replace Large Image when clicking on page * Fix php cs errors * Fix php cs errors * Fix php cs errors * fix php cs errors * Add support to Interactivity API * Fix phpcs errors * Fix phpcs errors * Remove unnecessary code and fix block classes * Rename interactivity actions * Remove unnecessary type conversion * Fix error when clicking on page in Pager block * Fix php cs errors * Fix ProductGalleryUtils import * fix php cs error * Fix styles for next/previous buttons * Fix styles for the next/previous buttons * Fix php cs errors * Fix next/previous icons when buttons are outside image * Fix php cs errors * Fix php cs errors * Fix buttons not visible in Editor * Delete src/SpeciticTemplateController.php Delete unnecessary file that is causing php cs error --- assets/js/blocks/product-gallery/frontend.tsx | 29 +++ .../editor.scss | 7 +- .../product-gallery-large-image/editor.scss | 7 - assets/js/blocks/product-gallery/style.scss | 7 +- src/BlockTypes/ProductGallery.php | 16 +- .../ProductGalleryLargeImageNextPrevious.php | 200 +++++++++++------- src/BlockTypes/ProductGalleryPager.php | 2 +- src/Utils/ProductGalleryUtils.php | 22 +- 8 files changed, 192 insertions(+), 98 deletions(-) diff --git a/assets/js/blocks/product-gallery/frontend.tsx b/assets/js/blocks/product-gallery/frontend.tsx index e102dbad085..93af417a031 100644 --- a/assets/js/blocks/product-gallery/frontend.tsx +++ b/assets/js/blocks/product-gallery/frontend.tsx @@ -11,6 +11,7 @@ interface Context { woocommerce: { selectedImage: string; imageId: string; + visibleImagesIds: string[]; isDialogOpen: boolean; }; } @@ -19,6 +20,7 @@ interface Selectors { woocommerce: { isSelected: ( store: unknown ) => boolean; pagerDotFillOpacity: ( store: SelectorsStore ) => number; + selectedImageIndex: ( store: SelectorsStore ) => number; isDialogOpen: ( store: unknown ) => boolean; }; } @@ -80,6 +82,33 @@ interactivityApiStore( { handleSelectImage: ( { context }: Store ) => { context.woocommerce.selectedImage = context.woocommerce.imageId; }, + handleNextImageButtonClick: ( store: Store ) => { + const { context } = store; + const selectedImageIdIndex = + context.woocommerce.visibleImagesIds.indexOf( + context.woocommerce.selectedImage + ); + const nextImageIndex = Math.min( + selectedImageIdIndex + 1, + context.woocommerce.visibleImagesIds.length - 1 + ); + + context.woocommerce.selectedImage = + context.woocommerce.visibleImagesIds[ nextImageIndex ]; + }, + handlePreviousImageButtonClick: ( store: Store ) => { + const { context } = store; + const selectedImageIdIndex = + context.woocommerce.visibleImagesIds.indexOf( + context.woocommerce.selectedImage + ); + const previousImageIndex = Math.max( + selectedImageIdIndex - 1, + 0 + ); + context.woocommerce.selectedImage = + context.woocommerce.visibleImagesIds[ previousImageIndex ]; + }, }, }, } ); diff --git a/assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image-next-previous/editor.scss b/assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image-next-previous/editor.scss index 9f557bc69fd..d19b69f6e58 100644 --- a/assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image-next-previous/editor.scss +++ b/assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image-next-previous/editor.scss @@ -5,9 +5,8 @@ width: 100%; position: absolute; height: 50px; -} -.wc-block-editor-product-gallery-large-image-next-previous--outside-image .wc-block-product-gallery-large-image-next-previous { - margin-right: 0; - margin-left: 0; + svg { + z-index: 1; + } } diff --git a/assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image/editor.scss b/assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image/editor.scss index 64e93fcaa06..65b0e5b7bf6 100644 --- a/assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image/editor.scss +++ b/assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image/editor.scss @@ -9,10 +9,3 @@ max-width: calc(100% - 60px); } } - -.wc-block-product-gallery-large-image__inner-blocks { - .wc-block-editor-product-gallery-large-image-next-previous--outside-image & > * { - margin-left: 30px; - margin-right: 30px; - } -} diff --git a/assets/js/blocks/product-gallery/style.scss b/assets/js/blocks/product-gallery/style.scss index 396c2c3c76d..126b943eb1e 100644 --- a/assets/js/blocks/product-gallery/style.scss +++ b/assets/js/blocks/product-gallery/style.scss @@ -107,9 +107,13 @@ $outside-image-max-width: calc(100% - (2 * $outside-image-offset)); width: 100%; height: 100%; - svg { + button { + cursor: pointer; z-index: 3; pointer-events: all; + padding: 0; + border: none; + background: none; } .is-vertically-aligned-top { @@ -215,4 +219,3 @@ $outside-image-max-width: calc(100% - (2 * $outside-image-offset)); } } - diff --git a/src/BlockTypes/ProductGallery.php b/src/BlockTypes/ProductGallery.php index aea7bc25267..8a491c727a9 100644 --- a/src/BlockTypes/ProductGallery.php +++ b/src/BlockTypes/ProductGallery.php @@ -1,8 +1,8 @@ render_dialog() : ''; - $post_id = $block->context['postId'] ?? ''; - $product = wc_get_product( $post_id ); + $number_of_thumbnails = $block->attributes['thumbnailsNumberOfThumbnails'] ?? 0; + $classname = $attributes['className'] ?? ''; + $dialog = ( true === $attributes['fullScreenOnClick'] && isset( $attributes['mode'] ) && 'full' !== $attributes['mode'] ) ? $this->render_dialog() : ''; + $post_id = $block->context['postId'] ?? ''; + $product = wc_get_product( $post_id ); $html = $this->inject_dialog( $content, $dialog ); $p = new \WP_HTML_Tag_Processor( $html ); @@ -136,8 +137,9 @@ protected function render( $attributes, $content, $block ) { wp_json_encode( array( 'woocommerce' => array( - 'selectedImage' => $product->get_image_id(), - 'isDialogOpen' => false, + 'selectedImage' => $product->get_image_id(), + 'visibleImagesIds' => ProductGalleryUtils::get_product_gallery_image_ids( $product, $number_of_thumbnails, true ), + 'isDialogOpen' => false, ), ) ) diff --git a/src/BlockTypes/ProductGalleryLargeImageNextPrevious.php b/src/BlockTypes/ProductGalleryLargeImageNextPrevious.php index f45ec53bc8a..60fd86f9410 100644 --- a/src/BlockTypes/ProductGalleryLargeImageNextPrevious.php +++ b/src/BlockTypes/ProductGalleryLargeImageNextPrevious.php @@ -40,83 +40,23 @@ protected function get_block_type_uses_context() { } /** - * Return icons and class based on the nextPreviousButtonsPosition option + * Return class suffix * * @param array $context Block context. * @return string */ - private function get_icons( $context ) { + private function get_class_suffix( $context ) { switch ( $context['nextPreviousButtonsPosition'] ) { case 'insideTheImage': - return array( - 'class' => 'inside-image', - 'prev_button' => ' - - - - - - - - - - - - - ', - 'next_button' => ' - - - - - - - - - - - - - ', - ); + return 'inside-image'; case 'outsideTheImage': - return array( - 'class' => 'outside-image', - 'prev_button' => ' - - ', - 'next_button' => ' - - ', - ); - + return 'outside-image'; case 'off': - return array( - 'class' => 'off', - ); + return 'off'; default: - return array( 'class' => 'off' ); - } } + return 'off'; + } + } /** * Include and render the block. @@ -141,11 +81,30 @@ protected function render( $attributes, $content, $block ) { } $context = $block->context; - $prev_button = isset( $this->get_icons( $context )['prev_button'] ) ? $this->get_icons( $context )['prev_button'] : ''; - $next_button = isset( $this->get_icons( $context )['next_button'] ) ? $this->get_icons( $context )['next_button'] : ''; + $prev_button = $this->get_button( 'previous', $context ); + $p = new \WP_HTML_Tag_Processor( $prev_button ); - $alignment_class = isset( $attributes['layout']['verticalAlignment'] ) ? 'is-vertically-aligned-' . esc_attr( $attributes['layout']['verticalAlignment'] ) : ''; - $position_class = 'wc-block-product-gallery-large-image-next-previous--' . $this->get_icons( $context )['class']; + if ( $p->next_tag() ) { + $p->set_attribute( + 'data-wc-on--click', + 'actions.woocommerce.handlePreviousImageButtonClick' + ); + $prev_button = $p->get_updated_html(); + } + + $next_button = $this->get_button( 'next', $context ); + $p = new \WP_HTML_Tag_Processor( $next_button ); + + if ( $p->next_tag() ) { + $p->set_attribute( + 'data-wc-on--click', + 'actions.woocommerce.handleNextImageButtonClick' + ); + $next_button = $p->get_updated_html(); + } + + $alignment_class = isset( $attributes['layout']['verticalAlignment'] ) ? 'is-vertically-aligned-' . $attributes['layout']['verticalAlignment'] : ''; + $position_class = 'wc-block-product-gallery-large-image-next-previous--' . $this->get_class_suffix( $context ); return strtr( '