Files
flipper/src/ui/components/Panel.js
Daniel Büchele fbbf8cf16b Initial commit 🎉
fbshipit-source-id: b6fc29740c6875d2e78953b8a7123890a67930f2
Co-authored-by: Sebastian McKenzie <sebmck@fb.com>
Co-authored-by: John Knox <jknox@fb.com>
Co-authored-by: Emil Sjölander <emilsj@fb.com>
Co-authored-by: Pritesh Nandgaonkar <prit91@fb.com>
2018-06-01 11:03:58 +01:00

180 lines
4.2 KiB
JavaScript

/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import FlexColumn from './FlexColumn.js';
import styled from '../styled/index.js';
import FlexBox from './FlexBox.js';
import {colors} from './colors.js';
import Glyph from './Glyph.js';
const BORDER = '1px solid #dddfe2';
const ignoreAttributes = ['floating', 'padded'];
const Chevron = Glyph.extends({
marginRight: 4,
marginLeft: -2,
marginBottom: 1,
});
/**
* A Panel component.
*/
export default class Panel extends styled.StylableComponent<
{|
/**
* Class name to customise styling.
*/
className?: string,
/**
* Whether this panel is floating from the rest of the UI. ie. if it has
* margin and a border.
*/
floating?: boolean,
/**
* Whether the panel takes up all the space it can. Equivalent to the following CSS:
*
* height: 100%;
* width: 100%;
*/
fill?: boolean,
/**
* Heading for this panel. If this is anything other than a string then no
* padding is applied to the heading.
*/
heading: React$Node,
/**
* Contents of the panel.
*/
children?: React$Node,
/**
* Whether the panel header and body have padding.
*/
padded?: boolean,
/**
* Whether the panel can be collapsed. Defaults to true
*/
collapsable: boolean,
/**
* Initial state for panel if it is collapsable
*/
collapsed?: boolean,
/**
* Heading for this panel. If this is anything other than a string then no
* padding is applied to the heading.
*/
accessory?: React$Node,
|},
{
collapsed: boolean,
},
> {
static defaultProps: {|
floating: boolean,
fill: boolean,
collapsable: boolean,
|} = {
fill: false,
floating: true,
collapsable: true,
};
static PanelContainer = FlexColumn.extends(
{
flexShrink: 0,
padding: props => (props.floating ? 10 : 0),
borderBottom: props => (props.collapsed ? 'none' : BORDER),
},
{ignoreAttributes: ['collapsed', ...ignoreAttributes]},
);
static PanelHeader = FlexBox.extends(
{
backgroundColor: '#f6f7f9',
border: props => (props.floating ? BORDER : 'none'),
borderBottom: BORDER,
borderTopLeftRadius: 2,
borderTopRightRadius: 2,
justifyContent: 'space-between',
lineHeight: '27px',
fontWeight: 500,
flexShrink: 0,
padding: props => (props.padded ? '0 10px' : 0),
'&:not(:first-child)': {
borderTop: BORDER,
},
},
{ignoreAttributes},
);
static PanelBody = FlexColumn.extends(
{
backgroundColor: '#fff',
border: props => (props.floating ? BORDER : 'none'),
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
borderTop: 'none',
flexGrow: 1,
padding: props => (props.padded ? 10 : 0),
},
{ignoreAttributes},
);
state = {
collapsed: this.props.collapsed == null ? false : this.props.collapsed,
};
onClick = () => this.setState({collapsed: !this.state.collapsed});
render() {
const {
padded,
children,
className,
fill,
floating,
heading,
collapsable,
accessory,
} = this.props;
const {collapsed} = this.state;
return (
<Panel.PanelContainer
className={className}
floating={floating}
fill={fill}
collapsed={collapsed}>
<Panel.PanelHeader
floating={floating}
padded={typeof heading === 'string'}
onClick={this.onClick}>
<span>
{collapsable && (
<Chevron
color={colors.macOSTitleBarIcon}
name={collapsed ? 'triangle-right' : 'triangle-down'}
size={12}
/>
)}
{heading}
</span>
{accessory}
</Panel.PanelHeader>
{children == null || (collapsable && collapsed) ? null : (
<Panel.PanelBody
fill={fill}
padded={padded == null ? true : padded}
floating={floating}>
{children}
</Panel.PanelBody>
)}
</Panel.PanelContainer>
);
}
}