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

Commit 2c26920

Browse files
authored
Expose Validation to 3PD blocks. (#4685)
* introduce useValidation hook * remove the hook return * simplfy validation to avoid infinit setState * remove extra todo
1 parent 21e183b commit 2c26920

File tree

5 files changed

+87
-7
lines changed

5 files changed

+87
-7
lines changed

assets/js/base/context/hooks/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ export * from './use-checkout-notices';
1313
export * from './use-checkout-submit';
1414
export * from './use-emit-response';
1515
export * from './use-checkout-extension-data';
16+
export * from './use-validation';
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { useCallback } from '@wordpress/element';
5+
import type {
6+
ValidationData,
7+
ValidationContextError,
8+
} from '@woocommerce/type-defs/contexts';
9+
10+
/**
11+
* Internal dependencies
12+
*/
13+
import { useValidationContext } from '../providers/validation/';
14+
15+
/**
16+
* Custom hook for setting for adding errors to the validation system.
17+
*/
18+
export const useValidation = (): ValidationData => {
19+
const {
20+
hasValidationErrors,
21+
getValidationError,
22+
clearValidationError,
23+
hideValidationError,
24+
setValidationErrors,
25+
} = useValidationContext();
26+
const prefix = 'extensions-errors';
27+
28+
return {
29+
hasValidationErrors,
30+
getValidationError: useCallback(
31+
( validationErrorId: string ) =>
32+
getValidationError( `${ prefix }-${ validationErrorId }` ),
33+
[ getValidationError ]
34+
),
35+
clearValidationError: useCallback(
36+
( validationErrorId: string ) =>
37+
clearValidationError( `${ prefix }-${ validationErrorId }` ),
38+
[ clearValidationError ]
39+
),
40+
hideValidationError: useCallback(
41+
( validationErrorId: string ) =>
42+
hideValidationError( `${ prefix }-${ validationErrorId }` ),
43+
[ hideValidationError ]
44+
),
45+
setValidationErrors: useCallback(
46+
( errorsObject: Record< string, ValidationContextError > ) =>
47+
setValidationErrors(
48+
Object.fromEntries(
49+
Object.entries(
50+
errorsObject
51+
).map( ( [ validationErrorId, error ] ) => [
52+
`${ prefix }-${ validationErrorId }`,
53+
error,
54+
] )
55+
)
56+
),
57+
[ setValidationErrors ]
58+
),
59+
};
60+
};

assets/js/blocks/cart-checkout/checkout-i2/frontend.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import { Children, cloneElement, isValidElement } from '@wordpress/element';
55
import { getValidBlockAttributes } from '@woocommerce/base-utils';
66
import { useStoreCart } from '@woocommerce/base-context';
7-
import { useCheckoutExtensionData } from '@woocommerce/base-context/hooks';
7+
import {
8+
useCheckoutExtensionData,
9+
useValidation,
10+
} from '@woocommerce/base-context/hooks';
811
import { getRegisteredBlockComponents } from '@woocommerce/blocks-registry';
912
import {
1013
withStoreCartApiHydration,
@@ -38,13 +41,14 @@ const Wrapper = ( {
3841
// eslint-disable-next-line no-unused-vars
3942
const { extensions, receiveCart, ...cart } = useStoreCart();
4043
const checkoutExtensionData = useCheckoutExtensionData();
41-
44+
const validation = useValidation();
4245
return Children.map( children, ( child ) => {
4346
if ( isValidElement( child ) ) {
4447
const componentProps = {
4548
extensions,
4649
cart,
4750
checkoutExtensionData,
51+
validation,
4852
};
4953
return cloneElement( child, componentProps );
5054
}

assets/js/blocks/cart-checkout/checkout-i2/inner-blocks/checkout-terms-block/frontend.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import { __ } from '@wordpress/i18n';
55
import classnames from 'classnames';
66
import { useState, useEffect } from '@wordpress/element';
77
import CheckboxControl from '@woocommerce/base-components/checkbox-control';
8-
import { useValidationContext } from '@woocommerce/base-context';
98
import { useCheckoutSubmit } from '@woocommerce/base-context/hooks';
109
import { withInstanceId } from '@wordpress/compose';
11-
10+
import type { ValidationData } from '@woocommerce/type-defs/contexts';
1211
/**
1312
* Internal dependencies
1413
*/
@@ -19,22 +18,24 @@ const FrontendBlock = ( {
1918
text,
2019
checkbox,
2120
instanceId,
21+
validation,
2222
}: {
2323
text: string;
2424
checkbox: boolean;
2525
instanceId: string;
26+
validation: ValidationData;
2627
} ): JSX.Element => {
2728
const [ checked, setChecked ] = useState( false );
2829

29-
// @todo Checkout i2 - Pass validation context to Inner Blocks to avoid exporting in a public package.
3030
const { isDisabled } = useCheckoutSubmit();
31+
32+
const validationErrorId = 'terms-and-conditions-' + instanceId;
3133
const {
3234
getValidationError,
3335
setValidationErrors,
3436
clearValidationError,
35-
} = useValidationContext();
37+
} = validation;
3638

37-
const validationErrorId = 'terms-and-conditions-' + instanceId;
3839
const error = getValidationError( validationErrorId ) || {};
3940
const hasError = error.message && ! error.hidden;
4041

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export type ValidationContextError = {
2+
message: string;
3+
hidden: boolean;
4+
};
5+
6+
export type ValidationData = {
7+
hasValidationErrors: boolean;
8+
getValidationError: ( validationErrorId: string ) => ValidationContextError;
9+
clearValidationError: ( validationErrorId: string ) => void;
10+
hideValidationError: ( validationErrorId: string ) => void;
11+
setValidationErrors: (
12+
errors: Record< string, ValidationContextError >
13+
) => void;
14+
};

0 commit comments

Comments
 (0)