Skip to content

Commit bfa8530

Browse files
committed
Tag slider/text-input viewer fns with :var-from-def? meta
Function viewers whose returned viewer map opts out of var-from-def unwrapping need to advertise that intent upfront, otherwise the outer code can't know whether to pass the raw var-from-def map or the deref'd value. Metadata on the fn value lets `apply-viewer- unwrapping-var-from-def` decide in a single pass. Also updates the viewer-test case for fn viewers to use meta-based opt-out instead of the post-hoc return-shape detection.
1 parent 76ee287 commit bfa8530

3 files changed

Lines changed: 21 additions & 6 deletions

File tree

src/nextjournal/clerk/experimental.clj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
([!state] (slider {} !state))
3434
([opts !state] (viewer/with-viewer (assoc viewer/render-eval-viewer :render-fn (render-slider opts)) !state)))
3535

36+
(alter-var-root #'slider with-meta {:var-from-def? true})
37+
3638

3739
(defn render-text-input
3840
([] (render-slider {}))
@@ -49,3 +51,5 @@
4951
([!state] (text-input {} !state))
5052
([opts !state] (viewer/with-viewer (assoc viewer/render-eval-viewer :render-fn (render-text-input opts)) !state)))
5153

54+
(alter-var-root #'text-input with-meta {:var-from-def? true})
55+

src/nextjournal/clerk/viewer.cljc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,13 +438,15 @@
438438
:transform-fn (update-val unwrap-var-value)})
439439

440440
(defn apply-viewer-unwrapping-var-from-def
441-
"Applies the `viewer` (if set) to the given result `result`. In case
442-
the `value` is a `var-from-def?` it will be unwrapped (so that the
443-
viewer operates on the def's value) unless the viewer map opts out
444-
with a truthy `:var-from-def?`."
441+
"Applies the `viewer` (if set) to the given result `result`. By default
442+
the `value` of a `var-from-def?` is unwrapped so that the viewer
443+
operates on the def's value. To opt out, a viewer map must carry
444+
`:var-from-def? true`, or a viewer fn must have `:var-from-def? true`
445+
in its metadata (use `with-meta` / `alter-var-root`)."
445446
[{:as result :nextjournal/keys [value viewer]}]
446447
(if viewer
447-
(let [opts-out? (and (map? viewer) (:var-from-def? viewer))
448+
(let [opts-out? (or (and (map? viewer) (:var-from-def? viewer))
449+
(and (ifn? viewer) (:var-from-def? (meta viewer))))
448450
value' (cond-> value
449451
(and (var-from-def? value) (not opts-out?))
450452
unwrap-var-value)

test/nextjournal/clerk/viewer_test.clj

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,16 @@
238238
(is (= [1 2 3]
239239
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var
240240
:nextjournal.clerk/var-snapshot [1 2 3]}
241-
:nextjournal/viewer v/row})))))
241+
:nextjournal/viewer v/row}))))
242+
243+
(testing "function viewer tagged with `:var-from-def? true` metadata receives the raw var-from-def (e.g. cx/slider)"
244+
(let [viewer-fn (with-meta (fn [v] (v/with-viewer v/html-viewer v))
245+
{:var-from-def? true})]
246+
(is (= {:nextjournal.clerk/var-from-def #'my-test-var
247+
:nextjournal.clerk/var-snapshot [:h1 "hi"]}
248+
(apply+get-value {:nextjournal/value {:nextjournal.clerk/var-from-def #'my-test-var
249+
:nextjournal.clerk/var-snapshot [:h1 "hi"]}
250+
:nextjournal/viewer viewer-fn}))))))
242251

243252

244253
(deftest resolve-aliases

0 commit comments

Comments
 (0)