optimizely-oui
Version:
Optimizely's Component Library.
87 lines (77 loc) • 2.46 kB
JavaScript
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
/**
*
* @param {Object} props - Properties passed to component
* @returns {ReactElement}
*/
const Disclose = ({
children,
childrenStyle,
className,
headerStyle,
isDisabled,
isInitiallyOpen,
isOpen,
indented,
openHandler,
title,
...props
}) => {
const [isExpanded, setIsExpanded] = useState(isInitiallyOpen);
useEffect(() => {
if (isOpen !== undefined) setIsExpanded(isOpen);
}, [isOpen]);
useEffect(() => {
if (openHandler) {
openHandler(setIsExpanded);
}
}, [openHandler]);
const toggleOpenDisclose = () => !isDisabled && setIsExpanded(!isExpanded);
const contentClass = classNames("oui-disclose__content", {
"border--sides border--bottom": childrenStyle === "border",
"border--bottom": childrenStyle === "divider" && isExpanded,
});
const linkClass = classNames(
"oui-disclose__link soft-half flush",
{
"background--faint display--block": headerStyle === "header",
"border--all background--faint display--block": headerStyle === "header-bordered",
"hard--left": !indented,
"link--dark": !isDisabled,
"link--disabled": isDisabled,
},
className
);
const arrowClass = classNames("oui-disclose", {
"is-active": isExpanded,
});
return (
<div className={arrowClass} style={{ marginTop: "-1px" }}>
<a onClick={toggleOpenDisclose} className={linkClass} {...props}>
<div className="flex flex-align--start oui-disclose__arrow">
<span className="oui-disclose__symbol push--right" />
{title}
</div>
</a>
<div className={contentClass}>{isExpanded && children}</div>
</div>
);
};
Disclose.propTypes = {
children: PropTypes.node.isRequired,
childrenStyle: PropTypes.string,
headerStyle: PropTypes.string,
indented: PropTypes.bool,
isDisabled: PropTypes.bool,
isInitiallyOpen: PropTypes.bool,
isOpen: PropTypes.bool,
noBorder: PropTypes.bool,
openHandler: PropTypes.func,
title: PropTypes.oneOfType([PropTypes.node, PropTypes.string]).isRequired,
};
Disclose.defaultProps = {
indented: true,
};
export default Disclose;