Skip to content

Commit

Permalink
feat(bar): enable tooltip for keyboard based navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed Aug 14, 2021
1 parent ce11205 commit 8a32e50
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
47 changes: 33 additions & 14 deletions packages/bar/src/BarItem.tsx
@@ -1,6 +1,6 @@
import { BarDatum, BarItemProps } from './types'
import { animated, to } from '@react-spring/web'
import { createElement, useCallback } from 'react'
import { createElement, FocusEvent, MouseEvent, useCallback, useMemo } from 'react'
import { useTheme } from '@nivo/core'
import { useTooltip } from '@nivo/tooltip'

Expand Down Expand Up @@ -38,34 +38,51 @@ export const BarItem = <RawDatum extends BarDatum>({
ariaDescribedBy,
}: BarItemProps<RawDatum>) => {
const theme = useTheme()
const { showTooltipFromEvent, hideTooltip } = useTooltip()
const { showTooltipFromEvent, showTooltipAt, hideTooltip } = useTooltip()

const renderTooltip = useMemo(() => () => createElement(tooltip, { ...bar, ...data }), [
tooltip,
bar,
data,
])

const handleClick = useCallback(
(event: React.MouseEvent<SVGRectElement>) => {
(event: MouseEvent<SVGRectElement>) => {
onClick?.({ color: bar.color, ...data }, event)
},
[bar, data, onClick]
)
const handleTooltip = useCallback(
(event: React.MouseEvent<SVGRectElement>) =>
showTooltipFromEvent(createElement(tooltip, { ...bar, ...data }), event),
[bar, data, showTooltipFromEvent, tooltip]
(event: MouseEvent<SVGRectElement>) => showTooltipFromEvent(renderTooltip(), event),
[showTooltipFromEvent, renderTooltip]
)
const handleMouseEnter = useCallback(
(event: React.MouseEvent<SVGRectElement>) => {
(event: MouseEvent<SVGRectElement>) => {
onMouseEnter?.(data, event)
showTooltipFromEvent(createElement(tooltip, { ...bar, ...data }), event)
showTooltipFromEvent(renderTooltip(), event)
},
[bar, data, onMouseEnter, showTooltipFromEvent, tooltip]
[data, onMouseEnter, showTooltipFromEvent, renderTooltip]
)
const handleMouseLeave = useCallback(
(event: React.MouseEvent<SVGRectElement>) => {
(event: MouseEvent<SVGRectElement>) => {
onMouseLeave?.(data, event)
hideTooltip()
},
[data, hideTooltip, onMouseLeave]
)

// extra handlers to allow keyboard navigation
const handleFocus = useCallback(
(event: FocusEvent<SVGRectElement>) => {
console.log(bar)
showTooltipAt(renderTooltip(), [bar.x, bar.y])
},
[showTooltipAt, renderTooltip, bar]
)
const handleBlur = useCallback(() => {
hideTooltip()
}, [hideTooltip])

return (
<animated.g transform={transform}>
<animated.rect
Expand All @@ -76,15 +93,17 @@ export const BarItem = <RawDatum extends BarDatum>({
fill={data.fill ?? color}
strokeWidth={borderWidth}
stroke={borderColor}
onMouseEnter={isInteractive ? handleMouseEnter : undefined}
onMouseMove={isInteractive ? handleTooltip : undefined}
onMouseLeave={isInteractive ? handleMouseLeave : undefined}
onClick={isInteractive ? handleClick : undefined}
focusable={isFocusable}
tabIndex={isFocusable ? 0 : undefined}
aria-label={ariaLabel ? ariaLabel() : undefined}
aria-labelledby={ariaLabelledBy ? ariaLabelledBy() : undefined}
aria-describedby={ariaDescribedBy ? ariaDescribedBy() : undefined}
onMouseEnter={isInteractive ? handleMouseEnter : undefined}
onMouseMove={isInteractive ? handleTooltip : undefined}
onMouseLeave={isInteractive ? handleMouseLeave : undefined}
onClick={isInteractive ? handleClick : undefined}
onFocus={isInteractive && isFocusable ? handleFocus : undefined}
onBlur={isInteractive && isFocusable ? handleBlur : undefined}
/>
{shouldRenderLabel && (
<animated.text
Expand Down
4 changes: 4 additions & 0 deletions website/src/data/components/bar/props.js
Expand Up @@ -595,6 +595,10 @@ const props = [
flavors: ['svg'],
group: 'Accessibility',
help: 'Make the root SVG element and each bar item focusable, for keyboard navigation.',
description: `
If enabled, focusing will also reveal the tooltip if \`isInteractive\` is \`true\`,
when a bar gains focus and hide it on blur.
`,
type: 'boolean',
controlType: 'switch',
},
Expand Down

0 comments on commit 8a32e50

Please sign in to comment.