Skip to content

Commit 8733471

Browse files
committed
Add ComponentsMultiTypeReactHooks
1 parent 1644a08 commit 8733471

File tree

6 files changed

+188
-0
lines changed

6 files changed

+188
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/bower_components/
2+
/node_modules/
3+
/.pulp-cache/
4+
/output/
5+
/generated-docs/
6+
/.psc-package/
7+
/.psc*
8+
/.purs*
9+
/.psa*
10+
/.spago
11+
/.cache/
12+
/dist/
13+
/web-dist/
14+
/prod-dist/
15+
/prod/
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# ComponentsMultiTypeReactHooks
2+
3+
Demonstrates a parent component with several children components, each with different prop types.
4+
5+
## Expected Behavior:
6+
7+
### Browser
8+
9+
A toggle button, a count button, and an input field are the children of the parent. The user can modify the state of any of those inputs and then click the "Check now" button. This will update the most recent observed state.
10+
11+
## Dependencies Used:
12+
13+
[react](https://www.npmjs.com/package/react)
14+
[react-dom](https://www.npmjs.com/package/react-dom)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{ name = "ComponentsMultiTypeReactHooks"
2+
, dependencies =
3+
[ "console"
4+
, "effect"
5+
, "psci-support"
6+
, "react-basic-hooks"
7+
, "react-basic-dom"
8+
]
9+
, packages = ../../packages.dhall
10+
, sources = [ "recipes/ComponentsMultiTypeReactHooks/src/**/*.purs" ]
11+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
module ComponentsMultiTypeReactHooks.Main where
2+
3+
import Prelude
4+
import Data.Maybe (Maybe(..), fromMaybe)
5+
import Data.Tuple (fst)
6+
import Effect (Effect)
7+
import Effect.Exception (throw)
8+
import React.Basic.DOM (render)
9+
import React.Basic.DOM as R
10+
import React.Basic.DOM.Events (targetValue)
11+
import React.Basic.Events (EventHandler, handler, handler_)
12+
import React.Basic.Hooks
13+
( Component
14+
, Hook
15+
, UseState
16+
, component
17+
, useState
18+
, useState'
19+
, (/\)
20+
, type (/\)
21+
)
22+
import React.Basic.Hooks as React
23+
import Web.HTML (window)
24+
import Web.HTML.HTMLDocument (body)
25+
import Web.HTML.HTMLElement (toElement)
26+
import Web.HTML.Window (document)
27+
28+
main :: Effect Unit
29+
main = do
30+
body <- body =<< document =<< window
31+
case body of
32+
Nothing -> throw "Could not find body."
33+
Just b -> do
34+
container <- mkContainer
35+
render (container unit) (toElement b)
36+
37+
mkContainer :: Component Unit
38+
mkContainer = do
39+
componentA <- mkComponentA
40+
componentB <- mkComponentB
41+
componentC <- mkComponentC
42+
component "Container" \_ -> React.do
43+
observedState /\ setObservedState <-
44+
useState' { a: Nothing, b: Nothing, c: Nothing }
45+
enabledState <- useState false
46+
countState <- useState 0
47+
inputState <- useInput "Hello"
48+
pure
49+
$ R.div_
50+
[ R.div
51+
{ className: "box"
52+
, children:
53+
[ R.h1_ [ R.text "Component A" ]
54+
, componentA enabledState
55+
]
56+
}
57+
, R.div
58+
{ className: "box"
59+
, children:
60+
[ R.h1_ [ R.text "Component B" ]
61+
, componentB countState
62+
]
63+
}
64+
, R.div
65+
{ className: "box"
66+
, children:
67+
[ R.h1_ [ R.text "Component C" ]
68+
, componentC inputState
69+
]
70+
}
71+
, R.p_
72+
[ R.text "Last observed states:" ]
73+
, R.ul_
74+
[ R.li_ [ R.text ("Component A: " <> show observedState.a) ]
75+
, R.li_ [ R.text ("Component B: " <> show observedState.b) ]
76+
, R.li_ [ R.text ("Component C: " <> show observedState.c) ]
77+
]
78+
, R.button
79+
{ onClick:
80+
handler_ do
81+
setObservedState
82+
{ a: Just (fst enabledState)
83+
, b: Just (fst countState)
84+
, c: Just (fst inputState)
85+
}
86+
, children: [ R.text "Check states now" ]
87+
}
88+
]
89+
90+
type SetState state
91+
= (state -> state) -> Effect Unit
92+
93+
mkComponentA :: Component (Boolean /\ SetState Boolean)
94+
mkComponentA =
95+
component "Component A" \(enabled /\ setEnabled) ->
96+
pure
97+
$ R.div_
98+
[ R.p_ [ R.text "Toggle me!" ]
99+
, R.button
100+
{ onClick: handler_ (setEnabled not)
101+
, children: [ R.text (if enabled then "On" else "Off") ]
102+
}
103+
]
104+
105+
mkComponentB :: Component (Int /\ SetState Int)
106+
mkComponentB =
107+
component "Component B" \(count /\ setCount) ->
108+
pure
109+
$ R.div_
110+
[ R.p_
111+
[ R.text "Current value: "
112+
, R.strong_ [ R.text (show count) ]
113+
]
114+
, R.button
115+
{ onClick: handler_ (setCount (_ + 1))
116+
, children: [ R.text "Increment" ]
117+
}
118+
]
119+
120+
mkComponentC :: Component (String /\ EventHandler)
121+
mkComponentC =
122+
component "Component C" \(value /\ onChange) ->
123+
pure
124+
$ R.label_
125+
[ R.p_ [ R.text "What do you have to say?" ]
126+
, R.input { value, onChange }
127+
]
128+
129+
useInput :: String -> Hook (UseState String) (String /\ EventHandler)
130+
useInput initialValue = React.do
131+
state /\ setState <- useState' initialValue
132+
let
133+
onChange = handler targetValue \t -> setState (fromMaybe "" t)
134+
pure (state /\ onChange)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>ComponentsMultiTypeReactHooks</title>
6+
</head>
7+
8+
<body>
9+
<div id="root"></div>
10+
<script src="./index.js"></script>
11+
</body>
12+
</html>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
"use strict";
2+
require("../../../output/ComponentsMultiTypeReactHooks.Main/index.js").main();

0 commit comments

Comments
 (0)