[Product Block Editor]: introduce `<SectionActions />` slot (#43540)

* pick clientId by using hook

* do not pass clientId to BlockFill component

* pick clientId from core hook

* introduce SectionActions slot component

* expose SectionActions slot component

* fix ts issue

* changelog

* fix closing component bug

* do not pass clientId to the BlockSlot instance

* revert changes in the description block

* fix name for the section actions component

* export section actions properly

* add a warning when the slot DOM doesn't exist

* define the name explicitely

* export SectionActions component name

* import SectionActions from product list cmp

* rename ProductListBlockEdit component fn
This commit is contained in:
Damián Suárez 2024-01-12 10:20:39 -03:00 committed by GitHub
parent be1c794387
commit ec2a3f839f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 61 additions and 27 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: add
[Product Block Editor]: introduce `<SectionActions />` slot

View File

@ -13,7 +13,6 @@ import { SectionDescriptionBlockAttributes } from './types';
export function SectionDescriptionBlockEdit( { export function SectionDescriptionBlockEdit( {
attributes, attributes,
clientId,
}: ProductEditorBlockEditProps< SectionDescriptionBlockAttributes > ) { }: ProductEditorBlockEditProps< SectionDescriptionBlockAttributes > ) {
const { content } = attributes; const { content } = attributes;
const blockProps = useWooBlockProps( attributes ); const blockProps = useWooBlockProps( attributes );
@ -22,7 +21,6 @@ export function SectionDescriptionBlockEdit( {
<BlockFill <BlockFill
{ ...blockProps } { ...blockProps }
name="section-description" name="section-description"
clientId={ clientId }
slotContainerBlockName="woocommerce/product-section" slotContainerBlockName="woocommerce/product-section"
> >
<div>{ content }</div> <div>{ content }</div>

View File

@ -66,16 +66,10 @@ export function SectionBlockEdit( {
) } ) }
</h2> </h2>
<BlockSlot <BlockSlot name="section-actions" />
name="section-actions"
clientId={ clientId }
/>
</div> </div>
<BlockSlot <BlockSlot name="section-description" />
name="section-description"
clientId={ clientId }
/>
</HeadingTagName> </HeadingTagName>
) } ) }

View File

@ -255,7 +255,6 @@ export function ProductDetailsSectionDescriptionBlockEdit( {
return ( return (
<BlockFill <BlockFill
name="section-description" name="section-description"
clientId={ clientId }
slotContainerBlockName="woocommerce/product-section" slotContainerBlockName="woocommerce/product-section"
> >
<div { ...blockProps }> <div { ...blockProps }>

View File

@ -26,7 +26,6 @@ import {
getProductImageStyle, getProductImageStyle,
ReorderProductsModal, ReorderProductsModal,
} from '../../../components/add-products-modal'; } from '../../../components/add-products-modal';
import { BlockFill } from '../../../components/block-slot-fill';
import { ProductEditorBlockEditProps } from '../../../types'; import { ProductEditorBlockEditProps } from '../../../types';
import { UploadsBlockAttributes } from './types'; import { UploadsBlockAttributes } from './types';
import { import {
@ -37,11 +36,11 @@ import { Shirt } from '../../../images/shirt';
import { Pants } from '../../../images/pants'; import { Pants } from '../../../images/pants';
import { Glasses } from '../../../images/glasses'; import { Glasses } from '../../../images/glasses';
import { AdviceCard } from '../../../components/advice-card'; import { AdviceCard } from '../../../components/advice-card';
import { SectionActions } from '../../../components/block-slot-fill';
export function Edit( { export function ProductListBlockEdit( {
attributes, attributes,
context: { postType }, context: { postType },
clientId,
}: ProductEditorBlockEditProps< UploadsBlockAttributes > ) { }: ProductEditorBlockEditProps< UploadsBlockAttributes > ) {
const { property } = attributes; const { property } = attributes;
const blockProps = useWooBlockProps( attributes ); const blockProps = useWooBlockProps( attributes );
@ -125,11 +124,7 @@ export function Edit( {
return ( return (
<div { ...blockProps }> <div { ...blockProps }>
<BlockFill <SectionActions>
name="section-actions"
clientId={ clientId }
slotContainerBlockName="woocommerce/product-section"
>
<div className="wp-block-woocommerce-product-list-field__header"> <div className="wp-block-woocommerce-product-list-field__header">
{ ! isLoading && groupedProducts.length > 0 && ( { ! isLoading && groupedProducts.length > 0 && (
<Button <Button
@ -146,7 +141,7 @@ export function Edit( {
{ __( 'Add products', 'woocommerce' ) } { __( 'Add products', 'woocommerce' ) }
</Button> </Button>
</div> </div>
</BlockFill> </SectionActions>
<div className="wp-block-woocommerce-product-list-field__body"> <div className="wp-block-woocommerce-product-list-field__body">
{ ! isLoading && groupedProducts.length === 0 && ( { ! isLoading && groupedProducts.length === 0 && (

View File

@ -2,7 +2,7 @@
* Internal dependencies * Internal dependencies
*/ */
import blockConfiguration from './block.json'; import blockConfiguration from './block.json';
import { Edit } from './edit'; import { ProductListBlockEdit } from './edit';
import { registerProductEditorBlockType } from '../../../utils'; import { registerProductEditorBlockType } from '../../../utils';
const { name, ...metadata } = blockConfiguration; const { name, ...metadata } = blockConfiguration;
@ -11,7 +11,7 @@ export { metadata, name };
export const settings = { export const settings = {
example: {}, example: {},
edit: Edit, edit: ProductListBlockEdit,
}; };
export function init() { export function init() {

View File

@ -4,6 +4,10 @@
import { Fill } from '@wordpress/components'; import { Fill } from '@wordpress/components';
import { useSelect } from '@wordpress/data'; import { useSelect } from '@wordpress/data';
import { createElement } from '@wordpress/element'; import { createElement } from '@wordpress/element';
import {
// @ts-expect-error no exported member.
useBlockEditContext,
} from '@wordpress/block-editor';
/** /**
* Internal dependencies * Internal dependencies
@ -13,10 +17,11 @@ import { BlockFillProps } from './types';
export function BlockFill( { export function BlockFill( {
name, name,
clientId,
slotContainerBlockName, slotContainerBlockName,
...props ...props
}: BlockFillProps ) { }: BlockFillProps ) {
const { clientId } = useBlockEditContext();
const closestAncestorClientId = useSelect( const closestAncestorClientId = useSelect(
( select ) => { ( select ) => {
// @ts-expect-error Outdated type definition. // @ts-expect-error Outdated type definition.
@ -34,7 +39,11 @@ export function BlockFill( {
[ clientId, slotContainerBlockName ] [ clientId, slotContainerBlockName ]
); );
if ( ! closestAncestorClientId ) return null; if ( ! closestAncestorClientId ) {
// eslint-disable-next-line no-console
console.warn( 'No closest ancestor client ID found for block fill.' );
return null;
}
return ( return (
<Fill { ...props } name={ getName( name, closestAncestorClientId ) } /> <Fill { ...props } name={ getName( name, closestAncestorClientId ) } />

View File

@ -3,6 +3,10 @@
*/ */
import { Slot } from '@wordpress/components'; import { Slot } from '@wordpress/components';
import { createElement } from '@wordpress/element'; import { createElement } from '@wordpress/element';
import {
// @ts-expect-error no exported member.
useBlockEditContext,
} from '@wordpress/block-editor';
/** /**
* Internal dependencies * Internal dependencies
@ -10,6 +14,7 @@ import { createElement } from '@wordpress/element';
import { getName } from './utils/get-name'; import { getName } from './utils/get-name';
import { BlockSlotProps } from './types'; import { BlockSlotProps } from './types';
export function BlockSlot( { name, clientId, ...props }: BlockSlotProps ) { export function BlockSlot( { name, ...props }: BlockSlotProps ) {
const { clientId } = useBlockEditContext();
return <Slot { ...props } name={ getName( name, clientId ) } />; return <Slot { ...props } name={ getName( name, clientId ) } />;
} }

View File

@ -1,3 +1,4 @@
export * from './block-fill'; export * from './block-fill';
export * from './block-slot'; export * from './block-slot';
export * from './section-actions/index';
export * from './types'; export * from './types';

View File

@ -0,0 +1,30 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
/**
* Internal dependencies
*/
import { BlockFill } from '../block-fill';
import { BlockFillProps } from '../types';
export type SectionActionsProps = Omit<
BlockFillProps,
'name' | 'slotContainerBlockName'
> & {
containerBlockName?: string;
};
export function SectionActions( {
containerBlockName = 'woocommerce/product-section',
...restProps
}: SectionActionsProps ) {
return (
<BlockFill
{ ...restProps }
name="section-actions"
slotContainerBlockName={ containerBlockName }
/>
);
}

View File

@ -4,8 +4,7 @@
import { Fill, Slot } from '@wordpress/components'; import { Fill, Slot } from '@wordpress/components';
export type BlockSlotFillProps = { export type BlockSlotFillProps = {
clientId: string; name: 'section-actions' | 'section-description';
name: string;
}; };
export type BlockSlotProps = BlockSlotFillProps & Slot.Props; export type BlockSlotProps = BlockSlotFillProps & Slot.Props;