/** * External dependencies */ import classNames from 'classnames'; import { _n, sprintf } from '@wordpress/i18n'; import { decodeEntities } from '@wordpress/html-entities'; import Label from '@woocommerce/base-components/label'; import Title from '@woocommerce/base-components/title'; import type { ReactElement } from 'react'; import type { PackageRateOption } from '@woocommerce/type-defs/shipping'; import { Panel } from '@woocommerce/blocks-checkout'; import { useSelectShippingRate } from '@woocommerce/base-context/hooks'; import type { CartShippingPackageShippingRate } from '@woocommerce/type-defs/cart'; /** * Internal dependencies */ import PackageRates from './package-rates'; import './style.scss'; interface PackageItem { name: string; key: string; quantity: number; } interface Destination { // eslint-disable-next-line camelcase address_1: string; // eslint-disable-next-line camelcase address_2: string; city: string; state: string; postcode: string; country: string; } export interface PackageData { destination: Destination; name: string; // eslint-disable-next-line camelcase shipping_rates: CartShippingPackageShippingRate[]; items: PackageItem[]; } export type PackageRateRenderOption = ( option: CartShippingPackageShippingRate ) => PackageRateOption; interface PackageProps { /* PackageId can be a string, WooCommerce Subscriptions uses strings for example, but WooCommerce core uses numbers */ packageId: string | number; renderOption: PackageRateRenderOption; collapse?: boolean; packageData: PackageData; className?: string; collapsible?: boolean; noResultsMessage: ReactElement; showItems?: boolean; } export const ShippingRatesControlPackage = ( { packageId, className, noResultsMessage, renderOption, packageData, collapsible = false, collapse = false, showItems = false, }: PackageProps ): ReactElement => { const { selectShippingRate, selectedShippingRate } = useSelectShippingRate( packageId, packageData.shipping_rates ); const header = ( <> { ( showItems || collapsible ) && ( <Title className="wc-block-components-shipping-rates-control__package-title" headingLevel="3" > { packageData.name } </Title> ) } { showItems && ( <ul className="wc-block-components-shipping-rates-control__package-items"> { Object.values( packageData.items ).map( ( v ) => { const name = decodeEntities( v.name ); const quantity = v.quantity; return ( <li key={ v.key } className="wc-block-components-shipping-rates-control__package-item" > <Label label={ quantity > 1 ? `${ name } × ${ quantity }` : `${ name }` } screenReaderLabel={ sprintf( /* translators: %1$s name of the product (ie: Sunglasses), %2$d number of units in the current cart package */ _n( '%1$s (%2$d unit)', '%1$s (%2$d units)', quantity, 'woo-gutenberg-products-block' ), name, quantity ) } /> </li> ); } ) } </ul> ) } </> ); const body = ( <PackageRates className={ className } noResultsMessage={ noResultsMessage } rates={ packageData.shipping_rates } onSelectRate={ selectShippingRate } selected={ selectedShippingRate } renderOption={ renderOption } /> ); if ( collapsible ) { return ( <Panel className="wc-block-components-shipping-rates-control__package" initialOpen={ ! collapse } title={ header } > { body } </Panel> ); } return ( <div className={ classNames( 'wc-block-components-shipping-rates-control__package', className ) } > { header } { body } </div> ); }; export default ShippingRatesControlPackage;