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:
parent
a4205a956e
commit
c98e607a6f
|
@ -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 */
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>;
|
||||
},
|
||||
} );
|
||||
|
|
|
@ -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"; ',
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue