feat: add icon support to button, alert, badge, and form input

Button:
- :icon-left, :icon-right props for buttons with leading/trailing icons
- :icon prop for icon-only buttons (square padding via .btn-icon class)
- Icon size scales with button size (sm→sm, md/lg→sm/md)

Alert:
- Auto-assigns variant-specific icons (circle-check, alert-triangle,
  alert-circle, info) per variant
- :icon-name prop to override default, false to suppress
- Layout restructured with .alert-icon + .alert-content wrapper

Badge:
- :icon-name prop adds a leading icon before text
- .badge-icon CSS scales icon to match badge font size

Form input:
- :icon-left and :icon-right props on form-input
- Wraps input in .form-input-wrap with absolutely-positioned icon spans
- Padding adjusts automatically via .form-input--icon-left/right

All three dev targets (hiccup, replicant, squint) updated with demos.
This commit is contained in:
Florian Schroedl
2026-03-05 19:33:55 +01:00
parent e3132a3cb4
commit 93edebf144
15 changed files with 438 additions and 122 deletions

View File

@@ -78,7 +78,19 @@
[(button/button {:variant "primary" :href "#"} "Link primary")
(button/button {:variant "secondary" :href "#"} "Link secondary")
(button/button {:variant "link"} "Link button")
(button/button {:variant "link" :href "https://example.com"} "Link with href")])))
(button/button {:variant "link" :href "https://example.com"} "Link with href")])
(into [:div {:style {"display" "flex" "gap" "0.75rem" "flex-wrap" "wrap" "align-items" "center"}}]
[(button/button {:variant "primary" :icon-left "plus"} "Add item")
(button/button {:variant "secondary" :icon-right "arrow-right"} "Next")
(button/button {:variant "primary" :icon-left "download" :icon-right "arrow-down"} "Download")
(button/button {:variant "ghost" :icon-left "edit"} "Edit")])
(into [:div {:style {"display" "flex" "gap" "0.75rem" "flex-wrap" "wrap" "align-items" "center"}}]
[(button/button {:variant "primary" :icon "plus"})
(button/button {:variant "secondary" :icon "search"})
(button/button {:variant "ghost" :icon "settings"})
(button/button {:variant "danger" :icon "trash"})
(button/button {:variant "primary" :icon "plus" :size "sm"})
(button/button {:variant "primary" :icon "plus" :size "lg"})])))
(defn alert-demo []
(section "Alert"
@@ -96,7 +108,12 @@
(badge/badge {:variant "outline"} "Outline")
(badge/badge {:variant "success"} "Success")
(badge/badge {:variant "warning"} "Warning")
(badge/badge {:variant "danger"} "Danger")])))
(badge/badge {:variant "danger"} "Danger")])
(into [:div {:style {"display" "flex" "gap" "0.5rem" "flex-wrap" "wrap" "align-items" "center"}}]
[(badge/badge {:icon-name "check" :variant "success"} "Verified")
(badge/badge {:icon-name "star"} "Featured")
(badge/badge {:icon-name "alert-triangle" :variant "warning"} "Caution")
(badge/badge {:icon-name "clock" :variant "secondary"} "Pending")])))
(defn card-demo []
(section "Card"
@@ -253,6 +270,10 @@
(form/form-input {:type "datetime-local"}))
(form/form-field {:label "Date"}
(form/form-input {:type "date"}))
(form/form-field {:label "Search (icon left)"}
(form/form-input {:type "text" :placeholder "Search..." :icon-left "search"}))
(form/form-field {:label "URL (both icons)"}
(form/form-input {:type "text" :placeholder "example.com" :icon-left "globe" :icon-right "check"}))
(form/form-checkbox {:label "I agree to the terms"})
(form/form-radio-group {:label "Preference"
:radio-name "pref"