Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Commit b7dba0d

Browse files
committed
Rewrite with react-assemble
1 parent 7883675 commit b7dba0d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1315
-1097
lines changed

karma.conf.js

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ module.exports = (config) => {
4747
sourceMap: true,
4848
module: "commonjs",
4949
},
50+
exclude: [
51+
/node_modules/,
52+
],
5053
},
5154
{
5255
enforce: "post",

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"@types/react": "^0.14.43",
5656
"@types/react-addons-transition-group": "^0.14.17",
5757
"@types/sinon": "^1.16.31",
58-
"awesome-typescript-loader": "^3.0.0-beta.17",
58+
"awesome-typescript-loader": "^3.0.0-beta.18",
5959
"cash-rm": "^0.2.0",
6060
"chai": "^3.5.0",
6161
"coveralls": "^2.11.14",
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @license
3+
* Copyright (C) 2016-present Chi Vinh Le and contributors.
4+
*
5+
* This software may be modified and distributed under the terms
6+
* of the MIT license. See the LICENSE file for details.
7+
*/
8+
9+
import * as React from "react";
10+
import { assert } from "chai";
11+
import { shallow } from "enzyme";
12+
import { assemble } from "react-assemble";
13+
14+
import { mergeWithStyle } from "./mergeWithStyle";
15+
import { Component } from "../../test/component";
16+
17+
describe("mergeWithStyle", () => {
18+
it("should merge style with transitionStyle", () => {
19+
const input = {
20+
style: { top: 0, left: 2 },
21+
transitionStyle: { left: 10 },
22+
};
23+
const output = {
24+
style: { top: 0, left: 10 },
25+
};
26+
const composable = mergeWithStyle;
27+
const Assembly = assemble<any, any>(composable)(Component);
28+
const wrapper = shallow(<Assembly {...input} />);
29+
assert.deepEqual(wrapper.props(), output);
30+
});
31+
});

src/composables/mergeWithStyle.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* @license
3+
* Copyright (C) 2016-present Chi Vinh Le and contributors.
4+
*
5+
* This software may be modified and distributed under the terms
6+
* of the MIT license. See the LICENSE file for details.
7+
*/
8+
9+
import { combine, withProps, omitProps } from "react-assemble";
10+
11+
export const mergeWithStyle = combine(
12+
withProps<any, any>(({ transitionStyle, style }: any) => ({ style: { ...style, ...transitionStyle } })),
13+
omitProps<any>("transitionStyle"),
14+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @license
3+
* Copyright (C) 2016-present Chi Vinh Le and contributors.
4+
*
5+
* This software may be modified and distributed under the terms
6+
* of the MIT license. See the LICENSE file for details.
7+
*/
8+
9+
import * as React from "react";
10+
import { assert } from "chai";
11+
import { shallow } from "enzyme";
12+
import { assemble } from "react-assemble";
13+
14+
import { withTransitionInfo } from "./withTransitionInfo";
15+
import { Component } from "../../test/component";
16+
17+
describe("withTransitionInfo", () => {
18+
it("should pass transitionInfo for ongoing transition", () => {
19+
const input = {
20+
style: {
21+
transition: "height 2ms 2s linear, width ease 10s 10ms",
22+
},
23+
};
24+
const output = {
25+
...input,
26+
transitionInfo: {
27+
firstProperty: "width",
28+
firstPropertyDelay: 10,
29+
lastProperty: "width",
30+
inTransition: true,
31+
},
32+
};
33+
const composable = withTransitionInfo;
34+
const Assembly = assemble<any, any>(composable)(Component);
35+
const wrapper = shallow(<Assembly {...input} />);
36+
assert.deepEqual(wrapper.props(), output);
37+
});
38+
39+
it("should pass transitionInfo for absent transition", () => {
40+
const input = {
41+
style: {},
42+
};
43+
const output = {
44+
...input,
45+
transitionInfo: {
46+
inTransition: false,
47+
},
48+
};
49+
const composable = withTransitionInfo;
50+
const Assembly = assemble<any, any>(composable)(Component);
51+
const wrapper = shallow(<Assembly {...input} />);
52+
assert.deepEqual(wrapper.props(), output);
53+
});
54+
});

src/composables/withTransitionInfo.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @license
3+
* Copyright (C) 2016-present Chi Vinh Le and contributors.
4+
*
5+
* This software may be modified and distributed under the terms
6+
* of the MIT license. See the LICENSE file for details.
7+
*/
8+
9+
import { withProps } from "react-assemble";
10+
11+
import parseTransition from "../utils/parseTransition";
12+
13+
export const withTransitionInfo =
14+
withProps<any, any>(({style}: any) => {
15+
if (style.transition) {
16+
const [{delay: firstPropertyDelay, property: firstProperty}, {property: lastProperty}] =
17+
parseTransition(style.transition);
18+
return {
19+
transitionInfo: {
20+
firstPropertyDelay,
21+
firstProperty,
22+
lastProperty,
23+
inTransition: true,
24+
},
25+
};
26+
}
27+
return { transitionInfo: { inTransition: false } };
28+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/**
2+
* @license
3+
* Copyright (C) 2016-present Chi Vinh Le and contributors.
4+
*
5+
* This software may be modified and distributed under the terms
6+
* of the MIT license. See the LICENSE file for details.
7+
*/
8+
9+
import * as React from "react";
10+
import { assert } from "chai";
11+
import { shallow, ShallowWrapper } from "enzyme";
12+
import { spy } from "sinon";
13+
import { assemble } from "react-assemble";
14+
15+
import { withTransitionObserver } from "./withTransitionObserver";
16+
import { Component } from "../../test/component";
17+
18+
describe("withTransitionObserver", () => {
19+
const composable = withTransitionObserver;
20+
const Assembly = assemble<any, any>(composable)(Component);
21+
const transitionInfo = {
22+
firstProperty: "width",
23+
lastProperty: "height",
24+
inTransition: true,
25+
};
26+
let wrapper: ShallowWrapper<any, any>;
27+
let handlers = {
28+
onTransitionStart: spy(),
29+
onTransitionEnd: spy(),
30+
onTransitionBegin: spy(),
31+
onTransitionComplete: spy(),
32+
};
33+
34+
beforeEach(() => {
35+
const props = {
36+
transitionInfo,
37+
...handlers,
38+
};
39+
wrapper = shallow(<Assembly {...props} />);
40+
Object.keys(handlers).forEach((s) => (handlers as any)[s].reset());
41+
});
42+
43+
describe("onTransitionBegin", () => {
44+
it("should not call onTransitionBegin yet", () => {
45+
assert.isTrue(handlers.onTransitionBegin.notCalled);
46+
});
47+
48+
it("should cal onTransitionStart", () => {
49+
const event = {
50+
target: "descendant",
51+
};
52+
wrapper.simulate("transitionStart", event);
53+
assert.isTrue(handlers.onTransitionStart.calledWith(event));
54+
});
55+
56+
it("should not call onTransitionBegin when origin from descendants", () => {
57+
const event = {
58+
target: "descendant",
59+
};
60+
wrapper.simulate("transitionStart", event);
61+
assert.isTrue(handlers.onTransitionBegin.notCalled);
62+
});
63+
64+
it("should not call onTransitionBegin when propertyName mismatches", () => {
65+
const event = {
66+
propertyName: "foo",
67+
};
68+
wrapper.simulate("transitionStart", event);
69+
assert.isTrue(handlers.onTransitionBegin.notCalled);
70+
});
71+
72+
it("should call onTransitionBegin", () => {
73+
const event = {
74+
propertyName: "width",
75+
};
76+
wrapper.simulate("transitionStart", event);
77+
assert.isTrue(handlers.onTransitionBegin.called);
78+
});
79+
80+
it("should not call onTransitionBegin when inTransition=false", () => {
81+
const event = {
82+
propertyName: "width",
83+
};
84+
wrapper.setProps({ transitionInfo: { inTransition: false } });
85+
wrapper.simulate("transitionStart", event);
86+
assert.isTrue(handlers.onTransitionBegin.notCalled);
87+
});
88+
});
89+
90+
describe("onTransitionComplete", () => {
91+
it("should not call onTransitionComplete yet", () => {
92+
assert.isTrue(handlers.onTransitionComplete.notCalled);
93+
});
94+
95+
it("should cal onTransitionEnd", () => {
96+
const event = {
97+
target: "descendant",
98+
};
99+
wrapper.simulate("transitionEnd", event);
100+
assert.isTrue(handlers.onTransitionEnd.calledWith(event));
101+
});
102+
103+
it("should not call onTransitionComplete when origin from descendants", () => {
104+
const event = {
105+
target: "descendant",
106+
};
107+
wrapper.simulate("transitionEnd", event);
108+
assert.isTrue(handlers.onTransitionComplete.notCalled);
109+
});
110+
111+
it("should not call onTransitionComplete when propertyName mismatches", () => {
112+
const event = {
113+
propertyName: "foo",
114+
};
115+
wrapper.simulate("transitionEnd", event);
116+
assert.isTrue(handlers.onTransitionComplete.notCalled);
117+
});
118+
119+
it("should call onTransitionComplete", () => {
120+
const event = {
121+
propertyName: "height",
122+
};
123+
wrapper.simulate("transitionEnd", event);
124+
assert.isTrue(handlers.onTransitionComplete.called);
125+
});
126+
127+
it("should not call onTransitionComplete when inTransition=false", () => {
128+
const event = {
129+
propertyName: "height",
130+
};
131+
wrapper.setProps({ transitionInfo: { inTransition: false } });
132+
wrapper.simulate("transitionEnd", event);
133+
assert.isTrue(handlers.onTransitionComplete.notCalled);
134+
});
135+
});
136+
});
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @license
3+
* Copyright (C) 2016-present Chi Vinh Le and contributors.
4+
*
5+
* This software may be modified and distributed under the terms
6+
* of the MIT license. See the LICENSE file for details.
7+
*/
8+
9+
import { TransitionEvent } from "react";
10+
import { withHandlers } from "react-assemble";
11+
12+
import matchTransitionProperty from "../utils/matchTransitionProperty";
13+
14+
export const withTransitionObserver =
15+
withHandlers<any, any>({
16+
onTransitionStart: (
17+
{transitionInfo: { firstProperty, inTransition }, onTransitionStart, onTransitionBegin}: any,
18+
) => (e: TransitionEvent) => {
19+
if (onTransitionStart) { onTransitionStart(e); }
20+
if (!inTransition || e.target !== e.currentTarget ||
21+
!matchTransitionProperty(e.propertyName, firstProperty)) {
22+
return;
23+
}
24+
onTransitionBegin();
25+
},
26+
onTransitionEnd: (
27+
{transitionInfo: {lastProperty, inTransition}, onTransitionEnd, onTransitionComplete}: any,
28+
) => (e: TransitionEvent) => {
29+
if (onTransitionEnd) { onTransitionEnd(e); }
30+
if (!inTransition || e.target !== e.currentTarget ||
31+
!matchTransitionProperty(e.propertyName, lastProperty)) {
32+
return;
33+
}
34+
onTransitionComplete();
35+
},
36+
});

0 commit comments

Comments
 (0)