Help us shape the future of Go! Take the 2026 Go Developer Survey

card

package
v0.3.3 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package card is AutoDoc's native UI kit for dialog and card plugins (ADR 1792254331): a plugin describes what its card shows as a Page of blocks and controls, and a Card fits it to the size AutoDoc gives, draws it in the theme's colours, and handles the keys, the focus and the pointer.

The controls (Input, Buttons, List, Tree) are values the plugin keeps between draws; the Card asks for the page afresh on every draw, so the screen is always the plugin's state:

type myPlugin struct {
	peer *plugin.Peer
	card *card.Card
	name card.Input
	ok   card.Buttons
}

func (p *myPlugin) page() card.Page {
	return card.Page{
		Title:   "Hello",
		Header:  []card.Block{card.Line(card.Title, "Who are you?")},
		Body:    []card.Block{&p.name},
		Buttons: &p.ok,
		Keys:    "Tab: move · Enter: greet · q: close",
	}
}

A plugin forwards its Handler's methods to the Card (Open, Resize, Theme, Focus, Pointer, and Key, keeping the keys the Card does not use). The Card's methods run on the Handler's goroutine only, as the plugin's own state does.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Block

type Block interface {
	// contains filtered or unexported methods
}

Block is one part of a page. Only the kit makes them: Text, Line, Blank, and the controls.

func Blank

func Blank() Block

Blank is an empty row.

func Line

func Line(r Role, s string) Block

Line is one row in r, cut with … at the card's width.

func Text

func Text(r Role, s string) Block

Text is a paragraph in r, wrapped at spaces to the card's width; a word wider than a row breaks after its last / or -, else at the row's end. A newline starts a new row.

type Buttons

type Buttons struct {
	Labels  []string
	OnPress func(i int) // Enter, Space, or a left press
	// contains filtered or unexported fields
}

Buttons are a row of buttons, "[ label ]" each, centred, wrapping as words do.

func (*Buttons) Focused

func (b *Buttons) Focused() int

Focused is the button that has the focus when the Buttons do.

type Card

type Card struct {
	// contains filtered or unexported fields
}

Card is a plugin's card or dialog: its size, theme and focus, the page it shows, and the control with the focus. Its methods run on the Handler's goroutine only.

func New

func New(page func() Page, o Options) *Card

New is a Card showing page(), asked for afresh on every draw.

func (*Card) Attach

func (c *Card) Attach(h Host, w, hh int, t plugin.Theme)

Attach is Open with any Host: a test's, say.

func (*Card) Draw

func (c *Card) Draw()

Draw sends the card as it stands: the page laid out to the size AutoDoc last gave, and the title when it has changed.

func (*Card) Focus

func (c *Card) Focus(focused bool)

Focus is plugin.focus: the card took AutoDoc's keys, or gave them back. A modal one ignores it.

func (*Card) FocusOn

func (c *Card) FocusOn(ctl Control)

FocusOn gives ctl the focus, and draws.

func (*Card) Focused

func (c *Card) Focused() Control

Focused is the control with the focus; nil when the page has none.

func (*Card) Key

func (c *Card) Key(k plugin.Key) bool

Key is a key typed into the card. It returns true when the card used it, and has drawn; false leaves it to the plugin: its own letters, q to close (never while an Input has the keys, where q is text).

any control      Tab / Shift+Tab     the next / previous control, wrapping; every button of a
                                     Buttons bar is a stop of its own
Input            text                inserted at the cursor (an IME commit or a paste, whole)
                 Backspace Delete Left Right Home End    edit, move the cursor
                 Ctrl+U              Clear
                 Up / Down           the previous / next control
                 Enter               OnEnter, else the next control
Buttons          Left / Right        the previous / next button
                 Enter / Space       OnPress
                 Up / Down           the previous / next control
List, Tree       Up k, Down j        the selection
                 PageUp Ctrl+U, PageDown Ctrl+D          half the card's height
                 Home g, End G       the first, the last row
List             Enter               OnEnter(Sel); nothing on an empty list
Tree             Right l             open (OnOpen first); on an open node, its first row
                 Left h              close; on a closed node or a leaf, the row holding it
                 Enter               OnEnter; when it returns false, open or close

func (*Card) Open

func (c *Card) Open(p *plugin.Peer, o plugin.Open)

Open is plugin.open: the card draws to p at the size and in the theme given.

func (*Card) Pointer

func (c *Card) Pointer(at plugin.Pointer) bool

Pointer is a left press or a wheel step on the card (protocol 6), read against the last draw. It returns true when the card used it, and has drawn.

press, left, on an Input's row        focus it
press, left, on a button              focus the Buttons on it, and OnPress it
press, left, on a List or Tree row    focus it, and select that row
wheel                                 the focused List's or Tree's selection, 3 rows a step
                                      (48 at most); with neither focused, the body scrolls

func (*Card) Resize

func (c *Card) Resize(w, h int)

Resize is plugin.resize.

func (*Card) Theme

func (c *Card) Theme(t plugin.Theme)

Theme is plugin.theme.

func (*Card) Typing

func (c *Card) Typing() bool

Typing reports whether an Input has the focus: every printable key is then text, q too.

type Control

type Control interface {
	Block
	// contains filtered or unexported methods
}

Control is a block that takes focus: *Input, *Buttons, *List, *Tree.

type Host

type Host interface {
	Frame(*plugin.Frame) error
	Title(string) error
}

Host is what a Card draws to: *plugin.Peer, or a test's fake.

type Input

type Input struct {
	Label   string // the row above the field; "" for none
	Masked  bool   // each character drawn as •
	OnEnter func() // nil: Enter moves to the next control
	// contains filtered or unexported fields
}

Input is a one-row text field, under its label. A Masked one draws each character as •, and its value never leaves the rune buffer to be drawn: read it with Runes and Clear it when done.

func (*Input) Clear

func (in *Input) Clear()

Clear zeroes the runes, then empties the field.

func (*Input) Runes

func (in *Input) Runes() []rune

Runes is the live buffer, for a passphrase read without a string copy. It is valid until the next key or Clear.

func (*Input) Set

func (in *Input) Set(s string)

Set replaces the text, the cursor at its end. The old runes are zeroed.

func (*Input) Value

func (in *Input) Value() string

Value is the text typed.

type List

type List struct {
	Len     int
	Item    func(i int) string
	Sel     int
	OnEnter func(i int)
}

List is Len rows of text, one selected. Item is asked only for the rows in view, so a list of thousands is never drawn whole.

type Node

type Node struct {
	Text     string
	Leaf     bool // a row that never opens
	Open     bool
	Children []*Node
	Empty    string // shown under an open node with no children: "(no tables)"
	Value    any    // the plugin's own
}

Node is one row of a Tree.

type Options

type Options struct {
	Modal bool // a modal dialog: always focused, since AutoDoc sends it no plugin.focus
}

Options are a Card's settings.

type Page

type Page struct {
	Title   string   // host.title, sent only when it changes; "" sends nothing
	Header  []Block  // always shown, from the top
	Body    []Block  // under it; scrolls to keep the focused control's row in view
	Buttons *Buttons // the bar under the rule; nil for none
	Keys    string   // the hint line, in Dim
	Status  string   // what was done last, in Plain
	Problem string   // what went wrong, in Problem
}

Page is what the card shows now, built by the plugin on every draw.

type Role

type Role int

Role is a kind of text, which the theme gives its style.

const (
	Plain   Role = iota // as the card's text
	Dim                 // a hint, a path, a note
	Title               // a heading
	Good                // what went right
	Problem             // what went wrong
)

type Tree

type Tree struct {
	Roots   []*Node
	OnOpen  func(n *Node) bool // a closed node opening; false keeps it closed (a load failed)
	OnEnter func(n *Node) bool // false: Enter opens or closes the node, as on one with no handler
	// contains filtered or unexported fields
}

Tree is nodes under their parents, open ones showing what they hold. Its selection is a node, kept by identity as nodes open, close and change.

func (*Tree) Select

func (t *Tree) Select(n *Node)

Select makes n the selection.

func (*Tree) Selected

func (t *Tree) Selected() *Node

Selected is the selected node; nil when an Empty row is, or the tree is empty.

Jump to

Keyboard shortcuts

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