Skip to content

Commit 91d07ac

Browse files
committed
Merge pull request #37 from ethul/topic/createElement
Topic/create element
2 parents ca42942 + a9b29cc commit 91d07ac

File tree

5 files changed

+87
-7
lines changed

5 files changed

+87
-7
lines changed

Diff for: docs/React.md

+25-1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,14 @@ type UISpec props state eff = { render :: Render props state eff, displayName ::
160160

161161
A specification of a component.
162162

163+
#### `UIFactory`
164+
165+
``` purescript
166+
type UIFactory props = props -> UI
167+
```
168+
169+
Factory function for components.
170+
163171
#### `spec`
164172

165173
``` purescript
@@ -184,6 +192,14 @@ getRefs :: forall write eff. UIRef -> Eff (refs :: ReactRefs (Read write) | eff)
184192

185193
Read the component refs.
186194

195+
#### `getChildren`
196+
197+
``` purescript
198+
getChildren :: forall props eff. UIRef -> Eff (props :: ReactProps props | eff) (Array UI)
199+
```
200+
201+
Read the component children property.
202+
187203
#### `writeState`
188204

189205
``` purescript
@@ -211,7 +227,7 @@ Transform the component state by applying a function.
211227
#### `mkUI`
212228

213229
``` purescript
214-
mkUI :: forall props state eff. UISpec props state eff -> props -> UI
230+
mkUI :: forall props state eff. UISpec props state eff -> UIFactory props
215231
```
216232

217233
Create a component from a component spec.
@@ -248,4 +264,12 @@ renderToElementById :: forall eff. String -> UI -> Eff (dom :: DOM | eff) UI
248264

249265
Render a component to the element with the specified ID.
250266

267+
#### `createElement`
268+
269+
``` purescript
270+
createElement :: forall props. UIFactory props -> props -> Array UI -> UI
271+
```
272+
273+
Create an element from a component factory.
274+
251275

Diff for: src/React.js

+14
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ exports.getRefs = function(ctx) {
1515
};
1616
};
1717

18+
exports.getChildren = function(ctx) {
19+
return function() {
20+
return ctx.props.children;
21+
};
22+
};
23+
1824
exports.writeState = function(ctx) {
1925
return function(state) {
2026
return function() {
@@ -79,3 +85,11 @@ exports.renderToElementById = function(id) {
7985
}
8086
}
8187
};
88+
89+
exports.createElement = function(factory) {
90+
return function(props) {
91+
return function(children){
92+
return React.createElement.apply(React, [factory, props].concat(children));
93+
};
94+
};
95+
};

Diff for: src/React.purs

+15-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module React
2222
, Render()
2323

2424
, UISpec()
25+
, UIFactory()
2526

2627
, Event()
2728
, MouseEvent()
@@ -33,6 +34,7 @@ module React
3334

3435
, getProps
3536
, getRefs
37+
, getChildren
3638

3739
, readState
3840
, writeState
@@ -45,6 +47,7 @@ module React
4547
, renderToString
4648
, renderToBody
4749
, renderToElementById
50+
, createElement
4851
) where
4952

5053
import Prelude
@@ -202,6 +205,9 @@ type UISpec props state eff =
202205
) Unit
203206
}
204207

208+
-- | Factory function for components.
209+
type UIFactory props = props -> UI
210+
205211
-- | Create a component specification.
206212
spec :: forall props state eff. state -> Render props state eff -> UISpec props state eff
207213
spec st render =
@@ -227,6 +233,11 @@ foreign import getRefs :: forall write eff.
227233
UIRef ->
228234
Eff (refs :: ReactRefs (Read write) | eff) Refs
229235

236+
-- | Read the component children property.
237+
foreign import getChildren :: forall props eff.
238+
UIRef ->
239+
Eff (props :: ReactProps props | eff) (Array UI)
240+
230241
-- | Write the component state.
231242
foreign import writeState :: forall state eff.
232243
UIRef ->
@@ -250,8 +261,7 @@ transformState ctx f = do
250261
-- | Create a component from a component spec.
251262
foreign import mkUI :: forall props state eff.
252263
UISpec props state eff ->
253-
props ->
254-
UI
264+
UIFactory props
255265

256266
-- | Create an event handler.
257267
foreign import handle :: forall eff ev props state result.
@@ -266,3 +276,6 @@ foreign import renderToBody :: forall eff. UI -> Eff (dom :: DOM | eff) UI
266276

267277
-- | Render a component to the element with the specified ID.
268278
foreign import renderToElementById :: forall eff. String -> UI -> Eff (dom :: DOM | eff) UI
279+
280+
-- | Create an element from a component factory.
281+
foreign import createElement :: forall props. UIFactory props -> props -> Array UI -> UI

Diff for: test/Container.purs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module Test.Container where
2+
3+
import Prelude
4+
5+
import React
6+
7+
import qualified React.DOM as D
8+
import qualified React.DOM.Props as P
9+
10+
container = mkUI $ spec unit \ctx -> do
11+
children <- getChildren ctx
12+
13+
let ui = D.div [ P.style { borderColor: "red"
14+
, borderWidth: 2
15+
, padding: 10
16+
}
17+
] children
18+
19+
return ui

Diff for: test/Main.purs

+14-4
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ import React
1010
import qualified React.DOM as D
1111
import qualified React.DOM.Props as P
1212

13-
foreign import interval :: forall eff a.
14-
Int ->
13+
import Test.Container (container)
14+
15+
foreign import interval :: forall eff a.
16+
Int ->
1517
Eff eff a ->
1618
Eff eff Unit
1719

1820
hello = mkUI $ spec unit \ctx -> do
1921
props <- getProps ctx
2022
return $ D.h1 [ P.className "Hello"
2123
, P.style { background: "lightgray" }
22-
]
24+
]
2325
[ D.text "Hello, "
2426
, D.text props.name
2527
]
@@ -44,5 +46,13 @@ counter = mkUI counterSpec
4446
]
4547

4648
main = do
47-
let component = D.div' [ hello { name: "World" }, counter unit ]
49+
let component = D.div' [
50+
hello { name: "World" },
51+
counter unit,
52+
createElement container unit [
53+
D.p [] [ D.text "This is line one" ],
54+
D.p [] [ D.text "This is line two" ]
55+
]
56+
]
57+
4858
renderToBody component

0 commit comments

Comments
 (0)