Panel
Summary: _typescript_ Reviewed By: priteshrnandgaonkar Differential Revision: D16828813 fbshipit-source-id: 9307391dc914ea10b458092b2ec72cd30e2eb0e9
This commit is contained in:
committed by
Facebook Github Bot
parent
027a7f8336
commit
d5a5ce21c9
176
src/ui/components/Panel.tsx
Normal file
176
src/ui/components/Panel.tsx
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* 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 React from 'react';
|
||||
import styled from 'react-emotion';
|
||||
import FlexColumn from './FlexColumn.js';
|
||||
import FlexBox from './FlexBox.js';
|
||||
import {colors} from './colors';
|
||||
import Glyph from './Glyph.js';
|
||||
|
||||
const BORDER = '1px solid #dddfe2';
|
||||
|
||||
const Chevron = styled(Glyph)({
|
||||
marginRight: 4,
|
||||
marginLeft: -2,
|
||||
marginBottom: 1,
|
||||
});
|
||||
|
||||
/**
|
||||
* A Panel component.
|
||||
*/
|
||||
export default class Panel extends React.Component<
|
||||
{
|
||||
/**
|
||||
* 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%;
|
||||
*/
|
||||
grow?: boolean;
|
||||
/**
|
||||
* Heading for this panel. If this is anything other than a string then no
|
||||
* padding is applied to the heading.
|
||||
*/
|
||||
heading: React.ReactNode;
|
||||
/**
|
||||
* Contents of the panel.
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
/**
|
||||
* 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.ReactNode;
|
||||
},
|
||||
{
|
||||
collapsed: boolean;
|
||||
}
|
||||
> {
|
||||
static defaultProps: {
|
||||
floating: boolean;
|
||||
grow: boolean;
|
||||
collapsable: boolean;
|
||||
} = {
|
||||
grow: false,
|
||||
floating: true,
|
||||
collapsable: true,
|
||||
};
|
||||
|
||||
static PanelContainer = styled(FlexColumn)(
|
||||
(props: {floating?: boolean; collapsed?: boolean}) => ({
|
||||
flexShrink: 0,
|
||||
padding: props.floating ? 10 : 0,
|
||||
borderBottom: props.collapsed ? 'none' : BORDER,
|
||||
}),
|
||||
);
|
||||
|
||||
static PanelHeader = styled(FlexBox)(
|
||||
(props: {floating?: boolean; padded?: boolean}) => ({
|
||||
backgroundColor: '#f6f7f9',
|
||||
border: props.floating ? BORDER : 'none',
|
||||
borderBottom: BORDER,
|
||||
borderTopLeftRadius: 2,
|
||||
borderTopRightRadius: 2,
|
||||
justifyContent: 'space-between',
|
||||
lineHeight: '27px',
|
||||
fontWeight: 500,
|
||||
flexShrink: 0,
|
||||
padding: props.padded ? '0 10px' : 0,
|
||||
'&:not(:first-child)': {
|
||||
borderTop: BORDER,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
static PanelBody = styled(FlexColumn)(
|
||||
(props: {floating?: boolean; padded?: boolean}) => ({
|
||||
backgroundColor: '#fff',
|
||||
border: props.floating ? BORDER : 'none',
|
||||
borderBottomLeftRadius: 2,
|
||||
borderBottomRightRadius: 2,
|
||||
borderTop: 'none',
|
||||
flexGrow: 1,
|
||||
padding: props.padded ? 10 : 0,
|
||||
overflow: 'visible',
|
||||
}),
|
||||
);
|
||||
state = {
|
||||
collapsed: this.props.collapsed == null ? false : this.props.collapsed,
|
||||
};
|
||||
|
||||
onClick = () => this.setState({collapsed: !this.state.collapsed});
|
||||
|
||||
render() {
|
||||
const {
|
||||
padded,
|
||||
children,
|
||||
className,
|
||||
grow,
|
||||
floating,
|
||||
heading,
|
||||
collapsable,
|
||||
accessory,
|
||||
} = this.props;
|
||||
const {collapsed} = this.state;
|
||||
return (
|
||||
<Panel.PanelContainer
|
||||
className={className}
|
||||
floating={floating}
|
||||
grow={grow}
|
||||
collapsed={collapsed}>
|
||||
<Panel.PanelHeader
|
||||
floating={floating}
|
||||
padded={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
|
||||
scrollable
|
||||
grow={grow}
|
||||
padded={padded == null ? true : padded}
|
||||
floating={floating}>
|
||||
{children}
|
||||
</Panel.PanelBody>
|
||||
)}
|
||||
</Panel.PanelContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user