diff --git a/plugins/woocommerce-blocks/assets/js/base/context/hooks/use-checkout-address.ts b/plugins/woocommerce-blocks/assets/js/base/context/hooks/use-checkout-address.ts
index 308318d73d3..a69c2d22160 100644
--- a/plugins/woocommerce-blocks/assets/js/base/context/hooks/use-checkout-address.ts
+++ b/plugins/woocommerce-blocks/assets/js/base/context/hooks/use-checkout-address.ts
@@ -25,7 +25,11 @@ interface CheckoutAddress {
setBillingAddress: ( data: Partial< BillingAddress > ) => void;
setEmail: ( value: string ) => void;
useShippingAsBilling: boolean;
+ editingBillingAddress: boolean;
+ editingShippingAddress: boolean;
setUseShippingAsBilling: ( useShippingAsBilling: boolean ) => void;
+ setEditingBillingAddress: ( isEditing: boolean ) => void;
+ setEditingShippingAddress: ( isEditing: boolean ) => void;
defaultFields: AddressFields;
showShippingFields: boolean;
showBillingFields: boolean;
@@ -40,15 +44,25 @@ interface CheckoutAddress {
*/
export const useCheckoutAddress = (): CheckoutAddress => {
const { needsShipping } = useShippingData();
- const { useShippingAsBilling, prefersCollection } = useSelect(
- ( select ) => ( {
- useShippingAsBilling:
- select( CHECKOUT_STORE_KEY ).getUseShippingAsBilling(),
- prefersCollection: select( CHECKOUT_STORE_KEY ).prefersCollection(),
- } )
- );
- const { __internalSetUseShippingAsBilling } =
- useDispatch( CHECKOUT_STORE_KEY );
+ const {
+ useShippingAsBilling,
+ prefersCollection,
+ editingBillingAddress,
+ editingShippingAddress,
+ } = useSelect( ( select ) => ( {
+ useShippingAsBilling:
+ select( CHECKOUT_STORE_KEY ).getUseShippingAsBilling(),
+ prefersCollection: select( CHECKOUT_STORE_KEY ).prefersCollection(),
+ editingBillingAddress:
+ select( CHECKOUT_STORE_KEY ).getEditingBillingAddress(),
+ editingShippingAddress:
+ select( CHECKOUT_STORE_KEY ).getEditingShippingAddress(),
+ } ) );
+ const {
+ __internalSetUseShippingAsBilling,
+ setEditingBillingAddress,
+ setEditingShippingAddress,
+ } = useDispatch( CHECKOUT_STORE_KEY );
const {
billingAddress,
setBillingAddress,
@@ -77,6 +91,10 @@ export const useCheckoutAddress = (): CheckoutAddress => {
defaultFields,
useShippingAsBilling,
setUseShippingAsBilling: __internalSetUseShippingAsBilling,
+ editingBillingAddress,
+ editingShippingAddress,
+ setEditingBillingAddress,
+ setEditingShippingAddress,
needsShipping,
showShippingFields:
! forcedBillingAddress && needsShipping && ! prefersCollection,
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/block.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/block.tsx
index bcdcbac3e69..d56938d94df 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/block.tsx
+++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/block.tsx
@@ -7,14 +7,12 @@ import {
useCheckoutAddress,
useEditorContext,
noticeContexts,
- useShippingData,
} from '@woocommerce/base-context';
import Noninteractive from '@woocommerce/base-components/noninteractive';
import type { ShippingAddress, FormFieldsConfig } from '@woocommerce/settings';
import { StoreNoticesContainer } from '@woocommerce/blocks-components';
import { useSelect } from '@wordpress/data';
import { CART_STORE_KEY } from '@woocommerce/block-data';
-import isShallowEqual from '@wordpress/is-shallow-equal';
/**
* Internal dependencies
@@ -36,14 +34,9 @@ const Block = ( {
showPhoneField: boolean;
requirePhoneField: boolean;
} ): JSX.Element => {
- const {
- shippingAddress,
- billingAddress,
- setShippingAddress,
- useBillingAsShipping,
- } = useCheckoutAddress();
+ const { billingAddress, setShippingAddress, useBillingAsShipping } =
+ useCheckoutAddress();
const { isEditor } = useEditorContext();
- const { needsShipping } = useShippingData();
// Syncs shipping address with billing address if "Force shipping to the customer billing address" is enabled.
useEffectOnce( () => {
@@ -101,19 +94,6 @@ const Block = ( {
};
} );
- // Default editing state for CustomerAddress component comes from the current address and whether or not we're in the editor.
- const hasAddress = !! (
- billingAddress.address_1 &&
- ( billingAddress.first_name || billingAddress.last_name )
- );
- const { email, ...billingAddressWithoutEmail } = billingAddress;
- const billingMatchesShipping = isShallowEqual(
- billingAddressWithoutEmail,
- shippingAddress
- );
- const defaultEditingAddress =
- isEditor || ! hasAddress || ( needsShipping && billingMatchesShipping );
-
return (
<>
@@ -121,7 +101,6 @@ const Block = ( {
{ cartDataLoaded ? (
) : null }
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/customer-address.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/customer-address.tsx
index b36708f4314..668fe20cf61 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/customer-address.tsx
+++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-billing-address-block/customer-address.tsx
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
-import { useState, useCallback, useEffect } from '@wordpress/element';
+import { useCallback, useEffect } from '@wordpress/element';
import { Form } from '@woocommerce/base-components/cart-checkout';
import { useCheckoutAddress, useStoreEvents } from '@woocommerce/base-context';
import type {
@@ -20,19 +20,18 @@ import AddressCard from '../../address-card';
const CustomerAddress = ( {
addressFieldsConfig,
- defaultEditing = false,
}: {
addressFieldsConfig: FormFieldsConfig;
- defaultEditing?: boolean;
} ) => {
const {
billingAddress,
setShippingAddress,
setBillingAddress,
useBillingAsShipping,
+ editingBillingAddress: editing,
+ setEditingBillingAddress: setEditing,
} = useCheckoutAddress();
const { dispatchCheckoutEvent } = useStoreEvents();
- const [ editing, setEditing ] = useState( defaultEditing );
// Forces editing state if store has errors.
const { hasValidationErrors, invalidProps } = useSelect( ( select ) => {
@@ -55,7 +54,7 @@ const CustomerAddress = ( {
if ( invalidProps.length > 0 && editing === false ) {
setEditing( true );
}
- }, [ editing, hasValidationErrors, invalidProps.length ] );
+ }, [ editing, hasValidationErrors, invalidProps.length, setEditing ] );
const onChangeAddress = useCallback(
( values: AddressFormValues ) => {
@@ -86,7 +85,7 @@ const CustomerAddress = ( {
isExpanded={ editing }
/>
),
- [ billingAddress, addressFieldsConfig, editing ]
+ [ billingAddress, addressFieldsConfig, editing, setEditing ]
);
const renderAddressFormComponent = useCallback(
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/block.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/block.tsx
index 2ddbb0d7744..e749fa33afe 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/block.tsx
+++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/block.tsx
@@ -47,6 +47,7 @@ const Block = ( {
billingAddress,
useShippingAsBilling,
setUseShippingAsBilling,
+ setEditingBillingAddress,
} = useCheckoutAddress();
const { isEditor } = useEditorContext();
const isGuest = getSetting( 'currentUserId' ) === 0;
@@ -116,10 +117,6 @@ const Block = ( {
const noticeContext = useShippingAsBilling
? [ noticeContexts.SHIPPING_ADDRESS, noticeContexts.BILLING_ADDRESS ]
: [ noticeContexts.SHIPPING_ADDRESS ];
- const hasAddress = !! (
- shippingAddress.address_1 &&
- ( shippingAddress.first_name || shippingAddress.last_name )
- );
const { cartDataLoaded } = useSelect( ( select ) => {
const store = select( CART_STORE_KEY );
@@ -128,9 +125,6 @@ const Block = ( {
};
} );
- // Default editing state for CustomerAddress component comes from the current address and whether or not we're in the editor.
- const defaultEditingAddress = isEditor || ! hasAddress;
-
return (
<>
@@ -138,7 +132,6 @@ const Block = ( {
{ cartDataLoaded ? (
) : null }
@@ -151,6 +144,7 @@ const Block = ( {
if ( checked ) {
syncBillingWithShipping();
} else {
+ setEditingBillingAddress( true );
clearBillingAddress( billingAddress );
}
} }
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx
index 1c21625c188..fed4e47c7ba 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx
+++ b/plugins/woocommerce-blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
-import { useState, useCallback, useEffect } from '@wordpress/element';
+import { useCallback, useEffect } from '@wordpress/element';
import { Form } from '@woocommerce/base-components/cart-checkout';
import { useCheckoutAddress, useStoreEvents } from '@woocommerce/base-context';
import type {
@@ -20,19 +20,18 @@ import AddressCard from '../../address-card';
const CustomerAddress = ( {
addressFieldsConfig,
- defaultEditing = false,
}: {
addressFieldsConfig: FormFieldsConfig;
- defaultEditing?: boolean;
} ) => {
const {
shippingAddress,
setShippingAddress,
setBillingAddress,
useShippingAsBilling,
+ editingShippingAddress: editing,
+ setEditingShippingAddress: setEditing,
} = useCheckoutAddress();
const { dispatchCheckoutEvent } = useStoreEvents();
- const [ editing, setEditing ] = useState( defaultEditing );
// Forces editing state if store has errors.
const { hasValidationErrors, invalidProps } = useSelect( ( select ) => {
@@ -54,7 +53,7 @@ const CustomerAddress = ( {
if ( invalidProps.length > 0 && editing === false ) {
setEditing( true );
}
- }, [ editing, hasValidationErrors, invalidProps.length ] );
+ }, [ editing, hasValidationErrors, invalidProps.length, setEditing ] );
const onChangeAddress = useCallback(
( values: AddressFormValues ) => {
@@ -85,7 +84,7 @@ const CustomerAddress = ( {
isExpanded={ editing }
/>
),
- [ shippingAddress, addressFieldsConfig, editing ]
+ [ shippingAddress, addressFieldsConfig, editing, setEditing ]
);
const renderAddressFormComponent = useCallback(
diff --git a/plugins/woocommerce-blocks/assets/js/data/checkout/action-types.ts b/plugins/woocommerce-blocks/assets/js/data/checkout/action-types.ts
index 327cd10bca1..3b1b82a5254 100644
--- a/plugins/woocommerce-blocks/assets/js/data/checkout/action-types.ts
+++ b/plugins/woocommerce-blocks/assets/js/data/checkout/action-types.ts
@@ -17,4 +17,6 @@ export const ACTION_TYPES = {
SET_REDIRECT_URL: 'SET_REDIRECT_URL',
SET_SHOULD_CREATE_ACCOUNT: 'SET_SHOULD_CREATE_ACCOUNT',
SET_USE_SHIPPING_AS_BILLING: 'SET_USE_SHIPPING_AS_BILLING',
+ SET_EDITING_BILLING_ADDRESS: 'SET_EDITING_BILLING_ADDRESS',
+ SET_EDITING_SHIPPING_ADDRESS: 'SET_EDITING_SHIPPING_ADDRESS',
} as const;
diff --git a/plugins/woocommerce-blocks/assets/js/data/checkout/actions.ts b/plugins/woocommerce-blocks/assets/js/data/checkout/actions.ts
index 8cc1f724274..eee54051f65 100644
--- a/plugins/woocommerce-blocks/assets/js/data/checkout/actions.ts
+++ b/plugins/woocommerce-blocks/assets/js/data/checkout/actions.ts
@@ -118,6 +118,30 @@ export const __internalSetUseShippingAsBilling = (
useShippingAsBilling,
} );
+/**
+ * Set whether the billing address is being edited
+ *
+ * @param isEditing True if the billing address is being edited, false otherwise
+ */
+export const setEditingBillingAddress = ( isEditing: boolean ) => {
+ return {
+ type: types.SET_EDITING_BILLING_ADDRESS,
+ isEditing,
+ };
+};
+
+/**
+ * Set whether the shipping address is being edited
+ *
+ * @param isEditing True if the shipping address is being edited, false otherwise
+ */
+export const setEditingShippingAddress = ( isEditing: boolean ) => {
+ return {
+ type: types.SET_EDITING_SHIPPING_ADDRESS,
+ isEditing,
+ };
+};
+
/**
* Whether an account should be created for the user while checking out
*
@@ -182,6 +206,8 @@ export type CheckoutAction =
| typeof __internalSetCustomerId
| typeof __internalSetCustomerPassword
| typeof __internalSetUseShippingAsBilling
+ | typeof setEditingBillingAddress
+ | typeof setEditingShippingAddress
| typeof __internalSetShouldCreateAccount
| typeof __internalSetOrderNotes
| typeof setPrefersCollection
diff --git a/plugins/woocommerce-blocks/assets/js/data/checkout/default-state.ts b/plugins/woocommerce-blocks/assets/js/data/checkout/default-state.ts
index 7891c255565..1a82d4d5056 100644
--- a/plugins/woocommerce-blocks/assets/js/data/checkout/default-state.ts
+++ b/plugins/woocommerce-blocks/assets/js/data/checkout/default-state.ts
@@ -23,8 +23,28 @@ export type CheckoutState = {
shouldCreateAccount: boolean; // Should a user account be created?
status: STATUS; // Status of the checkout
useShippingAsBilling: boolean; // Should the billing form be hidden and inherit the shipping address?
+ editingBillingAddress: boolean; // Is the billing address being edited?
+ editingShippingAddress: boolean; // Is the shipping address being edited?
};
+// Default editing state for CustomerAddress component comes from the current address and whether or not we're in the editor.
+const hasBillingAddress = !! (
+ checkoutData.billing_address.address_1 &&
+ ( checkoutData.billing_address.first_name ||
+ checkoutData.billing_address.last_name )
+);
+
+const hasShippingAddress = !! (
+ checkoutData.shipping_address.address_1 &&
+ ( checkoutData.shipping_address.first_name ||
+ checkoutData.shipping_address.last_name )
+);
+
+const billingMatchesShipping = isSameAddress(
+ checkoutData.billing_address,
+ checkoutData.shipping_address
+);
+
export const defaultState: CheckoutState = {
additionalFields: checkoutData.additional_fields || {},
calculatingCount: 0,
@@ -38,8 +58,7 @@ export const defaultState: CheckoutState = {
redirectUrl: '',
shouldCreateAccount: false,
status: STATUS.IDLE,
- useShippingAsBilling: isSameAddress(
- checkoutData.billing_address,
- checkoutData.shipping_address
- ),
+ useShippingAsBilling: billingMatchesShipping,
+ editingBillingAddress: ! hasBillingAddress,
+ editingShippingAddress: ! hasShippingAddress,
};
diff --git a/plugins/woocommerce-blocks/assets/js/data/checkout/reducers.ts b/plugins/woocommerce-blocks/assets/js/data/checkout/reducers.ts
index 1a01c5772df..01bf428d245 100644
--- a/plugins/woocommerce-blocks/assets/js/data/checkout/reducers.ts
+++ b/plugins/woocommerce-blocks/assets/js/data/checkout/reducers.ts
@@ -130,6 +130,20 @@ const reducer = ( state = defaultState, action: CheckoutAction ) => {
}
break;
+ case types.SET_EDITING_BILLING_ADDRESS:
+ newState = {
+ ...state,
+ editingBillingAddress: action.isEditing,
+ };
+ break;
+
+ case types.SET_EDITING_SHIPPING_ADDRESS:
+ newState = {
+ ...state,
+ editingShippingAddress: action.isEditing,
+ };
+ break;
+
case types.SET_SHOULD_CREATE_ACCOUNT:
if (
action.shouldCreateAccount !== undefined &&
diff --git a/plugins/woocommerce-blocks/assets/js/data/checkout/selectors.ts b/plugins/woocommerce-blocks/assets/js/data/checkout/selectors.ts
index c472bc25bc8..759049db2ba 100644
--- a/plugins/woocommerce-blocks/assets/js/data/checkout/selectors.ts
+++ b/plugins/woocommerce-blocks/assets/js/data/checkout/selectors.ts
@@ -36,6 +36,14 @@ export const getUseShippingAsBilling = ( state: CheckoutState ) => {
return state.useShippingAsBilling;
};
+export const getEditingBillingAddress = ( state: CheckoutState ) => {
+ return state.editingBillingAddress;
+};
+
+export const getEditingShippingAddress = ( state: CheckoutState ) => {
+ return state.editingShippingAddress;
+};
+
export const getExtensionData = ( state: CheckoutState ) => {
return state.extensionData;
};
diff --git a/plugins/woocommerce-blocks/docs/third-party-developers/extensibility/data-store/checkout.md b/plugins/woocommerce-blocks/docs/third-party-developers/extensibility/data-store/checkout.md
index 5badd9d879e..b4a99cc4ecb 100644
--- a/plugins/woocommerce-blocks/docs/third-party-developers/extensibility/data-store/checkout.md
+++ b/plugins/woocommerce-blocks/docs/third-party-developers/extensibility/data-store/checkout.md
@@ -1,5 +1,7 @@
# Checkout Store (`wc/store/checkout`)
+
+
> 💡 What's the difference between the Cart Store and the Checkout Store?
>
> The **Cart Store (`wc/store/cart`)** manages and retrieves data about the shopping cart, including items, customer data, and interactions like coupons.
@@ -173,6 +175,36 @@ const store = select( CHECKOUT_STORE_KEY );
const useShippingAsBilling = store.getUseShippingAsBilling();
```
+### getEditingBillingAddress
+
+Returns true if the billing address is being edited.
+
+#### _Returns_
+
+- `boolean`: True if the billing address is being edited.
+
+#### _Example_
+
+```js
+const store = select( CHECKOUT_STORE_KEY );
+const editingBillingAddress = store.getEditingBillingAddress();
+```
+
+### getEditingShippingAddress
+
+Returns true if the shipping address is being edited.
+
+#### _Returns_
+
+- `boolean`: True if the shipping address is being edited.
+
+#### _Example_
+
+```js
+const store = select( CHECKOUT_STORE_KEY );
+const editingShippingAddress = store.getEditingShippingAddress();
+```
+
### hasError
Returns true if an error occurred, and false otherwise.
@@ -293,7 +325,6 @@ const store = select( CHECKOUT_STORE_KEY );
const isCalculating = store.isCalculating();
```
-
### prefersCollection
Returns true if the customer prefers to collect their order, and false otherwise.
@@ -326,6 +357,36 @@ const store = dispatch( CHECKOUT_STORE_KEY );
store.setPrefersCollection( true );
```
+### setEditingBillingAddress
+
+Set the billing address to editing state or collapsed state. Note that if the address has invalid fields, it will not be set to collapsed state.
+
+#### _Parameters_
+
+- _isEditing_ `boolean`: True to set the billing address to editing state, false to set it to collapsed state.
+
+#### _Example_
+
+```js
+const store = dispatch( CHECKOUT_STORE_KEY );
+store.setEditingBillingAddress( true );
+```
+
+### setEditingShippingAddress
+
+Set the shipping address to editing state or collapsed state. Note that if the address has invalid fields, it will not be set to collapsed state.
+
+#### _Parameters_
+
+- _isEditing_ `boolean`: True to set the shipping address to editing state, false to set it to collapsed state.
+
+#### _Example_
+
+```js
+const store = dispatch( CHECKOUT_STORE_KEY );
+store.setEditingShippingAddress( true );
+```
+
---
diff --git a/plugins/woocommerce-blocks/packages/components/panel/style.scss b/plugins/woocommerce-blocks/packages/components/panel/style.scss
index 8df33917d6a..d4651f9b918 100644
--- a/plugins/woocommerce-blocks/packages/components/panel/style.scss
+++ b/plugins/woocommerce-blocks/packages/components/panel/style.scss
@@ -16,7 +16,6 @@
.wc-block-components-panel__button {
box-sizing: border-box;
height: auto;
- line-height: inherit;
margin-top: em(6px);
padding-right: #{24px + $gap-smaller};
padding-top: em($gap-small - 6px);
diff --git a/plugins/woocommerce/changelog/51386-add-control-address-edit-from-data-store b/plugins/woocommerce/changelog/51386-add-control-address-edit-from-data-store
new file mode 100644
index 00000000000..38a81b13fff
--- /dev/null
+++ b/plugins/woocommerce/changelog/51386-add-control-address-edit-from-data-store
@@ -0,0 +1,4 @@
+Significance: patch
+Type: enhancement
+
+Move address card state management to data stores in Checkout block.
\ No newline at end of file