Skip to content

Commit

Permalink
Merge pull request #2396 from FormidableLabs/feature/migrate-victory-…
Browse files Browse the repository at this point in the history
…group-to-ts

TS Migrate: `victory-group`
  • Loading branch information
scottrippey authored Aug 15, 2022
2 parents 06f5c73 + ae4c089 commit 4c71518
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 92 deletions.
2 changes: 1 addition & 1 deletion packages/victory-axis/src/victory-axis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export interface VictoryAxisProps
interface VictoryAxisBase extends EventsMixinClass<VictoryAxisProps> {}

class VictoryAxisBase extends React.Component<VictoryAxisProps> {
static animationWhitelist = [
static animationWhitelist: Array<keyof VictoryAxisProps> = [
"style",
"domain",
"range",
Expand Down
4 changes: 2 additions & 2 deletions packages/victory-box-plot/src/victory-box-plot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export interface VictoryBoxPlotProps
interface VictoryBoxPlotBase extends EventsMixinClass<VictoryBoxPlotProps> {}

class VictoryBoxPlotBase extends React.Component<VictoryBoxPlotProps> {
static animationWhitelist = [
static animationWhitelist: Array<keyof VictoryBoxPlotProps> = [
"data",
"domain",
"height",
Expand Down Expand Up @@ -306,7 +306,7 @@ class VictoryBoxPlotBase extends React.Component<VictoryBoxPlotProps> {
static getDomain = getDomain;
static getData = getData;
static getBaseProps = (props) => getBaseProps(props, fallbackProps);
static expectedComponents = [
static expectedComponents: Array<keyof VictoryBoxPlotProps> = [
"maxComponent",
"maxLabelComponent",
"medianComponent",
Expand Down
41 changes: 37 additions & 4 deletions packages/victory-core/src/victory-util/add-events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,47 @@ export interface EventMixinCalculatedValues {
events: unknown;
}

/**
* These are the common roles that we care about internally.
*/
export type VictoryComponentCommonRole =
| "container"
| "group"
| "histogram"
| "label"
| "line"
| "portal"
| "stack"
| "tooltip"
| "voronoi";

/**
* A component can have any "role",
* but there are certain ones that we actually care about internally
*/
export type VictoryComponentRole = VictoryComponentCommonRole | string;

/**
* Static component fields used by Victory for common behavior
*/
export interface VictoryComponentConfiguration<TProps> {
getBaseProps?(props: TProps): EventMixinCalculatedValues["baseProps"];
role?: VictoryComponentRole;
expectedComponents?: Array<keyof TProps | string>;
getChildren?: (
props: TProps,
childComponents?: Array<React.ReactNode>,
calculatedProps?: TProps,
) => void;
animationWhitelist?: Array<keyof TProps | string>;
}

/**
* This represents the class itself, including static fields
*/
export interface WrappedComponentClass<TProps> {
export interface WrappedComponentClass<TProps>
extends VictoryComponentConfiguration<TProps> {
new (props: TProps): React.Component<TProps>;
getBaseProps?(props: TProps): EventMixinCalculatedValues["baseProps"];
role?: string;
expectedComponents?: string[];
}

export function addEvents<
Expand Down
3 changes: 2 additions & 1 deletion packages/victory-group/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"victory-shared-events": "^36.6.0"
},
"devDependencies": {
"victory-bar": "*"
"victory-bar": "*",
"victory-group": "*"
},
"peerDependencies": {
"react": ">=16.6.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export function getCalculatedProps(props, childComponents) {
const style = Wrapper.getStyle(props.theme, props.style, role);
const { offset, colorScale, color, polar, horizontal } = props;
const categories =
props.categories || Wrapper.getCategories(props, childComponents);
const datasets = props.datasets || Wrapper.getDataFromChildren(props);
props.categories || Wrapper.getCategories(props, childComponents, null);
const datasets = props.datasets || Wrapper.getDataFromChildren(props, null);
const domain = {
x: Wrapper.getDomain(
assign({}, props, { categories }),
Expand Down Expand Up @@ -67,12 +67,14 @@ export function getCalculatedProps(props, childComponents) {
// With shared events, the props change on every event, and every value is re-calculated
const withoutSharedEvents = (props) => {
const { children } = props;
const modifiedChildren = React.Children.toArray(children).map((child) => {
return {
...child,
props: Helpers.omit(child.props, ["sharedEvents"]),
};
});
const modifiedChildren = React.Children.toArray(children).map(
(child: Record<string, any> | any) => {
return {
...child,
props: Helpers.omit(child.props, ["sharedEvents"]),
};
},
);
props.children = modifiedChildren;
return props;
};
Expand Down Expand Up @@ -186,7 +188,7 @@ function getDataWithOffset(props, defaultDataset = [], offset) {
});
}

export function getChildren(props, childComponents, calculatedProps) {
export function getChildren(props, childComponents?, calculatedProps?) {
props = Helpers.modifyProps(props, fallbackProps, "stack");
childComponents = childComponents || React.Children.toArray(props.children);
calculatedProps =
Expand Down
37 changes: 0 additions & 37 deletions packages/victory-group/src/index.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/victory-group/src/index.js

This file was deleted.

1 change: 1 addition & 0 deletions packages/victory-group/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./victory-group";
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ describe("components/victory-group", () => {
</VictoryGroup>,
);
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", () => {
Expand All @@ -30,7 +30,7 @@ describe("components/victory-group", () => {
);
const svg = container.querySelector("svg");
const viewBoxValue = `0 0 ${450} ${300}`;
expect(svg.getAttribute("viewBox")).toEqual(viewBoxValue);
expect(svg?.getAttribute("viewBox")).toEqual(viewBoxValue);
});

it("accepts user props", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,24 @@ import { assign, defaults, isEmpty } from "lodash";
import PropTypes from "prop-types";
import React from "react";
import {
CategoryPropType,
ColorScalePropType,
CommonProps,
DomainPaddingPropType,
DomainPropType,
EventPropTypeInterface,
Helpers,
Hooks,
StringOrNumberOrCallback,
UserProps,
VictoryCommonProps,
VictoryContainer,
VictoryDatableProps,
VictoryMultiLabelableProps,
VictoryStyleInterface,
VictoryTheme,
Wrapper,
VictoryComponentConfiguration,
} from "victory-core";
import { VictorySharedEvents } from "victory-shared-events";
import { getChildren, useMemoizedProps } from "./helper-methods";
Expand All @@ -21,9 +32,31 @@ const fallbackProps = {
offset: 0,
};

const VictoryGroup = (initialProps) => {
export type VictoryGroupTTargetType = "data" | "labels" | "parent";
export interface VictoryGroupProps
extends VictoryCommonProps,
VictoryDatableProps,
VictoryMultiLabelableProps {
categories?: CategoryPropType;
children?: React.ReactNode;
color?: string;
colorScale?: ColorScalePropType;
domain?: DomainPropType;
domainPadding?: DomainPaddingPropType;
events?: EventPropTypeInterface<
VictoryGroupTTargetType,
StringOrNumberOrCallback
>[];
eventKey?: StringOrNumberOrCallback;
horizontal?: boolean;
offset?: number;
style?: VictoryStyleInterface;
displayName?: string;
}

const VictoryGroupBase: React.FC<VictoryGroupProps> = (initialProps) => {
// eslint-disable-next-line no-use-before-define
const { role } = VictoryGroupMemo;
const role = VictoryGroup?.role;
const { getAnimationProps, setAnimationState, getProps } =
Hooks.useAnimationState();
const props = getProps(initialProps);
Expand Down Expand Up @@ -51,7 +84,7 @@ const VictoryGroup = (initialProps) => {
const children = getChildren(props, childComponents, calculatedProps);
return children.map((child, index) => {
const childProps = assign(
{ animate: getAnimationProps(props, child, index, "victory-group") },
{ animate: getAnimationProps(props, child, index) },
child.props,
);
return React.cloneElement(child, childProps);
Expand Down Expand Up @@ -144,32 +177,18 @@ const VictoryGroup = (initialProps) => {
return React.cloneElement(container, container.props, newChildren);
};

VictoryGroup.propTypes = {
VictoryGroupBase.propTypes = {
...CommonProps.baseProps,
...CommonProps.dataProps,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]),
color: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
colorScale: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.string),
PropTypes.oneOf([
"grayscale",
"qualitative",
"heatmap",
"warm",
"cool",
"red",
"green",
"blue",
]),
]),
horizontal: PropTypes.bool,
offset: PropTypes.number,
};

VictoryGroup.defaultProps = {
VictoryGroupBase.defaultProps = {
containerComponent: <VictoryContainer />,
groupComponent: <g />,
samples: 50,
Expand All @@ -178,19 +197,18 @@ VictoryGroup.defaultProps = {
theme: VictoryTheme.grayscale,
};

// We need to attatch the static properties to the memoized version, or else
// VictoryChart will not be able to get this component's role type
const VictoryGroupMemo = React.memo(VictoryGroup, isEqual);

VictoryGroupMemo.displayName = "VictoryGroup";
VictoryGroupMemo.role = "group";

VictoryGroupMemo.expectedComponents = [
"groupComponent",
"containerComponent",
"labelComponent",
];

VictoryGroupMemo.getChildren = getChildren;
const componentConfig: VictoryComponentConfiguration<VictoryGroupProps> = {
role: "group",
expectedComponents: [
"groupComponent",
"containerComponent",
"labelComponent",
],
getChildren,
};

export default VictoryGroupMemo;
export const VictoryGroup = Object.assign(
React.memo(VictoryGroupBase, isEqual),
componentConfig,
);
VictoryGroup.displayName = "VictoryGroup";
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4c71518

Please sign in to comment.