All files / components/OverlayWrapper OverlayWrapper.jsx

100% Statements 9/9
100% Branches 4/4
100% Functions 0/0
100% Lines 9/9
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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121                        134x   134x                 134x                                                                                           268x                                 21x   21x   21x 21x   21x                                                      
import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { lucidClassNames } from '../../util/style-helpers';
import {
	createClass,
	getFirst,
	rejectTypes,
	omitProps,
} from '../../util/component-types';
import ReactTransitionGroup from 'react-transition-group/CSSTransitionGroup';
 
const cx = lucidClassNames.bind('&-OverlayWrapper');
 
const { bool, node, oneOf, string } = PropTypes;
 
/**
 *
 * {"categories": ["utility"]}
 *
 * A wrapper with optional overlay to wrap content. `Overlay` is meant for overlaying an entire page, while this component is meant to wrap another component and cover its content.
 *
 */
const OverlayWrapper = createClass({
	displayName: 'OverlayWrapper',
	propTypes: {
		/**
		 * Controls whether the message should be displayed over the wrapped content.
		 */
		isVisible: bool,
		/**
		 * Set this to `false` if you don't want the semi-transparent overlay over
		 * the wrapped content.
		 */
		hasOverlay: bool,
		/**
		 * Class names that are appended to the defaults.
		 */
		className: string,
		/**
		 * Any valid React children.
		 */
		children: node,
		/**
		 * Style variations for the overlay behind the message.
		 */
		overlayKind: oneOf(['light', 'dark']),
		/**
		 * *Child Element*
		 *
		 * The Message to display in the overlay.
		 */
		Message: node,
	},
 
	components: {
		Message: createClass({
			displayName: 'OverlayWrapper.Message',
			propName: 'Message',
			propTypes: {
				/**
				 * Any valid React children.
				 */
				children: node,
			},
		}),
	},
 
	getDefaultProps() {
		return {
			hasOverlay: true,
			overlayKind: 'light',
		};
	},
 
	render() {
		const {
			props,
			props: {
				hasOverlay,
				isVisible,
				className,
				children,
				overlayKind,
				...passThroughs
			},
		} = this;
 
		const { Message } = OverlayWrapper;
 
		const messageElementProp = _.get(getFirst(props, Message), 'props', {});
		const otherChildren = rejectTypes(children, [Message]);
 
		return (
			<div
				{...omitProps(passThroughs, OverlayWrapper)}
				className={cx('&', className)}
			>
				{otherChildren}
				<ReactTransitionGroup
					transitionName={cx('&-message-container')}
					transitionEnterTimeout={300}
					transitionLeaveTimeout={300}
				>
					{isVisible &&
						<div
							className={cx('&-message-container', {
								'&-has-overlay': hasOverlay,
								'&-kind-light': hasOverlay && overlayKind === 'light',
							})}
						>
							<div {...messageElementProp} />
						</div>}
				</ReactTransitionGroup>
			</div>
		);
	},
});
 
export default OverlayWrapper;