A ClojureScript library to interactively visualize and edit clojure collections
Coll-pen renders clojure collections as interactive elements using reagent. It was generally built for development or internal use, and is great for examining the state of an app. That said, it can certainly be used as a component in end-user applications as well.
Additionally, it is fully keyboard navigable and designed with accessibility in mind.
Check out the demo
There is one main function, coll-pen.core/draw
which takes one or two parameters
coll
- the collection to be drawnopts
- optional options map
:key
- Used to ensure a unique react component is created for the collection. Also used to store state across dynamic reloads (for figwheel-style development) which can be cleared with the coll-pen.core/clear-state-data!
:load-data-fn
- A function of 3 args [coll path loaded-callback]
which will be called when an unloaded collection is first expanded. If nil
, all data is presumed to be loaded. loaded-callback
takes a single optional parameter which should be a sequence of sub-paths (that have been loaded) to auto-expand.:edit-handler
- A function of 3 args [edit-map ok-callback fail-callback]
which is called when an element is added, edited, or deleted. See example. If edit-handler
is nil
, no edit controls will appear. If an edit is successful ok-callback
should be called with an optional single success-message parameter. If the update fails, fail-callback
should be called with an optional fail-message
parameter. The contents of the edit-map
will be:
:old-coll
- the collection before editing:new-coll
- the collection after editing:path
path - keyseq of the coll relative to the root:key
- the key in the collection which was edited:old-value
- the old value associated with the key:new-value
- the new value associated with the key :deleted -> true if the key was deleted/removed:search-handler
- either a keyword indicating one of the built-in search functions or a functions of two arguments [coll search-string]
which should return a collection of results. If nil, search functionality will be disabled. Built-in search functions are:subs
- substring search (default)
:regex
- regular expression search
:prefix
- prefix string search
:eq
- equality/exact-match search:search-instructions
- a string to explain searching, can be used to override the built-in search function instructions:expanded-paths
- a sequence of paths which are initially loaded/expanded. If a keyword is supplied instead, all paths will be expanded by default. Default '([])
:estimated-count-fn
- a function which will be called to determine the size of a collapsed/unloaded collection. If :load-data-fn
is nil, the default is count
.:el-per-page
- number of elements to show in a collection before paginating. Default 10
:truncate
- permitted length of a string before it is truncated. Falsely value disables truncation. Default 35
:palette
- :dark
, :light
, or map with the following keys specifying colors (and font): :background
:foreground
:shadow
:highlight
:control
:active
:disabled
:status
:error
:string
:keyword
:symbol
:number
:other
:idx
:font
. Missing keys will be substituted from the :dark
theme.:custom-renderer
- a function of one argument which will be called before rendering a collection or value. If it evaluates to nil the default renderer will be used.:always-highlight
- by default, highlighting behavior is reduced when using mouse-interaction setting this to true will always use keyboard-interaction highlight behavior.The other available functions are:
clear-state-data!
- which clears any state associated with keys (only relevant for dynamic reloading situations)unroll-paths
- a helper function useful for expanding all paths when calling a loading-callback
function. e.g. (loaded-callback (unroll-paths loaded-collection))
create-css-link
- a simple utility to inject stylesheet data into a page by creating a hiccup-style uri-encoded link elementThe display and editing functionality varies between the four main collection types:
Nested collections are only rendered as elements if their parent is associative, otherwise they are rendered as text. So, the children of map
s and vector
s will be interactive collections, but the children of set
s and sequence
s will always be text. Map keys are always rendered as text.
+
will open the element adder3/7
) will open a page-jump field?
will open the search field.Tab
bableEnter
on opening bracket/brace expands/collapses an elementEnter
on a map key, vector index, or set element opens the editorArrowLeft
and ArrowRight
will move between pages. Enter
will open a page-jump field and ?
will open the search fieldCtrl/Cmd + Enter
will saveCtrl/Cmd + Backspace/Delete
will deleteEscape
will close jump, search, and editor fields(require '[coll-pen.core :as cp])
(cp/draw {'a :map} {:key :map})
(cp/draw ["this" "is" "a" "vector"] {:key :vector})
(cp/draw #{'example/set} {:key :set})
(cp/draw '(a "sequence" :of [:elements]) {:key :seq})
Note how the last item [:element]
is not rendered as a collection because a sequence is not an associative structure.
(cp/draw {[1 2] [3 #{4 5}]} {:key :nested})
Note how the map key [1 2]
, despite being a vector, is not rendered as an interactive collection.
A very simple local edit handler.
(def state (reagent/atom {:stuff :here}))
(cp/draw state {:edit-handler (fn [{:keys [path new-call]} ok-cb fail-cb]
(if (empty? path)
(reset! state/app-state new-coll)
(swap! state/app-state assoc-in path new-coll))
(ok-cb "success"))})
for a more complete code example, view the coll-pen/demo/main.cljs
source file
Contributions and feature requests are welcome.
Feedback on accessibility would also be appreciated, as I am trying to improve my understanding of accessibility to better support all users in my projects.
Copyright © 2020 David Scarpetti
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close