From 63b0917193518c489c104fdc497208c7261c8755 Mon Sep 17 00:00:00 2001 From: Kevin Miller Date: Fri, 22 Mar 2024 10:20:24 -0500 Subject: [PATCH 1/6] fix textinput.CurrentSuggestion() panic When suggestions are not yet set CurrentSuggestion() will panic. This change fixes that with a guard and returns an empty string when there is no current suggestion. --- textinput/textinput_test.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 textinput/textinput_test.go diff --git a/textinput/textinput_test.go b/textinput/textinput_test.go new file mode 100644 index 0000000..27a7640 --- /dev/null +++ b/textinput/textinput_test.go @@ -0,0 +1,32 @@ +package textinput + +import ( + "testing" +) + +func Test_CurrentSuggestion(t *testing.T) { + textinput := New() + textinput.ShowSuggestions = true + + suggestion := textinput.CurrentSuggestion() + expected := "" + if suggestion != expected { + t.Fatalf("Error: expected no current suggestion but was %s", suggestion) + } + + textinput.SetSuggestions([]string{"test1", "test2", "test3"}) + suggestion = textinput.CurrentSuggestion() + expected = "" + if suggestion != expected { + t.Fatalf("Error: expected no current suggestion but was %s", suggestion) + } + + textinput.SetValue("test") + textinput.updateSuggestions() + textinput.nextSuggestion() + suggestion = textinput.CurrentSuggestion() + expected = "test2" + if suggestion != expected { + t.Fatalf("Error: expected first suggestion but was %s", suggestion) + } +} From 04658fed8eb24c81d1612d89db091e4f6c1be19f Mon Sep 17 00:00:00 2001 From: Kevin Miller Date: Thu, 11 Apr 2024 07:32:49 -0500 Subject: [PATCH 2/6] Add support fo style func to table bubble --- table/table.go | 30 ++++++++++++++++++++++++------ table/table_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/table/table.go b/table/table.go index 7bff090..34d5ae8 100644 --- a/table/table.go +++ b/table/table.go @@ -14,11 +14,12 @@ import ( type Model struct { KeyMap KeyMap - cols []Column - rows []Row - cursor int - focus bool - styles Styles + cols []Column + rows []Row + cursor int + focus bool + styles Styles + styleFunc StyleFunc viewport viewport.Model start int @@ -188,6 +189,13 @@ func WithStyles(s Styles) Option { } } +// WithStyleFunc sets the table style func which can determine a cell style per column, row, and selected state. +func WithStyleFunc(f StyleFunc) Option { + return func(m *Model) { + m.styleFunc = f + } +} + // WithKeyMap sets the key map. func WithKeyMap(km KeyMap) Option { return func(m *Model) { @@ -397,6 +405,9 @@ func (m *Model) FromValues(value, separator string) { m.SetRows(rows) } +// StyleFunc is a function that can be used to customize the style of a table cell based on the row and column index. +type StyleFunc func(row, col int, value string) lipgloss.Style + func (m Model) headersView() string { var s = make([]string, 0, len(m.cols)) for _, col := range m.cols { @@ -416,8 +427,15 @@ func (m *Model) renderRow(rowID int) string { if m.cols[i].Width <= 0 { continue } + var cellStyle lipgloss.Style + if m.styleFunc != nil { + cellStyle = m.styleFunc(rowID, i, value) + } else { + cellStyle = m.styles.Cell + } + style := lipgloss.NewStyle().Width(m.cols[i].Width).MaxWidth(m.cols[i].Width).Inline(true) - renderedCell := m.styles.Cell.Render(style.Render(runewidth.Truncate(value, m.cols[i].Width, "…"))) + renderedCell := cellStyle.Render(style.Render(runewidth.Truncate(value, m.cols[i].Width, "…"))) s = append(s, renderedCell) } diff --git a/table/table_test.go b/table/table_test.go index d927be0..24f075f 100644 --- a/table/table_test.go +++ b/table/table_test.go @@ -1,6 +1,7 @@ package table import ( + "strings" "testing" "github.com/charmbracelet/lipgloss" @@ -108,3 +109,33 @@ func TestRenderRow(t *testing.T) { }) } } +func TestRenderRowStyleFunc(t *testing.T) { + tests := []struct { + name string + table *Model + expected string + }{ + { + name: "simple row", + table: &Model{ + rows: []Row{{"Foooooo", "Baaaaar", "Baaaaaz"}}, + cols: cols, + styleFunc: func(row, col int, value string) lipgloss.Style { + if strings.HasSuffix(value, "z") { + return lipgloss.NewStyle().Transform(strings.ToLower) + } + return lipgloss.NewStyle().Transform(strings.ToUpper) + }, + }, + expected: "FOOOOOO BAAAAAR baaaaaz ", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + row := tc.table.renderRow(0) + if row != tc.expected { + t.Fatalf("\n\nWant: \n%s\n\nGot: \n%s\n", tc.expected, row) + } + }) + } +} From 68a68a472d13efee41d4658ecaede456b3b98988 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Wed, 24 Apr 2024 13:50:10 -0400 Subject: [PATCH 3/6] fix(table): inherit SelectedStyle for StyleFunc --- table/table.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/table/table.go b/table/table.go index 34d5ae8..e355b23 100644 --- a/table/table.go +++ b/table/table.go @@ -421,15 +421,18 @@ func (m Model) headersView() string { return lipgloss.JoinHorizontal(lipgloss.Left, s...) } -func (m *Model) renderRow(rowID int) string { +func (m *Model) renderRow(r int) string { var s = make([]string, 0, len(m.cols)) - for i, value := range m.rows[rowID] { + for i, value := range m.rows[r] { if m.cols[i].Width <= 0 { continue } var cellStyle lipgloss.Style if m.styleFunc != nil { - cellStyle = m.styleFunc(rowID, i, value) + cellStyle = m.styleFunc(r, i, value) + if r == m.cursor { + cellStyle.Inherit(m.styles.Selected) + } } else { cellStyle = m.styles.Cell } @@ -441,7 +444,7 @@ func (m *Model) renderRow(rowID int) string { row := lipgloss.JoinHorizontal(lipgloss.Left, s...) - if rowID == m.cursor { + if r == m.cursor { return m.styles.Selected.Render(row) } From c6bfeb0e6c7828b4d8b765174f05a83aeb062c1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 10:26:29 -0400 Subject: [PATCH 4/6] chore(deps): bump golangci/golangci-lint-action from 4 to 5 (#514) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 4 to 5. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/v4...v5) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint-soft.yml | 2 +- .github/workflows/lint.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-soft.yml b/.github/workflows/lint-soft.yml index c739bcf..cd79f53 100644 --- a/.github/workflows/lint-soft.yml +++ b/.github/workflows/lint-soft.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v4 + uses: golangci/golangci-lint-action@v5 with: # Optional: golangci-lint command line arguments. args: --config .golangci-soft.yml --issues-exit-code=0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 35158ce..7e45846 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v4 + uses: golangci/golangci-lint-action@v5 with: # Optional: golangci-lint command line arguments. #args: From de18ed2891980c66cdd6994ec930a016c6e6ca56 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Wed, 8 May 2024 12:21:36 -0400 Subject: [PATCH 5/6] chore(readme): add kevm/bubbleo to 'additional bubbles' --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 80eb2aa..f6e4d21 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { * [mritd/bubbles](https://github.com/mritd/bubbles): Some general-purpose bubbles. Inputs with validation, menu selection, a modified progressbar, and so on. +* [kevm/bubbleo](https://github.com/KevM/bubbleo): A set of bubbles with a + focus on navigation: navigation stacks, breakcrumbs, menus and so on. * [treilik/bubbleboxer](https://github.com/treilik/bubbleboxer): Layout multiple bubbles side-by-side in a layout-tree. * [treilik/bubblelister](https://github.com/treilik/bubblelister): An alternate From 65933b4ef686b2f60618ef49d11c83c56b60bd58 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Wed, 8 May 2024 13:58:30 -0400 Subject: [PATCH 6/6] chore(lint): drop deprecated 'ifshort' linter directive --- .golangci-soft.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.golangci-soft.yml b/.golangci-soft.yml index ef456e0..1b6824b 100644 --- a/.golangci-soft.yml +++ b/.golangci-soft.yml @@ -23,7 +23,6 @@ linters: - gomnd - gomoddirectives - goprintffuncname - - ifshort # - lll - misspell - nakedret