pane

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: 8 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 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
}

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) Init

func (p Pane) Init() tea.Cmd

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