├── Procfile
├── .gitignore
├── README.md
├── src
├── clj
│ └── cljs_react_material_ui_example
│ │ ├── util.clj
│ │ ├── website.clj
│ │ ├── core.clj
│ │ └── system.clj
└── cljs
│ └── cljs_react_material_ui_example
│ ├── util.cljs
│ ├── parser.cljs
│ ├── state.cljs
│ └── core.cljs
├── env
├── prod
│ └── clj
│ │ └── cljs_react_material_ui_example
│ │ └── prod_server.clj
└── dev
│ └── clj
│ └── cljs_react_material_ui_example
│ ├── dev_server.clj
│ └── figwheel.clj
├── resources
└── public
│ ├── html
│ └── index.html
│ └── css
│ └── style.css
├── project.clj
├── LICENSE
└── cljs-react-material-ui-example.iml
/Procfile:
--------------------------------------------------------------------------------
1 | web: java $JVM_OPTS -cp target/cljs-react-material-ui-example.jar clojure.main -m cljs-react-material-ui-example.prod-server
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /classes
3 | /checkouts
4 | pom.xml
5 | pom.xml.asc
6 | *.jar
7 | *.class
8 | /.lein-*
9 | /cljs-react-material-ui-example.iml
10 | /.nrepl-port
11 | .hgignore
12 | .hg/
13 | /resources/public/js
14 | .idea
15 | /figwheel_server.log
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Material-UI Om.Next example app
2 |
3 | http://cljs-react-material-ui-example.herokuapp.com/
4 |
5 | This is example app, which uses my library [cljs-react-material-ui](https://github.com/madvas/cljs-react-material-ui) to get [Material-UI](http://www.material-ui.com/) working in Clojurescript.
6 |
7 | `lein run`
8 |
9 | Head on to http://localhost:8081/ to see the running application.
10 |
11 |
--------------------------------------------------------------------------------
/src/clj/cljs_react_material_ui_example/util.clj:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.util
2 | (:require [clojure.pprint :refer [pprint]]))
3 |
4 | (defn p [& args]
5 | "Like print, but returns last arg. For debugging purposes"
6 | (doseq [a args]
7 | (let [f (if (map? a) pprint print)]
8 | (f a)))
9 | (println)
10 | (flush)
11 | (last args))
12 |
13 | (defn str->int [s]
14 | (if (number? s)
15 | s
16 | (Integer/parseInt (re-find #"\A-?\d+" s))))
--------------------------------------------------------------------------------
/env/prod/clj/cljs_react_material_ui_example/prod_server.clj:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.prod-server
2 | (:require [cljs-react-material-ui-example.core :as app])
3 | (:gen-class))
4 |
5 | (def config
6 | {:web-port (or (System/getenv "PORT") 8082)})
7 |
8 | (defn -main [& args]
9 | (println "Starting on port " (:web-port config))
10 | (app/dev-start config)
11 | (println (str "Started server on port " (:web-port config)))
12 | (.addShutdownHook (Runtime/getRuntime)
13 | (Thread. #(do (app/stop)
14 | (println "Server stopped")))))
--------------------------------------------------------------------------------
/env/dev/clj/cljs_react_material_ui_example/dev_server.clj:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.dev-server
2 | (:require [cljs-react-material-ui-example.core :as cljs-react-material-ui-example]
3 | [cljs-react-material-ui-example.figwheel :as f]))
4 |
5 |
6 | (def config
7 | {:web-port 8999})
8 |
9 | (cljs-react-material-ui-example/dev-start config)
10 | (println (str "Started server on port " (:web-port config)))
11 | (.addShutdownHook (Runtime/getRuntime)
12 | (Thread. #(do (cljs-react-material-ui-example/stop)
13 | (println "Server stopped"))))
14 | (f/start-fig!)
--------------------------------------------------------------------------------
/src/clj/cljs_react_material_ui_example/website.clj:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.website
2 | (:require [com.stuartsierra.component :as c]
3 | [bidi.bidi :as b]
4 | [clojure.java.io :as io]
5 | [yada.yada :refer [yada]]
6 | [yada.resources.classpath-resource :as yr]))
7 |
8 | (defrecord Website []
9 | c/Lifecycle
10 | (start [component]
11 | component)
12 | (stop [component]
13 | component)
14 |
15 | b/RouteProvider
16 | (routes [component]
17 | ["/" [["" (yada (io/resource "public/html/index.html"))]
18 | ["" (yada (yr/new-classpath-resource "public/"))]]]))
19 |
20 | (defn new-website []
21 | (-> (map->Website {})))
--------------------------------------------------------------------------------
/src/clj/cljs_react_material_ui_example/core.clj:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.core
2 | (:require [com.stuartsierra.component :as component]
3 | [cljs-react-material-ui-example.system :as system]))
4 |
5 | (def servlet-system (atom nil))
6 |
7 | ;; =============================================================================
8 | ;; Development
9 |
10 | (defn dev-start [config]
11 | (let [sys (system/dev-system config)
12 | sys' (component/start sys)]
13 | (reset! servlet-system sys')
14 | (println "System started")
15 | sys'))
16 |
17 | (defn stop []
18 | (swap! servlet-system component/stop)
19 | (println "System stopped"))
20 |
21 | (defn dev-restart [config]
22 | (stop)
23 | (dev-start config))
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/resources/public/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Material UI Om.Next Example App
7 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/env/dev/clj/cljs_react_material_ui_example/figwheel.clj:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.figwheel
2 | (:require [figwheel-sidecar.repl-api :as ra]
3 | [cljs.build.api :as b]))
4 |
5 |
6 | (def opts
7 | {:main 'cljs-react-material-ui-example.core
8 | :asset-path "/js"
9 | :output-to "resources/public/js/app.js"
10 | :output-dir "resources/public/js"
11 | :parallel-build true
12 | :compiler-stats true
13 | :verbose true})
14 |
15 | (comment
16 | (b/build "src/cljs" opts))
17 |
18 | (defn build []
19 | (b/build "src/cljs" opts))
20 |
21 |
22 | (defn start-fig! []
23 | (ra/start-figwheel!
24 | {:figwheel-options {:server-port 5309}
25 | :build-ids ["dev"]
26 | :all-builds [{:id "dev"
27 | :figwheel true
28 | :source-paths ["src/cljs"]
29 | :compiler opts}]}))
30 |
31 | (ra/cljs-repl)
32 |
--------------------------------------------------------------------------------
/src/cljs/cljs_react_material_ui_example/util.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.util
2 | (:require [cognitect.transit :as t]
3 | [cljs.pprint :refer [pprint]]
4 | [goog.events.KeyCodes :as kc]))
5 |
6 |
7 | (defn p [& args]
8 | "Like print, but returns last arg. For debugging purposes"
9 | (doseq [a args]
10 | (let [f (if (map? a) pprint print)]
11 | (f a)))
12 | (println)
13 | (flush)
14 | (last args))
15 |
16 | (defn pcoll [items]
17 | (doall (map p items)))
18 |
19 | (defn prevent-default [e]
20 | (doto e (.preventDefault) (.stopPropagation)))
21 |
22 | (defn target-val [e]
23 | (.. e -target -value))
24 |
25 | (defn on-key-down [key-fns]
26 | (fn [e]
27 | (let [f (condp == (aget e "keyCode")
28 | kc/ESC (:key/esc key-fns)
29 | kc/ENTER (:key/enter key-fns)
30 | #(do %))]
31 | (f e))))
32 |
33 | (defn event-data [e]
34 | (aget (.-event_ e) "data"))
35 |
36 | (defn apply-if [pred f x & args]
37 | (if-not (pred x)
38 | (apply f x args)
39 | x))
40 |
41 | (defn find-by-key [k v coll]
42 | (first (filter #(= v (get % k)) coll)))
--------------------------------------------------------------------------------
/src/cljs/cljs_react_material_ui_example/parser.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.parser
2 | (:require [om.next :as om]
3 | [cljs-react-material-ui-example.state :refer [init-state]]))
4 |
5 | ;; =============================================================================
6 | ;; Reads
7 |
8 | (defmulti read om/dispatch)
9 |
10 | (defmethod read :default
11 | [{:keys [state query]} k _]
12 | #_(println "Default read " k query)
13 | (let [st @state]
14 | {:remote false
15 | :value (om/db->tree query (k st) st)}))
16 |
17 | (defmethod read :person/new
18 | [{:keys [state]} k _]
19 | {:value (k @state)})
20 |
21 | (defmulti mutate om/dispatch)
22 |
23 | (defmethod mutate :default
24 | [_ k _]
25 | (println "Default mutate " k)
26 | {:remote false})
27 |
28 | (defmethod mutate 'person-new/change
29 | [{:keys [state]} _ {:keys [value path]}]
30 | {:action (fn []
31 | (swap! state assoc-in (cons :person/new path) value))})
32 |
33 |
34 | (defmethod mutate 'person-new/add
35 | [{:keys [state]} _]
36 | {:action (fn []
37 | (let [id (rand-int 9999)
38 | person-new (-> (:person/new @state)
39 | (assoc :db/id id))]
40 | (swap! state assoc-in [:person/by-id id] person-new)
41 | (swap! state update :person/list conj [:person/by-id id])
42 | (swap! state assoc :person/new (:person/new init-state))))})
43 |
--------------------------------------------------------------------------------
/src/clj/cljs_react_material_ui_example/system.clj:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.system
2 | (:require [com.stuartsierra.component :as c]
3 | cljs-react-material-ui-example.website
4 | [modular.maker :as mm]
5 | [modular.bidi :refer [new-router new-web-resources]]
6 | [modular.aleph :refer [new-webserver]]
7 | [cljs-react-material-ui-example.util :as u]))
8 |
9 | (defn http-listener-components [system config]
10 | (assoc system :http-listener (new-webserver :port (u/str->int (:web-port config)))))
11 |
12 | (defn modular-bidi-router-components [system config]
13 | (assoc system :bidi-request-handler (mm/make new-router config)))
14 |
15 | (defn website-components [system config]
16 | (assoc system :website
17 | (-> (mm/make cljs-react-material-ui-example.website/new-website config)
18 | (c/using []))))
19 |
20 | (defn new-dependency-map []
21 | {:http-listener {:request-handler :bidi-request-handler}
22 | :bidi-request-handler {:website :website}})
23 |
24 | (defn new-system-map
25 | [config]
26 | (apply c/system-map
27 | (apply concat
28 | (-> {}
29 | (http-listener-components config)
30 | (modular-bidi-router-components config)
31 | (website-components config)))))
32 |
33 | (defn dev-system
34 | ([] (dev-system {}))
35 | ([config]
36 | (-> (new-system-map config)
37 | (c/system-using (new-dependency-map)))))
38 |
--------------------------------------------------------------------------------
/src/cljs/cljs_react_material_ui_example/state.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.state)
2 |
3 | (defonce init-state
4 | {:person/list [[:person/by-id 1]
5 | [:person/by-id 2]]
6 | :person/by-id {1 {:db/id 1
7 | :person/name "John"
8 | :person/date #inst "2016-04-08T22:00:00.000-00:00"
9 | :person/status [:status/by-id 1]
10 | :person/happiness [:happiness/by-id 3]}
11 | 2 {:db/id 2
12 | :person/name "Susan"
13 | :person/date #inst "2016-04-08T22:00:00.000-00:00"
14 | :person/status [:status/by-id 4]
15 | :person/happiness [:happiness/by-id 2]}}
16 | :person/new {:person/name ""
17 | :person/date nil
18 | :person/status nil
19 | :person/happiness [:happiness/by-id 2]}
20 | :status/list [[:status/by-id 1] [:status/by-id 2] [:status/by-id 3] [:status/by-id 4]
21 | [:status/by-id 5]]
22 | :status/by-id {1 {:db/id 1 :status/name "Employed"}
23 | 2 {:db/id 2 :status/name "Unemployed"}
24 | 3 {:db/id 3 :status/name "Freelancer"}
25 | 4 {:db/id 4 :status/name "Entrepreneur"}
26 | 5 {:db/id 5 :status/name "Parental leave"}}
27 | :happiness/list [[:happiness/by-id 1] [:happiness/by-id 2] [:happiness/by-id 3]]
28 | :happiness/by-id {1 {:db/id 1 :happiness/name "Sad"}
29 | 2 {:db/id 2 :happiness/name "Normal"}
30 | 3 {:db/id 3 :happiness/name "Superb"}}})
--------------------------------------------------------------------------------
/project.clj:
--------------------------------------------------------------------------------
1 | (defproject cljs-react-material-ui-example "0.1.0-SNAPSHOT"
2 | :description "Example app for library cljs-react-material-ui"
3 | :url "http://example.com/FIXME"
4 | :license {:name "Eclipse Public License"
5 | :url "http://www.eclipse.org/legal/epl-v10.html"}
6 | :dependencies [[org.clojure/clojure "1.8.0"]
7 | [org.clojure/clojurescript "1.9.908"]
8 | [org.omcljs/om "1.0.0-alpha37"]
9 | [com.stuartsierra/component "0.3.1"]
10 | [com.cemerick/piggieback "0.2.1"]
11 | [cljsjs/react "15.6.1-1"]
12 | [cljsjs/react-dom "15.6.1-1"]
13 | [figwheel-sidecar "0.5.0-2" :scope "test"]
14 | [com.cemerick/piggieback "0.2.1"]
15 | [org.clojure/tools.nrepl "0.2.10"]
16 | [aleph "0.4.1-beta5"]
17 | [bidi "2.0.4"]
18 | [yada "1.1.5"]
19 | [juxt.modular/bidi "0.9.5"]
20 | [juxt.modular/maker "0.5.0"]
21 | [juxt.modular/wire-up "0.5.0"]
22 | [juxt.modular/aleph "0.1.4"]
23 | [com.andrewmcveigh/cljs-time "0.4.0"]
24 | [cljs-react-material-ui "0.2.50"]
25 | [cljsjs/material-ui-chip-input "0.17.2-0"]
26 | [prismatic/schema "1.1.1"]
27 | [print-foo-cljs "2.0.0"]]
28 |
29 | :plugins [[lein-cljsbuild "1.1.3"]]
30 | :min-lein-version "2.0.0"
31 | :uberjar-name "cljs-react-material-ui-example.jar"
32 | :clean-targets ^{:protect false} ["resources/public/js"]
33 | :source-paths ["src/clj" "src/cljs"]
34 |
35 | :cljsbuild {:builds {:app {:source-paths ["src/cljs"]
36 | :figwheel true
37 | :compiler {:main cljs-react-material-ui-example.core
38 | :output-to "resources/public/js/app.js"
39 | :output-dir "resources/public/js"
40 | :asset-path "/js"
41 | :optimizations :none
42 | :pretty-print true
43 | :externs ["src/js/externs.js"]
44 | :closure-defines {goog.DEBUG false}
45 | :parallel-build true
46 | :verbose true}}}}
47 |
48 | :profiles {:dev {:source-paths ["env/dev/clj"]
49 | :main cljs-react-material-ui-example.dev-server
50 | :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
51 | :plugins [[lein-figwheel "0.5.1"]]}
52 | :uberjar {:source-paths ["env/prod/clj"]
53 | :main cljs-react-material-ui-example.prod-server
54 | :hooks [leiningen.cljsbuild]
55 | :aot :all
56 | :omit-source true
57 | :cljsbuild {:builds {:app
58 | {:compiler {:optimizations :advanced
59 | :closure-defines {:goog.DEBUG false}
60 | :pretty-print false}}}}}})
--------------------------------------------------------------------------------
/resources/public/css/style.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v2.0 | 20110126
3 | License: none (public domain)
4 | */
5 | html,
6 | body,
7 | div,
8 | span,
9 | applet,
10 | object,
11 | iframe,
12 | h1,
13 | h2,
14 | h3,
15 | h4,
16 | h5,
17 | h6,
18 | p,
19 | blockquote,
20 | pre,
21 | a,
22 | abbr,
23 | acronym,
24 | address,
25 | big,
26 | cite,
27 | code,
28 | del,
29 | dfn,
30 | em,
31 | img,
32 | ins,
33 | kbd,
34 | q,
35 | s,
36 | samp,
37 | small,
38 | strike,
39 | strong,
40 | sub,
41 | sup,
42 | tt,
43 | var,
44 | b,
45 | u,
46 | i,
47 | center,
48 | dl,
49 | dt,
50 | dd,
51 | ol,
52 | ul,
53 | li,
54 | fieldset,
55 | form,
56 | label,
57 | legend,
58 | table,
59 | caption,
60 | tbody,
61 | tfoot,
62 | thead,
63 | tr,
64 | th,
65 | td,
66 | article,
67 | aside,
68 | canvas,
69 | details,
70 | embed,
71 | figure,
72 | figcaption,
73 | footer,
74 | header,
75 | hgroup,
76 | menu,
77 | nav,
78 | output,
79 | ruby,
80 | section,
81 | summary,
82 | time,
83 | mark,
84 | audio,
85 | video {
86 | margin: 0;
87 | padding: 0;
88 | border: 0;
89 | font-size: 100%;
90 | font: inherit;
91 | }
92 | /* HTML5 display-role reset for older browsers */
93 | article,
94 | aside,
95 | details,
96 | figcaption,
97 | figure,
98 | footer,
99 | header,
100 | hgroup,
101 | menu,
102 | nav,
103 | section {
104 | display: block;
105 | }
106 | ol,
107 | ul {
108 | list-style: none;
109 | }
110 | blockquote,
111 | q {
112 | quotes: none;
113 | }
114 | blockquote:before,
115 | blockquote:after,
116 | q:before,
117 | q:after {
118 | content: '';
119 | content: none;
120 | }
121 | table {
122 | border-collapse: collapse;
123 | border-spacing: 0;
124 | }
125 | button::-moz-focus-inner,
126 | input::-moz-focus-inner {
127 | border: 0;
128 | padding: 0;
129 | }
130 |
131 | .pad-top-20 {
132 | padding-top: 20px;
133 | }
134 | .pad-lef-20 {
135 | padding-left: 20px;
136 | }
137 | .pad-rig-20 {
138 | padding-right: 20px;
139 | }
140 | .pad-bot-20 {
141 | padding-bottom: 20px;
142 | }
143 | .pad-top-15 {
144 | padding-top: 15px;
145 | }
146 | .pad-lef-15 {
147 | padding-left: 15px;
148 | }
149 | .pad-rig-15 {
150 | padding-right: 15px;
151 | }
152 | .pad-bot-15 {
153 | padding-bottom: 15px;
154 | }
155 | .pad-top-10 {
156 | padding-top: 10px;
157 | }
158 | .pad-lef-10 {
159 | padding-left: 10px;
160 | }
161 | .pad-rig-10 {
162 | padding-right: 10px;
163 | }
164 | .pad-bot-10 {
165 | padding-bottom: 10px;
166 | }
167 | .pad-top-5 {
168 | padding-top: 5px;
169 | }
170 | .pad-lef-5 {
171 | padding-left: 5px;
172 | }
173 | .pad-rig-5 {
174 | padding-right: 5px;
175 | }
176 | .pad-bot-5 {
177 | padding-bottom: 5px;
178 | }
179 | .pad-top-0 {
180 | padding-top: 0;
181 | }
182 | .pad-lef-0 {
183 | padding-left: 0;
184 | }
185 | .pad-rig-0 {
186 | padding-right: 0;
187 | }
188 | .pad-bot-0 {
189 | padding-bottom: 0;
190 | }
191 | .pad-ver-0 {
192 | padding-top: 0;
193 | padding-bottom: 0;
194 | }
195 | .pad-ver-5 {
196 | padding-top: 5px;
197 | padding-bottom: 5px;
198 | }
199 | .pad-ver-10 {
200 | padding-top: 10px;
201 | padding-bottom: 10px;
202 | }
203 | .pad-ver-15 {
204 | padding-top: 15px;
205 | padding-bottom: 15px;
206 | }
207 | .pad-ver-20 {
208 | padding-top: 20px;
209 | padding-bottom: 20px;
210 | }
211 | .pad-hor-0 {
212 | padding-left: 0;
213 | padding-right: 0;
214 | }
215 | .pad-hor-5 {
216 | padding-left: 5px;
217 | padding-right: 5px;
218 | }
219 | .pad-hor-10 {
220 | padding-left: 10px;
221 | padding-right: 10px;
222 | }
223 | .pad-hor-15 {
224 | padding-left: 15px;
225 | padding-right: 15px;
226 | }
227 | .pad-hor-20 {
228 | padding-left: 20px;
229 | padding-right: 20px;
230 | }
231 | .pad-0 {
232 | padding: 0px !important;
233 | }
234 | .pad-5 {
235 | padding: 5px;
236 | }
237 | .pad-10 {
238 | padding: 10px;
239 | }
240 | .pad-15 {
241 | padding: 15px;
242 | }
243 | .pad-20 {
244 | padding: 20px;
245 | }
246 | .pad-top-30 {
247 | padding-top: 30px;
248 | }
249 | .pad-top-40 {
250 | padding-top: 40px;
251 | }
252 | .mar-top-30 {
253 | margin-top: 30px;
254 | }
255 | .mar-top-40 {
256 | margin-top: 40px;
257 | }
258 | .mar-top-20 {
259 | margin-top: 20px;
260 | }
261 | .mar-lef-20 {
262 | margin-left: 20px;
263 | }
264 | .mar-rig-20 {
265 | margin-right: 20px;
266 | }
267 | .mar-bot-20 {
268 | margin-bottom: 20px;
269 | }
270 | .mar-top-15 {
271 | margin-top: 15px;
272 | }
273 | .mar-lef-15 {
274 | margin-left: 15px;
275 | }
276 | .mar-rig-15 {
277 | margin-right: 15px;
278 | }
279 | .mar-bot-15 {
280 | margin-bottom: 15px;
281 | }
282 | .mar-top-10 {
283 | margin-top: 10px;
284 | }
285 | .mar-lef-10 {
286 | margin-left: 10px;
287 | }
288 | .mar-rig-10 {
289 | margin-right: 10px;
290 | }
291 | .mar-bot-10 {
292 | margin-bottom: 10px;
293 | }
294 | .mar-top-5 {
295 | margin-top: 5px;
296 | }
297 | .mar-lef-5 {
298 | margin-left: 5px;
299 | }
300 | .mar-rig-5 {
301 | margin-right: 5px;
302 | }
303 | .mar-bot-5 {
304 | margin-bottom: 5px;
305 | }
306 | .mar-top-0 {
307 | margin-top: 0;
308 | }
309 | .mar-lef-0 {
310 | margin-left: 0;
311 | }
312 | .mar-rig-0 {
313 | margin-right: 0;
314 | }
315 | .mar-bot-0 {
316 | margin-bottom: 0;
317 | }
318 | .mar-ver-0 {
319 | margin-top: 0;
320 | margin-bottom: 0;
321 | }
322 | .mar-ver-5 {
323 | margin-top: 5px;
324 | margin-bottom: 5px;
325 | }
326 | .mar-ver-10 {
327 | margin-top: 10px;
328 | margin-bottom: 10px;
329 | }
330 | .mar-ver-15 {
331 | margin-top: 15px;
332 | margin-bottom: 15px;
333 | }
334 | .mar-ver-20 {
335 | margin-top: 20px;
336 | margin-bottom: 20px;
337 | }
338 | .mar-hor-0 {
339 | margin-left: 0;
340 | margin-right: 0;
341 | }
342 | .mar-hor-5 {
343 | margin-left: 5px;
344 | margin-right: 5px;
345 | }
346 | .mar-hor-10 {
347 | margin-left: 10px;
348 | margin-right: 10px;
349 | }
350 | .mar-hor-15 {
351 | margin-left: 15px;
352 | margin-right: 15px;
353 | }
354 | .mar-hor-20 {
355 | margin-left: 20px;
356 | margin-right: 20px;
357 | }
358 | .mar-0 {
359 | margin: 0px !important;
360 | }
361 | .mar-5 {
362 | margin: 5px;
363 | }
364 | .mar-10 {
365 | margin: 10px;
366 | }
367 | .mar-15 {
368 | margin: 15px;
369 | }
370 | .mar-20 {
371 | margin: 20px;
372 | }
373 |
374 | .w-100 {
375 | width: 100% !important;
376 | }
377 |
378 | .h-100 {
379 | height: 100%;
380 | }
381 |
382 | #app {
383 | background-color: #f5f5f5;
384 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
4 |
5 | 1. DEFINITIONS
6 |
7 | "Contribution" means:
8 |
9 | a) in the case of the initial Contributor, the initial code and
10 | documentation distributed under this Agreement, and
11 |
12 | b) in the case of each subsequent Contributor:
13 |
14 | i) changes to the Program, and
15 |
16 | ii) additions to the Program;
17 |
18 | where such changes and/or additions to the Program originate from and are
19 | distributed by that particular Contributor. A Contribution 'originates' from
20 | a Contributor if it was added to the Program by such Contributor itself or
21 | anyone acting on such Contributor's behalf. Contributions do not include
22 | additions to the Program which: (i) are separate modules of software
23 | distributed in conjunction with the Program under their own license
24 | agreement, and (ii) are not derivative works of the Program.
25 |
26 | "Contributor" means any person or entity that distributes the Program.
27 |
28 | "Licensed Patents" mean patent claims licensable by a Contributor which are
29 | necessarily infringed by the use or sale of its Contribution alone or when
30 | combined with the Program.
31 |
32 | "Program" means the Contributions distributed in accordance with this
33 | Agreement.
34 |
35 | "Recipient" means anyone who receives the Program under this Agreement,
36 | including all Contributors.
37 |
38 | 2. GRANT OF RIGHTS
39 |
40 | a) Subject to the terms of this Agreement, each Contributor hereby grants
41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to
42 | reproduce, prepare derivative works of, publicly display, publicly perform,
43 | distribute and sublicense the Contribution of such Contributor, if any, and
44 | such derivative works, in source code and object code form.
45 |
46 | b) Subject to the terms of this Agreement, each Contributor hereby grants
47 | Recipient a non-exclusive, worldwide, royalty-free patent license under
48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise
49 | transfer the Contribution of such Contributor, if any, in source code and
50 | object code form. This patent license shall apply to the combination of the
51 | Contribution and the Program if, at the time the Contribution is added by the
52 | Contributor, such addition of the Contribution causes such combination to be
53 | covered by the Licensed Patents. The patent license shall not apply to any
54 | other combinations which include the Contribution. No hardware per se is
55 | licensed hereunder.
56 |
57 | c) Recipient understands that although each Contributor grants the licenses
58 | to its Contributions set forth herein, no assurances are provided by any
59 | Contributor that the Program does not infringe the patent or other
60 | intellectual property rights of any other entity. Each Contributor disclaims
61 | any liability to Recipient for claims brought by any other entity based on
62 | infringement of intellectual property rights or otherwise. As a condition to
63 | exercising the rights and licenses granted hereunder, each Recipient hereby
64 | assumes sole responsibility to secure any other intellectual property rights
65 | needed, if any. For example, if a third party patent license is required to
66 | allow Recipient to distribute the Program, it is Recipient's responsibility
67 | to acquire that license before distributing the Program.
68 |
69 | d) Each Contributor represents that to its knowledge it has sufficient
70 | copyright rights in its Contribution, if any, to grant the copyright license
71 | set forth in this Agreement.
72 |
73 | 3. REQUIREMENTS
74 |
75 | A Contributor may choose to distribute the Program in object code form under
76 | its own license agreement, provided that:
77 |
78 | a) it complies with the terms and conditions of this Agreement; and
79 |
80 | b) its license agreement:
81 |
82 | i) effectively disclaims on behalf of all Contributors all warranties and
83 | conditions, express and implied, including warranties or conditions of title
84 | and non-infringement, and implied warranties or conditions of merchantability
85 | and fitness for a particular purpose;
86 |
87 | ii) effectively excludes on behalf of all Contributors all liability for
88 | damages, including direct, indirect, special, incidental and consequential
89 | damages, such as lost profits;
90 |
91 | iii) states that any provisions which differ from this Agreement are offered
92 | by that Contributor alone and not by any other party; and
93 |
94 | iv) states that source code for the Program is available from such
95 | Contributor, and informs licensees how to obtain it in a reasonable manner on
96 | or through a medium customarily used for software exchange.
97 |
98 | When the Program is made available in source code form:
99 |
100 | a) it must be made available under this Agreement; and
101 |
102 | b) a copy of this Agreement must be included with each copy of the Program.
103 |
104 | Contributors may not remove or alter any copyright notices contained within
105 | the Program.
106 |
107 | Each Contributor must identify itself as the originator of its Contribution,
108 | if any, in a manner that reasonably allows subsequent Recipients to identify
109 | the originator of the Contribution.
110 |
111 | 4. COMMERCIAL DISTRIBUTION
112 |
113 | Commercial distributors of software may accept certain responsibilities with
114 | respect to end users, business partners and the like. While this license is
115 | intended to facilitate the commercial use of the Program, the Contributor who
116 | includes the Program in a commercial product offering should do so in a
117 | manner which does not create potential liability for other Contributors.
118 | Therefore, if a Contributor includes the Program in a commercial product
119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend
120 | and indemnify every other Contributor ("Indemnified Contributor") against any
121 | losses, damages and costs (collectively "Losses") arising from claims,
122 | lawsuits and other legal actions brought by a third party against the
123 | Indemnified Contributor to the extent caused by the acts or omissions of such
124 | Commercial Contributor in connection with its distribution of the Program in
125 | a commercial product offering. The obligations in this section do not apply
126 | to any claims or Losses relating to any actual or alleged intellectual
127 | property infringement. In order to qualify, an Indemnified Contributor must:
128 | a) promptly notify the Commercial Contributor in writing of such claim, and
129 | b) allow the Commercial Contributor tocontrol, and cooperate with the
130 | Commercial Contributor in, the defense and any related settlement
131 | negotiations. The Indemnified Contributor may participate in any such claim
132 | at its own expense.
133 |
134 | For example, a Contributor might include the Program in a commercial product
135 | offering, Product X. That Contributor is then a Commercial Contributor. If
136 | that Commercial Contributor then makes performance claims, or offers
137 | warranties related to Product X, those performance claims and warranties are
138 | such Commercial Contributor's responsibility alone. Under this section, the
139 | Commercial Contributor would have to defend claims against the other
140 | Contributors related to those performance claims and warranties, and if a
141 | court requires any other Contributor to pay any damages as a result, the
142 | Commercial Contributor must pay those damages.
143 |
144 | 5. NO WARRANTY
145 |
146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
151 | appropriateness of using and distributing the Program and assumes all risks
152 | associated with its exercise of rights under this Agreement , including but
153 | not limited to the risks and costs of program errors, compliance with
154 | applicable laws, damage to or loss of data, programs or equipment, and
155 | unavailability or interruption of operations.
156 |
157 | 6. DISCLAIMER OF LIABILITY
158 |
159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
166 | OF SUCH DAMAGES.
167 |
168 | 7. GENERAL
169 |
170 | If any provision of this Agreement is invalid or unenforceable under
171 | applicable law, it shall not affect the validity or enforceability of the
172 | remainder of the terms of this Agreement, and without further action by the
173 | parties hereto, such provision shall be reformed to the minimum extent
174 | necessary to make such provision valid and enforceable.
175 |
176 | If Recipient institutes patent litigation against any entity (including a
177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself
178 | (excluding combinations of the Program with other software or hardware)
179 | infringes such Recipient's patent(s), then such Recipient's rights granted
180 | under Section 2(b) shall terminate as of the date such litigation is filed.
181 |
182 | All Recipient's rights under this Agreement shall terminate if it fails to
183 | comply with any of the material terms or conditions of this Agreement and
184 | does not cure such failure in a reasonable period of time after becoming
185 | aware of such noncompliance. If all Recipient's rights under this Agreement
186 | terminate, Recipient agrees to cease use and distribution of the Program as
187 | soon as reasonably practicable. However, Recipient's obligations under this
188 | Agreement and any licenses granted by Recipient relating to the Program shall
189 | continue and survive.
190 |
191 | Everyone is permitted to copy and distribute copies of this Agreement, but in
192 | order to avoid inconsistency the Agreement is copyrighted and may only be
193 | modified in the following manner. The Agreement Steward reserves the right to
194 | publish new versions (including revisions) of this Agreement from time to
195 | time. No one other than the Agreement Steward has the right to modify this
196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The
197 | Eclipse Foundation may assign the responsibility to serve as the Agreement
198 | Steward to a suitable separate entity. Each new version of the Agreement will
199 | be given a distinguishing version number. The Program (including
200 | Contributions) may always be distributed subject to the version of the
201 | Agreement under which it was received. In addition, after a new version of
202 | the Agreement is published, Contributor may elect to distribute the Program
203 | (including its Contributions) under the new version. Except as expressly
204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
205 | licenses to the intellectual property of any Contributor under this
206 | Agreement, whether expressly, by implication, estoppel or otherwise. All
207 | rights in the Program not expressly granted under this Agreement are
208 | reserved.
209 |
210 | This Agreement is governed by the laws of the State of New York and the
211 | intellectual property laws of the United States of America. No party to this
212 | Agreement will bring a legal action under this Agreement more than one year
213 | after the cause of action arose. Each party waives its rights to a jury trial
214 | in any resulting litigation.
215 |
--------------------------------------------------------------------------------
/cljs-react-material-ui-example.iml:
--------------------------------------------------------------------------------
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 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/src/cljs/cljs_react_material_ui_example/core.cljs:
--------------------------------------------------------------------------------
1 | (ns cljs-react-material-ui-example.core
2 | (:require
3 | [cljsjs.material-ui]
4 | [cljs-react-material-ui.core :as ui]
5 | [cljs-react-material-ui.icons :as ic]
6 | [goog.dom :as gdom]
7 | [om.next :as om :refer-macros [defui]]
8 | [cljs-react-material-ui-example.parser :as p]
9 | [cljs-react-material-ui-example.util :as u]
10 | [cljs-react-material-ui.chip-input.core :refer [chip-input]]
11 | [om.dom :as dom]
12 | [cljs-time.format :as tf]
13 | [cljs-time.coerce :refer [from-date]]
14 | [cljs-react-material-ui-example.state :refer [init-state]]
15 | ;[schema.core :as s :include-macros true]
16 | [print.foo :as pf :include-macros true]))
17 |
18 | (enable-console-print!)
19 |
20 | (defn get-step-content [step-index]
21 | (case step-index
22 | 0 "Select campaign settings..."
23 | 1 "What is an ad group anyways?"
24 | 2 "This is the bit I really care about!"
25 | "You're a long way from home sonny jim!"))
26 |
27 | (defui MyStepper
28 | Object
29 | (componentWillMount [this]
30 | (om/set-state! this {:finished? false :step-index 0}))
31 | (render [this]
32 | (let [{:keys [finished? step-index]} (om/get-state this)]
33 | (dom/div
34 | #js {:className "row center-xs mar-top-20"}
35 | (ui/paper
36 | {:class-name "col-xs-12 col-md-8 col-lg-6 pad-10"}
37 | (ui/stepper
38 | {:active-step step-index}
39 | (ui/step
40 | (ui/step-label "Select campaign settings"))
41 | (ui/step
42 | (ui/step-label "Create an ad group"))
43 | (ui/step
44 | (ui/step-label "Create an ad")))
45 | (if finished?
46 | (dom/div
47 | nil
48 | (ui/floating-action-button
49 | {:secondary true
50 | :on-click #(om/set-state! this {:finished? false :step-index 0})}
51 | (ic/content-clear)))
52 | (dom/div
53 | nil
54 | (dom/p #js {:className "mar-bot-20"} (get-step-content step-index))
55 | (dom/div
56 | nil
57 | (ui/flat-button
58 | {:label "Back"
59 | :disabled (= step-index 0)
60 | :on-click #(om/set-state! this {:step-index (- step-index 1)})})
61 | (ui/raised-button
62 | {:label (if (= step-index 2) "Finish" "Next")
63 | :primary true
64 | :on-click #(om/set-state! this {:step-index (+ step-index 1)
65 | :finished? (>= step-index 2)})})))))))))
66 |
67 | (def my-stepper (om/factory MyStepper {}))
68 |
69 | (defui Person
70 | static om/Ident
71 | (ident [this {:keys [db/id]}]
72 | [:person/by-id id])
73 |
74 | static om/IQuery
75 | (query [this]
76 | [:db/id :person/name :person/date {:person/status [:status/name]} {:person/happiness [:db/id :happiness/name]}])
77 |
78 | Object
79 | (render [this]
80 | (let [{:keys [person/name person/date person/status person/happiness]} (om/props this)]
81 | (ui/table-row
82 | (ui/table-row-column name)
83 | (ui/table-row-column (tf/unparse (:date tf/formatters) (from-date date)))
84 | (ui/table-row-column (:status/name status))
85 | (ui/table-row-column (:happiness/name happiness))))))
86 |
87 | (def person (om/factory Person {}))
88 |
89 | (defn my-table [people]
90 | (ui/table
91 | {:height "250px"}
92 | (ui/table-header
93 | {:display-select-all false
94 | :adjust-for-checkbox false}
95 | (ui/table-row
96 | (ui/table-header-column "Name")
97 | (ui/table-header-column "Date")
98 | (ui/table-header-column "Status")
99 | (ui/table-header-column "Happiness")))
100 | (ui/table-body
101 | (map person people))))
102 |
103 |
104 | (defn radio-btn-group [c happiness-list val]
105 | (let [[sad normal superb] happiness-list]
106 | (ui/radio-button-group
107 | {:name "happiness"
108 | :value-selected (str val)
109 | :on-change #(om/transact! c `[(person-new/change {:value ~(js/parseInt %2)
110 | :path [:person/happiness 1]})
111 | :person/new])
112 | :class-name "row between-xs mar-ver-15"}
113 | (ui/radio-button
114 | {:value (str (:db/id sad))
115 | :label (:happiness/name sad)
116 | :class-name "col-xs-4"
117 | :checked-icon (ic/social-sentiment-dissatisfied)
118 | :unchecked-icon (ic/social-sentiment-dissatisfied)})
119 | (ui/radio-button
120 | {:value (str (:db/id normal))
121 | :label (:happiness/name normal)
122 | :class-name "col-xs-4"})
123 | (ui/radio-button
124 | {:value (str (:db/id superb))
125 | :label (:happiness/name superb)
126 | :class-name "col-xs-4"
127 | :checked-icon (ic/action-favorite)
128 | :unchecked-icon (ic/action-favorite-border)}))))
129 |
130 | #_(s/defschema ValidPerson
131 | {:person/name s/Str
132 | :person/date s/Inst
133 | :person/status [(s/one s/Keyword "status/by-id") s/Int]
134 | :person/happiness [(s/one s/Keyword "happiness/by-id") s/Int]})
135 |
136 | (defn handle-chip-delete [this idx]
137 | (om/update-state! this (fn [state]
138 | (update state :chip-data (partial remove #(= (key %) idx))))))
139 |
140 | (defui MyChips
141 | Object
142 | (componentWillMount [this]
143 | (om/set-state! this {:chip-data {0 "Clojure"
144 | 1 "Clojurescript"
145 | 2 "Om.Next"
146 | 3 "MaterialUI"}}))
147 | (render [this]
148 | (let [chip-data (:chip-data (om/get-state this))]
149 | (ui/paper
150 | {:class-name "col-xs-12 col-md-8 col-md-offset-2 col-lg-6 col-lg-offset-3 pad-10 mar-top-20 row"}
151 | (for [chip (into [] chip-data)]
152 | (ui/chip {:key (key chip)
153 | :style {:margin-right 5}
154 | :on-request-delete #(handle-chip-delete this (key chip))}
155 | (val chip)))))))
156 |
157 | (def my-chips (om/factory MyChips))
158 |
159 | (defui AppRoot
160 | static om/IQuery
161 | (query [this]
162 | [{:person/list (om/get-query Person)}
163 | {:status/list [:db/id :status/name]}
164 | {:happiness/list [:db/id :happiness/name]}
165 | {:person/new (om/get-query Person)}])
166 | Object
167 | (render [this]
168 | (let [props (om/props this)
169 | state (om/get-state this)
170 | person-list (:person/list props)
171 | status-list (:status/list props)
172 | happiness-list (:happiness/list props)
173 | person-new (:person/new props)
174 | close-help #(om/update-state! this assoc :open-help? false)
175 | {:keys [drawer-open?]} (om/get-state this)]
176 | (ui/mui-theme-provider
177 | {:mui-theme (ui/get-mui-theme)}
178 | (dom/div
179 | #js {:className "h-100"}
180 | (ui/app-bar
181 | {:title "Material UI Om.Next App"
182 | :icon-element-right
183 | (ui/flat-button
184 | {:label "Github"
185 | :href "https://github.com/madvas/cljs-react-material-ui-example"
186 | :secondary true
187 | :target :_blank})
188 | :on-left-icon-button-touch-tap
189 | #(om/set-state! this {:drawer-open? true})})
190 | (ui/drawer
191 | {:docked false
192 | :open drawer-open?
193 | :on-request-change #(om/set-state! this {:drawer-open? %})}
194 | (ui/menu-item {:on-click #(println "Menu Item Clicked")} "Menu Item")
195 | (ui/menu-item "Menu Item 2"))
196 |
197 | (dom/div
198 | #js {:className "row around-xs mar-top-20"}
199 | (ui/paper
200 | {:class-name "col-xs-11 col-md-6 col-lg-4"}
201 | (ui/text-field
202 | {:floating-label-text "Name"
203 | :class-name "w-100"
204 | :value (:person/name person-new)
205 | :on-change #(om/transact! this `[(person-new/change {:value ~(u/target-val %)
206 | :path [:person/name]})
207 | :person/new])})
208 | (ui/date-picker
209 | {:hint-text "Select Date"
210 | :mode :landscape
211 | :class-name "w-100"
212 | :value (:person/date person-new)
213 | :on-change #(om/transact! this `[(person-new/change {:value ~%2
214 | :path [:person/date]})
215 | :person/new])})
216 | (ui/auto-complete
217 | {:dataSource (map :status/name status-list)
218 | :hint-text "Type status"
219 | :full-width true
220 | :open-on-focus true
221 | :search-text (or (:status/name
222 | (u/find-by-key :db/id (second (:person/status person-new)) status-list))
223 | "")
224 |
225 | :filter (aget js/MaterialUI "AutoComplete" "caseInsensitiveFilter")
226 | :on-new-request (fn [chosen]
227 | (let [status-id (:db/id (u/find-by-key :status/name chosen status-list))]
228 | (om/transact! this `[(person-new/change {:value [:status/by-id ~status-id]
229 | :path [:person/status]})
230 | :person/new])))})
231 |
232 | (radio-btn-group this happiness-list (get-in person-new [:person/happiness 1]))
233 | (dom/div
234 | #js {:className "row pad-10 reverse"}
235 | (ui/raised-button
236 | {:label "Add"
237 | :primary true
238 | :label-position :before
239 | :icon (ic/content-add-circle)
240 | ;:disabled (boolean (s/check ValidPerson person-new))
241 | :on-click #(om/transact! this `[(person-new/add)
242 | :person/new :person/list])})
243 | (ui/raised-button
244 | {:label "Help"
245 | :class-name "mar-rig-10"
246 | :secondary true
247 | :label-position :before
248 | :icon (ic/action-help)
249 | :on-click #(om/update-state! this assoc :open-help? true)})))
250 |
251 | (ui/paper
252 | {:class-name "col-xs-11 col-md-11 col-lg-7"}
253 | (ui/mui-theme-provider
254 | {:mui-theme (ui/get-mui-theme
255 | {:table-header-column
256 | {:text-color (ui/color :deep-orange500)}})}
257 | (my-table person-list))))
258 |
259 | (ui/mui-theme-provider
260 | {:mui-theme (ui/get-mui-theme
261 | {:palette {:primary1-color (ui/color :amber600)
262 | :shadow-color (ui/color :deep-orange900)
263 | :text-color (ui/color :indigo900)}
264 | :stepper {:inactive-icon-color (ui/color :deep-orange900)
265 | :connector-line-color (ui/color :light-blue600)
266 | :text-color (ui/color :teal900)
267 | :disabled-text-color (ui/color :teal200)}})}
268 | (my-stepper))
269 | (my-chips)
270 | (ui/paper
271 | {:class-name "col-xs-12 col-md-8 col-md-offset-2 col-lg-6 col-lg-offset-3 pad-10 mar-top-20 row"}
272 | (chip-input
273 | {:full-width true
274 | :default-value ["write" "here"]}))
275 | (ui/dialog
276 | {:title "Help"
277 | :key "dialog"
278 | :modal false
279 | :open (boolean (:open-help? state))
280 | :actions [(ui/raised-button
281 | {:label "Back"
282 | :key "back"
283 | :on-click close-help})
284 | (ui/raised-button
285 | {:label "Thanks"
286 | :key "thanks"
287 | :on-click close-help})]
288 | :on-request-close close-help})
289 | )))))
290 |
291 | (def reconciler
292 | (om/reconciler
293 | {:state (atom init-state)
294 | :normalize true
295 | :parser (om/parser {:read p/read :mutate p/mutate})}))
296 |
297 | (om/add-root! reconciler AppRoot (gdom/getElement "app"))
298 |
299 |
--------------------------------------------------------------------------------