All files / components/Panel Panel.jsx

100% Statements 8/8
100% Branches 4/4
100% Functions 1/1
100% Lines 8/8
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          120x             120x             120x                                                                                                         120x                           36x   36x 36x   36x                                                                
import _ from 'lodash';
import React from 'react';
import { lucidClassNames } from '../../util/style-helpers';
import { createClass, findTypes, omitProps } from '../../util/component-types';
 
const cx = lucidClassNames.bind('&-Panel');
 
const {
	bool,
	node,
	object,
	string,
} = React.PropTypes;
 
/**
 * {"categories": ["layout"]}
 *
 * Panel is used to wrap content to better organize elements in window.
 */
const Panel = createClass({
	displayName: 'Panel',
 
	components: {
		/**
		 * Content displayed at the top of the panel.
		 */
		Header: createClass({
			displayName: 'Panel.Header',
			propName: 'Header',
		}),
		/**
		 * Content displayed at the bottom of the panel.
		 */
		Footer: createClass({
			displayName: 'Panel.Footer',
			propName: 'Footer',
		}),
	},
 
	propTypes: {
		/**
		 * Appended to the component-specific class names set on the root element.
		 */
		className: string,
		/**
		 * *Child Element* - Header contents. Only one `Header` is used.
		 */
		Header: node,
		/**
		 * *Child Element* - Footer contents. Only one `Footer` is used.
		 */
		Footer: node,
		/**
		 * Generally you should only have a single child element so the centering
		 * works correctly.
		 */
		children: node,
		/**
		 * If set to true, creates a content section with no padding.
		 */
		isGutterless: bool,
		/**
		 * If set to false, removes margin around the Panel
		 */
		hasMargin: bool,
		/**
		 * Styles that are passed through to root element.
		 */
		style: object,
	},
 
	getDefaultProps() {
		return {
			isGutterless: false,
			hasMargin: true,
		};
	},
 
	render: function() {
		const {
			children,
			className,
			isGutterless,
			hasMargin,
			style,
			...passThroughs,
		} = this.props;
 
		const headerChildProp = _.first(_.map(findTypes(this.props, Panel.Header), 'props'));
		const footerChildProp = _.first(_.map(findTypes(this.props, Panel.Footer), 'props'));
 
		return (
			<div
				{...omitProps(passThroughs, Panel)}
				className={cx('&', className, {
					'&-is-not-gutterless': !isGutterless,
					'&-has-margin': hasMargin,
				})}
				style={style}
			>
				{headerChildProp ? (
					<header
						{...headerChildProp}
						className={cx('&-Header', headerChildProp.className)}
					/>
				) : null}
 
				<section className={cx('&-content')} >
					{children}
				</section>
 
				{footerChildProp ? (
					<footer
						{...footerChildProp}
						className={cx('&-Footer', footerChildProp.className)}
					/>
				) : null}
			</div>
		)
	},
})
 
export default Panel;