[Experimental] Fix a bug where new attribute filter block flickers in editor. (#44147)

This commit is contained in:
Sam Seay 2024-01-30 20:10:12 +08:00 committed by GitHub
parent 9eff44945a
commit 08d5cc05aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 116 additions and 56 deletions

View File

@ -2,7 +2,7 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { useEffect, useState } from '@wordpress/element';
import { useCallback, useEffect, useState } from '@wordpress/element';
import { BlockControls, useBlockProps } from '@wordpress/block-editor';
import { getSetting } from '@woocommerce/settings';
import {
@ -39,6 +39,67 @@ import './style.scss';
const ATTRIBUTES = getSetting< AttributeSetting[] >( 'attributes', [] );
const Toolbar = ( {
onClick,
isEditing,
}: {
onClick: () => void;
isEditing: boolean;
} ) => (
<BlockControls>
<ToolbarGroup
controls={ [
{
icon: 'edit',
title: __( 'Edit', 'woocommerce' ),
onClick,
isActive: isEditing,
},
] }
/>
</BlockControls>
);
const Wrapper = ( {
children,
onClickToolbarEdit,
isEditing,
blockProps,
}: {
children: React.ReactNode;
onClickToolbarEdit: () => void;
isEditing: boolean;
blockProps: object;
} ) => (
<div { ...blockProps }>
<Toolbar onClick={ onClickToolbarEdit } isEditing={ isEditing } />
{ children }
</div>
);
const AttributeSelectPlaceholder = ( {
attributeId,
setAttributeId,
onClickDone,
}: {
attributeId: number;
setAttributeId: ( id: number ) => void;
onClickDone: () => void;
} ) => (
<AttributesPlaceholder>
<div className="wc-block-attribute-filter__selection">
<AttributeSelectControls
isCompact={ false }
attributeId={ attributeId }
setAttributeId={ setAttributeId }
/>
<Button variant="primary" onClick={ onClickDone }>
{ __( 'Done', 'woocommerce' ) }
</Button>
</div>
</AttributesPlaceholder>
);
const Edit = ( props: EditProps ) => {
const {
attributes: blockAttributes,
@ -93,76 +154,63 @@ const Edit = ( props: EditProps ) => {
);
}, [ attributeTerms, filteredCounts ] );
const Toolbar = () => (
<BlockControls>
<ToolbarGroup
controls={ [
{
icon: 'edit',
title: __( 'Edit', 'woocommerce' ),
onClick: () => setIsEditing( ! isEditing ),
isActive: isEditing,
},
] }
/>
</BlockControls>
const onClickDone = useCallback( () => {
setIsEditing( false );
debouncedSpeak(
__(
'Now displaying a preview of the Filter Products by Attribute block.',
'woocommerce'
)
);
}, [ setIsEditing ] );
const setAttributeId = useCallback(
( id ) => {
setAttributes( {
attributeId: id,
} );
},
[ setAttributes ]
);
const AttributeSelectPlaceholder = () => (
<AttributesPlaceholder>
<div className="wc-block-attribute-filter__selection">
<AttributeSelectControls
isCompact={ false }
attributeId={ attributeId }
setAttributeId={ ( id ) =>
setAttributes( {
attributeId: id,
} )
}
/>
<Button
variant="primary"
onClick={ () => {
setIsEditing( false );
debouncedSpeak(
__(
'Now displaying a preview of the Filter Products by Attribute block.',
'woocommerce'
)
);
} }
>
{ __( 'Done', 'woocommerce' ) }
</Button>
</div>
</AttributesPlaceholder>
);
const Wrapper = ( { children }: { children: React.ReactNode } ) => (
<div { ...blockProps }>
<Toolbar />
{ children }
</div>
);
const toggleEditing = useCallback( () => {
setIsEditing( ! isEditing );
}, [ isEditing ] );
// Block rendering starts.
if ( Object.keys( ATTRIBUTES ).length === 0 )
return (
<Wrapper>
<Wrapper
onClickToolbarEdit={ toggleEditing }
isEditing={ isEditing }
blockProps={ blockProps }
>
<NoAttributesPlaceholder />
</Wrapper>
);
if ( isEditing )
return (
<Wrapper>
<AttributeSelectPlaceholder />
<Wrapper
onClickToolbarEdit={ toggleEditing }
isEditing={ isEditing }
blockProps={ blockProps }
>
<AttributeSelectPlaceholder
onClickDone={ onClickDone }
attributeId={ attributeId }
setAttributeId={ setAttributeId }
/>
</Wrapper>
);
if ( ! attributeId || ! attributeObject )
return (
<Wrapper>
<Wrapper
onClickToolbarEdit={ toggleEditing }
isEditing={ isEditing }
blockProps={ blockProps }
>
<Notice status="warning" isDismissible={ false }>
<p>
{ __(
@ -176,7 +224,11 @@ const Edit = ( props: EditProps ) => {
if ( attributeOptions.length === 0 )
return (
<Wrapper>
<Wrapper
onClickToolbarEdit={ toggleEditing }
isEditing={ isEditing }
blockProps={ blockProps }
>
<Notice status="warning" isDismissible={ false }>
<p>
{ __(
@ -189,7 +241,11 @@ const Edit = ( props: EditProps ) => {
);
return (
<Wrapper>
<Wrapper
onClickToolbarEdit={ toggleEditing }
isEditing={ isEditing }
blockProps={ blockProps }
>
<Inspector { ...props } />
<Disabled>
{ displayStyle === 'dropdown' ? (

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
[Experimental] Fix a bug where the editor for attribute selector would flicker and re-render constantly.