Update menu functionality to match latest designs

This commit is contained in:
claudiulodro 2018-02-15 09:42:24 -08:00
parent 6533d2f166
commit 149a546290
6 changed files with 379 additions and 172 deletions

View File

@ -1 +1 @@
.wc-products-block-preview.grid{overflow:hidden}.wc-products-block-preview.grid .product-preview{float:right;text-align:center;margin-left:3.8%}.wc-products-block-preview.grid.cols-1 .product-preview{float:none;margin-left:0}.wc-products-block-preview.grid.cols-2 .product-preview{width:48%}.wc-products-block-preview.grid.cols-2 .product-preview:nth-of-type(2n){margin-left:0}.wc-products-block-preview.grid.cols-3 .product-preview{width:30.75%}.wc-products-block-preview.grid.cols-3 .product-preview:nth-of-type(3n){margin-left:0}.wc-products-block-preview.grid.cols-4 .product-preview{width:22.05%}.wc-products-block-preview.grid.cols-4 .product-preview:nth-of-type(4n){margin-left:0}.wc-products-block-preview.grid.cols-5 .product-preview{width:16.9%}.wc-products-block-preview.grid.cols-5 .product-preview:nth-of-type(5n){margin-left:0}.wc-products-block-preview.list .product-preview{overflow:hidden}.wc-products-block-preview.list img{float:right;width:50%;margin-left:2em;margin-bottom:2em}.wc-products-block-preview .product-add-to-cart{background:gray;border-radius:10px;color:#fff;cursor:pointer;padding:.5em 1em;line-height:3em}.wc-product-display-settings{background-color:#f8f9f9;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;padding:1em;min-height:200px;position:relative}.wc-product-display-settings>h4{text-align:center}.wc-product-display-settings .display-settings-container{background-color:#fff}.wc-product-display-settings .display-settings-container.existing{position:absolute;width:100%;z-index:999}.wc-product-display-settings .wc-products-display-option{border:1px solid gray}.wc-product-display-settings .display-select{margin:0 -1em 20px;padding-bottom:20px;border-bottom:1px solid #e6eaee;text-align:center}.wc-product-display-settings .display-select select{margin-right:1em}.wc-product-display-settings .product-specific-select .add-new{background:#ddd;display:inline-block;margin-bottom:20px;padding:60px 30px}.wc-product-display-settings .product-category-select{margin:0 auto;position:relative}.wc-product-display-settings .product-category-select div+div>ul{height:100px;overflow-y:scroll;padding:0 0 15px}.wc-product-display-settings .product-category-select #product-category-search{width:100%;margin:0 0 10px}.wc-product-display-settings .product-category-select ul{list-style-type:none}.wc-product-display-settings .product-category-select ul li{margin:3px 0}.wc-product-display-settings .product-category-select ul li input[type=checkbox]{margin-left:5px}.wc-product-display-settings .product-category-select ul li ul li input[type=checkbox]{margin-left:20px}.wc-product-display-settings .product-category-select:after{content:'';position:absolute;bottom:0;width:100%;height:1.5em;background:-webkit-linear-gradient(rgba(255,255,255,.1) 0,#f8f9f9 100%);background:linear-gradient(rgba(255,255,255,.1) 0,#f8f9f9 100%)}.wc-product-display-settings .block-footer{margin:0 -1em;padding-top:1em;border-top:1px solid #e6eaee;text-align:center}.wc-product-display-settings .display-select+.block-footer{padding-top:0;border:0}@media only screen and (min-width:700px){.wc-product-display-settings .product-category-select{width:400px}.wc-product-display-settings .product-category-select div+div{overflow:hidden}.wc-product-display-settings .product-category-select div+div>ul{width:440px}} .wc-products-block-preview.grid{overflow:hidden}.wc-products-block-preview.grid .product-preview{float:right;text-align:center;margin-left:3.8%}.wc-products-block-preview.grid.cols-1 .product-preview{float:none;margin-left:0}.wc-products-block-preview.grid.cols-2 .product-preview{width:48%}.wc-products-block-preview.grid.cols-2 .product-preview:nth-of-type(2n){margin-left:0}.wc-products-block-preview.grid.cols-3 .product-preview{width:30.75%}.wc-products-block-preview.grid.cols-3 .product-preview:nth-of-type(3n){margin-left:0}.wc-products-block-preview.grid.cols-4 .product-preview{width:22.05%}.wc-products-block-preview.grid.cols-4 .product-preview:nth-of-type(4n){margin-left:0}.wc-products-block-preview.grid.cols-5 .product-preview{width:16.9%}.wc-products-block-preview.grid.cols-5 .product-preview:nth-of-type(5n){margin-left:0}.wc-products-block-preview.list .product-preview{overflow:hidden}.wc-products-block-preview.list img{float:right;width:50%;margin-left:2em;margin-bottom:2em}.wc-products-block-preview .product-add-to-cart{background:gray;border-radius:10px;color:#fff;cursor:pointer;padding:.5em 1em;line-height:3em}.wc-product-display-settings{background-color:#f8f9f9;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;padding:1em;min-height:200px;position:relative}.wc-product-display-settings>h4{text-align:center}.wc-product-display-settings .wc-products-display-option{background-color:#fff;padding:1.5em;box-sizing:border-box;border:1px solid gray;width:80%;margin-right:auto;margin-left:auto}.wc-product-display-settings .wc-products-display-option h4{margin:0;font-size:1.25em}.wc-product-display-settings .wc-products-display-option p{margin:0}.wc-product-display-settings .wc-products-display-option.value-attribute,.wc-product-display-settings .wc-products-display-option.value-best_rated,.wc-product-display-settings .wc-products-display-option.value-best_sellers,.wc-product-display-settings .wc-products-display-option.value-featured,.wc-product-display-settings .wc-products-display-option.value-on_sale{display:none}.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-attribute,.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-best_rated,.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-best_sellers,.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-featured,.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-on_sale{display:block}.wc-product-display-settings .display-settings-container.existing{left:0;position:absolute;width:80%;z-index:999}.wc-product-display-settings .display-settings-container.existing .wc-products-display-option{margin-left:0}.wc-product-display-settings .settings-heading{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.wc-product-display-settings .display-select{margin:0 -1em 20px;padding-bottom:20px;border-bottom:1px solid #e6eaee;text-align:center}.wc-product-display-settings .display-select select{margin-right:1em}.wc-product-display-settings .product-specific-select .add-new{background:#ddd;display:inline-block;margin-bottom:20px;padding:60px 30px}.wc-product-display-settings .product-category-select{margin:0 auto;position:relative}.wc-product-display-settings .product-category-select div+div>ul{height:100px;overflow-y:scroll;padding:0 0 15px}.wc-product-display-settings .product-category-select #product-category-search{width:100%;margin:0 0 10px}.wc-product-display-settings .product-category-select ul{list-style-type:none}.wc-product-display-settings .product-category-select ul li{margin:3px 0}.wc-product-display-settings .product-category-select ul li input[type=checkbox]{margin-left:5px}.wc-product-display-settings .product-category-select ul li ul li input[type=checkbox]{margin-left:20px}.wc-product-display-settings .product-category-select:after{content:'';position:absolute;bottom:0;width:100%;height:1.5em;background:-webkit-linear-gradient(rgba(255,255,255,.1) 0,#f8f9f9 100%);background:linear-gradient(rgba(255,255,255,.1) 0,#f8f9f9 100%)}.wc-product-display-settings .block-footer{margin:0 -1em;padding-top:1em;border-top:1px solid #e6eaee;text-align:center}.wc-product-display-settings .display-select+.block-footer{padding-top:0;border:0}@media only screen and (min-width:700px){.wc-product-display-settings .product-category-select{width:400px}.wc-product-display-settings .product-category-select div+div{overflow:hidden}.wc-product-display-settings .product-category-select div+div>ul{width:440px}}

View File

@ -1 +1 @@
.wc-products-block-preview.grid{overflow:hidden}.wc-products-block-preview.grid .product-preview{float:left;text-align:center;margin-right:3.8%}.wc-products-block-preview.grid.cols-1 .product-preview{float:none;margin-right:0}.wc-products-block-preview.grid.cols-2 .product-preview{width:48%}.wc-products-block-preview.grid.cols-2 .product-preview:nth-of-type(2n){margin-right:0}.wc-products-block-preview.grid.cols-3 .product-preview{width:30.75%}.wc-products-block-preview.grid.cols-3 .product-preview:nth-of-type(3n){margin-right:0}.wc-products-block-preview.grid.cols-4 .product-preview{width:22.05%}.wc-products-block-preview.grid.cols-4 .product-preview:nth-of-type(4n){margin-right:0}.wc-products-block-preview.grid.cols-5 .product-preview{width:16.9%}.wc-products-block-preview.grid.cols-5 .product-preview:nth-of-type(5n){margin-right:0}.wc-products-block-preview.list .product-preview{overflow:hidden}.wc-products-block-preview.list img{float:left;width:50%;margin-right:2em;margin-bottom:2em}.wc-products-block-preview .product-add-to-cart{background:gray;border-radius:10px;color:#fff;cursor:pointer;padding:.5em 1em;line-height:3em}.wc-product-display-settings{background-color:#f8f9f9;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;padding:1em;min-height:200px;position:relative}.wc-product-display-settings>h4{text-align:center}.wc-product-display-settings .display-settings-container{background-color:#fff}.wc-product-display-settings .display-settings-container.existing{position:absolute;width:100%;z-index:999}.wc-product-display-settings .wc-products-display-option{border:1px solid gray}.wc-product-display-settings .display-select{margin:0 -1em 20px;padding-bottom:20px;border-bottom:1px solid #e6eaee;text-align:center}.wc-product-display-settings .display-select select{margin-left:1em}.wc-product-display-settings .product-specific-select .add-new{background:#ddd;display:inline-block;margin-bottom:20px;padding:60px 30px}.wc-product-display-settings .product-category-select{margin:0 auto;position:relative}.wc-product-display-settings .product-category-select div+div>ul{height:100px;overflow-y:scroll;padding:0 0 15px}.wc-product-display-settings .product-category-select #product-category-search{width:100%;margin:0 0 10px}.wc-product-display-settings .product-category-select ul{list-style-type:none}.wc-product-display-settings .product-category-select ul li{margin:3px 0}.wc-product-display-settings .product-category-select ul li input[type=checkbox]{margin-right:5px}.wc-product-display-settings .product-category-select ul li ul li input[type=checkbox]{margin-right:20px}.wc-product-display-settings .product-category-select:after{content:'';position:absolute;bottom:0;width:100%;height:1.5em;background:-webkit-linear-gradient(rgba(255,255,255,.1) 0,#f8f9f9 100%);background:linear-gradient(rgba(255,255,255,.1) 0,#f8f9f9 100%)}.wc-product-display-settings .block-footer{margin:0 -1em;padding-top:1em;border-top:1px solid #e6eaee;text-align:center}.wc-product-display-settings .display-select+.block-footer{padding-top:0;border:0}@media only screen and (min-width:700px){.wc-product-display-settings .product-category-select{width:400px}.wc-product-display-settings .product-category-select div+div{overflow:hidden}.wc-product-display-settings .product-category-select div+div>ul{width:440px}} .wc-products-block-preview.grid{overflow:hidden}.wc-products-block-preview.grid .product-preview{float:left;text-align:center;margin-right:3.8%}.wc-products-block-preview.grid.cols-1 .product-preview{float:none;margin-right:0}.wc-products-block-preview.grid.cols-2 .product-preview{width:48%}.wc-products-block-preview.grid.cols-2 .product-preview:nth-of-type(2n){margin-right:0}.wc-products-block-preview.grid.cols-3 .product-preview{width:30.75%}.wc-products-block-preview.grid.cols-3 .product-preview:nth-of-type(3n){margin-right:0}.wc-products-block-preview.grid.cols-4 .product-preview{width:22.05%}.wc-products-block-preview.grid.cols-4 .product-preview:nth-of-type(4n){margin-right:0}.wc-products-block-preview.grid.cols-5 .product-preview{width:16.9%}.wc-products-block-preview.grid.cols-5 .product-preview:nth-of-type(5n){margin-right:0}.wc-products-block-preview.list .product-preview{overflow:hidden}.wc-products-block-preview.list img{float:left;width:50%;margin-right:2em;margin-bottom:2em}.wc-products-block-preview .product-add-to-cart{background:gray;border-radius:10px;color:#fff;cursor:pointer;padding:.5em 1em;line-height:3em}.wc-product-display-settings{background-color:#f8f9f9;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;padding:1em;min-height:200px;position:relative}.wc-product-display-settings>h4{text-align:center}.wc-product-display-settings .wc-products-display-option{background-color:#fff;padding:1.5em;box-sizing:border-box;border:1px solid gray;width:80%;margin-left:auto;margin-right:auto}.wc-product-display-settings .wc-products-display-option h4{margin:0;font-size:1.25em}.wc-product-display-settings .wc-products-display-option p{margin:0}.wc-product-display-settings .wc-products-display-option.value-attribute,.wc-product-display-settings .wc-products-display-option.value-best_rated,.wc-product-display-settings .wc-products-display-option.value-best_sellers,.wc-product-display-settings .wc-products-display-option.value-featured,.wc-product-display-settings .wc-products-display-option.value-on_sale{display:none}.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-attribute,.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-best_rated,.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-best_sellers,.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-featured,.wc-product-display-settings.expanded-group-filter .wc-products-display-option.value-on_sale{display:block}.wc-product-display-settings .display-settings-container.existing{right:0;position:absolute;width:80%;z-index:999}.wc-product-display-settings .display-settings-container.existing .wc-products-display-option{margin-right:0}.wc-product-display-settings .settings-heading{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.wc-product-display-settings .display-select{margin:0 -1em 20px;padding-bottom:20px;border-bottom:1px solid #e6eaee;text-align:center}.wc-product-display-settings .display-select select{margin-left:1em}.wc-product-display-settings .product-specific-select .add-new{background:#ddd;display:inline-block;margin-bottom:20px;padding:60px 30px}.wc-product-display-settings .product-category-select{margin:0 auto;position:relative}.wc-product-display-settings .product-category-select div+div>ul{height:100px;overflow-y:scroll;padding:0 0 15px}.wc-product-display-settings .product-category-select #product-category-search{width:100%;margin:0 0 10px}.wc-product-display-settings .product-category-select ul{list-style-type:none}.wc-product-display-settings .product-category-select ul li{margin:3px 0}.wc-product-display-settings .product-category-select ul li input[type=checkbox]{margin-right:5px}.wc-product-display-settings .product-category-select ul li ul li input[type=checkbox]{margin-right:20px}.wc-product-display-settings .product-category-select:after{content:'';position:absolute;bottom:0;width:100%;height:1.5em;background:-webkit-linear-gradient(rgba(255,255,255,.1) 0,#f8f9f9 100%);background:linear-gradient(rgba(255,255,255,.1) 0,#f8f9f9 100%)}.wc-product-display-settings .block-footer{margin:0 -1em;padding-top:1em;border-top:1px solid #e6eaee;text-align:center}.wc-product-display-settings .display-select+.block-footer{padding-top:0;border:0}@media only screen and (min-width:700px){.wc-product-display-settings .product-category-select{width:400px}.wc-product-display-settings .product-category-select div+div{overflow:hidden}.wc-product-display-settings .product-category-select div+div>ul{width:440px}}

View File

@ -92,18 +92,67 @@
text-align: center; text-align: center;
} }
.display-settings-container { .wc-products-display-option {
background-color: #ffffff; background-color: #FFFFFF;
padding: 1.5em;
box-sizing: border-box;
border: 1px solid gray; // @todo remove this when doing real styles.
width: 80%;
margin-left: auto;
margin-right: auto;
h4 {
margin: 0;
font-size: 1.25em;
}
p {
margin: 0;
}
/**
* These settings are only shown when the parent group is expanded.
*/
&.value-featured,
&.value-best_sellers,
&.value-best_rated,
&.value-on_sale,
&.value-attribute {
display: none;
}
}
/**
* Show options when the Filter group is expanded.
*/
&.expanded-group-filter {
.wc-products-display-option {
&.value-featured,
&.value-best_sellers,
&.value-best_rated,
&.value-on_sale,
&.value-attribute {
display: block;
}
}
}
.display-settings-container {
&.existing { &.existing {
right: 0;
position: absolute; position: absolute;
width: 100%; width: 80%;
z-index: 999; z-index: 999;
}
}
.wc-products-display-option { .wc-products-display-option {
border: 1px solid gray; // @todo remove this when doing real styles. margin-right: 0;
}
}
}
.settings-heading {
display: flex;
justify-content: space-between;
} }
.display-select { .display-select {

View File

@ -95,6 +95,63 @@ var RangeControl = InspectorControls.RangeControl,
ToggleControl = InspectorControls.ToggleControl, ToggleControl = InspectorControls.ToggleControl,
SelectControl = InspectorControls.SelectControl; SelectControl = InspectorControls.SelectControl;
/**
* A setting has the following properties:
* title - Display title of the setting.
* description - Display description of the setting.
* value - Display setting slug to set when selected.
* group_container - (optional) If set the setting is a parent container.
*/
var PRODUCTS_BLOCK_DISPLAY_SETTINGS = {
'specific': {
title: __('Individual products'),
description: __('Hand-pick which products to display'),
value: 'specific'
},
'category': {
title: __('Product category'),
description: __('Display products from a specific category or multiple categories'),
value: 'category'
},
'filter': {
title: __('Filter products'),
description: __('E.g. featured products, or products with a specific attribute like size or color'),
value: 'filter',
group_container: 'filter'
},
'featured': {
title: __('Featured products'),
description: '',
value: 'featured'
},
'best_sellers': {
title: __('Best sellers'),
description: '',
value: 'best_sellers'
},
'best_rated': {
title: __('Best rated'),
description: '',
value: 'best_rated'
},
'on_sale': {
title: __('On sale'),
description: '',
value: 'on_sale'
},
'attribute': {
title: __('Attribute'),
description: '',
value: 'attribute'
},
'all': {
title: __('All products'),
description: __('Display all products ordered chronologically'),
value: 'all'
}
};
/** /**
* When the display mode is 'Specific products' search for and add products to the block. * When the display mode is 'Specific products' search for and add products to the block.
* *
@ -119,7 +176,7 @@ var ProductsSpecificSelect = function (_React$Component) {
} }
_createClass(ProductsSpecificSelect, [{ _createClass(ProductsSpecificSelect, [{
key: "selectProduct", key: 'selectProduct',
value: function selectProduct(evt) { value: function selectProduct(evt) {
evt.preventDefault(); evt.preventDefault();
@ -130,30 +187,30 @@ var ProductsSpecificSelect = function (_React$Component) {
}); });
} }
}, { }, {
key: "render", key: 'render',
value: function render() { value: function render() {
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
{ className: "product-specific-select" }, { className: 'product-specific-select' },
wp.element.createElement( wp.element.createElement(
"div", 'div',
{ className: "add-new" }, { className: 'add-new' },
wp.element.createElement(Dropdown, { wp.element.createElement(Dropdown, {
className: "my-container-class-name", className: 'my-container-class-name',
contentClassName: "my-popover-content-classname", contentClassName: 'my-popover-content-classname',
position: "bottom right", position: 'bottom right',
renderToggle: function renderToggle(_ref) { renderToggle: function renderToggle(_ref) {
var isOpen = _ref.isOpen, var isOpen = _ref.isOpen,
onToggle = _ref.onToggle; onToggle = _ref.onToggle;
return wp.element.createElement( return wp.element.createElement(
"button", 'button',
{ className: "button button-large", onClick: onToggle, "aria-expanded": isOpen }, { className: 'button button-large', onClick: onToggle, 'aria-expanded': isOpen },
__('Add product') __('Add product')
); );
}, },
renderContent: function renderContent() { renderContent: function renderContent() {
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
null, null,
wp.element.createElement(ProductSpecifcSearch, null) wp.element.createElement(ProductSpecifcSearch, null)
); );
@ -187,17 +244,17 @@ var ProductSpecifcSearch = withAPIData(function (props) {
var products = _ref3.products; var products = _ref3.products;
return products.length > 0 && wp.element.createElement( return products.length > 0 && wp.element.createElement(
"ul", 'ul',
null, null,
products.map(function (product) { products.map(function (product) {
return wp.element.createElement( return wp.element.createElement(
"li", 'li',
null, null,
wp.element.createElement( wp.element.createElement(
"button", 'button',
{ type: "button", "class": "components-button", id: 'product-' + product.id }, { type: 'button', className: 'components-button', id: 'product-' + product.id },
wp.element.createElement("img", { src: product.images[0].src, width: "30px" }), wp.element.createElement('img', { src: product.images[0].src, width: '30px' }),
" ", ' ',
product.name product.name
) )
); );
@ -208,8 +265,8 @@ var ProductSpecifcSearch = withAPIData(function (props) {
var productsData = products.data; var productsData = products.data;
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
{ role: "menu", "aria-orientation": "vertical", "aria-label": "{ __( 'Products list' ) }" }, { role: 'menu', 'aria-orientation': 'vertical', 'aria-label': '{ __( \'Products list\' ) }' },
wp.element.createElement(ProductsList, { products: productsData }) wp.element.createElement(ProductsList, { products: productsData })
); );
}); });
@ -225,7 +282,7 @@ var ProductsSpecificList = function ProductsSpecificList(_ref4) {
var attributes = {}; var attributes = {};
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
{ className: classes }, { className: classes },
selectedProducts.data.map(function (product) { selectedProducts.data.map(function (product) {
return wp.element.createElement(ProductPreview, { product: product, attributes: attributes }); return wp.element.createElement(ProductPreview, { product: product, attributes: attributes });
@ -266,7 +323,7 @@ var ProductsCategorySelect = function (_React$Component2) {
_createClass(ProductsCategorySelect, [{ _createClass(ProductsCategorySelect, [{
key: "checkboxChange", key: 'checkboxChange',
value: function checkboxChange(evt) { value: function checkboxChange(evt) {
var selectedCategories = this.state.selectedCategories; var selectedCategories = this.state.selectedCategories;
@ -292,7 +349,7 @@ var ProductsCategorySelect = function (_React$Component2) {
*/ */
}, { }, {
key: "filterResults", key: 'filterResults',
value: function filterResults(evt) { value: function filterResults(evt) {
this.setState({ this.setState({
filterQuery: evt.target.value filterQuery: evt.target.value
@ -304,11 +361,11 @@ var ProductsCategorySelect = function (_React$Component2) {
*/ */
}, { }, {
key: "render", key: 'render',
value: function render() { value: function render() {
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
{ className: "product-category-select" }, { className: 'product-category-select' },
wp.element.createElement(ProductCategoryFilter, { filterResults: this.filterResults }), wp.element.createElement(ProductCategoryFilter, { filterResults: this.filterResults }),
wp.element.createElement(ProductCategoryList, { filterQuery: this.state.filterQuery, selectedCategories: this.state.selectedCategories, checkboxChange: this.checkboxChange }) wp.element.createElement(ProductCategoryList, { filterQuery: this.state.filterQuery, selectedCategories: this.state.selectedCategories, checkboxChange: this.checkboxChange })
); );
@ -327,9 +384,9 @@ var ProductCategoryFilter = function ProductCategoryFilter(_ref5) {
var filterResults = _ref5.filterResults; var filterResults = _ref5.filterResults;
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
null, null,
wp.element.createElement("input", { id: "product-category-search", type: "search", placeholder: __('Search for categories'), onChange: filterResults }) wp.element.createElement('input', { id: 'product-category-search', type: 'search', placeholder: __('Search for categories'), onChange: filterResults })
); );
}; };
@ -363,22 +420,22 @@ var ProductCategoryList = withAPIData(function (props) {
}); });
return filteredCategories.length > 0 && wp.element.createElement( return filteredCategories.length > 0 && wp.element.createElement(
"ul", 'ul',
null, null,
filteredCategories.map(function (category) { filteredCategories.map(function (category) {
return wp.element.createElement( return wp.element.createElement(
"li", 'li',
{ key: category.id }, { key: category.id },
wp.element.createElement( wp.element.createElement(
"label", 'label',
{ htmlFor: 'product-category-' + category.id }, { htmlFor: 'product-category-' + category.id },
wp.element.createElement("input", { type: "checkbox", wp.element.createElement('input', { type: 'checkbox',
id: 'product-category-' + category.id, id: 'product-category-' + category.id,
value: category.id, value: category.id,
checked: selectedCategories.includes(category.id), checked: selectedCategories.includes(category.id),
onChange: checkboxChange onChange: checkboxChange
}), }),
" ", ' ',
category.name category.name
), ),
wp.element.createElement(CategoryTree, { categories: categories, parent: category.id }) wp.element.createElement(CategoryTree, { categories: categories, parent: category.id })
@ -396,7 +453,7 @@ var ProductCategoryList = withAPIData(function (props) {
} }
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
null, null,
wp.element.createElement(CategoryTree, { categories: categoriesData, parent: 0 }) wp.element.createElement(CategoryTree, { categories: categoriesData, parent: 0 })
); );
@ -416,22 +473,22 @@ var ProductsBlockSettingsEditorDisplayOption = function (_React$Component3) {
} }
_createClass(ProductsBlockSettingsEditorDisplayOption, [{ _createClass(ProductsBlockSettingsEditorDisplayOption, [{
key: "render", key: 'render',
value: function render() { value: function render() {
var _this4 = this; var _this4 = this;
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
{ className: "wc-products-display-option", onClick: function onClick() { { className: 'wc-products-display-option value-' + this.props.value, onClick: function onClick() {
_this4.props.update_display_callback(_this4.props.value); _this4.props.update_display_callback(_this4.props.value);
} }, } },
wp.element.createElement( wp.element.createElement(
"h4", 'h4',
null, null,
this.props.title this.props.title
), ),
wp.element.createElement( wp.element.createElement(
"p", 'p',
null, null,
this.props.description this.props.description
) )
@ -457,40 +514,32 @@ var ProductsBlockSettingsEditorDisplayOptions = function (_React$Component4) {
} }
_createClass(ProductsBlockSettingsEditorDisplayOptions, [{ _createClass(ProductsBlockSettingsEditorDisplayOptions, [{
key: "render", key: 'render',
value: function render() { value: function render() {
var _this6 = this;
var products_block_display_settings = [{
title: __('All'),
description: __('All products'),
value: 'all'
}, {
title: __('Specific'),
description: __('Hand-picked products'),
value: 'specific'
}, {
title: __('Category'),
description: __('Products from a specific category'),
value: 'category'
}];
var classes = 'display-settings-container'; var classes = 'display-settings-container';
if (this.props.existing) { if (this.props.existing) {
classes += ' existing'; classes += ' existing';
} }
return wp.element.createElement( var display_settings = [];
"div", for (var setting_key in PRODUCTS_BLOCK_DISPLAY_SETTINGS) {
{ className: classes }, display_settings.push(wp.element.createElement(ProductsBlockSettingsEditorDisplayOption, _extends({}, PRODUCTS_BLOCK_DISPLAY_SETTINGS[setting_key], { update_display_callback: this.props.update_display_callback })));
wp.element.createElement( }
"p",
var description = null;
if (!this.props.existing) {
description = wp.element.createElement(
'p',
null, null,
__('Select the scope for products to display:') __('Choose which products you\'d like to display:')
), );
products_block_display_settings.map(function (setting) { }
return wp.element.createElement(ProductsBlockSettingsEditorDisplayOption, _extends({}, setting, { update_display_callback: _this6.props.update_display_callback }));
}) return wp.element.createElement(
'div',
{ className: classes },
description,
display_settings
); );
} }
}]); }]);
@ -512,43 +561,60 @@ var ProductsBlockSettingsEditor = function (_React$Component5) {
function ProductsBlockSettingsEditor(props) { function ProductsBlockSettingsEditor(props) {
_classCallCheck(this, ProductsBlockSettingsEditor); _classCallCheck(this, ProductsBlockSettingsEditor);
var _this7 = _possibleConstructorReturn(this, (ProductsBlockSettingsEditor.__proto__ || Object.getPrototypeOf(ProductsBlockSettingsEditor)).call(this, props)); var _this6 = _possibleConstructorReturn(this, (ProductsBlockSettingsEditor.__proto__ || Object.getPrototypeOf(ProductsBlockSettingsEditor)).call(this, props));
_this7.state = { _this6.state = {
display: props.selected_display, display: props.selected_display,
menu_visible: props.selected_display ? false : true menu_visible: props.selected_display ? false : true,
expanded_group: ''
}; };
_this7.updateDisplay = _this7.updateDisplay.bind(_this7); _this6.updateDisplay = _this6.updateDisplay.bind(_this6);
return _this7; return _this6;
} }
/** /**
* Update the display settings for the block. * Update the display settings for the block.
* *
* @param Event object evt * @param value String
*/ */
_createClass(ProductsBlockSettingsEditor, [{ _createClass(ProductsBlockSettingsEditor, [{
key: "updateDisplay", key: 'updateDisplay',
value: function updateDisplay(value) { value: function updateDisplay(value) {
this.setState({
display: value,
menu_visible: false
});
// If not a group update display.
var new_state = {
display: value,
menu_visible: false,
expanded_group: ''
};
// If a settings group expand the group but keep display settings the same.
if ('undefined' !== PRODUCTS_BLOCK_DISPLAY_SETTINGS[value].group_container && PRODUCTS_BLOCK_DISPLAY_SETTINGS[value].group_container) {
new_state = {
menu_visible: true,
expanded_group: value
};
}
this.setState(new_state);
// Only update the display setting if a non-group setting was selected.
if ('undefined' === PRODUCTS_BLOCK_DISPLAY_SETTINGS[value].group_container || !PRODUCTS_BLOCK_DISPLAY_SETTINGS[value].group_container) {
this.props.update_display_callback(value); this.props.update_display_callback(value);
} }
}
/** /**
* Render the display settings dropdown and any extra contextual settings. * Render the display settings dropdown and any extra contextual settings.
*/ */
}, { }, {
key: "render", key: 'render',
value: function render() { value: function render() {
var _this8 = this; var _this7 = this;
var extra_settings = null; var extra_settings = null;
if ('specific' === this.state.display) { if ('specific' === this.state.display) {
@ -559,53 +625,63 @@ var ProductsBlockSettingsEditor = function (_React$Component5) {
var menu = this.state.menu_visible ? wp.element.createElement(ProductsBlockSettingsEditorDisplayOptions, { existing: this.state.display ? true : false, update_display_callback: this.updateDisplay }) : null; var menu = this.state.menu_visible ? wp.element.createElement(ProductsBlockSettingsEditorDisplayOptions, { existing: this.state.display ? true : false, update_display_callback: this.updateDisplay }) : null;
var heading = wp.element.createElement( var heading = null;
"h4", if (this.state.display) {
null, var menu_link = wp.element.createElement(
__('Products') 'a',
);
if (this.state.display && !this.state.menu_visible) {
heading = wp.element.createElement(
"h4",
null,
__('Displaying ' + this.state.display),
" ",
wp.element.createElement(
"a",
{ onClick: function onClick() { { onClick: function onClick() {
_this8.setState({ menu_visible: true }); _this7.setState({ menu_visible: true });
} }, } },
__('Change') __('Display different products')
)
); );
} else if (this.state.display) { if (this.state.menu_visible) {
heading = wp.element.createElement( menu_link = wp.element.createElement(
"h4", 'a',
null,
__('Displaying ' + this.state.display),
" ",
wp.element.createElement(
"a",
{ onClick: function onClick() { { onClick: function onClick() {
_this8.setState({ menu_visible: false }); _this7.setState({ menu_visible: false });
} }, } },
__('Cancel') __('Cancel')
);
}
heading = wp.element.createElement(
'div',
{ className: 'settings-heading' },
wp.element.createElement(
'div',
{ className: 'currently-displayed' },
__('Displaying '),
wp.element.createElement(
'strong',
null,
__(PRODUCTS_BLOCK_DISPLAY_SETTINGS[this.state.display].title)
)
),
wp.element.createElement(
'div',
{ className: 'change-display' },
menu_link
) )
); );
} }
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
{ className: "wc-product-display-settings" }, { className: 'wc-product-display-settings ' + (this.state.expanded_group ? 'expanded-group-' + this.state.expanded_group : '') },
wp.element.createElement(
'h4',
null,
__('Products')
),
heading, heading,
menu, menu,
extra_settings, extra_settings,
wp.element.createElement( wp.element.createElement(
"div", 'div',
{ className: "block-footer" }, { className: 'block-footer' },
wp.element.createElement( wp.element.createElement(
"button", 'button',
{ type: "button", className: "button button-large", onClick: this.props.done_callback }, { type: 'button', className: 'button button-large', onClick: this.props.done_callback },
__('Done') __('Done')
) )
) )
@ -631,7 +707,7 @@ var ProductPreview = function (_React$Component6) {
} }
_createClass(ProductPreview, [{ _createClass(ProductPreview, [{
key: "render", key: 'render',
value: function render() { value: function render() {
var _props = this.props, var _props = this.props,
attributes = _props.attributes, attributes = _props.attributes,
@ -640,14 +716,14 @@ var ProductPreview = function (_React$Component6) {
var image = null; var image = null;
if (product.images.length) { if (product.images.length) {
image = wp.element.createElement("img", { src: product.images[0].src }); image = wp.element.createElement('img', { src: product.images[0].src });
} }
var title = null; var title = null;
if (attributes.display_title) { if (attributes.display_title) {
title = wp.element.createElement( title = wp.element.createElement(
"div", 'div',
{ className: "product-title" }, { className: 'product-title' },
product.name product.name
); );
} }
@ -655,8 +731,8 @@ var ProductPreview = function (_React$Component6) {
var price = null; var price = null;
if (attributes.display_price) { if (attributes.display_price) {
price = wp.element.createElement( price = wp.element.createElement(
"div", 'div',
{ className: "product-price" }, { className: 'product-price' },
product.price product.price
); );
} }
@ -664,15 +740,15 @@ var ProductPreview = function (_React$Component6) {
var add_to_cart = null; var add_to_cart = null;
if (attributes.display_add_to_cart) { if (attributes.display_add_to_cart) {
add_to_cart = wp.element.createElement( add_to_cart = wp.element.createElement(
"span", 'span',
{ className: "product-add-to-cart" }, { className: 'product-add-to-cart' },
__('Add to cart') __('Add to cart')
); );
} }
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
{ className: "product-preview" }, { className: 'product-preview' },
image, image,
title, title,
price, price,
@ -757,7 +833,7 @@ var ProductsBlockPreview = withAPIData(function (_ref8) {
var classes = "wc-products-block-preview " + attributes.layout + " cols-" + attributes.columns; var classes = "wc-products-block-preview " + attributes.layout + " cols-" + attributes.columns;
return wp.element.createElement( return wp.element.createElement(
"div", 'div',
{ className: classes }, { className: classes },
products.data.map(function (product) { products.data.map(function (product) {
return wp.element.createElement(ProductPreview, { key: product.id, product: product, attributes: attributes }); return wp.element.createElement(ProductPreview, { key: product.id, product: product, attributes: attributes });
@ -885,9 +961,9 @@ registerBlockType('woocommerce/products', {
function getInspectorControls() { function getInspectorControls() {
return wp.element.createElement( return wp.element.createElement(
InspectorControls, InspectorControls,
{ key: "inspector" }, { key: 'inspector' },
wp.element.createElement( wp.element.createElement(
"h3", 'h3',
null, null,
__('Layout') __('Layout')
), ),
@ -931,7 +1007,7 @@ registerBlockType('woocommerce/products', {
} }
}), }),
wp.element.createElement(SelectControl, { wp.element.createElement(SelectControl, {
key: "query-panel-select", key: 'query-panel-select',
label: __('Order'), label: __('Order'),
value: order, value: order,
options: [{ options: [{
@ -981,7 +1057,7 @@ registerBlockType('woocommerce/products', {
return wp.element.createElement( return wp.element.createElement(
BlockControls, BlockControls,
{ key: "controls" }, { key: 'controls' },
wp.element.createElement(Toolbar, { controls: layoutControls }), wp.element.createElement(Toolbar, { controls: layoutControls }),
wp.element.createElement(Toolbar, { controls: editButton }) wp.element.createElement(Toolbar, { controls: editButton })
); );

View File

@ -3,6 +3,63 @@ const { registerBlockType, InspectorControls, BlockControls } = wp.blocks;
const { Toolbar, withAPIData, Dropdown } = wp.components; const { Toolbar, withAPIData, Dropdown } = wp.components;
const { RangeControl, ToggleControl, SelectControl } = InspectorControls; const { RangeControl, ToggleControl, SelectControl } = InspectorControls;
/**
* A setting has the following properties:
* title - Display title of the setting.
* description - Display description of the setting.
* value - Display setting slug to set when selected.
* group_container - (optional) If set the setting is a parent container.
*/
const PRODUCTS_BLOCK_DISPLAY_SETTINGS = {
'specific' : {
title: __( 'Individual products' ),
description: __( 'Hand-pick which products to display' ),
value: 'specific',
},
'category' : {
title: __( 'Product category' ),
description: __( 'Display products from a specific category or multiple categories' ),
value: 'category',
},
'filter' : {
title: __( 'Filter products' ),
description: __( 'E.g. featured products, or products with a specific attribute like size or color' ),
value: 'filter',
group_container: 'filter'
},
'featured' : {
title: __( 'Featured products' ),
description: '',
value: 'featured',
},
'best_sellers' : {
title: __( 'Best sellers' ),
description: '',
value: 'best_sellers',
},
'best_rated' : {
title: __( 'Best rated' ),
description: '',
value: 'best_rated',
},
'on_sale' : {
title: __( 'On sale' ),
description: '',
value: 'on_sale',
},
'attribute' : {
title: __( 'Attribute' ),
description: '',
value: 'attribute',
},
'all' : {
title: __( 'All products' ),
description: __( 'Display all products ordered chronologically' ),
value: 'all',
}
};
/** /**
* When the display mode is 'Specific products' search for and add products to the block. * When the display mode is 'Specific products' search for and add products to the block.
* *
@ -75,7 +132,7 @@ const ProductSpecifcSearch = withAPIData( ( props ) => {
<ul> <ul>
{ products.map( ( product ) => ( { products.map( ( product ) => (
<li> <li>
<button type="button" class="components-button" id={ 'product-' + product.id }> <button type="button" className="components-button" id={ 'product-' + product.id }>
<img src={ product.images[0].src } width="30px" /> { product.name } <img src={ product.images[0].src } width="30px" /> { product.name }
</button> </button>
</li> </li>
@ -245,7 +302,7 @@ const ProductCategoryList = withAPIData( ( props ) => {
class ProductsBlockSettingsEditorDisplayOption extends React.Component { class ProductsBlockSettingsEditorDisplayOption extends React.Component {
render() { render() {
return ( return (
<div className="wc-products-display-option" onClick={ () => { this.props.update_display_callback( this.props.value ) } } > <div className={ 'wc-products-display-option value-' + this.props.value } onClick={ () => { this.props.update_display_callback( this.props.value ) } } >
<h4>{ this.props.title }</h4> <h4>{ this.props.title }</h4>
<p>{ this.props.description }</p> <p>{ this.props.description }</p>
</div> </div>
@ -257,36 +314,27 @@ class ProductsBlockSettingsEditorDisplayOption extends React.Component {
* A list of all available ways to display products. * A list of all available ways to display products.
*/ */
class ProductsBlockSettingsEditorDisplayOptions extends React.Component { class ProductsBlockSettingsEditorDisplayOptions extends React.Component {
render() {
const products_block_display_settings = [
{
title: __( 'All' ),
description: __( 'All products' ),
value: 'all',
},
{
title: __( 'Specific' ),
description: __( 'Hand-picked products' ),
value: 'specific',
},
{
title: __( 'Category' ),
description: __( 'Products from a specific category' ),
value: 'category',
}
];
render() {
let classes = 'display-settings-container'; let classes = 'display-settings-container';
if ( this.props.existing ) { if ( this.props.existing ) {
classes += ' existing'; classes += ' existing';
} }
let display_settings = [];
for ( var setting_key in PRODUCTS_BLOCK_DISPLAY_SETTINGS ) {
display_settings.push( <ProductsBlockSettingsEditorDisplayOption { ...PRODUCTS_BLOCK_DISPLAY_SETTINGS[ setting_key ] } update_display_callback={ this.props.update_display_callback } /> );
}
let description = null;
if ( ! this.props.existing ) {
description = <p>{ __( 'Choose which products you\'d like to display:' ) }</p>;
}
return ( return (
<div className={ classes }> <div className={ classes }>
<p>{ __( 'Select the scope for products to display:' ) }</p> { description }
{ products_block_display_settings.map( ( setting ) => { display_settings }
<ProductsBlockSettingsEditorDisplayOption { ...setting } update_display_callback={ this.props.update_display_callback } />
) }
</div> </div>
); );
} }
@ -305,6 +353,7 @@ class ProductsBlockSettingsEditor extends React.Component {
this.state = { this.state = {
display: props.selected_display, display: props.selected_display,
menu_visible: props.selected_display ? false : true, menu_visible: props.selected_display ? false : true,
expanded_group: '',
} }
this.updateDisplay = this.updateDisplay.bind( this ); this.updateDisplay = this.updateDisplay.bind( this );
@ -313,16 +362,32 @@ class ProductsBlockSettingsEditor extends React.Component {
/** /**
* Update the display settings for the block. * Update the display settings for the block.
* *
* @param Event object evt * @param value String
*/ */
updateDisplay( value ) { updateDisplay( value ) {
this.setState( {
// If not a group update display.
let new_state = {
display: value, display: value,
menu_visible: false, menu_visible: false,
} ); expanded_group: '',
};
// If a settings group expand the group but keep display settings the same.
if ( 'undefined' !== PRODUCTS_BLOCK_DISPLAY_SETTINGS[ value ].group_container && PRODUCTS_BLOCK_DISPLAY_SETTINGS[ value ].group_container ) {
new_state = {
menu_visible: true,
expanded_group: value,
}
}
this.setState( new_state );
// Only update the display setting if a non-group setting was selected.
if ( 'undefined' === PRODUCTS_BLOCK_DISPLAY_SETTINGS[ value ].group_container || ! PRODUCTS_BLOCK_DISPLAY_SETTINGS[ value ].group_container ) {
this.props.update_display_callback( value ); this.props.update_display_callback( value );
} }
}
/** /**
* Render the display settings dropdown and any extra contextual settings. * Render the display settings dropdown and any extra contextual settings.
@ -337,15 +402,29 @@ class ProductsBlockSettingsEditor extends React.Component {
const menu = this.state.menu_visible ? <ProductsBlockSettingsEditorDisplayOptions existing={ this.state.display ? true : false } update_display_callback={ this.updateDisplay } /> : null; const menu = this.state.menu_visible ? <ProductsBlockSettingsEditorDisplayOptions existing={ this.state.display ? true : false } update_display_callback={ this.updateDisplay } /> : null;
let heading = <h4>{ __( 'Products' ) }</h4>; let heading = null;
if ( this.state.display && ! this.state.menu_visible ) { if ( this.state.display ) {
heading = <h4>{ __( 'Displaying ' + this.state.display ) } <a onClick={ () => { this.setState( { menu_visible: true } ) } }>{ __( 'Change' ) }</a></h4>; var menu_link = <a onClick={ () => { this.setState( { menu_visible: true } ) } }>{ __( 'Display different products' ) }</a>;
} else if ( this.state.display ) { if ( this.state.menu_visible ) {
heading = <h4>{ __( 'Displaying ' + this.state.display ) } <a onClick={ () => { this.setState( { menu_visible: false } ) } }>{ __( 'Cancel' ) }</a></h4>; menu_link = <a onClick={ () => { this.setState( { menu_visible: false } ) } }>{ __( 'Cancel' ) }</a>;
}
heading = (
<div className="settings-heading">
<div className="currently-displayed">
{ __( 'Displaying ' ) }
<strong>{ __( PRODUCTS_BLOCK_DISPLAY_SETTINGS[ this.state.display ].title ) }</strong>
</div>
<div className="change-display">
{ menu_link }
</div>
</div>
);
} }
return ( return (
<div className="wc-product-display-settings"> <div className={ 'wc-product-display-settings ' + ( this.state.expanded_group ? 'expanded-group-' + this.state.expanded_group : '' ) }>
<h4>{ __( 'Products' ) }</h4>
{ heading } { heading }

View File

@ -10,6 +10,9 @@
defined( 'ABSPATH' ) || die(); defined( 'ABSPATH' ) || die();
/**
* Load up the assets if Gutenberg is active.
*/
function wgpb_initialize() { function wgpb_initialize() {
if ( function_exists( 'register_block_type' ) ) { if ( function_exists( 'register_block_type' ) ) {