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

Commit

Permalink
Add global style support to Mini Cart (button) (#5100)
Browse files Browse the repository at this point in the history
  • Loading branch information
dinhtungdu authored Nov 17, 2021
1 parent e76f569 commit c47f461
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 40 deletions.
33 changes: 24 additions & 9 deletions assets/js/blocks/cart-checkout/mini-cart/block.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import classNames from 'classnames';
import classnames from 'classnames';
import { __, _n, sprintf } from '@wordpress/i18n';
import { useState, useEffect, useRef } from '@wordpress/element';
import {
Expand Down Expand Up @@ -31,10 +31,6 @@ import CartLineItemsTable from '../cart/cart-line-items-table';
import QuantityBadge from './quantity-badge';
import './style.scss';

interface MiniCartBlockProps {
isInitiallyOpen?: boolean;
}

const PaymentMethodIconsElement = (): JSX.Element => {
const { paymentMethods } = usePaymentMethods();
return (
Expand All @@ -44,9 +40,18 @@ const PaymentMethodIconsElement = (): JSX.Element => {
);
};

interface Props {
isInitiallyOpen?: boolean;
transparentButton: boolean;
colorClassNames?: string;
style?: Record< string, Record< string, string > >;
}

const MiniCartBlock = ( {
isInitiallyOpen = false,
}: MiniCartBlockProps ): JSX.Element => {
colorClassNames,
style,
}: Props ): JSX.Element => {
const {
cartItems,
cartItemsCount,
Expand Down Expand Up @@ -115,6 +120,11 @@ const MiniCartBlock = ( {
formatPrice( subTotal, getCurrencyFromPriceResponse( cartTotals ) )
);

const colorStyle = {
backgroundColor: style?.color?.background,
color: style?.color?.text,
};

const contents =
! cartIsLoading && cartItems.length === 0 ? (
<div
Expand Down Expand Up @@ -176,7 +186,8 @@ const MiniCartBlock = ( {
return (
<>
<button
className="wc-block-mini-cart__button"
className={ `wc-block-mini-cart__button ${ colorClassNames }` }
style={ colorStyle }
onClick={ () => {
if ( ! isOpen ) {
setIsOpen( true );
Expand All @@ -191,10 +202,14 @@ const MiniCartBlock = ( {
getCurrencyFromPriceResponse( cartTotals )
) }
</span>
<QuantityBadge count={ cartItemsCount } />
<QuantityBadge
count={ cartItemsCount }
colorClassNames={ colorClassNames }
style={ colorStyle }
/>
</button>
<Drawer
className={ classNames(
className={ classnames(
'wc-block-mini-cart__drawer',
'is-mobile',
{
Expand Down
19 changes: 15 additions & 4 deletions assets/js/blocks/cart-checkout/mini-cart/component-frontend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,21 @@ const renderMiniCartFrontend = () => {
renderFrontend( {
selector: '.wc-block-mini-cart',
Block: MiniCartBlock,
getProps: ( el: HTMLElement ) => ( {
isDataOutdated: el.dataset.isDataOutdated,
isInitiallyOpen: el.dataset.isInitiallyOpen === 'true',
} ),
getProps: ( el: HTMLElement ) => {
let colorClassNames = '';
const button = el.querySelector( '.wc-block-mini-cart__button' );
if ( button !== null ) {
colorClassNames = button.classList
.toString()
.replace( 'wc-block-mini-cart__button', '' );
}
return {
isDataOutdated: el.dataset.isDataOutdated,
isInitiallyOpen: el.dataset.isInitiallyOpen === 'true',
colorClassNames,
style: el.dataset.style ? JSON.parse( el.dataset.style ) : {},
};
},
} );

// Refocus previously focused button if drawer is not open.
Expand Down
87 changes: 82 additions & 5 deletions assets/js/blocks/cart-checkout/mini-cart/edit.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,108 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import {
InspectorControls,
useBlockProps,
getColorClassName,
} from '@wordpress/block-editor';
import type { ReactElement } from 'react';
import { formatPrice } from '@woocommerce/price-format';
import { CartCheckoutCompatibilityNotice } from '@woocommerce/editor-components/compatibility-notices';
import { PanelBody, ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import classnames from 'classnames';

/**
* Internal dependencies
*/
import QuantityBadge from './quantity-badge';

const MiniCartBlock = (): ReactElement => {
interface Attributes {
isInitiallyOpen?: boolean;
transparentButton: boolean;
backgroundColor?: string;
textColor?: string;
style?: Record< string, Record< string, string > >;
}

interface Props {
attributes: Attributes;
setAttributes: ( attributes: Record< string, unknown > ) => void;
}

const MiniCartBlock = ( {
attributes,
setAttributes,
}: Props ): ReactElement => {
const { transparentButton, backgroundColor, textColor, style } = attributes;
const blockProps = useBlockProps( {
className: 'wc-block-mini-cart',
className: classnames( 'wc-block-mini-cart', {
'is-transparent': transparentButton,
} ),
} );

/**
* @todo Replace `getColorClassName` and manual style manipulation with
* `useColorProps` once the hook is no longer experimental.
*/
const backgroundClass = getColorClassName(
'background-color',
backgroundColor
);
const textColorClass = getColorClassName( 'color', textColor );

const colorStyle = {
backgroundColor: style?.color?.background,
color: style?.color?.text,
};

const colorClassNames = classnames( backgroundClass, textColorClass, {
'has-background': backgroundClass || style?.color?.background,
'has-text-color': textColorClass || style?.color?.text,
} );

const productCount = 0;
const productTotal = 0;

return (
<div { ...blockProps }>
<button className="wc-block-mini-cart__button">
<InspectorControls>
<PanelBody
title={ __(
'Button style',
'woo-gutenberg-products-block'
) }
>
<ToggleControl
label={ __(
'Use transparent button',
'woo-gutenberg-products-block'
) }
checked={ transparentButton }
onChange={ () =>
setAttributes( {
transparentButton: ! transparentButton,
} )
}
/>
</PanelBody>
</InspectorControls>
<button
className={ classnames(
'wc-block-mini-cart__button',
colorClassNames
) }
style={ colorStyle }
>
<span className="wc-block-mini-cart__amount">
{ formatPrice( productTotal ) }
</span>
<QuantityBadge count={ productCount } />
<QuantityBadge
count={ productCount }
colorClassNames={ colorClassNames }
style={ colorStyle }
/>
</button>
<CartCheckoutCompatibilityNotice blockName="mini-cart" />
</div>
Expand Down
17 changes: 17 additions & 0 deletions assets/js/blocks/cart-checkout/mini-cart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ const settings = {
supports: {
html: false,
multiple: false,
color: {
/**
* Because we don't target the wrapper element, we don't need
* to add color classes and style to the wrapper.
*/
__experimentalSkipSerialization: true,
},
/**
* We need this experimental flag because we don't want to style the
* wrapper but inner elements.
*/
__experimentalSelector:
'.wc-block-mini-cart__button, .wc-block-mini-cart__badge',
},
example: {
attributes: {
Expand All @@ -38,6 +51,10 @@ const settings = {
default: false,
save: false,
},
transparentButton: {
type: 'boolean',
default: true,
},
},

edit,
Expand Down
37 changes: 27 additions & 10 deletions assets/js/blocks/cart-checkout/mini-cart/quantity-badge/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,32 @@ import { Icon, miniCart } from '@woocommerce/icons';
*/
import './style.scss';

const QuantityBadge = ( { count }: { count: number } ): JSX.Element => (
<span className="wc-block-mini-cart__quantity-badge">
<Icon
className="wc-block-mini-cart__icon"
size={ 20 }
srcElement={ miniCart }
/>
<span className="wc-block-mini-cart__badge">{ count }</span>
</span>
);
interface Props {
count: number;
colorClassNames?: string;
style?: Record< string, string | undefined >;
}

const QuantityBadge = ( {
count,
colorClassNames,
style,
}: Props ): JSX.Element => {
return (
<span className="wc-block-mini-cart__quantity-badge">
<Icon
className="wc-block-mini-cart__icon"
size={ 20 }
srcElement={ miniCart }
/>
<span
className={ `wc-block-mini-cart__badge ${ colorClassNames }` }
style={ style }
>
{ count }
</span>
</span>
);
};

export default QuantityBadge;
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
.wc-block-mini-cart__badge {
align-items: center;
background: #fff;
border: 2px solid;
border: 0.15em solid;
border-radius: 1em;
box-shadow: 0 0 0 2px #fff;
box-sizing: border-box;
color: #000;
display: flex;
Expand Down
11 changes: 8 additions & 3 deletions assets/js/blocks/cart-checkout/mini-cart/style.scss
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
.wc-block-mini-cart {
.wc-block-mini-cart.wp-block-woocommerce-mini-cart {
background-color: transparent !important;
display: flex;
justify-content: flex-end;

&.is-transparent .wc-block-mini-cart__button {
background-color: transparent !important;
}
}

.wc-block-mini-cart__button {
align-items: center;
background: transparent;
border: none;
color: inherit;
display: flex;
font-weight: 400;
padding: em($gap-small) em($gap-smaller);

&:hover {
background: transparent;
opacity: 0.6;
}
}
Expand All @@ -38,6 +42,7 @@
font-size: 1rem;

.components-modal__content {
box-sizing: border-box;
display: flex;
flex-direction: column;
height: 100%;
Expand Down
Loading

0 comments on commit c47f461

Please sign in to comment.