diff --git a/.gitignore b/.gitignore index 04c5219..5387438 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ index.html assets/ -news/ +/news/ target pom.xml .lein-repl-history diff --git a/demo/reagentdemo/common.cljs b/demo/reagentdemo/common.cljs index 7d12cd1..14d2ef3 100644 --- a/demo/reagentdemo/common.cljs +++ b/demo/reagentdemo/common.cljs @@ -21,9 +21,7 @@ ") (defn src-for-names [srcmap names] - (string/join "\n" (-> srcmap - (select-keys names) - vals))) + (string/join "\n" (map srcmap names))) (defn fun-map [src] (-> src src-parts src-defs (assoc :ns nssrc))) @@ -36,7 +34,7 @@ (fn [] [:div (when comp - [:div.demo-example + [:div.demo-example.clearfix [:a.demo-example-hide {:on-click (fn [e] (.preventDefault e) (swap! showing not) @@ -48,6 +46,6 @@ [:div.simple-demo [comp]] [comp]))]) (when @showing - [:div.demo-source + [:div.demo-source.clearfix [:h3.demo-heading "Source"] src])]))) diff --git a/demo/reagentdemo/news.cljs b/demo/reagentdemo/news.cljs index 926b7ab..2204f9e 100644 --- a/demo/reagentdemo/news.cljs +++ b/demo/reagentdemo/news.cljs @@ -4,6 +4,7 @@ [reagentdemo.syntax :refer-macros [get-source]] [reagentdemo.page :refer [title link page-map]] [reagentdemo.common :as common :refer [demo-component]] + [reagentdemo.news.async :as async] [todomvc :as todomvc])) (def funmap (-> "reagentdemo/news.cljs" get-source common/fun-map)) @@ -81,7 +82,9 @@ [undo-demo-cleanup]]])) (defn main [] - [undo-example]) + [:div + [async/main] + [undo-example]]) (swap! page-map assoc "news/cloact-reagent-undo-demo.html" undo-example) diff --git a/demo/reagentdemo/news/async.cljs b/demo/reagentdemo/news/async.cljs new file mode 100644 index 0000000..a6abbce --- /dev/null +++ b/demo/reagentdemo/news/async.cljs @@ -0,0 +1,106 @@ +(ns reagentdemo.news.async + (:require [reagent.core :as reagent :refer [atom]] + [reagent.debug :refer-macros [dbg println]] + [reagentdemo.syntax :refer-macros [get-source]] + [reagentdemo.page :refer [title link page-map]] + [reagentdemo.common :as common :refer [demo-component]])) + +(def funmap (-> "reagentdemo/news/async.cljs" get-source common/fun-map)) +(def src-for (partial common/src-for funmap)) + +(defn timing-wrapper [{f :component-fn}] + (let [start-time (atom nil) + render-time (atom nil) + now #(.now js/Date) + start (fn [] (reset! start-time (now)) nil) + stop #(reset! render-time (- (now) @start-time)) + timed-f (with-meta f + {:get-initial-state start + :component-will-update start + :component-did-mount stop + :component-did-update stop})] + (fn [props children] + [:div + [:p [:em "render time: " @render-time "ms"]] + (into [timed-f props] children)]))) + +(def base-color (atom {:red 130 :green 160 :blue 120})) +(def ncolors (atom 20)) +(def random-colors (atom nil)) + +(defn to-rgb [{:keys [red green blue]}] + (let [hex (fn [x] + (str (if (< x 16) "0") + (-> x js/Math.round (.toString 16))))] + (str "#" (hex red) (hex green) (hex blue)))) + +(defn tweak-color [{:keys [red green blue]}] + (let [rnd #(-> (js/Math.random) (* 256)) + tweak #(-> % (+ (rnd)) (/ 2) js/Math.floor)] + {:red (tweak red) :green (tweak green) :blue (tweak blue)})) + +(defn reset-random-colors [] + (reset! random-colors + (repeatedly #(-> @base-color tweak-color to-rgb)))) + +(defn color-choose [{color-part :color-part}] + [:div (name color-part) " " (color-part @base-color) + [:input {:type "range" :min 0 :max 255 + :style {:width "100%"} + :value (color-part @base-color) + :on-change + (fn [e] + (swap! base-color assoc + color-part (-> e .-target .-value int)) + (reset-random-colors))}]]) + +(defn ncolors-choose [] + [:div + "number of colors " @ncolors + [:input {:type "range" :min 0 :max 500 + :style {:width "100%"} + :value @ncolors + :on-change #(reset! ncolors (-> % .-target .-value))}]]) + +(defn color-plate [{color :color}] + [:div.color-plate + {:style {:background-color color}}]) + +(defn palette [] + (let [color @base-color + n @ncolors] + [:div + [:div + [:p "base color: "] + [color-plate {:color (to-rgb color)}]] + [:div.color-samples + [:p n " random matching colors:"] + (map-indexed (fn [k v] + [color-plate {:key k :color v}]) + (take n @random-colors))]])) + +(defn color-demo [] + (reset-random-colors) + (fn [] + [:div + [:h2 "Matching colors"] + [color-choose {:color-part :red}] + [color-choose {:color-part :green}] + [color-choose {:color-part :blue}] + [ncolors-choose] + [timing-wrapper {:component-fn palette}]])) + +(defn main [] + [:div.reagent-demo + [title "Reagent: Faster by waiting"] + [:h1 [link {:href main} "Faster by waiting"]] + + [demo-component {:comp color-demo + :src (src-for + [:ns :timing-wrapper :base-color + :ncolors :random-colors :to-rgb + :tweak-color :reset-random-colors :color-choose + :ncolors-choose :palette :color-demo])}]]) + +(swap! page-map assoc + "news/reagent-is-async.html" main) diff --git a/demo/reagentdemo/page.cljs b/demo/reagentdemo/page.cljs index eb1c244..7a3cb51 100644 --- a/demo/reagentdemo/page.cljs +++ b/demo/reagentdemo/page.cljs @@ -78,10 +78,16 @@ identity)) children))) +(add-watch page ::title-watch + (fn [_ _ _ p] + ;; First title on a page wins + (reset! title-atom ""))) + (defn title [props children] (let [name (first children)] - (if reagent/is-client - (let [title (aget (.getElementsByTagName js/document "title") 0)] - (set! (.-innerHTML title) name))) - (reset! title-atom name) + (when (= @title-atom "") + (if reagent/is-client + (let [title (aget (.getElementsByTagName js/document "title") 0)] + (set! (.-innerHTML title) name))) + (reset! title-atom name)) [:div])) diff --git a/site/demo.css b/site/demo.css index e527fb1..be6dce3 100644 --- a/site/demo.css +++ b/site/demo.css @@ -5,6 +5,16 @@ box-sizing: border-box; } + +.clearfix:before, .clearfix:after { + content: " "; + display: table; +} + +.clearfix:after { + clear: both; +} + div.nav { position: absolute; top: 0; @@ -139,4 +149,17 @@ ul.nav > li.brand > a { .demo-example-hide { float: right; cursor: pointer; +} + +/* Color demo */ + +.color-plate { + float: left; + height: 100px; + width: 100px; +} + +.color-samples { + clear: both; + padding-top: 0.5em; } \ No newline at end of file