Skip to content

Commit 036bbfe

Browse files
committed
Support JSX Factory
Fixes #8 Implementation of `jsxFactory` is just a copy and paste from @sliptype's pull request (cyclejs/react-dom#3). Test cases have been rewritten in a DOM-free way (using enzyme).
1 parent f9b4a13 commit 036bbfe

File tree

5 files changed

+124
-2
lines changed

5 files changed

+124
-2
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@
4848
"compile": "npm run compile-cjs && npm run compile-es6",
4949
"compile-cjs": "tsc --module commonjs --outDir ./lib/cjs",
5050
"compile-es6": "echo 'TODO' : tsc --module es6 --outDir ./lib/es6",
51-
"test": "$(npm bin)/mocha test/*.ts --require ts-node/register --recursive"
51+
"test": "$(npm bin)/mocha test/*.ts test/*.tsx --require ts-node/register --recursive"
5252
}
5353
}

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export {ReactSource} from './ReactSource';
55
export {h} from './h';
66
export {incorporate} from './incorporate';
77
export {StreamRenderer} from './StreamRenderer';
8+
export {default as jsxFactory} from './jsxFactory';

src/jsxFactory.ts

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {createElement, ReactElement, ReactType} from 'react';
2+
import {incorporate} from './incorporate';
3+
export {Attributes} from 'react';
4+
5+
declare global {
6+
namespace JSX {
7+
interface IntrinsicAttributes {
8+
sel?: string | symbol;
9+
}
10+
}
11+
namespace React {
12+
interface ClassAttributes<T> extends Attributes {
13+
sel?: string | symbol;
14+
}
15+
}
16+
}
17+
18+
type PropsExtensions = {
19+
sel?: string | symbol;
20+
}
21+
22+
function createIncorporatedElement<P = any>(
23+
type: ReactType<P>,
24+
props: P & PropsExtensions | null,
25+
...children: Array<string | ReactElement<any>>
26+
): ReactElement<P> {
27+
if (!props || !props.sel) {
28+
return createElement(type, props, ...children);
29+
} else {
30+
return createElement(incorporate(type), props, ...children);
31+
}
32+
}
33+
34+
export default {
35+
createElement: createIncorporatedElement
36+
}

test/jsxFactory.tsx

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import * as React from 'react';
2+
import * as Adapter from 'enzyme-adapter-react-16';
3+
import * as Enzyme from 'enzyme';
4+
const assert = require('assert');
5+
import {jsxFactory, h, ReactSource, makeCycleReactComponent} from '../src';
6+
7+
Enzyme.configure({adapter: new Adapter()});
8+
9+
const { shallow } = Enzyme;
10+
11+
describe('jsxFactory', function () {
12+
it('w/ nothing', () => {
13+
const wrapper = shallow(<h1></h1>);
14+
15+
assert.strictEqual(wrapper.find('h1').length, 1);
16+
});
17+
18+
it('w/ text child', () => {
19+
const wrapper = shallow(<h1>heading 1</h1>);
20+
21+
const h1 = wrapper.find('h1');
22+
assert.strictEqual(h1.text(), 'heading 1');
23+
});
24+
25+
it('w/ children array', () => {
26+
const wrapper = shallow(
27+
<section>
28+
<h1>heading 1</h1>
29+
<h2>heading 2</h2>
30+
<h3>heading 3</h3>
31+
</section>
32+
);
33+
34+
const section = wrapper.find('section');
35+
assert.strictEqual(section.children().length, 3);
36+
});
37+
38+
it('w/ props', () => {
39+
const wrapper = shallow(<section data-foo='bar' />);
40+
41+
assert(wrapper.exists('[data-foo="bar"]'));
42+
});
43+
44+
it('w/ props and children', () => {
45+
const wrapper = shallow(
46+
<section data-foo="bar">
47+
<h1>heading 1</h1>
48+
<h2>heading 2</h2>
49+
<h3>heading 3</h3>
50+
</section>
51+
);
52+
53+
const section = wrapper.first();
54+
assert.strictEqual(section.length, 1);
55+
assert(section.exists('[data-foo="bar"]'));
56+
assert.deepStrictEqual(section.children().length, 3);
57+
});
58+
59+
it('w/ className', () => {
60+
const wrapper = shallow(<section className="foo" />);
61+
62+
assert(wrapper.hasClass('foo'));
63+
});
64+
65+
it('renders functional component', () => {
66+
const Test = () => <h1>Functional</h1>;
67+
const wrapper = shallow(<Test />);
68+
69+
assert.strictEqual(wrapper.first().type(), 'h1');
70+
});
71+
72+
it('renders class component', () => {
73+
class Test extends React.Component {
74+
render() {
75+
return <h1>Class</h1>;
76+
}
77+
}
78+
79+
const wrapper = shallow(<Test />);
80+
81+
assert.strictEqual(wrapper.first().type(), 'h1');
82+
});
83+
});

tsconfig.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
"rootDir": "src/",
1212
"outDir": "lib/cjs/",
1313
"skipLibCheck": true,
14-
"lib": ["dom", "es5", "scripthost", "es2015"]
14+
"lib": ["dom", "es5", "scripthost", "es2015"],
15+
"jsx": "react",
16+
"jsxFactory": "jsxFactory.createElement"
1517
},
1618
"files": ["src/index.ts"]
1719
}

0 commit comments

Comments
 (0)