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.

93 lines (90 loc) 3.42 kB
import React, { useState, useRef, useMemo, useCallback } from "react"; import styled, { css } from "styled-components"; import { getBreakpointWidth } from "../utils/mediaQuery"; import { SIZE_OPTIONS } from "./consts"; import { StyledText } from "../Text"; import Portal from "../Portal"; import RandomID from "../utils/randomID"; import { QUERIES } from "../utils/mediaQuery/consts"; import useTheme from "../hooks/useTheme"; import TooltipContent from "./components/TooltipContent"; import useStateWithTimeout from "../hooks/useStateWithTimeout"; const StyledTooltipChildren = styled.span.withConfig({ displayName: "Tooltip__StyledTooltipChildren", componentId: "sc-1l15bi-0" })(["display:inline-flex;&:focus:active{outline:none;}", ";"], ({ enabled, removeUnderlinedText }) => enabled && !removeUnderlinedText && css(["", "{display:inline-block;text-decoration:underline;text-decoration:underline currentColor dotted;}"], StyledText)); const Tooltip = ({ children, enabled = true, tabIndex = "0", dataTest, size = SIZE_OPTIONS.SMALL, content, preferredPosition, stopPropagation = false, removeUnderlinedText }) => { const theme = useTheme(); const [shown, setShown] = useState(false); const [render, setRender, setRenderWithTimeout, clearRenderTimeout] = useStateWithTimeout(false, 200); const [shownMobile, setShownMobile, setShownMobileWithTimeout] = useStateWithTimeout(false, 200); const tooltipId = useMemo(() => RandomID("tooltip"), []); const container = useRef(null); const handleIn = useCallback(() => { if (window.innerWidth > +getBreakpointWidth(QUERIES.LARGEMOBILE, theme, true)) { setRender(true); setShown(true); clearRenderTimeout(); } }, [clearRenderTimeout, setRender, theme]); const handleOut = useCallback(() => { if (window.innerWidth > +getBreakpointWidth(QUERIES.LARGEMOBILE, theme, true)) { setShown(false); setRenderWithTimeout(false); } }, [setRenderWithTimeout, theme]); const handleInMobile = useCallback(ev => { if (stopPropagation) { ev.stopPropagation(); } if (window.innerWidth <= +getBreakpointWidth(QUERIES.LARGEMOBILE, theme, true)) { ev.preventDefault(); setRender(true); setShownMobileWithTimeout(true); clearRenderTimeout(); } }, [clearRenderTimeout, setRender, setShownMobileWithTimeout, stopPropagation, theme]); const handleOutMobile = useCallback(() => { setShownMobile(false); setRenderWithTimeout(false); }, [setRenderWithTimeout, setShownMobile]); return React.createElement(React.Fragment, null, React.createElement(StyledTooltipChildren, { onMouseEnter: handleIn, onMouseLeave: handleOut, onClick: handleInMobile, onFocus: handleIn, onBlur: handleOut, ref: container, "aria-describedby": enabled ? tooltipId : undefined, tabIndex: enabled ? tabIndex : undefined, enabled: enabled, removeUnderlinedText: removeUnderlinedText }, children), enabled && render && React.createElement(Portal, { renderInto: "tooltips" }, React.createElement(TooltipContent, { dataTest: dataTest, shownMobile: shownMobile, shown: shown, size: size, tooltipId: tooltipId, onClose: handleOut, onCloseMobile: handleOutMobile, onEnter: handleIn, preferredPosition: preferredPosition, containerRef: container }, content))); }; export default Tooltip;