UNPKG

@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
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;