All files / owid-grapher/grapher/chart Tippy.tsx

64.56% Statements 51/79
100% Branches 1/1
33.33% Functions 1/3
64.56% Lines 51/79

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 571x 1x 1x 1x 1x 1x 1x 1x 38x 38x 38x 38x 38x 1x 1x 1x 1x 1x                                             1x 1x 1x 1x 1x 1x 1x 1x 1x 1x             1x
import * as React from "react"
import { default as OriginalTippy, TippyProps } from "@tippyjs/react"
 
interface CustomTippyProps extends TippyProps {
    lazy?: boolean
}
 
export const Tippy = (props: CustomTippyProps): JSX.Element => {
    const { lazy, ...tippyProps } = props
 
    const TippyInstance = lazy ? LazyTippy : OriginalTippy
    return <TippyInstance theme="light" {...tippyProps} />
}
 
// A Tippy instance that only evaluates `content` when the tooltip is shown.
// Taken from https://gist.github.com/atomiks/520f4b0c7b537202a23a3059d4eec908
// This will hopefully become supported in Tippy itself someday: See https://github.com/atomiks/tippyjs-react/issues/209
export const LazyTippy = (props: TippyProps): React.ReactElement => {
    const [mounted, setMounted] = React.useState(false)

    const lazyPlugin = {
        fn: () => ({
            onMount: () => setMounted(true),
            onHidden: () => setMounted(false),
        }),
    }

    const computedProps = { ...props }

    computedProps.plugins = [lazyPlugin, ...(props.plugins || [])]

    if (props.render) {
        const render = props.render // let TypeScript safely derive that render is not undefined
        computedProps.render = (...args) => (mounted ? render(...args) : "")
    } else {
        computedProps.content = mounted ? props.content : ""
    }

    return <Tippy {...computedProps} />
}
 
interface TippyIfInteractiveProps extends CustomTippyProps {
    isInteractive: boolean
}
 
// We sometimes need a conditional Tippy instance, i.e. a Tippy that is only hooked up to
// interactive charts (and not in static SVG exports etc.). This is that: If `isInteractive=false`,
// then it bypasses Tippy and just renders the children.
export const TippyIfInteractive = (
    props: TippyIfInteractiveProps
): JSX.Element => {
    const { isInteractive, ...tippyProps } = props

    if (isInteractive) return <Tippy {...tippyProps} />
    else return <>{props.children}</>
}