Skip to content

Instantly share code, notes, and snippets.

@bashbunni
Created September 7, 2022 22:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bashbunni/2ef5da9acb042c1ae0732b1d682e5d9a to your computer and use it in GitHub Desktop.
Save bashbunni/2ef5da9acb042c1ae0732b1d682e5d9a to your computer and use it in GitHub Desktop.
Toggle Between List Examples
package main
import (
"fmt"
"os"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
var (
docStyle = lipgloss.NewStyle().Margin(1, 2)
vh int
vw int
)
type item struct {
title, desc string
}
func (i item) Title() string { return i.title }
func (i item) Description() string { return i.desc }
func (i item) FilterValue() string { return i.title }
type model struct {
list list.Model
}
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:
if msg.String() == "ctrl+c" {
return m, tea.Quit
}
if msg.String() == "a" {
return NewSimpleListModel(), nil
}
case tea.WindowSizeMsg:
h, v := docStyle.GetFrameSize()
vh = msg.Height - v
vw = msg.Height - h
m.list.SetSize(vw, vh)
}
var cmd tea.Cmd
m.list, cmd = m.list.Update(msg)
return m, cmd
}
func (m model) View() string {
return docStyle.Render(m.list.View())
}
func main() {
m := NewDefaultListModel()
p := tea.NewProgram(m, tea.WithAltScreen())
if err := p.Start(); err != nil {
fmt.Println("Error running program:", err)
os.Exit(1)
}
}
func NewDefaultListModel() tea.Model {
items := []list.Item{
item{title: "Raspberry Pi’s", desc: "I have ’em all over my house"},
item{title: "Nutella", desc: "It's good on toast"},
item{title: "Bitter melon", desc: "It cools you down"},
item{title: "Nice socks", desc: "And by that I mean socks without holes"},
item{title: "Eight hours of sleep", desc: "I had this once"},
item{title: "Cats", desc: "Usually"},
item{title: "Plantasia, the album", desc: "My plants love it too"},
item{title: "Pour over coffee", desc: "It takes forever to make though"},
item{title: "VR", desc: "Virtual reality...what is there to say?"},
item{title: "Noguchi Lamps", desc: "Such pleasing organic forms"},
item{title: "Linux", desc: "Pretty much the best OS"},
item{title: "Business school", desc: "Just kidding"},
item{title: "Pottery", desc: "Wet clay is a great feeling"},
item{title: "Shampoo", desc: "Nothing like clean hair"},
item{title: "Table tennis", desc: "It’s surprisingly exhausting"},
item{title: "Milk crates", desc: "Great for packing in your extra stuff"},
item{title: "Afternoon tea", desc: "Especially the tea sandwich part"},
item{title: "Stickers", desc: "The thicker the vinyl the better"},
item{title: "20° Weather", desc: "Celsius, not Fahrenheit"},
item{title: "Warm light", desc: "Like around 2700 Kelvin"},
item{title: "The vernal equinox", desc: "The autumnal equinox is pretty good too"},
item{title: "Gaffer’s tape", desc: "Basically sticky fabric"},
item{title: "Terrycloth", desc: "In other words, towel fabric"},
}
m := model{list: list.New(items, list.NewDefaultDelegate(), 0, 0)}
m.list.Title = "My Fave Things"
if vh != 0 && vw != 0 {
m.list.SetSize(vw, vh)
}
return m
}
package main
import (
"fmt"
"io"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
const listHeight = 14
var (
titleStyle = lipgloss.NewStyle().MarginLeft(2)
itemStyle = lipgloss.NewStyle().PaddingLeft(4)
selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170"))
paginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(4)
helpStyle = list.DefaultStyles().HelpStyle.PaddingLeft(4).PaddingBottom(1)
quitTextStyle = lipgloss.NewStyle().Margin(1, 0, 2, 4)
)
type item2 string
func (i item2) FilterValue() string { return "" }
type itemDelegate struct{}
func (d itemDelegate) Height() int { return 1 }
func (d itemDelegate) Spacing() int { return 0 }
func (d itemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
i, ok := listItem.(item2)
if !ok {
return
}
str := fmt.Sprintf("%d. %s", index+1, i)
fn := itemStyle.Render
if index == m.Index() {
fn = func(s string) string {
return selectedItemStyle.Render("> " + s)
}
}
fmt.Fprintf(w, fn(str))
}
type model2 struct {
list list.Model
choice string
quitting bool
}
func (m model2) Init() tea.Cmd {
return nil
}
func (m model2) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.list.SetWidth(msg.Width)
return m, nil
case tea.KeyMsg:
switch keypress := msg.String(); keypress {
case "ctrl+c":
m.quitting = true
return m, tea.Quit
case "enter":
i, ok := m.list.SelectedItem().(item2)
if ok {
m.choice = string(i)
}
return m, tea.Quit
case "h":
return NewDefaultListModel(), nil
}
}
var cmd tea.Cmd
m.list, cmd = m.list.Update(msg)
return m, cmd
}
func (m model2) View() string {
if m.choice != "" {
return quitTextStyle.Render(fmt.Sprintf("%s? Sounds good to me.", m.choice))
}
if m.quitting {
return quitTextStyle.Render("Not hungry? That’s cool.")
}
return "\n" + m.list.View()
}
func NewSimpleListModel() tea.Model {
items := []list.Item{
item2("Ramen"),
item2("Tomato Soup"),
item2("Hamburgers"),
item2("Cheeseburgers"),
item2("Currywurst"),
item2("Okonomiyaki"),
item2("Pasta"),
item2("Fillet Mignon"),
item2("Caviar"),
item2("Just Wine"),
}
const defaultWidth = 20
l := list.New(items, itemDelegate{}, defaultWidth, listHeight)
l.Title = "What do you want for dinner?"
l.SetShowStatusBar(false)
l.SetFilteringEnabled(false)
l.Styles.Title = titleStyle
l.Styles.PaginationStyle = paginationStyle
l.Styles.HelpStyle = helpStyle
m := model2{list: l}
return m
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment