Skip to content

Commit

Permalink
Add user props to top-level container or group
Browse files Browse the repository at this point in the history
This moves the user props logic from the container component to the
top-level returned component, whether that is a container or a group
component. This allows the safe props to work in a standlone component,
or a component that is a child of another victory container or
VictoryChart component.
  • Loading branch information
Becca Bailey committed May 24, 2022
1 parent 812749d commit fa40657
Show file tree
Hide file tree
Showing 18 changed files with 193 additions and 89 deletions.
10 changes: 4 additions & 6 deletions packages/victory-area/src/victory-area.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,11 @@ class VictoryArea extends React.Component {
}

const children = this.renderContinuousData(props);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)
const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
11 changes: 5 additions & 6 deletions packages/victory-bar/src/victory-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,12 @@ class VictoryBar extends React.Component {
}

const children = this.renderData(props);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)

const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
10 changes: 4 additions & 6 deletions packages/victory-box-plot/src/victory-box-plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,11 @@ class VictoryBoxPlot extends React.Component {
}

const children = this.renderBoxPlot(props);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)
const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
11 changes: 5 additions & 6 deletions packages/victory-candlestick/src/victory-candlestick.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,13 +296,12 @@ class VictoryCandlestick extends React.Component {
}

const children = this.renderCandleData(props, this.shouldRenderDatum);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)

const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import PropTypes from "prop-types";
import * as CustomPropTypes from "../victory-util/prop-types";
import * as Helpers from "../victory-util/helpers";
import * as UserProps from "../victory-util/user-props";
import { assign, defaults, isObject, uniqueId } from "lodash";
import ClipPath from "../victory-primitives/clip-path";
import Circle from "../victory-primitives/circle";
Expand Down Expand Up @@ -84,6 +85,7 @@ export default class VictoryClipContainer extends React.Component {
}

renderClippedGroup(props, clipId) {
const userProps = UserProps.getSafeUserProps(props);
const {
style,
events,
Expand All @@ -106,7 +108,7 @@ export default class VictoryClipContainer extends React.Component {
);
return React.cloneElement(
groupComponent,
{ ...groupProps, "aria-label": props["aria-label"], tabIndex },
{ ...groupProps, tabIndex, ...userProps },
[clipComponent, ...React.Children.toArray(children)]
);
}
Expand Down
13 changes: 13 additions & 0 deletions packages/victory-core/src/victory-util/user-props.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as React from "react";

/*
USER_PROPS_SAFELIST is to contain any string deemed safe for user props.
The startsWidth array will contain the start of any accepted user-prop that
Expand Down Expand Up @@ -79,3 +81,14 @@ export const getSafeUserProps = (props) => {
})
);
};

/**
* Wraps a component and adds safe user props
*
* @param {ReactNode} component: parent component
* @param {Object} props: props to be filtered
* @returns {ReactNode} modified component
*/
export const withSafeUserProps = (component, props) => {
return React.cloneElement(component, getSafeUserProps(props));
};
11 changes: 5 additions & 6 deletions packages/victory-errorbar/src/victory-errorbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,12 @@ class VictoryErrorBar extends React.Component {
}

const children = this.renderData(props);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)

const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
11 changes: 4 additions & 7 deletions packages/victory-histogram/src/victory-histogram.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,11 @@ export class VictoryHistogram extends React.Component {

const children = this.renderData(props);

const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(this.props)
);

return props.standalone
? this.renderContainer(container, children)
const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
11 changes: 5 additions & 6 deletions packages/victory-line/src/victory-line.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,12 @@ class VictoryLine extends React.Component {
}

const children = this.renderContinuousData(props);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)

const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}
export default addEvents(VictoryLine, options);
11 changes: 5 additions & 6 deletions packages/victory-pie/src/victory-pie.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,12 @@ class VictoryPie extends React.Component {
}

const children = this.renderData(props);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)

const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
11 changes: 5 additions & 6 deletions packages/victory-scatter/src/victory-scatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,12 @@ class VictoryScatter extends React.Component {
}

const children = this.renderData(props);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)

const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
11 changes: 5 additions & 6 deletions packages/victory-voronoi/src/victory-voronoi.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,12 @@ class VictoryVoronoi extends React.Component {
}

const children = this.renderData(props);
const container = React.cloneElement(
props.containerComponent,
UserProps.getSafeUserProps(props)
);
return props.standalone
? this.renderContainer(container, children)

const component = props.standalone
? this.renderContainer(props.containerComponent, children)
: children;

return UserProps.withSafeUserProps(component, props);
}
}

Expand Down
3 changes: 1 addition & 2 deletions test/jest/rendering-utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { render } from "@testing-library/react";
import * as React from "react";

export const renderInSvg = (component) => {
return render(<svg>{component}</svg>);
return render(component, { wrapper: "svg" });
};
34 changes: 30 additions & 4 deletions test/jest/victory-area/victory-area.test.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
import "@testing-library/jest-dom";
import { fireEvent, render, screen } from "@testing-library/react";
import { curveCatmullRom } from "victory-vendor/d3-shape";
import { range } from "lodash";
import React from "react";
import { Area, VictoryArea } from "victory-area";
import { VictoryChart } from "victory-chart";
import { curveCatmullRom } from "victory-vendor/d3-shape";
import { calculateD3Path } from "../../svg-test-helper";

describe("components/victory-area", () => {
describe("default component rendering", () => {
it("accepts user props", () => {
render(<VictoryArea data-testid="victory-area" aria-label="Chart" />);
it("attaches safe user props to the container component", () => {
render(
<VictoryArea
data-testid="victory-area"
aria-label="Chart"
unsafe-prop="test"
/>
);

const container = screen.getByTestId("victory-area");
expect(screen.getByLabelText("Chart")).toBeDefined();
expect(container).not.toHaveAttribute("unsafe-prop");
expect(container.nodeName).toEqual("svg");
});

it("attaches safe user props to the group component if the component is rendered inside a VictoryChart", () => {
render(
<VictoryArea
data-testid="victory-area"
aria-label="Chart"
unsafe-prop="test"
/>,
{ wrapper: VictoryChart }
);

expect(screen.queryByTestId("victory-area")).toBeDefined();
const container = screen.getByTestId("victory-area");
expect(screen.getByLabelText("Chart")).toBeDefined();
expect(container).not.toHaveAttribute("unsafe-prop");
expect(container.nodeName).toEqual("g");
});

it("renders an svg with the correct viewbox", () => {
Expand Down
22 changes: 19 additions & 3 deletions test/jest/victory-bar/victory-bar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import React from "react";
import { render, fireEvent, screen } from "@testing-library/react";
import { range } from "lodash";
import { VictoryChart } from "victory-chart";
import { VictoryBar, Bar } from "victory-bar";
import { isBar, getBarHeight } from "../../svg-test-helper";
import "@testing-library/jest-dom";
Expand All @@ -18,11 +19,26 @@ describe("components/victory-bar", () => {
/>
);

expect(screen.getByTestId("victory-bar")).toBeDefined();
const container = screen.getByTestId("victory-bar");
expect(screen.getByLabelText("Chart")).toBeDefined();
expect(screen.getByTestId("victory-bar")).not.toHaveAttribute(
"unsafe-prop"
expect(container).not.toHaveAttribute("unsafe-prop");
expect(container.tagName).toEqual("svg");
});

it("attaches safe user props to the group component if the component is rendered inside a VictoryChart", () => {
render(
<VictoryBar
data-testid="victory-bar"
aria-label="Chart"
unsafe-prop="test"
/>,
{ wrapper: VictoryChart }
);

const container = screen.getByTestId("victory-bar");
expect(screen.getByLabelText("Chart")).toBeDefined();
expect(container).not.toHaveAttribute("unsafe-prop");
expect(container.tagName).toEqual("g");
});

it("renders an svg with the correct width and height", () => {
Expand Down
33 changes: 29 additions & 4 deletions test/jest/victory-box-plot/victory-box-plot.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/*eslint-disable react/prop-types */
import React from "react";
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import React from "react";
import { VictoryBoxPlot } from "victory-box-plot";
import { LineSegment, Whisker, Border } from "victory-core";
import { VictoryChart } from "victory-chart";
import { Border, LineSegment, Whisker } from "victory-core";

const TEST_GROUP_ID = "test-group-id";
const dataset = [
Expand All @@ -26,12 +28,35 @@ const renderWithTestGroup = (data = dataset) => {

describe("components/victory-box-plot", () => {
describe("default component rendering", () => {
it("accepts user props", () => {
it("attaches safe user props to the container component", () => {
render(
<VictoryBoxPlot data-testid="victory-boxplot" aria-label="Chart" />
<VictoryBoxPlot
data-testid="victory-boxplot"
aria-label="Chart"
unsafe-prop="test"
/>
);

const container = screen.getByTestId("victory-boxplot");
expect(screen.getByLabelText("Chart")).toBeDefined();
expect(container).not.toHaveAttribute("unsafe-prop");
expect(container.nodeName).toEqual("svg");
});

it("attaches safe user props to the group component if the component is rendered inside a VictoryChart", () => {
render(
<VictoryBoxPlot
data-testid="victory-boxplot"
aria-label="Chart"
unsafe-prop="test"
/>,
{ wrapper: VictoryChart }
);

const container = screen.getByTestId("victory-boxplot");
expect(screen.getByLabelText("Chart")).toBeDefined();
expect(container).not.toHaveAttribute("unsafe-prop");
expect(container.nodeName).toEqual("g");
});

it("renders an svg with the correct width and height", () => {
Expand Down
Loading

0 comments on commit fa40657

Please sign in to comment.