From c9991c7032db6739dd7726336bba493e55722811 Mon Sep 17 00:00:00 2001 From: Cesar Perez Date: Wed, 15 Nov 2023 13:07:29 -0400 Subject: [PATCH] Added ability to forward refs in Bar and Path components (#2673) Co-authored-by: Cesar Perez --- .changeset/orange-timers-run.md | 6 +++ packages/victory-bar/src/bar.js | 8 ++-- .../src/victory-primitives/path.tsx | 14 ++++-- stories/victory-bar.stories.js | 47 ++++++++++++++++++- 4 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 .changeset/orange-timers-run.md diff --git a/.changeset/orange-timers-run.md b/.changeset/orange-timers-run.md new file mode 100644 index 000000000..b4aacdccc --- /dev/null +++ b/.changeset/orange-timers-run.md @@ -0,0 +1,6 @@ +--- +"victory-bar": minor +"victory-core": minor +--- + +added ref forwarding for path and bar components diff --git a/packages/victory-bar/src/bar.js b/packages/victory-bar/src/bar.js index 631109739..ccc5e73cc 100644 --- a/packages/victory-bar/src/bar.js +++ b/packages/victory-bar/src/bar.js @@ -1,6 +1,6 @@ import { assign } from "lodash"; import PropTypes from "prop-types"; -import React from "react"; +import React, { forwardRef } from "react"; import { CommonProps, Helpers, Path } from "victory-core"; import { getStyle, getBarWidth, getCornerRadius } from "./bar-helper-methods"; import { getPolarBarPath, getBarPath } from "./path-helper-methods"; @@ -41,7 +41,8 @@ const evaluateProps = (props) => { }); }; -const Bar = (props) => { +// eslint-disable-next-line prefer-arrow-callback +const Bar = forwardRef(function Bar(props, ref) { props = evaluateProps(props); const { polar, origin, style, barWidth, cornerRadius } = props; @@ -63,8 +64,9 @@ const Bar = (props) => { shapeRendering: props.shapeRendering, transform: props.transform || defaultTransform, tabIndex: props.tabIndex, + ref, }); -}; +}); Bar.propTypes = { ...CommonProps.primitiveProps, diff --git a/packages/victory-core/src/victory-primitives/path.tsx b/packages/victory-core/src/victory-primitives/path.tsx index 129ff76b0..c32f7aa13 100644 --- a/packages/victory-core/src/victory-primitives/path.tsx +++ b/packages/victory-core/src/victory-primitives/path.tsx @@ -1,16 +1,20 @@ -import React from "react"; +import React, { forwardRef } from "react"; import { VictoryPrimitiveShapeProps } from "./types"; -export const Path = (props: VictoryPrimitiveShapeProps) => { +// eslint-disable-next-line prefer-arrow-callback +export const Path = forwardRef(function Path( + props: VictoryPrimitiveShapeProps, + ref, +) { // eslint-disable-next-line react/prop-types const { desc, ...rest } = props; return desc ? ( // @ts-expect-error FIXME: "id cannot be a number" - + {desc} ) : ( // @ts-expect-error FIXME: "id cannot be a number" - + ); -}; +}); diff --git a/stories/victory-bar.stories.js b/stories/victory-bar.stories.js index 63dd5edd0..7baa52c7e 100644 --- a/stories/victory-bar.stories.js +++ b/stories/victory-bar.stories.js @@ -1,6 +1,6 @@ /* eslint-disable no-magic-numbers*/ /* eslint-disable react/no-multi-comp*/ -import React from "react"; +import React, { useRef, useEffect, useCallback } from "react"; import { VictoryBar, Bar } from "victory-bar"; import { VictoryChart } from "victory-chart"; import { VictoryGroup } from "victory-group"; @@ -1028,3 +1028,48 @@ export const DisableInlineStyles = () => { ); }; + +export const FocusWithRefs = () => { + const barsRef = useRef(null); + + const getMap = () => { + if (!barsRef.current) { + // Initialize the Map on first usage. + barsRef.current = new Map(); + } + return barsRef.current; + }; + + const focusOnBar = (id) => { + const map = getMap(); + const node = map.get(id); + node.focus(); + }; + + useEffect(() => { + if (barsRef.current) { + focusOnBar("1"); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const setRef = useCallback((node) => { + const map = getMap(); + if (node) { + map.set(node.attributes.index.value, node); + } + }, []); + + return ( +
+ + `x: ${datum.x}`} + labelComponent={} + dataComponent={} + /> + +
+ ); +};