Skip to content

Commit 6176477

Browse files
author
Luke William Westby
committed
enable stateless function components
1 parent 6563760 commit 6176477

File tree

4 files changed

+143
-55
lines changed

4 files changed

+143
-55
lines changed

src/extendReactClass.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import linkClass from './linkClass';
2+
import React from 'react';
3+
import _ from 'lodash';
4+
5+
let extendReactClass;
6+
7+
extendReactClass = (Component, defaultStyles, options) => {
8+
return class extends Component {
9+
render () {
10+
let renderResult,
11+
styles;
12+
13+
if (this.props.styles) {
14+
styles = this.props.styles;
15+
} else if (_.isObject(defaultStyles)) {
16+
styles = defaultStyles;
17+
} else {
18+
styles = {};
19+
}
20+
21+
renderResult = super.render();
22+
23+
if (renderResult) {
24+
return linkClass(renderResult, styles, options);
25+
}
26+
27+
return React.createElement('noscript');
28+
}
29+
};
30+
};
31+
32+
export default extendReactClass;

src/index.js

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import linkClass from './linkClass';
2-
import React from 'react';
3-
import _ from 'lodash';
1+
import extendReactClass from './extendReactClass';
2+
import wrapStatelessFunction from './wrapStatelessFunction';
43

54
let decoratorConstructor,
65
functionConstructor;
@@ -16,28 +15,9 @@ let decoratorConstructor,
1615
functionConstructor = (Component, defaultStyles, options) => {
1716
let decoratedClass;
1817

19-
decoratedClass = class extends Component {
20-
render () {
21-
let renderResult,
22-
styles;
23-
24-
if (this.props.styles) {
25-
styles = this.props.styles;
26-
} else if (_.isObject(defaultStyles)) {
27-
styles = defaultStyles;
28-
} else {
29-
styles = {};
30-
}
31-
32-
renderResult = super.render();
33-
34-
if (renderResult) {
35-
return linkClass(renderResult, styles, options);
36-
}
37-
38-
return React.createElement('noscript');
39-
}
40-
};
18+
decoratedClass = Component.isReactClass ?
19+
extendReactClass(Component, defaultStyles, options) :
20+
wrapStatelessFunction(Component, defaultStyles, options);
4121

4222
if (Component.displayName) {
4323
decoratedClass.displayName = Component.displayName;

src/wrapStatelessFunction.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import linkClass from './linkClass';
2+
import React from 'react';
3+
import _ from 'lodash';
4+
5+
let wrapStatelessFunction;
6+
7+
wrapStatelessFunction = (Component, defaultStyles, options) => {
8+
return (props, ...args) => {
9+
let renderResult,
10+
styles;
11+
12+
if (props.styles) {
13+
styles = props.styles;
14+
} else if (_.isObject(defaultStyles)) {
15+
styles = defaultStyles;
16+
} else {
17+
styles = {};
18+
}
19+
20+
renderResult = Component(props, ...args);
21+
22+
if (renderResult) {
23+
return linkClass(renderResult, styles, options);
24+
}
25+
26+
return React.createElement('noscript');
27+
};
28+
};
29+
30+
export default wrapStatelessFunction;

test/reactCssModules.js

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,54 +34,100 @@ describe('reactCssModules', () => {
3434
});
3535
});
3636
context('a ReactComponent renders an element with the styleName prop', () => {
37-
it('that element should contain the equivalent className', () => {
38-
let Foo,
39-
component,
40-
shallowRenderer;
37+
context('the component is a class that extends React.Component', () => {
38+
it('that element should contain the equivalent className', () => {
39+
let Foo,
40+
component,
41+
shallowRenderer;
4142

42-
shallowRenderer = TestUtils.createRenderer();
43+
shallowRenderer = TestUtils.createRenderer();
4344

44-
Foo = class extends React.Component {
45-
render () {
46-
return <div styleName='foo'>Hello</div>;
47-
}
48-
};
45+
Foo = class extends React.Component {
46+
render () {
47+
return <div styleName='foo'>Hello</div>;
48+
}
49+
};
50+
51+
Foo = reactCssModules(Foo, {
52+
foo: 'foo-1'
53+
});
54+
55+
shallowRenderer.render(<Foo />);
56+
57+
component = shallowRenderer.getRenderOutput();
4958

50-
Foo = reactCssModules(Foo, {
51-
foo: 'foo-1'
59+
expect(component.props.className).to.equal('foo-1');
5260
});
61+
});
62+
context('the component is a stateless function component', () => {
63+
it('that element should contain the equivalent className', () => {
64+
let Foo,
65+
component,
66+
shallowRenderer;
67+
68+
shallowRenderer = TestUtils.createRenderer();
69+
70+
Foo = () => <div styleName='foo'>Hello</div>;
5371

54-
shallowRenderer.render(<Foo />);
72+
Foo = reactCssModules(Foo, {
73+
foo: 'foo-1'
74+
});
5575

56-
component = shallowRenderer.getRenderOutput();
76+
shallowRenderer.render(<Foo />);
5777

58-
expect(component.props.className).to.equal('foo-1');
78+
component = shallowRenderer.getRenderOutput();
79+
80+
expect(component.props.className).to.equal('foo-1');
81+
});
5982
});
6083
});
6184

6285
context('a ReactComponent renders nothing', () => {
63-
it('linkClass must not intervene', () => {
64-
let Foo,
65-
component,
66-
shallowRenderer;
86+
context('the component is a class that extends React.Component', () => {
87+
it('linkClass must not intervene', () => {
88+
let Foo,
89+
component,
90+
shallowRenderer;
6791

68-
shallowRenderer = TestUtils.createRenderer();
92+
shallowRenderer = TestUtils.createRenderer();
6993

70-
Foo = class extends React.Component {
71-
render () {
72-
return null;
73-
}
74-
};
94+
Foo = class extends React.Component {
95+
render () {
96+
return null;
97+
}
98+
};
99+
100+
Foo = reactCssModules(Foo, {
101+
foo: 'foo-1'
102+
});
103+
104+
shallowRenderer.render(<Foo />);
105+
106+
component = shallowRenderer.getRenderOutput();
75107

76-
Foo = reactCssModules(Foo, {
77-
foo: 'foo-1'
108+
expect(typeof component).to.equal('object');
78109
});
110+
});
111+
context('the component is a stateless function component', () => {
112+
it('that element should contain the equivalent className', () => {
113+
let Foo,
114+
component,
115+
shallowRenderer;
116+
117+
shallowRenderer = TestUtils.createRenderer();
118+
119+
Foo = () => null;
79120

80-
shallowRenderer.render(<Foo />);
121+
Foo = reactCssModules(Foo, {
122+
foo: 'foo-1'
123+
});
81124

82-
component = shallowRenderer.getRenderOutput();
125+
shallowRenderer.render(<Foo />);
83126

84-
expect(typeof component).to.equal('object');
127+
component = shallowRenderer.getRenderOutput();
128+
129+
expect(typeof component).to.equal('object');
130+
});
85131
});
86132
});
87133
});

0 commit comments

Comments
 (0)