Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
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;