@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.
136 lines (134 loc) • 4.99 kB
JavaScript
import React, { useRef, useEffect } from "react";
import styled, { css } from "styled-components";
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";
const StyledPopoverParent = styled.div.withConfig({
displayName: "ContentWrapper__StyledPopoverParent",
componentId: "v01g55-0"
})(["position:fixed;bottom:0;left:0;right:0;width:100%;box-sizing:border-box;border-top-left-radius:9px;border-top-right-radius:9px;background-color:", ";padding:", ";box-shadow:", ";overflow:hidden;z-index:1000;transition:", ";transform:translateY(", ");&:focus{outline:0;}", ""], ({
theme
}) => theme.orbit.backgroundModal, ({
theme,
noPadding
}) => noPadding ? 0 : theme.orbit.spaceMedium, ({
theme
}) => theme.orbit.boxShadowElevatedLevel1, transition(["opacity", "transform"], "fast", "ease-in-out"), ({
shownMobile
}) => shownMobile ? "0%" : "100%", media.largeMobile(css(["position:", ";left:auto;right:auto;bottom:auto;width:", ";opacity:", ";transform:none;border-radius:", ";", " ", ""], ({
fixed
}) => fixed ? "fixed" : "absolute", ({
width
}) => width ? `${width}` : "auto", ({
shown
}) => shown ? "1" : "0", ({
theme
}) => theme.orbit.borderRadiusNormal, resolvePopoverPosition, resolvePopoverHorizontal)));
StyledPopoverParent.defaultProps = {
theme: defaultTheme
};
const StyledPopoverContent = styled.div.withConfig({
displayName: "ContentWrapper__StyledPopoverContent",
componentId: "v01g55-1"
})([""]);
const StyledOverlay = styled.div.withConfig({
displayName: "ContentWrapper__StyledOverlay",
componentId: "v01g55-2"
})(["display:block;position:fixed;opacity:", ";top:0;left:0;right:0;width:100%;height:100%;background-color:rgba(23,27,30,0.6);transition:opacity ", " ease-in-out;z-index:999;", ";"], ({
shown
}) => shown ? "1" : "0", ({
theme
}) => theme.orbit.durationNormal, media.largeMobile(css(["display:none;"])));
StyledOverlay.defaultProps = {
theme: defaultTheme
};
const StyledPopoverClose = styled.div.withConfig({
displayName: "ContentWrapper__StyledPopoverClose",
componentId: "v01g55-3"
})(["padding:", ";padding-top:", ";", ""], ({
theme,
noPadding
}) => noPadding ? theme.orbit.spaceMedium : 0, ({
theme
}) => theme.orbit.spaceMedium, media.largeMobile(css(["display:none;visibility:hidden;padding-bottom:0;"])));
StyledPopoverClose.defaultProps = {
theme: defaultTheme
};
const PopoverContentWrapper = ({
children,
onClose,
width,
dataTest,
preferredPosition,
containerRef,
noPadding,
overlapped,
shown,
fixed
}) => {
const popover = useRef(null);
const content = useRef(null);
const overlay = useRef(null);
const position = calculatePopoverPosition(preferredPosition);
const dimensions = useDimensions({
containerRef,
popover,
content,
fixed
});
const verticalPosition = calculateVerticalPosition(position[0], dimensions);
const horizontalPosition = calculateHorizontalPosition(position[1], dimensions);
useEffect(() => {
const timer = setTimeout(() => {
if (popover.current) {
popover.current.focus();
}
}, 100);
return () => clearTimeout(timer);
}, []);
useClickOutside(popover, onClose);
return React.createElement(React.Fragment, null, React.createElement(StyledOverlay, {
ref: overlay,
shown: shown
}), 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
}, React.createElement(StyledPopoverContent, {
ref: content
}, children, React.createElement(StyledPopoverClose, {
noPadding: noPadding
}, React.createElement(Button, {
type: "secondary",
block: true,
onClick: onClose
}, React.createElement(Translate, {
tKey: "button_close"
}))))));
};
export default PopoverContentWrapper;