Skip to content

Commit

Permalink
feat(pie): added more event listener on bar and arc
Browse files Browse the repository at this point in the history
  • Loading branch information
jingcai86 committed Aug 15, 2024
1 parent d90a326 commit 867d98c
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 4 deletions.
38 changes: 37 additions & 1 deletion packages/arcs/src/ArcShape.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, MouseEvent } from 'react'
import { useCallback, MouseEvent, FocusEvent } from 'react'
import { SpringValue, Interpolation, animated } from '@react-spring/web'
import { DatumWithArcAndColor } from './types'

Expand All @@ -7,6 +7,11 @@ export type ArcMouseHandler<Datum extends DatumWithArcAndColor> = (
event: MouseEvent<SVGPathElement>
) => void

export type ArcKeyboardHandler<Datum extends DatumWithArcAndColor> = (
datum: Datum,
event: FocusEvent<SVGPathElement>
) => void

export interface ArcShapeProps<Datum extends DatumWithArcAndColor> {
datum: Datum
style: {
Expand All @@ -17,9 +22,13 @@ export interface ArcShapeProps<Datum extends DatumWithArcAndColor> {
path: Interpolation<string>
}
onClick?: ArcMouseHandler<Datum>
onMouseDown?: ArcMouseHandler<Datum>
onMouseUp?: ArcMouseHandler<Datum>
onMouseEnter?: ArcMouseHandler<Datum>
onMouseMove?: ArcMouseHandler<Datum>
onMouseLeave?: ArcMouseHandler<Datum>
onFocus?: ArcKeyboardHandler<Datum>
onBlur?: ArcKeyboardHandler<Datum>
}

/**
Expand All @@ -35,6 +44,10 @@ export const ArcShape = <Datum extends DatumWithArcAndColor>({
onMouseEnter,
onMouseMove,
onMouseLeave,
onMouseDown,
onMouseUp,
onFocus,
onBlur,
}: ArcShapeProps<Datum>) => {
const handleClick = useCallback(
(event: MouseEvent<SVGPathElement>) => onClick?.(datum, event),
Expand All @@ -56,6 +69,23 @@ export const ArcShape = <Datum extends DatumWithArcAndColor>({
[onMouseLeave, datum]
)

const handleMouseDown = useCallback(
(event: MouseEvent<SVGPathElement>) => onMouseDown?.(datum, event),
[onMouseDown, datum]
)
const handleMouseUp = useCallback(
(event: MouseEvent<SVGPathElement>) => onMouseUp?.(datum, event),
[onMouseUp, datum]
)
const handleFocus = useCallback(
(event: FocusEvent<SVGPathElement>) => onFocus?.(datum, event),
[onFocus, datum]
)
const handleBlur = useCallback(
(event: FocusEvent<SVGPathElement>) => onBlur?.(datum, event),
[onBlur, datum]
)

return (
<animated.path
d={style.path}
Expand All @@ -64,9 +94,15 @@ export const ArcShape = <Datum extends DatumWithArcAndColor>({
stroke={style.borderColor}
strokeWidth={style.borderWidth}
onClick={onClick ? handleClick : undefined}
onMouseDown={onMouseDown ? handleMouseDown : undefined}
onMouseUp={onMouseUp ? handleMouseUp : undefined}
onMouseEnter={onMouseEnter ? handleMouseEnter : undefined}
onMouseMove={onMouseMove ? handleMouseMove : undefined}
onMouseLeave={onMouseLeave ? handleMouseLeave : undefined}
onFocus={onFocus ? handleFocus : undefined}
onBlur={onBlur ? handleBlur : undefined}
focusable={onFocus || onBlur ? true : undefined}
tabIndex={onFocus || onBlur ? 0 : undefined}
/>
)
}
14 changes: 13 additions & 1 deletion packages/arcs/src/ArcsLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { InheritedColorConfig, useInheritedColor } from '@nivo/colors'
import { DatumWithArcAndColor, ArcGenerator } from './types'
import { useArcsTransition } from './useArcsTransition'
import { ArcTransitionMode } from './arcTransitionMode'
import { ArcMouseHandler, ArcShape, ArcShapeProps } from './ArcShape'
import { ArcKeyboardHandler, ArcMouseHandler, ArcShape, ArcShapeProps } from './ArcShape'

export type ArcComponent<Datum extends DatumWithArcAndColor> = (
props: ArcShapeProps<Datum>
Expand All @@ -17,9 +17,13 @@ interface ArcsLayerProps<Datum extends DatumWithArcAndColor> {
borderWidth: number
borderColor: InheritedColorConfig<Datum>
onClick?: ArcMouseHandler<Datum>
onMouseDown?: ArcMouseHandler<Datum>
onMouseUp?: ArcMouseHandler<Datum>
onMouseEnter?: ArcMouseHandler<Datum>
onMouseMove?: ArcMouseHandler<Datum>
onMouseLeave?: ArcMouseHandler<Datum>
onFocus?: ArcKeyboardHandler<Datum>
onBlur?: ArcKeyboardHandler<Datum>
transitionMode: ArcTransitionMode
component?: ArcComponent<Datum>
}
Expand All @@ -34,6 +38,10 @@ export const ArcsLayer = <Datum extends DatumWithArcAndColor>({
onMouseEnter,
onMouseMove,
onMouseLeave,
onMouseDown,
onMouseUp,
onFocus,
onBlur,
transitionMode,
component = ArcShape,
}: ArcsLayerProps<Datum>) => {
Expand Down Expand Up @@ -88,6 +96,10 @@ export const ArcsLayer = <Datum extends DatumWithArcAndColor>({
onMouseEnter,
onMouseMove,
onMouseLeave,
onMouseDown,
onMouseUp,
onFocus,
onBlur,
})
})}
</g>
Expand Down
46 changes: 46 additions & 0 deletions packages/pie/src/Arcs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ interface ArcsProps<RawDatum> {
borderWidth: CompletePieSvgProps<RawDatum>['borderWidth']
borderColor: CompletePieSvgProps<RawDatum>['borderColor']
isInteractive: CompletePieSvgProps<RawDatum>['isInteractive']
isFocusable: CompletePieSvgProps<RawDatum>['isFocusable']
onClick?: CompletePieSvgProps<RawDatum>['onClick']
onMouseEnter?: CompletePieSvgProps<RawDatum>['onMouseEnter']
onMouseMove?: CompletePieSvgProps<RawDatum>['onMouseMove']
onMouseLeave?: CompletePieSvgProps<RawDatum>['onMouseLeave']
onMouseDown?: CompletePieSvgProps<RawDatum>['onMouseDown']
onMouseUp?: CompletePieSvgProps<RawDatum>['onMouseUp']
onFocus?: CompletePieSvgProps<RawDatum>['onFocus']
onBlur?: CompletePieSvgProps<RawDatum>['onBlur']
setActiveId: (id: null | string | number) => void
tooltip: CompletePieSvgProps<RawDatum>['tooltip']
transitionMode: CompletePieSvgProps<RawDatum>['transitionMode']
Expand All @@ -27,16 +32,37 @@ export const Arcs = <RawDatum,>({
borderWidth,
borderColor,
isInteractive,
isFocusable,
onClick,
onMouseEnter,
onMouseMove,
onMouseLeave,
onMouseDown,
onMouseUp,
onFocus,
onBlur,
setActiveId,
tooltip,
transitionMode,
}: ArcsProps<RawDatum>) => {
const { showTooltipFromEvent, hideTooltip } = useTooltip()

const handleFocus = useMemo(() => {
if (!(isFocusable && isFocusable)) return undefined

return (datum: ComputedDatum<RawDatum>, event: React.FocusEvent<SVGPathElement>) => {
onFocus?.(datum, event)
}
}, [isFocusable, isFocusable , onFocus])

Check failure on line 56 in packages/pie/src/Arcs.tsx

View workflow job for this annotation

GitHub Actions / build

Delete `·`

Check failure on line 56 in packages/pie/src/Arcs.tsx

View workflow job for this annotation

GitHub Actions / build

Delete `·`

const handleBlur = useMemo(() => {
if (!(isInteractive && isFocusable)) return undefined

return (datum: ComputedDatum<RawDatum>, event: React.FocusEvent<SVGPathElement>) => {
onBlur?.(datum, event)
}
}, [isInteractive, isFocusable , onBlur])

Check failure on line 64 in packages/pie/src/Arcs.tsx

View workflow job for this annotation

GitHub Actions / build

Delete `·`

Check failure on line 64 in packages/pie/src/Arcs.tsx

View workflow job for this annotation

GitHub Actions / build

Delete `·`

const handleClick = useMemo(() => {
if (!isInteractive) return undefined

Expand All @@ -45,6 +71,22 @@ export const Arcs = <RawDatum,>({
}
}, [isInteractive, onClick])

const handleMouseDown = useMemo(() => {
if (!isInteractive) return undefined

return (datum: ComputedDatum<RawDatum>, event: React.MouseEvent<SVGPathElement>) => {
onMouseDown?.(datum, event)
}
}, [isInteractive, onMouseDown])

const handleMouseUp = useMemo(() => {
if (!isInteractive) return undefined

return (datum: ComputedDatum<RawDatum>, event: React.MouseEvent<SVGPathElement>) => {
onMouseUp?.(datum, event)
}
}, [isInteractive, onMouseUp])

const handleMouseEnter = useMemo(() => {
if (!isInteractive) return undefined

Expand Down Expand Up @@ -86,6 +128,10 @@ export const Arcs = <RawDatum,>({
onMouseEnter={handleMouseEnter}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onBlur={handleBlur}
onFocus={handleFocus}
/>
)
}
18 changes: 17 additions & 1 deletion packages/pie/src/Pie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,15 @@ const InnerPie = <RawDatum extends MayHaveLabel>({

// interactivity
isInteractive = defaultProps.isInteractive,
isFocusable = defaultProps.isFocusable,
onClick,
onMouseEnter,
onMouseMove,
onMouseLeave,
onMouseDown,
onMouseUp,
onFocus,
onBlur,
tooltip = defaultProps.tooltip,
activeId: activeIdFromProps,
onActiveIdChange,
Expand Down Expand Up @@ -147,10 +152,15 @@ const InnerPie = <RawDatum extends MayHaveLabel>({
borderWidth={borderWidth}
borderColor={borderColor}
isInteractive={isInteractive}
isFocusable={isFocusable}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseMove={onMouseMove}
onMouseLeave={onMouseLeave}
onMouseDown={onMouseDown}
onMouseUp={onMouseUp}
onFocus={onFocus}
onBlur={onBlur}
setActiveId={setActiveId}
tooltip={tooltip}
transitionMode={transitionMode}
Expand Down Expand Up @@ -241,6 +251,7 @@ const InnerPie = <RawDatum extends MayHaveLabel>({

export const Pie = <RawDatum extends MayHaveLabel>({
isInteractive = defaultProps.isInteractive,
isFocusable = defaultProps.isFocusable,
animate = defaultProps.animate,
motionConfig = defaultProps.motionConfig,
theme,
Expand All @@ -251,11 +262,16 @@ export const Pie = <RawDatum extends MayHaveLabel>({
{...{
animate,
isInteractive,
isFocusable,
motionConfig,
renderWrapper,
theme,
}}
>
<InnerPie<RawDatum> isInteractive={isInteractive} {...otherProps} />
<InnerPie<RawDatum>
isInteractive={isInteractive}
isFocusable={isFocusable}
{...otherProps}
/>
</Container>
)
2 changes: 1 addition & 1 deletion packages/pie/src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const defaultProps = {
fill: [],

isInteractive: true,

isFocusable: false,
animate: true,
motionConfig: 'gentle',
transitionMode: 'innerRadius' as ArcTransitionMode,
Expand Down
10 changes: 10 additions & 0 deletions packages/pie/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ export type MouseEventHandler<RawDatum, ElementType = HTMLCanvasElement> = (
event: React.MouseEvent<ElementType>
) => void

export type FocusEventHandler<RawDatum, ElementType = HTMLCanvasElement> = (
datum: ComputedDatum<RawDatum>,
event: React.FocusEvent<ElementType>
) => void

export type PieLayerId = 'arcLinkLabels' | 'arcs' | 'arcLabels' | 'legends'

export interface PieCustomLayerProps<RawDatum> {
Expand Down Expand Up @@ -112,6 +117,7 @@ export type CommonPieProps<RawDatum> = {

// interactivity
isInteractive: boolean
isFocusable: boolean
tooltip: React.FC<PieTooltipProps<RawDatum>>
activeId: DatumId | null
onActiveIdChange: (id: DatumId | null) => void
Expand All @@ -130,6 +136,10 @@ export type PieHandlers<RawDatum, ElementType> = {
onMouseEnter?: MouseEventHandler<RawDatum, ElementType>
onMouseMove?: MouseEventHandler<RawDatum, ElementType>
onMouseLeave?: MouseEventHandler<RawDatum, ElementType>
onMouseDown?: MouseEventHandler<RawDatum, ElementType>
onMouseUp?: MouseEventHandler<RawDatum, ElementType>
onFocus?: FocusEventHandler<RawDatum, ElementType>
onBlur?: FocusEventHandler<RawDatum, ElementType>
}

export type PieSvgCustomComponents<RawDatum> = {
Expand Down

0 comments on commit 867d98c

Please sign in to comment.