Skip to content

Commit

Permalink
Introduce Additional Fields API for Checkout Block woocommerce/woocom…
Browse files Browse the repository at this point in the history
  • Loading branch information
senadir committed Dec 14, 2023
1 parent 81c19c0 commit cfbee08
Show file tree
Hide file tree
Showing 33 changed files with 1,501 additions and 462 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,22 @@ import {
import { useEffect, useMemo, useRef } from '@wordpress/element';
import { useInstanceId } from '@wordpress/compose';
import { useShallowEqual } from '@woocommerce/base-hooks';
import { defaultAddressFields } from '@woocommerce/settings';
import isShallowEqual from '@wordpress/is-shallow-equal';

/**
* Internal dependencies
*/
import {
AddressFormProps,
FieldType,
FieldConfig,
AddressFormFields,
} from './types';
import { AddressFormProps, FieldConfig, AddressFormFields } from './types';
import prepareAddressFields from './prepare-address-fields';
import validateShippingCountry from './validate-shipping-country';
import customValidationHandler from './custom-validation-handler';

const defaultFields = Object.keys(
defaultAddressFields
) as unknown as FieldType[];

/**
* Checkout address form.
*/
const AddressForm = ( {
id = '',
fields = defaultFields,
fields,
fieldConfig = {} as FieldConfig,
onChange,
type = 'shipping',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
AddressField,
AddressFields,
CountryAddressFields,
defaultAddressFields,
defaultFields,
KeyedAddressField,
LocaleSpecificAddressField,
} from '@woocommerce/settings';
Expand Down Expand Up @@ -114,7 +114,7 @@ const prepareAddressFields = (

return fields
.map( ( field ) => {
const defaultConfig = defaultAddressFields[ field ] || {};
const defaultConfig = defaultFields[ field ] || {};
const localeConfig = localeConfigs[ field ] || {};
const fieldConfig = fieldConfigs[ field ] || {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { CheckoutProvider } from '@woocommerce/base-context';
import { useCheckoutAddress } from '@woocommerce/base-context/hooks';
import { ADDRESS_FIELDS_KEYS } from '@woocommerce/block-settings';

/**
* Internal dependencies
Expand Down Expand Up @@ -81,15 +82,14 @@ const inputAddress = async ( {

describe( 'AddressForm Component', () => {
const WrappedAddressForm = ( { type } ) => {
const { defaultAddressFields, setShippingAddress, shippingAddress } =
useCheckoutAddress();
const { setShippingAddress, shippingAddress } = useCheckoutAddress();

return (
<AddressForm
type={ type }
onChange={ setShippingAddress }
values={ shippingAddress }
fields={ Object.keys( defaultAddressFields ) }
fields={ ADDRESS_FIELDS_KEYS }
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import {
defaultAddressFields,
defaultFields,
AddressFields,
ShippingAddress,
BillingAddress,
Expand All @@ -26,7 +26,7 @@ interface CheckoutAddress {
setEmail: ( value: string ) => void;
useShippingAsBilling: boolean;
setUseShippingAsBilling: ( useShippingAsBilling: boolean ) => void;
defaultAddressFields: AddressFields;
defaultFields: AddressFields;
showShippingFields: boolean;
showBillingFields: boolean;
forcedBillingAddress: boolean;
Expand Down Expand Up @@ -74,7 +74,7 @@ export const useCheckoutAddress = (): CheckoutAddress => {
setShippingAddress,
setBillingAddress,
setEmail,
defaultAddressFields,
defaultFields,
useShippingAsBilling,
setUseShippingAsBilling: __internalSetUseShippingAsBilling,
needsShipping,
Expand Down
33 changes: 15 additions & 18 deletions plugins/woocommerce-blocks/assets/js/base/utils/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,12 @@ import type {
CartResponseBillingAddress,
CartResponseShippingAddress,
} from '@woocommerce/types';
import {
AddressFields,
defaultAddressFields,
ShippingAddress,
BillingAddress,
} from '@woocommerce/settings';
import { ShippingAddress, BillingAddress } from '@woocommerce/settings';
import { decodeEntities } from '@wordpress/html-entities';
import {
SHIPPING_COUNTRIES,
SHIPPING_STATES,
ADDRESS_FIELDS_KEYS,
} from '@woocommerce/block-settings';

/**
Expand All @@ -26,10 +22,9 @@ export const isSameAddress = < T extends ShippingAddress | BillingAddress >(
address1: T,
address2: T
): boolean => {
return Object.keys( defaultAddressFields ).every(
( field: string ) =>
address1[ field as keyof T ] === address2[ field as keyof T ]
);
return Object.keys( ADDRESS_FIELDS_KEYS ).every( ( field: string ) => {
return address1[ field as keyof T ] === address2[ field as keyof T ];
} );
};

/**
Expand Down Expand Up @@ -94,10 +89,11 @@ export const emptyHiddenAddressFields = <
>(
address: T
): T => {
const fields = Object.keys(
defaultAddressFields
) as ( keyof AddressFields )[];
const addressFields = prepareAddressFields( fields, {}, address.country );
const addressFields = prepareAddressFields(
ADDRESS_FIELDS_KEYS,
{},
address.country
);
const newAddress = Object.assign( {}, address ) as T;

addressFields.forEach( ( { key = '', hidden = false } ) => {
Expand Down Expand Up @@ -160,10 +156,11 @@ export const isAddressComplete = (
if ( ! address.country ) {
return false;
}
const fields = Object.keys(
defaultAddressFields
) as ( keyof AddressFields )[];
const addressFields = prepareAddressFields( fields, {}, address.country );
const addressFields = prepareAddressFields(
ADDRESS_FIELDS_KEYS,
{},
address.country
);

return addressFields.every(
( { key = '', hidden = false, required = false } ) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
} from '@woocommerce/settings';
import { useSelect } from '@wordpress/data';
import { VALIDATION_STORE_KEY } from '@woocommerce/block-data';
import { ADDRESS_FIELDS_KEYS } from '@woocommerce/block-settings';

/**
* Internal dependencies
Expand All @@ -26,7 +27,6 @@ const CustomerAddress = ( {
defaultEditing?: boolean;
} ) => {
const {
defaultAddressFields,
billingAddress,
setShippingAddress,
setBillingAddress,
Expand Down Expand Up @@ -58,10 +58,6 @@ const CustomerAddress = ( {
}
}, [ editing, hasValidationErrors, invalidProps.length ] );

const addressFieldKeys = Object.keys(
defaultAddressFields
) as ( keyof AddressFields )[];

const onChangeAddress = useCallback(
( values: Partial< BillingAddress > ) => {
setBillingAddress( values );
Expand Down Expand Up @@ -101,17 +97,12 @@ const CustomerAddress = ( {
type="billing"
onChange={ onChangeAddress }
values={ billingAddress }
fields={ addressFieldKeys }
fields={ ADDRESS_FIELDS_KEYS }
fieldConfig={ addressFieldsConfig }
/>
</>
),
[
addressFieldKeys,
addressFieldsConfig,
billingAddress,
onChangeAddress,
]
[ addressFieldsConfig, billingAddress, onChangeAddress ]
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
} from '@woocommerce/settings';
import { useSelect } from '@wordpress/data';
import { VALIDATION_STORE_KEY } from '@woocommerce/block-data';
import { ADDRESS_FIELDS_KEYS } from '@woocommerce/block-settings';

/**
* Internal dependencies
Expand All @@ -26,7 +27,6 @@ const CustomerAddress = ( {
defaultEditing?: boolean;
} ) => {
const {
defaultAddressFields,
shippingAddress,
setShippingAddress,
setBillingAddress,
Expand Down Expand Up @@ -57,9 +57,6 @@ const CustomerAddress = ( {
}
}, [ editing, hasValidationErrors, invalidProps.length ] );

const addressFieldKeys = Object.keys(
defaultAddressFields
) as ( keyof AddressFields )[];
const onChangeAddress = useCallback(
( values: Partial< ShippingAddress > ) => {
setShippingAddress( values );
Expand Down Expand Up @@ -98,16 +95,11 @@ const CustomerAddress = ( {
type="shipping"
onChange={ onChangeAddress }
values={ shippingAddress }
fields={ addressFieldKeys }
fields={ ADDRESS_FIELDS_KEYS }
fieldConfig={ addressFieldsConfig }
/>
),
[
addressFieldKeys,
addressFieldsConfig,
onChangeAddress,
shippingAddress,
]
[ addressFieldsConfig, onChangeAddress, shippingAddress ]
);

return (
Expand Down
55 changes: 29 additions & 26 deletions plugins/woocommerce-blocks/assets/js/data/cart/default-state.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
/**
* External dependencies
*/
import type { Cart, CartMeta, ApiErrorResponse } from '@woocommerce/types';
import type {
Cart,
CartMeta,
ApiErrorResponse,
CartShippingAddress,
CartBillingAddress,
} from '@woocommerce/types';
import { AddressField, defaultFields } from '@woocommerce/settings';

/**
* Internal dependencies
Expand Down Expand Up @@ -30,37 +37,33 @@ export interface CartState {
metaData: CartMeta;
errors: ApiErrorResponse[];
}

const shippingAddress: Partial<
CartShippingAddress & { email: AddressField }
> = {};
Object.keys( defaultFields ).forEach( ( key ) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore the default fields contain keys for each field.
shippingAddress[ key ] = '';
} );
delete shippingAddress.email;

const billingAddress: Partial< CartBillingAddress & { email: AddressField } > =
{};
Object.keys( defaultFields ).forEach( ( key ) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore the default fields contain keys for each field.
billingAddress[ key ] = '';
} );

export const defaultCartState: CartState = {
cartItemsPendingQuantity: EMPTY_PENDING_QUANTITY,
cartItemsPendingDelete: EMPTY_PENDING_DELETE,
cartData: {
coupons: EMPTY_CART_COUPONS,
shippingRates: EMPTY_SHIPPING_RATES,
shippingAddress: {
first_name: '',
last_name: '',
company: '',
address_1: '',
address_2: '',
city: '',
state: '',
postcode: '',
country: '',
phone: '',
},
billingAddress: {
first_name: '',
last_name: '',
company: '',
address_1: '',
address_2: '',
city: '',
state: '',
postcode: '',
country: '',
phone: '',
email: '',
},
shippingAddress: shippingAddress as CartShippingAddress,
billingAddress: billingAddress as CartBillingAddress,
items: EMPTY_CART_ITEMS,
itemsCount: 0,
itemsWeight: 0,
Expand Down
38 changes: 38 additions & 0 deletions plugins/woocommerce-blocks/assets/js/settings/blocks/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ type CountryData = {
locale: Record< string, LocaleSpecificAddressField >;
};

type FieldsLocations = {
address: string[];
contact: string[];
additional: string[];
};

// Contains country names.
const countries = getSetting< Record< string, string > >( 'countries', {} );

Expand Down Expand Up @@ -112,3 +118,35 @@ export const COUNTRY_LOCALE = Object.fromEntries(
return [ countryCode, countryData[ countryCode ].locale || [] ];
} )
);

const defaultFieldsLocations: FieldsLocations = {
address: [
'first_name',
'last_name',
'company',
'address_1',
'address_2',
'city',
'postcode',
'country',
'state',
'phone',
],
contact: [ 'email' ],
additional: [],
};

export const ADDRESS_FIELDS_KEYS = getSetting< FieldsLocations >(
'addressFieldsLocations',
defaultFieldsLocations
).address;

export const CONTACT_FIELDS_KEYS = getSetting< FieldsLocations >(
'addressFieldsLocations',
defaultFieldsLocations
).contact;

export const ADDITIONAL_FIELDS_KEYS = getSetting< FieldsLocations >(
'addressFieldsLocations',
defaultFieldsLocations
).additional;
Loading

0 comments on commit cfbee08

Please sign in to comment.