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

⚛️ Introduce Product Element Blocks #2871

Merged
merged 16 commits into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion assets/css/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@
}

.wc-block-grid__products .wc-block-grid__product-onsale,
.wc-block-layout .wc-block-components-product-sale-badge {
.wc-block-components-product-sale-badge {
background: $twentytwenty-highlights-color;
color: #fff;
font-family: $twentytwenty-headings;
Expand Down
24 changes: 12 additions & 12 deletions assets/js/atomic/blocks/component-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-price',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/price" */ './product/price/block'
/* webpackChunkName: "atomic-block-components/price" */ './product-elements/price/block'
)
),
} );
Expand All @@ -22,7 +22,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-image',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/image" */ './product/image/frontend'
/* webpackChunkName: "atomic-block-components/image" */ './product-elements/image/frontend'
)
),
} );
Expand All @@ -31,7 +31,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-title',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/title" */ './product/title/frontend'
/* webpackChunkName: "atomic-block-components/title" */ './product-elements/title/frontend'
)
),
} );
Expand All @@ -40,7 +40,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-rating',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/rating" */ './product/rating/block'
/* webpackChunkName: "atomic-block-components/rating" */ './product-elements/rating/block'
)
),
} );
Expand All @@ -49,7 +49,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-button',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/button" */ './product/button/block'
/* webpackChunkName: "atomic-block-components/button" */ './product-elements/button/block'
)
),
} );
Expand All @@ -58,7 +58,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-summary',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/summary" */ './product/summary/block'
/* webpackChunkName: "atomic-block-components/summary" */ './product-elements/summary/block'
)
),
} );
Expand All @@ -67,7 +67,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-sale-badge',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/sale-badge" */ './product/sale-badge/block'
/* webpackChunkName: "atomic-block-components/sale-badge" */ './product-elements/sale-badge/block'
)
),
} );
Expand All @@ -76,7 +76,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-sku',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/sku" */ './product/sku/block'
/* webpackChunkName: "atomic-block-components/sku" */ './product-elements/sku/block'
)
),
} );
Expand All @@ -85,7 +85,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-category-list',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/category-list" */ './product/category-list/block'
/* webpackChunkName: "atomic-block-components/category-list" */ './product-elements/category-list/block'
)
),
} );
Expand All @@ -94,7 +94,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-tag-list',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/tag-list" */ './product/tag-list/block'
/* webpackChunkName: "atomic-block-components/tag-list" */ './product-elements/tag-list/block'
)
),
} );
Expand All @@ -103,7 +103,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-stock-indicator',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/stock-indicator" */ './product/stock-indicator/block'
/* webpackChunkName: "atomic-block-components/stock-indicator" */ './product-elements/stock-indicator/block'
)
),
} );
Expand All @@ -112,7 +112,7 @@ registerBlockComponent( {
blockName: 'woocommerce/product-add-to-cart',
component: lazy( () =>
import(
/* webpackChunkName: "atomic-block-components/add-to-cart" */ './product/add-to-cart/frontend'
/* webpackChunkName: "atomic-block-components/add-to-cart" */ './product-elements/add-to-cart/frontend'
)
),
} );
24 changes: 12 additions & 12 deletions assets/js/atomic/blocks/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/**
* Internal dependencies
*/
import './product/title';
import './product/price';
import './product/image';
import './product/rating';
import './product/button';
import './product/summary';
import './product/sale-badge';
import './product/sku';
import './product/category-list';
import './product/tag-list';
import './product/stock-indicator';
import './product/add-to-cart';
import './product-elements/title';
import './product-elements/price';
import './product-elements/image';
import './product-elements/rating';
import './product-elements/button';
import './product-elements/summary';
import './product-elements/sale-badge';
import './product-elements/sku';
import './product-elements/category-list';
import './product-elements/tag-list';
import './product-elements/stock-indicator';
import './product-elements/add-to-cart';
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ export const blockAttributes = {
type: 'boolean',
default: false,
},
productId: {
type: 'number',
default: 0,
},
};

export default blockAttributes;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import classnames from 'classnames';
import { AddToCartFormContextProvider } from '@woocommerce/base-context';
import { useProductDataContext } from '@woocommerce/shared-context';
import { isEmpty } from 'lodash';
import { withProductDataContext } from '@woocommerce/shared-hocs';

/**
* Internal dependencies
Expand All @@ -25,13 +26,10 @@ import {
* @param {Object} props Incoming props.
* @param {string} [props.className] CSS Class name for the component.
* @param {boolean} [props.showFormElements] Should form elements be shown?
* @param {Object} [props.product] Optional product object. Product from context will be
* used if this is not provided.
* @return {*} The component.
*/
const Block = ( { className, showFormElements, ...props } ) => {
const productDataContext = useProductDataContext();
const product = props.product || productDataContext.product || {};
const Block = ( { className, showFormElements } ) => {
const { product } = useProductDataContext();
const componentClass = classnames(
className,
'wc-block-components-product-add-to-cart',
Expand All @@ -50,9 +48,7 @@ const Block = ( { className, showFormElements, ...props } ) => {
<div className={ componentClass }>
<>
{ showFormElements ? (
<AddToCartForm
productType={ product.type || 'simple' }
/>
<AddToCartForm productType={ product.type } />
) : (
<AddToCartButton />
) }
Expand Down Expand Up @@ -80,7 +76,6 @@ const AddToCartForm = ( { productType } ) => {

Block.propTypes = {
className: PropTypes.string,
product: PropTypes.object,
};

export default Block;
export default withProductDataContext( Block );
12 changes: 12 additions & 0 deletions assets/js/atomic/blocks/product-elements/add-to-cart/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { cart, Icon } from '@woocommerce/icons';

export const BLOCK_TITLE = __( 'Add to Cart', 'woo-gutenberg-products-block' );
export const BLOCK_ICON = <Icon srcElement={ cart } />;
export const BLOCK_DESCRIPTION = __(
'Displays an add to cart button. Optionally displays other add to cart form elements.',
'woo-gutenberg-products-block'
);
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import { InspectorControls } from '@wordpress/block-editor';
*/
import './style.scss';
import Block from './block';
import withProductSelector from '../shared/with-product-selector';
import { BLOCK_TITLE, BLOCK_ICON } from './constants';

export default ( { attributes, setAttributes } ) => {
const productDataContext = useProductDataContext();
const product = productDataContext.product || {};
const Edit = ( { attributes, setAttributes } ) => {
const { product } = useProductDataContext();
const { className, showFormElements } = attributes;

return (
Expand All @@ -26,7 +27,7 @@ export default ( { attributes, setAttributes } ) => {
'wc-block-components-product-add-to-cart'
) }
>
<EditProductLink productId={ product.id || 0 } />
<EditProductLink productId={ product.id } />
{ product.type !== 'external' && (
<InspectorControls>
<PanelBody
Expand Down Expand Up @@ -57,3 +58,12 @@ export default ( { attributes, setAttributes } ) => {
</div>
);
};

export default withProductSelector( {
icon: BLOCK_ICON,
label: BLOCK_TITLE,
description: __(
"Choose a product to display it's add to cart form.",
'woo-gutenberg-products-block'
),
} )( Edit );
32 changes: 32 additions & 0 deletions assets/js/atomic/blocks/product-elements/add-to-cart/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* External dependencies
*/
import { registerExperimentalBlockType } from '@woocommerce/block-settings';

/**
* Internal dependencies
*/
import sharedConfig from '../shared/config';
import edit from './edit';
import attributes from './attributes';
import {
BLOCK_TITLE as title,
BLOCK_ICON as icon,
BLOCK_DESCRIPTION as description,
} from './constants';

const blockConfig = {
title,
description,
icon: {
src: icon,
foreground: '#874FB9',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we switched to the new purple?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was this way in the mocks. Should we keep old purple? Only affects new elements.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might as well migrate all of our blocks then?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably best answered by @nerrad or @LevinMedia, but shouldn't be blocking as it's a minor thing.

},
edit,
attributes,
};

registerExperimentalBlockType( 'woocommerce/product-add-to-cart', {
...sharedConfig,
...blockConfig,
} );
43 changes: 43 additions & 0 deletions assets/js/atomic/blocks/product-elements/add-to-cart/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.wc-block-components-product-add-to-cart {
margin: 0;
display: flex;
flex-wrap: wrap;

.wc-block-components-product-add-to-cart-button {
margin: 0 0 em($gap-small) 0;

.wc-block-components-button__text {
display: block;

> svg {
fill: currentColor;
vertical-align: top;
width: 1.5em;
height: 1.5em;
margin: -0.25em 0 -0.25em 0.5em;
}
}
}

.wc-block-components-product-add-to-cart-quantity {
margin: 0 1em em($gap-small) 0;
width: 5em;
padding: 0.618em;
background: $white;
border: 1px solid #ccc;
border-radius: 2px;
color: #43454b;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.125);
text-align: center;
}
}
.wc-block-components-product-add-to-cart--placeholder {
.wc-block-components-product-add-to-cart-quantity,
.wc-block-components-product-add-to-cart-button {
@include placeholder();
}
}

.wc-block-grid .wc-block-components-product-add-to-cart {
justify-content: center;
}
8 changes: 8 additions & 0 deletions assets/js/atomic/blocks/product-elements/button/attributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const blockAttributes = {
productId: {
type: 'number',
default: 0,
},
};

export default blockAttributes;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
useInnerBlockLayoutContext,
useProductDataContext,
} from '@woocommerce/shared-context';
import { withProductDataContext } from '@woocommerce/shared-hocs';

/**
* Internal dependencies
Expand All @@ -23,25 +24,24 @@ import './style.scss';
*
* @param {Object} props Incoming props.
* @param {string} [props.className] CSS Class name for the component.
* @param {Object} [props.product] Optional product object. Product from context will be used if
* this is not provided.
* @return {*} The component.
*/
const Block = ( { className, ...props } ) => {
const Block = ( { className } ) => {
const { parentClassName } = useInnerBlockLayoutContext();
const productDataContext = useProductDataContext();
const product = props.product || productDataContext.product;
const { product } = useProductDataContext();

return (
<div
className={ classnames(
className,
'wp-block-button',
'wc-block-components-product-button',
`${ parentClassName }__product-add-to-cart`
{
[ `${ parentClassName }__product-add-to-cart` ]: parentClassName,
}
) }
>
{ product ? (
{ product.id ? (
<AddToCartButton product={ product } />
) : (
<AddToCartButtonPlaceholder />
Expand Down Expand Up @@ -142,7 +142,6 @@ const AddToCartButtonPlaceholder = () => {

Block.propTypes = {
className: PropTypes.string,
product: PropTypes.object,
};

export default Block;
export default withProductDataContext( Block );
Loading