2019-07-11 11:43:07 +00:00
|
|
|
import React from 'react'
|
|
|
|
import PropTypes from 'prop-types'
|
|
|
|
import styled from 'styled-components'
|
2019-07-11 13:21:39 +00:00
|
|
|
import device from '../device'
|
|
|
|
import Backdrop from '../backdrop'
|
2019-07-11 19:47:07 +00:00
|
|
|
import { Icons } from '../icons'
|
2019-07-11 11:43:07 +00:00
|
|
|
|
|
|
|
const StyledArticle = styled.article`
|
|
|
|
padding: 0 16px;
|
|
|
|
background: #F8F9F9;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
2019-07-15 09:22:15 +00:00
|
|
|
width: 264px;
|
2019-07-11 11:43:07 +00:00
|
|
|
transition: width .3s ease-in-out;
|
|
|
|
|
|
|
|
@media ${device.tablet} {
|
2019-07-11 14:40:55 +00:00
|
|
|
${props => props.visible
|
|
|
|
? props.pinned
|
2019-07-11 11:43:07 +00:00
|
|
|
? `
|
|
|
|
display: flex;
|
|
|
|
width: 240px;
|
|
|
|
`
|
|
|
|
: `
|
2019-07-15 09:22:15 +00:00
|
|
|
width: 240px;
|
2019-07-11 11:43:07 +00:00
|
|
|
position: fixed;
|
|
|
|
height: 100%;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
z-index: 400;
|
|
|
|
`
|
|
|
|
: `
|
|
|
|
display: none;
|
|
|
|
width: 0px;
|
|
|
|
`
|
|
|
|
}
|
2019-07-15 09:22:15 +00:00
|
|
|
}
|
2019-07-11 11:43:07 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
const StyledArticleHeader = styled.div`
|
|
|
|
border-bottom: 1px solid #ECEEF1;
|
|
|
|
font-weight: bold;
|
|
|
|
font-size: 27px;
|
|
|
|
line-height: 56px;
|
|
|
|
height: 56px;
|
|
|
|
|
|
|
|
@media ${device.tablet} {
|
2019-07-11 14:40:55 +00:00
|
|
|
display: ${props => props.visible ? 'block' : 'none'};
|
2019-07-11 11:43:07 +00:00
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
const StyledArticleBody = styled.div`
|
|
|
|
margin: 16px 0;
|
|
|
|
outline: 1px dotted;
|
|
|
|
flex-grow: 1;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const StyledArticlePinPanel = styled.div`
|
2019-07-11 19:47:07 +00:00
|
|
|
border-top: 1px solid #ECEEF1;
|
2019-07-11 11:43:07 +00:00
|
|
|
height: 56px;
|
|
|
|
display: none;
|
|
|
|
|
|
|
|
@media ${device.tablet} {
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
|
|
|
|
@media ${device.mobile} {
|
|
|
|
display: none;
|
|
|
|
}
|
2019-07-11 19:47:07 +00:00
|
|
|
|
|
|
|
div {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
cursor: pointer;
|
|
|
|
user-select: none;
|
2019-07-12 08:15:17 +00:00
|
|
|
height: 100%;
|
2019-07-11 19:47:07 +00:00
|
|
|
|
|
|
|
span {
|
|
|
|
margin-left: 8px;
|
|
|
|
}
|
|
|
|
}
|
2019-07-11 11:43:07 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
const StyledSection = styled.section`
|
|
|
|
padding: 0 16px;
|
|
|
|
flex-grow: 1;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const StyledSectionHeader = styled.div`
|
|
|
|
border-bottom: 1px solid #ECEEF1;
|
|
|
|
font-weight: bold;
|
|
|
|
font-size: 21px;
|
|
|
|
line-height: 56px;
|
|
|
|
height: 56px;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const StyledSectionBody = styled.div`
|
|
|
|
margin: 16px 0;
|
|
|
|
outline: 1px dotted;
|
|
|
|
flex-grow: 1;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const StyledSectionPagingPanel = styled.div`
|
2019-07-11 19:47:07 +00:00
|
|
|
height: 64px;
|
2019-07-11 11:43:07 +00:00
|
|
|
display: none;
|
|
|
|
|
|
|
|
@media ${device.tablet} {
|
2019-07-11 14:40:55 +00:00
|
|
|
display: ${props => props.visible ? 'block' : 'none'};
|
2019-07-11 11:43:07 +00:00
|
|
|
}
|
2019-07-11 19:47:07 +00:00
|
|
|
|
|
|
|
div {
|
|
|
|
width: 48px;
|
|
|
|
height: 48px;
|
2019-07-12 08:15:17 +00:00
|
|
|
padding: 12px 13px 14px 15px;
|
2019-07-11 19:47:07 +00:00
|
|
|
box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.13);
|
|
|
|
border-radius: 48px;
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
2019-07-11 11:43:07 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
class PageLayout extends React.Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
2019-07-12 10:35:13 +00:00
|
|
|
let isArticleHeaderAvailable = !!props.articleHeaderContent ,
|
2019-07-12 10:31:18 +00:00
|
|
|
isArticleBodyAvailable = !!props.articleBodyContent,
|
|
|
|
isArticleAvailable = isArticleHeaderAvailable || isArticleBodyAvailable,
|
|
|
|
isSectionHeaderAvailable = !!props.sectionHeaderContent,
|
|
|
|
isSectionBodyAvailable = !!props.sectionBodyContent,
|
2019-07-12 10:35:13 +00:00
|
|
|
isSectionAvailable = isSectionHeaderAvailable || isSectionBodyAvailable || isArticleAvailable,
|
|
|
|
isBackdropAvailable = isArticleAvailable;
|
2019-07-12 10:31:18 +00:00
|
|
|
|
2019-07-11 11:43:07 +00:00
|
|
|
this.state = {
|
2019-07-12 10:31:18 +00:00
|
|
|
isBackdropAvailable: isBackdropAvailable,
|
|
|
|
isArticleAvailable: isArticleAvailable,
|
|
|
|
isArticleHeaderAvailable: isArticleHeaderAvailable,
|
|
|
|
isArticleBodyAvailable: isArticleBodyAvailable,
|
|
|
|
isSectionAvailable: isSectionAvailable,
|
|
|
|
isSectionHeaderAvailable: isSectionHeaderAvailable,
|
|
|
|
isSectionBodyAvailable: isSectionBodyAvailable,
|
|
|
|
|
2019-07-11 14:40:55 +00:00
|
|
|
isBackdropVisible: props.isBackdropVisible,
|
|
|
|
isArticleVisible: props.isArticleVisible,
|
2019-07-12 08:25:32 +00:00
|
|
|
isArticlePinned: props.isArticlePinned,
|
|
|
|
|
|
|
|
articleHeaderContent: props.articleHeaderContent,
|
|
|
|
articleBodyContent: props.articleBodyContent,
|
|
|
|
sectionHeaderContent: props.sectionHeaderContent,
|
|
|
|
sectionBodyContent: props.sectionBodyContent
|
2019-07-11 11:43:07 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
backdropClick = () => {
|
|
|
|
this.setState({
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: false,
|
2019-07-11 14:40:55 +00:00
|
|
|
isArticleVisible: false,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: false
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
pinArticle = () => {
|
|
|
|
this.setState({
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: false,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: true,
|
2019-07-11 14:40:55 +00:00
|
|
|
isArticleVisible: true
|
2019-07-11 11:43:07 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
unpinArticle = () => {
|
|
|
|
this.setState({
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: true,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: false,
|
2019-07-11 14:40:55 +00:00
|
|
|
isArticleVisible: true
|
2019-07-11 11:43:07 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
showArticle = () => {
|
|
|
|
this.setState({
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: true,
|
2019-07-11 14:40:55 +00:00
|
|
|
isArticleVisible: true,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: false
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<>
|
2019-07-12 10:31:18 +00:00
|
|
|
{
|
|
|
|
this.state.isBackdropAvailable &&
|
|
|
|
<Backdrop visible={this.state.isBackdropVisible} onClick={this.backdropClick}/>
|
|
|
|
}
|
|
|
|
{
|
|
|
|
this.state.isArticleAvailable &&
|
|
|
|
<StyledArticle visible={this.state.isArticleVisible} pinned={this.state.isArticlePinned}>
|
|
|
|
{
|
|
|
|
this.state.isArticleHeaderAvailable &&
|
|
|
|
<StyledArticleHeader visible={this.state.isArticlePinned}>{this.state.articleHeaderContent}</StyledArticleHeader>
|
|
|
|
}
|
|
|
|
{
|
|
|
|
this.state.isArticleBodyAvailable &&
|
|
|
|
<StyledArticleBody>{this.state.articleBodyContent}</StyledArticleBody>
|
|
|
|
}
|
|
|
|
{
|
|
|
|
this.state.isArticleBodyAvailable &&
|
|
|
|
<StyledArticlePinPanel>
|
|
|
|
{
|
|
|
|
this.state.isArticlePinned
|
|
|
|
? <div onClick={this.unpinArticle}>
|
|
|
|
<Icons.CatalogUnpinIcon size="medium"/>
|
|
|
|
<span>Unpin this panel</span>
|
|
|
|
</div>
|
|
|
|
: <div onClick={this.pinArticle}>
|
|
|
|
<Icons.CatalogPinIcon size="medium"/>
|
|
|
|
<span>Pin this panel</span>
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
</StyledArticlePinPanel>
|
|
|
|
}
|
|
|
|
</StyledArticle>
|
|
|
|
}
|
|
|
|
{
|
|
|
|
this.state.isSectionAvailable &&
|
|
|
|
<StyledSection>
|
|
|
|
{
|
|
|
|
this.state.isSectionHeaderAvailable &&
|
|
|
|
<StyledSectionHeader>{this.state.sectionHeaderContent}</StyledSectionHeader>
|
|
|
|
}
|
|
|
|
{
|
|
|
|
this.state.isSectionBodyAvailable &&
|
|
|
|
<StyledSectionBody>{this.state.sectionBodyContent}</StyledSectionBody>
|
|
|
|
}
|
2019-07-11 11:43:07 +00:00
|
|
|
{
|
2019-07-12 10:31:18 +00:00
|
|
|
this.state.isArticleAvailable &&
|
|
|
|
<StyledSectionPagingPanel visible={!this.state.isArticlePinned}>
|
|
|
|
<div onClick={this.showArticle}>
|
|
|
|
<Icons.CatalogButtonIcon size="scale"/>
|
|
|
|
</div>
|
|
|
|
</StyledSectionPagingPanel>
|
2019-07-11 11:43:07 +00:00
|
|
|
}
|
2019-07-12 10:31:18 +00:00
|
|
|
</StyledSection>
|
|
|
|
}
|
2019-07-11 11:43:07 +00:00
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PageLayout.propTypes = {
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: PropTypes.bool,
|
2019-07-11 14:40:55 +00:00
|
|
|
isArticleVisible: PropTypes.bool,
|
2019-07-12 08:25:32 +00:00
|
|
|
isArticlePinned: PropTypes.bool,
|
|
|
|
|
|
|
|
articleHeaderContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
|
|
|
|
articleBodyContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
|
|
|
|
sectionHeaderContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
|
|
|
|
sectionBodyContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node])
|
2019-07-11 11:43:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PageLayout.defaultProps = {
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: false,
|
2019-07-11 14:40:55 +00:00
|
|
|
isArticleVisible: false,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: false
|
|
|
|
}
|
|
|
|
|
|
|
|
export default PageLayout
|