Skip to content

Commit cfbee08

Browse files
committed
Introduce Additional Fields API for Checkout Block woocommerce/woocommerce-blocks#12073
1 parent 81c19c0 commit cfbee08

File tree

33 files changed

+1501
-462
lines changed

33 files changed

+1501
-462
lines changed

plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/address-form/address-form.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,22 @@ import {
1717
import { useEffect, useMemo, useRef } from '@wordpress/element';
1818
import { useInstanceId } from '@wordpress/compose';
1919
import { useShallowEqual } from '@woocommerce/base-hooks';
20-
import { defaultAddressFields } from '@woocommerce/settings';
2120
import isShallowEqual from '@wordpress/is-shallow-equal';
2221

2322
/**
2423
* Internal dependencies
2524
*/
26-
import {
27-
AddressFormProps,
28-
FieldType,
29-
FieldConfig,
30-
AddressFormFields,
31-
} from './types';
25+
import { AddressFormProps, FieldConfig, AddressFormFields } from './types';
3226
import prepareAddressFields from './prepare-address-fields';
3327
import validateShippingCountry from './validate-shipping-country';
3428
import customValidationHandler from './custom-validation-handler';
3529

36-
const defaultFields = Object.keys(
37-
defaultAddressFields
38-
) as unknown as FieldType[];
39-
4030
/**
4131
* Checkout address form.
4232
*/
4333
const AddressForm = ( {
4434
id = '',
45-
fields = defaultFields,
35+
fields,
4636
fieldConfig = {} as FieldConfig,
4737
onChange,
4838
type = 'shipping',

plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/address-form/prepare-address-fields.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
AddressField,
88
AddressFields,
99
CountryAddressFields,
10-
defaultAddressFields,
10+
defaultFields,
1111
KeyedAddressField,
1212
LocaleSpecificAddressField,
1313
} from '@woocommerce/settings';
@@ -114,7 +114,7 @@ const prepareAddressFields = (
114114

115115
return fields
116116
.map( ( field ) => {
117-
const defaultConfig = defaultAddressFields[ field ] || {};
117+
const defaultConfig = defaultFields[ field ] || {};
118118
const localeConfig = localeConfigs[ field ] || {};
119119
const fieldConfig = fieldConfigs[ field ] || {};
120120

plugins/woocommerce-blocks/assets/js/base/components/cart-checkout/address-form/test/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { render, screen } from '@testing-library/react';
55
import userEvent from '@testing-library/user-event';
66
import { CheckoutProvider } from '@woocommerce/base-context';
77
import { useCheckoutAddress } from '@woocommerce/base-context/hooks';
8+
import { ADDRESS_FIELDS_KEYS } from '@woocommerce/block-settings';
89

910
/**
1011
* Internal dependencies
@@ -81,15 +82,14 @@ const inputAddress = async ( {
8182

8283
describe( 'AddressForm Component', () => {
8384
const WrappedAddressForm = ( { type } ) => {
84-
const { defaultAddressFields, setShippingAddress, shippingAddress } =
85-
useCheckoutAddress();
85+
const { setShippingAddress, shippingAddress } = useCheckoutAddress();
8686

8787
return (
8888
<AddressForm
8989
type={ type }
9090
onChange={ setShippingAddress }
9191
values={ shippingAddress }
92-
fields={ Object.keys( defaultAddressFields ) }
92+
fields={ ADDRESS_FIELDS_KEYS }
9393
/>
9494
);
9595
};

plugins/woocommerce-blocks/assets/js/base/context/hooks/use-checkout-address.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* External dependencies
33
*/
44
import {
5-
defaultAddressFields,
5+
defaultFields,
66
AddressFields,
77
ShippingAddress,
88
BillingAddress,
@@ -26,7 +26,7 @@ interface CheckoutAddress {
2626
setEmail: ( value: string ) => void;
2727
useShippingAsBilling: boolean;
2828
setUseShippingAsBilling: ( useShippingAsBilling: boolean ) => void;
29-
defaultAddressFields: AddressFields;
29+
defaultFields: AddressFields;
3030
showShippingFields: boolean;
3131
showBillingFields: boolean;
3232
forcedBillingAddress: boolean;
@@ -74,7 +74,7 @@ export const useCheckoutAddress = (): CheckoutAddress => {
7474
setShippingAddress,
7575
setBillingAddress,
7676
setEmail,
77-
defaultAddressFields,
77+
defaultFields,
7878
useShippingAsBilling,
7979
setUseShippingAsBilling: __internalSetUseShippingAsBilling,
8080
needsShipping,

plugins/woocommerce-blocks/assets/js/base/utils/address.ts

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,12 @@ import type {
77
CartResponseBillingAddress,
88
CartResponseShippingAddress,
99
} from '@woocommerce/types';
10-
import {
11-
AddressFields,
12-
defaultAddressFields,
13-
ShippingAddress,
14-
BillingAddress,
15-
} from '@woocommerce/settings';
10+
import { ShippingAddress, BillingAddress } from '@woocommerce/settings';
1611
import { decodeEntities } from '@wordpress/html-entities';
1712
import {
1813
SHIPPING_COUNTRIES,
1914
SHIPPING_STATES,
15+
ADDRESS_FIELDS_KEYS,
2016
} from '@woocommerce/block-settings';
2117

2218
/**
@@ -26,10 +22,9 @@ export const isSameAddress = < T extends ShippingAddress | BillingAddress >(
2622
address1: T,
2723
address2: T
2824
): boolean => {
29-
return Object.keys( defaultAddressFields ).every(
30-
( field: string ) =>
31-
address1[ field as keyof T ] === address2[ field as keyof T ]
32-
);
25+
return Object.keys( ADDRESS_FIELDS_KEYS ).every( ( field: string ) => {
26+
return address1[ field as keyof T ] === address2[ field as keyof T ];
27+
} );
3328
};
3429

3530
/**
@@ -94,10 +89,11 @@ export const emptyHiddenAddressFields = <
9489
>(
9590
address: T
9691
): T => {
97-
const fields = Object.keys(
98-
defaultAddressFields
99-
) as ( keyof AddressFields )[];
100-
const addressFields = prepareAddressFields( fields, {}, address.country );
92+
const addressFields = prepareAddressFields(
93+
ADDRESS_FIELDS_KEYS,
94+
{},
95+
address.country
96+
);
10197
const newAddress = Object.assign( {}, address ) as T;
10298

10399
addressFields.forEach( ( { key = '', hidden = false } ) => {
@@ -160,10 +156,11 @@ export const isAddressComplete = (
160156
if ( ! address.country ) {
161157
return false;
162158
}
163-
const fields = Object.keys(
164-
defaultAddressFields
165-
) as ( keyof AddressFields )[];
166-
const addressFields = prepareAddressFields( fields, {}, address.country );
159+
const addressFields = prepareAddressFields(
160+
ADDRESS_FIELDS_KEYS,
161+
{},
162+
address.country
163+
);
167164

168165
return addressFields.every(
169166
( { key = '', hidden = false, required = false } ) => {

plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/customer-address.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
} from '@woocommerce/settings';
1212
import { useSelect } from '@wordpress/data';
1313
import { VALIDATION_STORE_KEY } from '@woocommerce/block-data';
14+
import { ADDRESS_FIELDS_KEYS } from '@woocommerce/block-settings';
1415

1516
/**
1617
* Internal dependencies
@@ -26,7 +27,6 @@ const CustomerAddress = ( {
2627
defaultEditing?: boolean;
2728
} ) => {
2829
const {
29-
defaultAddressFields,
3030
billingAddress,
3131
setShippingAddress,
3232
setBillingAddress,
@@ -58,10 +58,6 @@ const CustomerAddress = ( {
5858
}
5959
}, [ editing, hasValidationErrors, invalidProps.length ] );
6060

61-
const addressFieldKeys = Object.keys(
62-
defaultAddressFields
63-
) as ( keyof AddressFields )[];
64-
6561
const onChangeAddress = useCallback(
6662
( values: Partial< BillingAddress > ) => {
6763
setBillingAddress( values );
@@ -101,17 +97,12 @@ const CustomerAddress = ( {
10197
type="billing"
10298
onChange={ onChangeAddress }
10399
values={ billingAddress }
104-
fields={ addressFieldKeys }
100+
fields={ ADDRESS_FIELDS_KEYS }
105101
fieldConfig={ addressFieldsConfig }
106102
/>
107103
</>
108104
),
109-
[
110-
addressFieldKeys,
111-
addressFieldsConfig,
112-
billingAddress,
113-
onChangeAddress,
114-
]
105+
[ addressFieldsConfig, billingAddress, onChangeAddress ]
115106
);
116107

117108
return (

plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
} from '@woocommerce/settings';
1212
import { useSelect } from '@wordpress/data';
1313
import { VALIDATION_STORE_KEY } from '@woocommerce/block-data';
14+
import { ADDRESS_FIELDS_KEYS } from '@woocommerce/block-settings';
1415

1516
/**
1617
* Internal dependencies
@@ -26,7 +27,6 @@ const CustomerAddress = ( {
2627
defaultEditing?: boolean;
2728
} ) => {
2829
const {
29-
defaultAddressFields,
3030
shippingAddress,
3131
setShippingAddress,
3232
setBillingAddress,
@@ -57,9 +57,6 @@ const CustomerAddress = ( {
5757
}
5858
}, [ editing, hasValidationErrors, invalidProps.length ] );
5959

60-
const addressFieldKeys = Object.keys(
61-
defaultAddressFields
62-
) as ( keyof AddressFields )[];
6360
const onChangeAddress = useCallback(
6461
( values: Partial< ShippingAddress > ) => {
6562
setShippingAddress( values );
@@ -98,16 +95,11 @@ const CustomerAddress = ( {
9895
type="shipping"
9996
onChange={ onChangeAddress }
10097
values={ shippingAddress }
101-
fields={ addressFieldKeys }
98+
fields={ ADDRESS_FIELDS_KEYS }
10299
fieldConfig={ addressFieldsConfig }
103100
/>
104101
),
105-
[
106-
addressFieldKeys,
107-
addressFieldsConfig,
108-
onChangeAddress,
109-
shippingAddress,
110-
]
102+
[ addressFieldsConfig, onChangeAddress, shippingAddress ]
111103
);
112104

113105
return (

plugins/woocommerce-blocks/assets/js/data/cart/default-state.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
/**
22
* External dependencies
33
*/
4-
import type { Cart, CartMeta, ApiErrorResponse } from '@woocommerce/types';
4+
import type {
5+
Cart,
6+
CartMeta,
7+
ApiErrorResponse,
8+
CartShippingAddress,
9+
CartBillingAddress,
10+
} from '@woocommerce/types';
11+
import { AddressField, defaultFields } from '@woocommerce/settings';
512

613
/**
714
* Internal dependencies
@@ -30,37 +37,33 @@ export interface CartState {
3037
metaData: CartMeta;
3138
errors: ApiErrorResponse[];
3239
}
40+
41+
const shippingAddress: Partial<
42+
CartShippingAddress & { email: AddressField }
43+
> = {};
44+
Object.keys( defaultFields ).forEach( ( key ) => {
45+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
46+
// @ts-ignore the default fields contain keys for each field.
47+
shippingAddress[ key ] = '';
48+
} );
49+
delete shippingAddress.email;
50+
51+
const billingAddress: Partial< CartBillingAddress & { email: AddressField } > =
52+
{};
53+
Object.keys( defaultFields ).forEach( ( key ) => {
54+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
55+
// @ts-ignore the default fields contain keys for each field.
56+
billingAddress[ key ] = '';
57+
} );
58+
3359
export const defaultCartState: CartState = {
3460
cartItemsPendingQuantity: EMPTY_PENDING_QUANTITY,
3561
cartItemsPendingDelete: EMPTY_PENDING_DELETE,
3662
cartData: {
3763
coupons: EMPTY_CART_COUPONS,
3864
shippingRates: EMPTY_SHIPPING_RATES,
39-
shippingAddress: {
40-
first_name: '',
41-
last_name: '',
42-
company: '',
43-
address_1: '',
44-
address_2: '',
45-
city: '',
46-
state: '',
47-
postcode: '',
48-
country: '',
49-
phone: '',
50-
},
51-
billingAddress: {
52-
first_name: '',
53-
last_name: '',
54-
company: '',
55-
address_1: '',
56-
address_2: '',
57-
city: '',
58-
state: '',
59-
postcode: '',
60-
country: '',
61-
phone: '',
62-
email: '',
63-
},
65+
shippingAddress: shippingAddress as CartShippingAddress,
66+
billingAddress: billingAddress as CartBillingAddress,
6467
items: EMPTY_CART_ITEMS,
6568
itemsCount: 0,
6669
itemsWeight: 0,

plugins/woocommerce-blocks/assets/js/settings/blocks/constants.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ type CountryData = {
5858
locale: Record< string, LocaleSpecificAddressField >;
5959
};
6060

61+
type FieldsLocations = {
62+
address: string[];
63+
contact: string[];
64+
additional: string[];
65+
};
66+
6167
// Contains country names.
6268
const countries = getSetting< Record< string, string > >( 'countries', {} );
6369

@@ -112,3 +118,35 @@ export const COUNTRY_LOCALE = Object.fromEntries(
112118
return [ countryCode, countryData[ countryCode ].locale || [] ];
113119
} )
114120
);
121+
122+
const defaultFieldsLocations: FieldsLocations = {
123+
address: [
124+
'first_name',
125+
'last_name',
126+
'company',
127+
'address_1',
128+
'address_2',
129+
'city',
130+
'postcode',
131+
'country',
132+
'state',
133+
'phone',
134+
],
135+
contact: [ 'email' ],
136+
additional: [],
137+
};
138+
139+
export const ADDRESS_FIELDS_KEYS = getSetting< FieldsLocations >(
140+
'addressFieldsLocations',
141+
defaultFieldsLocations
142+
).address;
143+
144+
export const CONTACT_FIELDS_KEYS = getSetting< FieldsLocations >(
145+
'addressFieldsLocations',
146+
defaultFieldsLocations
147+
).contact;
148+
149+
export const ADDITIONAL_FIELDS_KEYS = getSetting< FieldsLocations >(
150+
'addressFieldsLocations',
151+
defaultFieldsLocations
152+
).additional;

0 commit comments

Comments
 (0)