Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions bower.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{
"name": "purescript-react-basic",
"license": "Apache-2.0",
"ignore": ["**/.*", "node_modules", "bower_components", "output"],
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"output"
],
"repository": {
"type": "git",
"url": "git://github.com/lumihq/purescript-react-basic.git"
Expand All @@ -17,7 +22,9 @@
"purescript-typelevel-prelude": "^3.0.0",
"purescript-unsafe-coerce": "^4.0.0",
"purescript-web-dom": "^1.0.0",
"purescript-web-events": "^1.0.0"
"purescript-web-events": "^1.0.0",
"purescript-profunctor-lenses": "^5.0.0",
"purescript-indexed-monad": "^1.0.0"
},
"devDependencies": {
"purescript-web-html": "^1.0.0"
Expand Down
5 changes: 2 additions & 3 deletions examples/component/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

## Building

```
npm install
make all
```sh
make
```

This will compile the PureScript source files, bundle them, and use Browserify to combine PureScript and NPM sources into a single bundle.
Expand Down
4 changes: 2 additions & 2 deletions examples/component/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": {
"react": "^16.4.2",
"react-dom": "^16.4.2"
"react": "16.7.0-alpha.2",
"react-dom": "16.7.0-alpha.2"
},
"devDependencies": {
"browserify": "^16.2.2"
Expand Down
25 changes: 13 additions & 12 deletions examples/component/src/Container.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ module Container where

import Prelude

import React.Basic (Component, JSX, createComponent, makeStateless)
import React.Basic (CreateComponent, component, element)
import React.Basic as React
import React.Basic.DOM as R
import ToggleButton (toggleButton)
import ToggleButton (mkToggleButton)

component :: Component Unit
component = createComponent "Container"
mkToggleButtonContainer :: CreateComponent {} Unit
mkToggleButtonContainer = do
toggleButton <- mkToggleButton

toggleButtonContainer :: JSX
toggleButtonContainer = unit # makeStateless component \_ ->
R.div
{ children:
[ toggleButton { label: "A" }
, toggleButton { label: "B" }
]
}
component "Container" \_ ->
React.pure $ R.div
{ children:
[ element toggleButton { label: "A" }
, element toggleButton { label: "B" }
]
}
10 changes: 6 additions & 4 deletions examples/component/src/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ module Main where

import Prelude

import Container (toggleButtonContainer)
import Container (mkToggleButtonContainer)
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Effect.Exception (throw)
import React.Basic (element)
import React.Basic.DOM (render)
import Web.DOM.NonElementParentNode (getElementById)
import Web.HTML (window)
Expand All @@ -17,6 +18,7 @@ main = do
container <- getElementById "container" =<< (map toNonElementParentNode $ document =<< window)
case container of
Nothing -> throw "Container element not found."
Just c ->
let app = toggleButtonContainer
in render app c
Just c -> do
toggleButtonContainer <- mkToggleButtonContainer
let app = element toggleButtonContainer {}
render app c
54 changes: 19 additions & 35 deletions examples/component/src/ToggleButton.purs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,24 @@ module ToggleButton where
import Prelude

import Effect.Console (log)
import React.Basic (Component, JSX, StateUpdate(..), capture_, createComponent, make)
import React.Basic (CreateComponent, UseEffect, UseState, component, toKey, useEffect, useState, (/\))
import React.Basic as React
import React.Basic.DOM as R

component :: Component Props
component = createComponent "ToggleButton"

type Props =
{ label :: String
}

data Action
= Toggle

toggleButton :: Props -> JSX
toggleButton = make component
{ initialState:
{ on: false
import React.Basic.DOM.Events (capture_)

mkToggleButton :: CreateComponent { label :: String } (UseEffect (UseState Boolean Unit))
mkToggleButton = do
component "ToggleButton" \{ label } -> React.do
on /\ setOn <- useState false

useEffect [toKey on] do
log $ "State: " <> if on then "On" else "Off"
pure (pure unit)

React.pure $ R.button
{ onClick: capture_ $ setOn not
, children:
[ R.text label
, R.text if on then " On" else " Off"
]
}

, update: \self -> case _ of
Toggle ->
UpdateAndSideEffects
self.state { on = not self.state.on }
\nextSelf -> do
log $ "next state: " <> show nextSelf.state

, render: \self ->
R.button
{ onClick: capture_ self Toggle
, children:
[ R.text self.props.label
, R.text if self.state.on
then " On"
else " Off"
]
}
}
5 changes: 2 additions & 3 deletions examples/controlled-input/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

## Building

```
npm install
make all
```sh
make
```

This will compile the PureScript source files, bundle them, and use Browserify to combine PureScript and NPM sources into a single bundle.
Expand Down
4 changes: 2 additions & 2 deletions examples/controlled-input/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": {
"react": "^16.4.2",
"react-dom": "^16.4.2"
"react": "16.7.0-alpha.2",
"react-dom": "16.7.0-alpha.2"
},
"devDependencies": {
"browserify": "^16.2.2"
Expand Down
79 changes: 43 additions & 36 deletions examples/controlled-input/src/ControlledInput.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,51 @@ module ControlledInput where

import Prelude

import Control.Applicative.Indexed (ipure)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import React.Basic (Component, JSX, StateUpdate(..), capture, createComponent, make)
import React.Basic (CreateComponent, Render, UseState, component, fragment, useState, (/\))
import React.Basic as React
import React.Basic.DOM as R
import React.Basic.DOM.Events (targetValue, timeStamp)
import React.Basic.Events (merge)

component :: Component Props
component = createComponent "ControlledInput"

type Props = Unit

data Action
= ValueChanged String Number

controlledInput :: Props -> JSX
controlledInput = make component
{ initialState:
{ value: "hello world"
, timestamp: Nothing
}

, update: \self -> case _ of
ValueChanged value timestamp ->
Update self.state
{ value = value
, timestamp = Just timestamp
}
import React.Basic.DOM.Events (capture, targetValue, timeStamp)
import React.Basic.Events (EventHandler, merge)

mkControlledInput :: CreateComponent {} (UseInput () (UseInput () Unit))
mkControlledInput =
component "ControlledInput" \props -> React.do
firstName <- useInput "hello"
lastName <- useInput "world"

React.pure $ R.form_
[ renderInput firstName
, renderInput lastName
]
where
renderInput input =
fragment
[ R.input { onChange: input.onChange, value: input.value }
, R.p_ [ R.text ("Current value = " <> show input.value) ]
, R.p_ [ R.text ("Changed at = " <> maybe "never" show input.lastChanged) ]
]

, render: \self ->
React.fragment
[ R.input
{ onChange:
capture self (merge { targetValue, timeStamp })
\{ timeStamp, targetValue } -> ValueChanged (fromMaybe "" targetValue) timeStamp
, value: self.state.value
type InputState state = { value :: String, lastChanged :: Maybe Number | state }

type UseInput state hooks = UseState (InputState state) hooks
useInput
:: forall hooks
. String
-> Render hooks
(UseInput () hooks)
(InputState ( onChange :: EventHandler ))
useInput initialValue = React.do
{ value, lastChanged } /\ replaceState <- useState { value: initialValue, lastChanged: Nothing }
ipure
{ onChange: capture
(merge { targetValue, timeStamp })
\{ timeStamp, targetValue } -> do
replaceState \_ ->
{ value: fromMaybe "" targetValue
, lastChanged: Just timeStamp
}
, R.p_ [ R.text ("Current value = " <> show self.state.value) ]
, R.p_ [ R.text ("Changed at = " <> maybe "never" show self.state.timestamp) ]
]
}
, value
, lastChanged
}
10 changes: 6 additions & 4 deletions examples/controlled-input/src/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ module Main where

import Prelude

import ControlledInput (controlledInput)
import ControlledInput (mkControlledInput)
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Effect.Exception (throw)
import React.Basic (element)
import React.Basic.DOM (render)
import Web.DOM.NonElementParentNode (getElementById)
import Web.HTML (window)
Expand All @@ -17,6 +18,7 @@ main = do
container <- getElementById "container" =<< (map toNonElementParentNode $ document =<< window)
case container of
Nothing -> throw "Container element not found."
Just c ->
let app = controlledInput unit
in render app c
Just c -> do
controlledInput <- mkControlledInput
let app = element controlledInput {}
render app c
5 changes: 2 additions & 3 deletions examples/counter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

## Building

```
npm install
make all
```sh
make
```

This will compile the PureScript source files, bundle them, and use Browserify to combine PureScript and NPM sources into a single bundle.
Expand Down
4 changes: 2 additions & 2 deletions examples/counter/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": {
"react": "16.6.0",
"react-dom": "16.6.0"
"react": "16.7.0-alpha.2",
"react-dom": "16.7.0-alpha.2"
},
"devDependencies": {
"browserify": "16.2.3"
Expand Down
7 changes: 7 additions & 0 deletions examples/counter/src/Counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"use strict";

exports.setDocumentTitle = function(title) {
return function() {
document.title = title;
};
};
39 changes: 16 additions & 23 deletions examples/counter/src/Counter.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,24 @@ module Counter where

import Prelude


import React.Basic (Component, JSX, StateUpdate(..), capture_, createComponent, make)
import Effect (Effect)
import React.Basic (CreateComponent, UseEffect, UseState, component, toKey, useEffect, useState, (/\))
import React.Basic as React
import React.Basic.DOM as R
import React.Basic.DOM.Events (capture_)

component :: Component Props
component = createComponent "Counter"

type Props =
{ label :: String
}

data Action
= Increment
mkCounter :: CreateComponent {} (UseEffect (UseState Int Unit))
mkCounter = do
component "Counter" \props -> React.do
counter /\ setCounter <- useState 0

counter :: Props -> JSX
counter = make component { initialState, update, render }
where
initialState = { counter: 0, dummy: 0 }
useEffect [toKey counter] do
setDocumentTitle $ "Count: " <> show counter
pure mempty

update self = case _ of
Increment ->
Update self.state { counter = self.state.counter + 1 }
React.pure $ R.button
{ onClick: capture_ $ setCounter (_ + 1)
, children: [ R.text $ "Increment: " <> show counter ]
}

render self =
R.button
{ onClick: capture_ self Increment
, children: [ R.text (self.props.label <> ": " <> show self.state.counter) ]
}
foreign import setDocumentTitle :: String -> Effect Unit
10 changes: 6 additions & 4 deletions examples/counter/src/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ module Main where

import Prelude

import Counter (counter)
import Counter (mkCounter)
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Effect.Exception (throw)
import React.Basic (element)
import React.Basic.DOM (render)
import Web.DOM.NonElementParentNode (getElementById)
import Web.HTML (window)
Expand All @@ -17,6 +18,7 @@ main = do
container <- getElementById "container" =<< (map toNonElementParentNode $ document =<< window)
case container of
Nothing -> throw "Container element not found."
Just c ->
let app = counter { label: "Increment" }
in render app c
Just c -> do
counter <- mkCounter
let app = element counter {}
render app c
Loading