diff --git a/packages/funnel/src/Funnel.tsx b/packages/funnel/src/Funnel.tsx index c5570718f7..6d6d8f8f42 100644 --- a/packages/funnel/src/Funnel.tsx +++ b/packages/funnel/src/Funnel.tsx @@ -45,6 +45,7 @@ const InnerFunnel = ({ onMouseMove, onMouseLeave, onClick, + tooltip, role = svgDefaultProps.role, ariaLabel, ariaLabelledBy, @@ -91,6 +92,7 @@ const InnerFunnel = ({ onMouseMove, onMouseLeave, onClick, + tooltip, }) const layerById: Record = { diff --git a/packages/funnel/src/PartTooltip.tsx b/packages/funnel/src/PartTooltip.tsx index 0b889e0298..9c195d7029 100644 --- a/packages/funnel/src/PartTooltip.tsx +++ b/packages/funnel/src/PartTooltip.tsx @@ -1,7 +1,7 @@ import { BasicTooltip } from '@nivo/tooltip' import { FunnelDatum, FunnelPartWithHandlers } from './types' -interface PartTooltipProps { +export interface PartTooltipProps { part: FunnelPartWithHandlers } diff --git a/packages/funnel/src/hooks.ts b/packages/funnel/src/hooks.ts index 27ab8934d7..ca026177ab 100644 --- a/packages/funnel/src/hooks.ts +++ b/packages/funnel/src/hooks.ts @@ -6,7 +6,7 @@ import { useTheme, useValueFormatter } from '@nivo/core' import { useAnnotations } from '@nivo/annotations' import { useTooltip, TooltipActionsContextData } from '@nivo/tooltip' import { svgDefaultProps as defaults } from './props' -import { PartTooltip } from './PartTooltip' +import { PartTooltip, PartTooltipProps } from './PartTooltip' import { FunnelDatum, FunnelCommonProps, @@ -213,6 +213,7 @@ export const computePartsHandlers = ({ onClick, showTooltipFromEvent, hideTooltip, + tooltip = PartTooltip, }: { parts: FunnelPart[] setCurrentPartId: (id: string | number | null) => void @@ -223,13 +224,14 @@ export const computePartsHandlers = ({ onClick?: FunnelCommonProps['onClick'] showTooltipFromEvent: TooltipActionsContextData['showTooltipFromEvent'] hideTooltip: () => void + tooltip?: (props: PartTooltipProps) => JSX.Element }) => { if (!isInteractive) return parts return parts.map(part => { const boundOnMouseEnter = (event: MouseEvent) => { setCurrentPartId(part.data.id) - showTooltipFromEvent(createElement(PartTooltip, { part }), event) + showTooltipFromEvent(createElement(tooltip, { part }), event) onMouseEnter !== undefined && onMouseEnter(part, event) } @@ -240,7 +242,7 @@ export const computePartsHandlers = ({ } const boundOnMouseMove = (event: MouseEvent) => { - showTooltipFromEvent(createElement(PartTooltip, { part }), event) + showTooltipFromEvent(createElement(tooltip, { part }), event) onMouseMove !== undefined && onMouseMove(part, event) } @@ -296,6 +298,7 @@ export const useFunnel = ({ onMouseMove, onMouseLeave, onClick, + tooltip, }: { data: FunnelDataProps['data'] width: number @@ -324,6 +327,7 @@ export const useFunnel = ({ onMouseMove?: FunnelCommonProps['onMouseMove'] onMouseLeave?: FunnelCommonProps['onMouseLeave'] onClick?: FunnelCommonProps['onClick'] + tooltip?: (props: PartTooltipProps) => JSX.Element }) => { const theme = useTheme() const getColor = useOrdinalColorScale(colors, 'id') @@ -573,6 +577,7 @@ export const useFunnel = ({ onClick, showTooltipFromEvent, hideTooltip, + tooltip, }), [ parts, @@ -584,6 +589,7 @@ export const useFunnel = ({ onClick, showTooltipFromEvent, hideTooltip, + tooltip, ] ) diff --git a/packages/funnel/src/types.ts b/packages/funnel/src/types.ts index 4be0f9026d..831c8e8f02 100644 --- a/packages/funnel/src/types.ts +++ b/packages/funnel/src/types.ts @@ -3,6 +3,7 @@ import { Area, Line } from 'd3-shape' import { Box, Theme, Dimensions, ModernMotionProps, ValueFormat } from '@nivo/core' import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors' import { AnnotationMatcher } from '@nivo/annotations' +import { PartTooltipProps } from './PartTooltip' export interface FunnelDatum { id: string | number @@ -116,6 +117,7 @@ export interface FunnelCommonProps { onMouseLeave: FunnelPartEventHandler onMouseMove: FunnelPartEventHandler onClick: FunnelPartEventHandler + tooltip: (props: PartTooltipProps) => JSX.Element renderWrapper: boolean diff --git a/packages/funnel/stories/funnel.stories.tsx b/packages/funnel/stories/funnel.stories.tsx new file mode 100644 index 0000000000..5b10a19fa7 --- /dev/null +++ b/packages/funnel/stories/funnel.stories.tsx @@ -0,0 +1,65 @@ +import { withKnobs } from '@storybook/addon-knobs' +import { storiesOf } from '@storybook/react' + +import { ResponsiveFunnel } from '../src' + +const commonProps = { + data: [ + { + id: 'step_sent', + value: 85523, + label: 'Sent', + }, + { + id: 'step_viewed', + value: 74844, + label: 'Viewed', + }, + { + id: 'step_clicked', + value: 62617, + label: 'Clicked', + }, + { + id: 'step_add_to_card', + value: 50425, + label: 'Add To Card', + }, + { + id: 'step_purchased', + value: 31139, + label: 'Purchased', + }, + ], + margin: { top: 20, right: 20, bottom: 20, left: 20 }, + borderWidth: 20, + motionConfig: 'wobbly', +} + +const stories = storiesOf('Funnel', module) + +stories.addDecorator(withKnobs) + +stories.add('custom tooltip', () => ( +
+ ( +
+ Look, I'm custom :) +
+ + {part.data.id}: {part.formattedValue} + +
+ )} + /> +
+))