Skip to content

Commit

Permalink
feat(tooltip): replace react-motion by react-spring
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed Jun 17, 2020
1 parent 6ce539c commit a5850bc
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 85 deletions.
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"dist/"
],
"dependencies": {
"@nivo/tooltip": "0.62.0",
"d3-color": "^1.2.3",
"d3-format": "^1.4.4",
"d3-hierarchy": "^1.1.8",
Expand All @@ -31,6 +30,7 @@
"recompose": "^0.30.0"
},
"peerDependencies": {
"@nivo/tooltip": "0.62.0",
"prop-types": ">= 15.5.10 < 16.0.0",
"react": ">= 16.8.4 < 17.0.0"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/tooltip/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
"dist/"
],
"dependencies": {
"@nivo/core": "0.62.0",
"react-measure": "^2.2.4",
"react-motion": "^0.5.2"
"react-spring": "^8.0.27"
},
"peerDependencies": {
"@nivo/core": "0.62.0",
"prop-types": ">= 15.5.10 < 16.0.0"
},
"publishConfig": {
Expand Down
37 changes: 11 additions & 26 deletions packages/tooltip/src/components/CrosshairLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
*/
import React, { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { Motion, spring } from 'react-motion'
import { useSpring, animated } from 'react-spring'
import { useTheme, useMotionConfig } from '@nivo/core'

const CrosshairLine = memo(({ x0, x1, y0, y1 }) => {
const theme = useTheme()
const { animate, springConfig } = useMotionConfig()
const { animate, config: springConfig } = useMotionConfig()
const style = useMemo(
() => ({
...theme.crosshair.line,
Expand All @@ -22,31 +22,16 @@ const CrosshairLine = memo(({ x0, x1, y0, y1 }) => {
[theme.crosshair.line]
)

if (animate !== true) {
return <line x1={x0} x2={x1} y1={y0} y2={y1} fill="none" style={style} />
}
const animatedProps = useSpring({
x1: x0,
x2: x1,
y1: y0,
y2: y1,
config: springConfig,
immediate: !animate,
})

return (
<Motion
style={{
x0: spring(x0, springConfig),
x1: spring(x1, springConfig),
y0: spring(y0, springConfig),
y1: spring(y1, springConfig),
}}
>
{line => (
<line
x1={line.x0}
x2={line.x1}
y1={line.y0}
y2={line.y1}
fill="none"
style={style}
/>
)}
</Motion>
)
return <animated.line {...animatedProps} fill="none" style={style} />
})

CrosshairLine.displayName = 'CrosshairLine'
Expand Down
96 changes: 40 additions & 56 deletions packages/tooltip/src/components/TooltipWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { memo, useMemo, useState } from 'react'
import React, { memo, useMemo, useState, useRef, useEffect } from 'react'
import PropTypes from 'prop-types'
import Measure from 'react-measure'
import { Motion, spring } from 'react-motion'
import { useSpring, animated } from 'react-spring'
import { useTheme, useMotionConfig } from '@nivo/core'

const TOOLTIP_OFFSET = 14
Expand All @@ -23,9 +23,14 @@ const tooltipStyle = {
}

const TooltipWrapper = memo(({ position, anchor, children }) => {
const [dimensions, setDimensions] = useState(null)
const theme = useTheme()
const { animate, springConfig } = useMotionConfig()
const { animate, config: springConfig } = useMotionConfig()

const [dimensions, setDimensions] = useState(null)
const previousDimensions = useRef(null)
useEffect(() => {
previousDimensions.current = dimensions
})

let x = Math.round(position[0])
let y = Math.round(position[1])
Expand All @@ -48,71 +53,50 @@ const TooltipWrapper = memo(({ position, anchor, children }) => {
}
}

const isInitializing = dimensions === null || previousDimensions.current === null

const animatedProps = useSpring({
transform: `translate(${x}px, ${y}px)`,
config: springConfig,
immediate: !animate || isInitializing,
})

const style = useMemo(
() => ({
...tooltipStyle,
...theme.tooltip,
transform: `translate(${x}px, ${y}px)`,
opacity: dimensions === null ? 0 : 1,
opacity: isInitializing ? 0 : 1,
}),
[x, y, dimensions, theme.tooltip]
[dimensions, theme.tooltip, isInitializing]
)

// if we don't have dimensions yet, we use
// the non animated version with a 0 opacity
// to avoid a flash effect and weird initial transition
if (animate !== true || dimensions === null) {
return (
<Measure
client={false}
offset={false}
bounds={true}
margin={false}
onResize={({ bounds }) => {
setDimensions([bounds.width, bounds.height])
}}
>
{({ measureRef }) => (
<div ref={measureRef} style={style}>
{children}
</div>
)}
</Measure>
)
}

return (
<Motion
style={{
x: spring(x, springConfig),
y: spring(y, springConfig),
<Measure
client={false}
offset={false}
bounds={true}
margin={false}
onResize={({ bounds }) => {
setDimensions([bounds.width, bounds.height])
}}
>
{animatedPosition => (
<Measure
client={false}
offset={false}
bounds={true}
margin={false}
onResize={({ bounds }) => {
setDimensions([bounds.width, bounds.height])
}}
>
{({ measureRef }) => (
<div
ref={measureRef}
style={{
...tooltipStyle,
...theme.tooltip,
transform: `translate3d(${animatedPosition.x}px, ${animatedPosition.y}px, 0)`,
}}
>
{children}
</div>
)}
</Measure>
)}
</Motion>
{({ measureRef }) => {
return (
<animated.div
ref={measureRef}
style={{
...style,
...animatedProps,
}}
>
{children}
</animated.div>
)
}}
</Measure>
)
})

Expand Down

0 comments on commit a5850bc

Please sign in to comment.