list

package
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package list is a scrollable, single-selection list of pre-rendered rows. Its defining property is that the selected item (cursor) is tracked independently of the scroll offset: moving the cursor adjusts the offset only enough to keep the selection visible, and a resize never loses the selection. Rows are opaque strings, so the component is decoupled from how a caller styles them - it owns only the selection/scroll math and an optional scrollbar.

WithSearch adds a type-to-filter line above the rows: typing narrows the list fzf-style (every printable key feeds the filter, arrows navigate), and the caller reads Model.Selected on its own submit key - the list never consumes enter or esc. Matching is a case-insensitive substring test against each row's visible (ANSI-stripped) text, and selection reports the original row index, so the caller keeps its own parallel value slice.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Model

type Model struct {

	// Styles style the cursor row and placeholders.
	Styles Styles
	// Scrollbar draws a proportional scrollbar column when the list overflows.
	Scrollbar bool
	// contains filtered or unexported fields
}

Model is a list viewport over caller-rendered rows.

func New

func New(opts ...Option) *Model

New returns a list with a sensible default cursor highlight. It returns a pointer because every mutating method has a pointer receiver.

func (*Model) Bottom

func (m *Model) Bottom()

Bottom selects the last visible row.

func (*Model) Cursor

func (m *Model) Cursor() int

Cursor returns the original index of the selected row, or -1 when nothing is selectable (the list is empty, or a search filter matches nothing).

func (*Model) CursorLine

func (m *Model) CursorLine() int

CursorLine returns the cursor row's line offset within View - the filter line, when showing, counts as a line above it - or -1 when nothing is selectable. It is the region a dialog scroll hint reports so an outer viewport keeps the selection visible when a taller-than-the-box list scrolls inside it.

func (*Model) Len

func (m *Model) Len() int

Len returns the total number of rows, ignoring any active filter.

func (*Model) MoveDown

func (m *Model) MoveDown(n int)

MoveDown moves the cursor down by n (n may be negative).

func (*Model) MoveUp

func (m *Model) MoveUp(n int)

MoveUp moves the cursor up by n.

func (*Model) PageDown

func (m *Model) PageDown()

PageDown moves the cursor down by a viewport height.

func (*Model) PageUp

func (m *Model) PageUp()

PageUp moves the cursor up by a viewport height.

func (*Model) Selected

func (m *Model) Selected() (int, bool)

Selected returns the original index of the row under the cursor; ok is false when nothing is selectable.

func (*Model) SetCursor

func (m *Model) SetCursor(i int)

SetCursor selects visible position i (equal to the row index when no filter is active), clamping to range and scrolling it into view.

func (*Model) SetRows

func (m *Model) SetRows(rows []string)

SetRows replaces the rows, refilters when searching, and clamps the cursor/offset to the new length so the selection stays valid (and visible) when the data shrinks.

func (*Model) SetSize

func (m *Model) SetSize(width, height int)

SetSize sets the viewport dimensions and reclamps so the cursor stays visible. height is the total view height: when the filter line is showing, one row of it goes to the filter.

func (*Model) Top

func (m *Model) Top()

Top selects the first visible row.

func (*Model) Update

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

Update routes messages when searching: up/down move the cursor and everything else (typing, paste, cursor movement inside the filter) goes to the filter input. Arrow keys match on Code, not String(), so modified arrows keep working; every printable key belongs to the filter (fzf semantics), so letter aliases like j/k are deliberately not navigation here. Enter and esc are deliberately not handled - submit/cancel belong to the caller. Without search, Update is a no-op: the caller drives the cursor through the Move methods.

func (*Model) View

func (m *Model) View() string

View renders the filter line (once the user typed something) and the visible rows, highlighting the cursor row and appending a scrollbar column when the list overflows and Scrollbar is enabled. Rows are padded/truncated to the content width (viewport width minus the scrollbar column) so the cursor highlight spans the full row and the output never exceeds the declared width.

func (*Model) VisibleRange

func (m *Model) VisibleRange() (int, int)

VisibleRange returns the [start, end) visible-list positions currently on screen.

type Option

type Option func(*Model)

Option configures a Model.

func WithSearch

func WithSearch() Option

WithSearch adds the type-to-filter line: every printable key routed through Update feeds the filter, up/down move the cursor, and the visible rows are the matching subset.

type Styles

type Styles struct {
	// Cursor highlights the selected row. New defaults it to reverse video.
	Cursor lg.Style
	// Dim styles the "(no match)" placeholder shown when a search filter
	// matches nothing.
	Dim lg.Style
}

Styles are the list's injected render styles.

Jump to

Keyboard shortcuts

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