Skip to content

Commit 618bd6d

Browse files
authored
Improve types in victory-core helpers (#2999)
1 parent efc701b commit 618bd6d

File tree

18 files changed

+191
-61
lines changed

18 files changed

+191
-61
lines changed

.changeset/poor-crabs-hear.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
"victory-axis": patch
3+
"victory-chart": patch
4+
"victory-core": patch
5+
"victory-cursor-container": patch
6+
"victory-group": patch
7+
"victory-legend": patch
8+
"victory-pie": patch
9+
"victory-polar-axis": patch
10+
"victory-scatter": patch
11+
"victory-stack": patch
12+
"victory-tooltip": patch
13+
"victory-voronoi-container": patch
14+
---
15+
16+
Improve types in victory-core helpers

packages/victory-axis/src/helper-methods.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ const getOrientation = (props) => {
467467
const getCalculatedValues = (props) => {
468468
const defaultStyles = getStyleObject(props);
469469
const style = getStyles(props, defaultStyles);
470-
const padding = Helpers.getPadding(props);
470+
const padding = Helpers.getPadding(props.padding);
471471
const labelPadding = getLabelPadding(props, style);
472472
const stringTicks = Axis.stringTicks(props) ? props.tickValues : undefined;
473473
const axis = Axis.getAxis(props);

packages/victory-chart/src/helper-methods.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export function getCalculatedProps(initialProps, childComponents) {
115115

116116
const origin = polar ? Helpers.getPolarOrigin(props) : Axis.getOrigin(domain);
117117

118-
const padding = Helpers.getPadding(props);
118+
const padding = Helpers.getPadding(props.padding);
119119

120120
return {
121121
categories,

packages/victory-core/src/victory-clip-container/victory-clip-container.tsx

+2-4
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export class VictoryClipContainer extends React.Component<
7575
translateX = 0,
7676
translateY = 0,
7777
} = props;
78-
const clipPadding = Helpers.getPadding({ padding: props.clipPadding });
78+
const clipPadding = Helpers.getPadding(props.clipPadding);
7979
const radius = props.radius || Helpers.getRadius(props);
8080
return {
8181
x: (polar ? origin.x : translateX) - clipPadding.left,
@@ -158,9 +158,7 @@ export class VictoryClipContainer extends React.Component<
158158
rectComponent,
159159
clipPathComponent,
160160
} = props;
161-
const { top, bottom, left, right } = Helpers.getPadding({
162-
padding: props.clipPadding,
163-
});
161+
const { top, bottom, left, right } = Helpers.getPadding(props.clipPadding);
164162
let child;
165163
if (polar) {
166164
const radius = props.radius || Helpers.getRadius(props);

packages/victory-core/src/victory-label/victory-label.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,11 @@ const getBackgroundPadding = (props) => {
146146
if (props.backgroundPadding && Array.isArray(props.backgroundPadding)) {
147147
return props.backgroundPadding.map((backgroundPadding) => {
148148
const padding = Helpers.evaluateProp(backgroundPadding, props);
149-
return Helpers.getPadding({ padding });
149+
return Helpers.getPadding(padding);
150150
});
151151
}
152152
const padding = Helpers.evaluateProp(props.backgroundPadding, props);
153-
return Helpers.getPadding({ padding });
153+
return Helpers.getPadding(padding);
154154
};
155155

156156
const getLineHeight = (props) => {

packages/victory-core/src/victory-util/helpers.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ describe("victory-util/helpers", () => {
165165
describe("getPadding", () => {
166166
it("sets padding from a single number", () => {
167167
const props = { padding: 40 };
168-
expect(Helpers.getPadding(props)).toEqual({
168+
expect(Helpers.getPadding(props.padding)).toEqual({
169169
top: 40,
170170
bottom: 40,
171171
left: 40,
@@ -177,14 +177,14 @@ describe("victory-util/helpers", () => {
177177
const props = {
178178
padding: { top: 20, bottom: 40, left: 60, right: 80 },
179179
};
180-
expect(Helpers.getPadding(props)).toEqual(props.padding);
180+
expect(Helpers.getPadding(props.padding)).toEqual(props.padding);
181181
});
182182

183183
it("fills missing values with 0", () => {
184184
const props = {
185185
padding: { top: 40, bottom: 40 },
186186
};
187-
expect(Helpers.getPadding(props)).toEqual({
187+
expect(Helpers.getPadding(props.padding)).toEqual({
188188
top: 40,
189189
bottom: 40,
190190
left: 0,

packages/victory-core/src/victory-util/helpers.ts

+149-35
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,73 @@ import pick from "lodash/pick";
55

66
import { ValueOrAccessor } from "../types/prop-types";
77

8-
// Private Functions
8+
export type ElementPadding = {
9+
top: number;
10+
bottom: number;
11+
left: number;
12+
right: number;
13+
};
14+
15+
export type MaybePointData = {
16+
x?: number;
17+
x0?: number;
18+
x1?: number;
19+
y?: number;
20+
y0?: number;
21+
y1?: number;
22+
_x?: number;
23+
_x0?: number;
24+
_x1?: number;
25+
_y?: number;
26+
_y0?: number;
27+
_y1?: number;
28+
_voronoiX?: number;
29+
_voronoiY?: number;
30+
};
931

10-
function getCartesianRange(props, axis) {
11-
// determine how to lay the axis and what direction positive and negative are
12-
const vertical = axis !== "x";
13-
const padding = getPadding(props);
32+
/**
33+
* Determine the range of a cartesian axis
34+
*/
35+
function getCartesianRange(options: {
36+
axis: "x" | "y";
37+
height: number;
38+
width: number;
39+
padding: ElementPadding;
40+
}): [number, number] {
41+
const vertical = options.axis !== "x";
1442
if (vertical) {
15-
return [props.height - padding.bottom, padding.top];
43+
return [options.height - options.padding.bottom, options.padding.top];
1644
}
17-
return [padding.left, props.width - padding.right];
45+
return [options.padding.left, options.width - options.padding.right];
1846
}
1947

20-
function getPolarRange(props, axis) {
21-
if (axis === "x") {
22-
const startAngle = degreesToRadians(props.startAngle || 0);
23-
const endAngle = degreesToRadians(props.endAngle || 360);
48+
/**
49+
* Determine the range of a polar axis in radians
50+
*/
51+
function getPolarRange(options: {
52+
axis: "x" | "y";
53+
innerRadius?: number;
54+
startAngle?: number;
55+
endAngle?: number;
56+
padding: ElementPadding;
57+
height: number;
58+
width: number;
59+
}): [number, number] {
60+
if (options.axis === "x") {
61+
const startAngle = degreesToRadians(options.startAngle || 0);
62+
const endAngle = degreesToRadians(options.endAngle || 360);
2463
return [startAngle, endAngle];
2564
}
26-
return [props.innerRadius || 0, getRadius(props)];
65+
return [
66+
options.innerRadius || 0,
67+
getRadius({
68+
height: options.height,
69+
width: options.width,
70+
padding: options.padding,
71+
}),
72+
];
2773
}
2874

29-
// Exported Functions
30-
3175
/**
3276
* Creates an object composed of the inverted keys and values of object.
3377
* If object contains duplicate values, subsequent values overwrite property assignments of previous values.
@@ -65,21 +109,36 @@ export function omit<T, Keys extends keyof T>(
65109
return newObject;
66110
}
67111

68-
export function getPoint(datum) {
69-
const exists = (val) => val !== undefined;
112+
/**
113+
* Coalesce the x and y values from a data point
114+
*/
115+
export function getPoint(datum: MaybePointData): MaybePointData {
70116
const { _x, _x1, _x0, _voronoiX, _y, _y1, _y0, _voronoiY } = datum;
71-
const defaultX = exists(_x1) ? _x1 : _x;
72-
const defaultY = exists(_y1) ? _y1 : _y;
117+
const defaultX = _x1 ?? _x;
118+
const defaultY = _y1 ?? _y;
119+
73120
const point = {
74-
x: exists(_voronoiX) ? _voronoiX : defaultX,
75-
x0: exists(_x0) ? _x0 : _x,
76-
y: exists(_voronoiY) ? _voronoiY : defaultY,
77-
y0: exists(_y0) ? _y0 : _y,
121+
x: _voronoiX ?? defaultX,
122+
x0: _x0 ?? _x,
123+
y: _voronoiY ?? defaultY,
124+
y0: _y0 ?? _y,
78125
};
126+
79127
return defaults({}, point, datum);
80128
}
81129

82-
export function scalePoint(props, datum) {
130+
/**
131+
* Scale a point based on the origin, direction, and given scale function
132+
*/
133+
export function scalePoint(
134+
props: {
135+
scale: { x: (x?: number) => number; y: (y?: number) => number };
136+
polar?: boolean;
137+
horizontal?: boolean;
138+
origin?: { x: number; y: number };
139+
},
140+
datum: MaybePointData,
141+
) {
83142
const { scale, polar, horizontal } = props;
84143
const d = getPoint(datum);
85144
const origin = props.origin || { x: 0, y: 0 };
@@ -95,8 +154,12 @@ export function scalePoint(props, datum) {
95154
};
96155
}
97156

98-
export function getPadding(props, name = "padding") {
99-
const padding = props[name];
157+
/**
158+
* Returns a padding value from a number or partial padding values
159+
*/
160+
export function getPadding(
161+
padding?: number | Partial<ElementPadding>,
162+
): ElementPadding {
100163
const paddingVal = typeof padding === "number" ? padding : 0;
101164
const paddingObj = typeof padding === "object" ? padding : {};
102165
return {
@@ -107,7 +170,10 @@ export function getPadding(props, name = "padding") {
107170
};
108171
}
109172

110-
export function isTooltip(component) {
173+
/**
174+
* Returns true if the component is defined as a tooltip
175+
*/
176+
export function isTooltip(component?: { type?: { role?: string } }) {
111177
const labelRole = component && component.type && component.type.role;
112178
return labelRole === "tooltip";
113179
}
@@ -140,6 +206,9 @@ export function getStyles(style, defaultStyles) {
140206
};
141207
}
142208

209+
/**
210+
* Returns the value of a prop or accessor function with the given props
211+
*/
143212
export function evaluateProp<TValue>(
144213
prop: ValueOrAccessor<TValue, Record<string, any>>,
145214
props: Record<string, any>,
@@ -168,15 +237,29 @@ export function radiansToDegrees(radians) {
168237
return typeof radians === "number" ? radians / (Math.PI / 180) : radians;
169238
}
170239

171-
export function getRadius(props) {
172-
const { left, right, top, bottom } = getPadding(props);
173-
const { width, height } = props;
240+
/**
241+
* Get the maximum radius that will fit in the container
242+
*/
243+
export function getRadius(options: {
244+
height: number;
245+
width: number;
246+
padding: ElementPadding;
247+
}) {
248+
const { width, height, padding } = options;
249+
const { left, right, top, bottom } = padding;
174250
return Math.min(width - left - right, height - top - bottom) / 2;
175251
}
176252

177-
export function getPolarOrigin(props) {
253+
/**
254+
* Returns the origin for a polar chart within the padded area
255+
*/
256+
export function getPolarOrigin(props: {
257+
height: number;
258+
width: number;
259+
padding: ElementPadding;
260+
}): { x: number; y: number } {
178261
const { width, height } = props;
179-
const { top, bottom, left, right } = getPadding(props);
262+
const { top, bottom, left, right } = getPadding(props.padding);
180263
const radius = Math.min(width - left - right, height - top - bottom) / 2;
181264
const offsetWidth = width / 2 + left - right;
182265
const offsetHeight = height / 2 + top - bottom;
@@ -186,15 +269,43 @@ export function getPolarOrigin(props) {
186269
};
187270
}
188271

189-
export function getRange(props, axis) {
272+
/**
273+
* Determine the range of an axis based on the given props
274+
*/
275+
export function getRange(
276+
props: {
277+
range?: [number, number];
278+
polar?: boolean;
279+
innerRadius?: number;
280+
startAngle?: number;
281+
endAngle?: number;
282+
height: number;
283+
width: number;
284+
padding: number | Partial<ElementPadding>;
285+
},
286+
axis: "x" | "y",
287+
) {
190288
if (props.range && props.range[axis]) {
191289
return props.range[axis];
192290
} else if (props.range && Array.isArray(props.range)) {
193291
return props.range;
194292
}
195293
return props.polar
196-
? getPolarRange(props, axis)
197-
: getCartesianRange(props, axis);
294+
? getPolarRange({
295+
axis,
296+
innerRadius: props.innerRadius,
297+
startAngle: props.startAngle,
298+
endAngle: props.endAngle,
299+
height: props.height,
300+
width: props.width,
301+
padding: getPadding(props.padding),
302+
})
303+
: getCartesianRange({
304+
axis,
305+
height: props.height,
306+
width: props.width,
307+
padding: getPadding(props.padding),
308+
});
198309
}
199310

200311
/**
@@ -392,7 +503,10 @@ export function reduceChildren<
392503
* @returns {Boolean} returns true if the props object contains `horizontal: true` of if any
393504
* children or nested children are horizontal
394505
*/
395-
export function isHorizontal(props) {
506+
export function isHorizontal(props: {
507+
horizontal?: boolean;
508+
children?: React.ReactNode;
509+
}) {
396510
if (props.horizontal !== undefined || !props.children) {
397511
return props.horizontal;
398512
}

packages/victory-core/src/victory-util/type-helpers.ts

-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ export function getValueForAxis<T = unknown>(
3030
return value;
3131
}
3232

33-
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
34-
export function isFunction<T = Function>(func?: unknown): func is T {
35-
return typeof func === "function";
36-
}
37-
3833
export function isDate(value: unknown): value is Date {
3934
return value instanceof Date;
4035
}

packages/victory-cursor-container/src/victory-cursor-container.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export const useVictoryCursorContainer = (
9797
: props.children;
9898
return Helpers.getPadding(child?.props);
9999
}
100-
return Helpers.getPadding(props);
100+
return Helpers.getPadding(props.padding);
101101
};
102102

103103
const getCursorElements = () => {

packages/victory-group/src/helper-methods.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function getCalculatedProps(initialProps, childComponents) {
4343
};
4444

4545
const origin = polar ? props.origin : Helpers.getPolarOrigin(props);
46-
const padding = Helpers.getPadding(props);
46+
const padding = Helpers.getPadding(props.padding);
4747
return {
4848
datasets,
4949
categories,

packages/victory-legend/src/helper-methods.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const getCalculatedValues = (props) => {
3838
const style = getStyles(props, defaultStyles);
3939
const colorScale = getColorScale(props);
4040
const isHorizontal = orientation === "horizontal";
41-
const borderPadding = Helpers.getPadding({ padding: props.borderPadding });
41+
const borderPadding = Helpers.getPadding(props.borderPadding);
4242
return Object.assign({}, props, {
4343
style,
4444
isHorizontal,

0 commit comments

Comments
 (0)