UNPKG

@bigfishtv/cockpit

Version:

97 lines (88 loc) 3.19 kB
import PropTypes from 'prop-types' import React, { Component } from 'react' import classnames from 'classnames' import PanelToolbar from './PanelToolbar' import Icon from '../../Icon' // we define this because react-docgen fails when defaultProp directly references an imported component const DefaultPanelToolbar = props => <PanelToolbar {...props} /> /** * Wraps children in a panel with PanelToolbar and PanelActions, * can be controlled or uncontrolled in terms of collapsibility etc. */ export default class Panel extends Component { static propTypes = { /** String or react node */ title: PropTypes.node, collapsible: PropTypes.bool, removable: PropTypes.bool, collapsed: PropTypes.bool, /** Callback function for when panel is collapsed / uncollapsed */ onToggleCollapsed: PropTypes.func, onRemove: PropTypes.func, panelClassName: PropTypes.string, /** Whether or not pannel is allowed to control its own collapse state */ uncontrolled: PropTypes.bool, /** React component for panel toolbar */ PanelToolbar: PropTypes.func, /** React component for panel actions */ PanelActions: PropTypes.func, /** React component for panel drawer */ PanelDrawer: PropTypes.func, /** Panel margin, true for default margin-medium otherwise 'xsmall', 'small' etc. */ margin: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), icon: PropTypes.string, } static defaultProps = { collapsible: false, removable: false, collapsed: false, onToggleCollapsed: () => {}, onRemove: () => {}, panelClassName: 'panel', uncontrolled: false, PanelToolbar: DefaultPanelToolbar, } constructor(props) { super() this.state = { collapsed: props.collapsed } } isCollapsed() { return this.props.uncontrolled ? this.state.collapsed : this.props.collapsed } toggleCollapsed() { const collapsed = this.isCollapsed() if (this.props.uncontrolled) { this.setState({ collapsed: !collapsed }) } this.props.onToggleCollapsed(!collapsed) } render() { const collapsed = this.isCollapsed() const { PanelToolbar, PanelActions, PanelDrawer, icon, children, panelClassName, margin, ...props } = this.props const marginClassName = margin === true ? 'margin-medium' : margin ? 'margin-' + margin : '' return ( <div className={classnames(panelClassName, marginClassName)}> {(this.props.collapsible || this.props.title || PanelToolbar != DefaultPanelToolbar) && ( <header className="panel-header"> {icon && <Icon name={icon} className="icon" size={18} />} {this.props.title && ( <h3 className={classnames('panel-title', { truncate: typeof this.props.title !== 'object' })}> {this.props.title} </h3> )} {PanelToolbar && ( <PanelToolbar {...props} collapsed={collapsed} onToggleCollapsed={() => this.toggleCollapsed()} /> )} </header> )} <div className={classnames('panel-content', { hide: collapsed })}>{children}</div> {PanelActions && ( <footer className={classnames('panel-footer', { hide: collapsed })}> <PanelActions {...props} /> </footer> )} {!collapsed && PanelDrawer && <PanelDrawer {...props} />} </div> ) } }