@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.
179 lines (170 loc) • 6.63 kB
JavaScript
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import React, { useCallback, useEffect, useMemo, useRef } from "react";
import styled, { css } from "styled-components";
import convertHexToRgba from "@kiwicom/orbit-design-tokens/lib/convertHexToRgba";
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-1auf65o-0"
})(["display:flex;visibility:", ";position:fixed;top:0;left:0;right:0;bottom:0;width:100%;height:100%;background-color:", ";z-index:825;transition:background-color ", " ease-in-out;"], ({
overlayShown
}) => overlayShown ? "visible" : "hidden", ({
theme,
shown
}) => shown ? convertHexToRgba(theme.orbit.paletteInkNormal, 50) : "transparent", ({
theme
}) => theme.orbit.durationFast);
StyledDrawer.defaultProps = {
theme: defaultTheme
};
const StyledDrawerSide = styled((_ref) => {
let {
theme,
width,
position,
shown,
suppressed
} = _ref,
props = _objectWithoutProperties(_ref, ["theme", "width", "position", "shown", "suppressed"]);
return React.createElement("aside", props);
}).withConfig({
displayName: "Drawer__StyledDrawerSide",
componentId: "sc-1auf65o-1"
})(["display:block;position:absolute;box-sizing:border-box;top:0;bottom:0;height:100%;font-family:", ";overflow-y:auto;box-shadow:", ";background:", ";transition:transform ", " ease-in-out;width:100%;", ";", ";", ";"], ({
theme
}) => theme.orbit.fontFamily, ({
theme
}) => theme.orbit.boxShadowRaised, ({
theme,
suppressed
}) => suppressed ? theme.orbit.paletteCloudLight : theme.orbit.paletteWhite, ({
theme
}) => theme.orbit.durationNormal, mq.largeMobile(css(["max-width:", ";"], ({
width
}) => width)), getPosition, getTransitionAnimation);
StyledDrawerSide.defaultProps = {
theme: defaultTheme
};
const StyledDrawerContent = styled((_ref2) => {
let {
theme,
type,
hasTopPadding,
noPadding,
hasClose
} = _ref2,
props = _objectWithoutProperties(_ref2, ["theme", "type", "hasTopPadding", "noPadding", "hasClose"]);
return React.createElement("div", props);
}).withConfig({
displayName: "Drawer__StyledDrawerContent",
componentId: "sc-1auf65o-2"
})(["", ";margin-bottom:", ";margin-top:", ";"], getPadding, ({
theme,
noPadding
}) => noPadding && theme.orbit.spaceLarge, ({
hasClose,
theme,
noPadding
}) => !hasClose && noPadding && theme.orbit.spaceLarge);
StyledDrawerContent.defaultProps = {
theme: defaultTheme
};
const StyledDrawerHeader = styled.div.withConfig({
displayName: "Drawer__StyledDrawerHeader",
componentId: "sc-1auf65o-3"
})(["display:flex;justify-content:flex-end;align-items:center;background:", ";height:64px;box-sizing:border-box;", ";", ";"], ({
suppressed,
bordered,
theme
}) => suppressed && !bordered ? theme.orbit.paletteCloudLight : theme.orbit.paletteWhite, ({
bordered,
theme
}) => bordered && css(["border-bottom:1px solid ", ";"], theme.orbit.paletteCloudNormal), ({
noPadding,
theme
}) => !noPadding && css(["padding:0 ", ";", ";"], theme.orbit.spaceMedium, mq.largeMobile(css(["padding:", ";"], rtlSpacing(`0 ${theme.orbit.spaceMedium} 0 ${theme.orbit.spaceXLarge}`)))));
StyledDrawerHeader.defaultProps = {
theme: defaultTheme
};
const Drawer = ({
children,
onClose,
shown = true,
width = "320px",
position = POSITIONS.RIGHT,
dataTest,
noPadding,
suppressed,
title,
actions
}) => {
const theme = useTheme();
const overlayRef = useRef(null);
const timeoutLength = useMemo(() => parseFloat(theme.orbit.durationNormal) * 1000, [theme.orbit.durationNormal]);
const [overlayShown, setOverlayShown, setOverlayShownWithTimeout] = useStateWithTimeout(shown, timeoutLength);
const handleOnClose = useCallback(ev => {
if (onClose && ev.target === overlayRef.current) {
onClose();
}
}, [onClose]);
useEffect(() => {
if (overlayShown !== shown) {
if (shown) {
setOverlayShown(true);
} else if (!shown) {
setOverlayShownWithTimeout(false);
}
}
}, [overlayShown, setOverlayShown, setOverlayShownWithTimeout, shown]);
return React.createElement(StyledDrawer, {
role: "button",
overlayShown: overlayShown,
shown: shown,
onClick: handleOnClose,
"data-test": dataTest,
"aria-hidden": !shown,
ref: overlayRef
}, React.createElement(StyledDrawerSide, {
shown: shown,
width: width,
position: position,
role: "navigation",
suppressed: suppressed
}, (title || actions || onClose) && React.createElement(StyledDrawerHeader, {
bordered: title || actions,
suppressed: suppressed
}, title && React.createElement(Heading, {
type: "title2"
}, title), actions && React.createElement(Stack, {
spacing: "none",
justify: "end",
flex: true,
shrink: true
}, actions), onClose && React.createElement(DrawerClose, {
onClick: onClose
})), React.createElement(StyledDrawerContent, {
noPadding: noPadding,
hasClose: !!onClose,
hasTopPadding: title || actions
}, children)));
};
export default Drawer;