-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathgraph-tooltip.tsx
More file actions
65 lines (62 loc) · 1.72 KB
/
graph-tooltip.tsx
File metadata and controls
65 lines (62 loc) · 1.72 KB
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
57
58
59
60
61
62
63
64
65
import React, { ReactNode, useLayoutEffect, useRef, useState } from 'react'
import { Transition } from '@headlessui/react'
export const GraphTooltipWrapper = ({
x,
y,
maxX,
minWidth,
children,
className,
onClick,
isTouchDevice
}: {
x: number
y: number
maxX: number
minWidth: number
children: ReactNode
className?: string
onClick?: () => void
isTouchDevice?: boolean
}) => {
const ref = useRef<HTMLDivElement>(null)
// bigger on mobile to have room between thumb and tooltip
const xOffsetFromCursor = isTouchDevice ? 24 : 12
const yOffsetFromCursor = isTouchDevice ? 48 : 24
const [measuredWidth, setMeasuredWidth] = useState(minWidth)
// center tooltip above the cursor, clamped to prevent left/right overflow
const rawLeft = x + xOffsetFromCursor
const tooltipLeft = Math.max(0, Math.min(rawLeft, maxX - measuredWidth))
useLayoutEffect(() => {
if (!ref.current) {
return
}
setMeasuredWidth(ref.current.offsetWidth)
}, [children, className, minWidth])
return (
<Transition
as={React.Fragment}
appear
show
// enter delay on mobile is needed to prevent the tooltip from entering when the user starts to y-pan
// but the y-pan is not yet certain
enter={isTouchDevice ? 'transition-opacity duration-0 delay-150' : ''}
enterFrom={isTouchDevice ? 'opacity-0' : ''}
enterTo={isTouchDevice ? 'opacity-100' : ''}
>
<div
ref={ref}
className={className}
onClick={onClick}
style={{
minWidth,
left: tooltipLeft,
top: y,
transform: `translateY(-100%) translateY(-${yOffsetFromCursor}px)`
}}
>
{children}
</div>
</Transition>
)
}