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            120x             120x                 120x                                                                                                 120x                                 21x   21x   21x 21x   21x                                                  
import React from 'react';
import _ from 'lodash';
import { lucidClassNames } from '../../util/style-helpers';
import { createClass, getFirst, rejectTypes, omitProps } from '../../util/component-types';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
 
const cx = lucidClassNames.bind('&-OverlayWrapper');
 
const {
	bool,
	node,
	oneOf,
	string,
} = React.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}
				<ReactCSSTransitionGroup
					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>)}
				</ReactCSSTransitionGroup>
			</div>
		);
	},
});
 
export default OverlayWrapper;