From 3050d3cf50213e6a5b9b85075e0b512122d4eb4e Mon Sep 17 00:00:00 2001 From: eric thul Date: Tue, 11 Aug 2015 22:52:13 -0400 Subject: [PATCH 1/4] Adding createElement The createElement function takes a component factory and props and creates a new component that can be nested in other components. --- src/React.js | 8 ++++++++ src/React.purs | 11 +++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/React.js b/src/React.js index d5b17e5..cd8b5dd 100644 --- a/src/React.js +++ b/src/React.js @@ -79,3 +79,11 @@ exports.renderToElementById = function(id) { } } }; + +exports.createElement = function(factory) { + return function(props) { + return function(children){ + return React.createElement.apply(React, [factory, props].concat(children)); + }; + }; +}; diff --git a/src/React.purs b/src/React.purs index 6f4bd5c..0226897 100644 --- a/src/React.purs +++ b/src/React.purs @@ -22,6 +22,7 @@ module React , Render() , UISpec() + , UIFactory() , Event() , MouseEvent() @@ -45,6 +46,7 @@ module React , renderToString , renderToBody , renderToElementById + , createElement ) where import Prelude @@ -202,6 +204,9 @@ type UISpec props state eff = ) Unit } +-- | Factory function for components. +type UIFactory props = props -> UI + -- | Create a component specification. spec :: forall props state eff. state -> Render props state eff -> UISpec props state eff spec st render = @@ -250,8 +255,7 @@ transformState ctx f = do -- | Create a component from a component spec. foreign import mkUI :: forall props state eff. UISpec props state eff -> - props -> - UI + UIFactory props -- | Create an event handler. foreign import handle :: forall eff ev props state result. @@ -266,3 +270,6 @@ foreign import renderToBody :: forall eff. UI -> Eff (dom :: DOM | eff) UI -- | Render a component to the element with the specified ID. foreign import renderToElementById :: forall eff. String -> UI -> Eff (dom :: DOM | eff) UI + +-- | Create an element from a component factory. +foreign import createElement :: forall props. UIFactory props -> props -> Array UI -> UI From caec2a7622d2bd9db94bd3a61d27e4dfdf719ff2 Mon Sep 17 00:00:00 2001 From: eric thul Date: Tue, 11 Aug 2015 22:59:27 -0400 Subject: [PATCH 2/4] Updating module documentation --- docs/React.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/React.md b/docs/React.md index cc41134..f26fbf4 100644 --- a/docs/React.md +++ b/docs/React.md @@ -160,6 +160,14 @@ type UISpec props state eff = { render :: Render props state eff, displayName :: A specification of a component. +#### `UIFactory` + +``` purescript +type UIFactory props = props -> UI +``` + +Factory function for components. + #### `spec` ``` purescript @@ -211,7 +219,7 @@ Transform the component state by applying a function. #### `mkUI` ``` purescript -mkUI :: forall props state eff. UISpec props state eff -> props -> UI +mkUI :: forall props state eff. UISpec props state eff -> UIFactory props ``` Create a component from a component spec. @@ -248,4 +256,12 @@ renderToElementById :: forall eff. String -> UI -> Eff (dom :: DOM | eff) UI Render a component to the element with the specified ID. +#### `createElement` + +``` purescript +createElement :: forall props. UIFactory props -> props -> Array UI -> UI +``` + +Create an element from a component factory. + From ab287a280b5b8b9025a1483c11df252d79a9f301 Mon Sep 17 00:00:00 2001 From: eric thul Date: Tue, 11 Aug 2015 23:40:30 -0400 Subject: [PATCH 3/4] Adding getChildren function Allows for access to the implicit `children` prop on components. --- docs/React.md | 8 ++++++++ src/React.js | 6 ++++++ src/React.purs | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/docs/React.md b/docs/React.md index f26fbf4..067a560 100644 --- a/docs/React.md +++ b/docs/React.md @@ -192,6 +192,14 @@ getRefs :: forall write eff. UIRef -> Eff (refs :: ReactRefs (Read write) | eff) Read the component refs. +#### `getChildren` + +``` purescript +getChildren :: forall props eff. UIRef -> Eff (props :: ReactProps props | eff) (Array UI) +``` + +Read the component children property. + #### `writeState` ``` purescript diff --git a/src/React.js b/src/React.js index cd8b5dd..5c4ca38 100644 --- a/src/React.js +++ b/src/React.js @@ -15,6 +15,12 @@ exports.getRefs = function(ctx) { }; }; +exports.getChildren = function(ctx) { + return function() { + return ctx.props.children; + }; +}; + exports.writeState = function(ctx) { return function(state) { return function() { diff --git a/src/React.purs b/src/React.purs index 0226897..a4dacf2 100644 --- a/src/React.purs +++ b/src/React.purs @@ -34,6 +34,7 @@ module React , getProps , getRefs + , getChildren , readState , writeState @@ -232,6 +233,11 @@ foreign import getRefs :: forall write eff. UIRef -> Eff (refs :: ReactRefs (Read write) | eff) Refs +-- | Read the component children property. +foreign import getChildren :: forall props eff. + UIRef -> + Eff (props :: ReactProps props | eff) (Array UI) + -- | Write the component state. foreign import writeState :: forall state eff. UIRef -> From a9b29cc74fe3aed7793d014b23b715deb96f83c1 Mon Sep 17 00:00:00 2001 From: eric thul Date: Fri, 14 Aug 2015 22:23:27 -0400 Subject: [PATCH 4/4] Adding an example for createElement --- test/Container.purs | 19 +++++++++++++++++++ test/Main.purs | 18 ++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 test/Container.purs diff --git a/test/Container.purs b/test/Container.purs new file mode 100644 index 0000000..526409c --- /dev/null +++ b/test/Container.purs @@ -0,0 +1,19 @@ +module Test.Container where + +import Prelude + +import React + +import qualified React.DOM as D +import qualified React.DOM.Props as P + +container = mkUI $ spec unit \ctx -> do + children <- getChildren ctx + + let ui = D.div [ P.style { borderColor: "red" + , borderWidth: 2 + , padding: 10 + } + ] children + + return ui diff --git a/test/Main.purs b/test/Main.purs index 4bc8552..565bfc3 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -10,8 +10,10 @@ import React import qualified React.DOM as D import qualified React.DOM.Props as P -foreign import interval :: forall eff a. - Int -> +import Test.Container (container) + +foreign import interval :: forall eff a. + Int -> Eff eff a -> Eff eff Unit @@ -19,7 +21,7 @@ hello = mkUI $ spec unit \ctx -> do props <- getProps ctx return $ D.h1 [ P.className "Hello" , P.style { background: "lightgray" } - ] + ] [ D.text "Hello, " , D.text props.name ] @@ -44,5 +46,13 @@ counter = mkUI counterSpec ] main = do - let component = D.div' [ hello { name: "World" }, counter unit ] + let component = D.div' [ + hello { name: "World" }, + counter unit, + createElement container unit [ + D.p [] [ D.text "This is line one" ], + D.p [] [ D.text "This is line two" ] + ] + ] + renderToBody component