Every colour was a 256-colour ANSI index hardcoded in styles.go, so changing the palette meant editing the styles themselves. This puts a semantic token set between the two: styles name roles, a theme supplies the colours. internal/theme holds the twelve tokens, the two built-ins (gruvbox-dark, the new default, and gruvbox-light) and the loader for user themes in ~/.config/terdut-tui/themes/. A user file may 'extends:' a built-in and override only what it cares about, and may shadow a built-in name to tweak it in place. Unknown keys, malformed colours and incomplete themes are refused with a message naming what went wrong. Colours are truecolor hex now: lipgloss downsamples for 256- and 16-colour terminals and honours NO_COLOR, so themes carry no fallbacks of their own. An ANSI index is still accepted for anyone who would rather follow their terminal's own palette. The 21 package-level style vars become a Styles struct on the Model, which is what rule 3 asked for all along; the four free functions in view.go take one as their first argument. The embedded bubbles components are restyled from the same tokens — otherwise a theme would leave a pink selected row and grey help text behind. Note that the table's Cell style deliberately keeps no foreground: bubbles renders cells before wrapping the row in Selected, so a colour there cuts the selection highlight short.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"git.ryuvia.com/niklas/terdut-tui/internal/api"
|
||||
"git.ryuvia.com/niklas/terdut-tui/internal/theme"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
@@ -31,7 +32,7 @@ func press(t *testing.T, m Model, key string) (Model, tea.Cmd) {
|
||||
|
||||
// sized returns a connected model with a usable window, which most handlers need.
|
||||
func sized() Model {
|
||||
m := NewModel(nil, "http://test", time.Minute)
|
||||
m := NewModel(nil, "http://test", time.Minute, theme.GruvboxDark)
|
||||
m.width, m.height = 120, 40
|
||||
m.connected = true
|
||||
return m
|
||||
@@ -690,7 +691,7 @@ func containsAll(s string, subs ...string) bool {
|
||||
// So this test must NOT touch the cursor. It reproduces the real order of
|
||||
// events: size first, data second, keys third.
|
||||
func TestSchedule_AssignWeekAfterStartupSizingDoesNotPanic(t *testing.T) {
|
||||
m := NewModel(nil, "http://test", time.Minute)
|
||||
m := NewModel(nil, "http://test", time.Minute, theme.GruvboxDark)
|
||||
m.connected = true
|
||||
m.activeSection = sectionSchedule
|
||||
m.scheduleWindow = time.Date(2026, 7, 27, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
Reference in New Issue
Block a user