-
Notifications
You must be signed in to change notification settings - Fork 1
/
dom.clj
74 lines (64 loc) · 2.78 KB
/
dom.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
(ns ^{:doc "Supporting macros for Reacl's DOM library ."}
reacl.dom)
(defmacro ^:no-doc defdom
"Internal macro for constructing DOM-construction wrappers."
[n]
`(def ~n (dom-function ~(symbol (str "js/React.DOM." (name n))))))
(defmacro letdom
"Bind DOM nodes to names for use in event handlers.
This should be used together with [[reacl.core/class]] or [[reacl.core/defclass]].
Its syntax is like `let`, but all right-hand sides must evaluate to
virtual DOM nodes - typically input elements.
The objects can be used with the [[dom-node]] function,
which returns the corresponding real DOM node.
Example:
(reacl.core/defclass search-bar
app-state [filter-text in-stock-only on-user-input]
render
(fn [& {:keys [dom-node]}]
(dom/letdom
[textbox (dom/input
{:type \"text\"
:placeholder \"Search...\"
:value filter-text
:onChange (fn [e]
(on-user-input
(.-value (dom-node textbox))
(.-checked (dom-node checkbox))))})
checkbox (dom/input
{:type \"checkbox\"
:value in-stock-only
:onChange (fn [e]
(on-user-input
(.-value (dom-node textbox))
(.-checked (dom-node checkbox))))})]
(dom/form
textbox
(dom/p
checkbox
\"Only show products in stock\")))))
Note that the resulting DOM-node objects need to be used together
with the other DOM wrappers in `reacl.dom`."
[clauses body0 & bodies]
;; FIXME: error check
(let [pairs (partition 2 clauses)]
`(let [~@(mapcat (fn [p]
(let [lhs (first p)]
(cond
(symbol? lhs)
`[~lhs (reacl.dom/make-dom-binding '~lhs false)]
(and (list? lhs)
(= (count lhs) 2)
(= :literally (first lhs))
(symbol? (second lhs)))
`[~(second lhs) (reacl.dom/make-dom-binding '~(second lhs) true)]
:else
(throw (Exception. (str "Not a valid letdom lhs " lhs))))))
pairs)]
~@(map (fn [p]
(let [lhs (first p)
rhs (second p)]
`(reacl.dom/set-dom-binding! ~(first p)
~(second p))))
pairs)
~body0 ~@bodies)))