terra-content-container
Version:
The Terra ContentContainer is a structural component for the purpose of arranging content with a header.
100 lines (90 loc) • 3.17 kB
JSX
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames/bind';
import Scroll from 'terra-scroll';
import ThemeContext from 'terra-theme-context';
import styles from './ContentContainer.module.scss';
const cx = classNames.bind(styles);
const propTypes = {
/**
* The header element to be placed within the header area of the container.
*/
header: PropTypes.node,
/**
* The footer element to be placed within the footer area of the container.
*/
footer: PropTypes.node,
/**
* The children to be placed within the main content area of the container.
*/
children: PropTypes.node,
/**
* Whether or not the container should expanded to fill its parent element.
*/
fill: PropTypes.bool,
/**
* Ref callback for the scrollable area of the content container.
*/
scrollRefCallback: PropTypes.func,
/**
* 
* Sets focus on content when set to `true`. Focus on content helps in scrolling within container when there is no interactive element to focus within container.
*/
setFocusOnContainer: PropTypes.bool,
/**
* 
* This prop needs to be set only if `setFocusOnContainer` is set. Based on dark or light background color the border will be white or black respectively to maintain
* an accessible color contrast ratio.
*/
backgroundColor: PropTypes.oneOf(['dark', 'light']),
};
const defaultProps = {
header: undefined,
footer: undefined,
children: undefined,
fill: false,
scrollRefCallback: undefined,
setFocusOnContainer: false,
backgroundColor: undefined,
};
const ContentContainer = ({
header,
footer,
children,
fill,
scrollRefCallback,
setFocusOnContainer,
backgroundColor,
...customProps
}) => {
const theme = React.useContext(ThemeContext);
const lightBackground = 'light';
const contentLayoutClassNames = cx([
`content-container-${fill ? 'fill' : 'static'}`,
customProps.className,
]);
// setting tab index to 0 if setFocusOnContainer is set
const scrollAttrs = (setFocusOnContainer) ? { tabIndex: 0 } : '';
// border will only be visible when setFocusOnContainer is set for content-container
const background = setFocusOnContainer && (backgroundColor || lightBackground);
const scrollClassNames = cx(
'normalizer',
theme.className,
{ 'content-container-focused-padding': setFocusOnContainer },
background,
);
return (
<div {...customProps} className={contentLayoutClassNames}>
{header && <div className={cx('header', { 'content-container-focused-padding': setFocusOnContainer })}>{header}</div>}
<div className={cx('main')}>
<Scroll className={scrollClassNames} refCallback={scrollRefCallback} {...scrollAttrs}>
{children}
</Scroll>
</div>
{footer && <div className={cx('footer', { 'content-container-focused-padding': setFocusOnContainer })}>{footer}</div>}
</div>
);
};
ContentContainer.propTypes = propTypes;
ContentContainer.defaultProps = defaultProps;
export default ContentContainer;