Use a portal to render the Drawer close button to fix the alignment with the Mini-Cart Contents block (https://github.com/woocommerce/woocommerce-blocks/pull/9507)

This commit is contained in:
Albert Juhé Lluveras 2023-05-30 15:39:19 +02:00 committed by GitHub
parent 6b105f0504
commit c267504bd6
5 changed files with 81 additions and 10 deletions

View File

@ -0,0 +1,7 @@
const DrawerCloseButton = () => {
// The Drawer component will use a portal to render the close button inside
// this div.
return <div className="wc-block-components-drawer__close-wrapper"></div>;
};
export default DrawerCloseButton;

View File

@ -7,7 +7,7 @@
*/
import classNames from 'classnames';
import { useDebounce } from 'use-debounce';
import type { ForwardedRef, KeyboardEvent } from 'react';
import type { ForwardedRef, KeyboardEvent, RefObject } from 'react';
import { __ } from '@wordpress/i18n';
import {
createPortal,
@ -41,6 +41,33 @@ interface DrawerProps {
slideOut?: boolean;
}
interface CloseButtonPortalProps {
onClick: () => void;
contentRef: RefObject< HTMLDivElement >;
}
const CloseButtonPortal = ( {
onClick,
contentRef,
}: CloseButtonPortalProps ) => {
const closeButtonWrapper = contentRef?.current?.querySelector(
'.wc-block-components-drawer__close-wrapper'
);
return closeButtonWrapper
? createPortal(
<Button
className="wc-block-components-drawer__close"
icon={ close }
onClick={ onClick }
label={ __( 'Close', 'woo-gutenberg-products-block' ) }
showTooltip={ false }
/>,
closeButtonWrapper
)
: null;
};
const UnforwardedDrawer = (
{
children,
@ -137,12 +164,9 @@ const UnforwardedDrawer = (
role="document"
ref={ contentRef }
>
<Button
className="wc-block-components-drawer__close"
<CloseButtonPortal
contentRef={ contentRef }
onClick={ onRequestClose }
icon={ close }
label={ __( 'Close', 'woo-gutenberg-products-block' ) }
showTooltip={ false }
/>
{ children }
</div>
@ -152,6 +176,7 @@ const UnforwardedDrawer = (
);
};
export const Drawer = forwardRef( UnforwardedDrawer );
const Drawer = forwardRef( UnforwardedDrawer );
export default Drawer;
export { default as DrawerCloseButton } from './close-button';

View File

@ -1,6 +1,7 @@
/**
* External dependencies
*/
import { DrawerCloseButton } from '@woocommerce/base-components/drawer';
/**
* Internal dependencies
@ -17,5 +18,10 @@ export const MiniCartContentsBlock = (
): JSX.Element => {
const { children } = props;
return <>{ children }</>;
return (
<>
<DrawerCloseButton />
{ children }
</>
);
};

View File

@ -57,6 +57,7 @@
.wp-block-woocommerce-mini-cart-contents {
box-sizing: border-box;
padding: 0;
position: relative;
justify-content: center;
.wc-block-components-notices {

View File

@ -25,7 +25,14 @@ import { defaultCartState } from '../../../data/cart/default-state';
const MiniCartBlock = ( props ) => (
<SlotFillProvider>
<Block
contents='<div class="wc-block-mini-cart-contents"></div>'
contents='<div data-block-name="woocommerce/mini-cart-contents" class="wp-block-woocommerce-mini-cart-contents"><div data-block-name="woocommerce/filled-mini-cart-contents-block" class="wp-block-woocommerce-filled-mini-cart-contents-block"><div data-block-name="woocommerce/mini-cart-title-block" class="wp-block-woocommerce-mini-cart-title-block"><div data-block-name="woocommerce/mini-cart-title-label-block" class="wp-block-woocommerce-mini-cart-title-label-block"></div>
<div data-block-name="woocommerce/mini-cart-title-items-counter-block" class="wp-block-woocommerce-mini-cart-title-items-counter-block"></div></div>
<div data-block-name="woocommerce/mini-cart-items-block" class="wp-block-woocommerce-mini-cart-items-block"><div data-block-name="woocommerce/mini-cart-products-table-block" class="wp-block-woocommerce-mini-cart-products-table-block"></div></div>
<div data-block-name="woocommerce/mini-cart-footer-block" class="wp-block-woocommerce-mini-cart-footer-block"><div data-block-name="woocommerce/mini-cart-cart-button-block" class="wp-block-woocommerce-mini-cart-cart-button-block"></div>
<div data-block-name="woocommerce/mini-cart-checkout-button-block" class="wp-block-woocommerce-mini-cart-checkout-button-block"></div></div></div>
<div data-block-name="woocommerce/empty-mini-cart-contents-block" class="wp-block-woocommerce-empty-mini-cart-contents-block">
<p class="has-text-align-center"><strong>Your cart is currently empty!</strong></p>
<div data-block-name="woocommerce/mini-cart-shopping-button-block" class="wp-block-woocommerce-mini-cart-shopping-button-block"></div></div></div>'
{ ...props }
/>
</SlotFillProvider>
@ -88,7 +95,32 @@ describe( 'Testing Mini-Cart', () => {
await waitFor( () => expect( fetchMock ).toHaveBeenCalled() );
userEvent.click( screen.getByLabelText( /items/i ) );
expect( fetchMock ).toHaveBeenCalledTimes( 1 );
await waitFor( () =>
expect( screen.getByText( /your cart/i ) ).toBeInTheDocument()
);
} );
it( 'closes the drawer when clicking on the close button', async () => {
render( <MiniCartBlock /> );
await waitFor( () => expect( fetchMock ).toHaveBeenCalled() );
// Open drawer.
userEvent.click( screen.getByLabelText( /items/i ) );
// Close drawer.
let closeButton = null;
await waitFor( () => {
closeButton = screen.getByLabelText( /close/i );
} );
if ( closeButton ) {
userEvent.click( closeButton );
}
await waitFor( () => {
expect(
screen.queryByText( /your cart/i )
).not.toBeInTheDocument();
} );
} );
it( 'renders empty cart if there are no items in the cart', async () => {