UNPKG

@drivy/cobalt

Version:

Opinionated design system for Drivy's projects.

64 lines (61 loc) 3.46 kB
import React, { useState, useEffect } from 'react'; import cx from 'classnames'; import Modal from '../Modal/index.js'; import useBreakpoint from '../../hooks/useBreakpoint.js'; import '../Icon/index.js'; import ReactDOM from 'react-dom'; import { Fixed } from '../Layout/Surfaces/index.js'; import CloseIcon from '../Icon/__generated__/CloseIcon.js'; const SidepanelFooter = ({ children, className }) => { return (React.createElement("div", { className: cx("c-p-sm c-border-t c-border-outline", className) }, children)); }; // Memoized component to not render content when the panel is collapsing function _SidepanelContent({ title, close, children }) { return (React.createElement(React.Fragment, null, title && (React.createElement("div", { className: "c-flex c-gap-sm c-items-center c-px-sm c-py-md c-border-b c-border-outline" }, React.createElement("div", { className: "c-text-title-md c-flex-1" }, title), close && (React.createElement("div", { className: "c-w-md c-cursor-pointer", onClick: close }, React.createElement(CloseIcon, { size: 24 }))))), children)); } function areSidepanelContentEqual(_prevProps, nextProps) { return !nextProps.isOpen; } const SidepanelContent = React.memo(_SidepanelContent, areSidepanelContentEqual); SidepanelContent.displayName = "SidepanelContent"; // Only for the API, render nothing const SidepanelFooterAPI = (_props) => null; const isSidepanelFooterAPIComponent = (component) => React.isValidElement(component) && component.type === SidepanelFooterAPI; const _Sidepanel = ({ isOpen, title, close, withDesktopOverlay, width = 420, children, }) => { const { isMobile } = useBreakpoint(); // To display box-shadow when visible. We can't rely on isOpen because it triggers the collapse animation and so the box shadow would not be set during the transition const [isPanelVisible, setIsPanelVisible] = useState(false); useEffect(() => { isOpen && setIsPanelVisible(true); }, [isOpen]); const sidepanelFooter = React.Children.toArray(children).find((c) => isSidepanelFooterAPIComponent(c)); let footer = null; if (React.isValidElement(sidepanelFooter)) { footer = isMobile ? (React.createElement(Modal.Footer, { ...sidepanelFooter.props })) : (React.createElement(SidepanelFooter, { ...sidepanelFooter.props })); } return isMobile ? (React.createElement(Modal, { "aria-label": "Sidepanel", isOpen: isOpen, bodySpacing: false, close: close, title: title }, children, footer)) : (ReactDOM.createPortal(React.createElement(React.Fragment, null, React.createElement("div", { className: cx("cobalt-sidepanel", { "cobalt-sidepanel--show": isOpen, "cobalt-sidepanel--visible": isPanelVisible, }), onTransitionEnd: () => { !isOpen && setIsPanelVisible(false); } }, React.createElement(Fixed, { width: width, isFullHeight: true }, React.createElement(SidepanelContent, { isOpen: isOpen, title: title, close: close }, children, footer))), withDesktopOverlay && React.createElement("div", { className: "cobalt-sidepanel-overlay" })), document.body)); }; _Sidepanel.displayName = "Sidepanel"; const Sidepanel = Object.assign(_Sidepanel, { Footer: SidepanelFooterAPI, }); export { Sidepanel }; //# sourceMappingURL=index.js.map