All files / components/EmptyStateWrapper EmptyStateWrapper.jsx

100% Statements 7/7
100% Branches 4/4
100% Functions 0/0
100% Lines 7/7
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 122 123 124 125 126 127                  134x   134x                 134x                                                                                                                       16x   16x       16x           16x                                                                    
import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { createClass, getFirst, omitProps } from '../../util/component-types';
import { lucidClassNames } from '../../util/style-helpers';
 
import LoadingIndicator from '../LoadingIndicator/LoadingIndicator';
import OverlayWrapper from '../OverlayWrapper/OverlayWrapper';
 
const cx = lucidClassNames.bind('&-EmptyStateWrapper');
 
const { any, bool, node, string } = PropTypes;
 
/**
 *
 * {"categories": ["utility"], "madeFrom": ["LoadingIndicator", "OverlayWrapper"]}
 *
 * A wrapper which can display either a `LoadingIndicator` or `OverlayWrapper`.
 *
 */
const EmptyStateWrapper = createClass({
	_isPrivate: true,
 
	displayName: 'EmptyStateWrapper',
 
	propTypes: {
		/**
		 * Class names that are appended to the defaults.
		 */
		className: string,
		/**
		 * Any valid React children.
		 */
		children: node,
		/**
		 * Controls the visibility of the `EmptyMessage`
		 */
		isEmpty: bool,
		/**
		 * Controls the visibility of the `LoadingMessage`.
		 */
		isLoading: bool,
		/**
		 * *Child Element*
		 *
		 * The element to display in the body of the overlay.
		 */
		Body: any,
		/**
		 * *Child Element*
		 *
		 * The element to display in the title of the overlay.
		 */
		Title: any,
	},
 
	components: {
		/**
		 * Body content for the message to display when there is no data.
		 */
		Body: createClass({
			displayName: 'EmptyStateWrapper.Body',
			propName: 'Body',
		}),
		/**
		 * Title text for the message to display when there is no data.
		 */
		Title: createClass({
			displayName: 'EmptyStateWrapper.Title',
			propName: 'Title',
		}),
	},
 
	render() {
		const {
			children,
			className,
			isEmpty,
			isLoading,
			...passThroughs
		} = this.props;
 
		const emptyMessageBodyProp = _.get(
			getFirst(this.props, EmptyStateWrapper.Body),
			'props'
		);
		const emptyMessageTitleProp = _.get(
			getFirst(this.props, EmptyStateWrapper.Title),
			'props',
			{ children: 'You have no data.' }
		);
 
		return isLoading
			? <LoadingIndicator
					className={cx('&', className)}
					isLoading
					{...omitProps(passThroughs, EmptyStateWrapper, [], false)}
				>
					{children}
				</LoadingIndicator>
			: <OverlayWrapper
					className={cx('&', className)}
					hasOverlay={false}
					isVisible={isEmpty}
					{...omitProps(passThroughs, EmptyStateWrapper, [], false)}
				>
					<OverlayWrapper.Message className={cx('&-message-container')}>
						<div className={cx('&-message-header')} />
						<div className={cx('&-message-contents')}>
							<header
								{...emptyMessageTitleProp}
								className={cx(
									'&-message-title',
									emptyMessageTitleProp.className
								)}
							/>
							{emptyMessageBodyProp && <div {...emptyMessageBodyProp} />}
						</div>
					</OverlayWrapper.Message>
 
					{children}
				</OverlayWrapper>;
	},
});
 
export default EmptyStateWrapper;