@drivy/cobalt
Version:
Opinionated design system for Drivy's projects.
64 lines (61 loc) • 3.46 kB
JavaScript
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