Skip to content

Commit d01b2c6

Browse files
authored
Add FormsReactHooks (#164)
1 parent 7658e9b commit d01b2c6

File tree

7 files changed

+127
-0
lines changed

7 files changed

+127
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ Running a web-compatible recipe:
9999
| | :heavy_check_mark: | [DragAndDropHalogenHooks](recipes/DragAndDropHalogenHooks) | A Halogen port of the ["Files - Drag-and-Drop" Elm Example](https://elm-lang.org/examples/drag-and-drop). |
100100
| | :heavy_check_mark: | [FileUploadHalogenHooks](recipes/FileUploadHalogenHooks) | A Halogen port of the ["Files - Upload" Elm Example](https://elm-lang.org/examples/upload). |
101101
| | :heavy_check_mark: | [FindDomElementJs](recipes/FindDomElementJs) | This recipe shows how to find elements in the DOM by using query selectors. |
102+
| | :heavy_check_mark: | [FormsReactHooks](recipes/FormsReactHooks) | A React port of the ["User Interface - Forms" Elm Example](https://elm-lang.org/examples/forms). |
102103
| | :heavy_check_mark: | [GroceriesHalogenHooks](recipes/GroceriesHalogenHooks) | A Halogen port of the ["HTML - Groceries" Elm Example](https://elm-lang.org/examples). |
103104
| | :heavy_check_mark: | [GroceriesReactHooks](recipes/GroceriesReactHooks) | A React port of the ["HTML - Groceries" Elm Example](https://elm-lang.org/examples). |
104105
| | :heavy_check_mark: | [HelloHalogenHooks](recipes/HelloHalogenHooks) | A Halogen port of the ["HTML - Hello" Elm Example](https://elm-lang.org/examples). |

recipes/FormsReactHooks/.gitignore

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/

recipes/FormsReactHooks/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# FormsReactHooks
2+
3+
A React port of the ["User Interface - Forms" Elm Example](https://elm-lang.org/examples/forms).
4+
5+
## Expected Behavior:
6+
7+
### Browser
8+
9+
The browser will display a form with three text fields, for name, password and password confirmation. A validation status will show below the form, to indicate "OK" if the passwords match, or "Passwords don't match!" otherwise.
10+
11+
## Dependencies Used:
12+
13+
[react](https://www.npmjs.com/package/react)
14+
[react-dom](https://www.npmjs.com/package/react-dom)

recipes/FormsReactHooks/spago.dhall

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{ name = "FormsReactHooks"
2+
, dependencies =
3+
[ "console"
4+
, "effect"
5+
, "psci-support"
6+
, "react-basic-hooks"
7+
]
8+
, packages = ../../packages.dhall
9+
, sources = [ "recipes/FormsReactHooks/src/**/*.purs" ]
10+
}

recipes/FormsReactHooks/src/Main.purs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
module FormsReactHooks.Main where
2+
3+
import Prelude
4+
import Data.Maybe (Maybe(..), fromMaybe)
5+
import Effect (Effect)
6+
import Effect.Exception (throw)
7+
import React.Basic.DOM (css, render)
8+
import React.Basic.DOM as R
9+
import React.Basic.DOM.Events (preventDefault, targetValue)
10+
import React.Basic.Events (EventHandler, handler)
11+
import React.Basic.Hooks (Component, component, useState, (/\), Hook, UseState, type (/\))
12+
import React.Basic.Hooks as React
13+
import Web.DOM.NonElementParentNode (getElementById)
14+
import Web.HTML (window)
15+
import Web.HTML.HTMLDocument (toNonElementParentNode)
16+
import Web.HTML.Window (document)
17+
18+
main :: Effect Unit
19+
main = do
20+
container <- getElementById "root" =<< map toNonElementParentNode (document =<< window)
21+
case container of
22+
Nothing -> throw "Root element not found."
23+
Just c -> do
24+
form <- mkForm
25+
render (form {}) c
26+
27+
mkForm :: Component {}
28+
mkForm = do
29+
component "Form" \_ -> React.do
30+
name /\ onNameChange <- useInput ""
31+
password /\ onPasswordChange <- useInput ""
32+
passwordAgain /\ onPasswordAgainChange <- useInput ""
33+
let
34+
renderValidation =
35+
if password == passwordAgain then
36+
R.div { style: css { color: "green" }, children: [ R.text "OK" ] }
37+
else
38+
R.div { style: css { color: "red" }, children: [ R.text "Passwords do not match!" ] }
39+
pure
40+
$ R.form
41+
{ onSubmit: handler preventDefault mempty
42+
, children:
43+
[ R.input
44+
{ placeholder: "Name"
45+
, value: name
46+
, onChange: onNameChange
47+
}
48+
, R.input
49+
{ type: "password"
50+
, placeholder: "Password"
51+
, value: password
52+
, onChange: onPasswordChange
53+
}
54+
, R.input
55+
{ type: "password"
56+
, placeholder: "Re-enter Password"
57+
, value: passwordAgain
58+
, onChange: onPasswordAgainChange
59+
}
60+
, renderValidation
61+
]
62+
}
63+
64+
useInput ::
65+
String ->
66+
Hook
67+
(UseState String)
68+
(String /\ EventHandler)
69+
useInput initialValue = React.do
70+
value /\ setValue <- useState initialValue
71+
let
72+
onChange = handler targetValue (setValue <<< const <<< fromMaybe "")
73+
pure (value /\ 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>FormsReactHooks</title>
6+
</head>
7+
8+
<body>
9+
<div id="root"></div>
10+
<script src="./index.js"></script>
11+
</body>
12+
</html>

recipes/FormsReactHooks/web/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
"use strict";
2+
require("../../../output/FormsReactHooks.Main/index.js").main();

0 commit comments

Comments
 (0)