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.

253 lines (244 loc) 10.1 kB
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import * as React from "react"; import styled, { css } from "styled-components"; import convertHexToRgba from "@kiwicom/orbit-design-tokens/lib/convertHexToRgba"; import defaultTheme from "../../defaultTheme"; import media from "../../utils/mediaQuery"; import Button from "../../Button"; import resolvePopoverPosition from "../helpers/resolvePopoverPosition"; import resolvePopoverHorizontal from "../helpers/resolvePopoverHorizontal"; import calculatePopoverPosition from "../helpers/calculatePopoverPosition"; import calculateVerticalPosition from "../helpers/calculateVerticalPosition"; import calculateHorizontalPosition from "../helpers/calculateHorizontalPosition"; import useDimensions from "../hooks/useDimensions"; import Translate from "../../Translate"; import transition from "../../utils/transition"; import useClickOutside from "../../hooks/useClickOutside"; import { ModalContext } from "../../Modal/ModalContext"; import boundingClientRect from "../../utils/boundingClientRect"; import getScrollableParent from "../helpers/getScrollableParent"; import { StyledButtonPrimitive } from "../../primitives/ButtonPrimitive"; var useRef = React.useRef, useEffect = React.useEffect, useContext = React.useContext, useMemo = React.useMemo, useCallback = React.useCallback; var mobileTop = function mobileTop(theme) { return theme.orbit.spaceXLarge; }; var popoverPadding = function popoverPadding(theme) { return theme.orbit.spaceMedium; }; var StyledContentWrapper = styled.div.attrs(function (props) { return { style: { bottom: props.actionsHeight ? props.actionsHeight : 0, // Calculates all the spacing relative to viewport to get space for action box // 32 here is the fixed gap from the top, same with modal. maxHeight: "".concat(props.windowHeight - props.actionsHeight - 32, "px") } }; }).withConfig({ displayName: "ContentWrapper__StyledContentWrapper", componentId: "v01g55-0" })(["overflow:auto;border-top-left-radius:12px;border-top-right-radius:12px;position:absolute;left:0;width:100%;background-color:", ";", ";"], function (_ref) { var theme = _ref.theme; return theme.orbit.paletteWhite; }, media.largeMobile(css(["max-height:100%;border-radius:3px;bottom:auto;left:auto;position:relative;"]))); StyledContentWrapper.defaultProps = { theme: defaultTheme }; var StyledActions = styled.div.withConfig({ displayName: "ContentWrapper__StyledActions", componentId: "v01g55-1" })(["position:fixed;bottom:0;left:0;width:100%;box-sizing:border-box;padding:", ";padding-top:", ";background-color:", ";", "{width:100%;flex:1 1 auto;}", ";"], function (_ref2) { var theme = _ref2.theme; return popoverPadding(theme); }, function (_ref3) { var theme = _ref3.theme; return theme.orbit.spaceSmall; }, function (_ref4) { var theme = _ref4.theme; return theme.orbit.paletteWhite; }, StyledButtonPrimitive, media.largeMobile(css(["position:relative;bottom:auto;left:auto;", "{width:auto;flex-grow:0;}"], StyledButtonPrimitive))); StyledActions.defaultProps = { theme: defaultTheme }; var StyledPopoverParent = styled.div.withConfig({ displayName: "ContentWrapper__StyledPopoverParent", componentId: "v01g55-2" })(["position:fixed;bottom:0;left:0;right:0;width:100%;height:auto;box-sizing:border-box;background-color:", ";box-shadow:", ";z-index:1000;transition:", ";transform:translateY(", ");max-height:", ";&:focus{outline:0;}", ""], function (_ref5) { var theme = _ref5.theme; return theme.orbit.backgroundModal; }, function (_ref6) { var theme = _ref6.theme; return theme.orbit.boxShadowRaisedReverse; }, transition(["opacity", "transform"], "fast", "ease-in-out"), function (_ref7) { var shownMobile = _ref7.shownMobile; return shownMobile ? "0%" : "100%"; }, function (_ref8) { var theme = _ref8.theme; return "calc(100% - ".concat(mobileTop(theme), ")"); }, media.largeMobile(css(["z-index:", ";position:", ";left:auto;right:auto;bottom:auto;width:", ";opacity:", ";transform:none;border-radius:", ";box-shadow:", ";max-height:none;", " ", ""], function (_ref9) { var isInsideModal = _ref9.isInsideModal; return isInsideModal ? "1000" : "600"; }, function (_ref10) { var fixed = _ref10.fixed; return fixed ? "fixed" : "absolute"; }, function (_ref11) { var width = _ref11.width; return width ? "".concat(width) : "auto"; }, function (_ref12) { var shown = _ref12.shown; return shown ? "1" : "0"; }, function (_ref13) { var theme = _ref13.theme; return theme.orbit.borderRadiusNormal; }, function (_ref14) { var theme = _ref14.theme; return theme.orbit.boxShadowRaised; }, resolvePopoverPosition, resolvePopoverHorizontal))); StyledPopoverParent.defaultProps = { theme: defaultTheme }; var StyledPopoverPadding = styled.div.withConfig({ displayName: "ContentWrapper__StyledPopoverPadding", componentId: "v01g55-3" })(["padding:", ";"], function (_ref15) { var noPadding = _ref15.noPadding, theme = _ref15.theme; return noPadding ? 0 : popoverPadding(theme); }); StyledPopoverPadding.defaultProps = { theme: defaultTheme }; var StyledPopoverContent = styled.div.withConfig({ displayName: "ContentWrapper__StyledPopoverContent", componentId: "v01g55-4" })([""]); var StyledOverlay = styled.div.withConfig({ displayName: "ContentWrapper__StyledOverlay", componentId: "v01g55-5" })(["display:block;position:fixed;opacity:", ";top:0;left:0;right:0;width:100%;height:100%;background-color:", ";transition:", ";z-index:999;", ";"], function (_ref16) { var shown = _ref16.shown; return shown ? "1" : "0"; }, function (_ref17) { var theme = _ref17.theme; return convertHexToRgba(theme.orbit.paletteInkNormal, 60); }, transition(["opacity"], "normal", "ease-in-out"), media.largeMobile(css(["display:none;"]))); StyledOverlay.defaultProps = { theme: defaultTheme }; var StyledPopoverClose = styled.div.withConfig({ displayName: "ContentWrapper__StyledPopoverClose", componentId: "v01g55-6" })(["padding:", ";", ""], function (_ref18) { var theme = _ref18.theme; return popoverPadding(theme); }, media.largeMobile(css(["display:none;visibility:hidden;padding-bottom:0;"]))); StyledPopoverClose.defaultProps = { theme: defaultTheme }; var PopoverContentWrapper = function PopoverContentWrapper(_ref19) { var children = _ref19.children, onClose = _ref19.onClose, width = _ref19.width, dataTest = _ref19.dataTest, preferredPosition = _ref19.preferredPosition, preferredAlign = _ref19.preferredAlign, containerRef = _ref19.containerRef, noPadding = _ref19.noPadding, overlapped = _ref19.overlapped, shown = _ref19.shown, fixed = _ref19.fixed, actions = _ref19.actions; var _useContext = useContext(ModalContext), isInsideModal = _useContext.isInsideModal; var popover = useRef(null); var content = useRef(null); var intervalRef = useRef(null); var position = calculatePopoverPosition(preferredPosition, preferredAlign); var scrollableParent = useMemo(function () { return getScrollableParent(containerRef.current); }, [containerRef]); var dimensions = useDimensions({ containerRef: containerRef, popover: popover, content: content, fixed: fixed, scrollableParent: scrollableParent, children: children }); var verticalPosition = calculateVerticalPosition(position[0], dimensions); var horizontalPosition = calculateHorizontalPosition(position[1], dimensions); var _React$useState = React.useState(0), _React$useState2 = _slicedToArray(_React$useState, 2), actionsDimensions = _React$useState2[0], setActionsDimensions = _React$useState2[1]; var windowHeight = typeof window !== "undefined" ? window.innerHeight : 0; var measuredRef = useCallback(function (node) { if (node !== null) { var timer = setTimeout(function () { setActionsDimensions(boundingClientRect({ current: node })); }, 15); intervalRef.current = timer; } }, [actions]); useEffect(function () { var timer = setTimeout(function () { if (popover.current) { popover.current.focus(); } }, 100); return function () { clearTimeout(timer); clearTimeout(intervalRef.current); }; }, []); useClickOutside(popover, onClose); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StyledOverlay, { shown: shown, isInsideModal: isInsideModal }), /*#__PURE__*/React.createElement(StyledPopoverParent, { shownMobile: shown, shown: shown && verticalPosition && horizontalPosition, anchor: horizontalPosition, position: verticalPosition, containerTop: dimensions.containerTop, containerLeft: dimensions.containerLeft, containerPureTop: dimensions.containerPureTop, containerHeight: dimensions.containerHeight, containerWidth: dimensions.containerWidth, popoverHeight: dimensions.popoverHeight, popoverWidth: dimensions.popoverWidth, width: width, ref: popover, tabIndex: "0", "data-test": dataTest, noPadding: noPadding, overlapped: overlapped, role: "tooltip", fixed: fixed, isInsideModal: isInsideModal }, /*#__PURE__*/React.createElement(StyledPopoverContent, { ref: content }, /*#__PURE__*/React.createElement(StyledContentWrapper, { actionsHeight: actionsDimensions ? actionsDimensions.height : 0, windowHeight: windowHeight }, /*#__PURE__*/React.createElement(StyledPopoverPadding, { noPadding: noPadding }, children)), actions ? /*#__PURE__*/React.createElement(StyledActions, { ref: measuredRef }, actions) : /*#__PURE__*/React.createElement(StyledPopoverClose, { ref: measuredRef }, /*#__PURE__*/React.createElement(Button, { type: "secondary", fullWidth: true, onClick: onClose }, /*#__PURE__*/React.createElement(Translate, { tKey: "button_close" })))))); }; export default PopoverContentWrapper;