Themes, classes and styles

run-app's #:theme gives "light", "dark" or the system's for a model, and is
set again when it changes. classed puts a view in classes, and #:styles
are rules of style: a kind and a class, and colours, a font size, a
padding and a radius. A button's rule may also give the colours while the
pointer is over it and while it is pressed; those are set on the presenter
in its template, as the Fluent theme sets its own.

Avalonia's Selectors.Class adds a class to a type-and-class selector it is
given rather than making a new one, so each style's selector is made anew.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
This commit is contained in:
Linus Björnstam 2026-10-25 18:08:34 +01:00
parent 56a01efe76
commit e3c54c4348
3 changed files with 201 additions and 11 deletions

View file

@ -32,6 +32,8 @@
(AutoCompleteBox (: Avalonia.Controls.AutoCompleteBox))
(Expander (: Avalonia.Controls.Expander))
(DockEdge (: Avalonia.Controls.Dock))
(StyledElement (: Avalonia.StyledElement))
(Classes (: Avalonia.Controls.Classes))
((Nullable %a) (: System.Nullable)))
(import/extern
@ -52,6 +54,7 @@
(dock-of (: Avalonia.Controls.DockPanel.GetDock (-> Control DockEdge)))
(children (: Avalonia.Controls.Panel.Children (-> Panel Controls) #:get))
(count (: Avalonia.Controls.Controls.Count (-> Controls int) #:get))
(classes-of (: Avalonia.StyledElement.Classes (-> StyledElement Classes) #:get))
(clr-string (: System.Convert.ToString (-> string ClrString))))
(type (: Msg (Union (: Switched bool) (: Picked string) (: Amount double) (: Dated string)
@ -81,7 +84,8 @@
(expander "More" (.open m) Opened (text "inside")) ; 5
(tooltip (text "hover me") "a tip") ; 6
(flow #:spacing 4.0 (text "a") (text "b") (text "c")) ; 7
(dock (at-top (text "top")) (text "fill")))) ; 8
(dock (at-top (text "top")) (text "fill")) ; 8
(if (.open m) (classed (text "c") "wide") (classed (text "c") "big" "red")))) ; 9
(defun (main)
(def app (start-app (Model (on #f) (pick "tea") (amount 2.0) (date "2026-10-25")
@ -127,4 +131,14 @@
(expect "a flow's children" (count (children (cast Panel (ctl '(7))))) 3)
(expect "a docked child" (written (dock-of (ctl '(8 0)))) "Top")
;; --- classes ---------------------------------------------------------------------
;; The expander was opened above, so the view has "wide" and not the others.
(def cls (classes-of (cast StyledElement (ctl '(9)))))
(defun (has-class? (: c Classes) (: name string)) (.Contains c name))
(expect "a class" (has-class? cls "wide") #t)
(expect "the classes of the last view are gone" (has-class? cls "big") #f)
(put! '(5) (cast AvaloniaProperty expanded-property) (cast Object #f))
(expect "and change with the model" (list (has-class? cls "big") (has-class? cls "red") (has-class? cls "wide"))
'(#t #t #f))
(println "bjogui inputs ok"))