@kiwicom/orbit-components
Version:
Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.
98 lines (97 loc) • 4.31 kB
JavaScript
"use client";
import * as React from "react";
import cx from "clsx";
import KEY_CODE_MAP from "../common/keyMaps";
import useFocusTrap from "../hooks/useFocusTrap";
import useLockScrolling from "../hooks/useLockScrolling";
import DrawerClose from "./components/DrawerClose";
import POSITIONS from "./consts";
import Stack from "../Stack";
import Heading from "../Heading";
import theme from "../defaultTheme";
import useStateWithTimeout from "../hooks/useStateWithTimeout";
const getTransitionClasses = (shown, position) => {
if (shown) return "translate-x-0";
return position === POSITIONS.RIGHT ? "ltr:lm:translate-x-[var(--lm-drawer-width)] rtl:lm:-translate-x-[var(--lm-drawer-width)] ltr:translate-x-full rtl:-translate-x-full" : "ltr:lm:-translate-x-[var(--lm-drawer-width)] rtl:lm:-translate-x-[var(--lm-drawer-width)] ltr:-translate-x-full rtl:translate-x-full";
};
const Drawer = ({
children,
onClose,
lockScrolling = true,
fixedHeader,
labelHide = "Hide",
shown = true,
width = "320px",
position = POSITIONS.RIGHT,
dataTest,
id,
noPadding,
suppressed,
title,
actions
}) => {
const overlayRef = React.useRef(null);
const closeButtonRef = React.useRef(null);
const scrollableRef = React.useRef(null);
const [overlayShown, setOverlayShown, setOverlayShownWithTimeout] = useStateWithTimeout(shown, parseFloat(theme.orbit.durationNormal) * 1000);
const handleOnClose = React.useCallback(ev => {
if (onClose && ev.target === overlayRef.current) {
onClose();
}
}, [onClose]);
useFocusTrap(scrollableRef);
useLockScrolling(scrollableRef, lockScrolling && overlayShown);
const handleKeyDown = React.useCallback(ev => {
if (ev.keyCode === KEY_CODE_MAP.ESC && onClose) {
onClose();
}
}, [onClose]);
React.useEffect(() => {
closeButtonRef.current?.focus();
if (overlayShown !== shown) {
if (shown) {
setOverlayShown(true);
} else if (!shown) {
setOverlayShownWithTimeout(false);
}
}
}, [overlayShown, setOverlayShown, shown, setOverlayShownWithTimeout, onClose]);
const vars = {
"--lm-drawer-width": width
};
const varClasses = [vars["--lm-drawer-width"] != null && "lm:max-w-[var(--lm-drawer-width)]"];
const onlyIcon = !title && !actions;
const bordered = !!(title || actions);
return /*#__PURE__*/React.createElement("div", {
role: "button",
tabIndex: 0,
onKeyDown: handleKeyDown,
className: cx("orbit-drawer", "flex", "fixed inset-0", "h-full w-full", "z-drawer", "duration-fast transition-colors ease-in-out", overlayShown ? "visible" : "invisible", shown ? "bg-drawer-overlay-background" : "transparent"),
onClick: handleOnClose,
"data-test": dataTest,
id: id,
"aria-hidden": !shown,
ref: overlayRef
}, /*#__PURE__*/React.createElement("aside", {
className: cx("box-border block", "absolute bottom-0 top-0", "h-full w-full", "font-base", "overflow-y-auto", "overflow-x-hidden", "shadow-raised", "duration-normal transform-gpu transition-transform ease-in-out", getTransitionClasses(shown, position), suppressed ? "bg-cloud-light" : "bg-white-normal", position === POSITIONS.RIGHT ? "end-0" : "start-0", ...varClasses),
style: vars,
ref: scrollableRef,
role: "navigation"
}, (title || actions || onClose) && /*#__PURE__*/React.createElement("div", {
className: cx("flex", "items-center", "h-[64px]", "box-border", suppressed && !bordered ? "bg-cloud-light" : "bg-white-normal", fixedHeader && "z-sticky sticky top-0", onlyIcon ? "justify-end" : "justify-between", bordered && "border-cloud-normal border-b border-l-0 border-r-0 border-t-0 border-solid", !noPadding && "px-md lm:ps-xl lm:pe-lg py-0")
}, title && /*#__PURE__*/React.createElement(Heading, {
type: "title2"
}, title), actions && /*#__PURE__*/React.createElement(Stack, {
spacing: "none",
justify: "end",
flex: true,
shrink: true
}, actions), onClose && /*#__PURE__*/React.createElement(DrawerClose, {
onClick: onClose,
ref: closeButtonRef,
title: labelHide
})), /*#__PURE__*/React.createElement("div", {
className: cx(!onClose && noPadding && "mt-lg", noPadding && "mb-lg", !noPadding && (bordered ? "p-md lm:p-xl" : "px-md pb-md lm:px-xl lm:pb-xl"))
}, children)));
};
export default Drawer;