Repository URL to install this package:
|
Version:
7.11.3 ▾
|
import React from 'react';
import PropTypes from 'prop-types';
import Navigation, { NavigationTypes } from '../Navigation';
import ProductFooter, { ProductFooterTypes } from '../ProductFooter';
import Pattern from '../Pattern';
import Button from '../../controls/Button/Button';
import OneColumnLayout from './OneColumnLayout';
import TwoColumnLayout from './TwoColumnLayout';
export const LAYOUT_TYPES = {
ONE_COLUMN: 'one-column',
TWO_COLUMN: 'two-column',
TWO_COLUMN_FLEXIBLE: 'two-column-flexible',
};
export const Theme = {
backgroundColor: PropTypes.string,
backgroundImage: PropTypes.shape({
url: PropTypes.string,
}),
backgroundTiling: PropTypes.bool,
};
const PageLayout = ({ header, theme, footer, children, actions, layoutType, schedexColorTheme }) => {
const { backgroundImage, backgroundTiling, backgroundColor } = theme;
return (
<div className={`PageLayout PageLayout--${layoutType}`}>
{schedexColorTheme && (
<div className="PageLayout__BrandingTheme" style={{ backgroundColor: schedexColorTheme }} />
)}
<div className="PageLayout__header">
<Navigation {...header} />
</div>
<Pattern backgroundImage={backgroundImage.url} repeat={backgroundTiling} color={backgroundColor}>
<div className="PageLayout__content">{children}</div>
{footer && (
<div className="PageLayout__footer">
<ProductFooter {...footer} />
</div>
)}
</Pattern>
{Array.isArray(actions) &&
actions.length > 0 && (
<div className="PageLayout__action-bar">
<div className="PageLayout__actions-wrapper">
<div className="PageLayout__actions">
{actions.map((action, index) => (
// We do not expect new action props after first render, so it's fine to use index
// eslint-disable-next-line react/no-array-index-key
<div key={index} className="PageLayout__action">
{action}
</div>
))}
</div>
</div>
</div>
)}
</div>
);
};
function validateChildren(props, propName, componentName) {
const children = React.Children.toArray(props[propName]);
const invalidType = children.find(child => child.type !== OneColumnLayout && child.type !== TwoColumnLayout);
return invalidType
? new TypeError(
`\`${componentName}\` children should be of type \`OneColumnLayout\` or \`TwoColumnLayout\`. Are you only setting the layoutType? Please note that the layoutType prop only affects the width of the header and the action bar.`
)
: '';
}
validateChildren.isRequired = (props, propName, componentName) => {
const children = React.Children.toArray(props[propName]);
if (children.length === 0) {
return new TypeError(`\`${componentName}\` children prop is required.`);
}
return validateChildren(props, propName, componentName);
};
PageLayout.propTypes = {
/**
* Props to be passed to the Navigation component
* @todo bug with passed PropTypes, so have to ignore it for styleguide
* https://github.com/reactjs/react-docgen/pull/352
* @ignore
* */
header: PropTypes.shape(NavigationTypes).isRequired,
/**
* Props to be passed to the ProductFooter component
* @todo bug with passed PropTypes, so have to ignore it for styleguide
* https://github.com/reactjs/react-docgen/pull/352
* @ignore
*/
footer: PropTypes.shape(ProductFooterTypes),
/** Content that is either a OneColumnLayout or TwoColumnLayout component */
children: validateChildren.isRequired,
/** An array of Buttons to be rendered in the action bar. If none are provided, action bar won't be rendered */
actions: PropTypes.array,
/**
* A control to make header and action bar, same width as the content, which depends on children passed
*
* Please note that the layoutType prop only affects the width of the header and the action bar.
* Make sure you add OneColumnLayout or TwoColumnLayout components as children.
*/
layoutType: PropTypes.oneOf(Object.values(LAYOUT_TYPES)).isRequired,
/**
* An object representing the theme settings to be used as background.
*/
theme: PropTypes.shape(Theme),
/**
* Enable SchedEx color theme.
* Show branding colored tile on top instead of background.
*/
schedexColorTheme: PropTypes.string,
};
PageLayout.defaultProps = {
actions: null,
footer: null,
theme: {
backgroundImage: {
url: null,
},
},
schedexColorTheme: null,
};
export default PageLayout;