Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 484d4bf

Browse files
Product Gallery: Polish Gallery in full view mode (#10947)
* Product Gallery: add support for On Sale Badge Block * add align support * Add E2E tests * set margin via Block Styles * disable experimental flag * add next previous block * restore support file * fix TS error * fix layout * change product * change product * Product Gallert Block: Add zoom on hover * set to true by default * remove block is already registered error * remove unecessary await * Improve zoom logic Co-authored-by: Alexandre Lara <[email protected]> * Product Gallery Full view mode: Add the logic to render the dedicated template * use template-part instead template * add E2E tests * update selectors * add feature flag product gallery template part * fix E2E tests * remove not necessary file * polish the dialog * fix: dialog show always the selected product * fix: not open the dialog when the user click on icon * rename handleClick to handleCloseButtonClick * improve style * fix overlay css * fix registration * improve logic * improve default template --------- Co-authored-by: Alexandre Lara <[email protected]>
1 parent 1cbc69f commit 484d4bf

File tree

11 files changed

+171
-55
lines changed

11 files changed

+171
-55
lines changed

assets/js/blocks/product-gallery/block.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"productGalleryClientId": "productGalleryClientId",
2121
"nextPreviousButtonsPosition": "nextPreviousButtonsPosition",
2222
"pagerDisplayMode": "pagerDisplayMode",
23-
"hoverZoom": "hoverZoom"
23+
"hoverZoom": "hoverZoom",
24+
"fullScreenOnClick": "fullScreenOnClick"
2425
},
2526
"usesContext": [ "postId" ],
2627
"attributes": {

assets/js/blocks/product-gallery/edit.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,14 @@ const TEMPLATE: InnerBlockTemplate[] = [
8888
],
8989
];
9090

91-
const setMode = (
92-
currentTemplateId: string,
93-
templateType: string,
94-
setAttributes: ( attrs: Partial< ProductGalleryAttributes > ) => void
95-
) => {
91+
const getMode = ( currentTemplateId: string, templateType: string ) => {
9692
if (
9793
templateType === 'wp_template_part' &&
9894
currentTemplateId.includes( 'product-gallery' )
9995
) {
100-
setAttributes( {
101-
mode: 'full',
102-
} );
96+
return 'full';
10397
}
98+
return 'standard';
10499
};
105100

106101
export const Edit = ( {
@@ -123,17 +118,22 @@ export const Edit = ( {
123118
);
124119

125120
useEffect( () => {
126-
setMode( currentTemplateId, templateType, setAttributes );
127-
}, [ currentTemplateId, setAttributes, templateType ] );
121+
const mode = getMode( currentTemplateId, templateType );
128122

129-
useEffect( () => {
130123
setAttributes( {
131124
...attributes,
125+
mode,
132126
productGalleryClientId: clientId,
133127
} );
134128
// Move the Thumbnails block to the correct above or below the Large Image based on the thumbnailsPosition attribute.
135129
moveInnerBlocksToPosition( attributes, clientId );
136-
}, [ setAttributes, attributes, clientId ] );
130+
}, [
131+
setAttributes,
132+
attributes,
133+
clientId,
134+
currentTemplateId,
135+
templateType,
136+
] );
137137

138138
return (
139139
<div { ...blockProps }>

assets/js/blocks/product-gallery/frontend.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ interactivityApiStore( {
6060
: 0.2;
6161
},
6262
isDialogOpen: ( { context }: Store ) => {
63-
return context?.woocommerce.isDialogOpen;
63+
return context.woocommerce.isDialogOpen;
6464
},
6565
},
6666
},
@@ -72,6 +72,11 @@ interactivityApiStore( {
7272
context.woocommerce.imageId;
7373
},
7474
},
75+
dialog: {
76+
handleCloseButtonClick: ( { context }: Store ) => {
77+
context.woocommerce.isDialogOpen = false;
78+
},
79+
},
7580
handleSelectImage: ( { context }: Store ) => {
7681
context.woocommerce.selectedImage = context.woocommerce.imageId;
7782
},
Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
22
* External dependencies
33
*/
4-
import { registerBlockSingleProductTemplate } from '@woocommerce/atomic-utils';
54
import { isExperimentalBuild } from '@woocommerce/block-settings';
5+
import { registerBlockType } from '@wordpress/blocks';
66

77
/**
88
* Internal dependencies
@@ -18,16 +18,10 @@ import './inner-blocks/product-gallery-pager';
1818
import './inner-blocks/product-gallery-thumbnails';
1919

2020
if ( isExperimentalBuild() ) {
21-
registerBlockSingleProductTemplate( {
22-
blockName: metadata.name,
23-
// @ts-expect-error: `metadata` currently does not have a type definition in WordPress core
24-
blockMetadata: metadata,
25-
blockSettings: {
26-
icon,
27-
// @ts-expect-error `edit` can be extended to include other attributes
28-
edit: Edit,
29-
save: Save,
30-
},
31-
isAvailableOnPostEditor: true,
21+
// @ts-expect-error: `metadata` currently does not have a type definition in WordPress core.
22+
registerBlockType( metadata, {
23+
icon,
24+
edit: Edit,
25+
save: Save,
3226
} );
3327
}

assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image/block.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"description": "Display the Large Image of a product.",
88
"category": "woocommerce",
99
"keywords": [ "WooCommerce" ],
10-
"usesContext": [ "nextPreviousButtonsPosition", "postId", "hoverZoom"],
10+
"usesContext": [ "nextPreviousButtonsPosition", "postId", "hoverZoom", "fullScreenOnClick"],
1111
"supports": {
1212
"interactivity": true
1313
},

assets/js/blocks/product-gallery/inner-blocks/product-gallery-large-image/frontend.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,16 @@ interactivityStore(
6565
context.woocommerce.styles.transform = `scale(1.0)`;
6666
context.woocommerce.styles[ 'transform-origin' ] = '';
6767
},
68-
handleClick: ( { context }: { context: Context } ) => {
69-
context.woocommerce.isDialogOpen = true;
68+
handleClick: ( {
69+
context,
70+
event,
71+
}: {
72+
context: Context;
73+
event: Event;
74+
} ) => {
75+
if ( ( event.target as HTMLElement ).tagName === 'IMG' ) {
76+
context.woocommerce.isDialogOpen = true;
77+
}
7078
},
7179
},
7280
},

assets/js/blocks/product-gallery/style.scss

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,39 @@ $outside-image-max-width: calc(100% - (2 * $outside-image-offset));
1111

1212
// Product Gallery
1313
#{$gallery} {
14+
.wc-block-product-gallery-dialog__overlay {
15+
height: 100vh;
16+
width: 100vw;
17+
position: fixed;
18+
top: 0;
19+
left: 0;
20+
background-color: #808080;
21+
z-index: 9999;
22+
}
23+
1424
dialog {
1525
position: fixed;
16-
width: 90vw;
26+
width: calc(100vw - 100px);
27+
border: none;
28+
border-radius: 10px;
1729
height: 90vh;
1830
top: 0;
19-
margin: $gap-largest;
31+
margin-top: $gap-largest;
32+
margin-bottom: $gap-largest;
2033
z-index: 9999;
34+
35+
.wc-block-product-galler-dialog__header-right {
36+
display: flex;
37+
justify-content: flex-end;
38+
39+
.wc-block-product-gallery-dialog__close {
40+
border: none;
41+
background-color: transparent;
42+
outline: none;
43+
cursor: pointer;
44+
}
45+
}
46+
2147
}
2248
}
2349

@@ -37,9 +63,16 @@ $outside-image-max-width: calc(100% - (2 * $outside-image-offset));
3763

3864
img {
3965
display: block;
66+
position: relative;
4067
margin: 0 auto;
68+
z-index: 1;
4169
transition: all 0.1s linear;
4270

71+
// Keep the order in this way. The hoverZoom class should override the full-screen-on-click class when both are applied.
72+
&.wc-block-woocommerce-product-gallery-large-image__image--full-screen-on-click {
73+
cursor: pointer;
74+
}
75+
4376
&.wc-block-woocommerce-product-gallery-large-image__image--hoverZoom {
4477
cursor: zoom-in;
4578
}
@@ -53,8 +86,6 @@ $outside-image-max-width: calc(100% - (2 * $outside-image-offset));
5386
display: flex;
5487
flex-direction: column;
5588
position: absolute;
56-
pointer-events: none;
57-
z-index: 1;
5889
width: 100%;
5990
height: 100%;
6091
top: 0;
@@ -76,6 +107,11 @@ $outside-image-max-width: calc(100% - (2 * $outside-image-offset));
76107
width: 100%;
77108
height: 100%;
78109

110+
svg {
111+
z-index: 3;
112+
pointer-events: all;
113+
}
114+
79115
.is-vertically-aligned-top {
80116
align-items: flex-start;
81117
}

assets/js/blocks/product-gallery/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export interface ProductGalleryBlockAttributes {
99
cropImages?: boolean;
1010
hoverZoom?: boolean;
1111
fullScreenOnClick?: boolean;
12-
mode: 'standard' | 'full';
12+
mode?: 'standard' | 'full';
1313
}
1414

1515
export interface ProductGalleryThumbnailsBlockAttributes {

src/BlockTypes/ProductGallery.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,39 @@ function( $carry, $item ) {
6565
''
6666
);
6767

68-
$gallery_dialog = '<dialog data-wc-bind--open="selectors.woocommerce.isDialogOpen">' . $html . '</dialog>';
68+
$html_processor = new \WP_HTML_Tag_Processor( $html );
69+
70+
$html_processor->next_tag(
71+
array(
72+
'class_name' => 'wp-block-woocommerce-product-gallery',
73+
)
74+
);
75+
76+
$html_processor->remove_attribute( 'data-wc-context' );
77+
78+
$gallery_dialog = strtr(
79+
'
80+
<div class="wc-block-product-gallery-dialog__overlay" hidden data-wc-bind--hidden="!selectors.woocommerce.isDialogOpen">
81+
<dialog data-wc-bind--open="selectors.woocommerce.isDialogOpen">
82+
<div class="wc-block-product-gallery-dialog__header">
83+
<div class="wc-block-product-galler-dialog__header-right">
84+
<button class="wc-block-product-gallery-dialog__close" data-wc-on--click="actions.woocommerce.dialog.handleCloseButtonClick">
85+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
86+
<rect width="24" height="24" rx="2"/>
87+
<path d="M13 11.8L19.1 5.5L18.1 4.5L12 10.7L5.9 4.5L4.9 5.5L11 11.8L4.5 18.5L5.5 19.5L12 12.9L18.5 19.5L19.5 18.5L13 11.8Z" fill="black"/>
88+
</svg>
89+
</button>
90+
</div>
91+
</div>
92+
<div class="wc-block-product-gallery-dialog__body">
93+
{{html}}
94+
</div>
95+
</dialog>
96+
</div>',
97+
array(
98+
'{{html}}' => $html_processor->get_updated_html(),
99+
)
100+
);
69101
return $gallery_dialog;
70102
}
71103

src/BlockTypes/ProductGalleryLargeImage.php

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ protected function get_block_type_style() {
3030
* @return string[]
3131
*/
3232
protected function get_block_type_uses_context() {
33-
return [ 'postId', 'hoverZoom' ];
33+
return [ 'postId', 'hoverZoom', 'fullScreenOnClick' ];
3434
}
3535

3636
/**
@@ -41,7 +41,7 @@ protected function get_block_type_uses_context() {
4141
* @param WP_Block $block The block object.
4242
*/
4343
protected function enqueue_assets( array $attributes, $content, $block ) {
44-
if ( $block->context['hoverZoom'] ) {
44+
if ( $block->context['hoverZoom'] || $block->context['fullScreenOnClick'] ) {
4545
parent::enqueue_assets( $attributes, $content, $block );
4646
}
4747
}
@@ -124,6 +124,10 @@ private function get_main_images_html( $context, $product_id ) {
124124

125125
);
126126

127+
if ( $context['fullScreenOnClick'] ) {
128+
$attributes['class'] .= ' wc-block-woocommerce-product-gallery-large-image__image--full-screen-on-click';
129+
}
130+
127131
if ( $context['hoverZoom'] ) {
128132
$attributes['class'] .= ' wc-block-woocommerce-product-gallery-large-image__image--hoverZoom';
129133
$attributes['data-wc-bind--style'] = 'selectors.woocommerce.styles';
@@ -147,17 +151,30 @@ private function get_main_images_html( $context, $product_id ) {
147151
}
148152

149153
/**
150-
* Get directives for the hover zoom.
154+
* Get directives for the block.
151155
*
152156
* @param array $block_context The block context.
153157
*
154158
* @return array
155159
*/
156160
private function get_directives( $block_context ) {
161+
return array_merge(
162+
$this->get_zoom_directives( $block_context ),
163+
$this->get_open_dialog_directives( $block_context )
164+
);
165+
}
166+
167+
/**
168+
* Get directives for zoom.
169+
*
170+
* @param array $block_context The block context.
171+
*
172+
* @return array
173+
*/
174+
private function get_zoom_directives( $block_context ) {
157175
if ( ! $block_context['hoverZoom'] ) {
158176
return array();
159177
}
160-
161178
$context = array(
162179
'woocommerce' => array(
163180
'styles' => array(
@@ -170,8 +187,24 @@ private function get_directives( $block_context ) {
170187
return array(
171188
'data-wc-on--mousemove' => 'actions.woocommerce.handleMouseMove',
172189
'data-wc-on--mouseleave' => 'actions.woocommerce.handleMouseLeave',
173-
'data-wc-on--click' => 'actions.woocommerce.handleClick',
174190
'data-wc-context' => wp_json_encode( $context, JSON_NUMERIC_CHECK ),
175191
);
176192
}
193+
194+
/**
195+
* Get directives for opening the dialog.
196+
*
197+
* @param array $block_context The block context.
198+
*
199+
* @return array
200+
*/
201+
private function get_open_dialog_directives( $block_context ) {
202+
if ( ! $block_context['fullScreenOnClick'] ) {
203+
return array();
204+
}
205+
206+
return array(
207+
'data-wc-on--click' => 'actions.woocommerce.handleClick',
208+
);
209+
}
177210
}

0 commit comments

Comments
 (0)