-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
Slice.tsx
85 lines (77 loc) · 2.43 KB
/
Slice.tsx
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import React, { createElement, useCallback } from 'react'
import { animated, Interpolation } from 'react-spring'
import { useTooltip } from '@nivo/tooltip'
import { ComputedDatum, CompletePieSvgProps } from './types'
interface SliceProps<RawDatum> {
datum: ComputedDatum<RawDatum>
path: string | Interpolation<string>
borderWidth: number
borderColor: string
isInteractive: boolean
tooltip: CompletePieSvgProps<RawDatum>['tooltip']
onClick: CompletePieSvgProps<RawDatum>['onClick']
onMouseEnter: CompletePieSvgProps<RawDatum>['onMouseEnter']
onMouseMove: CompletePieSvgProps<RawDatum>['onMouseMove']
onMouseLeave: CompletePieSvgProps<RawDatum>['onMouseLeave']
setActiveId: (id: null | string | number) => void
}
export const Slice = <RawDatum,>({
datum,
path,
borderWidth,
borderColor,
isInteractive,
onClick,
onMouseEnter,
onMouseMove,
onMouseLeave,
tooltip,
setActiveId,
}: SliceProps<RawDatum>) => {
const { showTooltipFromEvent, hideTooltip } = useTooltip()
const handleTooltip = useCallback(
event => showTooltipFromEvent(createElement(tooltip, { datum }), event),
[showTooltipFromEvent, datum, tooltip]
)
const handleMouseEnter = useCallback(
event => {
onMouseEnter?.(datum, event)
setActiveId(datum.id)
handleTooltip(event)
},
[onMouseEnter, setActiveId, handleTooltip, datum]
)
const handleMouseMove = useCallback(
event => {
onMouseMove?.(datum, event)
handleTooltip(event)
},
[onMouseMove, handleTooltip, datum]
)
const handleMouseLeave = useCallback(
event => {
onMouseLeave?.(datum, event)
setActiveId(null)
hideTooltip()
},
[onMouseLeave, hideTooltip, datum]
)
const handleClick = useCallback(
event => {
onClick?.(datum, event)
},
[onClick, datum]
)
return (
<animated.path
d={path}
fill={datum.fill || datum.color}
strokeWidth={borderWidth}
stroke={borderColor}
onMouseEnter={isInteractive ? handleMouseEnter : undefined}
onMouseMove={isInteractive ? handleMouseMove : undefined}
onMouseLeave={isInteractive ? handleMouseLeave : undefined}
onClick={isInteractive ? handleClick : undefined}
/>
)
}