pane

package
v0.17.0 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package pane provides a bordered, titled, scrollable region for Bubble Tea TUIs. A Pane owns a viewport and renders a vertical scrollbar along its right edge. Any string content can be placed inside — render a child model to a string via its View() method and pass it to SetContent. While SetLoading(true) is in effect, the body is replaced by a centered spinner (with optional LoadingLabel) until SetLoading(false) restores the content.

Index

Constants

View Source
const (
	ScrollbarWidth  = 1
	ScrollbarHeight = 1
)
View Source
const HScrollStep = 4

HScrollStep is how many cells left/right scroll the pane horizontally.

Variables

This section is empty.

Functions

func Borderize

func Borderize(
	content string,
	border lipgloss.Border,
	color lipgloss.TerminalColor,
	embedded map[BorderPosition]string,
	slotBrackets SlotBracketStyle,
) string

Borderize wraps content in the given border with up to six embedded text slots (top/bottom × left/middle/right). Embedded text is flanked by inverted corner glyphs so it renders like `┤ title ├`. The border and all slot glyphs are drawn in color; embedded text passes through verbatim, so pre-style it with lipgloss if you want bold/colored labels.

func HScrollbar

func HScrollbar(width, total, visible, offset int) string

HScrollbar renders a single-row horizontal scrollbar of the given width. total is the total content width (longest line), visible is how much fits in the viewport, and offset is the current horizontal scroll column. When content fits entirely, returns a blank row.

func Scrollbar

func Scrollbar(height, total, visible, offset int) string

Scrollbar renders a single-column vertical scrollbar of the given height. total is the total number of lines in the content, visible is how many fit in the viewport, and offset is the current scroll offset from the top. When content fits entirely, returns a blank column of the given height.

Types

type BorderPosition

type BorderPosition int
const (
	TopLeftBorder BorderPosition = iota
	TopMiddleBorder
	TopRightBorder
	BottomLeftBorder
	BottomMiddleBorder
	BottomRightBorder
)

type Keys

type Keys struct {
	Left, Right key.Binding
	LeftEdge    key.Binding
	RightEdge   key.Binding
}

Keys is the pane's keymap for horizontal scroll. Each binding carries both its dispatch keys (WithKeys) and its help label (WithHelp); embedding components surface these in their own Help() so the hint strip stays honest when callers override defaults.

func DefaultKeys

func DefaultKeys() Keys

DefaultKeys returns the pane's stock h-scroll keymap.

func (*Keys) FillDefaults

func (k *Keys) FillDefaults()

FillDefaults fills any zero-valued binding in k with its DefaultKeys() counterpart. Exported so embedders (list/table/tree/inspector/logview) can call it on their nested pane.Keys field without re-implementing the merge.

type Options

type Options struct {
	Width, Height int
	Title         string
	// TitlePosition picks which border slot the title occupies. Defaults to
	// TopLeftBorder (the zero value).
	TitlePosition BorderPosition
	Focused       bool
	ActiveColor   lipgloss.TerminalColor
	InactiveColor lipgloss.TerminalColor
	// ActiveBorder is drawn when the Pane is focused. Defaults to
	// lipgloss.ThickBorder().
	ActiveBorder lipgloss.Border
	// InactiveBorder is drawn when the Pane is not focused. Defaults to
	// lipgloss.NormalBorder().
	InactiveBorder lipgloss.Border
	// SlotBrackets controls how the title and other border slot text are
	// bracketed against the border line. Defaults to SlotBracketsNone
	// (text sits inline on the border with no surrounding glyphs).
	SlotBrackets SlotBracketStyle
	// HScrollbar reserves a single row at the bottom of the inner content
	// area for a horizontal scrollbar. The thumb tracks xOffset against
	// the longest line; when content fits, the track renders blank.
	HScrollbar bool
	// Spinner picks the spinner frames used while the pane is in a
	// loading state (see SetLoading). When zero, defaults to spinner.Dot.
	Spinner *spinner.Spinner
	// SpinnerStyle is applied to the spinner glyph. The zero value
	// renders without any style; pass via theme.Pane() for a sensible
	// foreground.
	SpinnerStyle lipgloss.Style
	// LoadingLabel is rendered next to the spinner while loading. Use it
	// to give the user context — e.g. "loading cities…" or "fetching".
	LoadingLabel string

	// Keys overrides the pane's h-scroll keymap. Fields left zero fall
	// back to DefaultKeys(); embedders typically forward their own Keys
	// here so the user-facing override surface stays one struct per
	// component.
	Keys Keys
}

Options configures a new Pane. Zero-value fields fall back to defaults.

type Pane

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

Pane is a bordered region with a title, six metadata slots around the border, and a vertical scrollbar down the right edge.

func New

func New(opts Options) Pane

New constructs a Pane. SetContent must be called separately to populate it.

func (Pane) AtBottom

func (p Pane) AtBottom() bool

AtBottom reports whether the viewport is scrolled to the last line — useful for streaming-content components that auto-follow new output only while the user is parked at the bottom.

func (*Pane) EnsureVisible

func (p *Pane) EnsureVisible(n int)

EnsureVisible scrolls the viewport the minimum amount needed to put line `n` inside the visible window. Useful for cursor-driven list views, where moving the cursor past the viewport's bottom should pull the view with it.

func (Pane) Focused

func (p Pane) Focused() bool

Focused reports whether the pane is drawn in its active style.

func (*Pane) GotoBottom

func (p *Pane) GotoBottom()

GotoBottom scrolls the viewport to the last line.

func (*Pane) GotoTop

func (p *Pane) GotoTop()

GotoTop scrolls the viewport to the first line.

func (Pane) Height

func (p Pane) Height() int

Height returns the Pane's outer height.

func (Pane) HelpBindings

func (p Pane) HelpBindings() []key.Binding

HelpBindings returns the bindings to display in a component's hint strip — just the four pane keys (left/right move + edge jumps). The embedder appends these to its own Help() slice.

func (Pane) Init

func (p Pane) Init() tea.Cmd

func (Pane) Keys

func (p Pane) Keys() Keys

Keys returns the pane's h-scroll keymap. Embedding components include these in their own Help() so the hint strip surfaces h-scroll keys honestly (and reflects any caller overrides).

func (Pane) Loading

func (p Pane) Loading() bool

Loading reports whether the pane is currently in its loading state.

func (Pane) MaxXOffset

func (p Pane) MaxXOffset() int

MaxXOffset returns the largest meaningful horizontal scroll column — 0 when content fits in the inner width.

func (*Pane) SetActiveColor

func (p *Pane) SetActiveColor(c lipgloss.TerminalColor)

SetActiveColor updates the border color used when the pane is focused. Useful when reacting to a theme swap without rebuilding the model.

func (*Pane) SetBottomLeft

func (p *Pane) SetBottomLeft(s string)

func (*Pane) SetBottomMiddle

func (p *Pane) SetBottomMiddle(s string)

func (*Pane) SetBottomRight

func (p *Pane) SetBottomRight(s string)

SetBottomRight overrides the auto-generated scroll percentage. Pass "" to restore the default.

func (*Pane) SetContent

func (p *Pane) SetContent(s string)

SetContent replaces the pane's content. Pass any string — a child model's View() output, a pre-rendered table, a log, raw text — and the pane will scroll it. Long lines are truncated to the inner width so terminal wrap can't break row counting; use left/right (or SetXOffset) to scroll horizontally past the cut.

func (*Pane) SetDimensions

func (p *Pane) SetDimensions(width, height int)

SetDimensions sets the Pane's outer size (including border). The inner content area is sized as (width-2-scrollbar) × (height-2), shrunk by one more row when HScrollbar is enabled.

func (*Pane) SetFocused

func (p *Pane) SetFocused(b bool)

func (*Pane) SetInactiveColor

func (p *Pane) SetInactiveColor(c lipgloss.TerminalColor)

SetInactiveColor updates the border color used when the pane is unfocused.

func (*Pane) SetLoading

func (p *Pane) SetLoading(b bool) tea.Cmd

SetLoading toggles the loading state. When entering the loading state, returns the spinner's initial Tick command — propagate it back to bubbletea (typically by returning it from your screen's Update or batching with other commands) so the spinner animates. When leaving the loading state, returns nil; any in-flight TickMsg is silently dropped on the next Update.

func (*Pane) SetLoadingLabel

func (p *Pane) SetLoadingLabel(s string)

SetLoadingLabel updates the text shown next to the spinner while loading.

func (*Pane) SetSlotBrackets

func (p *Pane) SetSlotBrackets(s SlotBracketStyle)

SetSlotBrackets controls how the title and other slot text meet the border.

func (*Pane) SetSpinnerStyle

func (p *Pane) SetSpinnerStyle(s lipgloss.Style)

SetSpinnerStyle updates the lipgloss style applied to the spinner glyph. Useful for re-theming without rebuilding the pane.

func (*Pane) SetTitle

func (p *Pane) SetTitle(s string)

func (*Pane) SetTitlePosition

func (p *Pane) SetTitlePosition(pos BorderPosition)

func (*Pane) SetTopLeft

func (p *Pane) SetTopLeft(s string)

func (*Pane) SetTopRight

func (p *Pane) SetTopRight(s string)

func (*Pane) SetVirtualScroll

func (p *Pane) SetVirtualScroll(total, visible, offset int)

SetVirtualScroll overrides the right-edge scrollbar's source data. Instead of computing thumb size and position from the viewport's in-memory line count, the bar uses (total, visible, offset) directly — in any units the caller chooses, commonly logical row counts. Used by components that window their own content outside the viewport so the scrollbar still reflects the full dataset rather than the in-viewport slice (e.g. pkg/table reserves the top inner row for a sticky header and feeds the bar with len(rows) / dataRowsWindow / firstVisibleRow).

While virtual scroll is active the bottom-right "%" auto-fill is suppressed so the caller can paint a more meaningful indicator (e.g. "5 / 100") via SetBottomRight. Pass total <= 0 to disable and revert to viewport-driven metrics.

func (*Pane) SetXOffset

func (p *Pane) SetXOffset(n int)

SetXOffset jumps to the given horizontal scroll column, clamped into [0, MaxXOffset()].

func (*Pane) SetYOffset

func (p *Pane) SetYOffset(n int)

SetYOffset jumps to the given vertical scroll offset.

func (Pane) Update

func (p Pane) Update(msg tea.Msg) (Pane, tea.Cmd)

Update forwards key/mouse events to the embedded viewport so vertical scroll keys (pgup/pgdn/up/down/mouse wheel) work by default. Horizontal scroll keys are intercepted: left/h and right/l step by HScrollStep; 0 and home jump to the left edge; $ and end jump to the right edge. The content is re-cut to the visible window via ansi.Cut so ANSI styles stay intact across the slice. While loading, spinner.TickMsg events are consumed to advance the spinner; the chained next-tick command is returned so the animation keeps running.

func (Pane) View

func (p Pane) View() string

View renders the pane: content inside viewport, scrollbar on the right, both wrapped in a titled border with metadata slots. While loading, the inner content area is replaced with a centered spinner glyph (plus an optional label) and scroll chrome is suppressed.

func (Pane) VisibleRows

func (p Pane) VisibleRows() int

VisibleRows returns the inner viewport height — the number of content rows the pane can display at once, after subtracting borders and the horizontal scrollbar (when enabled). Useful for components that need to move a cursor by a window-relative amount (e.g. half-page jumps).

func (Pane) VisibleWidth

func (p Pane) VisibleWidth() int

VisibleWidth returns the inner viewport width — the number of visible cells the pane can display per row, after subtracting borders and the vertical scrollbar gutter. Useful for components that distribute horizontal space across sub-elements (e.g. flex columns).

func (Pane) Width

func (p Pane) Width() int

Width returns the Pane's outer width.

func (Pane) XOffset

func (p Pane) XOffset() int

XOffset returns the current horizontal scroll column.

func (Pane) YOffset

func (p Pane) YOffset() int

YOffset returns the current vertical scroll offset (top visible line).

type SlotBracketStyle

type SlotBracketStyle int

SlotBracketStyle controls how embedded slot text (titles, labels, scroll percentages) is bracketed against the surrounding border line.

const (
	// SlotBracketsNone draws the border edge straight through the slot region,
	// so text sits inline on the border line: `── text ──`. This is the
	// default — a titled pane reads as a plain rectangle with the title
	// floating on its top edge.
	SlotBracketsNone SlotBracketStyle = iota
	// SlotBracketsCorners wraps slot text with inverted corner glyphs so it
	// looks like a tab dipping into the pane: `┐ text ┌`. Matches pug's
	// aesthetic; useful when you want the title to read as a labeled tab.
	SlotBracketsCorners
	// SlotBracketsTees uses junction tees pointing into the slot text:
	// `─┤ text ├─`.
	SlotBracketsTees
)

Jump to

Keyboard shortcuts

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