From 7b53486be36e22dd041f77d184b250ff8771f0d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Wed, 19 Feb 2020 11:51:15 +0100 Subject: [PATCH] Add loading state to shipping rates selector (https://github.com/woocommerce/woocommerce-blocks/pull/1764) * Add loading state to shipping rates selector * Add screenReaderLabel specific for ShippingRatesControl * Rename LoadingComponent to LoadingMask --- .../js/base/components/loading-mask/index.js | 43 ++++++++++++++ .../base/components/loading-mask/style.scss | 16 ++++++ .../shipping-rates-control/index.js | 57 ++++++++++++------- .../woocommerce-blocks/bin/webpack-helpers.js | 2 + 4 files changed, 98 insertions(+), 20 deletions(-) create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/loading-mask/index.js create mode 100644 plugins/woocommerce-blocks/assets/js/base/components/loading-mask/style.scss diff --git a/plugins/woocommerce-blocks/assets/js/base/components/loading-mask/index.js b/plugins/woocommerce-blocks/assets/js/base/components/loading-mask/index.js new file mode 100644 index 00000000000..ba92d55e39b --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/loading-mask/index.js @@ -0,0 +1,43 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { Spinner } from 'wordpress-components'; + +/** + * Internal dependencies + */ +import './style.scss'; + +const LoadingMask = ( { + children, + className, + screenReaderLabel, + showSpinner = false, +} ) => { + return ( +
+ { showSpinner && } +
+ { children } +
+ + { screenReaderLabel || + __( 'Loading…', 'woo-gutenberg-products-block' ) } + +
+ ); +}; + +LoadingMask.propTypes = { + className: PropTypes.string, + screenReaderLabel: PropTypes.string, + showSpinner: PropTypes.bool, +}; + +export default LoadingMask; diff --git a/plugins/woocommerce-blocks/assets/js/base/components/loading-mask/style.scss b/plugins/woocommerce-blocks/assets/js/base/components/loading-mask/style.scss new file mode 100644 index 00000000000..343006a281e --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/base/components/loading-mask/style.scss @@ -0,0 +1,16 @@ +.wc-block-loading-mask { + position: relative; + min-height: 18px + $gap; + + .components-spinner { + position: absolute; + margin: 0; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } +} + +.wc-blocks-loading-mask__children { + opacity: 0.5; +} diff --git a/plugins/woocommerce-blocks/assets/js/base/components/shipping-rates-control/index.js b/plugins/woocommerce-blocks/assets/js/base/components/shipping-rates-control/index.js index 66d1538be1f..9d4b1115125 100644 --- a/plugins/woocommerce-blocks/assets/js/base/components/shipping-rates-control/index.js +++ b/plugins/woocommerce-blocks/assets/js/base/components/shipping-rates-control/index.js @@ -1,8 +1,9 @@ /** * External dependencies */ +import { __ } from '@wordpress/i18n'; import PropTypes from 'prop-types'; -import { useShippingRates } from '@woocommerce/base-hooks'; +import { usePrevious, useShippingRates } from '@woocommerce/base-hooks'; import { useEffect } from '@wordpress/element'; /** @@ -10,6 +11,7 @@ import { useEffect } from '@wordpress/element'; */ import Package from './package'; import './style.scss'; +import LoadingMask from '../loading-mask'; const ShippingRatesControl = ( { address, @@ -20,6 +22,28 @@ const ShippingRatesControl = ( { selected = [], } ) => { const { shippingRates, shippingRatesLoading } = useShippingRates( address ); + const previousShippingRates = usePrevious( + shippingRates, + ( newRates ) => newRates.length > 0 + ); + + const renderPackages = ( rates ) => + rates.map( ( shippingRate, i ) => ( + { + const newSelected = [ ...selected ]; + newSelected[ i ] = newShippingRate; + onChange( newSelected ); + } } + renderOption={ renderOption } + selected={ selected[ i ] } + shippingRate={ shippingRate } + showItems={ rates.length > 1 } + /> + ) ); // Select first item when shipping rates are loaded. useEffect( @@ -58,27 +82,20 @@ const ShippingRatesControl = ( { ); if ( shippingRatesLoading ) { - // @todo Add some indication that shipping rates are loading. - // see: https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/1555 - return null; + return ( + + { renderPackages( previousShippingRates || [] ) } + + ); } - return shippingRates.map( ( shippingRate, i ) => ( - { - const newSelected = [ ...selected ]; - newSelected[ i ] = newShippingRate; - onChange( newSelected ); - } } - renderOption={ renderOption } - selected={ selected[ i ] } - shippingRate={ shippingRate } - showItems={ shippingRates.length > 1 } - /> - ) ); + return renderPackages( shippingRates ); }; ShippingRatesControl.propTypes = { diff --git a/plugins/woocommerce-blocks/bin/webpack-helpers.js b/plugins/woocommerce-blocks/bin/webpack-helpers.js index 073931a7561..3b8ce82bb9b 100644 --- a/plugins/woocommerce-blocks/bin/webpack-helpers.js +++ b/plugins/woocommerce-blocks/bin/webpack-helpers.js @@ -132,6 +132,8 @@ const stableMainEntry = { 'panel-style': './node_modules/@wordpress/components/src/panel/style.scss', 'custom-select-control-style': './node_modules/@wordpress/components/src/custom-select-control/style.scss', + 'spinner-style': + './node_modules/@wordpress/components/src/spinner/style.scss', }; const experimentalMainEntry = {