optimizely-oui
Version:
Optimizely's Component Library.
146 lines (138 loc) • 4.48 kB
JavaScript
import PropTypes from "prop-types";
import React from "react";
import classNames from "classnames";
import Attention from "../Attention";
import ButtonRow from "../ButtonRow";
import CloseButton from "../CloseButton";
/**
*
* @param {Object} props - Properties passed to component
* @returns {ReactElement}
*/
const Sheet = ({
centerHeader,
children,
className,
footerButtonList,
hasCloseButton,
hasFooter,
hasRequiredFieldsIndicator,
onClose,
subtitle,
testSection,
title,
warningContent,
warningTestSection,
...props
}) => {
let subtitleContent;
if (subtitle && typeof subtitle === "string") {
subtitleContent = <p className="push--top flush--bottom">{subtitle}</p>;
} else {
subtitleContent = <div className="push--top flush--bottom">{subtitle}</div>;
}
let headerClasses = classNames({
"oui-sheet__header": true,
"text--center": centerHeader,
});
return (
<div className={classNames("oui-sheet__wrapper", className)} {...props}>
<div className="oui-sheet__overlay" />
<div data-oui-component={true} className="oui-sheet overflow-y--auto" data-test-section={testSection}>
{hasCloseButton && <CloseButton onClick={onClose} size="large" />}
{warningContent && (
<div className="oui-sheet__warning">
<Attention alignment="center" type="warning" testSection={warningTestSection}>
{warningContent}
</Attention>
</div>
)}
<header className={headerClasses}>
<h2 className="flush--bottom">{title}</h2>
{subtitleContent}
</header>
<div className="oui-sheet__body">{children}</div>
{hasFooter && (
<footer className="oui-sheet__footer">
<div className="flex flex-align--center">
{hasRequiredFieldsIndicator && (
<div className="oui-sheet__required-indicator cursor--default color--red">
<span>* Required field</span>
</div>
)}
<div className="flex--1">
<ButtonRow rightGroup={footerButtonList} />
</div>
</div>
</footer>
)}
</div>
</div>
);
};
Sheet.propTypes = {
/**
* Used to determine if the title & subtitle of the sheet should be centered.
*/
centerHeader: PropTypes.bool,
/**
* The body of the sheet to request information and data from the user.
*/
children: PropTypes.node.isRequired,
/** CSS class names. */
className: PropTypes.string,
/**
* Array of buttons used in the footer of the sheet.
*/
footerButtonList: PropTypes.array,
/**
* Used to determine if the sheet should have a close button.
*/
hasCloseButton: PropTypes.bool,
/**
* Determines if the sheet should have a footer.
*/
hasFooter: PropTypes.bool,
/**
* Determines if the sheet should have a message in the footer
* indicating required fields are marked with an asterisk (*).
*/
hasRequiredFieldsIndicator: PropTypes.bool,
/**
* Function to perform when the sheet is closed.
*/
onClose: PropTypes.func,
/**
* A subtitle for the sheet.
*/
subtitle: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
/**
* Identifier used to create data-test-section attributes for testing.
*/
testSection: PropTypes.string,
/**
* Main title of the sheet.
*/
title: PropTypes.string.isRequired,
/**
* Content of the warning Attention bar.
*/
warningContent: PropTypes.string,
/**
* Identifier used to create data-test-section
* attribute for the Attention bar.
*/
warningTestSection: PropTypes.string,
};
Sheet.defaultProps = {
centerHeader: false,
footerButtonList: [],
hasCloseButton: true,
hasFooter: true,
hasRequiredFieldsIndicator: false,
onClose: () => null,
subtitle: "",
testSection: "",
warningTestSection: "",
};
export default Sheet;