tab

package
v0.0.0-...-ef14c93 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package tab provides a tabbed container that hosts multiple screen.Screen bodies inside one parent screen. Each tab keeps its own state across switches; the active tab's body fills the area below a single-row strip.

A tab pane is not a navigation level — it lives entirely inside one screen and never touches the screen.Stack. The host screen forwards a small set of callbacks to tab.Model:

host.Update(msg)         → tabs.Update(msg)
host.OnEnter(result)     → tabs.OnEnterActive(result)
host.IsCapturingKeys()   → tabs.IsCapturingKeys()
host.SetTheme(t)         → tabs.SetTheme(t)        (fans to every body)
host.Help()              → host bindings + tabs.Help()
host.Layout()            → layout.Sized(&s.tabs)

If a tab body returns a screen.Push command from its Update, the cmd bubbles up through the host into the app stack, the new screen lands on top, and the host (with the tab pane intact) is preserved underneath. When that child later pops with a result, app.Stack delivers it to the host's OnEnter, which forwards via OnEnterActive so the body that initiated the push is the one that receives the result.

Tab bodies are full screen.Screen implementations, so anything you'd build as a top-level screen drops in unchanged. Only Title() and (usually) Init() are unused — Label is taken from the Tab struct, and most bodies do their activation work in OnEnter.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Model

type Model struct {
	// contains filtered or unexported fields
}

Model is the tab pane.

func New

func New(opts Options) Model

New constructs a tab pane. Panics on empty Tabs (a tab pane with zero entries has no body to render).

func (Model) ActiveLabel

func (m Model) ActiveLabel() string

ActiveLabel returns the active tab's label — useful for surfacing the tab in the host screen's breadcrumb Title().

func (Model) ActiveTab

func (m Model) ActiveTab() int

ActiveTab returns the active tab index.

func (Model) Help

func (m Model) Help() []key.Binding

Help returns the tab-switch bindings plus the active body's Help, deduped.

func (Model) Init

func (m Model) Init() tea.Cmd

Init batches every body's Init plus the initial tab's OnEnter(nil).

func (Model) IsCapturingKeys

func (m Model) IsCapturingKeys() bool

IsCapturingKeys reports whether the active body is consuming keystrokes (e.g. a focused filter). The host should expose this from its own IsCapturingKeys so app's global keys yield correctly.

func (Model) OnEnterActive

func (m Model) OnEnterActive(result any) tea.Cmd

OnEnterActive forwards a result into the active body's OnEnter. Use this from the host's OnEnter so a child screen popped via screen.Pop(value) reaches the body that initiated the push.

func (*Model) SetActiveTab

func (m *Model) SetActiveTab(i int) tea.Cmd

SetActiveTab switches tabs and returns the new body's OnEnter(nil) cmd. No-op (returns nil) when i resolves to the already-active tab.

func (*Model) SetDimensions

func (m *Model) SetDimensions(w, h int)

SetDimensions stores the available rect; renderStrip and the body share it.

func (*Model) SetTheme

func (m *Model) SetTheme(t theme.Theme)

SetTheme rebuilds the strip styles and fans the new theme out to every body, including inactive ones, so a tab the user hasn't visited yet still renders in the current palette when they switch to it.

func (Model) Update

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)

Update handles tab-switch keys (prev/next/numbers, gated by IsCapturingKeys on the active body) and forwards messages to the bodies.

Routing differs by message kind:

  • tea.KeyMsg goes to the active body only. Sending keystrokes to every tab would race "/" filters, "j/k" cursors, and similar shortcuts across panes the user can't see.
  • Every other message fans out to every body, so timers, async fetches, and other background streams in inactive tabs stay alive across switches. (A body's tea.Tick re-arm cmd that fired while another tab was active still reaches it.)

func (Model) View

func (m Model) View() string

View renders the tab strip on the first row and the active body's layout in the remaining rows.

type Options

type Options struct {
	Tabs []Tab
	// Theme drives default strip styling. Required when style overrides
	// are not provided.
	Theme theme.Theme
	// Initial is the starting tab index. Defaults to 0; out-of-range values
	// are clamped to 0.
	Initial int

	// PrevKey / NextKey switch tabs. Defaults: shift+left / shift+right.
	// We deliberately avoid tab/shift+tab — those are reserved for inner
	// pane focus cycling across tuilib examples.
	PrevKey key.Binding
	NextKey key.Binding
	// DisableNumberKeys turns off the 1–9 jump-to-tab shortcut. By default
	// "1" through "9" map to tabs[0]..tabs[8] (when at least 2 tabs exist).
	DisableNumberKeys bool

	// ActiveStyle styles the active tab label (with surrounding spaces).
	ActiveStyle *lipgloss.Style
	// InactiveStyle styles non-active tab labels.
	InactiveStyle *lipgloss.Style
	// SeparatorStyle styles the inter-tab separator.
	SeparatorStyle *lipgloss.Style
	// BarStyle is the strip's outer style — supplies the background fill
	// across the full width so the strip reads as one band.
	BarStyle *lipgloss.Style
	// Separator goes between tab labels. Defaults to " │ ".
	Separator string
}

Options configures a tab pane. Theme is used to derive default styles; override any of the Style/Separator fields to deviate from the palette.

type Tab

type Tab struct {
	// Label is rendered in the tab strip.
	Label string
	// Body is the screen rendered below the strip when this tab is active.
	// Title()/Init() are largely unused — see package doc.
	Body screen.Screen
}

Tab is one entry in a tab pane.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL