UNPKG

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
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, /** * ![IMPORTANT](https://badgen.net/badge/UX/Accessibility/blue) * 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, /** * ![IMPORTANT](https://badgen.net/badge/UX/Accessibility/blue) * 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;