Skip to content

Commit 9068d46

Browse files
committed
Respect react event handler
1 parent 5c71a2b commit 9068d46

File tree

3 files changed

+82
-25
lines changed

3 files changed

+82
-25
lines changed

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
"main": "lib/cjs/index.js",
1919
"typings": "lib/cjs/index.d.ts",
2020
"types": "lib/cjs/index.d.ts",
21+
"prettier": {
22+
"singleQuote": true,
23+
"trailingComma": "es5",
24+
"bracketSpacing": false
25+
},
2126
"peerDependencies": {
2227
"@cycle/run": "5.x.x",
2328
"react": "16.x.x",
@@ -30,6 +35,7 @@
3035
"@types/node": "^10.5.2",
3136
"@types/react": "16.9.49",
3237
"mocha": "^6.2.0",
38+
"prettier": "^2.1.2",
3339
"react": "16.13.1",
3440
"react-dom": "16.13.1",
3541
"react-test-renderer": "16.13.1",
@@ -46,6 +52,6 @@
4652
"compile": "npm run compile-cjs && npm run compile-es6",
4753
"compile-cjs": "tsc --module commonjs --outDir ./lib/cjs",
4854
"compile-es6": "echo 'TODO' : tsc --module es6 --outDir ./lib/es6",
49-
"test": "$(npm bin)/mocha test/*.ts --require ts-node/register --recursive"
55+
"test": "mocha test/*.ts --require ts-node/register --recursive"
5056
}
5157
}

src/Incorporator.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,15 @@ export default class Incorporator extends PureComponent<Props, State> {
3232
const handlers = scope.getSelectorHandlers(this.selector);
3333
for (const evType of Object.keys(handlers)) {
3434
const onFoo = `on${evType[0].toUpperCase()}${evType.slice(1)}`;
35-
props[onFoo] = (ev: any) => handlers[evType]._n(ev);
35+
const oldHandler =
36+
typeof props[onFoo] === 'function' ? props[onFoo] : undefined;
37+
props[onFoo] = (ev: any) => {
38+
const res = handlers[evType]._n(ev);
39+
if (oldHandler) {
40+
return oldHandler(ev);
41+
}
42+
return res;
43+
};
3644
}
3745
return props;
3846
}

test/conversion.ts

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ class Touchable extends PureComponent<any, any> {
1717
}
1818
}
1919

20-
describe('Conversion', function() {
21-
it('converts an MVI Cycle app into a React component', done => {
20+
describe('Conversion', function () {
21+
it('converts an MVI Cycle app into a React component', (done) => {
2222
function main(sources: {react: ReactSource}) {
2323
const inc$ = sources.react.select('button').events('press');
2424
const count$ = inc$.fold((acc: number, x: any) => acc + 1, 0);
2525
const vdom$ = count$.map((i: number) =>
26-
h(Touchable, {sel: 'button'}, [h('div', [h('h1', {}, '' + i)])]),
26+
h(Touchable, {sel: 'button'}, [h('div', [h('h1', {}, '' + i)])])
2727
);
2828
return {react: vdom$};
2929
}
@@ -52,13 +52,13 @@ describe('Conversion', function() {
5252
setTimeout(check, 150);
5353
});
5454

55-
it('allows Symbol selectors', done => {
55+
it('allows Symbol selectors', (done) => {
5656
function main(sources: {react: ReactSource}) {
5757
const inc = Symbol();
5858
const inc$ = sources.react.select(inc).events('press');
5959
const count$ = inc$.fold((acc: number, x: any) => acc + 1, 0);
6060
const vdom$ = count$.map((i: number) =>
61-
h(Touchable, {sel: inc}, [h('div', [h('h1', {}, '' + i)])]),
61+
h(Touchable, {sel: inc}, [h('div', [h('h1', {}, '' + i)])])
6262
);
6363
return {react: vdom$};
6464
}
@@ -87,10 +87,56 @@ describe('Conversion', function() {
8787
setTimeout(check, 150);
8888
});
8989

90-
it('output React component routes props to sources.react.props()', done => {
90+
it('calls on handler set on react component', (done) => {
91+
let onPressCalled = 0;
92+
function main(sources: {react: ReactSource}) {
93+
const inc = Symbol();
94+
const inc$ = sources.react.select(inc).events('press');
95+
const count$ = inc$.fold((acc: number, x: any) => acc + 1, 0);
96+
const vdom$ = count$.map((i: number) =>
97+
h(
98+
Touchable,
99+
{
100+
sel: inc,
101+
onPress: () => {
102+
onPressCalled++;
103+
},
104+
},
105+
[h('div', [h('h1', {}, '' + i)])]
106+
)
107+
);
108+
return {react: vdom$};
109+
}
110+
111+
let turn = 0;
112+
const RootComponent = makeCycleReactComponent(() => {
113+
const source = new ReactSource();
114+
const sink = main({react: source}).react;
115+
return {source, sink};
116+
});
117+
const r = renderer.create(createElement(RootComponent));
118+
const root = r.root;
119+
const check = () => {
120+
const to = root.findByType(Touchable);
121+
const view = to.props.children;
122+
const text = view.props.children;
123+
assert.strictEqual(text.props.children, `${turn}`);
124+
to.instance.press();
125+
turn++;
126+
if (turn === 3) {
127+
assert.strictEqual(onPressCalled, 3)
128+
done();
129+
}
130+
};
131+
setTimeout(check, 50);
132+
setTimeout(check, 100);
133+
setTimeout(check, 150);
134+
});
135+
136+
it('output React component routes props to sources.react.props()', (done) => {
91137
function main(sources: {react: ReactSource}) {
92138
sources.react.props().addListener({
93-
next: props => {
139+
next: (props) => {
94140
assert.strictEqual(props.name, 'Alice');
95141
assert.strictEqual(props.age, 30);
96142
done();
@@ -99,7 +145,7 @@ describe('Conversion', function() {
99145

100146
return {
101147
react: xs.of(
102-
h('section', [h('div', {}, [h('h1', {}, 'Hello world')])]),
148+
h('section', [h('div', {}, [h('h1', {}, 'Hello world')])])
103149
),
104150
};
105151
}
@@ -112,16 +158,13 @@ describe('Conversion', function() {
112158
renderer.create(createElement(RootComponent, {name: 'Alice', age: 30}));
113159
});
114160

115-
it('output React component routes other sinks to handlers in props', done => {
161+
it('output React component routes other sinks to handlers in props', (done) => {
116162
function main(sources: {react: ReactSource}) {
117163
return {
118164
react: xs.of(
119-
h('section', [h('div', {}, [h('h1', {}, 'Hello world')])]),
165+
h('section', [h('div', {}, [h('h1', {}, 'Hello world')])])
120166
),
121-
something: xs
122-
.periodic(200)
123-
.mapTo('yellow')
124-
.take(1),
167+
something: xs.periodic(200).mapTo('yellow').take(1),
125168
};
126169
}
127170

@@ -133,22 +176,22 @@ describe('Conversion', function() {
133176
});
134177
renderer.create(
135178
createElement(RootComponent, {
136-
onSomething: x => {
179+
onSomething: (x) => {
137180
assert.strictEqual(x, 'yellow');
138181
done();
139182
},
140-
}),
183+
})
141184
);
142185
});
143186

144-
it('sources.react.props() evolves over time as new props come in', done => {
187+
it('sources.react.props() evolves over time as new props come in', (done) => {
145188
function main(sources: {react: ReactSource}) {
146189
let first = false;
147190
sources.react
148191
.props()
149192
.take(1)
150193
.addListener({
151-
next: props => {
194+
next: (props) => {
152195
assert.strictEqual(props.name, 'Alice');
153196
assert.strictEqual(props.age, 30);
154197
first = true;
@@ -160,7 +203,7 @@ describe('Conversion', function() {
160203
.drop(1)
161204
.take(1)
162205
.addListener({
163-
next: props => {
206+
next: (props) => {
164207
assert.strictEqual(first, true);
165208
assert.strictEqual(props.name, 'alice');
166209
assert.strictEqual(props.age, 31);
@@ -170,7 +213,7 @@ describe('Conversion', function() {
170213

171214
return {
172215
react: xs.of(
173-
h('section', [h('div', {}, [h('h1', {}, 'Hello world')])]),
216+
h('section', [h('div', {}, [h('h1', {}, 'Hello world')])])
174217
),
175218
};
176219
}
@@ -181,12 +224,12 @@ describe('Conversion', function() {
181224
return {source, sink};
182225
});
183226
const r = renderer.create(
184-
createElement(RootComponent, {name: 'Alice', age: 30}),
227+
createElement(RootComponent, {name: 'Alice', age: 30})
185228
);
186229
r.update(createElement(RootComponent, {name: 'alice', age: 31}));
187230
});
188231

189-
it('no synchronous race conditions with handler registration', done => {
232+
it('no synchronous race conditions with handler registration', (done) => {
190233
function main(sources: {react: ReactSource}) {
191234
const inc$ = xs.create({
192235
start(listener: any) {
@@ -201,7 +244,7 @@ describe('Conversion', function() {
201244
});
202245
const count$ = inc$.fold((acc: number, x: any) => acc + 1, 0);
203246
const vdom$ = count$.map((i: number) =>
204-
h(Touchable, {sel: 'button'}, [h('div', [h('h1', {}, '' + i)])]),
247+
h(Touchable, {sel: 'button'}, [h('div', [h('h1', {}, '' + i)])])
205248
);
206249
return {react: vdom$};
207250
}

0 commit comments

Comments
 (0)