bubbles
                                
                                 bubbles copied to clipboard
                                
                                    bubbles copied to clipboard
                            
                            
                            
                        What about Table widget?
Hi guys,
Do you have any plan to implement Table widgets for Bubble Tea? Or a little hack with the "Viewpoint" widget to support simple tables?
Thanks for your great works!
Hi! Tables are pretty simple in Bubble Tea since they're just strings. Here's some example code we just pushed that shows how you can render a table in a viewport using Glamour.
That said, we do plan in making an interactive table widget. In the meantime, here's some example code for an interactive table using olekukonko/tablewriter:

package main
import (
	"fmt"
	"os"
	"strings"
	tea "github.com/charmbracelet/bubbletea"
	"github.com/muesli/termenv"
	"github.com/olekukonko/tablewriter"
)
var (
	term = termenv.ColorProfile()
	// The data for our table
	data = [][]string{
		{"A Fistful of Dollars", "Western", "1964"},
		{"For a few Dollars More", "Western", "1965"},
		{"The Good, the Bad and the Ugly", "Western", "1966"},
	}
)
type model int
func (m model) Init() tea.Cmd {
	return nil
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := msg.(type) {
	case tea.KeyMsg:
		switch msg.String() {
		case "q", "ctrl+c":
			return m, tea.Quit
		case "k", "up":
			m--
			if int(m) < 0 {
				m = model(len(data) - 1)
			}
		case "j", "down":
			m++
			if int(m) > len(data) {
				m = 0
			}
		}
	}
	return m, nil
}
func (m model) View() string {
	s := strings.Builder{}
	// Set table header
	table := tablewriter.NewWriter(&s)
	table.SetHeader([]string{"Name", "Genre", "Year"})
	// Add data to table
	for i, v := range data {
		if int(m) == i {
			// Color active item
			c := tablewriter.Colors{tablewriter.FgBlackColor, tablewriter.BgWhiteColor}
			var colors []tablewriter.Colors
			for range v {
				colors = append(colors, c)
			}
			table.Rich(v, colors)
		} else {
			table.Append(v)
		}
	}
	table.Render()
	s.WriteString(termenv.String(" ↑/↓: Choose • q: Quit").Foreground(term.Color("241")).String())
	return s.String()
}
func main() {
	if err := tea.NewProgram(model(0)).Start(); err != nil {
		fmt.Printf("Oh no! %v\n", err)
		os.Exit(1)
	}
}
There are plenty of other table drawing packages that would work too. Let us know if you have any questions.
Thanks for your help!
Fix a typo in the code snippet:
			if int(m) > len(data) {
				m = 0
			}
->
			if int(m) >= len(data) {
				m = 0
			}
However, I do hope you guys can support a formal table widget like the viewport in Glamour, the border lines of olekukonko/tablewriter looks really awkward.
Thanks for that. Glamour actually uses olekukonko/tablewriter but with custom glyphs for borders. Here’s the implementation and here are the glyphs.
Anyway, I'll let you know when we build a component for this; it will more than likely be based on the code above.
Is there a simple way to combine this example with a pager or the possibility to scroll the content of the table (and keep the header fixed to top) in AltMode? Because if there are too many items in the table, the selection/display is broken.
Table widget is now implemented https://github.com/charmbracelet/bubbles/tree/master/table
@maaslalani Great works! what about a little intro and demo gif in the README file?
@hyorigo Introduction is here (https://github.com/charmbracelet/bubbles/releases/tag/v0.14.0) and demo gif is now in the README (https://github.com/charmbracelet/bubbles)!
