woocommerce/plugins/woocommerce-blocks/assets/js/blocks/featured-items/with-update-button-attribut...

91 lines
2.3 KiB
TypeScript

/**
* External dependencies
*/
import { ComponentType, useEffect, useMemo, useState } from 'react';
import { WP_REST_API_Category } from 'wp-types';
import { ProductResponseItem } from '@woocommerce/types';
import { useDispatch, useSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
import { EditorBlock } from './types';
interface WithUpdateButtonRequiredAttributes {
editMode: boolean;
}
interface WithUpdateButtonAttributes< T > {
attributes: WithUpdateButtonRequiredAttributes &
EditorBlock< T >[ 'attributes' ];
}
interface WithUpdateButtonCategoryProps< T >
extends WithUpdateButtonAttributes< T > {
category: WP_REST_API_Category;
product: never;
}
interface WithUpdateButtonProductProps< T >
extends WithUpdateButtonAttributes< T > {
category: never;
product: ProductResponseItem;
}
type WithUpdateButtonProps< T extends EditorBlock< T > > =
| ( T & WithUpdateButtonCategoryProps< T > )
| ( T & WithUpdateButtonProductProps< T > );
export const withUpdateButtonAttributes = < T extends EditorBlock< T > >(
Component: ComponentType< T >
) => ( props: WithUpdateButtonProps< T > ) => {
const [ doUrlUpdate, setDoUrlUpdate ] = useState( false );
const { attributes, category, clientId, product } = props;
const item = category || product;
const { editMode } = attributes;
const permalink =
( item as WP_REST_API_Category )?.link ||
( item as ProductResponseItem )?.permalink;
const Block = useSelect( ( select ) => {
return select( 'core/block-editor' ).getBlock( clientId );
} );
const InnerButton = Block?.innerBlocks[ 0 ];
const buttonBlockId = InnerButton?.clientId || '';
const currentButtonAttributes = useMemo(
() => InnerButton?.attributes || {},
[ InnerButton ]
);
const { url } = currentButtonAttributes;
const { updateBlockAttributes } = useDispatch( 'core/block-editor' );
useEffect( () => {
if (
doUrlUpdate &&
buttonBlockId &&
! editMode &&
permalink &&
url &&
permalink !== url
) {
updateBlockAttributes( buttonBlockId, {
url: permalink,
} );
setDoUrlUpdate( false );
}
}, [
buttonBlockId,
doUrlUpdate,
editMode,
permalink,
updateBlockAttributes,
url,
] );
const triggerUrlUpdate = () => setDoUrlUpdate( true );
return <Component { ...props } triggerUrlUpdate={ triggerUrlUpdate } />;
};