root function is what gets added to our markup for the page. q/db is a query that just returns our entire re-frame db.
Some example styling for the inspector.
| .inspector { | |
| cursor: pointer; | |
| } | |
| @media screen and (max-width: 1024px) { | |
| .inspector { | |
| display: none !important; | |
| } | |
| } | |
| body.local .inspector { | |
| max-height: 80%; | |
| overflow: auto; | |
| padding: 5px 20px 5px 0; | |
| text-transform: none; | |
| position: fixed; | |
| right: 100px; | |
| bottom: 30px; | |
| z-index: 100; | |
| color: #fff; | |
| background: rgba(30, 28, 65, 0.97); | |
| } | |
| body.local .inspector > div > span > span { | |
| color: #FF7B7B !important; | |
| } | |
| body.local .inspector hr { | |
| display: none; | |
| } |
| (ns lumanu.ui.tags.inspector | |
| (:require [reagent.core :refer [atom]] | |
| [re-frame.core :as rf] | |
| [goog.format :as format] | |
| [lumanu.ui.queries :as q])) | |
| (defn map-sorter [m] | |
| (into (sorted-map) m)) | |
| (defn set-sorter [s] | |
| (apply sorted-set s)) | |
| (declare literal coll-view assoc-view) | |
| (defprotocol IInspect | |
| (-inspect [this] | |
| "Return a React or Om compatible representation of this.")) | |
| (extend-protocol IInspect | |
| Keyword | |
| (-inspect [this] (literal "keyword" this)) | |
| Symbol | |
| (-inspect [this] (literal "symbol" this)) | |
| PersistentArrayMap | |
| (-inspect [this] | |
| (assoc-view "{" "}" "map persistent-array-map" map-sorter)) | |
| PersistentHashMap | |
| (-inspect [this] | |
| (assoc-view "{" "}" "map persistent-hash-map" map-sorter)) | |
| PersistentVector | |
| (-inspect [this] (coll-view "[" "]" "vector")) | |
| PersistentHashSet | |
| (-inspect [this] (coll-view "#{" "}" "set persistent-hash-set" identity)) | |
| PersistentTreeSet | |
| (-inspect [this] (coll-view "#{" "}" "set persistent-tree-set" identity)) | |
| List | |
| (-inspect [this] (coll-view "(" ")" "list")) | |
| LazySeq | |
| (-inspect [this] (coll-view "(" ")" "seq lazy-seq")) | |
| KeySeq | |
| (-inspect [this] (coll-view "(" ")" "seq key-seq")) | |
| ValSeq | |
| (-inspect [this] (coll-view "(" ")" "seq val-seq")) | |
| PersistentArrayMapSeq | |
| (-inspect [this] (coll-view "(" ")" "seq persistent-array-map-seq")) | |
| Range | |
| (-inspect [this] (coll-view "(" ")" "seq range")) | |
| UUID | |
| (-inspect [this] (literal "uuid" this)) | |
| js/RegExp | |
| (-inspect [this] (literal "regexp" this)) | |
| js/Date | |
| (-inspect [this] (literal "date" this)) | |
| Atom | |
| (-inspect [this] (-inspect @this)) | |
| ExceptionInfo | |
| (-inspect [this] (assoc-view "#error {" "}" "object" (comp map-sorter | |
| #(hash-map :message (.-message %) | |
| :data (ex-data %))))) | |
| function | |
| (-inspect [this] (literal "function" this)) | |
| number | |
| (-inspect [this] (literal "number" this)) | |
| string | |
| (-inspect [this] (literal "string" this)) | |
| boolean | |
| (-inspect [this] (literal "boolean" this)) | |
| array | |
| (-inspect [this] (coll-view "#js [" "]" "array")) | |
| object | |
| (-inspect [this] (assoc-view "#js {" "}" "object" (comp map-sorter js->clj))) | |
| nil | |
| (-inspect [this] (literal "nil" this))) | |
| (defn inspect [thing] | |
| (-inspect thing)) | |
| (defn literal [class v] | |
| [:span (pr-str v)]) | |
| (defn assoc-view [start end class sorter] | |
| (let [open (atom false)] | |
| (fn [coll] | |
| [:div {:style {:padding-left "25px"} | |
| :on-click (fn [e] (swap! open not) (.stopPropagation e))} | |
| start | |
| (if @open | |
| (for [[k v] (sorter coll)] | |
| [:span {:key k} | |
| [:span {:style {:color "red"}} | |
| [inspect k]] | |
| [:div | |
| [inspect v]]]) | |
| (if (satisfies? ICounted coll) | |
| (str "...[" (count coll) "]...") | |
| "...")) | |
| end]))) | |
| (defn coll-view [start end class sorter] | |
| (let [open (atom false)] | |
| (fn [coll] | |
| [:div | |
| {:style {:padding-left "25px"} | |
| :on-click (fn [e] (swap! open not) (.stopPropagation e))} | |
| start | |
| (if @open | |
| (for [[idx i] (map-indexed vector ((or sorter identity) coll))] | |
| [:div {:key idx} [inspect i]]) | |
| (if (satisfies? ICounted coll) | |
| (str "...[" (count coll) "]...") | |
| "...")) | |
| end]))) | |
| (defn root [] | |
| [:div.inspector {:style {:text-transform "none"}} | |
| [:hr] | |
| [inspect @q/db]]) | |