Skip to content

Instantly share code, notes, and snippets.

@paf31

paf31/Main.purs Secret

Created November 21, 2015 01:28
Show Gist options
  • Save paf31/bdcb1fb0df19e565ade2 to your computer and use it in GitHub Desktop.
Save paf31/bdcb1fb0df19e565ade2 to your computer and use it in GitHub Desktop.
Thermite Example
{
"name": "purescript-thermite-example",
"moduleType": [
"node"
],
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"output"
],
"dependencies": {
"purescript-thermite": "^0.12.0"
"react": "^0.13.0"
}
}
<!doctype>
<html>
<head>
<title>Thermite Example</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="container" class="container">
<script src="../bower_components/react/react.js"></script>
<script src="index.js"></script>
</div>
</body>
</html>
module Main where
import Prelude
import Control.Monad.Eff
import Data.List as L
import Data.Foldable (fold)
import Data.Lens
import Data.Maybe (fromMaybe)
import Data.Maybe.Unsafe (fromJust)
import Data.Nullable (toMaybe)
import Data.Tuple
import Data.Either
import Thermite as T
import React as R
import React.DOM as R
import React.DOM.Props as RP
import DOM as DOM
import DOM.HTML as DOM
import DOM.HTML.Window as DOM
import DOM.HTML.Types as DOM
import DOM.Node.ParentNode as DOM
import Unsafe.Coerce
data TaskAction
= EditText String
| RemoveTask
type TaskState = { text :: String }
unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value
taskSpec :: forall eff props. T.Spec eff TaskState props TaskAction
taskSpec = T.simpleSpec performAction render
where
render :: T.Render TaskState _ TaskAction
render send _ s _ =
[ R.p' [ R.input [ RP.value s.text
, RP.onChange \e -> send (EditText (unsafeEventValue e))
] []
, R.button [ RP.onClick \_ -> send RemoveTask ] [ R.text "✖" ]
]
]
performAction :: T.PerformAction _ TaskState _ TaskAction
performAction (EditText text) _ _ update = update { text: text }
performAction _ _ _ _ = pure unit
data TaskListAction
= NewTask
| TaskAction Int TaskAction
_TaskAction :: PrismP TaskListAction (Tuple Int TaskAction)
_TaskAction = prism (uncurry TaskAction) \ta ->
case ta of
TaskAction i a -> Right (Tuple i a)
_ -> Left ta
type TaskListState = { tasks :: L.List TaskState }
_tasks :: LensP TaskListState (L.List TaskState)
_tasks = lens _.tasks (_ { tasks = _ })
taskList :: forall props eff. T.Spec eff TaskListState props TaskListAction
taskList = fold [ header
, T.focus _tasks _TaskAction $ T.foreach \_ -> taskSpec
]
where
header :: T.Spec _ TaskListState _ TaskListAction
header = T.simpleSpec performAction render
where
render :: T.Render TaskListState _ TaskListAction
render send _ state _ = [ R.p' [ R.button [ RP.onClick \_ -> send NewTask ] [ R.text "New Task" ] ] ]
performAction :: T.PerformAction _ TaskListState _ TaskListAction
performAction NewTask _ state update = update $ state { tasks = L.Cons { text: "" } state.tasks }
performAction (TaskAction i RemoveTask) _ state update = update $ state { tasks = fromMaybe state.tasks (L.deleteAt i state.tasks) }
performAction _ _ _ _ = pure unit
main :: Eff (dom :: DOM.DOM) Unit
main = void do
let component = T.createClass taskList { tasks: L.Nil }
document <- DOM.window >>= DOM.document
container <- fromJust <<< toMaybe <$> DOM.querySelector "#container" (DOM.htmlDocumentToParentNode document)
R.render (R.createFactory component {}) container
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment