Skip to content

Commit e1deb7d

Browse files
Add AceHalogenHooks (#162)
* Add AceHalogenHooks * Add ace to packages.dhall * Rename AceHalogenHooks to AceEditorHalogenHooks * Install ace-builds as a dependency rather than storing it in recipe * Use single definition for ace's html element label * Clarify type via type annotation * Remove added ace package; upgrade set to latest package set
1 parent 0008911 commit e1deb7d

File tree

8 files changed

+155
-0
lines changed

8 files changed

+155
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ Running a web-compatible recipe:
8383

8484
| Node | Web Browser | Recipe | Description |
8585
| :-: | :-: | - | - |
86+
| | :heavy_check_mark: | [AceEditorHalogenHooks](recipes/AceEditorHalogenHooks) | A Halogen Hooks port of the ["Ace Editor" Halogen Example](https://github.com/purescript-halogen/purescript-halogen/tree/master/examples/ace). |
8687
| | :heavy_check_mark: | [AddRemoveEventListenerJs](recipes/AddRemoveEventListenerJs) | This recipe shows how to add and remove an event listener to an HTML element. |
8788
| | :heavy_check_mark: | [BasicHalogenHooks](recipes/BasicHalogenHooks) | Displays a button that toggles the label to "On" and "Off". |
8889
| :heavy_check_mark: | :heavy_check_mark: | [BigIntJs](recipes/BigIntJs) | This recipe shows how to print, create, and use values of the `BigIntJs` type in either the node.js or web browser console. |

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"spago": "^0.15.3"
77
},
88
"dependencies": {
9+
"ace-builds": "^1.4.11",
910
"big-integer": "^1.6.48",
1011
"react": "^16.13.1",
1112
"react-dom": "^16.13.1"
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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# AceEditorHalogenHooks
2+
3+
A Halogen Hooks port of the ["Ace Editor" Halogen Example](https://github.com/purescript-halogen/purescript-halogen/tree/master/examples/ace).
4+
5+
## Expected Behavior:
6+
7+
### Browser
8+
9+
The browser will wrap the Ace editor in a Halogen component.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{ name = "AceEditorHalogenHooks"
2+
, dependencies = [ "ace", "console", "effect", "halogen-hooks", "psci-support" ]
3+
, packages = ../../packages.dhall
4+
, sources = [ "recipes/AceEditorHalogenHooks/src/**/*.purs" ]
5+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
module AceEditorHalogenHooks.Main where
2+
3+
import Prelude
4+
5+
import Ace (Editor)
6+
import Ace as Ace
7+
import Ace.EditSession as Session
8+
import Ace.Editor as Editor
9+
import Data.Foldable (traverse_)
10+
import Data.Maybe (Maybe(..))
11+
import Data.Symbol (SProxy(..))
12+
import Data.Tuple.Nested ((/\))
13+
import Effect (Effect)
14+
import Effect.Aff.Class (class MonadAff)
15+
import Halogen (liftEffect)
16+
import Halogen as H
17+
import Halogen.Aff as HA
18+
import Halogen.HTML as HH
19+
import Halogen.HTML.Events as HE
20+
import Halogen.HTML.Properties as HP
21+
import Halogen.Hooks as Hooks
22+
import Halogen.Query.EventSource as ES
23+
import Halogen.VDom.Driver (runUI)
24+
25+
main :: Effect Unit
26+
main =
27+
HA.runHalogenAff do
28+
body <- HA.awaitBody
29+
void $ runUI containerComponent unit body
30+
31+
_ace = SProxy :: SProxy "ace"
32+
33+
containerComponent
34+
:: forall unusedQuery unusedInput unusedOutput anyMonad
35+
. MonadAff anyMonad
36+
=> H.Component HH.HTML unusedQuery unusedInput unusedOutput anyMonad
37+
containerComponent = Hooks.component \rec _ -> Hooks.do
38+
msg /\ msgIdx <- Hooks.useState ""
39+
Hooks.pure $
40+
HH.div_
41+
[ HH.h1_
42+
[ HH.text "ace editor" ]
43+
, HH.div_
44+
[ HH.p_
45+
[ HH.button
46+
[ HE.onClick \_ -> Just do
47+
void $ Hooks.query rec.slotToken _ace unit $ H.tell (ChangeText "")
48+
]
49+
[ HH.text "Clear" ]
50+
]
51+
]
52+
, HH.div_
53+
[ HH.slot _ace unit aceComponent unit \(TextChanged t) -> Just do
54+
Hooks.put msgIdx t
55+
]
56+
, HH.p_
57+
[ HH.text ("Current text: " <> msg) ]
58+
]
59+
60+
data ParentAction
61+
= ClearText
62+
| HandleAceUpdate AceOutput
63+
64+
data AceQuery a = ChangeText String a
65+
66+
data AceOutput = TextChanged String
67+
68+
aceElemLabel :: H.RefLabel
69+
aceElemLabel = H.RefLabel "ace"
70+
71+
aceComponent
72+
:: forall unusedInput anyMonad
73+
. MonadAff anyMonad
74+
=> H.Component HH.HTML AceQuery unusedInput AceOutput anyMonad
75+
aceComponent = Hooks.component \rec _ -> Hooks.do
76+
state /\ stateIdx <- Hooks.useState (Nothing :: Maybe Editor)
77+
Hooks.useLifecycleEffect do
78+
Hooks.getHTMLElementRef aceElemLabel >>= traverse_ \element -> do
79+
editor <- liftEffect $ Ace.editNode element Ace.ace
80+
session <- liftEffect $ Editor.getSession editor
81+
Hooks.put stateIdx $ Just editor
82+
void $ Hooks.subscribe $ ES.effectEventSource \emitter -> do
83+
Session.onChange session \_ -> ES.emit emitter do
84+
Hooks.get stateIdx >>= traverse_ \editor' -> do
85+
text <- liftEffect (Editor.getValue editor')
86+
Hooks.raise rec.outputToken $ TextChanged text
87+
pure mempty
88+
pure $ Just do
89+
Hooks.put stateIdx Nothing
90+
91+
Hooks.useQuery rec.queryToken case _ of
92+
ChangeText text next -> do
93+
maybeEditor <- Hooks.get stateIdx
94+
case maybeEditor of
95+
Nothing -> pure unit
96+
Just editor -> do
97+
current <- liftEffect $ Editor.getValue editor
98+
when (text /= current) do
99+
void $ H.liftEffect $ Editor.setValue text Nothing editor
100+
Hooks.raise rec.outputToken $ TextChanged text
101+
pure (Just next)
102+
103+
Hooks.pure $
104+
HH.div [ HP.ref aceElemLabel ] []
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>AceEditorHalogenHooks</title>
7+
<style type="text/css" media="screen">
8+
.ace_editor {
9+
height: 200px;
10+
}
11+
</style>
12+
</head>
13+
14+
<body>
15+
<script src="./index.js"></script>
16+
</body>
17+
18+
</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/AceEditorHalogenHooks.Main/index.js").main();

0 commit comments

Comments
 (0)