Skip to content

Commit

Permalink
feat(tooltip): init TypeScript migration
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed Nov 15, 2020
1 parent 96cff43 commit 3413142
Show file tree
Hide file tree
Showing 38 changed files with 518 additions and 485 deletions.
6 changes: 3 additions & 3 deletions packages/bar/src/Bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
import React, { Fragment } from 'react'
import { TransitionMotion, spring } from 'react-motion'
import { bindDefs, Container, SvgWrapper, CartesianMarkers } from '@nivo/core'
import { bindDefs, LegacyContainer, SvgWrapper, CartesianMarkers } from '@nivo/core'
import { Axes, Grid } from '@nivo/axes'
import { BoxLegendSvg } from '@nivo/legends'
import { generateGroupedBars, generateStackedBars, getLegendData } from './compute'
Expand Down Expand Up @@ -160,7 +160,7 @@ const Bar = props => {
})

return (
<Container
<LegacyContainer
isInteractive={isInteractive}
theme={theme}
animate={animate}
Expand Down Expand Up @@ -334,7 +334,7 @@ const Bar = props => {
</SvgWrapper>
)
}}
</Container>
</LegacyContainer>
)
}

Expand Down
6 changes: 3 additions & 3 deletions packages/bar/src/BarCanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import React, { Component } from 'react'
import uniqBy from 'lodash/uniqBy'
import setDisplayName from 'recompose/setDisplayName'
import { getRelativeCursor, isCursorInRect, Container } from '@nivo/core'
import { getRelativeCursor, isCursorInRect, LegacyContainer } from '@nivo/core'
import { renderAxesToCanvas, renderGridLinesToCanvas } from '@nivo/axes'
import { renderLegendToCanvas } from '@nivo/legends'
import { BasicTooltip } from '@nivo/tooltip'
Expand Down Expand Up @@ -263,7 +263,7 @@ class BarCanvas extends Component {
const { outerWidth, outerHeight, pixelRatio, isInteractive, theme, canvasRef } = this.props

return (
<Container isInteractive={isInteractive} theme={theme} animate={false}>
<LegacyContainer isInteractive={isInteractive} theme={theme} animate={false}>
{({ showTooltip, hideTooltip }) => (
<canvas
ref={surface => {
Expand All @@ -282,7 +282,7 @@ class BarCanvas extends Component {
onClick={this.handleClick}
/>
)}
</Container>
</LegacyContainer>
)
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/circle-packing/src/Bubble.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import React from 'react'
import { TransitionMotion, spring } from 'react-motion'
import pick from 'lodash/pick'
import { Container, SvgWrapper } from '@nivo/core'
import { LegacyContainer, SvgWrapper } from '@nivo/core'
import { interpolateColor, getInterpolatedColor } from '@nivo/colors'
import enhance from './enhance'
import { nodeWillEnter, nodeWillLeave } from './motion'
Expand Down Expand Up @@ -62,7 +62,7 @@ const Bubble = ({
})

return (
<Container
<LegacyContainer
isInteractive={isInteractive}
theme={theme}
animate={animate}
Expand Down Expand Up @@ -139,7 +139,7 @@ const Bubble = ({
)}
</SvgWrapper>
)}
</Container>
</LegacyContainer>
)
}

Expand Down
6 changes: 3 additions & 3 deletions packages/circle-packing/src/BubbleCanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
/* eslint-disable react/prop-types */
import React, { Component } from 'react'
import { Container } from '@nivo/core'
import { LegacyContainer } from '@nivo/core'
import enhance from './enhance'

class BubbleCanvas extends Component {
Expand Down Expand Up @@ -90,7 +90,7 @@ class BubbleCanvas extends Component {
const { outerWidth, outerHeight, pixelRatio, isInteractive, theme } = this.props

return (
<Container isInteractive={isInteractive} theme={theme} animate={false}>
<LegacyContainer isInteractive={isInteractive} theme={theme} animate={false}>
{() => (
<canvas
ref={surface => {
Expand All @@ -104,7 +104,7 @@ class BubbleCanvas extends Component {
}}
/>
)}
</Container>
</LegacyContainer>
)
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/circle-packing/src/BubbleHtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import React from 'react'
import { TransitionMotion, spring } from 'react-motion'
import pick from 'lodash/pick'
import { Container } from '@nivo/core'
import { LegacyContainer } from '@nivo/core'
import { interpolateColor, getInterpolatedColor } from '@nivo/colors'
import enhance from './enhance'
import { nodeWillEnter, nodeWillLeave } from './motion'
Expand Down Expand Up @@ -60,7 +60,7 @@ const BubbleHtml = ({
})

return (
<Container
<LegacyContainer
isInteractive={isInteractive}
theme={theme}
animate={animate}
Expand Down Expand Up @@ -138,7 +138,7 @@ const BubbleHtml = ({
)}
</div>
)}
</Container>
</LegacyContainer>
)
}

Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/components/ConditionalWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import PropTypes from 'prop-types'
// wrapper: (children: JSX.Element) => JSX.Element
// }

const ConditionalWrapper = ({ children, condition, wrapper }) =>
condition ? cloneElement(wrapper(children)) : children
export const ConditionalWrapper = ({ children, condition, wrapper }) => {
if (!condition) return children

return cloneElement(wrapper, {}, children)
}

ConditionalWrapper.propTypes = {
children: PropTypes.node.isRequired,
condition: PropTypes.bool.isRequired,
wrapper: PropTypes.func.isRequired,
wrapper: PropTypes.element.isRequired,
}

export default ConditionalWrapper
58 changes: 11 additions & 47 deletions packages/core/src/components/Container.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,27 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { useRef, useMemo, useCallback } from 'react'
import React, { useRef } from 'react'
import PropTypes from 'prop-types'
import { tooltipContext, useTooltipHandlers, TooltipWrapper } from '@nivo/tooltip'
import noop from '../lib/noop'
import { TooltipProvider, Tooltip } from '@nivo/tooltip'
import { ThemeProvider } from '../theming'
import { MotionConfigProvider } from '../motion'
import ConditionalWrapper from './ConditionalWrapper'
import { ConditionalWrapper } from './ConditionalWrapper'

const containerStyle = {
position: 'relative',
}

const Container = ({
export const Container = ({
children,
theme,
isInteractive = true,
renderWrapper = true,
animate,
motionStiffness,
motionDamping,
motionConfig,
}) => {
const container = useRef(null)
const {
showTooltipAt,
showTooltipFromEvent,
hideTooltip,
isTooltipVisible,
tooltipContent,
tooltipPosition,
tooltipAnchor,
} = useTooltipHandlers(container)

const showTooltip = useCallback((content, event) => showTooltipFromEvent(content, event), [
showTooltipFromEvent,
])

const handlers = useMemo(
() => ({
showTooltip: isInteractive ? showTooltip : noop,
hideTooltip: isInteractive ? hideTooltip : noop,
}),
[hideTooltip, isInteractive, showTooltip]
)

return (
<ThemeProvider theme={theme}>
Expand All @@ -59,40 +36,27 @@ const Container = ({
damping={motionDamping}
config={motionConfig}
>
<tooltipContext.Provider
value={{ showTooltipAt, showTooltipFromEvent, hideTooltip }}
>
<TooltipProvider container={container}>
{/* we should not render the div element if using the HTTP API */}
<ConditionalWrapper
condition={renderWrapper}
wrapper={children => (
<div style={containerStyle} ref={container}>
{children}
{isTooltipVisible && (
<TooltipWrapper
position={tooltipPosition}
anchor={tooltipAnchor}
>
{tooltipContent}
</TooltipWrapper>
)}
</div>
)}
wrapper={<div style={containerStyle} ref={container} />}
>
{typeof children === 'function' ? children(handlers) : children}
{children}
<Tooltip />
</ConditionalWrapper>
</tooltipContext.Provider>
</TooltipProvider>
</MotionConfigProvider>
</ThemeProvider>
)
}

Container.propTypes = {
children: PropTypes.oneOf([PropTypes.func, PropTypes.node]).isRequired,
children: PropTypes.element.isRequired,
isInteractive: PropTypes.bool,
renderWrapper: PropTypes.bool,
theme: PropTypes.object.isRequired,
animate: PropTypes.bool.isRequired,
animate: PropTypes.bool,
motionStiffness: PropTypes.number,
motionDamping: PropTypes.number,
motionConfig: PropTypes.string,
Expand Down
93 changes: 93 additions & 0 deletions packages/core/src/components/LegacyContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* This file is part of the nivo project.
*
* Copyright 2016-present, Raphaël Benitte.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { useRef, useMemo, useCallback } from 'react'
import PropTypes from 'prop-types'
import {
TooltipActionsContext,
TooltipStateContext,
useTooltipHandlers,
Tooltip,
} from '@nivo/tooltip'
import noop from '../lib/noop'
import { ThemeProvider } from '../theming'
import { MotionConfigProvider } from '../motion'
import { ConditionalWrapper } from './ConditionalWrapper'

const containerStyle = {
position: 'relative',
}

/**
* This component should only be used when relying on render props,
* passing `showTooltip`, `hideTooltip`, but you should use the regular
* `Container` component.
*
* @deprecated
*/
export const LegacyContainer = ({
children,
theme,
isInteractive = true,
renderWrapper = true,
animate,
motionStiffness,
motionDamping,
motionConfig,
}) => {
const container = useRef(null)
const { actions: tooltipActions, state: tooltipState } = useTooltipHandlers(container)

const showTooltip = useCallback(
(content, event) => tooltipActions.showTooltipFromEvent(content, event),
[tooltipActions.showTooltipFromEvent]
)

const handlers = useMemo(
() => ({
showTooltip: isInteractive ? showTooltip : noop,
hideTooltip: isInteractive ? tooltipActions.hideTooltip : noop,
}),
[tooltipActions.hideTooltip, isInteractive, showTooltip]
)

return (
<ThemeProvider theme={theme}>
<MotionConfigProvider
animate={animate}
stiffness={motionStiffness}
damping={motionDamping}
config={motionConfig}
>
<TooltipActionsContext.Provider value={tooltipActions}>
<TooltipStateContext.Provider value={tooltipState}>
{/* we should not render the div element if using the HTTP API */}
<ConditionalWrapper
condition={renderWrapper}
wrapper={<div style={containerStyle} ref={container} />}
>
{children(handlers)}
{isInteractive && <Tooltip />}
</ConditionalWrapper>
</TooltipStateContext.Provider>
</TooltipActionsContext.Provider>
</MotionConfigProvider>
</ThemeProvider>
)
}

LegacyContainer.propTypes = {
children: PropTypes.func.isRequired,
isInteractive: PropTypes.bool,
renderWrapper: PropTypes.bool,
theme: PropTypes.object.isRequired,
animate: PropTypes.bool.isRequired,
motionStiffness: PropTypes.number,
motionDamping: PropTypes.number,
motionConfig: PropTypes.string,
}
Loading

0 comments on commit 3413142

Please sign in to comment.