Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Fix address block invalidations in the editor and address card displa…
Browse files Browse the repository at this point in the history
…y in Firefox (#11714)

* Add checks to see if getCartData finished before rendering address

* Prevent block error due to excessive updates of customValidation

* Do not condense address in admin and handle phone field

* Add missing showPhoneField for billing

---------

Co-authored-by: Thomas Roberts <[email protected]>
  • Loading branch information
2 people authored and tarhi-saad committed Nov 9, 2023
1 parent 207660f commit 2cc0ae0
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
ShippingStateInput,
} from '@woocommerce/base-components/state-input';
import { useEffect, useMemo, useRef } from '@wordpress/element';
import { withInstanceId } from '@wordpress/compose';
import { useInstanceId } from '@wordpress/compose';
import { useShallowEqual } from '@woocommerce/base-hooks';
import { defaultAddressFields } from '@woocommerce/settings';
import isShallowEqual from '@wordpress/is-shallow-equal';
Expand Down Expand Up @@ -44,11 +44,12 @@ const AddressForm = ( {
id = '',
fields = defaultFields,
fieldConfig = {} as FieldConfig,
instanceId,
onChange,
type = 'shipping',
values,
}: AddressFormProps ): JSX.Element => {
const instanceId = useInstanceId( AddressForm );

// Track incoming props.
const currentFields = useShallowEqual( fields );
const currentFieldConfig = useShallowEqual( fieldConfig );
Expand Down Expand Up @@ -99,7 +100,7 @@ const AddressForm = ( {
fieldsRef.current?.postcode?.revalidate();
}, [ currentCountry ] );

id = id || instanceId;
id = id || `${ instanceId }`;

return (
<div id={ id } className="wc-block-components-address-form">
Expand Down Expand Up @@ -206,4 +207,4 @@ const AddressForm = ( {
);
};

export default withInstanceId( AddressForm );
export default AddressForm;
2 changes: 0 additions & 2 deletions assets/js/base/components/cart-checkout/address-form/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export type AddressFormFields = {
export interface AddressFormProps {
// Id for component.
id?: string;
// Unique id for form.
instanceId: string;
// Type of form (billing or shipping).
type?: AddressType;
// Array of fields in form.
Expand Down
4 changes: 3 additions & 1 deletion assets/js/blocks/checkout/address-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ const AddressCard = ( {
address,
onEdit,
target,
showPhoneField,
}: {
address: CartShippingAddress | CartBillingAddress;
onEdit: () => void;
target: string;
showPhoneField: boolean;
} ): JSX.Element | null => {
return (
<div className="wc-block-components-address-card">
Expand All @@ -44,7 +46,7 @@ const AddressCard = ( {
<span key={ `address-` + index }>{ field }</span>
) ) }
</div>
{ address.phone ? (
{ address.phone && showPhoneField ? (
<div
key={ `address-phone` }
className="wc-block-components-address-card__address-section"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import type {
AddressFields,
} from '@woocommerce/settings';
import { StoreNoticesContainer } from '@woocommerce/blocks-checkout';
import { useSelect } from '@wordpress/data';
import { CART_STORE_KEY } from '@woocommerce/block-data';

/**
* Internal dependencies
Expand Down Expand Up @@ -81,16 +83,24 @@ const Block = ( {
? [ noticeContexts.BILLING_ADDRESS, noticeContexts.SHIPPING_ADDRESS ]
: [ noticeContexts.BILLING_ADDRESS ];

const { cartDataLoaded } = useSelect( ( select ) => {
const store = select( CART_STORE_KEY );
return {
cartDataLoaded: store.hasFinishedResolution( 'getCartData' ),
};
} );
return (
<>
<StoreNoticesContainer context={ noticeContext } />
<WrapperComponent>
<CustomerAddress
addressFieldsConfig={ addressFieldsConfig }
showPhoneField={ showPhoneField }
requirePhoneField={ requirePhoneField }
forceEditing={ forceEditing }
/>
{ cartDataLoaded ? (
<CustomerAddress
addressFieldsConfig={ addressFieldsConfig }
showPhoneField={ showPhoneField }
requirePhoneField={ requirePhoneField }
forceEditing={ forceEditing }
/>
) : null }
</WrapperComponent>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ const CustomerAddress = ( {
onEdit={ () => {
setEditing( true );
} }
showPhoneField={ showPhoneField }
/>
),
[ billingAddress ]
[ billingAddress, showPhoneField ]
);

const renderAddressFormComponent = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import type {
AddressField,
AddressFields,
} from '@woocommerce/settings';
import { useSelect } from '@wordpress/data';
import { CART_STORE_KEY } from '@woocommerce/block-data';

/**
* Internal dependencies
Expand Down Expand Up @@ -96,15 +98,24 @@ const Block = ( {
( shippingAddress.first_name || shippingAddress.last_name )
);

const { cartDataLoaded } = useSelect( ( select ) => {
const store = select( CART_STORE_KEY );
return {
cartDataLoaded: store.hasFinishedResolution( 'getCartData' ),
};
} );

return (
<>
<StoreNoticesContainer context={ noticeContext } />
<WrapperComponent>
<CustomerAddress
addressFieldsConfig={ addressFieldsConfig }
showPhoneField={ showPhoneField }
requirePhoneField={ requirePhoneField }
/>
{ cartDataLoaded ? (
<CustomerAddress
addressFieldsConfig={ addressFieldsConfig }
showPhoneField={ showPhoneField }
requirePhoneField={ requirePhoneField }
/>
) : null }
</WrapperComponent>
{ hasAddress && (
<CheckboxControl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
*/
import { useState, useCallback, useEffect } from '@wordpress/element';
import { AddressForm } from '@woocommerce/base-components/cart-checkout';
import { useCheckoutAddress, useStoreEvents } from '@woocommerce/base-context';
import {
useCheckoutAddress,
useStoreEvents,
useEditorContext,
} from '@woocommerce/base-context';
import type {
ShippingAddress,
AddressField,
Expand Down Expand Up @@ -38,11 +42,12 @@ const CustomerAddress = ( {
useShippingAsBilling,
} = useCheckoutAddress();
const { dispatchCheckoutEvent } = useStoreEvents();
const { isEditor } = useEditorContext();
const hasAddress = !! (
shippingAddress.address_1 &&
( shippingAddress.first_name || shippingAddress.last_name )
);
const [ editing, setEditing ] = useState( ! hasAddress );
const [ editing, setEditing ] = useState( ! hasAddress || isEditor );

// Forces editing state if store has errors.
const { hasValidationErrors, invalidProps } = useSelect( ( select ) => {
Expand Down Expand Up @@ -103,9 +108,10 @@ const CustomerAddress = ( {
onEdit={ () => {
setEditing( true );
} }
showPhoneField={ showPhoneField }
/>
),
[ shippingAddress ]
[ shippingAddress, showPhoneField ]
);

const renderAddressFormComponent = useCallback(
Expand Down Expand Up @@ -147,9 +153,11 @@ const CustomerAddress = ( {
dispatchCheckoutEvent,
onChangeAddress,
requirePhoneField,
setBillingPhone,
setShippingPhone,
shippingAddress,
showPhoneField,
useShippingAsBilling,
]
);

Expand Down
2 changes: 2 additions & 0 deletions packages/checkout/components/text-input/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export interface ValidatedTextInputProps
label?: string | undefined;
// Field value.
value: string;
// Other sibling fields that should be validated together.
values: string[];
// If true, validation errors will be shown.
showError?: boolean;
// Error message to display alongside the field regardless of validation.
Expand Down
25 changes: 14 additions & 11 deletions packages/checkout/components/text-input/validated-text-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const ValidatedTextInput = forwardRef<
customFormatter = ( newValue: string ) => newValue,
label,
validateOnMount = true,
instanceId: preferredInstanceId,
instanceId: preferredInstanceId = '',
...rest
},
forwardedRef
Expand Down Expand Up @@ -80,6 +80,14 @@ const ValidatedTextInput = forwardRef<
clearValidationError,
} = useDispatch( VALIDATION_STORE_KEY );

// Ref for validation callback.
const customValidationRef = useRef( customValidation );

// Update ref when validation callback changes.
useEffect( () => {
customValidationRef.current = customValidation;
}, [ customValidation ] );

const { validationError, validationErrorId } = useSelect(
( select ) => {
const store = select( VALIDATION_STORE_KEY );
Expand All @@ -105,7 +113,7 @@ const ValidatedTextInput = forwardRef<

if (
inputObject.checkValidity() &&
customValidation( inputObject )
customValidationRef.current( inputObject )
) {
clearValidationError( errorIdString );
return;
Expand All @@ -120,13 +128,7 @@ const ValidatedTextInput = forwardRef<
},
} );
},
[
clearValidationError,
customValidation,
errorIdString,
setValidationErrors,
label,
]
[ clearValidationError, errorIdString, setValidationErrors, label ]
);

// Allows parent to trigger revalidation.
Expand Down Expand Up @@ -184,6 +186,9 @@ const ValidatedTextInput = forwardRef<
if ( ! isPristine ) {
return;
}

setIsPristine( false );

if ( focusOnMount ) {
inputRef.current?.focus();
}
Expand All @@ -192,8 +197,6 @@ const ValidatedTextInput = forwardRef<
if ( validateOnMount || ! focusOnMount ) {
validateInput( true );
}

setIsPristine( false );
}, [
validateOnMount,
focusOnMount,
Expand Down

0 comments on commit 2cc0ae0

Please sign in to comment.