/** * External dependencies */ import { useState, useEffect } from '@wordpress/element'; import RadioControl, { RadioControlOptionLayout, } from '@woocommerce/base-components/radio-control'; import type { CartShippingPackageShippingRate } from '@woocommerce/types'; /** * Internal dependencies */ import { renderPackageRateOption } from './render-package-rate-option'; import type { PackageRateRenderOption } from '../shipping-rates-control-package'; interface PackageRates { onSelectRate: ( selectedRateId: string ) => void; rates: CartShippingPackageShippingRate[]; renderOption?: PackageRateRenderOption | undefined; className?: string; noResultsMessage: JSX.Element; selectedRate: CartShippingPackageShippingRate | undefined; } const PackageRates = ( { className = '', noResultsMessage, onSelectRate, rates, renderOption = renderPackageRateOption, selectedRate, }: PackageRates ): JSX.Element => { const selectedRateId = selectedRate?.rate_id || ''; // Store selected rate ID in local state so shipping rates changes are shown in the UI instantly. const [ selectedOption, setSelectedOption ] = useState( selectedRateId ); // Update the selected option if cart state changes in the data stores. useEffect( () => { if ( selectedRateId ) { setSelectedOption( selectedRateId ); } }, [ selectedRateId ] ); // Update the selected option if there is no rate selected on mount. useEffect( () => { // Check the rates to see if any are marked as selected. At least one should be. If no rate is selected, it could be // that the user toggled quickly from local pickup back to shipping. const isRateSelectedInDataStore = rates.some( ( { selected } ) => selected ); if ( ( ! selectedOption && rates[ 0 ] ) || ! isRateSelectedInDataStore ) { setSelectedOption( rates[ 0 ]?.rate_id ); onSelectRate( rates[ 0 ]?.rate_id ); } }, [ onSelectRate, rates, selectedOption ] ); if ( rates.length === 0 ) { return noResultsMessage; } if ( rates.length > 1 ) { return ( { setSelectedOption( value ); onSelectRate( value ); } } selected={ selectedOption } options={ rates.map( renderOption ) } /> ); } const { label, secondaryLabel, description, secondaryDescription } = renderOption( rates[ 0 ] ); return ( ); }; export default PackageRates;