Keep Button state presentation themeable

This commit is contained in:
Kinneyzhang 2026-08-22 10:19:16 +08:00
parent 0701bc76bb
commit 058bcab2a7
2 changed files with 44 additions and 7 deletions

View File

@ -254,6 +254,9 @@ SELECTED-KEY, and ROW-SELECTED-P provide interaction state."
(variant (and (not disabled) (etaf-current-prop :variant)))
(variant-values
(cond
(disabled
'(:color "#687386" :bgcolor "#E5E7EB"
:border ((1) solid "#9CA3AF") :face normal))
((and (eq variant 'secondary) state-pressed)
'(:color "#142235" :bgcolor "#B9DED7"
:border ((1) solid "#24736C") :face bold))
@ -265,7 +268,16 @@ SELECTED-KEY, and ROW-SELECTED-P provide interaction state."
:border ((1) solid "#A79F93") :face normal))
((eq variant 'ghost)
'(:color "#142235" :bgcolor "#FFFDF8"
:border ((1) solid "#C8C1B6") :face normal)))))
:border ((1) solid "#C8C1B6") :face normal))
;; The enabled/pressed catalog defaults used to come from
;; state selectors alone. Resolve them as props too so an
;; explicit theme can override the same state boundary.
(state-pressed
'(:color "#FFFFFF" :bgcolor "#1E5A56"
:border ((1) solid "#174A47") :face bold))
(t
'(:color "#FFFFFF" :bgcolor "#2F6B43"
:border ((1) solid "#2F6B43") :face bold)))))
(etaf-ui--button-view
label (and press-p press) disabled (etaf-current-prop :ref)
(let ((custom-class (etaf-current-prop :class)))
@ -295,12 +307,12 @@ contract; callers can still override presentation with the ordinary props."
:styles
(styles
("&" :width max-content)
("&.disabled" :color "#687386" :bgcolor "#E5E7EB"
:border ((1) solid "#9CA3AF") :padding (0 1) :face normal)
("&.enabled" :color "#FFFFFF" :bgcolor "#2F6B43"
:border ((1) solid "#2F6B43") :padding (0 1) :face bold)
("&.pressed" :color "#FFFFFF" :bgcolor "#1E5A56"
:border ((1) solid "#174A47") :padding (0 1) :face bold))
;; State classes carry semantic state only. Resolved presentation props
;; above remain authoritative, so a themed disabled Button cannot inherit
;; the catalog's light default surface.
("&.disabled" :padding (0 1) :face normal)
("&.enabled" :padding (0 1) :face bold)
("&.pressed" :padding (0 1) :face bold))
:setup
(etaf-ui--button-setup))

View File

@ -185,6 +185,31 @@
(when-let ((buffer (get-buffer buffer-name)))
(kill-buffer buffer)))))
(ert-deftest etaf-ui-button-disabled-preserves-explicit-theme-surface ()
"A disabled Button keeps explicit dark presentation props in its surface."
(let ((buffer-name " *etaf-ui-themed-disabled-button-test*"))
(unwind-protect
(progn
(etaf-mount
buffer-name
(etaf-view
(button :label "Unavailable" :ref 'themed-disabled
:disabled t :color "#F4F7FF" :bgcolor "#202C42"
:border "#34435A")))
(let ((position
(with-current-buffer buffer-name
(goto-char (point-min))
(search-forward "Unavailable")
(1- (point)))))
(with-current-buffer buffer-name
(let ((face (get-text-property position 'face)))
(should (string-match-p "#202C42" (format "%S" face)))
(should (string-match-p "#F4F7FF" (format "%S" face))))))
(when-let ((runtime (etaf-runtime-for-buffer buffer-name)))
(etaf-unmount runtime))
(when-let ((buffer (get-buffer buffer-name)))
(kill-buffer buffer))))))
(ert-deftest etaf-ui-button-owns-pointer-hover-and-pressed-feedback ()
"Buttons expose native pointer/hover affordances and a pressed state."
(let ((buffer-name " *etaf-ui-button-surface-test*")