123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package list
- import (
- "github.com/charmbracelet/bubbles/key"
- "github.com/charmbracelet/bubbles/list"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
- )
- var (
- appStyle = lipgloss.NewStyle().Padding(1, 2)
- titleStyle = lipgloss.NewStyle().
- Foreground(lipgloss.Color("#FFFDF5")).
- Background(lipgloss.Color("#25A065")).
- Padding(0, 1)
- statusMessageStyle = lipgloss.NewStyle().
- Foreground(lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#04B575"}).
- Render
- )
- type Item struct {
- title string
- description string
- }
- func NewItem(title string, description string) Item {
- return Item{title, description}
- }
- func (i Item) Title() string { return i.title }
- func (i Item) Description() string { return i.description }
- func (i Item) FilterValue() string { return i.title }
- type listKeyMap struct {
- toggleSpinner key.Binding
- toggleTitleBar key.Binding
- toggleStatusBar key.Binding
- togglePagination key.Binding
- toggleHelpMenu key.Binding
- }
- func newListKeyMap() *listKeyMap {
- return &listKeyMap{
- toggleSpinner: key.NewBinding(
- key.WithKeys("s"),
- key.WithHelp("s", "toggle spinner"),
- ),
- toggleTitleBar: key.NewBinding(
- key.WithKeys("T"),
- key.WithHelp("T", "toggle title"),
- ),
- toggleStatusBar: key.NewBinding(
- key.WithKeys("S"),
- key.WithHelp("S", "toggle status"),
- ),
- togglePagination: key.NewBinding(
- key.WithKeys("P"),
- key.WithHelp("P", "toggle pagination"),
- ),
- toggleHelpMenu: key.NewBinding(
- key.WithKeys("H"),
- key.WithHelp("H", "toggle help"),
- ),
- }
- }
- type model struct {
- list list.Model
- keys *listKeyMap
- delegateKeys *delegateKeyMap
- }
- func NewList(title string, items []list.Item) model {
- var (
- delegateKeys = newDelegateKeyMap()
- listKeys = newListKeyMap()
- )
- // Setup list
- delegate := newItemDelegate(delegateKeys)
- groceryList := list.New(items, delegate, 0, 0)
- groceryList.Title = title
- groceryList.Styles.Title = titleStyle
- groceryList.AdditionalFullHelpKeys = func() []key.Binding {
- return []key.Binding{
- listKeys.toggleSpinner,
- listKeys.toggleTitleBar,
- listKeys.toggleStatusBar,
- listKeys.togglePagination,
- listKeys.toggleHelpMenu,
- }
- }
- return model{
- list: groceryList,
- keys: listKeys,
- delegateKeys: delegateKeys,
- }
- }
- func (m model) Init() tea.Cmd {
- return tea.EnterAltScreen
- }
- func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
- var cmds []tea.Cmd
- switch msg := msg.(type) {
- case tea.WindowSizeMsg:
- h, v := appStyle.GetFrameSize()
- m.list.SetSize(msg.Width-h, msg.Height-v)
- case tea.KeyMsg:
- // Don't match any of the keys below if we're actively filtering.
- if m.list.FilterState() == list.Filtering {
- break
- }
- switch {
- case key.Matches(msg, m.keys.toggleSpinner):
- cmd := m.list.ToggleSpinner()
- return m, cmd
- case key.Matches(msg, m.keys.toggleTitleBar):
- v := !m.list.ShowTitle()
- m.list.SetShowTitle(v)
- m.list.SetShowFilter(v)
- m.list.SetFilteringEnabled(v)
- return m, nil
- case key.Matches(msg, m.keys.toggleStatusBar):
- m.list.SetShowStatusBar(!m.list.ShowStatusBar())
- return m, nil
- case key.Matches(msg, m.keys.togglePagination):
- m.list.SetShowPagination(!m.list.ShowPagination())
- return m, nil
- case key.Matches(msg, m.keys.toggleHelpMenu):
- m.list.SetShowHelp(!m.list.ShowHelp())
- return m, nil
- }
- }
- // This will also call our delegate's update function.
- newListModel, cmd := m.list.Update(msg)
- m.list = newListModel
- cmds = append(cmds, cmd)
- return m, tea.Batch(cmds...)
- }
- func (m model) View() string {
- return appStyle.Render(m.list.View())
- }
|