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