This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-28
Channels
- # beginners (2)
- # calva (8)
- # capetown (1)
- # clojure (28)
- # clojure-europe (6)
- # clojure-norway (82)
- # clojure-sweden (1)
- # clojuredesign-podcast (5)
- # clojurescript (26)
- # core-async (3)
- # cryogen (7)
- # datahike (30)
- # datomic (10)
- # figwheel-main (8)
- # honeysql (8)
- # hyperfiddle (15)
- # jobs-discuss (6)
- # lsp (6)
- # matrix (6)
- # off-topic (12)
- # overtone (1)
- # polylith (6)
- # portal (6)
- # releases (1)
- # shadow-cljs (9)
- # sql (1)
- # xtdb (5)
i'm looking for a hiccup library in clojurescript. i'm not looking to use something as heavy as reagent, i just want to convert [:div ...]
to <div>...</div>
in plain clojurescript for use in a simple app (modify the dom lightly). which is the best hiccup library for something with no backend?
take a look at hicada if you target jsx/react.
It's also a nice "template" on how to write your own, as Eugene said above it's relatively easy half a day project.
> half a day Barely an hour. :) It really doesn't require that much. Here's the code that I have, that also supports fragments to make some things easier:
(defrecord Fragment [children])
(defn fragment? [x]
(instance? Fragment x))
(defn append-child! [^js el child]
(if (fragment? child)
(doseq [child (:children child)
:when (some? child)]
(append-child! el child))
(.append el child)))
(defn hiccup->element [hv ^js doc]
(if (vector? hv)
(let [[tag attrs-or-child & children] hv
attrs (when (map? attrs-or-child) attrs-or-child)
children (cond->> children (nil? attrs) (cons attrs-or-child))]
(if (= tag :<>)
(do
(assert (nil? attrs))
(->Fragment (mapv #(hiccup->element % doc) children)))
(let [el (.createElement doc (name tag))]
(doseq [[attr val] attrs]
(.setAttribute el (name attr) (str val)))
(doseq [child children
:let [child-el (hiccup->element child doc)]
:when child-el]
(append-child! el child-el))
el)))
hv))
(defn hiccup->document [hv]
(let [doc (.createDocument js/document.implementation nil nil)
el (hiccup->element hv doc)]
(when el
(append-child! doc el))
doc))
Dang, thank you!
just write it yourself, takes maybe 50 lines tops
What's the fastest/most direct way to loop a collection for side effects in ClojureScript?
(doseq [x ["a" "b" "c" "d" "e" "f"]]
(js/console.log x))
This generates a surprising amount of code, I'm guessing because of the vector.Theres a large constant overhead for even the shortest CLJS programs
doseq
is the most idiomatic way to iterate through a collection for side effects
The amount of code is not because of the vector but because of doseq
. Although I've checked only the CLJS compiler output and I suspect a lot of that code will be removed by GCC during a production build.
You can try using run!
instead if all you need is to call a function.
loop
is another alternative.
yup, i agree โ in general, macros like for
and doseq
have high overhead and are only worth it IMO when you actually use list comprehensions
I would expect the lowest-overhead alternative, without writing JS interop, is to use loop
, followed by run!
, and then doseq
My "surprising amount of code" comment on doseq was based on a production build btw
yeah, in CLJS codebases I avoid for
and doseq
for similar reasons โ Iโve found them to have ridiculous overhead in simple cases like (for [x xs] (do thing with x))
thatโs why I personally avoid these macros unless I am using more complex list comprehensions
Related: I have a loop
that loops two collections. It currently uses first
and next
to process each item and recur, but I also occasionally need to perform .indexOf
style searches in them. Would it be better to write this with vectors, a separate n
and use nth
for lookup?
If you already have a vector, it has .indexOf
.
FWIW, I myself don't really try to limit myself in terms of constructs that I use. A single NPM dep will almost certainly increase the bundle size by much more than all the doseq
s that I can use in my code.
cljs is not a great choice if your priority is tiny bundle sizes