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

Commit ac52ef6

Browse files
authored
Split blocks into separate JS files (#305)
This lets us use the functionality of `register_block_type` to automatically enqueue the scripts and styles used by blocks in the editor, and eventually, styles on the frontend as well. Also adds cssnano to minify our CSS.
1 parent 31e0218 commit ac52ef6

File tree

23 files changed

+1421
-569
lines changed

23 files changed

+1421
-569
lines changed
Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Import the woocommerce components stylesheet
2-
// @todo Move this to a separate file so we can build a cacheable single stylesheet for all blocks.
32
@import "../../node_modules/@woocommerce/components/build-style/style.css";
43

54
// Hack to hide preview overflow.
@@ -36,6 +35,7 @@
3635
padding: 2em 1em;
3736
}
3837

38+
// Styles for "resuable block" preview.
3939
.editor-block-preview & {
4040
min-width: 5em;
4141

@@ -51,37 +51,3 @@
5151
}
5252
}
5353
}
54-
55-
.wc-block-products-category__selection,
56-
.wc-block-handpicked-products__selection {
57-
width: 100%;
58-
}
59-
60-
.components-panel {
61-
.woocommerce-search-list {
62-
padding: 0;
63-
}
64-
65-
.woocommerce-search-list__selected {
66-
margin: 0 0 $gap;
67-
padding: 0;
68-
border-top: none;
69-
// 54px is the height of 1 row of tags in the sidebar.
70-
min-height: 54px;
71-
}
72-
73-
.woocommerce-search-list__search {
74-
margin: 0 0 $gap;
75-
padding: 0;
76-
border-top: none;
77-
}
78-
79-
.woocommerce-product-categories__operator.components-base-control {
80-
margin-top: $gap;
81-
82-
.components-select-control__input {
83-
margin-left: 0;
84-
min-width: 100%;
85-
}
86-
}
87-
}

assets/js/handpicked-products.js renamed to assets/js/blocks/handpicked-products/block.js

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@
44
import { __ } from '@wordpress/i18n';
55
import { addQueryArgs } from '@wordpress/url';
66
import apiFetch from '@wordpress/api-fetch';
7-
import {
8-
BlockAlignmentToolbar,
9-
BlockControls,
10-
InspectorControls,
11-
} from '@wordpress/editor';
7+
import { BlockControls, InspectorControls } from '@wordpress/editor';
128
import {
139
Button,
1410
PanelBody,
@@ -25,11 +21,11 @@ import PropTypes from 'prop-types';
2521
/**
2622
* Internal dependencies
2723
*/
28-
import getQuery from './utils/get-query';
29-
import { IconWidgets } from './components/icons';
30-
import ProductsControl from './components/products-control';
31-
import ProductOrderbyControl from './components/product-orderby-control';
32-
import ProductPreview from './components/product-preview';
24+
import getQuery from '../../utils/get-query';
25+
import { IconWidgets } from '../../components/icons';
26+
import ProductsControl from '../../components/products-control';
27+
import ProductOrderbyControl from '../../components/product-orderby-control';
28+
import ProductPreview from '../../components/product-preview';
3329

3430
/**
3531
* Component to handle edit mode of "Hand-picked Products".
@@ -50,12 +46,9 @@ class ProductsBlock extends Component {
5046
}
5147

5248
componentDidUpdate( prevProps ) {
53-
const hasChange = [ 'products', 'columns', 'orderby' ].reduce(
54-
( acc, key ) => {
55-
return acc || prevProps.attributes[ key ] !== this.props.attributes[ key ];
56-
},
57-
false
58-
);
49+
const hasChange = [ 'products', 'columns', 'orderby' ].reduce( ( acc, key ) => {
50+
return acc || prevProps.attributes[ key ] !== this.props.attributes[ key ];
51+
}, false );
5952
if ( hasChange ) {
6053
this.debouncedGetProducts();
6154
}
@@ -129,7 +122,10 @@ class ProductsBlock extends Component {
129122
const onDone = () => {
130123
setAttributes( { editMode: false } );
131124
debouncedSpeak(
132-
__( 'Showing Hand-picked Products block preview.', 'woo-gutenberg-products-block' )
125+
__(
126+
'Showing Hand-picked Products block preview.',
127+
'woo-gutenberg-products-block'
128+
)
133129
);
134130
};
135131

@@ -161,7 +157,7 @@ class ProductsBlock extends Component {
161157

162158
render() {
163159
const { setAttributes } = this.props;
164-
const { align, columns, editMode } = this.props.attributes;
160+
const { columns, editMode } = this.props.attributes;
165161
const { loaded, products } = this.state;
166162
const hasSelectedProducts = products && products.length;
167163
const classes = [ 'wc-block-products-grid', 'wc-block-handpicked-products' ];
@@ -179,11 +175,6 @@ class ProductsBlock extends Component {
179175
return (
180176
<Fragment>
181177
<BlockControls>
182-
<BlockAlignmentToolbar
183-
controls={ [ 'wide', 'full' ] }
184-
value={ align }
185-
onChange={ ( nextAlign ) => setAttributes( { align: nextAlign } ) }
186-
/>
187178
<Toolbar
188179
controls={ [
189180
{
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { __ } from '@wordpress/i18n';
5+
import { registerBlockType } from '@wordpress/blocks';
6+
import { RawHTML } from '@wordpress/element';
7+
8+
/**
9+
* Internal dependencies
10+
*/
11+
import './style.scss';
12+
import Block from './block';
13+
import getShortcode from '../../utils/get-shortcode';
14+
import { IconWidgets } from '../../components/icons';
15+
16+
registerBlockType( 'woocommerce/handpicked-products', {
17+
title: __( 'Hand-picked Products', 'woo-gutenberg-products-block' ),
18+
icon: <IconWidgets />,
19+
category: 'woocommerce',
20+
keywords: [ __( 'WooCommerce', 'woo-gutenberg-products-block' ) ],
21+
description: __(
22+
'Display a selection of hand-picked products in a grid.',
23+
'woo-gutenberg-products-block'
24+
),
25+
supports: {
26+
align: [ 'wide', 'full' ],
27+
},
28+
attributes: {
29+
/**
30+
* Alignment of product grid
31+
*/
32+
align: {
33+
type: 'string',
34+
},
35+
36+
/**
37+
* Number of columns.
38+
*/
39+
columns: {
40+
type: 'number',
41+
default: wc_product_block_data.default_columns,
42+
},
43+
44+
/**
45+
* Toggle for edit mode in the block preview.
46+
*/
47+
editMode: {
48+
type: 'boolean',
49+
default: true,
50+
},
51+
52+
/**
53+
* How to order the products: 'date', 'popularity', 'price_asc', 'price_desc' 'rating', 'title'.
54+
*/
55+
orderby: {
56+
type: 'string',
57+
default: 'date',
58+
},
59+
60+
/**
61+
* The list of product IDs to display
62+
*/
63+
products: {
64+
type: 'array',
65+
default: [],
66+
},
67+
},
68+
69+
/**
70+
* Renders and manages the block.
71+
*/
72+
edit( props ) {
73+
return <Block { ...props } />;
74+
},
75+
76+
/**
77+
* Save the block content in the post content. Block content is saved as a products shortcode.
78+
*
79+
* @return string
80+
*/
81+
save( props ) {
82+
const {
83+
align,
84+
} = props.attributes; /* eslint-disable-line react/prop-types */
85+
return (
86+
<RawHTML className={ align ? `align${ align }` : '' }>
87+
{ getShortcode( props, 'woocommerce/handpicked-products' ) }
88+
</RawHTML>
89+
);
90+
},
91+
} );
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.wc-block-handpicked-products__selection {
2+
width: 100%;
3+
}

assets/js/product-best-sellers.js renamed to assets/js/blocks/product-best-sellers/block.js

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@
44
import { __ } from '@wordpress/i18n';
55
import { addQueryArgs } from '@wordpress/url';
66
import apiFetch from '@wordpress/api-fetch';
7-
import {
8-
BlockAlignmentToolbar,
9-
BlockControls,
10-
InspectorControls,
11-
} from '@wordpress/editor';
7+
import { InspectorControls } from '@wordpress/editor';
128
import { Component, Fragment } from '@wordpress/element';
139
import { debounce } from 'lodash';
1410
import Gridicon from 'gridicons';
@@ -23,9 +19,9 @@ import PropTypes from 'prop-types';
2319
/**
2420
* Internal dependencies
2521
*/
26-
import getQuery from './utils/get-query';
27-
import ProductCategoryControl from './components/product-category-control';
28-
import ProductPreview from './components/product-preview';
22+
import getQuery from '../../utils/get-query';
23+
import ProductCategoryControl from '../../components/product-category-control';
24+
import ProductPreview from '../../components/product-preview';
2925

3026
/**
3127
* Component to handle edit mode of "Best Selling Products".
@@ -121,8 +117,7 @@ class ProductBestSellersBlock extends Component {
121117
}
122118

123119
render() {
124-
const { setAttributes } = this.props;
125-
const { columns, align } = this.props.attributes;
120+
const { columns } = this.props.attributes;
126121
const { loaded, products } = this.state;
127122
const classes = [
128123
'wc-block-products-grid',
@@ -141,13 +136,6 @@ class ProductBestSellersBlock extends Component {
141136

142137
return (
143138
<Fragment>
144-
<BlockControls>
145-
<BlockAlignmentToolbar
146-
controls={ [ 'wide', 'full' ] }
147-
value={ align }
148-
onChange={ ( nextAlign ) => setAttributes( { align: nextAlign } ) }
149-
/>
150-
</BlockControls>
151139
{ this.getInspectorControls() }
152140
<div className={ classes.join( ' ' ) }>
153141
{ products.length ? (
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { __ } from '@wordpress/i18n';
5+
import Gridicon from 'gridicons';
6+
import { registerBlockType } from '@wordpress/blocks';
7+
import { RawHTML } from '@wordpress/element';
8+
9+
/**
10+
* Internal dependencies
11+
*/
12+
import Block from './block';
13+
import getShortcode from '../../utils/get-shortcode';
14+
import sharedAttributes from '../../utils/shared-attributes';
15+
16+
registerBlockType( 'woocommerce/product-best-sellers', {
17+
title: __( 'Best Selling Products', 'woo-gutenberg-products-block' ),
18+
icon: <Gridicon icon="stats-up-alt" />,
19+
category: 'woocommerce',
20+
keywords: [ __( 'WooCommerce', 'woo-gutenberg-products-block' ) ],
21+
description: __(
22+
'Display a grid of your all-time best selling products.',
23+
'woo-gutenberg-products-block'
24+
),
25+
supports: {
26+
align: [ 'wide', 'full' ],
27+
},
28+
attributes: {
29+
...sharedAttributes,
30+
},
31+
32+
/**
33+
* Renders and manages the block.
34+
*/
35+
edit( props ) {
36+
return <Block { ...props } />;
37+
},
38+
39+
/**
40+
* Save the block content in the post content. Block content is saved as a products shortcode.
41+
*
42+
* @return string
43+
*/
44+
save( props ) {
45+
const {
46+
align,
47+
} = props.attributes; /* eslint-disable-line react/prop-types */
48+
return (
49+
<RawHTML className={ align ? `align${ align }` : '' }>
50+
{ getShortcode( props, 'woocommerce/product-best-sellers' ) }
51+
</RawHTML>
52+
);
53+
},
54+
} );

0 commit comments

Comments
 (0)