treeview

package
v0.1.18 Latest Latest
Warning

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

Go to latest
Published: May 1, 2026 License: MIT Imports: 6 Imported by: 1

Documentation

Overview

Package treeview provides a hierarchical tree widget for displaying nested data structures such as file explorers, org charts, and configuration trees.

Construction uses functional options for immutable configuration:

root := &treeview.TreeNode{
    ID: "root", Label: "Root",
    Children: []*treeview.TreeNode{
        {ID: "child1", Label: "Child 1"},
        {ID: "child2", Label: "Child 2", Children: []*treeview.TreeNode{
            {ID: "grandchild", Label: "Grandchild"},
        }},
    },
}

tree := treeview.New(
    treeview.Root(root),
    treeview.ItemHeight(28),
    treeview.IndentWidth(20),
    treeview.ShowLines(true),
    treeview.SelectionModeOpt(treeview.SelectionSingle),
    treeview.OnSelect(func(node *treeview.TreeNode) { ... }),
    treeview.OnToggle(func(node *treeview.TreeNode, expanded bool) { ... }),
)

Tree Structure

The tree is built from TreeNode values. Each node has an ID, label, optional children, and an Expanded flag controlling whether its children are visible. The Data field carries arbitrary user payloads.

Virtualization

The tree flattens expanded nodes into a visible row list and renders only the rows within the viewport, enabling efficient display of large hierarchies. The flatten operation runs incrementally whenever the expanded state changes.

Keyboard Navigation

When focused, the tree supports full keyboard navigation:

  • Up/Down: move selection between visible rows
  • Left: collapse current node (or move to parent if leaf/collapsed)
  • Right: expand current node (or move to first child if expanded)
  • Enter/Space: activate OnSelect callback for current node
  • Home/End: jump to first/last visible row

Signal Binding

Tree properties can be bound to reactive signals from the state package.

Visual Style

The visual rendering (row backgrounds, selection highlights, expand icons, connector lines) is provided by a Painter implementation. Each design system supplies its own painter.

If no painter is set, DefaultPainter is used, which draws minimal visuals suitable for testing and prototyping.

Accessibility

TreeView implements a11y.Accessible with a11y.RoleTree. Keyboard navigation with arrow keys moves selection between visible nodes.

Focus

TreeView implements widget.Focusable and participates in tab navigation. When focused, arrow keys control selection and expand/collapse state.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ConnectorState

type ConnectorState struct {
	// RowBounds is the full row bounding rectangle.
	RowBounds geometry.Rect

	// Depth is the nesting level of this row.
	Depth int

	// IndentWidth is the pixel offset per nesting level.
	IndentWidth float32

	// IsLastChild is true if this node is the last child of its parent.
	IsLastChild bool

	// HasChildren is true if this node has children (branch node).
	HasChildren bool

	// ParentHasMore indicates which ancestor levels still have more
	// siblings below. Index 0 = depth 1, index 1 = depth 2, etc.
	// Used to draw vertical continuation lines.
	ParentHasMore []bool

	// ColorScheme provides theme-derived colors.
	ColorScheme TreeColorScheme
}

ConnectorState provides context for drawing tree connector lines.

type DefaultPainter

type DefaultPainter struct{}

DefaultPainter provides a minimal fallback painter with no design system styling. It draws simple tree visuals -- useful for testing and as a base reference.

func (DefaultPainter) PaintConnectorLines

func (p DefaultPainter) PaintConnectorLines(canvas widget.Canvas, s ConnectorState)

PaintConnectorLines draws L-shaped connector lines for tree hierarchy.

func (DefaultPainter) PaintEmptyState

func (p DefaultPainter) PaintEmptyState(canvas widget.Canvas, bounds geometry.Rect)

PaintEmptyState draws a centered "No items" message.

func (DefaultPainter) PaintExpandIcon

func (p DefaultPainter) PaintExpandIcon(canvas widget.Canvas, s ExpandIconState)

PaintExpandIcon draws a simple triangle expand/collapse icon.

func (DefaultPainter) PaintLabel

func (p DefaultPainter) PaintLabel(canvas widget.Canvas, s LabelState)

PaintLabel draws the node label text.

func (DefaultPainter) PaintRowBackground

func (p DefaultPainter) PaintRowBackground(canvas widget.Canvas, s RowPaintState)

PaintRowBackground draws the hover highlight for a tree row.

func (DefaultPainter) PaintSelection

func (p DefaultPainter) PaintSelection(canvas widget.Canvas, s RowPaintState)

PaintSelection draws the selection highlight for a selected row.

type ExpandIconState

type ExpandIconState struct {
	// Bounds is the bounding rectangle for the expand icon.
	Bounds geometry.Rect

	// Expanded is true if the node is currently expanded.
	Expanded bool

	// Hovered is true if the mouse cursor is over this row.
	Hovered bool

	// ColorScheme provides theme-derived colors.
	ColorScheme TreeColorScheme
}

ExpandIconState provides context for expand/collapse icon painting.

type LabelState

type LabelState struct {
	// Bounds is the bounding rectangle for the label text.
	Bounds geometry.Rect

	// Text is the label text.
	Text string

	// Selected is true if this row is selected.
	Selected bool

	// Disabled is true if the tree is disabled.
	Disabled bool

	// ColorScheme provides theme-derived colors.
	ColorScheme TreeColorScheme
}

LabelState provides context for drawing the node label.

type Option

type Option func(*config)

Option configures a tree view during construction.

func A11yLabel

func A11yLabel(label string) Option

A11yLabel sets the accessibility label for the tree.

func Disabled

func Disabled(d bool) Option

Disabled sets the tree view's disabled state.

func DisabledFn

func DisabledFn(fn func() bool) Option

DisabledFn sets a dynamic function for the disabled state. When set, this takes precedence over Disabled but not over DisabledSignal.

func DisabledReadonlySignal

func DisabledReadonlySignal(sig state.ReadonlySignal[bool]) Option

DisabledReadonlySignal binds the disabled state to a read-only signal. When set, this takes highest precedence over all other disabled sources.

func DisabledSignal

func DisabledSignal(sig state.Signal[bool]) Option

DisabledSignal binds the disabled state to a reactive signal. When set, the signal takes precedence over DisabledFn and Disabled but not over DisabledReadonlySignal.

func IndentWidth

func IndentWidth(w float32) Option

IndentWidth sets the horizontal offset per nesting level (pixels). Default: 20.

func ItemHeight

func ItemHeight(h float32) Option

ItemHeight sets the fixed height for each row in the tree (pixels). Default: 28.

func OnSelect

func OnSelect(fn func(node *TreeNode)) Option

OnSelect sets the callback invoked when a node is activated (clicked or Enter).

func OnToggle

func OnToggle(fn func(node *TreeNode, expanded bool)) Option

OnToggle sets the callback invoked when a node's expanded state changes.

func PainterOpt

func PainterOpt(p Painter) Option

PainterOpt sets the painter used to render tree-specific visuals. Each design system provides its own painter. If not set, DefaultPainter is used.

func Root

func Root(root *TreeNode) Option

Root sets the root node of the tree.

func RootReadonlySignal

func RootReadonlySignal(sig state.ReadonlySignal[*TreeNode]) Option

RootReadonlySignal binds the root node to a read-only signal. When set, this takes highest precedence over all other root sources.

func RootSignal

func RootSignal(sig state.Signal[*TreeNode]) Option

RootSignal binds the root node to a reactive signal. When set, the signal takes precedence over Root but not over RootReadonlySignal.

func SelectedNodeID

func SelectedNodeID(id string) Option

SelectedNodeID sets the initially selected node by ID. Use "" for no selection.

func SelectedNodeReadonlySignal

func SelectedNodeReadonlySignal(sig state.ReadonlySignal[string]) Option

SelectedNodeReadonlySignal binds the selected node ID to a read-only signal. When set, this takes highest precedence over all other selection sources.

func SelectedNodeSignal

func SelectedNodeSignal(sig state.Signal[string]) Option

SelectedNodeSignal binds the selected node ID to a reactive signal. This is a TWO-WAY binding: the widget reads from the signal, and when the user selects a node, the new ID is written back.

func SelectionModeOpt

func SelectionModeOpt(mode SelectionMode) Option

SelectionModeOpt sets the selection mode for the tree. Default is SelectionNone.

func ShowLines

func ShowLines(enabled bool) Option

ShowLines enables connector lines between parent and child nodes.

type Painter

type Painter interface {
	// PaintRowBackground draws the background for a tree row.
	// Called before the row label is drawn.
	PaintRowBackground(canvas widget.Canvas, state RowPaintState)

	// PaintSelection draws the selection highlight for a selected row.
	// Called before the row label is drawn.
	PaintSelection(canvas widget.Canvas, state RowPaintState)

	// PaintExpandIcon draws the expand/collapse indicator for branch nodes.
	PaintExpandIcon(canvas widget.Canvas, state ExpandIconState)

	// PaintConnectorLines draws the tree connector lines (if enabled).
	PaintConnectorLines(canvas widget.Canvas, state ConnectorState)

	// PaintLabel draws the node label text.
	PaintLabel(canvas widget.Canvas, state LabelState)

	// PaintEmptyState draws placeholder content when the tree has no root.
	PaintEmptyState(canvas widget.Canvas, bounds geometry.Rect)
}

Painter draws tree-specific visual elements. Each design system (Material 3, Fluent, Cupertino) provides its own Painter implementation to render the tree in its visual style.

If no Painter is set, the tree view uses DefaultPainter.

type RowPaintState

type RowPaintState struct {
	// Bounds is the full row bounding rectangle.
	Bounds geometry.Rect

	// Node is the tree node for this row.
	Node *TreeNode

	// Depth is the nesting level (0 = root).
	Depth int

	// Selected is true if this row is the currently selected node.
	Selected bool

	// Focused is true if the tree has keyboard focus and this row is selected.
	Focused bool

	// Hovered is true if the mouse cursor is over this row.
	Hovered bool

	// Disabled is true if the tree is disabled.
	Disabled bool

	// ColorScheme provides theme-derived colors.
	ColorScheme TreeColorScheme
}

RowPaintState provides context for row background and selection painting.

type SelectionMode

type SelectionMode uint8

SelectionMode defines how nodes can be selected in the tree.

const (
	// SelectionNone disables node selection. This is the default.
	SelectionNone SelectionMode = iota

	// SelectionSingle allows at most one node to be selected at a time.
	SelectionSingle
)

SelectionMode constants.

func (SelectionMode) String

func (m SelectionMode) String() string

String returns a human-readable name for the selection mode.

type TreeColorScheme

type TreeColorScheme struct {
	SelectionColor widget.Color // selected row background
	HoverColor     widget.Color // hovered row background
	FocusColor     widget.Color // focused row border/background
	LabelColor     widget.Color // default label text color
	LineColor      widget.Color // connector line color
	IconColor      widget.Color // expand/collapse icon color
	EmptyTextColor widget.Color // empty state text color
}

TreeColorScheme provides theme-derived colors for tree painting. Zero value means the painter should use its built-in defaults.

type TreeNode

type TreeNode struct {
	// ID uniquely identifies this node within the tree.
	// Must be unique across all nodes.
	ID string

	// Label is the display text for this node.
	Label string

	// Children are this node's child nodes. Nil or empty means leaf.
	Children []*TreeNode

	// Expanded controls whether this node's children are visible.
	// Only meaningful for branch nodes (len(Children) > 0).
	Expanded bool

	// Data carries an arbitrary user payload.
	Data interface{}
}

TreeNode represents a node in the hierarchical tree.

Each node has a unique ID, a display label, optional children, and an Expanded flag controlling child visibility. The Data field carries arbitrary user payloads.

Nodes form a tree: a node with non-nil Children is a branch node; one with nil or empty Children is a leaf.

func (*TreeNode) IsLeaf

func (n *TreeNode) IsLeaf() bool

IsLeaf reports whether this node has no children.

type Widget

type Widget struct {
	widget.WidgetBase
	// contains filtered or unexported fields
}

Widget implements a hierarchical tree view with expand/collapse per node, keyboard navigation, virtualization, and pluggable painting.

Create with New using functional options:

tree := treeview.New(
    treeview.Root(root),
    treeview.ItemHeight(28),
    treeview.IndentWidth(20),
    treeview.SelectionModeOpt(treeview.SelectionSingle),
    treeview.OnSelect(func(node *treeview.TreeNode) { ... }),
)

func New

func New(opts ...Option) *Widget

New creates a new tree view Widget with the given options.

The returned widget is visible, enabled, and focusable by default.

func (*Widget) AccessibilityActions

func (w *Widget) AccessibilityActions() []a11y.Action

AccessibilityActions returns the list of supported actions.

func (*Widget) AccessibilityHint

func (w *Widget) AccessibilityHint() string

AccessibilityHint returns the accessibility hint.

func (*Widget) AccessibilityLabel

func (w *Widget) AccessibilityLabel() string

AccessibilityLabel returns the accessibility label.

func (*Widget) AccessibilityRole

func (w *Widget) AccessibilityRole() a11y.Role

AccessibilityRole returns the ARIA role for this widget.

func (*Widget) AccessibilityState

func (w *Widget) AccessibilityState() a11y.State

AccessibilityState returns the current accessibility state.

func (*Widget) AccessibilityValue

func (w *Widget) AccessibilityValue() string

AccessibilityValue returns the current tree state as a string.

func (*Widget) Children

func (w *Widget) Children() []widget.Widget

Children returns nil (tree view is a leaf widget with internal rendering).

func (*Widget) CollapseAll

func (w *Widget) CollapseAll()

CollapseAll collapses all branch nodes in the tree.

func (*Widget) Draw

func (w *Widget) Draw(ctx widget.Context, canvas widget.Canvas)

Draw renders the tree view to the canvas.

func (*Widget) Event

func (w *Widget) Event(ctx widget.Context, e event.Event) bool

Event handles an input event and returns true if consumed.

func (*Widget) ExpandAll

func (w *Widget) ExpandAll()

ExpandAll expands all branch nodes in the tree.

func (*Widget) InvalidateData

func (w *Widget) InvalidateData()

InvalidateData signals that the tree data has changed. Rebuilds the flattened row list.

func (*Widget) IsFocusable

func (w *Widget) IsFocusable() bool

IsFocusable reports whether the tree view can currently receive focus.

func (*Widget) Layout

func (w *Widget) Layout(_ widget.Context, constraints geometry.Constraints) geometry.Size

Layout calculates the tree view's size within the given constraints.

func (*Widget) Mount

func (w *Widget) Mount(ctx widget.Context)

Mount creates signal bindings for push-based invalidation. Implements widget.Lifecycle.

func (*Widget) RowCount

func (w *Widget) RowCount() int

RowCount returns the number of currently visible (flattened) rows.

func (*Widget) ScrollToNode

func (w *Widget) ScrollToNode(id string)

ScrollToNode scrolls to make the node with the given ID visible. If the node is not in the flattened visible list, this is a no-op.

func (*Widget) Unmount

func (w *Widget) Unmount()

Unmount is called when the tree view is removed from the widget tree. Implements widget.Lifecycle.

func (*Widget) VisibleRange

func (w *Widget) VisibleRange() (start, end int)

VisibleRange returns the indices [start, end) of currently visible rows.

Jump to

Keyboard shortcuts

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