Product Gallery: Add Crop, Zoom and Full-screen settings (https://github.com/woocommerce/woocommerce-blocks/pull/10445)

* WIP Product Gallery: Add the Thumbnails block

* Product Gallery Thumbnails: Add block settings

* Add template for the Product Gallery block

* Add template for the Product Gallery block. Add the rest of the files.

* Product Gallery Thumbnails: Add context settings sharing between the Product Gallery and Thumbnails block.

* Product Gallery Thumbnails: Add UI functionality and frontend functionality. Add settings for the Thumbnails in both places - Product Gallery and the Thumbnails block.

* Product Gallery Thumbnails: Move the static template ouside of the component

* Make sure the context is set before accesing the array values

* Product Gallery Thumbnails: Move the setGroupAttributes() function outside of the component

* Product Gallery Thumbnails: Fix TS errors

* Product Gallery Thumbnails: Update the Features Flags and Experimental Interfaces doc

* Product Gallery Thumbnails: Fix TS error

* Product Gallery Thumbnails: Remove unused stylesheet

* Product Gallery Thumbnails: Fix TS errors

* Product Gallery Thumbnails: Remove unused context and fix the thumbnails bottom position styling on the frontend.

* Product Gallery Thumbnails: Allow the user to move the horizontal thumbnails above the large image and don't overwrite that automatically

* Product Gallery Thumbnails: Add code comments and remove the incorrect conditional check when moving thumbnails up and down

* Product Gallery Thumbnails: Fix the eslint dependency error

* Product Gallery Thumbnails: Refactor Product Gallery edit code and move the logic to a utils file

* Product Gallery Thumbnails: Update the utils file

* Product Gallery Thumbnails: Update the utils file. Fix comment indentation

* Product Gallery Thumbnails: Fix undefined variable html when only 1 product image is set

* Product Gallery: Rename clientId to productGalleryClientId

* Product Gallery Thumbnails: Combine the useEffect code having the same dependencies

* Product Gallery Thumbnails: Combine all useEffect code together

* Product Gallery Thumbnails: Add a ThumbnailsPosition enum

* Product Gallery Thumbnails: Update the thumbnailsPosition to an enum

* Product Gallery Thumbnails: Fix TS errors

* Product Gallery Thumbnails: Fix TS errors

* Product Gallery Thumbnails: Add missing dependency

* Product Gallery Thumbnails: Uppercase the enum and fix the thumbnails position bug when initially adding the Product Gallery block

* Product Gallery: Add crop, zoom and full-screen settings

* Product Gallery Thumbnails: Replace ts-ignore with ts-expect-error

* Product Gallery Thumbnails: Replace ts-ignore with ts-expect-error

* Product Gallery Thumbnails: Revert back to ts-ignore

* Revert "Product Gallery: Add crop, zoom and full-screen settings"

This reverts commit 840654197619e2611029b81990493387ae0b543d.

* Product Gallery: Add crop, zoom and full-screen settings

* Product Gallery: Remove the redundant React Fragment
This commit is contained in:
Daniel Dudzic 2023-08-02 12:43:08 +02:00 committed by GitHub
parent a9d29407eb
commit 6dc1deef9e
6 changed files with 156 additions and 44 deletions

View File

@ -0,0 +1,74 @@
/**
* External dependencies
*/
import { InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import type { ProductGallerySettingsProps } from '../types';
export const ProductGalleryBlockSettings = ( {
attributes,
setAttributes,
}: ProductGallerySettingsProps ) => {
const { cropImages, hoverZoom, fullScreenOnClick } = attributes;
return (
<InspectorControls>
<PanelBody
title={ __( 'Media Settings', 'woo-gutenberg-products-block' ) }
>
<ToggleControl
label={ __(
'Crop images to fit',
'woo-gutenberg-products-block'
) }
help={ __(
'Images will be cropped to fit within a square space.',
'woo-gutenberg-products-block'
) }
checked={ cropImages }
onChange={ () =>
setAttributes( {
cropImages: ! cropImages,
} )
}
/>
<ToggleControl
label={ __(
'Zoom while hovering',
'woo-gutenberg-products-block'
) }
help={ __(
'While hovering the large image will zoom in by 30%.',
'woo-gutenberg-products-block'
) }
checked={ hoverZoom }
onChange={ () =>
setAttributes( {
hoverZoom: ! hoverZoom,
} )
}
/>
<ToggleControl
label={ __(
'Full-screen when clicked',
'woo-gutenberg-products-block'
) }
help={ __(
'Clicking on the large image will open a full-screen gallery experience.',
'woo-gutenberg-products-block'
) }
checked={ fullScreenOnClick }
onChange={ () =>
setAttributes( {
fullScreenOnClick: ! fullScreenOnClick,
} )
}
/>
</PanelBody>
</InspectorControls>
);
};

View File

@ -29,6 +29,18 @@
"productGalleryClientId": {
"type": "string",
"default": ""
},
"cropImages": {
"type": "boolean",
"default": false
},
"hoverZoom": {
"type": "boolean",
"default": false
},
"fullScreenOnClick": {
"type": "boolean",
"default": false
}
}
}

View File

@ -17,8 +17,12 @@ import {
updateGroupBlockType,
getInnerBlocksLockAttributes,
} from './utils';
import { BlockSettings } from './inner-blocks/product-gallery-thumbnails/block-settings';
import type { BlockAttributes } from './types';
import { ProductGalleryThumbnailsBlockSettings } from './inner-blocks/product-gallery-thumbnails/block-settings';
import { ProductGalleryBlockSettings } from './block-settings/index';
import type {
ProductGalleryThumbnailsBlockAttributes,
ProductGalleryBlockAttributes,
} from './types';
const TEMPLATE: InnerBlockTemplate[] = [
[
@ -41,7 +45,9 @@ export const Edit = ( {
clientId,
attributes,
setAttributes,
}: BlockEditProps< BlockAttributes > ) => {
}: BlockEditProps<
ProductGalleryThumbnailsBlockAttributes & ProductGalleryBlockAttributes
> ) => {
const blockProps = useBlockProps();
// Update the Group block type when the thumbnailsPosition attribute changes.
@ -59,7 +65,7 @@ export const Edit = ( {
return (
<div { ...blockProps }>
<InspectorControls>
<BlockSettings
<ProductGalleryThumbnailsBlockSettings
attributes={ attributes }
setAttributes={ setAttributes }
context={ {
@ -70,6 +76,12 @@ export const Edit = ( {
} }
/>
</InspectorControls>
<InspectorControls>
<ProductGalleryBlockSettings
attributes={ attributes }
setAttributes={ setAttributes }
/>
</InspectorControls>
<InnerBlocks
allowedBlocks={ [
'woocommerce/product-gallery-large-image',

View File

@ -30,7 +30,7 @@ import {
* Internal dependencies
*/
import { ThumbnailsPosition } from '../constants';
import type { ThumbnailsSettingProps } from '../../../types';
import type { ProductGalleryThumbnailsSettingsProps } from '../../../types';
const positionHelp: Record< ThumbnailsPosition, string > = {
[ ThumbnailsPosition.OFF ]: __(
@ -51,7 +51,9 @@ const positionHelp: Record< ThumbnailsPosition, string > = {
),
};
export const BlockSettings = ( { context }: ThumbnailsSettingProps ) => {
export const ProductGalleryThumbnailsBlockSettings = ( {
context,
}: ProductGalleryThumbnailsSettingsProps ) => {
const maxNumberOfThumbnails = 8;
const minNumberOfThumbnails = 2;
const { productGalleryClientId } = context;

View File

@ -10,46 +10,43 @@ import { WC_BLOCKS_IMAGE_URL } from '@woocommerce/block-settings';
* Internal dependencies
*/
import './editor.scss';
import { BlockSettings } from './block-settings';
import type { BlockAttributes, Context } from '../../types';
import { ProductGalleryThumbnailsBlockSettings } from './block-settings';
import type {
ProductGalleryThumbnailsBlockAttributes,
Context,
} from '../../types';
import { ThumbnailsPosition } from './constants';
export const Edit = ( {
attributes,
setAttributes,
context,
}: BlockEditProps< BlockAttributes > & Context ) => {
}: BlockEditProps< ProductGalleryThumbnailsBlockAttributes > & Context ) => {
const blockProps = useBlockProps();
const Placeholder = () => {
return (
<>
{ context.thumbnailsPosition !== ThumbnailsPosition.OFF && (
<div className="wc-block-editor-product-gallery-thumbnails">
{ [
...Array(
context.thumbnailsNumberOfThumbnails
).keys(),
].map( ( index ) => {
return (
<img
key={ index }
src={ `${ WC_BLOCKS_IMAGE_URL }block-placeholders/product-image-gallery.svg` }
alt="Placeholder"
/>
);
} ) }
</div>
) }
</>
);
return context.thumbnailsPosition !== ThumbnailsPosition.OFF ? (
<div className="wc-block-editor-product-gallery-thumbnails">
{ [
...Array( context.thumbnailsNumberOfThumbnails ).keys(),
].map( ( index ) => {
return (
<img
key={ index }
src={ `${ WC_BLOCKS_IMAGE_URL }block-placeholders/product-image-gallery.svg` }
alt="Placeholder"
/>
);
} ) }
</div>
) : null;
};
return (
<>
<div { ...blockProps }>
<InspectorControls>
<BlockSettings
<ProductGalleryThumbnailsBlockSettings
attributes={ attributes }
setAttributes={ setAttributes }
context={ context }

View File

@ -3,12 +3,39 @@
*/
import { ThumbnailsPosition } from './inner-blocks/product-gallery-thumbnails/constants';
export interface BlockAttributes {
export interface ProductGalleryBlockAttributes {
cropImages?: boolean;
hoverZoom?: boolean;
fullScreenOnClick?: boolean;
}
export interface ProductGalleryThumbnailsBlockAttributes {
thumbnailsPosition: ThumbnailsPosition;
thumbnailsNumberOfThumbnails: number;
productGalleryClientId: string;
}
export interface ProductGalleryBlockEditProps {
clientId: string;
attributes: ProductGalleryThumbnailsBlockAttributes;
setAttributes: (
newAttributes: ProductGalleryThumbnailsBlockAttributes
) => void;
}
export interface ProductGallerySettingsProps {
attributes: ProductGalleryBlockAttributes;
setAttributes: ( attributes: ProductGalleryBlockAttributes ) => void;
}
export interface ProductGalleryThumbnailsSettingsProps {
attributes: ProductGalleryThumbnailsBlockAttributes;
setAttributes: (
attributes: ProductGalleryThumbnailsBlockAttributes
) => void;
context: ProductGalleryThumbnailsBlockAttributes;
}
export interface Context {
context: {
thumbnailsPosition: ThumbnailsPosition;
@ -16,15 +43,3 @@ export interface Context {
productGalleryClientId: string;
};
}
export interface ProductGalleryBlockEditProps {
clientId: string;
attributes: BlockAttributes;
setAttributes: ( newAttributes: BlockAttributes ) => void;
}
export interface ThumbnailsSettingProps {
attributes: BlockAttributes;
context: BlockAttributes;
setAttributes: ( attributes: BlockAttributes ) => void;
}