Add the "edit mode" toggle to the product category block (https://github.com/woocommerce/woocommerce-blocks/pull/144)

* Add sass mixins and variables

* Add an edit mode toggle, with the ability to choose categories

* Only add align classes when align is defined
This commit is contained in:
Kelly Dwan 2018-11-21 11:33:21 -05:00 committed by GitHub
parent a4205a956e
commit c98e607a6f
6 changed files with 243 additions and 23 deletions

View File

@ -0,0 +1,59 @@
/* stylelint-disable block-closing-brace-newline-after */
// Breakpoints
// Forked from https://github.com/Automattic/wp-calypso/blob/46ae24d8800fb85da6acf057a640e60dac988a38/assets/stylesheets/shared/mixins/_breakpoints.scss
// Think very carefully before adding a new breakpoint.
// The list below is based on wp-admin's main breakpoints
$breakpoints: 320px, 400px, 600px, 782px, 960px, 1280px, 1440px;
@mixin breakpoint( $sizes... ) {
@each $size in $sizes {
@if type-of( $size ) == string {
$approved-value: 0;
@each $breakpoint in $breakpoints {
$and-larger: '>' + $breakpoint;
$and-smaller: '<' + $breakpoint;
@if $size == $and-smaller {
$approved-value: 1;
@media (max-width: $breakpoint) {
@content;
}
} @else {
@if $size == $and-larger {
$approved-value: 2;
@media (min-width: $breakpoint + 1) {
@content;
}
} @else {
@each $breakpoint-end in $breakpoints {
$range: $breakpoint + '-' + $breakpoint-end;
@if $size == $range {
$approved-value: 3;
@media (min-width: $breakpoint + 1) and (max-width: $breakpoint-end) {
@content;
}
}
}
}
}
}
@if $approved-value == 0 {
$sizes: '';
@each $breakpoint in $breakpoints {
$sizes: $sizes + ' ' + $breakpoint;
}
@warn 'ERROR in breakpoint( #{ $size } ) : You can only use these sizes[ #{$sizes} ] using the following syntax [ <#{ nth( $breakpoints, 1 ) } >#{ nth( $breakpoints, 1 ) } #{ nth( $breakpoints, 1 ) }-#{ nth( $breakpoints, 2 ) } ]';
}
} @else {
$sizes: '';
@each $breakpoint in $breakpoints {
$sizes: $sizes + ' ' + $breakpoint;
}
@error 'ERROR in breakpoint( #{ $size } ) : Please wrap the breakpoint $size in parenthesis. You can use these sizes[ #{$sizes} ] using the following syntax [ <#{ nth( $breakpoints, 1 ) } >#{ nth( $breakpoints, 1 ) } #{ nth( $breakpoints, 1 ) }-#{ nth( $breakpoints, 2 ) } ]';
}
}
}
/* stylelint-enable */

View File

@ -0,0 +1,45 @@
// Greys
$core-grey-light-100: #f8f9f9;
$core-grey-light-200: #f3f4f5;
$core-grey-light-300: #edeff0;
$core-grey-light-400: #e8eaeb;
$core-grey-light-500: #e2e4e7;
$core-grey-light-600: #d7dade;
$core-grey-light-700: #ccd0d4;
$core-grey-light-800: #b5bcc2;
$core-grey-light-900: #a2aab2;
$core-grey-dark-100: #86909b;
$core-grey-dark-200: #78848f;
$core-grey-dark-300: #6c7781; // This & below have 4.5+ contrast against white
$core-grey-dark-400: #606a73;
$core-grey-dark-500: #555d66;
$core-grey-dark-600: #40464d;
$core-grey-dark-700: #32373c;
$core-grey-dark-800: #23282d;
$core-grey-dark-900: #191e23;
$gray-text: $core-grey-dark-500;
// WooCommerce Purples
$woocommerce-100: #ffd7ff;
$woocommerce-200: #e2a5d7;
$woocommerce-300: #c88bbd;
$woocommerce-400: #af72a4;
$woocommerce-500: #95588a;
$woocommerce-600: #7c3f71;
$woocommerce-700: #622557;
$woocommerce-800: #490c3e;
$woocommerce-900: #2f0024;
$woocommerce: $woocommerce-500;
$wp-admin-background: #f1f1f1;
$black: #24292d; // same as wp-admin sidebar
$white: #fff;
// Bright colors
$valid-green: #4ab866;
$notice-yellow: #ffb900;
$error-red: #d94f4f;
$box-shadow-blue: #5b9dd9;
$core-orange: #ca4a1f;

View File

@ -0,0 +1,36 @@
// Rem output with px fallback
@mixin font-size($sizeValue: 16, $lineHeight: false ) {
font-size: $sizeValue + px;
font-size: ($sizeValue / 16) + rem;
@if ($lineHeight) {
line-height: $lineHeight;
}
}
@mixin hover-state {
&:hover,
&:active,
&:focus {
@content;
}
}
// Adds animation to placeholder section
@mixin placeholder( $lighten-percentage: 30% ) {
animation: loading-fade 1.6s ease-in-out infinite;
background-color: $core-grey-light-500;
color: transparent;
&::after {
content: '\00a0';
}
}
// Adds animation to transforms
@mixin animate-transform( $duration: 0.2s ) {
transition: transform ease $duration;
@media screen and (prefers-reduced-motion: reduce) {
transition: none;
}
}

View File

@ -5,3 +5,14 @@
.wc-block-products-category {
overflow: hidden;
}
.wc-block-products-category__selection {
margin-top: 16px;
padding: 16px;
width: 100%;
border-top: 1px solid $core-grey-light-500;
.components-spinner {
float: none;
}
}

View File

@ -11,11 +11,13 @@ import {
InspectorControls,
} from '@wordpress/editor';
import {
Button,
PanelBody,
Placeholder,
RangeControl,
SelectControl,
Spinner,
Toolbar,
TreeSelect,
} from '@wordpress/components';
import PropTypes from 'prop-types';
@ -161,9 +163,50 @@ class ProductByCategoryBlock extends Component {
);
}
renderEditMode() {
const { setAttributes } = this.props;
const { categories } = this.props.attributes;
const { categoriesList } = this.state;
return (
<Placeholder
icon="category"
label={ __( 'Products by Category', 'woocommerce' ) }
>
{ __(
'Display a grid of products from your selected categories',
'woocommerce'
) }
{ categoriesList.length ? (
<div className="wc-block-products-category__selection">
<TreeSelect
label={ __( 'Product Category', 'woocommerce' ) }
tree={ categoriesList }
selectedId={ categories }
multiple
onChange={ ( value ) => {
setAttributes( { categories: value ? value : [] } );
} }
/>
<Button
isDefault
onClick={ () => setAttributes( { editMode: false } ) }
>
{ __( 'Done', 'woocommerce' ) }
</Button>
</div>
) : (
<div className="wc-block-products-category__selection">
<Spinner />
</div>
) }
</Placeholder>
);
}
render() {
const { setAttributes } = this.props;
const { columns, align } = this.props.attributes;
const { columns, align, editMode } = this.props.attributes;
const { loaded, products } = this.state;
return (
@ -174,26 +217,40 @@ class ProductByCategoryBlock extends Component {
value={ align }
onChange={ ( nextAlign ) => setAttributes( { align: nextAlign } ) }
/>
<Toolbar
controls={ [
{
icon: 'edit',
title: __( 'Edit' ),
onClick: () => setAttributes( { editMode: ! editMode } ),
isActive: editMode,
},
] }
/>
</BlockControls>
{ this.getInspectorControls() }
<div className={ `wc-block-products-category cols-${ columns }` }>
{ products.length ? (
products.map( ( product ) => (
<ProductPreview product={ product } key={ product.id } />
) )
) : (
<Placeholder
icon="category"
label={ __( 'Products by Category', 'woocommerce' ) }
>
{ ! loaded ? (
<Spinner />
) : (
__( 'No products in this category.', 'woocommerce' )
) }
</Placeholder>
) }
</div>
{ editMode ? (
this.renderEditMode()
) : (
<div className={ `wc-block-products-category cols-${ columns }` }>
{ products.length ? (
products.map( ( product ) => (
<ProductPreview product={ product } key={ product.id } />
) )
) : (
<Placeholder
icon="category"
label={ __( 'Products by Category', 'woocommerce' ) }
>
{ ! loaded ? (
<Spinner />
) : (
__( 'No products in this category.', 'woocommerce' )
) }
</Placeholder>
) }
</div>
) }
</Fragment>
);
}
@ -219,10 +276,13 @@ registerBlockType( 'woocommerce/product-category', {
title: __( 'Products by Category', 'woocommerce' ),
icon: 'category',
category: 'widgets',
description: __( 'Display a grid of products from your selected categories.', 'woocommerce' ),
description: __(
'Display a grid of products from your selected categories.',
'woocommerce'
),
attributes: {
...sharedAttributes,
edit_mode: {
editMode: {
type: 'boolean',
default: true,
},
@ -255,6 +315,6 @@ registerBlockType( 'woocommerce/product-category', {
const {
align,
} = props.attributes; /* eslint-disable-line react/prop-types */
return <RawHTML className={ `align${ align }` }>{ getShortcode( props ) }</RawHTML>;
return <RawHTML className={ align ? `align${ align }` : '' }>{ getShortcode( props ) }</RawHTML>;
},
} );

View File

@ -49,7 +49,16 @@ const GutenbergBlocksConfig = {
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
{
loader: 'sass-loader',
query: {
includePaths: [ 'assets/css/abstracts' ],
data:
'@import "_colors"; ' +
'@import "_breakpoints"; ' +
'@import "_mixins"; ',
},
}
],
},
],