@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.
196 lines (181 loc) • 7.6 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
const _excluded = ["theme", "width", "position", "shown", "suppressed"],
_excluded2 = ["theme", "type", "hasTopPadding", "noPadding", "hasClose"];
import * as React from "react";
import styled, { css } from "styled-components";
import { convertHexToRgba } from "@kiwicom/orbit-design-tokens";
import KEY_CODE_MAP from "../common/keyMaps";
import useFocusTrap from "../hooks/useFocusTrap";
import useLockScrolling from "../hooks/useLockScrolling";
import transition from "../utils/transition";
import mq from "../utils/mediaQuery";
import defaultTheme from "../defaultTheme";
import DrawerClose from "./components/DrawerClose";
import POSITIONS from "./consts";
import getPosition from "./helpers/getPosition";
import getTransitionAnimation from "./helpers/getTransitionAnimation";
import useTheme from "../hooks/useTheme";
import Stack from "../Stack";
import useStateWithTimeout from "../hooks/useStateWithTimeout";
import Heading from "../Heading";
import { rtlSpacing } from "../utils/rtl";
const getPadding = ({
noPadding,
theme,
hasTopPadding
}) => {
const padding = space => !hasTopPadding ? rtlSpacing(`0 ${space} ${space}`) : space;
return !noPadding && css(["padding:", ";", ";"], padding(theme.orbit.spaceMedium), mq.largeMobile(css(["padding:", "};"], padding(theme.orbit.spaceXLarge))));
};
const StyledDrawer = styled.div.withConfig({
displayName: "Drawer__StyledDrawer",
componentId: "sc-svgki0-0"
})(["", ""], ({
theme,
overlayShown,
shown
}) => css(["display:flex;visibility:", ";position:fixed;top:0;left:0;right:0;bottom:0;width:100%;height:100%;background-color:", ";z-index:", ";transition:", ";"], overlayShown ? "visible" : "hidden", shown ? convertHexToRgba(theme.orbit.paletteInkNormal, 50) : "transparent", theme.orbit.zIndexDrawer, transition(["background-color"], "fast", "ease-in-out"))); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledDrawer.defaultProps = {
theme: defaultTheme
};
const StyledDrawerSide = styled( /*#__PURE__*/React.forwardRef((_ref, ref) => {
let {
theme,
width,
position,
shown,
suppressed
} = _ref,
props = _objectWithoutProperties(_ref, _excluded);
return /*#__PURE__*/React.createElement("aside", _extends({
ref: ref
}, props));
})).withConfig({
displayName: "Drawer__StyledDrawerSide",
componentId: "sc-svgki0-1"
})(["", ""], ({
theme,
suppressed,
width
}) => css(["display:block;position:absolute;box-sizing:border-box;top:0;bottom:0;height:100%;font-family:", ";overflow-y:auto;box-shadow:", ";background:", ";transition:", ";width:100%;", ";", ";", ";"], theme.orbit.fontFamily, theme.orbit.boxShadowRaised, suppressed ? theme.orbit.paletteCloudLight : theme.orbit.paletteWhite, transition(["transform"], "normal", "ease-in-out"), mq.largeMobile(css(["max-width:", ";"], width)), getPosition, getTransitionAnimation)); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledDrawerSide.defaultProps = {
theme: defaultTheme
};
const StyledDrawerContent = styled((_ref2) => {
let {
theme,
type,
hasTopPadding,
noPadding,
hasClose
} = _ref2,
props = _objectWithoutProperties(_ref2, _excluded2);
return /*#__PURE__*/React.createElement("div", props);
}).withConfig({
displayName: "Drawer__StyledDrawerContent",
componentId: "sc-svgki0-2"
})(["", ""], ({
theme,
noPadding,
hasClose
}) => css(["", ";margin-bottom:", ";margin-top:", ";"], getPadding, noPadding && theme.orbit.spaceLarge, !hasClose && noPadding && theme.orbit.spaceLarge)); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledDrawerContent.defaultProps = {
theme: defaultTheme
};
const StyledDrawerHeader = styled.div.withConfig({
displayName: "Drawer__StyledDrawerHeader",
componentId: "sc-svgki0-3"
})(["", ""], ({
theme,
fixedHeader,
suppressed,
bordered,
noPadding,
onlyIcon
}) => css(["display:flex;", " justify-content:", ";align-items:center;background:", ";height:64px;box-sizing:border-box;border-bottom:", ";", ";"], fixedHeader && css(["position:sticky;top:0;z-index:", ";"], theme.orbit.zIndexSticky), onlyIcon ? "flex-end" : "space-between", suppressed && !bordered ? theme.orbit.paletteCloudLight : theme.orbit.paletteWhite, bordered && `1px solid ${theme.orbit.paletteCloudNormal}`, !noPadding && css(["padding:0 ", ";", ";"], theme.orbit.spaceMedium, mq.largeMobile(css(["padding:", ";"], rtlSpacing(`0 ${theme.orbit.spaceLarge} 0 ${theme.orbit.spaceXLarge}`)))))); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledDrawerHeader.defaultProps = {
theme: defaultTheme
};
const Drawer = ({
children,
onClose,
lockScrolling = true,
fixedHeader,
shown = true,
width = "320px",
position = POSITIONS.RIGHT,
dataTest,
noPadding,
suppressed,
title,
actions
}) => {
const theme = useTheme();
const overlayRef = React.useRef(null);
const closeButtonRef = React.useRef(null);
const scrollableRef = React.useRef(null);
const timeoutLength = React.useMemo(() => parseFloat(theme.orbit.durationNormal) * 1000, [theme.orbit.durationNormal]);
const [overlayShown, setOverlayShown, setOverlayShownWithTimeout] = useStateWithTimeout(shown, timeoutLength);
const handleOnClose = React.useCallback(ev => {
if (onClose && ev.target === overlayRef.current) {
onClose();
}
}, [onClose]);
useFocusTrap(scrollableRef);
useLockScrolling(scrollableRef, lockScrolling && overlayShown);
React.useEffect(() => {
var _closeButtonRef$curre;
(_closeButtonRef$curre = closeButtonRef.current) === null || _closeButtonRef$curre === void 0 ? void 0 : _closeButtonRef$curre.focus();
if (overlayShown !== shown) {
if (shown) {
setOverlayShown(true);
} else if (!shown) {
setOverlayShownWithTimeout(false);
}
}
const handleKeyDown = ev => {
if (ev.keyCode === KEY_CODE_MAP.ESC && onClose) {
onClose();
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [overlayShown, setOverlayShown, setOverlayShownWithTimeout, shown, onClose]);
return /*#__PURE__*/React.createElement(StyledDrawer, {
role: "button",
overlayShown: overlayShown,
shown: shown,
onClick: handleOnClose,
"data-test": dataTest,
"aria-hidden": !shown,
ref: overlayRef
}, /*#__PURE__*/React.createElement(StyledDrawerSide, {
ref: scrollableRef,
shown: shown,
width: width,
position: position,
role: "navigation",
suppressed: suppressed
}, (title || actions || onClose) && /*#__PURE__*/React.createElement(StyledDrawerHeader, {
onlyIcon: !title && !actions,
bordered: title || actions,
suppressed: suppressed,
fixedHeader: fixedHeader
}, 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
})), /*#__PURE__*/React.createElement(StyledDrawerContent, {
noPadding: noPadding,
hasClose: !!onClose,
hasTopPadding: title || actions
}, children)));
};
export default Drawer;