@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.
195 lines (192 loc) • 7.65 kB
JavaScript
import React, { useRef, useMemo, useCallback } from "react";
import styled, { css } from "styled-components";
import useTheme from "../../hooks/useTheme";
import resolveContainerPosition from "../helpers/resolveContainerPosition";
import resolveTooltipArrowAlign from "../helpers/resolveTooltipArrowAlign";
import resolveTooltipArrowPosition from "../helpers/resolveTooltipArrowPosition";
import { StyledText } from "../../Text/index";
import { Item } from "../../List/ListItem/index";
import media from "../../utils/mediaQuery/index";
import tooltipSize from "../helpers/tooltipSize";
import resolveContainerAlign from "../helpers/resolveContainerAlign";
import tooltipArrowStyle from "../helpers/tooltipArrowStyle";
import tooltipPadding from "../helpers/tooltipPadding";
import defaultTheme from "../../defaultTheme";
import Button from "../../Button";
import Translate from "../../Translate";
import calculateTooltipPosition from "../helpers/calculateTooltipPosition";
import calculateTooltipAlign from "../helpers/calculateTooltipAlign";
import sortPositionsAndAligns from "../helpers/sortPositionsAndAligns";
import useDimensions from "../hooks/useDimensions";
const StyledTooltip = styled.div.withConfig({
displayName: "TooltipContent__StyledTooltip",
componentId: "sc-1umu28w-0"
})(["width:100%;"]);
const StyledTooltipWrapper = styled.div.withConfig({
displayName: "TooltipContent__StyledTooltipWrapper",
componentId: "sc-1umu28w-1"
})(["display:block;position:fixed;width:100%;box-sizing:border-box;border-top-left-radius:9px;border-top-right-radius:9px;background-color:", ";box-shadow:", ";padding:", ";visibility:", ";opacity:", ";transition:bottom ", " ease-in-out,visibility ", " linear ", ";z-index:10012;bottom:", ";left:0;right:0;max-height:", ";overflow-y:scroll;img{max-width:100%;}", ";&::after{width:0;height:0;border-style:solid;content:\" \";display:none;position:absolute;", ";", ";", ";", ";}"], ({
theme
}) => theme.orbit.paletteWhite, ({
theme
}) => theme.orbit.boxShadowElevatedLevel1, ({
theme
}) => theme.orbit.spaceMedium, ({
shownMobile
}) => shownMobile ? "visible" : "hidden", ({
shownMobile
}) => shownMobile ? "1" : "0", ({
theme
}) => theme.orbit.durationNormal, ({
theme
}) => theme.orbit.durationFast, ({
shownMobile,
theme
}) => !shownMobile && theme.orbit.durationNormal, ({
shownMobile,
tooltipWidth
}) => shownMobile ? "0" : `-${tooltipWidth}px`, ({
theme
}) => `calc(100% - ${theme.orbit.spaceXLarge})`, media.largeMobile(css(["max-height:none;overflow:visible;width:auto;position:absolute;max-width:", ";border-radius:", ";padding:", ";background-color:", ";visibility:", ";opacity:", ";transition:opacity ", " ease-in-out,visibility ", " ease-in-out;top:auto;right:auto;bottom:auto;left:auto;", ";", ";"], tooltipSize, ({
theme
}) => theme.orbit.borderRadiusNormal, tooltipPadding, ({
theme
}) => theme.orbit.paletteBlueDark, ({
shown
}) => shown ? "visible" : "hidden", ({
shown
}) => shown ? "1" : "0", ({
theme
}) => theme.orbit.durationFast, ({
theme
}) => theme.orbit.durationFast, resolveContainerPosition, resolveContainerAlign)), tooltipArrowStyle, resolveTooltipArrowPosition, resolveTooltipArrowAlign, media.largeMobile(css(["display:block;"])));
StyledTooltipWrapper.defaultProps = {
theme: defaultTheme
};
const StyledTooltipContent = styled.div.withConfig({
displayName: "TooltipContent__StyledTooltipContent",
componentId: "sc-1umu28w-2"
})(["font-family:", ";font-size:", ";font-weight:", ";line-height:", ";color:", ";margin-bottom:16px;& ", ",", "{font-size:", ";font-weight:", ";color:", ";}", ";"], ({
theme
}) => theme.orbit.fontFamily, ({
theme
}) => theme.orbit.fontSizeTextNormal, ({
theme
}) => theme.orbit.fontWeightNormal, ({
theme
}) => theme.orbit.lineHeightText, ({
theme
}) => theme.orbit.paletteInkNormal, StyledText, Item, ({
theme
}) => theme.orbit.fontSizeTextNormal, ({
theme
}) => theme.orbit.fontWeightNormal, ({
theme
}) => theme.orbit.paletteInkNormal, media.largeMobile(css(["color:", ";font-size:", ";font-weight:", ";margin-bottom:0;& ", ",", "{color:", ";font-weight:", ";font-size:", ";}"], ({
theme
}) => theme.orbit.paletteWhite, ({
theme
}) => theme.orbit.fontSizeTextSmall, ({
theme
}) => theme.orbit.fontWeightMedium, StyledText, Item, ({
theme
}) => theme.orbit.paletteWhite, ({
theme
}) => theme.orbit.fontWeightMedium, ({
theme
}) => theme.orbit.fontSizeTextSmall)));
StyledTooltipContent.defaultProps = {
theme: defaultTheme
};
const StyledTooltipClose = styled.div.withConfig({
displayName: "TooltipContent__StyledTooltipClose",
componentId: "sc-1umu28w-3"
})(["", ""], media.largeMobile(css(["display:none;visibility:hidden;"])));
StyledTooltipClose.defaultProps = {
theme: defaultTheme
};
const StyledTooltipOverlay = styled.div.withConfig({
displayName: "TooltipContent__StyledTooltipOverlay",
componentId: "sc-1umu28w-4"
})(["position:fixed;display:block;visibility:", ";width:100%;height:100%;top:0;right:0;bottom:0;left:0;background-color:rgba(23,27,30,0.6);z-index:10011;opacity:", ";transition:opacity ", " ease-in-out,visibility ", " linear ", ";", ";"], ({
shownMobile
}) => shownMobile ? "visible" : "hidden", ({
shownMobile
}) => shownMobile ? "1" : "0", ({
theme
}) => theme.orbit.durationNormal, ({
theme
}) => theme.orbit.durationFast, ({
shownMobile,
theme
}) => !shownMobile && theme.orbit.durationNormal, media.largeMobile(css(["display:none;visibility:hidden;"])));
StyledTooltipOverlay.defaultProps = {
theme: defaultTheme
};
const TooltipContent = ({
dataTest,
shownMobile,
shown,
size,
tooltipId,
children,
onClose,
onCloseMobile,
onEnter,
preferredPosition,
containerRef
}) => {
const theme = useTheme();
const overlay = useRef(null);
const tooltip = useRef(null);
const content = useRef(null);
const [positions, aligns] = useMemo(() => sortPositionsAndAligns(preferredPosition, theme), [preferredPosition, theme]);
const dimensions = useDimensions({
containerRef,
tooltip,
content
}, children);
const position = useMemo(() => calculateTooltipPosition(positions, dimensions), [dimensions, positions]);
const align = useMemo(() => calculateTooltipAlign(position, aligns, dimensions), [aligns, dimensions, position]);
const handleClickOutside = useCallback(ev => {
ev.stopPropagation();
if (ev.target === overlay.current) {
onCloseMobile();
}
}, [onCloseMobile]);
return React.createElement(StyledTooltip, {
"data-test": dataTest
}, React.createElement(StyledTooltipOverlay, {
shownMobile: shownMobile,
ref: overlay,
onClick: handleClickOutside
}), React.createElement(StyledTooltipWrapper, {
shown: shown && position && align,
shownMobile: shownMobile,
size: size,
align: align,
position: position,
ref: tooltip,
containerTop: dimensions.containerTop,
containerLeft: dimensions.containerLeft,
containerHeight: dimensions.containerHeight,
containerWidth: dimensions.containerWidth,
tooltipHeight: dimensions.tooltipHeight,
tooltipWidth: dimensions.tooltipWidth,
contentHeight: dimensions.contentHeight,
role: "tooltip",
"aria-hidden": !shown && !shownMobile,
id: tooltipId,
onMouseEnter: onEnter,
onMouseLeave: onClose
}, React.createElement(StyledTooltipContent, {
ref: content
}, children), React.createElement(StyledTooltipClose, null, React.createElement(Button, {
type: "secondary",
block: true,
onClick: onCloseMobile
}, React.createElement(Translate, {
tKey: "button_close"
})))));
};
export default TooltipContent;