woocommerce/plugins/woocommerce-blocks/assets/js/base/context/providers/validation/context.js

258 lines
6.5 KiB
JavaScript
Raw Normal View History

Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
/**
* External dependencies
*/
import {
createContext,
useCallback,
useContext,
useState,
} from '@wordpress/element';
import { pickBy } from 'lodash';
import isShallowEqual from '@wordpress/is-shallow-equal';
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
/**
* @typedef { import('@woocommerce/type-defs/contexts').ValidationContext } ValidationContext
* @typedef {import('react')} React
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
*/
const ValidationContext = createContext( {
getValidationError: () => '',
setValidationErrors: ( errors ) => void errors,
clearValidationError: ( property ) => void property,
clearAllValidationErrors: () => void null,
hideValidationError: () => void null,
showValidationError: () => void null,
showAllValidationErrors: () => void null,
hasValidationErrors: false,
getValidationErrorId: ( errorId ) => errorId,
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
} );
/**
* @return {ValidationContext} The context values for the validation context.
*/
export const useValidationContext = () => {
return useContext( ValidationContext );
};
/**
* Validation context provider
*
* Any children of this context will be exposed to validation state and helpers
* for tracking validation.
*
* @param {Object} props Incoming props for the component.
* @param {React.ReactChildren} props.children What react elements are wrapped by this component.
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
*/
export const ValidationContextProvider = ( { children } ) => {
const [ validationErrors, updateValidationErrors ] = useState( {} );
/**
* This retrieves any validation error message that exists in state for the
* given property name.
*
* @param {string} property The property the error message is for.
*
* @return {Object} The error object for the given property.
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
*/
const getValidationError = useCallback(
( property ) => validationErrors[ property ],
[ validationErrors ]
);
/**
* Provides an id for the validation error that can be used to fill out
* aria-describedby attribute values.
*
* @param {string} errorId The input css id the validation error is related
* to.
* @return {string} The id to use for the validation error container.
*/
const getValidationErrorId = useCallback(
( errorId ) => {
const error = validationErrors[ errorId ];
if ( ! error || error.hidden ) {
return '';
}
return `validate-error-${ errorId }`;
},
[ validationErrors ]
);
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
/**
* Clears any validation error that exists in state for the given property
* name.
*
* @param {string} property The name of the property to clear if exists in
* validation error state.
*/
const clearValidationError = useCallback(
/**
* Callback that is memoized.
*
* @param {string} property
*/
( property ) => {
updateValidationErrors(
/**
* Callback for validation Errors handling.
*
* @param {Object} prevErrors
*/
( prevErrors ) => {
if ( ! prevErrors[ property ] ) {
return prevErrors;
}
const {
// eslint-disable-next-line no-unused-vars -- this is intentional to omit the dynamic property from the returned object.
[ property ]: clearedProperty,
...newErrors
} = prevErrors;
return newErrors;
}
);
},
[]
);
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
/**
* Clears the entire validation error state.
*/
const clearAllValidationErrors = useCallback(
() => void updateValidationErrors( {} ),
[]
);
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
/**
* Used to record new validation errors in the state.
*
* @param {Object} newErrors An object where keys are the property names the
* validation error is for and values are the
* validation error message displayed to the user.
*/
const setValidationErrors = useCallback( ( newErrors ) => {
if ( ! newErrors ) {
return;
}
updateValidationErrors( ( prevErrors ) => {
newErrors = pickBy( newErrors, ( error, property ) => {
if ( typeof error.message !== 'string' ) {
return false;
}
if ( prevErrors.hasOwnProperty( property ) ) {
return ! isShallowEqual( prevErrors[ property ], error );
}
return true;
} );
if ( Object.values( newErrors ).length === 0 ) {
return prevErrors;
}
return {
...prevErrors,
...newErrors,
};
} );
}, [] );
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
/**
* Used to update a validation error.
*
* @param {string} property The name of the property to update.
* @param {Object} newError New validation error object.
*/
const updateValidationError = useCallback( ( property, newError ) => {
updateValidationErrors( ( prevErrors ) => {
if ( ! prevErrors.hasOwnProperty( property ) ) {
return prevErrors;
}
const updatedError = {
...prevErrors[ property ],
...newError,
};
return isShallowEqual( prevErrors[ property ], updatedError )
? prevErrors
: {
...prevErrors,
[ property ]: updatedError,
};
} );
}, [] );
/**
* Given a property name and if an associated error exists, it sets its
* `hidden` value to true.
*
* @param {string} property The name of the property to set the `hidden`
* value to true.
*/
const hideValidationError = useCallback(
( property ) =>
void updateValidationError( property, {
hidden: true,
} ),
[ updateValidationError ]
);
/**
* Given a property name and if an associated error exists, it sets its
* `hidden` value to false.
*
* @param {string} property The name of the property to set the `hidden`
* value to false.
*/
const showValidationError = useCallback(
( property ) =>
void updateValidationError( property, {
hidden: false,
} ),
[ updateValidationError ]
);
/**
* Sets the `hidden` value of all errors to `false`.
*/
const showAllValidationErrors = useCallback(
() =>
void updateValidationErrors( ( prevErrors ) => {
const updatedErrors = {};
Object.keys( prevErrors ).forEach( ( property ) => {
if ( prevErrors[ property ].hidden ) {
updatedErrors[ property ] = {
...prevErrors[ property ],
hidden: false,
};
}
} );
if ( Object.values( updatedErrors ).length === 0 ) {
return prevErrors;
}
return {
...prevErrors,
...updatedErrors,
};
} ),
[]
);
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
const context = {
getValidationError,
setValidationErrors,
clearValidationError,
clearAllValidationErrors,
hideValidationError,
showValidationError,
showAllValidationErrors,
hasValidationErrors: Object.keys( validationErrors ).length > 0,
getValidationErrorId,
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
};
Add validation context provider and implement validation for shipping country and coupons. (https://github.com/woocommerce/woocommerce-blocks/pull/1972) * add errormessage handling to countryinput (along with storybook) * add types for react * Add validation context and implement * implement validation context for country field validation * tweak ValidationInputError so that it can receive property name for getting error from * improve storybook webpack config to pull from tsconfig.json * update storybook story to cover changes with context * Wrap Checkout Provider with Validation Context Provider * add screen-reader-text style to storybook * add styles for input error validation to text input * improve styling for ValidationInputError component * add validation error handling to TotalsCouponCode component And story * make sure errors are cleared on successful receive/remove item * dispatch loading cancellation on catching errors This is needed because loading would be cancelled before the error is thrown so any error handling after the thrown error will not be able to rely on loading. * implement validation setting for coupon errors * add error color to labels on inputs too * fix borders back and force border color * remove extra structure and improve validation error with alignment for coupon code * add aria-describedby for text inputs * add back in validation context provider to fix rebase issue * rework validation so it works for both checkout and cart * Some styling tweaks * more style fixes * remove unnecessary method * make sure new function is included in context defaults * package.lock update? seems harmless so rolling with it.
2020-03-17 11:45:33 +00:00
return (
<ValidationContext.Provider value={ context }>
{ children }
</ValidationContext.Provider>
);
};