Skip to content

Commit c397c49

Browse files
committed
Merge branch 'hotfix/41-prevent-render-blocking'
2 parents f890f06 + 0f6f1da commit c397c49

File tree

6 files changed

+81
-37
lines changed

6 files changed

+81
-37
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ module.exports = {
7474
"react/jsx-no-target-blank": 0,
7575
"react/require-extension": 0,
7676
"react/self-closing-comp": 0,
77+
"react/sort-comp": 0,
7778
"require-jsdoc": "warn"
7879
},
7980
};

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"test": "yarn lint && jest --coverage --verbose",
1313
"test:clean": "rimraf ./coverage",
1414
"test:watch": "jest --watchAll",
15+
"test:cov": "jest --coverage --verbose",
1516
"coveralls": "cat ./coverage/lcov.info | coveralls",
1617
"show:cov": "open coverage/lcov-report/index.html",
1718
"docs:react": "react-docgen src -e src/**/*.test.js$|scripts/buildDocs.sh",
@@ -39,10 +40,10 @@
3940
],
4041
"coverageThreshold": {
4142
"global": {
42-
"statements": 95,
43+
"statements": 94,
4344
"branches": 84,
4445
"functions": 90,
45-
"lines": 95
46+
"lines": 94
4647
}
4748
},
4849
"moduleNameMapper": {

src/Link/index.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,24 @@ export default class Link extends React.PureComponent {
1515
}
1616

1717
componentDidMount() {
18-
this.applyOpacity(1);
18+
this.applyOpacity(1, this.props.transitionDuration);
1919
}
2020

2121
componentWillLeave(done) {
22-
this.applyOpacity(0, done);
22+
this.applyOpacity(0, this.props.transitionDuration, done);
2323
}
2424

25-
applyOpacity(opacity, done = () => {}) {
26-
const { transitionDuration } = this.props;
27-
28-
select(this.link)
29-
.transition()
30-
.duration(transitionDuration)
31-
.style('opacity', opacity)
32-
.each('end', done);
25+
applyOpacity(opacity, transitionDuration, done = () => {}) {
26+
if (transitionDuration === 0) {
27+
select(this.link).style('opacity', opacity);
28+
done();
29+
} else {
30+
select(this.link)
31+
.transition()
32+
.duration(transitionDuration)
33+
.style('opacity', opacity)
34+
.each('end', done);
35+
}
3336
}
3437

3538
diagonalPath(linkData, orientation) {

src/Link/tests/index.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ describe('<Link />', () => {
9696

9797
expect(renderedComponent.instance().applyOpacity).toHaveBeenCalledWith(
9898
fixture,
99+
mockProps.transitionDuration,
99100
);
100101
});
101102
});

src/Node/index.js

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import './style.css';
88
export default class Node extends React.Component {
99
constructor(props) {
1010
super(props);
11-
const { parent } = props.nodeData;
11+
const { nodeData: { parent }, orientation } = props;
1212
const originX = parent ? parent.x : 0;
1313
const originY = parent ? parent.y : 0;
1414

1515
this.state = {
16-
transform: this.setTransformOrientation(originX, originY),
16+
transform: this.setTransformOrientation(originX, originY, orientation),
1717
initialStyle: {
1818
opacity: 0,
1919
},
@@ -23,48 +23,73 @@ export default class Node extends React.Component {
2323
}
2424

2525
componentDidMount() {
26-
const { x, y } = this.props.nodeData;
27-
const transform = this.setTransformOrientation(x, y);
26+
const { nodeData: { x, y }, orientation, transitionDuration } = this.props;
27+
const transform = this.setTransformOrientation(x, y, orientation);
2828

29-
this.applyTransform(transform);
29+
this.applyTransform(transform, transitionDuration);
3030
}
3131

3232
componentWillUpdate(nextProps) {
33-
const transform = this.setTransformOrientation(
34-
nextProps.nodeData.x,
35-
nextProps.nodeData.y,
33+
const shouldTransform = this.shouldNodeTransform(this.props, nextProps);
34+
if (shouldTransform) {
35+
const transform = this.setTransformOrientation(
36+
nextProps.nodeData.x,
37+
nextProps.nodeData.y,
38+
nextProps.orientation,
39+
);
40+
this.applyTransform(transform, nextProps.transitionDuration);
41+
}
42+
}
43+
44+
shouldNodeTransform(ownProps, nextProps) {
45+
return (
46+
nextProps.nodeData.x !== ownProps.nodeData.x ||
47+
nextProps.nodeData.y !== ownProps.nodeData.y ||
48+
nextProps.orientation !== ownProps.orientation
3649
);
37-
this.applyTransform(transform);
3850
}
3951

40-
setTransformOrientation(x, y) {
41-
return this.props.orientation === 'horizontal'
52+
setTransformOrientation(x, y, orientation) {
53+
return orientation === 'horizontal'
4254
? `translate(${y},${x})`
4355
: `translate(${x},${y})`;
4456
}
4557

46-
applyTransform(transform, opacity = 1, done = () => {}) {
47-
const { transitionDuration } = this.props;
48-
49-
select(this.node)
50-
.transition()
51-
.duration(transitionDuration)
52-
.attr('transform', transform)
53-
.style('opacity', opacity)
54-
.each('end', done);
58+
applyTransform(transform, transitionDuration, opacity = 1, done = () => {}) {
59+
if (transitionDuration === 0) {
60+
select(this.node)
61+
.attr('transform', transform)
62+
.style('opacity', opacity);
63+
done();
64+
} else {
65+
select(this.node)
66+
.transition()
67+
.duration(transitionDuration)
68+
.attr('transform', transform)
69+
.style('opacity', opacity)
70+
.each('end', done);
71+
}
5572
}
5673

5774
handleClick() {
5875
this.props.onClick(this.props.nodeData.id);
5976
}
6077

6178
componentWillLeave(done) {
62-
const { parent } = this.props.nodeData;
79+
const {
80+
nodeData: { parent },
81+
orientation,
82+
transitionDuration,
83+
} = this.props;
6384
const originX = parent ? parent.x : 0;
6485
const originY = parent ? parent.y : 0;
65-
const transform = this.setTransformOrientation(originX, originY);
86+
const transform = this.setTransformOrientation(
87+
originX,
88+
originY,
89+
orientation,
90+
);
6691

67-
this.applyTransform(transform, 0, done);
92+
this.applyTransform(transform, transitionDuration, 0, done);
6893
}
6994

7095
render() {

src/Node/tests/index.test.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,11 @@ describe('<Node />', () => {
215215

216216
expect(renderedComponent.instance().applyTransform).toHaveBeenCalledWith(
217217
fixture,
218+
mockProps.transitionDuration,
218219
);
219220
});
220221

221-
it('applies updated transform if either the `x` or `y` prop changes', () => {
222-
// jest.spyOn(Node.prototype, 'applyTransform');
222+
it('updates its position if `nodeData.x` or `nodeData.y` changes', () => {
223223
const updatedProps = {
224224
...mockProps,
225225
nodeData: {
@@ -236,15 +236,28 @@ describe('<Node />', () => {
236236

237237
expect(renderedComponent.instance().applyTransform).toHaveBeenCalledWith(
238238
initialTransform,
239+
mockProps.transitionDuration,
239240
);
240241

241242
renderedComponent.setProps(updatedProps);
242243

243244
expect(renderedComponent.instance().applyTransform).toHaveBeenCalledWith(
244245
updatedTransform,
246+
mockProps.transitionDuration,
245247
);
246248
});
247249

250+
it('updates its position if `orientation` changes', () => {
251+
const renderedComponent = mount(<Node {...mockProps} />);
252+
const nextProps = { ...mockProps, orientation: 'vertical' };
253+
254+
expect(
255+
renderedComponent
256+
.instance()
257+
.shouldNodeTransform(renderedComponent.props(), nextProps),
258+
).toBe(true);
259+
});
260+
248261
it('allows passing SVG shape elements + shapeProps to be used as the node element', () => {
249262
const fixture = { shape: 'ellipse', shapeProps: { rx: 20, ry: 10 } };
250263
const props = { ...mockProps, nodeSvgShape: fixture };

0 commit comments

Comments
 (0)