Document render-component

This commit is contained in:
Dan Holmsand 2014-01-03 15:52:18 +01:00
parent dc6b50e864
commit 059e190841
1 changed files with 55 additions and 23 deletions

View File

@ -34,12 +34,13 @@
(map #(% defs) names)))) (map #(% defs) names))))
(def builtins ["def" "defn" "ns" "atom" "let" "if" "when" (def builtins ["def" "defn" "ns" "atom" "let" "if" "when"
"cond" "merge"]) "cond" "merge" "assoc" "swap!" "reset!"])
(defn syntaxify [src] (defn syntaxify [src]
(let [str-p "\"[^\"]*\"" (let [sep "\\][(){} \\t\\n"
keyw-p ":[^\\][(){} \\t\\n]+" str-p "\"[^\"]*\""
res-p (string/join "\\b|" builtins) keyw-p (str ":[^" sep "]+")
res-p (string/join "|" (map #(str % "(?=[" sep "])") builtins))
any-p ".|\\n" any-p ".|\\n"
patt (re-pattern (str "(" patt (re-pattern (str "("
(string/join ")|(" [str-p keyw-p res-p any-p]) (string/join ")|(" [str-p keyw-p res-p any-p])
@ -56,11 +57,14 @@
[:pre (syntaxify (src-for-names defs))]) [:pre (syntaxify (src-for-names defs))])
(defn demo-component [props] (defn demo-component [props]
[:div.example [:div
[:h3 "Example"] (when (:comp props)
[(:comp props)] [:div.demo-example
[:h3 "Source"] [:h3.demo-heading "Example"]
[src-for props]]) [(:comp props)]])
[:div.demo-source
[:h3.demo-heading "Source"]
[src-for props]]])
(defn simple-component [] (defn simple-component []
[:div [:div
@ -88,7 +92,8 @@
(defn counting-component [] (defn counting-component []
[:div [:div
"The atom " [:code "click-count"] " has value: " @click-count ". " "The atom " [:code "click-count"] " has value: "
@click-count ". "
[:input {:type "button" [:input {:type "button"
:value "Click me!" :value "Click me!"
:on-click #(swap! click-count inc)}]]) :on-click #(swap! click-count inc)}]])
@ -99,10 +104,14 @@
[:div [:div
[:p "The value of " [:code "val"] " is now: " @val] [:p "The value of " [:code "val"] " is now: " @val]
[:p "Change it: " [:p "Change it: "
[:input {:type "text" [:input
:value @val {:type "text" :value @val
:on-change #(reset! val (-> % .-target .-value))}]]]))) :on-change #(reset! val (-> % .-target .-value))}]]])))
(defn render-simple []
(cloact/render-component [simple-component]
(.-body js/document)))
(defn calc-bmi [{:keys [height weight bmi] :as params}] (defn calc-bmi [{:keys [height weight bmi] :as params}]
(let [h (/ height 100)] (let [h (/ height 100)]
(if (nil? bmi) (if (nil? bmi)
@ -114,11 +123,11 @@
(defn set-bmi [key val clear] (defn set-bmi [key val clear]
(swap! bmi-data #(calc-bmi (merge % {key val, clear nil})))) (swap! bmi-data #(calc-bmi (merge % {key val, clear nil}))))
(defn slider [{:keys [value key clear min max]}] (defn slider [{:keys [value min max param clear]}]
[:div [:div
[:input {:type "range" :min min :max max :value value [:input {:type "range" :min min :max max :value value
:style {:width "100%"} :style {:width "100%"}
:on-change #(set-bmi key (-> % .-target .-value) :on-change #(set-bmi param (-> % .-target .-value)
(or clear :bmi))}]]) (or clear :bmi))}]])
(defn bmi-component [] (defn bmi-component []
@ -129,16 +138,18 @@
(< bmi 30) ["orange" "overweight"] (< bmi 30) ["orange" "overweight"]
:else ["red" "obese"])] :else ["red" "obese"])]
[:div [:div
[:h3 "BMI calculator"]
[:div [:div
"Height: " (int height) "cm" "Height: " (int height) "cm"
[slider {:value height :min 100 :max 220 :key :height}]] [slider {:value height :min 100 :max 220 :param :height}]]
[:div [:div
"Weight: " (int weight) "kg" "Weight: " (int weight) "kg"
[slider {:value weight :min 50 :max 200 :key :weight}]] [slider {:value weight :min 30 :max 150 :param :weight}]]
[:div [:div
"BMI: " (int bmi) " " "BMI: " (int bmi) " "
[:span {:style {:color color}} diagnose] [:span {:style {:color color}} diagnose]
[slider {:value bmi :min 10 :max 50 :key :bmi :clear :weight}]]])) [slider {:value bmi :min 10 :max 50 :param :bmi
:clear :weight}]]]))
(defn intro [] (defn intro []
[:div [:div
@ -172,15 +183,15 @@ Hiccup-like syntax."]
[:p "The easiest way to manage state in Cloact is to use Cloact's [:p "The easiest way to manage state in Cloact is to use Cloact's
own version of " [:code "atom"] ". It works exactly like the one in own version of " [:code "atom"] ". It works exactly like the one in
clojure.core, except that it keeps track of every time it is clojure.core, except that it keeps track of every time it is
deref'ed. Any component that uses the atom is automagically deref'ed. Any component that uses an " [:code "atom"]" is automagically
re-rendered."] re-rendered when its value changes."]
[:p "Let's demonstrate that with a simple example:"] [:p "Let's demonstrate that with a simple example:"]
[demo-component {:comp counting-component [demo-component {:comp counting-component
:defs [:ns :click-count :counting-component]}] :defs [:ns :click-count :counting-component]}]
[:p "Sometimes you may want to maintain state locally in a [:p "Sometimes you may want to maintain state locally in a
component. That is very easy to do with an " [:code "atom"] " as well."] component. That is easy to do with an " [:code "atom"] " as well."]
[:p "Here is an example of that:"] [:p "Here is an example of that:"]
[demo-component {:comp local-state [demo-component {:comp local-state
@ -193,18 +204,39 @@ Hiccup-like syntax."]
created components, without resorting to React's lifecycle created components, without resorting to React's lifecycle
events."]]) events."]])
(defn essential-api []
[:div
[:h2 "Essential API"]
[:p "Cloact supports (almost) the entire React API, but there is
really only one entry-point that is necessary for most
applications: " [:code "cloact.core/render-component"] "."]
[:p "It takes too arguments: a component, and a DOM node. For
example, splashing the very first example all over the page would
look like this:"]
[demo-component {:defs [:ns :simple-component :render-simple]}]])
(defn bmi-demo [] (defn bmi-demo []
[:div [:div
[:h2 "Simple BMI calculator"] [:h2 "Putting it all together"]
[:p "Here is a slightly less contrived example: a simple BMI
calculator."]
[:p "Data is kept in a single " [:code "cloact.core/atom"] ": a map
with height, weight and BMI as keys."]
[demo-component {:comp bmi-component [demo-component {:comp bmi-component
:defs [:ns :calc-bmi :bmi-data :set-bmi :slider :defs [:ns :calc-bmi :bmi-data :set-bmi :slider
:bmi-component]}]]) :bmi-component]}]])
(defn demo [] (defn demo []
[:div [:div.cloact-demo
[:h1 "This will become a demo"] [:h1 "This will become a demo"]
[intro] [intro]
[managing-state] [managing-state]
[essential-api]
[bmi-demo] [bmi-demo]
[:p "WIP"]]) [:p "WIP"]])