Expose Validation to 3PD blocks. (https://github.com/woocommerce/woocommerce-blocks/pull/4685)
* introduce useValidation hook * remove the hook return * simplfy validation to avoid infinit setState * remove extra todo
This commit is contained in:
parent
13c5377064
commit
148cb91a1e
|
@ -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';
|
||||
|
|
|
@ -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 ]
|
||||
),
|
||||
};
|
||||
};
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
Loading…
Reference in New Issue