[Product Block Editor]: relocate block actions in the sections area (#43555)

* handle section actions styles from section block

* rename DownloadBlockEdit

* remove unneeded wrap el from linked product list

* put Choose an Image button in the actions section

* move attribute control to block actions section

* changelog

* remove unused clientId prop

* tweak Image button

* remove `should show subtitle and "Add new" button` test
This commit is contained in:
Damián Suárez 2024-01-15 11:02:54 -03:00 committed by GitHub
parent 50c7e51d86
commit 8974b86a04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 95 additions and 99 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: update
[Product Block Editor]: tweak section actions of some blocks #43555

View File

@ -39,6 +39,7 @@ import {
LinkedProductListBlockEmptyState,
} from './types';
import getRelatedProducts from '../../../utils/get-related-products';
import { SectionActions } from '../../../components/block-slot-fill';
export function EmptyStateImage( {
image,
@ -157,7 +158,7 @@ export function LinkedProductListBlockEdit( {
return (
<div { ...blockProps }>
<div className="wp-block-woocommerce-product-linked-list-field__form-group-header">
<SectionActions>
<Button
variant="tertiary"
icon={ reusableBlock }
@ -165,7 +166,7 @@ export function LinkedProductListBlockEdit( {
>
{ __( 'Choose products for me', 'woocommerce' ) }
</Button>
</div>
</SectionActions>
<div className="wp-block-woocommerce-product-linked-list-field__form-group-content">
<ProductSelect

View File

@ -3,12 +3,6 @@
flex-direction: column;
gap: $grid-unit-30;
&__form-group-header {
display: flex;
flex-direction: row;
justify-content: right;
}
.woocommerce-advice-card {
min-height: 233px; // min height to cover the min rows rendered in the table on its back

View File

@ -65,7 +65,9 @@ export function SectionBlockEdit( {
) }
</h2>
<BlockSlot name="section-actions" />
<div className="wp-block-woocommerce-product-section__actions">
<BlockSlot name="section-actions" />
</div>
</div>
<BlockSlot name="section-description" />

View File

@ -63,6 +63,12 @@
margin: 0;
max-width: 300px;
}
&__actions {
display: flex;
justify-content: flex-end;
gap: $grid-unit;
}
}
.woocommerce-tooltip > .wp-block-woocommerce-product-section__heading-tooltip {

View File

@ -16,7 +16,7 @@ import { useEntityProp, useEntityId } from '@wordpress/core-data';
import { Attributes as AttributesContainer } from '../../../components/attributes/attributes';
import { ProductEditorBlockEditProps } from '../../../types';
export function Edit( {
export function AttributesBlockEdit( {
attributes,
}: ProductEditorBlockEditProps< BlockAttributes > ) {
const [ entityAttributes, setEntityAttributes ] = useEntityProp<

View File

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

View File

@ -32,6 +32,7 @@ import {
} from '../../../components/manage-download-limits-modal';
import { EditDownloadsModal } from './edit-downloads-modal';
import { UploadImage } from './upload-image';
import { SectionActions } from '../../../components/block-slot-fill';
function getFileName( url?: string ) {
const [ name ] = url?.split( '/' ).reverse() ?? [];
@ -46,7 +47,7 @@ function stringifyEntityId< ID, T extends { id?: ID } >( entity: T ): T {
return { ...entity, id: stringifyId( entity.id ) };
}
export function Edit( {
export function DownloadBlockEdit( {
attributes,
context: { postType },
}: ProductEditorBlockEditProps< UploadsBlockAttributes > ) {
@ -232,7 +233,7 @@ export function Edit( {
return (
<div { ...blockProps }>
<div className="wp-block-woocommerce-product-downloads-field__header">
<SectionActions>
{ Boolean( downloads.length ) && (
<Button
variant="tertiary"
@ -247,7 +248,7 @@ export function Edit( {
onUploadSuccess={ handleFileUpload }
onUploadError={ handleUploadError }
/>
</div>
</SectionActions>
<div className="wp-block-woocommerce-product-downloads-field__body">
<MediaUploader

View File

@ -6,13 +6,6 @@
$fixed-section-height: 224px;
.wp-block-woocommerce-product-downloads-field {
&__header {
display: flex;
justify-content: flex-end;
margin-bottom: $grid-unit-30;
gap: $grid-unit;
}
&__body {
position: relative;
}

View File

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

View File

@ -26,6 +26,7 @@ import { useEntityProp } from '@wordpress/core-data';
*/
import { ProductEditorBlockEditProps } from '../../../types';
import { PlaceHolder } from './place-holder';
import { SectionActions } from '../../../components/block-slot-fill';
type UploadImage = {
id?: number;
@ -48,7 +49,7 @@ function mapUploadImageToImage( upload: UploadImage ): Image | null {
};
}
export function Edit( {
export function ImageBlockEdit( {
attributes,
context,
}: ProductEditorBlockEditProps< BlockAttributes > ) {
@ -218,27 +219,36 @@ export function Edit( {
/>
</div>
) : (
<MediaUploader
value={
Array.isArray( propertyValue )
? propertyValue.map( ( { id } ) => id )
: propertyValue?.id ?? undefined
}
multipleSelect={ multiple ? 'add' : false }
onError={ () => null }
onFileUploadChange={ uploadHandler(
'product_images_add_via_file_upload_area'
) }
onMediaGalleryOpen={ () => {
recordEvent( 'product_images_media_gallery_open' );
} }
onSelect={ handleSelect }
onUpload={ uploadHandler(
'product_images_add_via_drag_and_drop_upload'
) }
label={ '' }
buttonText={ __( 'Choose an image', 'woocommerce' ) }
/>
<SectionActions>
<div className="woocommerce-product-form__media-uploader">
<MediaUploader
value={
Array.isArray( propertyValue )
? propertyValue.map( ( { id } ) => id )
: propertyValue?.id ?? undefined
}
multipleSelect={ multiple ? 'add' : false }
onError={ () => null }
onFileUploadChange={ uploadHandler(
'product_images_add_via_file_upload_area'
) }
onMediaGalleryOpen={ () => {
recordEvent(
'product_images_media_gallery_open'
);
} }
onSelect={ handleSelect }
onUpload={ uploadHandler(
'product_images_add_via_drag_and_drop_upload'
) }
label={ '' }
buttonText={ __(
'Choose an image',
'woocommerce'
) }
/>
</div>
</SectionActions>
) }
</div>
{ isImageGalleryVisible ? (

View File

@ -1,19 +1,6 @@
@import "./place-holder/style.scss";
.wp-block-woocommerce-product-images-field {
.woocommerce-media-uploader {
text-align: left;
.components-drop-zone {
// This height cannot be higher than this, otherwise it will invade the area from the block below.
min-height: 84px;
}
}
.woocommerce-media-uploader__label {
display: none;
}
.woocommerce-sortable {
margin-top: 0;
padding: 0;
@ -31,3 +18,16 @@
}
}
}
.woocommerce-product-form__media-uploader {
.woocommerce-media-uploader {
.components-drop-zone {
// This height cannot be higher than this, otherwise it will invade the area from the block below.
min-height: 84px;
}
&__label {
display: none;
}
}
}

View File

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

View File

@ -125,22 +125,20 @@ export function ProductListBlockEdit( {
return (
<div { ...blockProps }>
<SectionActions>
<div className="wp-block-woocommerce-product-list-field__header">
{ ! isLoading && groupedProducts.length > 0 && (
<Button
onClick={ handleReorderProductsButtonClick }
variant="tertiary"
>
{ __( 'Reorder', 'woocommerce' ) }
</Button>
) }
{ ! isLoading && groupedProducts.length > 0 && (
<Button
onClick={ handleAddProductsButtonClick }
variant="secondary"
onClick={ handleReorderProductsButtonClick }
variant="tertiary"
>
{ __( 'Add products', 'woocommerce' ) }
{ __( 'Reorder', 'woocommerce' ) }
</Button>
</div>
) }
<Button
onClick={ handleAddProductsButtonClick }
variant="secondary"
>
{ __( 'Add products', 'woocommerce' ) }
</Button>
</SectionActions>
<div className="wp-block-woocommerce-product-list-field__body">

View File

@ -3,13 +3,6 @@
flex-direction: column;
gap: $grid-unit-30;
&__header {
display: flex;
align-items: center;
justify-content: end;
gap: $gap-smaller;
}
&__body {
.woocommerce-advice-card {
padding: $grid-unit-60;

View File

@ -34,6 +34,7 @@ import { NewAttributeModal } from './new-attribute-modal';
import { RemoveConfirmationModal } from '../remove-confirmation-modal';
import { TRACKS_SOURCE } from '../../constants';
import { AttributeEmptyStateSkeleton } from './attribute-empty-state-skeleton';
import { SectionActions } from '../block-slot-fill';
type AttributeControlProps = {
value: EnhancedProductAttribute[];
@ -236,15 +237,17 @@ export const AttributeControl: React.FC< AttributeControlProps > = ( {
return (
<div className="woocommerce-attribute-field">
<Button
variant="secondary"
className="woocommerce-add-attribute-list-item__add-button"
onClick={ () => {
openNewModal();
} }
>
{ uiStrings.newAttributeListItemLabel }
</Button>
<SectionActions>
<Button
variant="secondary"
className="woocommerce-add-attribute-list-item__add-button"
onClick={ () => {
openNewModal();
} }
>
{ uiStrings.newAttributeListItemLabel }
</Button>
</SectionActions>
{ uiStrings.notice && (
<Notice
isDismissible={ true }

View File

@ -115,15 +115,6 @@ describe( 'AttributeControl', () => {
jest.clearAllMocks();
} );
describe( 'empty state', () => {
it( 'should show subtitle and "Add new" button', () => {
const { queryByText } = render(
<AttributeControl value={ [] } onChange={ () => {} } />
);
expect( queryByText( 'Add new' ) ).toBeInTheDocument();
} );
} );
it( 'should render the list of all attributes', async () => {
act( () => {
render(