refactor: replace BEM with utility classes, move component CSS to files
- Rename CSS classes from BEM double-dash (btn--primary) to flat utility-style single-dash (btn-primary) - Move button CSS from inline Clojure string in gen.clj to src/ui/button.css next to button.cljc - gen.clj now auto-collects all src/ui/*.css files via babashka.fs glob - Replace clojure.java.io with babashka.fs throughout gen.clj - Update AGENTS.md to reflect new conventions
This commit is contained in:
@@ -11,12 +11,12 @@
|
||||
|
||||
(defn button-class-list
|
||||
"Generate a vector of CSS class strings for a button given variant and size.
|
||||
Returns e.g. [\"btn\" \"btn--primary\" \"btn--lg\"]."
|
||||
Returns e.g. [\"btn\" \"btn-primary\" \"btn-lg\"]."
|
||||
[{:keys [variant size]}]
|
||||
(let [v (or (some-> variant kw-name) default-variant)
|
||||
s (or (some-> size kw-name) default-size)]
|
||||
(cond-> ["btn" (str "btn--" v)]
|
||||
(not= s "md") (conj (str "btn--" s)))))
|
||||
(cond-> ["btn" (str "btn-" v)]
|
||||
(not= s "md") (conj (str "btn-" s)))))
|
||||
|
||||
(defn button-classes
|
||||
"Generate CSS class string for a button. Returns a space-joined string."
|
||||
|
||||
65
src/ui/button.css
Normal file
65
src/ui/button.css
Normal file
@@ -0,0 +1,65 @@
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5em;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.25rem;
|
||||
border: none;
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
transition: background-color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--accent);
|
||||
color: var(--fg-on-accent);
|
||||
}
|
||||
.btn-primary:hover:not(:disabled) {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--bg-1);
|
||||
color: var(--fg-0);
|
||||
border: var(--border-0);
|
||||
}
|
||||
.btn-secondary:hover:not(:disabled) {
|
||||
background: var(--bg-2);
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--fg-0);
|
||||
}
|
||||
.btn-ghost:hover:not(:disabled) {
|
||||
background: var(--bg-1);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: var(--danger);
|
||||
color: var(--fg-on-danger);
|
||||
}
|
||||
.btn-danger:hover:not(:disabled) {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
(ns ui.css.gen
|
||||
(:require [clojure.edn :as edn]
|
||||
[clojure.java.io :as io]
|
||||
(:require [babashka.fs :as fs]
|
||||
[clojure.edn :as edn]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defn read-tokens
|
||||
@@ -32,68 +32,13 @@
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
}")
|
||||
|
||||
(defn component-css-button
|
||||
"Generate BEM-lite CSS for the button component."
|
||||
[]
|
||||
(str/join "\n\n"
|
||||
[".btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5em;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.25rem;
|
||||
border: none;
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
transition: background-color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
|
||||
font-family: inherit;
|
||||
}"
|
||||
".btn--primary {
|
||||
background: var(--accent);
|
||||
color: var(--fg-on-accent);
|
||||
}
|
||||
.btn--primary:hover:not(:disabled) {
|
||||
filter: brightness(1.1);
|
||||
}"
|
||||
".btn--secondary {
|
||||
background: var(--bg-1);
|
||||
color: var(--fg-0);
|
||||
border: var(--border-0);
|
||||
}
|
||||
.btn--secondary:hover:not(:disabled) {
|
||||
background: var(--bg-2);
|
||||
}"
|
||||
".btn--ghost {
|
||||
background: transparent;
|
||||
color: var(--fg-0);
|
||||
}
|
||||
.btn--ghost:hover:not(:disabled) {
|
||||
background: var(--bg-1);
|
||||
}"
|
||||
".btn--danger {
|
||||
background: var(--danger);
|
||||
color: var(--fg-on-danger);
|
||||
}
|
||||
.btn--danger:hover:not(:disabled) {
|
||||
filter: brightness(1.1);
|
||||
}"
|
||||
".btn--sm {
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
}"
|
||||
".btn--lg {
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5rem;
|
||||
}"
|
||||
".btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}"]))
|
||||
(defn collect-component-css
|
||||
"Read all .css files from the component source directory."
|
||||
[dir]
|
||||
(->> (fs/glob dir "*.css")
|
||||
(sort-by fs/file-name)
|
||||
(map #(slurp (str %)))
|
||||
(str/join "\n\n")))
|
||||
|
||||
(defn generate-css
|
||||
"Generate the full CSS output from parsed token data."
|
||||
@@ -106,7 +51,7 @@
|
||||
(str/replace (tokens->css-block dark-tokens) #"(?m)^ " " ")
|
||||
"\n }\n}")
|
||||
base (base-css)
|
||||
components (component-css-button)]
|
||||
components (collect-component-css "src/ui")]
|
||||
(str/join "\n\n" [root-block dark-attr dark-media base components ""])))
|
||||
|
||||
(defn build-theme!
|
||||
@@ -114,6 +59,6 @@
|
||||
[{:keys [input output]}]
|
||||
(let [token-data (read-tokens input)
|
||||
css (generate-css token-data)]
|
||||
(io/make-parents output)
|
||||
(fs/create-dirs (fs/parent output))
|
||||
(spit output css)
|
||||
(println (str "Generated " output " (" (count (str/split-lines css)) " lines)"))))
|
||||
|
||||
Reference in New Issue
Block a user