woocommerce/plugins/woocommerce-blocks/assets/js/blocks/product-collection/edit.tsx

135 lines
3.3 KiB
TypeScript

/**
* External dependencies
*/
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
import { BlockEditProps, InnerBlockTemplate } from '@wordpress/blocks';
import { useInstanceId } from '@wordpress/compose';
import { useEffect } from '@wordpress/element';
/**
* Internal dependencies
*/
import { ImageSizing } from '../../atomic/blocks/product-elements/image/types';
import type {
ProductCollectionAttributes,
ProductCollectionQuery,
} from './types';
import { VARIATION_NAME as PRODUCT_TITLE_ID } from './variations/elements/product-title';
import InspectorControls from './inspector-controls';
import { DEFAULT_ATTRIBUTES } from './constants';
import './editor.scss';
import { getDefaultValueOfInheritQueryFromTemplate } from './utils';
import ToolbarControls from './toolbar-controls';
export const INNER_BLOCKS_TEMPLATE: InnerBlockTemplate[] = [
[
'woocommerce/product-template',
{},
[
[
'woocommerce/product-image',
{
imageSizing: ImageSizing.THUMBNAIL,
},
],
[
'core/post-title',
{
textAlign: 'center',
level: 3,
fontSize: 'medium',
style: {
spacing: {
margin: {
bottom: '0.75rem',
top: '0',
},
},
},
isLink: true,
__woocommerceNamespace: PRODUCT_TITLE_ID,
},
],
[
'woocommerce/product-price',
{
textAlign: 'center',
fontSize: 'small',
},
],
[
'woocommerce/product-button',
{
textAlign: 'center',
fontSize: 'small',
},
],
],
],
[
'core/query-pagination',
{
layout: {
type: 'flex',
justifyContent: 'center',
},
},
],
[ 'woocommerce/product-collection-no-results' ],
];
const Edit = ( props: BlockEditProps< ProductCollectionAttributes > ) => {
const { attributes, setAttributes } = props;
const { queryId } = attributes;
const blockProps = useBlockProps();
const innerBlocksProps = useInnerBlocksProps( blockProps, {
template: INNER_BLOCKS_TEMPLATE,
} );
const instanceId = useInstanceId( Edit );
// We need this for multi-query block pagination.
// Query parameters for each block are scoped to their ID.
useEffect( () => {
if ( ! Number.isFinite( queryId ) ) {
setAttributes( { queryId: Number( instanceId ) } );
}
}, [ queryId, instanceId, setAttributes ] );
/**
* Because of issue https://github.com/WordPress/gutenberg/issues/7342,
* We are using this workaround to set default attributes.
*/
useEffect( () => {
setAttributes( {
...DEFAULT_ATTRIBUTES,
query: {
...( DEFAULT_ATTRIBUTES.query as ProductCollectionQuery ),
inherit: getDefaultValueOfInheritQueryFromTemplate(),
},
...( attributes as Partial< ProductCollectionAttributes > ),
} );
// We don't wanna add attributes as a dependency here.
// Because we want this to run only once.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ setAttributes ] );
/**
* If inherit is not a boolean, then we haven't set default attributes yet.
* We don't wanna render anything until default attributes are set.
* Default attributes are set in the useEffect above.
*/
if ( typeof attributes?.query?.inherit !== 'boolean' ) return null;
return (
<div { ...blockProps }>
<InspectorControls { ...props } />
<ToolbarControls { ...props } />
<div { ...innerBlocksProps } />
</div>
);
};
export default Edit;