From e42ba3134cb7ea807cce2bd4d5937ff9bde313de Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Fri, 19 Jan 2024 11:44:56 +0000 Subject: [PATCH] Migrate victory-voronoi to TypeScript (#2726) --- .changeset/long-files-itch.md | 5 ++ packages/victory-voronoi/src/index.d.ts | 46 ---------------- packages/victory-voronoi/src/index.js | 2 - packages/victory-voronoi/src/index.ts | 2 + ...ronoi.test.js => victory-voronoi.test.tsx} | 21 ++++---- ...victory-voronoi.js => victory-voronoi.tsx} | 52 +++++++++++++------ .../src/{voronoi.js => voronoi.tsx} | 45 +++++++--------- 7 files changed, 73 insertions(+), 100 deletions(-) create mode 100644 .changeset/long-files-itch.md delete mode 100644 packages/victory-voronoi/src/index.d.ts delete mode 100644 packages/victory-voronoi/src/index.js create mode 100644 packages/victory-voronoi/src/index.ts rename packages/victory-voronoi/src/{victory-voronoi.test.js => victory-voronoi.test.tsx} (94%) rename packages/victory-voronoi/src/{victory-voronoi.js => victory-voronoi.tsx} (55%) rename packages/victory-voronoi/src/{voronoi.js => voronoi.tsx} (75%) diff --git a/.changeset/long-files-itch.md b/.changeset/long-files-itch.md new file mode 100644 index 000000000..8e0800008 --- /dev/null +++ b/.changeset/long-files-itch.md @@ -0,0 +1,5 @@ +--- +"victory-voronoi": patch +--- + +Migrate victory-voronoi to TypeScript diff --git a/packages/victory-voronoi/src/index.d.ts b/packages/victory-voronoi/src/index.d.ts deleted file mode 100644 index 34016d612..000000000 --- a/packages/victory-voronoi/src/index.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from "react"; -import { - EventPropTypeInterface, - StringOrNumberOrCallback, - VictoryCommonProps, - VictoryCommonPrimitiveProps, - VictoryDatableProps, - VictoryLabelableProps, - VictoryMultiLabelableProps, - VictoryStyleInterface, -} from "victory-core"; - -export type VictoryVoronoiSortOrderType = "ascending" | "descending"; - -export interface VictoryVoronoiProps - extends Omit, - VictoryDatableProps, - VictoryLabelableProps, - VictoryMultiLabelableProps { - events?: EventPropTypeInterface< - string, - string | number | (string | number)[] - >[]; - type?: number; - sortKey?: StringOrNumberOrCallback | string[]; - sortOrder?: VictoryVoronoiSortOrderType; - size?: number | { (data: any): number }; - style?: VictoryStyleInterface; -} - -export interface VoronoiProps extends VictoryCommonPrimitiveProps { - circleComponent?: React.ReactElement; - clipId?: number | string; - clipPathComponent?: React.ReactElement; - datum?: any; - groupComponent?: React.ReactElement; - pathComponent?: React.ReactElement; - polygon?: []; - size?: number; - x?: number; - y?: number; -} - -export class VictoryVoronoi extends React.Component {} - -export class Voronoi extends React.Component {} diff --git a/packages/victory-voronoi/src/index.js b/packages/victory-voronoi/src/index.js deleted file mode 100644 index adc24834f..000000000 --- a/packages/victory-voronoi/src/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as VictoryVoronoi } from "./victory-voronoi"; -export { default as Voronoi } from "./voronoi"; diff --git a/packages/victory-voronoi/src/index.ts b/packages/victory-voronoi/src/index.ts new file mode 100644 index 000000000..fdee50a62 --- /dev/null +++ b/packages/victory-voronoi/src/index.ts @@ -0,0 +1,2 @@ +export * from "./victory-voronoi"; +export * from "./voronoi"; diff --git a/packages/victory-voronoi/src/victory-voronoi.test.js b/packages/victory-voronoi/src/victory-voronoi.test.tsx similarity index 94% rename from packages/victory-voronoi/src/victory-voronoi.test.js rename to packages/victory-voronoi/src/victory-voronoi.test.tsx index 79938eb5b..11a49f073 100644 --- a/packages/victory-voronoi/src/victory-voronoi.test.js +++ b/packages/victory-voronoi/src/victory-voronoi.test.tsx @@ -1,7 +1,7 @@ import React from "react"; import { random, range } from "lodash"; import { calculateD3Path } from "../../../test/helpers"; -import { VictoryVoronoi, Voronoi } from "victory-voronoi"; +import { VictoryVoronoi, VictoryVoronoiProps, Voronoi } from "victory-voronoi"; import { fireEvent, render, screen } from "@testing-library/react"; describe("components/victory-voronoi", () => { @@ -19,8 +19,8 @@ describe("components/victory-voronoi", () => { it("renders an svg with the correct width and height", () => { const { container } = render(); const svg = container.querySelector("svg"); - expect(svg.style.width).toEqual("100%"); - expect(svg.style.height).toEqual("100%"); + expect(svg?.style.width).toEqual("100%"); + expect(svg?.style.height).toEqual("100%"); }); it("renders an svg with the correct viewbox", () => { @@ -33,7 +33,7 @@ describe("components/victory-voronoi", () => { describe("component rendering with data", () => { it("renders the correct d3 path", () => { - const props = { + const props: VictoryVoronoiProps = { width: 400, height: 300, padding: 50, @@ -68,7 +68,7 @@ describe("components/victory-voronoi", () => { const renderedDataProps = screen .getAllByTestId("voronoi-1") - .map((node) => JSON.parse(node.getAttribute("data-props-json"))); + .map((node) => JSON.parse(node.getAttribute("data-props-json") || "")); expect(renderedDataProps.map((props) => props.datum._x)).toEqual([ 0, 1, 2, 3, 4, ]); @@ -91,7 +91,7 @@ describe("components/victory-voronoi", () => { const renderedDataProps = screen .getAllByTestId("voronoi-1") - .map((node) => JSON.parse(node.getAttribute("data-props-json"))); + .map((node) => JSON.parse(node.getAttribute("data-props-json") || "")); expect(renderedDataProps.map((props) => props.datum._x)).toEqual([ 4, 3, 2, 1, 0, @@ -125,7 +125,7 @@ describe("components/victory-voronoi", () => { />, ); const svg = container.querySelector("svg"); - fireEvent.click(svg); + fireEvent.click(svg!); expect(clickHandler).toBeCalled(); // the first argument is the standard evt object expect(Object.keys(clickHandler.mock.calls[0][1])).toEqual( @@ -164,7 +164,7 @@ describe("components/victory-voronoi", () => { const clickHandler = jest.fn(); const { container } = render( { const labels = container.querySelectorAll("text"); - // TODO: figure out why there's no labels rendering? - expect(labels).toHaveLength(0); + expect(labels).toHaveLength(1); labels.forEach((node, index) => { clickHandler.mockClear(); @@ -211,7 +210,7 @@ describe("components/victory-voronoi", () => { dataComponent={ `${datum.x}`} - tabIndex={({ index }) => index + 6} + tabIndex={({ index }) => Number(index) + 6} /> } />, diff --git a/packages/victory-voronoi/src/victory-voronoi.js b/packages/victory-voronoi/src/victory-voronoi.tsx similarity index 55% rename from packages/victory-voronoi/src/victory-voronoi.js rename to packages/victory-voronoi/src/victory-voronoi.tsx index 5785c6644..f25f51a7d 100644 --- a/packages/victory-voronoi/src/victory-voronoi.js +++ b/packages/victory-voronoi/src/victory-voronoi.tsx @@ -1,6 +1,5 @@ import React from "react"; import { - PropTypes as CustomPropTypes, Helpers, VictoryLabel, addEvents, @@ -9,20 +8,46 @@ import { DefaultTransitions, Data, Domain, - CommonProps, UserProps, + EventPropTypeInterface, + EventsMixinClass, + VictoryCommonProps, + VictoryDatableProps, + VictoryLabelableProps, + VictoryMultiLabelableProps, + VictoryStyleInterface, } from "victory-core"; -import Voronoi from "./voronoi"; +import { Voronoi } from "./voronoi"; import { getBaseProps } from "./helper-methods"; +export type VictoryVoronoiSortOrderType = "ascending" | "descending"; + +export interface VictoryVoronoiProps + extends Omit, + VictoryDatableProps, + VictoryLabelableProps, + VictoryMultiLabelableProps { + events?: EventPropTypeInterface< + string, + string | number | (string | number)[] + >[]; + type?: number; + sortOrder?: VictoryVoronoiSortOrderType; + size?: number | { (data: any): number }; + style?: VictoryStyleInterface; +} + const fallbackProps = { width: 450, height: 300, padding: 50, }; -class VictoryVoronoi extends React.Component { - static animationWhitelist = [ +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface VictoryVoronoiBase extends EventsMixinClass {} + +class VictoryVoronoiBase extends React.Component { + static animationWhitelist: (keyof VictoryVoronoiProps)[] = [ "data", "domain", "height", @@ -37,13 +62,7 @@ class VictoryVoronoi extends React.Component { static role = "voronoi"; static defaultTransitions = DefaultTransitions.discreteTransitions(); - static propTypes = { - ...CommonProps.baseProps, - ...CommonProps.dataProps, - size: CustomPropTypes.nonNegative, - }; - - static defaultProps = { + static defaultProps: VictoryVoronoiProps = { containerComponent: , dataComponent: , labelComponent: , @@ -56,8 +75,9 @@ class VictoryVoronoi extends React.Component { static getDomain = Domain.getDomain; static getData = Data.getData; - static getBaseProps = (props) => getBaseProps(props, fallbackProps); - static expectedComponents = [ + static getBaseProps = (props: VictoryVoronoiProps) => + getBaseProps(props, fallbackProps); + static expectedComponents: (keyof VictoryVoronoiProps)[] = [ "dataComponent", "labelComponent", "groupComponent", @@ -69,7 +89,7 @@ class VictoryVoronoi extends React.Component { return !!this.props.animate; } - render() { + render(): React.ReactElement { const { animationWhitelist, role } = VictoryVoronoi; const props = Helpers.modifyProps(this.props, fallbackProps, role); @@ -87,4 +107,4 @@ class VictoryVoronoi extends React.Component { } } -export default addEvents(VictoryVoronoi); +export const VictoryVoronoi = addEvents(VictoryVoronoiBase); diff --git a/packages/victory-voronoi/src/voronoi.js b/packages/victory-voronoi/src/voronoi.tsx similarity index 75% rename from packages/victory-voronoi/src/voronoi.js rename to packages/victory-voronoi/src/voronoi.tsx index 2824d43cd..22380f8dc 100644 --- a/packages/victory-voronoi/src/voronoi.js +++ b/packages/victory-voronoi/src/voronoi.tsx @@ -1,24 +1,35 @@ -/* eslint no-magic-numbers: ["error", { "ignore": [2] }]*/ import React from "react"; -import PropTypes from "prop-types"; import { assign } from "lodash"; import { Helpers, - CommonProps, ClipPath, Path, Circle, UserProps, + VictoryCommonPrimitiveProps, } from "victory-core"; -const getVoronoiPath = (props) => { +export interface VoronoiProps extends VictoryCommonPrimitiveProps { + circleComponent?: React.ReactElement; + clipId?: number | string; + clipPathComponent?: React.ReactElement; + datum?: any; + groupComponent?: React.ReactElement; + pathComponent?: React.ReactElement; + polygon?: []; + size?: number; + x?: number; + y?: number; +} + +const getVoronoiPath = (props: VoronoiProps) => { const { polygon } = props; return Array.isArray(polygon) && polygon.length - ? `M ${props.polygon.join("L")} Z` + ? `M ${props.polygon?.join("L")} Z` : ""; }; -const evaluateProps = (props) => { +function evaluateProps(props: T) { /** * Potential evaluated props are: * `aria-label` @@ -33,7 +44,7 @@ const evaluateProps = (props) => { const style = Helpers.evaluateStyle(props.style, props); const tabIndex = Helpers.evaluateProp(props.tabIndex, props); return assign({}, props, { ariaLabel, id, size, style, tabIndex }); -}; +} const defaultProps = { pathComponent: , @@ -44,9 +55,8 @@ const defaultProps = { shapeRendering: "auto", }; -const Voronoi = (initialProps) => { +export const Voronoi = (initialProps: VoronoiProps) => { const props = evaluateProps({ ...defaultProps, ...initialProps }); - const { ariaLabel, role, @@ -58,6 +68,7 @@ const Voronoi = (initialProps) => { size, tabIndex, } = props; + const voronoiPath = getVoronoiPath(props); const sharedProps = { "aria-label": ariaLabel, @@ -99,19 +110,3 @@ const Voronoi = (initialProps) => { d: voronoiPath, }); }; - -Voronoi.propTypes = { - ...CommonProps.primitiveProps, - circleComponent: PropTypes.element, - clipId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - clipPathComponent: PropTypes.element, - datum: PropTypes.object, - groupComponent: PropTypes.element, - pathComponent: PropTypes.element, - polygon: PropTypes.array, - size: PropTypes.number, - x: PropTypes.number, - y: PropTypes.number, -}; - -export default Voronoi;