Files
clj-ui-framework/bb.edn
Florian Schroedl c857954845 feat: add icon component with 50+ Lucide-based SVG icons
Adds a general-purpose icon system (ui.icon) with inline SVG rendering:
- 50+ icons from the Lucide icon set (navigation, actions, objects, UI,
  status, dev/technical categories)
- Size variants: sm (--size-4), md (--size-5), lg (--size-6), xl (--size-8)
- Pure data approach: icon paths stored as hiccup vectors, rendered into
  SVG with stroke="currentColor" so icons inherit text color
- API: (icon/icon {:icon-name :home :size :lg :class "custom"})

Integrates icons into the sidebar component:
- sidebar-menu-item now accepts :icon-name prop
- Renders icon in a .sidebar-menu-item-icon wrapper at :sm size

All three dev targets updated with icon gallery demo and sidebar icons.
2026-03-05 12:49:22 +01:00

137 lines
6.1 KiB
Clojure

{:paths ["src" "test" "dev/hiccup/src"]
:tasks
{build-theme
{:doc "Generate dist/theme.css from tokens.edn and copy to dev targets"
:requires ([ui.css.gen :as gen]
[clojure.java.io :as io])
:task (do (gen/build-theme! {:input "src/theme/tokens.edn"
:output "dist/theme.css"})
(let [css (slurp "dist/theme.css")]
(spit "dev/replicant/public/theme.css" css)
(io/make-parents "dev/squint/public/theme.css")
(spit "dev/squint/public/theme.css" css)
(println "Copied theme.css to dev targets")))}
test
{:doc "Run all unit tests"
:requires ([clojure.test :as t]
[ui.button-test]
[ui.alert-test]
[ui.badge-test]
[ui.card-test]
[ui.accordion-test]
[ui.table-test]
[ui.dialog-test]
[ui.spinner-test]
[ui.skeleton-test]
[ui.progress-test]
[ui.switch-test]
[ui.tooltip-test]
[ui.breadcrumb-test]
[ui.pagination-test]
[ui.form-test]
[ui.icon-test]
[ui.sidebar-test]
[ui.theme-test])
:task (let [{:keys [fail error]} (t/run-tests
'ui.button-test
'ui.alert-test
'ui.badge-test
'ui.card-test
'ui.accordion-test
'ui.table-test
'ui.dialog-test
'ui.spinner-test
'ui.skeleton-test
'ui.progress-test
'ui.switch-test
'ui.tooltip-test
'ui.breadcrumb-test
'ui.pagination-test
'ui.form-test
'ui.icon-test
'ui.sidebar-test
'ui.theme-test)]
(when (pos? (+ fail error))
(System/exit 1)))}
ensure-npm
{:doc "Install node_modules in dev/replicant and dev/squint if missing"
:task (do
(when-not (.exists (clojure.java.io/file "dev/replicant/node_modules"))
(println "Installing node_modules in dev/replicant...")
(shell {:dir "dev/replicant"} "npm install"))
(when-not (.exists (clojure.java.io/file "dev/squint/node_modules"))
(println "Installing node_modules in dev/squint...")
(shell {:dir "dev/squint"} "npm install")))}
dev-hiccup
{:doc "Start hiccup dev server (--port PORT, default 3003)"
:depends [build-theme]
:requires ([dev.hiccup])
:task (let [port (or (some-> (System/getenv "PORT") parse-long) 3003)]
(dev.hiccup/start! {:port port})
(deref (promise)))}
dev-replicant
{:doc "Start replicant dev server (PORT env var, default 3001)"
:depends [build-theme ensure-npm]
:requires ([clojure.edn :as edn])
:task (let [port (some-> (System/getenv "PORT") parse-long)
cfg-path "dev/replicant/shadow-cljs.edn"]
(when port
(let [cfg (edn/read-string (slurp cfg-path))]
(spit cfg-path (pr-str (assoc cfg :dev-http {port "public"})))))
(shell {:dir "dev/replicant"} "npx" "shadow-cljs" "watch" "app"))}
dev-squint
{:doc "Start squint dev server (PORT env var, default 3002)"
:depends [build-theme ensure-npm]
:task (let [port (or (some-> (System/getenv "PORT") parse-long) 3002)]
(shell {:dir "dev/squint"}
"bash" "-c" (str "npx squint watch & exec npx vite --port " port)))}
dev
{:doc "Start all dev servers"
:depends [build-theme]
:requires ([dev.hiccup])
:task (let [port (or (some-> (System/getenv "PORT") parse-long) 3003)]
(dev.hiccup/start! {:port port})
(println "Dev servers running:")
(println (str " Hiccup: http://localhost:" port))
(println " Replicant: cd dev/replicant && npx shadow-cljs watch app")
(println " Squint: cd dev/squint && npm run dev")
(println " Test page: dev/index.html")
(deref (promise)))}
dev-all
{:doc "Start all dev servers in tmux panes (bb dev-all [BASE_PORT], default 3000)"
:depends [build-theme ensure-npm]
:requires ([clojure.edn :as edn])
:task (let [base (or (some-> (first *command-line-args*) parse-long) 3000)
rport (+ base 1)
sport (+ base 2)
hport (+ base 3)
session "ui-dev"
;; Write shadow-cljs.edn with the correct port before launching
cfg-path "dev/replicant/shadow-cljs.edn"
cfg (edn/read-string (slurp cfg-path))]
(spit cfg-path (pr-str (assoc cfg :dev-http {rport "public"})))
(shell {:continue true} "tmux kill-session -t" session)
(shell "tmux new-session -d -s" session
(str "PORT=" hport " bb dev-hiccup"))
(shell "tmux split-window -h -t" session
(str "bash -c 'cd dev/replicant && npx shadow-cljs watch app'"))
(shell "tmux split-window -v -t" session
(str "bash -c 'cd dev/squint && npx squint watch"
" & cd dev/squint && npx vite --port " sport "'"))
(shell "tmux select-layout -t" session "tiled")
(println (str "Tmux session 'ui-dev' created (base port " base "):"))
(println (str " Pane 0: Hiccup → http://localhost:" hport))
(println (str " Pane 1: Replicant → http://localhost:" rport))
(println (str " Pane 2: Squint → http://localhost:" sport))
(println)
(when-not (zero? (:exit (shell {:continue true} "tmux attach -t" session)))
(println "Attach with: tmux attach -t" session)))}}}