1
1
-- | This module defines foreign types and functions which wrap React's functionality.
2
2
3
3
module React
4
- ( class ReactRender
5
- , ReactElement
4
+ ( ReactElement
6
5
, ReactComponent
7
6
, ReactThis
8
7
, TagName
@@ -66,6 +65,9 @@ module React
66
65
, childrenCount
67
66
68
67
, class ReactPropFields
68
+ , class IsReactElement
69
+ , toElement
70
+ , fragmentWithKey
69
71
) where
70
72
71
73
import Prelude
@@ -74,6 +76,7 @@ import Control.Monad.Eff (kind Effect, Eff)
74
76
import Control.Monad.Eff.Exception (Error )
75
77
import Control.Monad.Eff.Uncurried (EffFn2 , runEffFn2 )
76
78
import Data.Nullable (Nullable )
79
+ import Unsafe.Coerce (unsafeCoerce )
77
80
78
81
-- | Name of a tag.
79
82
type TagName = String
@@ -145,25 +148,13 @@ type EventHandlerContext eff props state result =
145
148
| eff
146
149
) result
147
150
148
- class ReactRender a
149
-
150
- instance arrayReactRender :: ReactRender (Array ReactElement )
151
-
152
- instance reactElementReactRender :: ReactRender ReactElement
153
-
154
- instance stringReactRender :: ReactRender String
155
-
156
- instance intReactRender :: ReactRender Int
157
-
158
- instance numberReactRender :: ReactRender Number
159
-
160
151
-- | A render function.
161
- type Render render eff =
152
+ type Render eff =
162
153
Eff
163
154
( props :: ReactProps
164
155
, state :: ReactState ReadOnly
165
156
| eff
166
- ) render
157
+ ) ReactElement
167
158
168
159
-- | A component will mount function.
169
160
type ComponentWillMount eff =
@@ -238,9 +229,9 @@ type ComponentWillUnmount eff =
238
229
) Unit
239
230
240
231
-- | Required fields for constructing a ReactClass.
241
- type ReactSpecRequired state render eff r =
232
+ type ReactSpecRequired state eff r =
242
233
( state :: state
243
- , render :: Render render eff
234
+ , render :: Render eff
244
235
| r
245
236
)
246
237
@@ -260,40 +251,38 @@ type ReactSpecShouldComponentUpdate props state eff =
260
251
( shouldComponentUpdate :: ShouldComponentUpdate props state eff
261
252
)
262
253
263
- type ReactSpecAll props state render eff =
264
- ReactSpecRequired state render eff (ReactSpecOptional props state eff (ReactSpecShouldComponentUpdate props state eff ))
254
+ type ReactSpecAll props state eff =
255
+ ReactSpecRequired state eff (ReactSpecOptional props state eff (ReactSpecShouldComponentUpdate props state eff ))
265
256
266
- type ReactSpecPure props state render eff =
267
- ReactSpecRequired state render eff (ReactSpecOptional props state eff ())
257
+ type ReactSpecPure props state eff =
258
+ ReactSpecRequired state eff (ReactSpecOptional props state eff ())
268
259
269
260
-- | The signature for a ReactClass constructor. A constructor takes the
270
261
-- | `ReactThis` context and returns a record with appropriate lifecycle
271
262
-- | methods.
272
- type ReactClassConstructor props state render eff r =
263
+ type ReactClassConstructor props state eff r =
273
264
ReactThis props state ->
274
265
Eff
275
266
( props :: ReactProps
276
267
, state :: ReactState Disallowed
277
268
| eff
278
- ) (Record (ReactSpecRequired state render eff r ))
269
+ ) (Record (ReactSpecRequired state eff r ))
279
270
280
271
-- | Creates a `ReactClass`` inherited from `React.Component`.
281
272
component
282
- :: forall props state render eff r x
283
- . Union (ReactSpecRequired (Record state ) render eff r ) x (ReactSpecAll (Record props ) (Record state ) render eff )
284
- => ReactRender render
273
+ :: forall props state eff r x
274
+ . Union (ReactSpecRequired (Record state ) eff r ) x (ReactSpecAll (Record props ) (Record state ) eff )
285
275
=> String
286
- -> ReactClassConstructor (Record props ) (Record state ) render eff r
276
+ -> ReactClassConstructor (Record props ) (Record state ) eff r
287
277
-> ReactClass (Record props )
288
278
component = componentImpl
289
279
290
280
-- | Creates a `ReactClass`` inherited from `React.PureComponent`.
291
281
pureComponent
292
- :: forall props state render eff r x
293
- . Union (ReactSpecRequired (Record state ) render eff r ) x (ReactSpecPure (Record props ) (Record state ) render eff )
294
- => ReactRender render
282
+ :: forall props state eff r x
283
+ . Union (ReactSpecRequired (Record state ) eff r ) x (ReactSpecPure (Record props ) (Record state ) eff )
295
284
=> String
296
- -> ReactClassConstructor (Record props ) (Record state ) render eff r
285
+ -> ReactClassConstructor (Record props ) (Record state ) eff r
297
286
-> ReactClass (Record props )
298
287
pureComponent = pureComponentImpl
299
288
@@ -314,6 +303,8 @@ foreign import statelessComponent :: forall props.
314
303
-- | React class for components.
315
304
foreign import data ReactClass :: Type -> Type
316
305
306
+ foreign import fragment :: ReactClass { children :: Children }
307
+
317
308
-- | Type for React refs. This type is opaque, but you can use `Data.Foreign`
318
309
-- | and `DOM` to validate the underlying representation.
319
310
foreign import data Ref :: Type
@@ -435,3 +426,28 @@ foreign import childrenCount :: Children -> Int
435
426
foreign import preventDefault :: forall eff . Event -> Eff eff Unit
436
427
437
428
foreign import stopPropagation :: forall eff . Event -> Eff eff Unit
429
+
430
+ class IsReactElement a where
431
+ toElement :: a -> ReactElement
432
+
433
+ instance isReactElementString :: IsReactElement String where
434
+ toElement = unsafeCoerce
435
+
436
+ instance isReactElementNumber :: IsReactElement Number where
437
+ toElement = unsafeCoerce
438
+
439
+ instance isReactElementInt :: IsReactElement Int where
440
+ toElement = unsafeCoerce
441
+
442
+ instance isReactElementChildren :: IsReactElement Children where
443
+ toElement = unsafeCoerce
444
+
445
+ instance isReactElementReactElement :: IsReactElement ReactElement where
446
+ toElement = id
447
+
448
+ instance isReactElementArray :: IsReactElement (Array ReactElement ) where
449
+ toElement = createElement fragment {}
450
+
451
+ -- | Creates a keyed fragment.
452
+ fragmentWithKey :: String -> Array ReactElement -> ReactElement
453
+ fragmentWithKey = createElement fragment <<< { key: _ }
0 commit comments