All files / Validation Validation.tsx

93.75% Statements 15/16
100% Branches 7/7
50% Functions 1/2
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105            176x   176x         176x 176x 176x         176x 176x                           176x 14x   14x         14x                                                           176x 176x               176x                                     176x      
import React from 'react';
import PropTypes from 'react-peek/prop-types';
import { lucidClassNames } from '../../util/style-helpers';
import { getFirst, omitProps, StandardProps } from '../../util/component-types';
import _ from 'lodash';
 
const cx = lucidClassNames.bind('&-Validation');
 
const { string, any } = PropTypes;
 
interface IValidationErrorProps extends StandardProps {
	description?: string;
}
const ValidationError = (_props: IValidationErrorProps): null => null;
ValidationError.displayName = 'Validation.Error';
ValidationError.peek = {
	description: `
		Content that will be displayed as an error message.
	`,
};
ValidationError.propName = 'Error';
ValidationError.propTypes = {
	description: string,
	children: any,
};
 
export interface IValidationProps
	extends StandardProps,
		React.DetailedHTMLProps<
			React.HTMLAttributes<HTMLDivElement>,
			HTMLDivElement
		> {
	Error?: React.ReactNode;
}
 
export const Validation = (props: IValidationProps): React.ReactElement => {
	const { className, children, ...passThroughs } = props;
 
	const errorChildProps = _.get(
		getFirst<IValidationErrorProps>(props, Validation.Error),
		'props'
	);
 
	return (
		<div
			{...omitProps<IValidationProps>(
				passThroughs,
				undefined,
				_.keys(Validation.propTypes)
			)}
			className={cx(
				'&',
				{
					'&-is-error': errorChildProps && errorChildProps.children,
				},
				className
			)}
		>
			{children}
			{errorChildProps &&
			errorChildProps.children &&
			errorChildProps.children !== true ? (
				<div
					{...omitProps<IValidationProps>(errorChildProps, undefined)}
					className={cx('&-error-content', errorChildProps.className)}
				>
					{errorChildProps.children}
				</div>
			) : null}
		</div>
	);
};
 
Validation.displayName = 'Validation';
Validation.peek = {
	description: `
		Validation is a wrapper component that's meant to be used by other
		components. Wrap your form components in it and style them accordingly
		if there's an error.
	`,
	categories: ['helpers'],
};
Validation.propTypes = {
	Error: any`
		In most cases this will be a string, but it also accepts any valid React
		element. If this is a falsey value, then no error message will be
		displayed.  If this is the literal \`true\`, it will add the
		\`-is-error\` class to the wrapper div, but not render the
		\`-error-content\` \`div\`.
	`,
 
	className: string`
		Classes that are appended to the component defaults. This prop is run
		through the \`classnames\` library.
	`,
 
	children: any.isRequired`
		Any valid React children.
	`,
};
 
Validation.Error = ValidationError;
 
export default Validation;