* introduce useValidation hook

* remove the hook return

* simplfy validation to avoid infinit setState

* remove extra todo
This commit is contained in:
Seghir Nadir 2021-09-09 16:35:53 +01:00 committed by GitHub
parent 13c5377064
commit 148cb91a1e
5 changed files with 87 additions and 7 deletions

View File

@ -13,3 +13,4 @@ export * from './use-checkout-notices';
export * from './use-checkout-submit';
export * from './use-emit-response';
export * from './use-checkout-extension-data';
export * from './use-validation';

View File

@ -0,0 +1,60 @@
/**
* External dependencies
*/
import { useCallback } from '@wordpress/element';
import type {
ValidationData,
ValidationContextError,
} from '@woocommerce/type-defs/contexts';
/**
* Internal dependencies
*/
import { useValidationContext } from '../providers/validation/';
/**
* Custom hook for setting for adding errors to the validation system.
*/
export const useValidation = (): ValidationData => {
const {
hasValidationErrors,
getValidationError,
clearValidationError,
hideValidationError,
setValidationErrors,
} = useValidationContext();
const prefix = 'extensions-errors';
return {
hasValidationErrors,
getValidationError: useCallback(
( validationErrorId: string ) =>
getValidationError( `${ prefix }-${ validationErrorId }` ),
[ getValidationError ]
),
clearValidationError: useCallback(
( validationErrorId: string ) =>
clearValidationError( `${ prefix }-${ validationErrorId }` ),
[ clearValidationError ]
),
hideValidationError: useCallback(
( validationErrorId: string ) =>
hideValidationError( `${ prefix }-${ validationErrorId }` ),
[ hideValidationError ]
),
setValidationErrors: useCallback(
( errorsObject: Record< string, ValidationContextError > ) =>
setValidationErrors(
Object.fromEntries(
Object.entries(
errorsObject
).map( ( [ validationErrorId, error ] ) => [
`${ prefix }-${ validationErrorId }`,
error,
] )
)
),
[ setValidationErrors ]
),
};
};

View File

@ -4,7 +4,10 @@
import { Children, cloneElement, isValidElement } from '@wordpress/element';
import { getValidBlockAttributes } from '@woocommerce/base-utils';
import { useStoreCart } from '@woocommerce/base-context';
import { useCheckoutExtensionData } from '@woocommerce/base-context/hooks';
import {
useCheckoutExtensionData,
useValidation,
} from '@woocommerce/base-context/hooks';
import { getRegisteredBlockComponents } from '@woocommerce/blocks-registry';
import {
withStoreCartApiHydration,
@ -38,13 +41,14 @@ const Wrapper = ( {
// eslint-disable-next-line no-unused-vars
const { extensions, receiveCart, ...cart } = useStoreCart();
const checkoutExtensionData = useCheckoutExtensionData();
const validation = useValidation();
return Children.map( children, ( child ) => {
if ( isValidElement( child ) ) {
const componentProps = {
extensions,
cart,
checkoutExtensionData,
validation,
};
return cloneElement( child, componentProps );
}

View File

@ -5,10 +5,9 @@ import { __ } from '@wordpress/i18n';
import classnames from 'classnames';
import { useState, useEffect } from '@wordpress/element';
import CheckboxControl from '@woocommerce/base-components/checkbox-control';
import { useValidationContext } from '@woocommerce/base-context';
import { useCheckoutSubmit } from '@woocommerce/base-context/hooks';
import { withInstanceId } from '@wordpress/compose';
import type { ValidationData } from '@woocommerce/type-defs/contexts';
/**
* Internal dependencies
*/
@ -19,22 +18,24 @@ const FrontendBlock = ( {
text,
checkbox,
instanceId,
validation,
}: {
text: string;
checkbox: boolean;
instanceId: string;
validation: ValidationData;
} ): JSX.Element => {
const [ checked, setChecked ] = useState( false );
// @todo Checkout i2 - Pass validation context to Inner Blocks to avoid exporting in a public package.
const { isDisabled } = useCheckoutSubmit();
const validationErrorId = 'terms-and-conditions-' + instanceId;
const {
getValidationError,
setValidationErrors,
clearValidationError,
} = useValidationContext();
} = validation;
const validationErrorId = 'terms-and-conditions-' + instanceId;
const error = getValidationError( validationErrorId ) || {};
const hasError = error.message && ! error.hidden;

View File

@ -0,0 +1,14 @@
export type ValidationContextError = {
message: string;
hidden: boolean;
};
export type ValidationData = {
hasValidationErrors: boolean;
getValidationError: ( validationErrorId: string ) => ValidationContextError;
clearValidationError: ( validationErrorId: string ) => void;
hideValidationError: ( validationErrorId: string ) => void;
setValidationErrors: (
errors: Record< string, ValidationContextError >
) => void;
};