mirror of
https://github.com/zoriya/bubbles.git
synced 2026-08-05 04:36:07 +00:00
feat(table): add option for custom StyleFunc
This commit is contained in:
+34
-17
@@ -16,13 +16,14 @@ type Model struct {
|
||||
KeyMap KeyMap
|
||||
Help help.Model
|
||||
|
||||
yoffset int
|
||||
height int
|
||||
headers []string
|
||||
rows [][]string
|
||||
cursor int
|
||||
focus bool
|
||||
styles Styles
|
||||
yoffset int
|
||||
height int
|
||||
headers []string
|
||||
rows [][]string
|
||||
cursor int
|
||||
focus bool
|
||||
styles Styles
|
||||
styleFunc table.StyleFunc
|
||||
|
||||
table *table.Table
|
||||
start int
|
||||
@@ -138,6 +139,12 @@ func (m *Model) SetStyles(s Styles) {
|
||||
m.table.BorderHeader(s.BorderHeader)
|
||||
}
|
||||
|
||||
// SetStyleFunc sets the table's custom StyleFunc. Use this for conditional
|
||||
// styling e.g. styling a cell by its contents or by index.
|
||||
func (m *Model) SetStyleFunc(s table.StyleFunc) {
|
||||
m.styleFunc = s
|
||||
}
|
||||
|
||||
// SetBorder is a shorthand function for setting or unsetting borders on a
|
||||
// table. The arguments work as follows:
|
||||
//
|
||||
@@ -311,6 +318,13 @@ func WithStyles(s Styles) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithStyleFunc sets the table StyleFunc for conditional styling.
|
||||
func WithStyleFunc(s table.StyleFunc) Option {
|
||||
return func(m *Model) {
|
||||
m.SetStyleFunc(s)
|
||||
}
|
||||
}
|
||||
|
||||
// WithKeyMap sets the key map.
|
||||
func WithKeyMap(km KeyMap) Option {
|
||||
return func(m *Model) {
|
||||
@@ -369,16 +383,19 @@ func (m *Model) Blur() {
|
||||
|
||||
// View renders the component.
|
||||
func (m Model) View() string {
|
||||
m.table.StyleFunc(func(row, col int) lipgloss.Style {
|
||||
if row == table.HeaderRow {
|
||||
return m.styles.Header
|
||||
}
|
||||
if row == m.cursor {
|
||||
return m.styles.Selected
|
||||
}
|
||||
return m.styles.Cell
|
||||
})
|
||||
|
||||
if m.styleFunc != nil {
|
||||
m.table.StyleFunc(m.styleFunc)
|
||||
} else {
|
||||
m.table.StyleFunc(func(row, col int) lipgloss.Style {
|
||||
if row == table.HeaderRow {
|
||||
return m.styles.Header
|
||||
}
|
||||
if row == m.cursor {
|
||||
return m.styles.Selected
|
||||
}
|
||||
return m.styles.Cell
|
||||
})
|
||||
}
|
||||
return m.table.String()
|
||||
}
|
||||
|
||||
|
||||
+96
-1
@@ -4,6 +4,8 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/charmbracelet/lipgloss/table"
|
||||
"github.com/charmbracelet/x/ansi"
|
||||
"github.com/charmbracelet/x/exp/golden"
|
||||
)
|
||||
@@ -136,7 +138,7 @@ func TestTableAlignment(t *testing.T) {
|
||||
s := DefaultStyles()
|
||||
s.BorderHeader = false
|
||||
biscuits := New(
|
||||
WithHeight(5),
|
||||
WithHeight(10),
|
||||
WithColumns([]Column{
|
||||
{Title: "Name", Width: 25},
|
||||
{Title: "Country of Origin", Width: 16},
|
||||
@@ -174,3 +176,96 @@ func TestTableAlignment(t *testing.T) {
|
||||
golden.RequireEqual(t, []byte(got))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetStyleFunc(t *testing.T) {
|
||||
t.Run("single cell styling", func(t *testing.T) {
|
||||
s := DefaultStyles()
|
||||
s.BorderHeader = false
|
||||
biscuits := New(
|
||||
WithColumns([]Column{
|
||||
{Title: "Name", Width: 25},
|
||||
{Title: "Country of Origin", Width: 16},
|
||||
{Title: "Dunk-able", Width: 12},
|
||||
}),
|
||||
WithRows([]Row{
|
||||
{"Chocolate Digestives", "UK", "Yes"},
|
||||
{"Tim Tams", "Australia", "No"},
|
||||
{"Hobnobs", "UK", "Yes"},
|
||||
}),
|
||||
)
|
||||
biscuits.SetStyleFunc(func(row, col int) lipgloss.Style {
|
||||
if row == table.HeaderRow {
|
||||
// TODO this should be exported to be usable outside of the lib.
|
||||
return s.Header
|
||||
}
|
||||
if row == 1 && col == 1 {
|
||||
return s.Cell.Bold(true)
|
||||
}
|
||||
return s.Cell
|
||||
})
|
||||
golden.RequireEqual(t, []byte(biscuits.View()))
|
||||
})
|
||||
}
|
||||
|
||||
func TestWithStyleFunc(t *testing.T) {
|
||||
t.Run("single cell styling", func(t *testing.T) {
|
||||
s := DefaultStyles()
|
||||
s.BorderHeader = false
|
||||
biscuits := New(
|
||||
WithColumns([]Column{
|
||||
{Title: "Name", Width: 25},
|
||||
{Title: "Country of Origin", Width: 16},
|
||||
{Title: "Dunk-able", Width: 12},
|
||||
}),
|
||||
WithRows([]Row{
|
||||
{"Chocolate Digestives", "UK", "Yes"},
|
||||
{"Tim Tams", "Australia", "No"},
|
||||
{"Hobnobs", "UK", "Yes"},
|
||||
}),
|
||||
WithStyleFunc(func(row, col int) lipgloss.Style {
|
||||
if row == table.HeaderRow {
|
||||
return s.Header
|
||||
}
|
||||
// TODO we should probably make it possible to retrieve Style
|
||||
// from the model in case it has been modified from the
|
||||
// defaults.
|
||||
if row == 1 && col == 1 {
|
||||
return s.Cell.Bold(true)
|
||||
}
|
||||
return s.Cell
|
||||
}))
|
||||
golden.RequireEqual(t, []byte(biscuits.View()))
|
||||
})
|
||||
t.Run("cell styling by content", func(t *testing.T) {
|
||||
rows := []Row{
|
||||
{"Chocolate Digestives", "UK", "Yes"},
|
||||
{"Tim Tams", "Australia", "No"},
|
||||
{"Hobnobs", "UK", "Yes"},
|
||||
}
|
||||
s := DefaultStyles()
|
||||
s.BorderHeader = false
|
||||
biscuits := New(
|
||||
WithColumns([]Column{
|
||||
{Title: "Name", Width: 25},
|
||||
{Title: "Country of Origin", Width: 16},
|
||||
{Title: "Dunk-able", Width: 12},
|
||||
}),
|
||||
WithRows(rows),
|
||||
WithStyleFunc(func(row, col int) lipgloss.Style {
|
||||
if row == table.HeaderRow {
|
||||
return s.Header
|
||||
}
|
||||
// TODO we should probably make it possible to retrieve Style
|
||||
// from the model in case it has been modified from the
|
||||
// defaults.
|
||||
|
||||
// you need to pre-define the rows for this to be accessible in
|
||||
// WithStyleFunc
|
||||
if rows[row][col] == "Yes" {
|
||||
return s.Cell.Bold(true)
|
||||
}
|
||||
return s.Cell
|
||||
}))
|
||||
golden.RequireEqual(t, []byte(biscuits.View()))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
╭──────────────────────┬───────────────────┬───────────╮
|
||||
│ [1mName[0m │ [1mCountry of Origin[0m │ [1mDunk-able[0m │
|
||||
├──────────────────────┼───────────────────┼───────────┤
|
||||
│ Chocolate Digestives │ UK │ Yes │
|
||||
│ Tim Tams │ [1mAustralia[0m │ No │
|
||||
│ Hobnobs │ UK │ Yes │
|
||||
╰──────────────────────┴───────────────────┴───────────╯
|
||||
@@ -0,0 +1,7 @@
|
||||
╭──────────────────────┬───────────────────┬───────────╮
|
||||
│ [1mName[0m │ [1mCountry of Origin[0m │ [1mDunk-able[0m │
|
||||
├──────────────────────┼───────────────────┼───────────┤
|
||||
│ Chocolate Digestives │ UK │ [1mYes[0m │
|
||||
│ Tim Tams │ Australia │ No │
|
||||
│ Hobnobs │ UK │ [1mYes[0m │
|
||||
╰──────────────────────┴───────────────────┴───────────╯
|
||||
@@ -0,0 +1,7 @@
|
||||
╭──────────────────────┬───────────────────┬───────────╮
|
||||
│ [1mName[0m │ [1mCountry of Origin[0m │ [1mDunk-able[0m │
|
||||
├──────────────────────┼───────────────────┼───────────┤
|
||||
│ Chocolate Digestives │ UK │ Yes │
|
||||
│ Tim Tams │ [1mAustralia[0m │ No │
|
||||
│ Hobnobs │ UK │ Yes │
|
||||
╰──────────────────────┴───────────────────┴───────────╯
|
||||
Reference in New Issue
Block a user