initial commit

This commit is contained in:
2021-12-10 12:03:04 +00:00
commit c46c7ddbf0
3643 changed files with 582794 additions and 0 deletions

View File

@ -0,0 +1,149 @@
/**
* External dependencies
*/
import classNames from 'classnames';
import { _n, sprintf } from '@wordpress/i18n';
import { decodeEntities } from '@wordpress/html-entities';
import type { ReactElement } from 'react';
import type { PackageRateOption } from '@woocommerce/type-defs/shipping';
import { Panel } from '@woocommerce/blocks-checkout';
import Label from '@woocommerce/base-components/label';
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 {
address_1: string;
address_2: string;
city: string;
state: string;
postcode: string;
country: string;
}
export interface PackageData {
destination: Destination;
name: string;
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 ) && (
<div className="wc-block-components-shipping-rates-control__package-title">
{ packageData.name }
</div>
) }
{ 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;

View File

@ -0,0 +1,69 @@
/**
* External dependencies
*/
import RadioControl, {
RadioControlOptionLayout,
} from '@woocommerce/base-components/radio-control';
import type { PackageRateOption } from '@woocommerce/type-defs/shipping';
import type { ReactElement } from 'react';
import type { CartShippingPackageShippingRate } from '@woocommerce/type-defs/cart';
/**
* Internal dependencies
*/
import { renderPackageRateOption } from './render-package-rate-option';
interface PackageRates {
onSelectRate: ( selectedRateId: string ) => void;
rates: CartShippingPackageShippingRate[];
renderOption?: (
option: CartShippingPackageShippingRate
) => PackageRateOption;
className?: string;
noResultsMessage: ReactElement;
selected?: string;
}
const PackageRates = ( {
className,
noResultsMessage,
onSelectRate,
rates,
renderOption = renderPackageRateOption,
selected,
}: PackageRates ): ReactElement => {
if ( rates.length === 0 ) {
return noResultsMessage;
}
if ( rates.length > 1 ) {
return (
<RadioControl
className={ className }
onChange={ ( selectedRateId: string ) => {
onSelectRate( selectedRateId );
} }
selected={ selected }
options={ rates.map( renderOption ) }
/>
);
}
const {
label,
secondaryLabel,
description,
secondaryDescription,
} = renderOption( rates[ 0 ] );
return (
<RadioControlOptionLayout
label={ label }
secondaryLabel={ secondaryLabel }
description={ description }
secondaryDescription={ secondaryDescription }
/>
);
};
export default PackageRates;

View File

@ -0,0 +1,46 @@
/**
* External dependencies
*/
import { decodeEntities } from '@wordpress/html-entities';
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount';
import type { PackageRateOption } from '@woocommerce/type-defs/shipping';
import { getSetting } from '@woocommerce/settings';
import { CartShippingPackageShippingRate } from '@woocommerce/type-defs/cart';
/**
* Default render function for package rate options.
*
* @param {Object} rate Rate data.
*/
export const renderPackageRateOption = (
rate: CartShippingPackageShippingRate
): PackageRateOption => {
const priceWithTaxes: number = getSetting(
'displayCartPricesIncludingTax',
false
)
? parseInt( rate.price, 10 ) + parseInt( rate.taxes, 10 )
: parseInt( rate.price, 10 );
return {
label: decodeEntities( rate.name ),
value: rate.rate_id,
description: (
<>
{ Number.isFinite( priceWithTaxes ) && (
<FormattedMonetaryAmount
currency={ getCurrencyFromPriceResponse( rate ) }
value={ priceWithTaxes }
/>
) }
{ Number.isFinite( priceWithTaxes ) && rate.delivery_time
? ' — '
: null }
{ decodeEntities( rate.delivery_time ) }
</>
),
};
};
export default renderPackageRateOption;

View File

@ -0,0 +1,43 @@
.wc-block-components-shipping-rates-control__package {
.wc-block-components-panel__button {
margin-bottom: 0;
margin-top: 0;
padding-bottom: em($gap-small);
padding-top: em($gap-small);
}
// Remove panel padding because we are adding bottom padding to `.wc-block-components-radio-control`
// and `.wc-block-components-radio-control__option-layout` in the next ruleset.
.wc-block-components-panel__content {
padding-bottom: 0;
}
.wc-block-components-radio-control,
.wc-block-components-radio-control__option-layout {
padding-bottom: 0;
}
.wc-block-components-radio-control .wc-block-components-radio-control__option-layout {
padding-bottom: 0;
}
}
.wc-block-components-shipping-rates-control__package-items {
@include font-size(small);
display: block;
list-style: none;
margin: 0;
padding: 0;
}
.wc-block-components-shipping-rates-control__package-item {
@include wrap-break-word();
display: inline-block;
margin: 0;
padding: 0;
}
.wc-block-components-shipping-rates-control__package-item:not(:last-child)::after {
content: ", ";
white-space: pre;
}