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

Release: 8.3.1 #6910

Merged
merged 14 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ const Packages = ( {
packageData={ packageData }
collapsible={ !! collapsible }
collapse={ !! collapse }
showItems={
showItems || packageData?.shipping_rates?.length > 1
}
showItems={ showItems || packages.length > 1 }
noResultsMessage={ noResultsMessage }
renderOption={ renderOption }
/>
Expand Down
40 changes: 40 additions & 0 deletions assets/js/base/components/filter-reset-button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import classNames from 'classnames';
import Label from '@woocommerce/base-components/label';

/**
* Internal dependencies
*/
import './style.scss';

interface FilterResetButtonProps {
className?: string;
label?: string;
onClick: () => void;
screenReaderLabel?: string;
}

const FilterResetButton = ( {
className,
/* translators: Reset button text for filters. */
label = __( 'Reset', 'woo-gutenberg-products-block' ),
onClick,
screenReaderLabel = __( 'Reset filter', 'woo-gutenberg-products-block' ),
}: FilterResetButtonProps ): JSX.Element => {
return (
<button
className={ classNames(
'wc-block-components-filter-reset-button',
className
) }
onClick={ onClick }
>
<Label label={ label } screenReaderLabel={ screenReaderLabel } />
</button>
);
};

export default FilterResetButton;
14 changes: 14 additions & 0 deletions assets/js/base/components/filter-reset-button/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.wc-block-components-filter-reset-button {
background: transparent;
border: none;
cursor: pointer;
font-size: inherit;

&:not([disabled]):hover {
text-decoration: underline;
}

&[disabled] {
cursor: not-allowed;
}
}
3 changes: 2 additions & 1 deletion assets/js/base/components/filter-submit-button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ const FilterSubmitButton = ( {
className,
disabled,
/* translators: Submit button text for filters. */
label = __( 'Go', 'woo-gutenberg-products-block' ),
label = __( 'Apply', 'woo-gutenberg-products-block' ),
onClick,
screenReaderLabel = __( 'Apply filter', 'woo-gutenberg-products-block' ),
}: FilterSubmitButtonProps ): JSX.Element => {
return (
<button
type="submit"
className={ classNames(
'wp-block-button__link',
'wc-block-filter-submit-button',
'wc-block-components-filter-submit-button',
className
Expand Down
1 change: 1 addition & 0 deletions assets/js/base/components/filter-submit-button/style.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.wc-block-components-filter-submit-button {
border: none;
display: block;
margin-left: auto;
white-space: nowrap;
Expand Down
257 changes: 141 additions & 116 deletions assets/js/base/components/price-slider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import classnames from 'classnames';
import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount';
import { Currency, isObject } from '@woocommerce/types';
import { useDebouncedCallback } from 'use-debounce';

/**
* Internal dependencies
Expand All @@ -20,6 +21,7 @@ import './style.scss';
import { constrainRangeSliderValues } from './constrain-range-slider-values';
import FilterSubmitButton from '../filter-submit-button';
import { isValidMaxValue, isValidMinValue } from './utils';
import FilterResetButton from '../filter-reset-button';

export interface PriceSliderProps {
/**
Expand Down Expand Up @@ -62,6 +64,10 @@ export interface PriceSliderProps {
* Whether to show input fields for the values or not.
*/
showInputFields?: boolean;
/**
* Whether to show input fields inline with the slider or not.
*/
inlineInput?: boolean;
/**
* What step values the slider uses.
*/
Expand All @@ -78,6 +84,7 @@ const PriceSlider = ( {
currency,
showInputFields = true,
showFilterButton = false,
inlineInput = true,
isLoading = false,
onSubmit = () => void 0,
}: PriceSliderProps ): JSX.Element => {
Expand Down Expand Up @@ -274,6 +281,8 @@ const PriceSlider = ( {
[ onChange, stepValue, minPriceInput, maxPriceInput ]
);

const debouncedUpdateQuery = useDebouncedCallback( onSubmit, 600 );

const classes = classnames(
'wc-block-price-filter',
'wc-block-components-price-slider',
Expand Down Expand Up @@ -301,133 +310,149 @@ const PriceSlider = ( {
maxPriceInput / 10 ** currency.minorUnit
);

const slider = (
<div
className="wc-block-price-filter__range-input-wrapper wc-block-components-price-slider__range-input-wrapper"
onMouseMove={ findClosestRange }
onFocus={ findClosestRange }
>
{ hasValidConstraints && (
<div aria-hidden={ showInputFields }>
<div
className="wc-block-price-filter__range-input-progress wc-block-components-price-slider__range-input-progress"
style={ progressStyles as React.CSSProperties }
/>
<input
type="range"
className="wc-block-price-filter__range-input wc-block-price-filter__range-input--min wc-block-components-price-slider__range-input wc-block-components-price-slider__range-input--min"
aria-label={ __(
'Filter products by minimum price',
'woo-gutenberg-products-block'
) }
aria-valuetext={ ariaReadableMinPrice }
value={
Number.isFinite( minPrice )
? minPrice
: minConstraint
}
onChange={ rangeInputOnChange }
step={ minRangeStep }
min={ minConstraint }
max={ maxConstraint }
ref={ minRange }
disabled={ isLoading && ! hasValidConstraints }
tabIndex={ showInputFields ? -1 : 0 }
/>
<input
type="range"
className="wc-block-price-filter__range-input wc-block-price-filter__range-input--max wc-block-components-price-slider__range-input wc-block-components-price-slider__range-input--max"
aria-label={ __(
'Filter products by maximum price',
'woo-gutenberg-products-block'
) }
aria-valuetext={ ariaReadableMaxPrice }
value={
Number.isFinite( maxPrice )
? maxPrice
: maxConstraint
}
onChange={ rangeInputOnChange }
step={ maxRangeStep }
min={ minConstraint }
max={ maxConstraint }
ref={ maxRange }
disabled={ isLoading }
tabIndex={ showInputFields ? -1 : 0 }
/>
</div>
) }
</div>
);

return (
<div className={ classes }>
<div
className="wc-block-price-filter__range-input-wrapper wc-block-components-price-slider__range-input-wrapper"
onMouseMove={ findClosestRange }
onFocus={ findClosestRange }
>
{ hasValidConstraints && (
<div aria-hidden={ showInputFields }>
<div
className="wc-block-price-filter__range-input-progress wc-block-components-price-slider__range-input-progress"
style={ progressStyles as React.CSSProperties }
/>
<input
type="range"
className="wc-block-price-filter__range-input wc-block-price-filter__range-input--min wc-block-components-price-slider__range-input wc-block-components-price-slider__range-input--min"
aria-label={ __(
'Filter products by minimum price',
'woo-gutenberg-products-block'
) }
aria-valuetext={ ariaReadableMinPrice }
value={
Number.isFinite( minPrice )
? minPrice
: minConstraint
{ ( ! inlineInput || ! showInputFields ) && slider }
{ showInputFields && (
<div className="wc-block-price-filter__controls wc-block-components-price-slider__controls">
<FormattedMonetaryAmount
currency={ currency }
displayType="input"
className="wc-block-price-filter__amount wc-block-price-filter__amount--min wc-block-form-text-input wc-block-components-price-slider__amount wc-block-components-price-slider__amount--min"
aria-label={ __(
'Filter products by minimum price',
'woo-gutenberg-products-block'
) }
allowNegative={ false }
isAllowed={ isValidMinValue( {
minConstraint,
minorUnit: currency.minorUnit,
currentMaxValue: maxPriceInput,
} ) }
onValueChange={ ( value ) => {
if ( value === minPriceInput ) {
return;
}
onChange={ rangeInputOnChange }
step={ minRangeStep }
min={ minConstraint }
max={ maxConstraint }
ref={ minRange }
disabled={ isLoading }
tabIndex={ showInputFields ? -1 : 0 }
/>
<input
type="range"
className="wc-block-price-filter__range-input wc-block-price-filter__range-input--max wc-block-components-price-slider__range-input wc-block-components-price-slider__range-input--max"
aria-label={ __(
'Filter products by maximum price',
'woo-gutenberg-products-block'
) }
aria-valuetext={ ariaReadableMaxPrice }
value={
Number.isFinite( maxPrice )
? maxPrice
: maxConstraint
setMinPriceInput( value );
} }
onBlur={ priceInputOnBlur }
disabled={ isLoading || ! hasValidConstraints }
value={ minPriceInput }
/>
{ inlineInput && slider }
<FormattedMonetaryAmount
currency={ currency }
displayType="input"
className="wc-block-price-filter__amount wc-block-price-filter__amount--max wc-block-form-text-input wc-block-components-price-slider__amount wc-block-components-price-slider__amount--max"
aria-label={ __(
'Filter products by maximum price',
'woo-gutenberg-products-block'
) }
isAllowed={ isValidMaxValue( {
maxConstraint,
minorUnit: currency.minorUnit,
} ) }
onValueChange={ ( value ) => {
if ( value === maxPriceInput ) {
return;
}
onChange={ rangeInputOnChange }
step={ maxRangeStep }
min={ minConstraint }
max={ maxConstraint }
ref={ maxRange }
disabled={ isLoading }
tabIndex={ showInputFields ? -1 : 0 }
/>
</div>
) }
</div>
<div className="wc-block-price-filter__controls wc-block-components-price-slider__controls">
{ showInputFields && (
<>
setMaxPriceInput( value );
} }
onBlur={ priceInputOnBlur }
disabled={ isLoading || ! hasValidConstraints }
value={ maxPriceInput }
/>
</div>
) }

{ ! showInputFields &&
! isLoading &&
Number.isFinite( minPrice ) &&
Number.isFinite( maxPrice ) && (
<div className="wc-block-price-filter__range-text wc-block-components-price-slider__range-text">
<FormattedMonetaryAmount
currency={ currency }
displayType="input"
className="wc-block-price-filter__amount wc-block-price-filter__amount--min wc-block-form-text-input wc-block-components-price-slider__amount wc-block-components-price-slider__amount--min"
aria-label={ __(
'Filter products by minimum price',
'woo-gutenberg-products-block'
) }
allowNegative={ false }
isAllowed={ isValidMinValue( {
minConstraint,
minorUnit: currency.minorUnit,
currentMaxValue: maxPriceInput,
} ) }
onValueChange={ ( value ) => {
if ( value === minPriceInput ) {
return;
}
setMinPriceInput( value );
} }
onBlur={ priceInputOnBlur }
disabled={ isLoading || ! hasValidConstraints }
value={ minPriceInput }
value={ minPrice }
/>
<FormattedMonetaryAmount
currency={ currency }
displayType="input"
className="wc-block-price-filter__amount wc-block-price-filter__amount--max wc-block-form-text-input wc-block-components-price-slider__amount wc-block-components-price-slider__amount--max"
aria-label={ __(
'Filter products by maximum price',
'woo-gutenberg-products-block'
) }
isAllowed={ isValidMaxValue( {
maxConstraint,
minorUnit: currency.minorUnit,
} ) }
onValueChange={ ( value ) => {
if ( value === maxPriceInput ) {
return;
}
setMaxPriceInput( value );
} }
onBlur={ priceInputOnBlur }
disabled={ isLoading || ! hasValidConstraints }
value={ maxPriceInput }
value={ maxPrice }
/>
</>
</div>
) }
<div className="wc-block-components-price-slider__actions">
{ ( minPrice !== minConstraint ||
maxPrice !== maxConstraint ) && (
<FilterResetButton
onClick={ () => {
onChange( [ minConstraint, maxConstraint ] );
debouncedUpdateQuery();
} }
screenReaderLabel={ __(
'Reset price filter',
'woo-gutenberg-products-block'
) }
/>
) }
{ ! showInputFields &&
! isLoading &&
Number.isFinite( minPrice ) &&
Number.isFinite( maxPrice ) && (
<div className="wc-block-price-filter__range-text wc-block-components-price-slider__range-text">
{ __( 'Price', 'woo-gutenberg-products-block' ) }
: &nbsp;
<FormattedMonetaryAmount
currency={ currency }
value={ minPrice }
/>
&nbsp;&ndash;&nbsp;
<FormattedMonetaryAmount
currency={ currency }
value={ maxPrice }
/>
</div>
) }
{ showFilterButton && (
<FilterSubmitButton
className="wc-block-price-filter__button wc-block-components-price-slider__button"
Expand Down
Loading