Bubble-table
A customizable, interactive table component for the
Bubble Tea framework.
View above sample source code
Contributing
Contributions welcome, please check the contributions doc
for a few helpful tips!
Features
For a code reference of most available features, please see the full feature example.
If you want to get started with a simple default table, check the simplest example.
Displays a table with a header, rows, footer, and borders. The header can be
hidden, and the footer can be set to automatically show page information, use
custom text, or be hidden by default.
Columns can be fixed-width or flexible width. A maximum
width can be specified which enables horizontal scrolling,
and left-most columns can be frozen for easier reference.
Border shape is customizable with a basic thick square default. The color can
be modified by applying a base style with lipgloss.NewStyle().BorderForeground(...)
.
Styles can be applied globally and to columns, rows, and individual cells.
The base style is applied first, then column, then row, then cell when
determining overrides. The default base style is a basic right-alignment.
See the main feature example to see styles and
how they override each other.
Styles can also be applied via a style function which can be used to apply
zebra striping, data-specific formatting, etc.
Can be focused to highlight a row and navigate with up/down (and j/k). These
keys can be customized with a KeyMap.
Can make rows selectable, and fetch the current selections.
Events can be checked for user interactions.
Pagination can be set with a given page size, which automatically generates a
simple footer to show the current page and total pages.
Built-in filtering can be enabled by setting any columns as filterable, using
a text box in the footer and /
(customizable by keybind) to start filtering.
A missing indicator can be supplied to show missing data in rows.
Columns can be sorted in either ascending or descending order. Multiple columns
can be specified in a row. If multiple columns are specified, first the table
is sorted by the first specified column, then each group within that column is
sorted in smaller and smaller groups. See the sorting example
for more information. If a column contains numbers (either ints or floats),
the numbers will be sorted by numeric value. Otherwise rendered string values
will be compared.
If a feature is confusing to use or could use a better example, please feel free
to open an issue.
Defining table data
A table is defined by a list of Column
values that define the columns in the
table. Each Column
is associated with a unique string key.
A table contains a list of Row
s. Each Row
contains a RowData
object which
is simply a map of string column IDs to arbitrary interface{}
data values.
When the table is rendered, each Row
is checked for each Column
key. If the
key exists in the Row
's RowData
, it is rendered with fmt.Sprintf("%v")
.
If it does not exist, nothing is rendered.
Extra data in the RowData
object is ignored. This can be helpful to simply
dump data into RowData
and create columns that select what is interesting to
view, or to generate different columns based on view options on the fly (see the
metadata example for an example of using this).
An example is given below. For more detailed examples, see
the examples directory.
const (
columnKeyID = "id"
columnKeyName = "何?!"
)
columns := []table.Column{
table.NewColumn(columnKeyID, "ID", 5),
table.NewColumn(columnKeyName, "Name", 10),
}
rows := []table.Row{
table.NewRow(table.RowData{
columnKeyID: "abc",
columnKeyName: "Hello",
}),
table.NewRow(table.RowData{
columnKeyID: "123",
columnKeyName: "Oh no",
"somethingelse": "Super bold!",
}),
table.NewRow(table.RowData{
columnKeyID: "def",
}),
table.NewRow(table.RowData{
columnKeyID: "bold",
columnKeyName: "Bolded",
}).WithStyle(lipgloss.NewStyle().Bold(true). ,
table.NewRow(table.RowData{
columnKeyID: "alert",
columnKeyName: table.NewStyledCell("Alert", lipgloss.NewStyle().Foreground(lipgloss.Color("#f88"))),
}).WithStyle(lipgloss.NewStyle().Bold(true),
}
A note on 'metadata'
There may be cases where you wish to reference some kind of data object in the
table. For example, a table of users may display a user name, ID, etc., and you
may wish to retrieve data about the user when the row is selected. This can be
accomplished by attaching hidden 'metadata' to the row in the same way as any
other data.
const (
columnKeyID = "id"
columnKeyName = "名前"
columnKeyUserData = "userstuff"
)
columns := []table.Column{
table.NewColumn(columnKeyID, "ID", 5),
table.NewColumn(columnKeyName, "Name", 10),
}
user := &SomeUser{
ID: 3,
Name: "Evertras",
}
rows := []table.Row{
table.NewRow(table.RowData{
columnKeyID: user.ID,
columnKeyName: user.Name,
columnKeyUserData: user,
}),
}
For a more detailed demonstration of this idea in action, please see the
metadata example.
Demos
Code examples are located in the examples directory. Run commands
are added to the Makefile for convenience but they should be as
simple as go run ./examples/features/main.go
, etc. You can also view what
they look like by checking the example's directory in each README here on
Github.
To run the examples, clone this repo and run:
make
make example-dimensions
go run ./examples/pagination/main.go