tree

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 tree provides a searchable, expand/collapse hierarchical view inside a bordered pane. It accepts any data shape that satisfies the minimal Node interface (Label + Children) and renders a flat list of visible rows with depth-aware indentation, a "▸/▾" expand glyph, and a cursor.

Use it for file trees, JSON browsers, nested categories — anything where the user wants to drill into a hierarchy. The body is a pkg/pane.Pane (so pgup/pgdn/arrows/mouse-wheel and horizontal scroll work out of the box) plus an optional pkg/filter.Model for the "/-to-search" overlay.

Features:

  • Cursor + scroll across the flat visible-row slice
  • Right/l expand or descend into the cursor's children; left/h collapse or jump to the parent; space toggles the cursor; enter selects; E expands every node in the tree, C collapses everything back to root
  • "/" focuses an embedded filter (case-insensitive substring against Label()); matches highlight inline with MatchStyle
  • "\" toggles filter mode: when on, only matching nodes (and their ancestors, so the path stays readable) are shown; n/N step through matches
  • InitialDepth controls how deep the tree starts pre-expanded

Items are caller-owned via the Node interface — copy from your own data shape without forcing tuilib's structs into your domain model.

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 tree widget. Embed by value; mutate via the setters.

func New

func New(opts Options) Model

New constructs a tree. Call Update/View from the parent model.

func (Model) Cursor

func (m Model) Cursor() int

Cursor returns the current row index.

func (Model) FilterMode

func (m Model) FilterMode() bool

FilterMode reports whether non-matching subtrees are currently hidden.

func (Model) Help

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

Help returns the keys this tree responds to. While the embedded filter is focused, returns the filter's keys.

func (Model) Init

func (m Model) Init() tea.Cmd

Init satisfies tea.Model.

func (Model) Loading

func (m Model) Loading() bool

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

func (Model) Query

func (m Model) Query() string

Query returns the current search text.

func (Model) Searching

func (m Model) Searching() bool

Searching reports whether the embedded filter currently has focus.

func (Model) Selected

func (m Model) Selected() (Node, bool)

Selected returns the node under the cursor. ok is false when the visible row set is empty (e.g. filter mode with no matches).

func (*Model) SetActiveColor

func (m *Model) SetActiveColor(c lipgloss.TerminalColor)

SetActiveColor updates the body pane's active border color.

func (*Model) SetCurrentLineStyle

func (m *Model) SetCurrentLineStyle(s lipgloss.Style)

SetCurrentLineStyle updates the row style applied under the cursor.

func (*Model) SetCursor

func (m *Model) SetCursor(n int)

SetCursor moves the cursor (clamped to the visible range) and scrolls to keep it on screen.

func (*Model) SetDimensions

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

SetDimensions resizes the tree in place.

func (*Model) SetFilterMode

func (m *Model) SetFilterMode(b bool)

SetFilterMode turns filter-only rendering on or off.

func (*Model) SetFocused

func (m *Model) SetFocused(b bool)

SetFocused flips the body pane's focus state.

func (*Model) SetInactiveColor

func (m *Model) SetInactiveColor(c lipgloss.TerminalColor)

SetInactiveColor updates the body pane's inactive border color.

func (*Model) SetLoading

func (m *Model) SetLoading(b bool) tea.Cmd

SetLoading toggles the loading state. When entering, returns the spinner's initial Tick command — propagate it back from your screen's Update so the spinner animates.

func (*Model) SetLoadingLabel

func (m *Model) SetLoadingLabel(s string)

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

func (*Model) SetMatchStyle

func (m *Model) SetMatchStyle(s lipgloss.Style)

SetMatchStyle updates the highlight style applied to matched substrings.

func (*Model) SetQuery

func (m *Model) SetQuery(s string)

SetQuery sets the search text programmatically.

func (*Model) SetRoot

func (m *Model) SetRoot(n Node)

SetRoot replaces the underlying tree, resets the expand state to InitialDepth=1 (root expanded), and rebuilds.

func (*Model) SetSpinnerStyle

func (m *Model) SetSpinnerStyle(s lipgloss.Style)

SetSpinnerStyle updates the lipgloss style applied to the spinner glyph.

func (*Model) SetTitle

func (m *Model) SetTitle(s string)

SetTitle sets the pane's top-left title.

func (Model) Update

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

Update handles cursor movement, expand/collapse, search, and forwards everything else to the body pane (so pgup/pgdn/arrows/mouse-wheel and horizontal scroll keep working).

func (Model) View

func (m Model) View() string

View stacks the filter (when searchable) above the body pane.

type Node

type Node interface {
	Label() string
	Children() []Node
}

Node is the minimal contract a caller's data must satisfy. Label is the row's display text; Children returns the immediate descendants (nil or empty for leaves). Tree never mutates the returned slice.

type Options

type Options struct {
	Width, Height int
	// Title sits on the pane's top-left border slot. Defaults to "tree".
	Title string
	// Root is the top-level node. Its own label is rendered as the first
	// row; pass a synthetic root if your data has multiple top-level items.
	Root Node
	// Searchable embeds a filter.Model above the body pane (three rows). If
	// false, "/" is ignored and the full height is used for the tree.
	Searchable bool
	// InitialDepth pre-expands every node whose depth is < InitialDepth.
	// 0 (default) shows only the root collapsed, 1 expands the root,
	// 2 expands the root and its direct children, etc.
	InitialDepth int

	// MatchStyle is the lipgloss style applied to matched substrings while
	// a query is active. Pass via theme.Tree() for a sensible default.
	MatchStyle lipgloss.Style

	// CurrentLineStyle is applied to the entire row holding the cursor,
	// padded out to the pane's inner width. theme.Tree() seeds a subtle
	// background.
	CurrentLineStyle lipgloss.Style

	// Pane pass-throughs. See pkg/pane.Options for defaults.
	ActiveColor    lipgloss.TerminalColor
	InactiveColor  lipgloss.TerminalColor
	ActiveBorder   lipgloss.Border
	InactiveBorder lipgloss.Border
	SlotBrackets   pane.SlotBracketStyle
	HScrollbar     bool

	// SpinnerStyle is applied to the spinner glyph rendered while the
	// tree is in its loading state (see SetLoading). Pass via theme.Tree()
	// for a sensible default.
	SpinnerStyle lipgloss.Style
	// LoadingLabel is rendered next to the spinner while loading.
	LoadingLabel string

	// Filter configures the embedded filter. Ignored when Searchable=false.
	Filter filter.Options
}

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

Jump to

Keyboard shortcuts

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