Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Use a portal to render the Drawer close button to fix the alignment w…
Browse files Browse the repository at this point in the history
…ith the Mini-Cart Contents block
  • Loading branch information
Aljullu committed May 18, 2023
1 parent 49f5d71 commit 8ac7626
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 10 deletions.
7 changes: 7 additions & 0 deletions assets/js/base/components/drawer/close-button.tsx
Original file line number Diff line number Diff line change
@@ -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;
39 changes: 32 additions & 7 deletions assets/js/base/components/drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>
Expand All @@ -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';
8 changes: 7 additions & 1 deletion assets/js/blocks/mini-cart/mini-cart-contents/block.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* External dependencies
*/
import { DrawerCloseButton } from '@woocommerce/base-components/drawer';

/**
* Internal dependencies
Expand All @@ -17,5 +18,10 @@ export const MiniCartContentsBlock = (
): JSX.Element => {
const { children } = props;

return <>{ children }</>;
return (
<>
<DrawerCloseButton />
{ children }
</>
);
};
1 change: 1 addition & 0 deletions assets/js/blocks/mini-cart/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
36 changes: 34 additions & 2 deletions assets/js/blocks/mini-cart/test/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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 () => {
Expand Down

0 comments on commit 8ac7626

Please sign in to comment.