From 0fa4dd05a56ed18f765c575f8f84c7c8dfd3777d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 6 Dec 2019 16:36:55 +0100 Subject: [PATCH] Add 'Go' button to Attribute Filter (https://github.com/woocommerce/woocommerce-blocks/pull/1332) * Add 'Go' button to Attribute Filter * Code cleanup * Fixes * Avoid onSubmit being called in the editor * Update attributes help texts * Fix wrong input check box width --- .../assets/js/base/components/label/index.js | 8 +- .../js/base/components/price-slider/index.js | 3 +- .../base/components/price-slider/style.scss | 5 - .../index.js} | 12 +- .../base/components/submit-button/style.scss | 5 + .../js/blocks/attribute-filter/block.js | 203 ++++++++++-------- .../assets/js/blocks/attribute-filter/edit.js | 24 +++ .../js/blocks/attribute-filter/frontend.js | 1 + .../js/blocks/attribute-filter/index.js | 8 + .../js/blocks/attribute-filter/label.js | 38 ++++ .../js/blocks/attribute-filter/preview.js | 29 +++ .../js/blocks/attribute-filter/style.scss | 5 + .../assets/js/blocks/price-filter/edit.js | 4 +- 13 files changed, 237 insertions(+), 108 deletions(-) rename plugins/woocommerce-blocks/assets/js/base/components/{price-slider/submit-button.js => submit-button/index.js} (64%) create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/submit-button/style.scss create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/attribute-filter/label.js create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/attribute-filter/preview.js diff --git a/plugins/woocommerce-blocks/assets/js/base/components/label/index.js b/plugins/woocommerce-blocks/assets/js/base/components/label/index.js index cdee9b1786e..a81b1d92551 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/label/index.js +++ b/plugins/woocommerce-blocks/assets/js/base/components/label/index.js @@ -18,7 +18,11 @@ const Label = ( { } ) => { let Wrapper; - if ( ! label && screenReaderLabel ) { + const hasLabel = typeof label !== 'undefined' && label !== null; + const hasScreenReaderLabel = + typeof screenReaderLabel !== 'undefined' && screenReaderLabel !== null; + + if ( ! hasLabel && hasScreenReaderLabel ) { Wrapper = wrapperElement || 'span'; wrapperProps = { ...wrapperProps, @@ -33,7 +37,7 @@ const Label = ( { Wrapper = wrapperElement || Fragment; - if ( label && screenReaderLabel && label !== screenReaderLabel ) { + if ( hasLabel && hasScreenReaderLabel && label !== screenReaderLabel ) { return ( diff --git a/plugins/woocommerce-blocks/assets/js/base/components/price-slider/index.js b/plugins/woocommerce-blocks/assets/js/base/components/price-slider/index.js index f2381905b54..ff595992ff7 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/price-slider/index.js +++ b/plugins/woocommerce-blocks/assets/js/base/components/price-slider/index.js @@ -19,7 +19,7 @@ import classnames from 'classnames'; import './style.scss'; import { constrainRangeSliderValues } from './utils'; import { formatPrice } from '../../utils/price'; -import SubmitButton from './submit-button'; +import SubmitButton from '../submit-button'; import PriceLabel from './price-label'; import PriceInput from './price-input'; @@ -307,6 +307,7 @@ const PriceSlider = ( { ) } { showFilterButton && ( diff --git a/plugins/woocommerce-blocks/assets/js/base/components/price-slider/style.scss b/plugins/woocommerce-blocks/assets/js/base/components/price-slider/style.scss index a2299d3afe9..c2f7ef20f26 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/price-slider/style.scss +++ b/plugins/woocommerce-blocks/assets/js/base/components/price-slider/style.scss @@ -96,11 +96,6 @@ margin-left: 0; margin-right: 10px; } - - .wc-block-price-filter__button { - margin-left: auto; - white-space: nowrap; - } } } .wc-block-price-filter__range-input { diff --git a/plugins/woocommerce-blocks/assets/js/base/components/price-slider/submit-button.js b/plugins/woocommerce-blocks/assets/js/base/components/submit-button/index.js similarity index 64% rename from plugins/woocommerce-blocks/assets/js/base/components/price-slider/submit-button.js rename to plugins/woocommerce-blocks/assets/js/base/components/submit-button/index.js index 66e996b03bc..9ff35814455 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/price-slider/submit-button.js +++ b/plugins/woocommerce-blocks/assets/js/base/components/submit-button/index.js @@ -3,16 +3,22 @@ */ import { __ } from '@wordpress/i18n'; import PropTypes from 'prop-types'; +import classNames from 'classnames'; -const SubmitButton = ( { disabled, onClick } ) => { +/** + * Internal dependencies + */ +import './style.scss'; + +const SubmitButton = ( { className, disabled, onClick } ) => { return ( ); diff --git a/plugins/woocommerce-blocks/assets/js/base/components/submit-button/style.scss b/plugins/woocommerce-blocks/assets/js/base/components/submit-button/style.scss new file mode 100644 index 00000000000..6961d478146 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/submit-button/style.scss @@ -0,0 +1,5 @@ +.wc-block-submit-button { + display: block; + margin-left: auto; + white-space: nowrap; +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/attribute-filter/block.js b/plugins/woocommerce-blocks/assets/js/blocks/attribute-filter/block.js index 584a0d0bf9f..49aad9d7d74 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/attribute-filter/block.js +++ b/plugins/woocommerce-blocks/assets/js/blocks/attribute-filter/block.js @@ -1,13 +1,14 @@ /** * External dependencies */ -import { __, _n, sprintf } from '@wordpress/i18n'; +import { __, sprintf } from '@wordpress/i18n'; import { speak } from '@wordpress/a11y'; import { useCollection, useQueryStateByKey, useQueryStateByContext, useCollectionData, + useShallowEqual, } from '@woocommerce/base-hooks'; import { useCallback, @@ -18,14 +19,17 @@ import { } from '@wordpress/element'; import CheckboxList from '@woocommerce/base-components/checkbox-list'; import DropdownSelector from '@woocommerce/base-components/dropdown-selector'; -import Label from '@woocommerce/base-components/label'; +import SubmitButton from '@woocommerce/base-components/submit-button'; +import isShallowEqual from '@wordpress/is-shallow-equal'; /** * Internal dependencies */ -import './style.scss'; import { getAttributeFromID } from '../../utils/attributes'; import { updateAttributeFilter } from '../../utils/attributes-query'; +import Label from './label'; +import { previewAttributeObject, previewOptions } from './preview'; +import './style.scss'; /** * Component displaying an attribute filter. @@ -34,68 +38,15 @@ const AttributeFilterBlock = ( { attributes: blockAttributes, isEditor = false, } ) => { - /** - * Get the label for an attribute term filter. - */ - const getLabel = useCallback( - ( name, count ) => { - return ( - - { name } - { blockAttributes.showCounts && count !== null && ( - - ); - }, - [ blockAttributes ] - ); - const attributeObject = blockAttributes.isPreview && ! blockAttributes.attributeId - ? { - id: 0, - name: 'preview', - taxonomy: 'preview', - label: 'Preview', - } + ? previewAttributeObject : getAttributeFromID( blockAttributes.attributeId ); + + const [ checked, setChecked ] = useState( [] ); const [ displayedOptions, setDisplayedOptions ] = useState( blockAttributes.isPreview && ! blockAttributes.attributeId - ? [ - { - value: 'preview-1', - name: 'Blue', - label: getLabel( 'Blue', 3 ), - }, - { - value: 'preview-2', - name: 'Green', - label: getLabel( 'Green', 3 ), - }, - { - value: 'preview-3', - name: 'Red', - label: getLabel( 'Red', 2 ), - }, - ] + ? previewOptions : [] ); @@ -105,15 +56,6 @@ const AttributeFilterBlock = ( { setProductAttributesQuery, ] = useQueryStateByKey( 'attributes', [] ); - const checked = useMemo( () => { - return productAttributesQuery - .filter( - ( attribute ) => - attribute.attribute === attributeObject.taxonomy - ) - .flatMap( ( attribute ) => attribute.slug ); - }, [ productAttributesQuery, attributeObject ] ); - const { results: attributeTerms, isLoading: attributeTermsLoading, @@ -157,39 +99,89 @@ const AttributeFilterBlock = ( { * Compare intersection of all terms and filtered counts to get a list of options to display. */ useEffect( () => { + /** + * Checks if a term slug is in the query state. + */ + const isTermInQueryState = ( termSlug ) => { + if ( ! queryState || ! queryState.attributes ) { + return false; + } + return queryState.attributes.some( + ( { attribute, slug = [] } ) => + attribute === attributeObject.taxonomy && + slug.includes( termSlug ) + ); + }; + if ( attributeTermsLoading || filteredCountsLoading ) { return; } - const newOptions = []; + const newOptions = attributeTerms + .map( ( term ) => { + const filteredTerm = getFilteredTerm( term.id ); - attributeTerms.forEach( ( term ) => { - const filteredTerm = getFilteredTerm( term.id ); - const isChecked = checked.includes( term.slug ); - const count = filteredTerm ? filteredTerm.count : null; + // If there is no match this term doesn't match the current product collection - only render if checked. + if ( + ! filteredTerm && + ! checked.includes( term.slug ) && + ! isTermInQueryState( term.slug ) + ) { + return null; + } - // If there is no match this term doesn't match the current product collection - only render if checked. - if ( ! filteredTerm && ! isChecked ) { - return; - } + const count = filteredTerm ? filteredTerm.count : 0; - newOptions.push( { - value: term.slug, - name: term.name, - label: getLabel( term.name, count ), - } ); - } ); + return { + value: term.slug, + name: term.name, + label: ( +