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:
parent
6b105f0504
commit
c267504bd6
|
@ -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;
|
|
@ -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';
|
||||
|
|
|
@ -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 }
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 () => {
|
||||
|
|
Loading…
Reference in New Issue