@@ -52,61 +52,40 @@ function isNativeClass(component: Function): boolean {
52
52
/ ^ \s * c l a s s \s + / . test ( component . toString ( ) ) ;
53
53
}
54
54
55
- export default function enhanceWithRadium (
56
- configOrComposedComponent : Class < any > | constructor | Function | Object ,
57
- config ?: Object = { }
58
- ) : constructor {
59
- if ( typeof configOrComposedComponent !== 'function' ) {
60
- const newConfig = { ...config , ...configOrComposedComponent } ;
61
- return function ( configOrComponent ) {
62
- return enhanceWithRadium ( configOrComponent , newConfig ) ;
63
- } ;
64
- }
65
-
66
- const component : Function = configOrComposedComponent ;
67
- let ComposedComponent : constructor = component ;
68
-
69
- // Radium is transpiled in npm, so it isn't really using es6 classes at
70
- // runtime. However, the user of Radium might be. In this case we have
71
- // to maintain forward compatibility with native es classes.
72
- if ( isNativeClass ( ComposedComponent ) ) {
73
- ComposedComponent = ( function ( OrigComponent ) : constructor {
74
- function NewComponent ( ) {
75
- // Use Reflect.construct to simulate 'new'
76
- const obj = Reflect . construct (
77
- OrigComponent ,
78
- arguments ,
79
- this . constructor
80
- ) ;
81
-
82
- return obj ;
83
- }
84
-
85
- // $FlowFixMe
86
- Reflect . setPrototypeOf ( NewComponent . prototype , OrigComponent . prototype ) ;
87
- // $FlowFixMe
88
- Reflect . setPrototypeOf ( NewComponent , OrigComponent ) ;
89
-
90
- return NewComponent ;
91
- } ) ( ComposedComponent ) ;
92
- }
93
-
94
- // Handle stateless components
95
- if ( isStateless ( ComposedComponent ) ) {
96
- ComposedComponent = class extends Component < any , Object > {
97
- render ( ) {
98
- return component ( this . props , this . context ) ;
99
- }
100
- } ;
101
-
102
- ComposedComponent . displayName = component . displayName || component . name ;
103
- }
104
-
105
- // Shallow copy composed if still original (we may mutate later).
106
- if ( ComposedComponent === component ) {
107
- ComposedComponent = class extends ComposedComponent { } ;
108
- }
55
+ // Handle es7 arrow functions on React class method names by detecting
56
+ // and transfering the instance method to original class prototype.
57
+ // (Using a copy of the class).
58
+ // See: https://github.com/FormidableLabs/radium/issues/738
59
+ function copyArrowFuncs ( enhancedSelf : Object , ComposedComponent : constructor ) {
60
+ RADIUM_METHODS . forEach ( name => {
61
+ const thisDesc = Object . getOwnPropertyDescriptor ( enhancedSelf , name ) ;
62
+ const thisMethod = ( thisDesc || { } ) . value ;
63
+ // Only care if have instance method.
64
+ if ( ! thisMethod ) {
65
+ return ;
66
+ }
67
+ const radiumDesc = Object . getOwnPropertyDescriptor ( RADIUM_PROTO , name ) ;
68
+ const radiumProtoMethod = ( radiumDesc || { } ) . value ;
69
+ const superProtoMethod = ComposedComponent . prototype [ name ] ;
70
+ // Allow transfer when:
71
+ // 1. have an instance method
72
+ // 2. the super class prototype doesn't have any method
73
+ // 3. it is not already the radium prototype's
74
+ if ( ! superProtoMethod && thisMethod !== radiumProtoMethod ) {
75
+ // Transfer dynamic render component to Component prototype (copy).
76
+ Object . defineProperty ( ComposedComponent . prototype , name , thisDesc ) ;
77
+ // Remove instance property, leaving us to have a contrived
78
+ // inheritance chain of (1) radium, (2) superclass.
79
+ delete enhancedSelf [ name ] ;
80
+ }
81
+ } ) ;
82
+ }
109
83
84
+ function createEnhancedComponent (
85
+ origComponent : Function ,
86
+ ComposedComponent : constructor ,
87
+ config ?: Object
88
+ ) {
110
89
class RadiumEnhancer extends ComposedComponent {
111
90
static _isRadiumEnhanced = true ;
112
91
@@ -129,36 +108,8 @@ export default function enhanceWithRadium(
129
108
130
109
const self : Object = this ;
131
110
132
- // Handle es7 arrow functions on React class method names by detecting
133
- // and transfering the instance method to original class prototype.
134
- // (Using a copy of the class).
135
- // See: https://github.com/FormidableLabs/radium/issues/738
136
- RADIUM_METHODS . forEach ( name => {
137
- const thisDesc = Object . getOwnPropertyDescriptor ( self , name ) ;
138
- const thisMethod = ( thisDesc || { } ) . value ;
139
-
140
- // Only care if have instance method.
141
- if ( ! thisMethod ) {
142
- return ;
143
- }
144
-
145
- const radiumDesc = Object . getOwnPropertyDescriptor ( RADIUM_PROTO , name ) ;
146
- const radiumProtoMethod = radiumDesc . value ;
147
- const superProtoMethod = ComposedComponent . prototype [ name ] ;
148
-
149
- // Allow transfer when:
150
- // 1. have an instance method
151
- // 2. the super class prototype doesn't have any method
152
- // 3. it is not already the radium prototype's
153
- if ( ! superProtoMethod && thisMethod !== radiumProtoMethod ) {
154
- // Transfer dynamic render component to Component prototype (copy).
155
- Object . defineProperty ( ComposedComponent . prototype , name , thisDesc ) ;
156
-
157
- // Remove instance property, leaving us to have a contrived
158
- // inheritance chain of (1) radium, (2) superclass.
159
- delete self [ name ] ;
160
- }
161
- } ) ;
111
+ // Handle es7 arrow functions on React class method
112
+ copyArrowFuncs ( self , ComposedComponent ) ;
162
113
}
163
114
164
115
componentWillUnmount ( ) {
@@ -191,7 +142,7 @@ export default function enhanceWithRadium(
191
142
return superChildContext ;
192
143
}
193
144
194
- const newContext = { ...superChildContext } ;
145
+ const newContext : Object = { ...superChildContext } ;
195
146
196
147
if ( this . props . radiumConfig ) {
197
148
newContext . _radiumConfig = this . props . radiumConfig ;
@@ -213,6 +164,7 @@ export default function enhanceWithRadium(
213
164
} ;
214
165
}
215
166
167
+ // do the style and interaction work
216
168
const { extraStateKeyMap , element } = resolveStyles (
217
169
this ,
218
170
renderedElement ,
@@ -255,7 +207,7 @@ export default function enhanceWithRadium(
255
207
// with IE <10 any static properties of the superclass aren't inherited and
256
208
// so need to be manually populated.
257
209
// See http://babeljs.io/docs/advanced/caveats/#classes-10-and-below-
258
- copyProperties ( component , RadiumEnhancer ) ;
210
+ copyProperties ( origComponent , RadiumEnhancer ) ;
259
211
260
212
if ( process . env . NODE_ENV !== 'production' ) {
261
213
// This also fixes React Hot Loader by exposing the original components top
@@ -264,17 +216,20 @@ export default function enhanceWithRadium(
264
216
copyProperties ( ComposedComponent . prototype , RadiumEnhancer . prototype ) ;
265
217
}
266
218
219
+ // add Radium propTypes to enhanced component's propTypes
267
220
if ( RadiumEnhancer . propTypes && RadiumEnhancer . propTypes . style ) {
268
221
RadiumEnhancer . propTypes = {
269
222
...RadiumEnhancer . propTypes ,
270
223
style : PropTypes . oneOfType ( [ PropTypes . array , PropTypes . object ] )
271
224
} ;
272
225
}
273
226
274
- RadiumEnhancer . displayName = component . displayName ||
275
- component . name ||
227
+ // copy display name to enhanced component
228
+ RadiumEnhancer . displayName = origComponent . displayName ||
229
+ origComponent . name ||
276
230
'Component' ;
277
231
232
+ // handle context
278
233
RadiumEnhancer . contextTypes = {
279
234
...RadiumEnhancer . contextTypes ,
280
235
_radiumConfig : PropTypes . object ,
@@ -289,3 +244,76 @@ export default function enhanceWithRadium(
289
244
290
245
return RadiumEnhancer ;
291
246
}
247
+
248
+ function createComposedFromStatelessFunc (
249
+ ComposedComponent : constructor ,
250
+ component : Function
251
+ ) {
252
+ ComposedComponent = class extends Component < any , Object > {
253
+ render ( ) {
254
+ return component ( this . props , this . context ) ;
255
+ }
256
+ } ;
257
+ ComposedComponent . displayName = component . displayName || component . name ;
258
+ return ComposedComponent ;
259
+ }
260
+
261
+ function createComposedFromNativeClass ( ComposedComponent : constructor ) {
262
+ ComposedComponent = ( function ( OrigComponent ) : constructor {
263
+ function NewComponent ( ) {
264
+ // Use Reflect.construct to simulate 'new'
265
+ const obj = Reflect . construct ( OrigComponent , arguments , this . constructor ) ;
266
+ return obj ;
267
+ }
268
+ // $FlowFixMe
269
+ Reflect . setPrototypeOf ( NewComponent . prototype , OrigComponent . prototype ) ;
270
+ // $FlowFixMe
271
+ Reflect . setPrototypeOf ( NewComponent , OrigComponent ) ;
272
+ return NewComponent ;
273
+ } ) ( ComposedComponent ) ;
274
+ return ComposedComponent ;
275
+ }
276
+
277
+ export default function enhanceWithRadium (
278
+ configOrComposedComponent : Class < any > | constructor | Function | Object ,
279
+ config ?: Object = { }
280
+ ) : constructor {
281
+ if ( typeof configOrComposedComponent !== 'function' ) {
282
+ return createFactoryFromConfig ( config , configOrComposedComponent ) ;
283
+ }
284
+
285
+ const origComponent : Function = configOrComposedComponent ;
286
+ let ComposedComponent : constructor = origComponent ;
287
+
288
+ // Radium is transpiled in npm, so it isn't really using es6 classes at
289
+ // runtime. However, the user of Radium might be. In this case we have
290
+ // to maintain forward compatibility with native es classes.
291
+ if ( isNativeClass ( ComposedComponent ) ) {
292
+ ComposedComponent = createComposedFromNativeClass ( ComposedComponent ) ;
293
+ }
294
+
295
+ // Handle stateless components
296
+ if ( isStateless ( ComposedComponent ) ) {
297
+ ComposedComponent = createComposedFromStatelessFunc (
298
+ ComposedComponent ,
299
+ origComponent
300
+ ) ;
301
+ }
302
+
303
+ // Shallow copy composed if still original (we may mutate later).
304
+ if ( ComposedComponent === origComponent ) {
305
+ ComposedComponent = class extends ComposedComponent { } ;
306
+ }
307
+
308
+ return createEnhancedComponent ( origComponent , ComposedComponent , config ) ;
309
+ }
310
+
311
+ function createFactoryFromConfig (
312
+ config : Object ,
313
+ configOrComposedComponent : Object
314
+ ) {
315
+ const newConfig = { ...config , ...configOrComposedComponent } ;
316
+ return function ( configOrComponent ) {
317
+ return enhanceWithRadium ( configOrComponent , newConfig ) ;
318
+ } ;
319
+ }
0 commit comments