BubbleO is a collection of components for the excellent terminal UI tool bubbletea.
go get "github.com/kevm/bubbleo"
Add support to your bubble tea application to easily transition between component models. The example below uses the menu component to let a user pick a color from a list of artist paintings.
s := shell.New()
s.Navstack.Push(navstack.NavigationItem{Model: m, Title: "Colors"})
p := tea.NewProgram(s, tea.WithAltScreen())
_, err := p.Run()
if err != nil {
fmt.Println("Error running program:", err)
os.Exit(1)
}
Push, well, pushes a new navigation item on the nav stack. The title is used for breadcrumbs (more later). The model at the top of the navstack has it's Update and View funcs used effectively making it the presented component on the stack.
Popping the stack will remove the topmost navigation item from the stack.
Navigation is accomplished by your components when they publish messages like navstack.PushNavigation{}
or navstack.PopNavigation{}
.
This example is from the included menu component which presents a list of choices. When a menu item is selected by pressing enter
the choice's model is pushed onto the stack by publishing navstack.PushNavigation
.
case tea.KeyEnter.String():
choice, ok := m.list.SelectedItem().(choiceItem)
if ok {
m.selected = &choice.key
item := navstack.NavigationItem{Title: choice.title, Model: choice.key.Model}
cmd := utils.Cmdize(navstack.PushNavigation{Item: item})
return m, cmd
}
There is no limit to the depth of the navigation stack. And the stack components may be dynamic based on your application and user needs.
Note: Cmdize simply wraps the given arg in a
tea.Cmd
(func that returns atea.Msg
)
To pop a component off the stack you might do the following in your bubbletea Update
func.
case color.ColorSelected:
pop := utils.Cmdize(navstack.PopNavigation{})
cmd := utils.Cmdize(ArtistSelected{Name: m.Artist.Name, Color: msg.RGB})
return m, tea.Sequence(pop, cmd)
The first cmd pops the current component off the stack while the second command is received by the previous component on the stack. This allows you to communicate the actions taken by the user up the nav stack.
If there are no items on the stack tea.Quit
command is sent and the applicaiton exits.
Important: In this example we are using
tea.Sequence
rather than the normaltea.Batch
to ensure the messages are played in the correct order. This ensures the pop is played before theArtistSelected
which means the component below on the stack will get the message after the navstack is update.
The menu component wraps the excellent The bubble/list component to let the user select from a menu of choices. Each choice is a model, title, and optional description which upon selection will take the user to this component's view. Menu expects to be used within a navigation stack. See the simple and deeper examples for detailed usage.
It is handy to give the user a sense of place by presenting a breadcrumb view showing them where they come from.
Checkout the deeper example for usage of breadcrumbs.
Finally the shell component emcapsulates the Breadcrumb and Navstack components allowing them to work together. See the simple and deeper examples to see how it works.