Skip to content

Components

Every component is a package under pkg/ with an Options struct, a New(Options) constructor and the Bubble Tea Init / Update / View methods. Every interactive one owns a bordered pane.Pane, so View() returns a finished box and Options.Title draws on its border.

Catalog

Component Package Use it for
Pane pkg/pane A bordered, scrollable region for arbitrary text; the primitive under every other component.
List pkg/list A cursor over strings, optionally filterable and markable. Menus, pickers, master lists.
Table pkg/table Records with columns: sort, scoped filters, flex widths, remote paging.
Tree pkg/tree Hierarchies: expand/collapse, search, filter that keeps ancestors.
Inspector pkg/inspector One structured record as aligned label/value rows (a k8s manifest, a JSON response).
TextView pkg/textview A static document: scroll, search, wrap.
LogView pkg/logview A stream of lines held whole: follow, search, filter mode, capped buffer.
Eventlog pkg/eventlog A timeline paged from a source too large to hold.
Filter pkg/filter A "/-to-focus, enter commits, esc clears" text field.
Input pkg/input A plain bordered text field, including passwords.
Toggle pkg/toggle A yes/no selector.
Form pkg/form Text, password, select and confirm fields with validation and a submit button.
Confirm pkg/confirm A yes/no modal.
Alert pkg/alert An acknowledge-this modal.
Action menu pkg/action A screen's verbs in a self-sizing menu.
Tabs pkg/tab Several screens behind a one-row tab strip.
Breadcrumb and statusbar pkg/breadcrumb, pkg/statusbar The shell's header and footer rows.
Metrics pkg/metrics Inline badges, ratios, bars and sparklines for cells.

The common shape

opts := t.List()             // pre-styled Options from the theme
opts.Title = "Cities"        // what's specific to this instance
opts.Filterable = true
s.list = list.New(opts)

// in Update — forward every message
s.list, cmd = s.list.Update(msg)

// in Layout
layout.Sized(&s.list)
  • Start from the theme builder (t.List(), t.Table(), …). It fills in colors, border shapes, glyphs, key bindings and nested filter options.
  • Don't set Width/Height on a component placed with layout.Sized.
  • Forward every message. Each component decides what to act on. Spinner ticks, focus requests and activity messages all arrive through Update.
  • Label with Title, never with a line above the component.

Capabilities shared across components

Most components implement the same small interfaces, so the surrounding machinery works with any of them.

Capability Methods Components
Placement SetRect(geom.Rect), View() all
State across rebuilds State(), Restore(State) list, table, tree, inspector, textview, logview, eventlog, filter, input, toggle
Key hints Help(), HelpSections() all interactive (filter has Help only)
Focus Focus() tea.Cmd, Blur(), Focused() (satisfies focus.Focusable) list, table, tree, inspector, textview, logview, eventlog, filter, input, toggle
Key capture IsCapturingKeys() list, table, tree, inspector, textview, logview, eventlog, filter, input, form
Filter regions FocusFilter(), BlurFilter() list, table, tree, inspector, textview, logview, eventlog
Open the selection IsActivate(msg), ActivatedMsg list, table, eventlog
Loading spinner SetLoading(bool) tea.Cmd, SetLoadingLabel, Loading() pane and every pane-owning viewer
Keyed data SetKeyedItems / SetKeyedRows, SelectedKey() list, table
Multi-select Options.Markable, Selection(), SelectionLabel(), Marks(), SetMarks, ClearMarks list, table, tree
Row activity BusyWhen, Dispatch, DispatchEach, Done, BeginRead, ApplyRead, ReadsFailing list, table, tree
Restyle in place SetActiveColor, SetInactiveColor, SetActiveBorder, SetInactiveBorder, SetTitle most
Custom keys Options.Keys (from DefaultKeys()) list, table, tree, inspector, textview, logview, eventlog, action menu

Pane pass-through options

Every pane-owning component's Options repeat the pane's chrome fields. The theme builder fills them; override one only deliberately.

Field Meaning
ActiveColor, InactiveColor border color when focused / not
ActiveBorder, InactiveBorder border shape when focused / not (lipgloss.Border)
Glyphs the glyph.Set the component and its scrollbars draw with
SlotBrackets how the title meets the border: pane.SlotBracketsNone, SlotBracketsCorners, SlotBracketsTees
HScrollbar reserve a row for a horizontal scrollbar and enable ←/→ scrolling
SpinnerStyle, LoadingLabel the loading spinner's style and caption

Loading state

Any pane-owning component can replace its body with a centered spinner while data is in flight:

s.list.SetItems(nil)            // drop stale data first
cmd := s.list.SetLoading(true)  // returns the spinner's first tick: return it
// … later, on the fetched message:
s.list.SetItems(items)
s.list.SetLoading(false)

Remote-bound tables and eventlogs manage this themselves; don't call it there. See examples/patterns/loading.