Summary: React 16 is not compatible with react-emotion 9 (it prints warnings, see also https://github.com/emotion-js/emotion/issues/644). So we should upgrade to 10. Reviewed By: mweststrate Differential Revision: D18905889 fbshipit-source-id: c00d2dbbadb1c08544632cb9bfcd63f2b1818a25
181 lines
4.3 KiB
TypeScript
181 lines
4.3 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* 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 '@emotion/styled';
|
|
import FlexColumn from './FlexColumn';
|
|
import FlexBox from './FlexBox';
|
|
import {colors} from './colors';
|
|
import Glyph from './Glyph';
|
|
|
|
const BORDER = '1px solid #dddfe2';
|
|
|
|
const Chevron = styled(Glyph)({
|
|
marginRight: 4,
|
|
marginLeft: -2,
|
|
marginBottom: 1,
|
|
});
|
|
Chevron.displayName = 'Panel:Chevron';
|
|
|
|
/**
|
|
* 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)<{
|
|
floating?: boolean;
|
|
collapsed?: boolean;
|
|
}>(props => ({
|
|
flexShrink: 0,
|
|
padding: props.floating ? 10 : 0,
|
|
borderBottom: props.collapsed ? 'none' : BORDER,
|
|
}));
|
|
|
|
static PanelHeader = styled(FlexBox)<{floating?: boolean; padded?: boolean}>(
|
|
props => ({
|
|
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)<{floating?: boolean; padded?: boolean}>(
|
|
props => ({
|
|
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>
|
|
);
|
|
}
|
|
}
|