grouped.go

  1package list
  2
  3import (
  4	tea "github.com/charmbracelet/bubbletea/v2"
  5	"github.com/charmbracelet/crush/internal/tui/components/core/layout"
  6	"github.com/charmbracelet/crush/internal/tui/util"
  7)
  8
  9type Group[T Item] struct {
 10	Section ItemSection
 11	Items   []T
 12}
 13type GroupedList[T Item] interface {
 14	util.Model
 15	layout.Sizeable
 16	Items() []Item
 17	Groups() []Group[T]
 18	SetGroups([]Group[T]) tea.Cmd
 19	MoveUp(int) tea.Cmd
 20	MoveDown(int) tea.Cmd
 21	GoToTop() tea.Cmd
 22	GoToBottom() tea.Cmd
 23	SelectItemAbove() tea.Cmd
 24	SelectItemBelow() tea.Cmd
 25	SetSelected(string) tea.Cmd
 26	SelectedItem() *T
 27}
 28type groupedList[T Item] struct {
 29	*list[Item]
 30	groups []Group[T]
 31}
 32
 33func NewGroupedList[T Item](groups []Group[T], opts ...ListOption) GroupedList[T] {
 34	list := &list[Item]{
 35		confOptions: &confOptions{
 36			direction: DirectionForward,
 37			keyMap:    DefaultKeyMap(),
 38			focused:   true,
 39		},
 40		items:         []Item{},
 41		indexMap:      make(map[string]int),
 42		renderedItems: make(map[string]renderedItem),
 43	}
 44	for _, opt := range opts {
 45		opt(list.confOptions)
 46	}
 47
 48	return &groupedList[T]{
 49		list: list,
 50	}
 51}
 52
 53func (g *groupedList[T]) Init() tea.Cmd {
 54	g.convertItems()
 55	return g.render()
 56}
 57
 58func (l *groupedList[T]) Update(msg tea.Msg) (util.Model, tea.Cmd) {
 59	u, cmd := l.list.Update(msg)
 60	l.list = u.(*list[Item])
 61	return l, cmd
 62}
 63
 64func (g *groupedList[T]) SelectedItem() *T {
 65	item := g.list.SelectedItem()
 66	if item == nil {
 67		return nil
 68	}
 69	dRef := *item
 70	c, ok := any(dRef).(T)
 71	if !ok {
 72		return nil
 73	}
 74	return &c
 75}
 76
 77func (g *groupedList[T]) convertItems() {
 78	var items []Item
 79	for _, g := range g.groups {
 80		items = append(items, g.Section)
 81		for _, g := range g.Items {
 82			items = append(items, g)
 83		}
 84	}
 85	g.items = items
 86}
 87
 88func (g *groupedList[T]) SetGroups(groups []Group[T]) tea.Cmd {
 89	g.groups = groups
 90	g.convertItems()
 91	return g.SetItems(g.items)
 92}
 93
 94func (g *groupedList[T]) Groups() []Group[T] {
 95	return g.groups
 96}
 97
 98func (g *groupedList[T]) Items() []Item {
 99	return g.list.Items()
100}