-
Notifications
You must be signed in to change notification settings - Fork 1
/
core.clj
71 lines (61 loc) · 2.42 KB
/
core.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
(ns ^{:doc "Supporting macros for Reacl."}
reacl.core
(:require [clojure.set :as set]
[reacl2.core])
(:refer-clojure :exclude [class]))
(defn- split-symbol [stuff]
(if (symbol? (first stuff))
[(first stuff) (rest stuff)]
[nil stuff]))
(defmacro class
[?name & ?stuff]
(let [[?component ?stuff] (split-symbol ?stuff)
[?app-state ?stuff] (split-symbol ?stuff)
[?local-state ?stuff] (split-symbol ?stuff)
?special-args (filter identity [?component ?app-state])
[?args & ?clauses] ?stuff
?clause-map (apply hash-map ?clauses)
?initial-state (get ?clause-map 'initial-state)
?clause-map (dissoc ?clause-map 'initial-state)]
`(reacl2.core/class ~?name ~@?special-args ~?args
~@(if ?local-state
`(~'local-state [~?local-state ~?initial-state])
'())
~'compat-v1? true
~@(apply concat ?clause-map))))
(defmacro defclass
[?name & ?stuff]
`(def ~?name (reacl.core/class ~(str ?name) ~@?stuff)))
(defmacro mixin
[& ?stuff]
`(reacl2.core/mixin ~@?stuff))
(defn- split-symbol-dflt [stuff dflt]
(if (symbol? (first stuff))
[(first stuff) (rest stuff)]
[dflt stuff]))
(defmacro view
[?name & ?stuff]
(let [[?component ?stuff] (split-symbol-dflt ?stuff `component#)
?app-state `app-state#
[?local-state ?stuff] (split-symbol-dflt ?stuff `local-state#)
[?args & ?clauses] ?stuff
;; this adds app-state arg to component-will-update,
;; component-did-update, should-component-update?
add-arg (fn [?current-fn]
(when ?current-fn
(let [?ignore `ignore#
?args `args#]
`(fn [~?ignore & ~?args]
(apply ~?current-fn ~?args)))))
?clause-map (-> (apply hash-map ?clauses)
(update-in ['component-will-update] add-arg)
(update-in ['component-did-update] add-arg)
(update-in ['should-component-update?] add-arg))
?clauses (apply concat ?clause-map)
]
`(reacl.core/class->view
(reacl.core/class ~?name ~?component ~?app-state ~?local-state [~@?args]
~@?clauses))))
(defmacro defview
[?name & ?stuff]
`(def ~?name (reacl.core/view ~(str ?name) ~@?stuff)))