diff --git a/README.md b/README.md
index 6cdb3ed3..3c18a80b 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,7 @@
+
`poke-cli` is a hybrid of a classic CLI and a modern TUI tool for viewing VG and TCG data about Pokémon!
View the [documentation](https://docs.poke-cli.com) on the data infrastructure in [data_platform/](https://github.com/digitalghost-dev/poke-cli/tree/main/data_platform) if you're interested.
diff --git a/cmd/berry/berry.go b/cmd/berry/berry.go
index 830175ec..67936c5e 100644
--- a/cmd/berry/berry.go
+++ b/cmd/berry/berry.go
@@ -119,7 +119,7 @@ func (m model) View() tea.View {
Width(52).
Height(29).
Border(lipgloss.RoundedBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
Padding(1).
Render(selectedBerry)
@@ -158,11 +158,11 @@ func tableGeneration() error {
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
BorderBottom(true)
s.Selected = s.Selected.
Foreground(lipgloss.Color("#000")).
- Background(styling.YellowColor)
+ Background(styling.ThemeColor)
t.SetStyles(s)
m := model{table: t}
@@ -185,7 +185,7 @@ func berryContainers(name string) string {
boxStyle := lipgloss.NewStyle().
Padding(1, 2).
BorderStyle(lipgloss.ThickBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
Width(34)
// Render both without height constraints to measure natural heights.
diff --git a/cmd/berry/berry_test.go b/cmd/berry/berry_test.go
index 31b828e3..c5060664 100644
--- a/cmd/berry/berry_test.go
+++ b/cmd/berry/berry_test.go
@@ -192,11 +192,11 @@ func createTestModel() model {
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
BorderBottom(true)
s.Selected = s.Selected.
Foreground(lipgloss.Color("#000")).
- Background(styling.YellowColor)
+ Background(styling.ThemeColor)
t.SetStyles(s)
return model{table: t}
diff --git a/cmd/card/cardlist.go b/cmd/card/cardlist.go
index 58a7aef2..b7a10df0 100644
--- a/cmd/card/cardlist.go
+++ b/cmd/card/cardlist.go
@@ -48,7 +48,7 @@ type cardDataMsg struct {
}
var (
- activeTableSelectedBg color.Color = styling.YellowColor
+ activeTableSelectedBg color.Color = styling.ThemeColor
inactiveTableSelectedBg color.Color = lipgloss.Color("#808080")
)
@@ -56,10 +56,10 @@ func cardTableStyles(selectedBg color.Color) table.Styles {
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
BorderBottom(true)
s.Selected = s.Selected.
- Foreground(lipgloss.Color("#000")).
+ Foreground(styling.ContrastText(selectedBg)).
Background(selectedBg)
return s
}
@@ -297,7 +297,7 @@ func (m cardsModel) View() tea.View {
Width(42).
Height(29).
Border(lipgloss.RoundedBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
Padding(1).
Render(selectedCard)
@@ -327,7 +327,7 @@ type cardData struct {
func CardsList(setID string) (cardsModel, error) {
s := spinner.New()
s.Spinner = spinner.Dot
- s.Style = styling.Yellow
+ s.Style = styling.Theme
return cardsModel{
SetID: setID,
diff --git a/cmd/card/imageviewer.go b/cmd/card/imageviewer.go
index 1de2277e..f4817dc0 100644
--- a/cmd/card/imageviewer.go
+++ b/cmd/card/imageviewer.go
@@ -83,7 +83,7 @@ func (m imageModel) View() tea.View {
content = lipgloss.NewStyle().
Padding(2).
BorderStyle(lipgloss.RoundedBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
Render(styling.Red.Render(m.Error.Error()))
} else {
content = m.ImageData
@@ -97,7 +97,7 @@ func (m imageModel) View() tea.View {
func ImageRenderer(cardName string, imageURL string) imageModel {
s := spinner.New()
s.Spinner = spinner.Dot
- s.Style = styling.Yellow
+ s.Style = styling.Theme
return imageModel{
CardName: cardName,
diff --git a/cmd/card/setslist.go b/cmd/card/setslist.go
index 6a2d60fc..1550bd93 100644
--- a/cmd/card/setslist.go
+++ b/cmd/card/setslist.go
@@ -174,7 +174,7 @@ type setData struct {
func SetsList(seriesID string) (setsModel, error) {
s := spinner.New()
s.Spinner = spinner.Dot
- s.Style = styling.Yellow
+ s.Style = styling.Theme
return setsModel{
SeriesName: seriesID,
diff --git a/cmd/comp/champions/tab_components.go b/cmd/comp/champions/tab_components.go
index 8d0e695e..1434f873 100644
--- a/cmd/comp/champions/tab_components.go
+++ b/cmd/comp/champions/tab_components.go
@@ -68,7 +68,7 @@ func renderPokemonDetail(row compInfoRow, width int) string {
teammates := renderStatColumn("Common Teammates", row.CommonTeammates, colWidth)
var b strings.Builder
- b.WriteString(styling.Yellow.Render(row.Pokemon))
+ b.WriteString(styling.Theme.Render(row.Pokemon))
b.WriteString("\n\n")
b.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, moves, " ", items))
b.WriteString("\n\n")
@@ -231,7 +231,7 @@ func renderTeamDetail(team teamRow, width int) string {
var b strings.Builder
title := fmt.Sprintf("%s (%s)", team.Player, team.Record)
- b.WriteString(styling.Yellow.Render("Selected Team"))
+ b.WriteString(styling.Theme.Render("Selected Team"))
b.WriteString("\n")
b.WriteString(styling.StyleBold.Render(title))
b.WriteString("\n")
@@ -392,7 +392,7 @@ func selectedSpeedTier(speedTable table.Model, rows []speedTierRow) speedTierRow
func renderSpeedDetail(row speedTierRow) string {
var b strings.Builder
- b.WriteString(styling.Yellow.Render("Selected Pokémon"))
+ b.WriteString(styling.Theme.Render("Selected Pokémon"))
b.WriteString("\n")
b.WriteString(styling.StyleBold.Render(row.Pokemon))
diff --git a/cmd/comp/shell/dashboard.go b/cmd/comp/shell/dashboard.go
index df7c926d..6c89b9c2 100644
--- a/cmd/comp/shell/dashboard.go
+++ b/cmd/comp/shell/dashboard.go
@@ -6,6 +6,7 @@ import (
"charm.land/bubbles/v2/table"
tea "charm.land/bubbletea/v2"
"github.com/digitalghost-dev/poke-cli/cmd/utils"
+ "github.com/digitalghost-dev/poke-cli/styling"
)
type dashboardModel struct {
@@ -139,7 +140,7 @@ func (m dashboardModel) renderTab(contentWidth int) string {
}
switch m.activeTab {
case 0:
- return m.decoded.Overview(contentWidth, m.styles.HighlightColor)
+ return m.decoded.Overview(contentWidth, styling.ThemeColor)
case 1:
return m.table.View()
case 2:
diff --git a/cmd/comp/shell/frame.go b/cmd/comp/shell/frame.go
index 9059673b..68b125b1 100644
--- a/cmd/comp/shell/frame.go
+++ b/cmd/comp/shell/frame.go
@@ -45,7 +45,7 @@ func (s *Styles) Render(tabs []string, activeTab, width int, renderContent func(
fillWidth := windowWidth - lipgloss.Width(row)
if fillWidth > 0 {
- fill := lipgloss.NewStyle().Foreground(s.HighlightColor).
+ fill := lipgloss.NewStyle().Foreground(styling.ThemeColor).
Render(strings.Repeat("─", fillWidth-1) + "┐")
row = row + fill
}
@@ -65,11 +65,11 @@ func TableStyles() table.Styles {
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
BorderBottom(true).
Bold(true)
s.Selected = s.Selected.
- Foreground(lipgloss.Color("#000")).
- Background(styling.YellowColor)
+ Foreground(styling.ContrastText(styling.ThemeColor)).
+ Background(styling.ThemeColor)
return s
}
diff --git a/cmd/comp/shell/frame_test.go b/cmd/comp/shell/frame_test.go
index ffe935e9..01089052 100644
--- a/cmd/comp/shell/frame_test.go
+++ b/cmd/comp/shell/frame_test.go
@@ -10,9 +10,6 @@ func TestNewStyles(t *testing.T) {
if s == nil {
t.Fatal("expected non-nil styles")
}
- if s.HighlightColor == nil {
- t.Error("expected highlight color to be set")
- }
}
func TestRender_ContainsTabsContentAndMenu(t *testing.T) {
diff --git a/cmd/comp/shell/picker.go b/cmd/comp/shell/picker.go
index 64b089e0..95108164 100644
--- a/cmd/comp/shell/picker.go
+++ b/cmd/comp/shell/picker.go
@@ -22,6 +22,7 @@ type pickerModel struct {
tournaments []TournamentRef
selected *TournamentRef
error error
+ goBack bool
list list.Model
loading bool
spinner spinner.Model
@@ -52,7 +53,7 @@ func fetchTournaments(listURL string, conn ConnFunc) tea.Cmd {
func newPicker(spec Spec, conn ConnFunc) pickerModel {
s := spinner.New()
s.Spinner = spinner.Dot
- s.Style = styling.Yellow
+ s.Style = styling.Theme
return pickerModel{
conn: conn,
@@ -76,6 +77,9 @@ func (m pickerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case "ctrl+c", "esc":
m.quitting = true
return m, tea.Quit
+ case "b":
+ m.goBack = true
+ return m, tea.Quit
case "w":
return m, utils.Open("https://web.poke-cli.com/")
case "enter":
@@ -112,12 +116,16 @@ func (m pickerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
l.Styles.PaginationStyle = styling.PaginationStyle
l.Styles.HelpStyle = styling.HelpStyle
+ backBinding := key.NewBinding(
+ key.WithKeys("b"),
+ key.WithHelp("b", "back"),
+ )
webBinding := key.NewBinding(
key.WithKeys("w"),
key.WithHelp("w", "web"),
)
- l.AdditionalShortHelpKeys = func() []key.Binding { return []key.Binding{webBinding} }
- l.AdditionalFullHelpKeys = func() []key.Binding { return []key.Binding{webBinding} }
+ l.AdditionalShortHelpKeys = func() []key.Binding { return []key.Binding{backBinding, webBinding} }
+ l.AdditionalFullHelpKeys = func() []key.Binding { return []key.Binding{backBinding, webBinding} }
m.list = l
m.loading = false
diff --git a/cmd/comp/shell/run.go b/cmd/comp/shell/run.go
index 84e64bc4..7479191b 100644
--- a/cmd/comp/shell/run.go
+++ b/cmd/comp/shell/run.go
@@ -59,10 +59,7 @@ func Run(spec Spec, conn ConnFunc) (back bool, err error) {
return result, nil
}
- if err := loop(spec, conn, runPicker, runDashboard); err != nil {
- return false, err
- }
- return true, nil
+ return loop(spec, conn, runPicker, runDashboard)
}
func loop(
@@ -70,25 +67,24 @@ func loop(
conn ConnFunc,
runPicker func(pickerModel) (pickerModel, error),
runDashboard func(dashboardModel) (dashboardModel, error),
-) error {
+) (back bool, err error) {
for {
result, err := runPicker(newPicker(spec, conn))
if err != nil {
- return fmt.Errorf("error running tournament selection program: %w", err)
+ return false, fmt.Errorf("error running tournament selection program: %w", err)
}
if result.selected == nil {
- break
+ return result.goBack, nil
}
dash, err := runDashboard(newDashboard(spec, conn, result.selected.Location))
if err != nil {
- return fmt.Errorf("error running dashboard program: %w", err)
+ return false, fmt.Errorf("error running dashboard program: %w", err)
}
if !dash.goBack {
- break
+ return false, nil
}
}
- return nil
}
func FormatInt(n int) string {
diff --git a/cmd/comp/shell/run_test.go b/cmd/comp/shell/run_test.go
index dbca0957..6450a232 100644
--- a/cmd/comp/shell/run_test.go
+++ b/cmd/comp/shell/run_test.go
@@ -66,11 +66,19 @@ func TestLoop_NoTournamentSelected(t *testing.T) {
dashCalled = true
return dashboardModel{}, nil
}
- err := loop(testSpec(), noopConn, runPicker, runDashboard)
+ back, err := loop(testSpec(), noopConn, runPicker, runDashboard)
require.NoError(t, err)
+ require.False(t, back, "esc/quit from the picker should not return to the selection menu")
require.False(t, dashCalled, "dashboard should not launch when no tournament is selected")
}
+func TestLoop_PickerGoBack_ReturnsBack(t *testing.T) {
+ runPicker := func(_ pickerModel) (pickerModel, error) { return pickerModel{selected: nil, goBack: true}, nil }
+ back, err := loop(testSpec(), noopConn, runPicker, nil)
+ require.NoError(t, err)
+ require.True(t, back, "pressing b in the picker should return to the selection menu")
+}
+
func TestLoop_TournamentSelected_DashboardExits(t *testing.T) {
td := TournamentRef{Location: "London"}
runPicker := func(_ pickerModel) (pickerModel, error) { return pickerModel{selected: &td}, nil }
@@ -78,7 +86,9 @@ func TestLoop_TournamentSelected_DashboardExits(t *testing.T) {
assert.Equal(t, "London", m.tournament)
return dashboardModel{goBack: false}, nil
}
- assert.NoError(t, loop(testSpec(), noopConn, runPicker, runDashboard))
+ back, err := loop(testSpec(), noopConn, runPicker, runDashboard)
+ require.NoError(t, err)
+ assert.False(t, back, "quitting the dashboard should not return to the selection menu")
}
func TestLoop_GoBack_LoopsToPicker(t *testing.T) {
@@ -92,13 +102,15 @@ func TestLoop_GoBack_LoopsToPicker(t *testing.T) {
return pickerModel{selected: nil}, nil
}
runDashboard := func(_ dashboardModel) (dashboardModel, error) { return dashboardModel{goBack: true}, nil }
- require.NoError(t, loop(testSpec(), noopConn, runPicker, runDashboard))
+ back, err := loop(testSpec(), noopConn, runPicker, runDashboard)
+ require.NoError(t, err)
+ require.False(t, back)
require.Equal(t, 2, calls, "expected the picker to run twice")
}
func TestLoop_PickerError(t *testing.T) {
runPicker := func(_ pickerModel) (pickerModel, error) { return pickerModel{}, errors.New("boom") }
- err := loop(testSpec(), noopConn, runPicker, nil)
+ _, err := loop(testSpec(), noopConn, runPicker, nil)
assert.ErrorContains(t, err, "tournament selection")
}
@@ -108,5 +120,6 @@ func TestLoop_DashboardError(t *testing.T) {
runDashboard := func(_ dashboardModel) (dashboardModel, error) {
return dashboardModel{}, errors.New("boom")
}
- assert.ErrorContains(t, loop(testSpec(), noopConn, runPicker, runDashboard), "dashboard")
+ _, err := loop(testSpec(), noopConn, runPicker, runDashboard)
+ assert.ErrorContains(t, err, "dashboard")
}
diff --git a/cmd/comp/shell/styles.go b/cmd/comp/shell/styles.go
index 0b605e6f..24e33dd4 100644
--- a/cmd/comp/shell/styles.go
+++ b/cmd/comp/shell/styles.go
@@ -1,18 +1,15 @@
package shell
import (
- "image/color"
-
"charm.land/lipgloss/v2"
"github.com/digitalghost-dev/poke-cli/styling"
)
type Styles struct {
- Doc lipgloss.Style
- InactiveTab lipgloss.Style
- ActiveTab lipgloss.Style
- Window lipgloss.Style
- HighlightColor color.Color
+ Doc lipgloss.Style
+ InactiveTab lipgloss.Style
+ ActiveTab lipgloss.Style
+ Window lipgloss.Style
}
func tabBorderWithBottom(left, middle, right string) lipgloss.Border {
@@ -26,24 +23,20 @@ func tabBorderWithBottom(left, middle, right string) lipgloss.Border {
func NewStyles() *Styles {
inactiveTabBorder := tabBorderWithBottom("┴", "─", "┴")
activeTabBorder := tabBorderWithBottom("┘", " ", "└")
- isDark := styling.HasDarkBackground()
- ld := lipgloss.LightDark(isDark)
- highlightColor := ld(lipgloss.Color("#874BFD"), lipgloss.Color("#7D56F4"))
s := new(Styles)
s.Doc = lipgloss.NewStyle().
Padding(1, 2, 1, 2)
s.InactiveTab = lipgloss.NewStyle().
Border(inactiveTabBorder, true).
- BorderForeground(highlightColor).
+ BorderForeground(styling.ThemeColor).
Padding(0, 1)
s.ActiveTab = s.InactiveTab.
Border(activeTabBorder, true)
s.Window = lipgloss.NewStyle().
- BorderForeground(highlightColor).
+ BorderForeground(styling.ThemeColor).
Padding(2, 0).
Border(lipgloss.NormalBorder()).
UnsetBorderTop()
- s.HighlightColor = highlightColor
return s
}
diff --git a/cmd/speed/speed.go b/cmd/speed/speed.go
index 75805dc7..8cc7b956 100644
--- a/cmd/speed/speed.go
+++ b/cmd/speed/speed.go
@@ -300,18 +300,18 @@ func formula() (string, error) {
finalSpeedStr := fmt.Sprintf("%.0f", finalSpeedFloor)
header := fmt.Sprintf("%s at level %s with selected options has a current speed of %s.",
- styling.Yellow.Render(chosenPokemon),
- styling.Yellow.Render(pokemon.Level),
- styling.Yellow.Render(finalSpeedStr),
+ styling.Theme.Render(chosenPokemon),
+ styling.Theme.Render(pokemon.Level),
+ styling.Theme.Render(finalSpeedStr),
)
body := fmt.Sprintf("EVs: %s\nIVs: %s\nModifiers: %s\nNature: %s\nAbility: %s\nSpeed Stage: %s\nBase Speed: %s",
- styling.Yellow.Render(pokemon.SpeedEV),
- styling.Yellow.Render(pokemon.SpeedIV),
- styling.Yellow.Render(xstrings.EnglishJoin(pokemon.Modifier, true)),
- styling.Yellow.Render(pokemon.Nature),
- styling.Yellow.Render(pokemon.Ability),
- styling.Yellow.Render(pokemon.SpeedStage),
- styling.Yellow.Render(speedStr),
+ styling.Theme.Render(pokemon.SpeedEV),
+ styling.Theme.Render(pokemon.SpeedIV),
+ styling.Theme.Render(xstrings.EnglishJoin(pokemon.Modifier, true)),
+ styling.Theme.Render(pokemon.Nature),
+ styling.Theme.Render(pokemon.Ability),
+ styling.Theme.Render(pokemon.SpeedStage),
+ styling.Theme.Render(speedStr),
)
isDark := styling.HasDarkBackground()
diff --git a/cmd/types/types.go b/cmd/types/types.go
index 4854cd38..6beef04f 100644
--- a/cmd/types/types.go
+++ b/cmd/types/types.go
@@ -120,11 +120,11 @@ func createTypeSelectionTable() model {
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
BorderBottom(true)
s.Selected = s.Selected.
- Foreground(lipgloss.Color("#000")).
- Background(styling.YellowColor)
+ Foreground(styling.ContrastText(styling.ThemeColor)).
+ Background(styling.ThemeColor)
tbl.SetStyles(s)
return model{table: tbl}
diff --git a/cmd/types/types_test.go b/cmd/types/types_test.go
index 463beb0d..f7259a78 100644
--- a/cmd/types/types_test.go
+++ b/cmd/types/types_test.go
@@ -75,11 +75,11 @@ func createTestModel() model {
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
BorderBottom(true)
s.Selected = s.Selected.
Foreground(lipgloss.Color("#000")).
- Background(styling.YellowColor)
+ Background(styling.ThemeColor)
t.SetStyles(s)
return model{table: t}
diff --git a/flags/pokemon_flagset.go b/flags/pokemon_flagset.go
index 5898846f..edcb051f 100644
--- a/flags/pokemon_flagset.go
+++ b/flags/pokemon_flagset.go
@@ -44,7 +44,7 @@ func header(header string) string {
HeaderBold := lipgloss.NewStyle().
BorderStyle(lipgloss.NormalBorder()).
- BorderForeground(styling.YellowColor).
+ BorderForeground(styling.ThemeColor).
BorderTop(true).
Bold(true).
Render(header)
diff --git a/setup/setup.go b/setup/setup.go
index 09b1bd4e..ef5913b5 100644
--- a/setup/setup.go
+++ b/setup/setup.go
@@ -135,7 +135,7 @@ func (m model) View() tea.View {
line := lipgloss.NewStyle().Render(label + " " + value)
if m.cursor == focused {
cursor = "> "
- line = styling.Yellow.Render(label + " " + value)
+ line = styling.Theme.Render(label + " " + value)
}
return cursor + line
}
@@ -155,7 +155,7 @@ func (m model) View() tea.View {
status := "poke-cache: " + cache
panel := lipgloss.NewStyle().Border(lipgloss.RoundedBorder()).
- BorderForeground(styling.YellowColor).Padding(1, 2)
+ BorderForeground(styling.ThemeColor).Padding(1, 2)
body := lipgloss.JoinVertical(lipgloss.Left, panel.Render(settings), panel.Render(status))
diff --git a/styling/styling.go b/styling/styling.go
index e69a63dd..908eb5ea 100644
--- a/styling/styling.go
+++ b/styling/styling.go
@@ -23,17 +23,13 @@ var palettes = map[string]string{
var accent string
-var (
- YellowColor color.Color
- YellowAdaptive color.Color
- YellowAdaptive2 color.Color
-)
+var ThemeColor color.Color
var (
Green = lipgloss.NewStyle().Foreground(lipgloss.Color("#38B000"))
Red = lipgloss.NewStyle().Foreground(lipgloss.Color("#D00000"))
Gray = lipgloss.Color("#777777")
- Yellow lipgloss.Style
+ Theme lipgloss.Style
ColoredBullet lipgloss.Style
CheckboxStyle lipgloss.Style
KeyMenu = lipgloss.NewStyle().Foreground(lipgloss.Color("#777777"))
@@ -87,10 +83,8 @@ func ApplyTheme(name string) {
accent = hex
c := lipgloss.Color(hex)
- YellowColor = c
- YellowAdaptive = c
- YellowAdaptive2 = c
- Yellow = lipgloss.NewStyle().Foreground(c)
+ ThemeColor = c
+ Theme = lipgloss.NewStyle().Foreground(c)
ColoredBullet = lipgloss.NewStyle().SetString("•").Foreground(c)
CheckboxStyle = lipgloss.NewStyle().Foreground(c)
HelpBorder = lipgloss.NewStyle().
@@ -189,3 +183,15 @@ func (col Color) Hex() string {
return fmt.Sprintf("#%02x%02x%02x",
uint8(col.R*255.0+0.5), uint8(col.G*255.0+0.5), uint8(col.B*255.0+0.5))
}
+
+func ContrastText(bg color.Color) color.Color {
+ c, ok := MakeColor(bg)
+ if !ok {
+ return lipgloss.Color("#000")
+ }
+ luma := 0.299*c.R + 0.587*c.G + 0.114*c.B
+ if luma > 0.5 {
+ return lipgloss.Color("#000")
+ }
+ return lipgloss.Color("#FFF")
+}
diff --git a/styling/styling_test.go b/styling/styling_test.go
index 52bc3ad3..f94239be 100644
--- a/styling/styling_test.go
+++ b/styling/styling_test.go
@@ -2,9 +2,11 @@ package styling
import (
"fmt"
- "github.com/stretchr/testify/assert"
"image/color"
"testing"
+
+ "charm.land/lipgloss/v2"
+ "github.com/stretchr/testify/assert"
)
func TestGetTypeColor(t *testing.T) {
@@ -119,13 +121,34 @@ func TestApplyThemeSwapsAndFallsBack(t *testing.T) {
t.Cleanup(func() { ApplyTheme("yellow") })
ApplyTheme("red")
- redColor := YellowColor
+ redColor := ThemeColor
assert.Equal(t, "#f00000", accent)
ApplyTheme("blue")
assert.Equal(t, "#3B4CCA", accent)
- assert.NotEqual(t, redColor, YellowColor)
+ assert.NotEqual(t, redColor, ThemeColor)
ApplyTheme("bogus")
assert.Equal(t, "#E1AD01", accent)
}
+
+func TestContrastText(t *testing.T) {
+ black := lipgloss.Color("#000")
+ white := lipgloss.Color("#FFF")
+ tests := []struct {
+ name string
+ bg string
+ want color.Color
+ }{
+ {"yellow theme", palettes["yellow"], black},
+ {"red theme", palettes["red"], white},
+ {"blue theme", palettes["blue"], white},
+ {"pure white", "#FFFFFF", black},
+ {"pure black", "#000000", white},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ assert.Equal(t, tt.want, ContrastText(lipgloss.Color(tt.bg)))
+ })
+ }
+}