This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
Hi there 👋 ... Playing with Clerk here: I'm writing a notebook to explain (and develop, actually) a model for chess-like games, for pedagogical purposes.
I have a working viewer for game boards, that's good. Now I found that I almost always want to show both the Clojure data structure in addition to the visual board representation. I started simply repeating the code, with metadata to use the standard viewer, and then my own viewer (hiding the code)... but it gets tedious.
Later I wrote a couple of macros... also problematic. So now I'm trying to implement something like the literal-viewer
described on "the Book", but cannot get it to work... no surprise here, since I'm not sure what I'm doing :-)
Here's what I have:
(def board-toggle-viewer
{:transform-fn (comp clerk/mark-preserve-keys
(clerk/update-val (fn [v]
{"Clojure" (clerk/with-viewer clerk-viewer/map-viewer v)
"Board" (clerk/with-viewer board-viewer v) })))
:render-fn '(fn [label->val]
(reagent.core/with-let [!selected-label (reagent.core/atom (ffirst label->val))]
...
The Clojure
version renders fine... But when I select by "Board", I get what seems to be a React error that reads: Doesn't support name: ["Board" 0]
.
Any ideas before I give up? :-\
Thanks!!It'd be awesome to have a generic "multi-viewer"... by default showing a "tab" for each matching viewer (truthy pred
). Would this be feasible? Any pointers to guide me in the right direction?
(def tabbed-viewer
"Clerk viewer for showing values in a tabbed interface. Use this viewer with
- A map of label => value
- A sequence of pairs of the form `[label, value]`
Use the second form if you care about the order of your tabs."
{:name `tabbed-viewer
:render-fn
'(fn [pairs opts]
(reagent.core/with-let
[ks (mapv
(fn [{[k] :nextjournal/value}]
(:nextjournal/value k))
pairs)
m (into {} (map
(fn [{[k v] :nextjournal/value}]
[(:nextjournal/value k) v]))
pairs)
!k (reagent.core/atom (first ks))]
[:<> (into
[:div.flex.items-center.font-sans.text-xs.mb-3
[:span.text-slate-500.mr-2 "View as:"]]
(map (fn [k]
[:button.px-3.py-1.font-medium.hover:bg-indigo-50.rounded-full.hover:text-indigo-600.transition
{:class
(if (= @!k k)
"bg-indigo-100 text-indigo-600"
"text-slate-500")
:on-click #(reset! !k k)}
k]))
ks)
[nextjournal.clerk.viewer/inspect-presented
(get m @!k)]]))})
(defn multi
"Given either
- A map of label => value
- A sequence of pairs of the form `[label, value]`
returns a form that will render in Clerk as a tabbed interface, where clicking
the tab assigned to a label will replace the space below with the
corresponding value.
Use the second form if you care about the order of your tabs."
[xs]
(viewer/with-viewer tabbed-viewer xs))
@U04V3C42G for example: https://emmy-viewers.mentat.org/dev/examples/mafs#multiviewer
Thanks @U017QJZ9M7W!... I'll give that a try later today. While not quite what I'm trying to achieve, it's definitely in the right direction