Skip to content

Commit 8c60b4f

Browse files
committed
Auto-emit one-arg render-fn, process defrules correctly, make emitting token values optional
1 parent bb3793b commit 8c60b4f

File tree

3 files changed

+81
-26
lines changed

3 files changed

+81
-26
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
## Added
44

55
- Support docstrings, they come after the tagname, before any styles or tokens
6+
- If there's only a zero-arg render function (fn-tail), also emit a one-arg
7+
version that takes HTML attributes to be merged in.
8+
- Add `defrules`, for general garden CSS rules
9+
- Add `defprop`, for CSS custom properties (aka variables)
10+
- Add `defutil`, for standalone utility classes
11+
- Add `import-tokens!`, for importing W3C design token JSON files as properties (as per `defprop`)
612

713
## Fixed
814

@@ -94,4 +100,4 @@
94100

95101
## Added
96102

97-
- Initial implementation
103+
- Initial implementation

notebooks/ornament_next.clj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@
4444
[:* {:box-sizing "border-box"}]
4545
[:form :mx-2])
4646

47+
;; Ornament features like tailwing utilities or referencing components work here
48+
;; too.
49+
50+
(o/defstyled menu :nav
51+
:hidden)
52+
53+
(o/defrules toggle-menu
54+
[:body.menu-open
55+
[menu :block]])
56+
57+
(o/defined-garden)
58+
4759
;; ## defutil
4860

4961
;; There's now also `defutil` for defining utility classes. This is in a way

src/lambdaisland/ornament.cljc

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@
232232
(into [] tag)
233233
[(cond
234234
(= ::styled (type tag))
235-
(classname tag)
235+
(str "." (classname tag))
236236
(sequential? tag)
237237
(process-rule tag)
238238
:else
@@ -361,6 +361,9 @@
361361
names."
362362
[classes class]
363363
(cond
364+
(nil? class)
365+
classes
366+
364367
(sequential? class)
365368
(reduce add-class classes class)
366369

@@ -416,24 +419,30 @@
416419
(reduce merge-attrs (merge-attrs p1 p2) ps)))
417420

418421
(defn attr-add-class [attrs class]
419-
(update attrs :class add-class class))
422+
(if class
423+
(update attrs :class add-class class)
424+
attrs))
420425

421426
(defn expand-hiccup-tag-simple
422427
"Expand an ornament component being called directly with child elements, without
423428
custom render function."
424429
[tag css-class children extra-attrs]
425-
(if (sequential? children)
426-
(as-> children $
427-
(if (= :<> (first $)) (next $) $)
428-
(if (map? (first $))
429-
(into [tag (attr-add-class
430-
(merge-attrs (first $) (meta children) extra-attrs)
431-
css-class)] (next $))
432-
(into [tag (attr-add-class
433-
(merge-attrs (meta children) extra-attrs)
434-
css-class)]
435-
(if (vector? $) (list $) $))))
436-
[tag (attr-add-class extra-attrs css-class) children]))
430+
(let [[tag attrs children :as result]
431+
(if (sequential? children)
432+
(as-> children $
433+
(if (= :<> (first $)) (next $) $)
434+
(if (map? (first $))
435+
(into [tag (attr-add-class
436+
(merge-attrs (first $) (meta children) extra-attrs)
437+
css-class)] (next $))
438+
(into [tag (attr-add-class
439+
(merge-attrs (meta children) extra-attrs)
440+
css-class)]
441+
(if (vector? $) (list $) $))))
442+
[tag (attr-add-class extra-attrs css-class) children])]
443+
(if (= :<> (first children))
444+
(recur tag nil children attrs)
445+
result)))
437446

438447
(defn expand-hiccup-tag
439448
"Handle expanding/rendering the component to Hiccup
@@ -663,6 +672,12 @@
663672
(when (symbol? tagname)
664673
(:fn-tails (get @registry (qualify-sym &env tagname)))))
665674

675+
fn-tails (when (seq fn-tails)
676+
(if (and (= 1 (count fn-tails))
677+
(= 0 (count (ffirst fn-tails))))
678+
`(([] ~@(rest (first fn-tails)))
679+
([attrs#] [:<> attrs# (do ~@(rest (first fn-tails)))]))
680+
fn-tails))
666681
;; For ClojureScript support (but also used in Clojure-only), add the
667682
;; Clojure-version of the styled component to the registry directly
668683
;; during macroexpansion, so that even in a ClojureScript-only world
@@ -745,9 +760,10 @@
745760
rules
746761
(cons nil rules))
747762
varsym (qualify-sym &env rules-name)
748-
rules (eval `(do
763+
rules (process-rules
764+
(eval `(do
749765
(in-ns '~(ns-name *ns*))
750-
~(cons 'list rules)))]
766+
~(cons 'list rules))))]
751767
(register! rules-registry varsym {:rules rules})
752768
(when-not (:ns &env)
753769
`(def ~rules-name ~(render-docstring docstring rules) '~rules)))))
@@ -857,26 +873,43 @@
857873

858874
#?(:clj
859875
(defn import-tokens*!
860-
([prefix tokens]
876+
([tokens {:keys [include-values? prefix]
877+
:or {include-values? true
878+
prefix ""}}]
861879
(mapcat
862880
identity
863881
(for [[tname tdef] tokens]
864882
(let [tname (str prefix tname)
865883
{:strs [$description $value $type]} tdef
866884
more (into {} (remove (fn [[k v]] (= (first k) \$))) tdef)]
867-
(cond-> [`(defprop ~(symbol tname) ~@(when $description [$description]) ~$value)]
885+
(cond-> [`(defprop ~(symbol tname)
886+
~@(when $description [(str $description "\n\nDefault: " $value)])
887+
~@(when (and $value include-values?)
888+
[$value]))]
868889
(seq more)
869890
(into (import-tokens*! (str tname "-") more)))))))))
870891

871892
#?(:clj
872893
(defmacro import-tokens!
873-
([tokens]
874-
`(import-tokens! "" ~tokens))
875-
([prefix tokens]
876-
`(do ~@(import-tokens*! prefix (eval tokens))))))
894+
"Import a standard design tokens JSON file.
895+
Emits a sequence of `defprop`, i.e. it defines custom CSS properties (aka
896+
variables). See https://design-tokens.github.io/community-group/format/
897+
- tokens: parsed JSON, we don't bundle a parser, you have to do that yourself
898+
- opts: options map, supports `:prefix` and `:include-values?`. Has to be
899+
literal (used by the macro itself)
900+
- prefix: string prefix to add to the (clojure and CSS) var names
901+
- :include-values? false: only create the Clojure vars to access the props,
902+
don't include their definitions/values in the CSS. Presumably because you are
903+
loading CSS separately that already defines these.
904+
"
905+
([tokens & [opts]]
906+
`(do ~@(import-tokens*! (eval tokens) opts)))))
877907

878908
#?(:clj
879-
(defn defined-garden []
909+
(defn defined-garden
910+
"All CSS defined through the different Ornament facilities (defprop, defstyled,
911+
defrules), in Garden syntax. Run this through `garden.compiler/compile-css`."
912+
[]
880913
(concat
881914
(let [props (->> @props-registry
882915
vals
@@ -889,8 +922,7 @@
889922
(->> @rules-registry
890923
vals
891924
(sort-by :index)
892-
(mapcat :rules)
893-
(map process-rules))
925+
(mapcat :rules))
894926
(->> @registry
895927
vals
896928
(sort-by :index)
@@ -934,3 +966,8 @@
934966
(comment
935967
(spit "/tmp/ornament.css" (defined-styles))
936968
)
969+
(->> @rules-registry
970+
vals
971+
(sort-by :index)
972+
(mapcat :rules)
973+
process-rules)

0 commit comments

Comments
 (0)