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
- func Borderize(content string, border lipgloss.Border, color lipgloss.TerminalColor, ...) string
- func HScrollbar(width, total, visible, offset int) string
- func Scrollbar(height, total, visible, offset int) string
- type BorderPosition
- type Keys
- type Options
- type Pane
- func (p Pane) AtBottom() bool
- func (p Pane) ContentRect() geom.Rect
- func (p *Pane) EnsureVisible(n int)
- func (p Pane) Focused() bool
- func (p *Pane) GotoBottom()
- func (p *Pane) GotoTop()
- func (p Pane) HScrollbarRect() geom.Rect
- func (p *Pane) HandleScrollbar(e mouse.Msg) (row int, ok bool)
- func (p Pane) Height() int
- func (p Pane) HelpBindings() []key.Binding
- func (p Pane) Init() tea.Cmd
- func (p Pane) Keys() Keys
- func (p Pane) Loading() bool
- func (p Pane) MaxXOffset() int
- func (p Pane) Rect() geom.Rect
- func (p Pane) RowAt(x, y int) (row int, ok bool)
- func (p *Pane) ScrollWheel(x, y int, up bool) bool
- func (p Pane) ScrollbarDrag() bool
- func (p *Pane) SetActiveColor(c lipgloss.TerminalColor)
- func (p *Pane) SetBottomLeft(s string)
- func (p *Pane) SetBottomMiddle(s string)
- func (p *Pane) SetBottomRight(s string)
- func (p *Pane) SetContent(s string)
- func (p *Pane) SetFocused(b bool)
- func (p *Pane) SetInactiveColor(c lipgloss.TerminalColor)
- func (p *Pane) SetLoading(b bool) tea.Cmd
- func (p *Pane) SetLoadingLabel(s string)
- func (p *Pane) SetRect(r geom.Rect)
- func (p *Pane) SetSlotBrackets(s SlotBracketStyle)
- func (p *Pane) SetSpinnerStyle(s lipgloss.Style)
- func (p *Pane) SetTitle(s string)
- func (p *Pane) SetTitlePosition(pos BorderPosition)
- func (p *Pane) SetTopLeft(s string)
- func (p *Pane) SetTopRight(s string)
- func (p *Pane) SetVirtualScroll(total, visible, offset int)
- func (p *Pane) SetXOffset(n int)
- func (p *Pane) SetYOffset(n int)
- func (p Pane) Update(msg tea.Msg) (Pane, tea.Cmd)
- func (p Pane) VScrollbarRect() geom.Rect
- func (p Pane) View() string
- func (p Pane) VisibleRows() int
- func (p Pane) VisibleWidth() int
- func (p Pane) Width() int
- func (p Pane) XOffset() int
- func (p Pane) YOffset() int
- type SlotBracketStyle
Constants ¶
const ( ScrollbarWidth = 1 ScrollbarHeight = 1 )
const HScrollStep = 4
HScrollStep is how many cells left/right scroll the pane horizontally.
const WheelStep = 3
WheelStep is how many lines one wheel notch scrolls. Three matches the convention terminals and GUI toolkits share.
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 ¶
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 ¶
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 ¶
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 (*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 (Pane) AtBottom ¶
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) ContentRect ¶ added in v0.18.0
ContentRect returns the rect covering the Pane's inner content area — the outer rect less the border, the right-edge scrollbar, and the horizontal scrollbar row when enabled. It is the region row 0 of the content occupies, so RowAt inverts against it.
func (*Pane) EnsureVisible ¶
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) GotoBottom ¶
func (p *Pane) GotoBottom()
GotoBottom scrolls the viewport to the last line.
func (Pane) HScrollbarRect ¶ added in v0.18.0
HScrollbarRect returns the rect of the horizontal scrollbar row, drawn below the body when HScrollbar is enabled. Empty when it isn't.
func (*Pane) HandleScrollbar ¶ added in v0.18.0
HandleScrollbar processes a mouse event against the Pane's scrollbars. Components call it first from their own mouse handling, so a click on the bar scrolls rather than selecting the row behind it.
ok reports whether the event was a scrollbar interaction at all. row is the content row the interaction targets — meaningful only when ok is true.
For a pane that scrolls its own viewport, the scroll is already applied and row can be ignored. For a component that windows its rows itself (pkg/table and pkg/inspector push metrics through SetVirtualScroll, and derive their window from the cursor), nothing is applied: moving the viewport under such a component would be undone on its next render, so it must move its cursor to row instead.
Pressing anywhere on the track jumps there, the thumb included — grabbing the thumb is a jump to where it already is, which leaves it put. Motion while the button is held keeps jumping, which is what makes it a drag. The pane tracks that state itself because the release can land outside the bar, or outside the pane entirely, and must still end the drag.
func (Pane) HelpBindings ¶
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) 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) MaxXOffset ¶
MaxXOffset returns the largest meaningful horizontal scroll column — 0 when content fits in the inner width.
func (Pane) Rect ¶ added in v0.18.0
Rect returns the outer rect the Pane was last placed at, border included.
func (Pane) RowAt ¶ added in v0.18.0
RowAt maps a terminal position to a zero-based index into the Pane's content, accounting for the border inset and the current vertical scroll. It reports ok=false when the position is outside the content area or the Pane wasn't drawn in the current frame, so a caller can forward the event on rather than claiming it.
func (*Pane) ScrollWheel ¶ added in v0.18.0
ScrollWheel applies a wheel event to the Pane's vertical scroll and reports whether it was consumed. It is the shared implementation for components that scroll the pane rather than moving a cursor — logview, textview, and a bare pane. Events outside the content area, or aimed at a Pane that wasn't drawn this frame, are declined so a sibling can claim them.
bubbles' viewport handles the wheel on tea.MouseMsg, but tuilib components receive mouse.Msg (which carries the resolved click count), so that path never fires — this is where wheel scrolling actually happens.
func (Pane) ScrollbarDrag ¶ added in v0.18.0
ScrollbarDrag reports whether a scrollbar drag is in progress.
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 (*Pane) SetBottomMiddle ¶
func (*Pane) SetBottomRight ¶
SetBottomRight overrides the auto-generated scroll percentage. Pass "" to restore the default.
func (*Pane) SetContent ¶
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) SetFocused ¶
func (*Pane) SetInactiveColor ¶
func (p *Pane) SetInactiveColor(c lipgloss.TerminalColor)
SetInactiveColor updates the border color used when the pane is unfocused.
func (*Pane) SetLoading ¶
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 ¶
SetLoadingLabel updates the text shown next to the spinner while loading.
func (*Pane) SetRect ¶ added in v0.18.0
SetRect places the Pane at an absolute position and 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.
The rect is retained so the Pane and the components embedding it can map a mouse position back to a content row — see Rect and ContentRect.
func (*Pane) SetSlotBrackets ¶
func (p *Pane) SetSlotBrackets(s SlotBracketStyle)
SetSlotBrackets controls how the title and other slot text meet the border.
func (*Pane) SetSpinnerStyle ¶
SetSpinnerStyle updates the lipgloss style applied to the spinner glyph. Useful for re-theming without rebuilding the pane.
func (*Pane) SetTitlePosition ¶
func (p *Pane) SetTitlePosition(pos BorderPosition)
func (*Pane) SetTopLeft ¶
func (*Pane) SetTopRight ¶
func (*Pane) SetVirtualScroll ¶
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 ¶
SetXOffset jumps to the given horizontal scroll column, clamped into [0, MaxXOffset()].
func (*Pane) SetYOffset ¶
SetYOffset jumps to the given vertical scroll offset.
func (Pane) Update ¶
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) VScrollbarRect ¶ added in v0.18.0
VScrollbarRect returns the rect of the vertical scrollbar column, which View draws immediately right of the viewport.
func (Pane) View ¶
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 ¶
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 ¶
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).
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 )