Skip to content

Commit 8149f55

Browse files
Add ComponentsHalogenHooks (#176)
* Add ComponentsHalogenHooks * Fix typo
1 parent 64b41eb commit 8149f55

File tree

7 files changed

+119
-0
lines changed

7 files changed

+119
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ Running a web-compatible recipe:
9494
| | :heavy_check_mark: | [CardsReactHooks](recipes/CardsReactHooks) | A React port of the ["Random - Cards" Elm Example](https://elm-lang.org/examples/cards). |
9595
| | :heavy_check_mark: | [CatGifsHalogenHooks](recipes/CatGifsHalogenHooks) | A Halogen port of the ["HTTP - Cat GIFs" Elm Example](https://elm-lang.org/examples/cat-gifs). |
9696
| | :heavy_check_mark: | [CatGifsReactHooks](recipes/CatGifsReactHooks) | A React port of the ["HTTP - Cat GIFs" Elm Example](https://elm-lang.org/examples/cat-gifs). |
97+
| | :heavy_check_mark: | [ComponentsHalogenHooks](recipes/ComponentsHalogenHooks) | Demonstrates how to nest one Halogen-Hooks-based component inside another and send/receive queries between the two. |
9798
| :heavy_check_mark: | :heavy_check_mark: | [DebuggingLog](recipes/DebuggingLog) | This recipe shows how to do print-debugging using the `Debug` module's `spy` and `traceM` functions. The compiler will emit warnings to remind you to remove these debug functions before you ship production code. |
9899
| :heavy_check_mark: | | [DiceCLI](recipes/DiceCLI) | This recipe shows how to create an interactive command line prompt that repeatedly generates a random number between 1 and 6. |
99100
| :heavy_check_mark: | :heavy_check_mark: | [DiceLog](recipes/DiceLog) | This recipe shows how to log a random integer between 1 and 6 (representing a roll of a die) in either the node.js or web browser console. |
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
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+
/web-dist/
12+
/prod-dist/
13+
/prod/
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# ComponentsHalogenHooks
2+
3+
Demonstrates how to nest one Halogen-Hooks-based component inside another and send/receive queries between the two.
4+
5+
## Expected Behavior:
6+
7+
### Browser
8+
9+
Clicking the "On/Off" button in the child will toggle the button's label and update the parent component's toggle count. If the user clicks the "Check now" button in the parent, the parent will update its cache of the child's label state.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{ name = "ComponentsHalogenHooks"
2+
, dependencies =
3+
[ "console", "effect", "psci-support", "halogen-hooks" ]
4+
, packages = ../../packages.dhall
5+
, sources = [ "recipes/ComponentsHalogenHooks/src/**/*.purs" ]
6+
}
7+
{-
8+
sources does not work with paths relative to this config
9+
sources = [ "src/**/*.purs" ]
10+
Paths must be relative to where this command is run
11+
-}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
module ComponentsHalogenHooks.Main where
2+
3+
import Prelude hiding (top)
4+
5+
import Data.Maybe (Maybe(..), maybe)
6+
import Data.Symbol (SProxy(..))
7+
import Data.Tuple.Nested ((/\))
8+
import Effect (Effect)
9+
import Halogen as H
10+
import Halogen.Aff as HA
11+
import Halogen.HTML as HH
12+
import Halogen.HTML.Events as HE
13+
import Halogen.HTML.Properties as HP
14+
import Halogen.Hooks as Hooks
15+
import Halogen.VDom.Driver (runUI)
16+
17+
main :: Effect Unit
18+
main =
19+
HA.runHalogenAff do
20+
body <- HA.awaitBody
21+
void $ runUI containerComponent unit body
22+
23+
_button :: SProxy "button"
24+
_button = SProxy
25+
26+
containerComponent
27+
:: forall unusedQuery unusedInput unusedOutput anyMonad
28+
. H.Component HH.HTML unusedQuery unusedInput unusedOutput anyMonad
29+
containerComponent = Hooks.component \rec _ -> Hooks.do
30+
toggleCount /\ toggleCountIdx <- Hooks.useState 0
31+
buttonState /\ buttonStateIdx <- Hooks.useState (Nothing :: Maybe Boolean)
32+
Hooks.pure $
33+
HH.div_
34+
[ HH.slot _button unit buttonComponent unit \_ -> Just do
35+
Hooks.modify_ toggleCountIdx (_ + 1)
36+
, HH.p_
37+
[ HH.text ("Button has been toggled " <> show toggleCount <> " time(s)") ]
38+
, HH.p_
39+
[ HH.text
40+
$ "Last time I checked, the button was: "
41+
<> (maybe "(not checked yet)" (if _ then "on" else "off") buttonState)
42+
<> ". "
43+
, HH.button
44+
[ HE.onClick \_ -> Just do
45+
mbBtnState <- Hooks.query rec.slotToken _button unit $ H.request IsOn
46+
Hooks.put buttonStateIdx mbBtnState
47+
]
48+
[ HH.text "Check now" ]
49+
]
50+
]
51+
52+
data ButtonMessage = Toggled Boolean
53+
data ButtonQuery a = IsOn (Boolean -> a)
54+
55+
buttonComponent
56+
:: forall unusedInput anyMonad
57+
. H.Component HH.HTML ButtonQuery unusedInput ButtonMessage anyMonad
58+
buttonComponent = Hooks.component \rec _ -> Hooks.do
59+
enabled /\ enabledIdx <- Hooks.useState false
60+
Hooks.useQuery rec.queryToken case _ of
61+
IsOn reply -> do
62+
isEnabled <- Hooks.get enabledIdx
63+
pure $ Just $ reply isEnabled
64+
let label = if enabled then "On" else "Off"
65+
Hooks.pure $
66+
HH.button
67+
[ HP.title label
68+
, HE.onClick \_ -> Just do
69+
newState <- Hooks.modify enabledIdx not
70+
Hooks.raise rec.outputToken $ Toggled newState
71+
]
72+
[ HH.text label ]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>ComponentsHalogenHooks</title>
6+
</head>
7+
8+
<body>
9+
<script src="./index.js"></script>
10+
</body>
11+
</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/ComponentsHalogenHooks.Main/index.js").main();

0 commit comments

Comments
 (0)