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.

195 lines (192 loc) 7.65 kB
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;