Documentation
¶
Overview ¶
Package board is a kanban screen: cards in lanes, grouped by a field the application names, with the cursor moving between them and cards moving between lanes.
Nothing here knows what a card is. The application says what its two lines read, which lanes it belongs in, and what moving it between them means; the board does the grouping, the layout, the scrolling and the hit-testing.
Index ¶
- Constants
- func Order(lanes ...string) func(a, b string) int
- type Axis
- type Board
- func (b *Board) Actions() []ninebox.Action
- func (b *Board) Axis() Axis
- func (b *Board) Collapsed(name string) bool
- func (b *Board) Columns() []Column
- func (b *Board) Commands() []ninebox.Command
- func (b *Board) Current() (Card, bool)
- func (b *Board) Cursor() (lane, card int)
- func (b *Board) Key(msg tea.KeyMsg) (tea.Cmd, bool)
- func (b *Board) Mouse(msg tea.MouseMsg) tea.Cmd
- func (b *Board) Move(lanes, cards int)
- func (b *Board) MoveCard(delta int) tea.Cmd
- func (b *Board) MoveTo(lane, card int)
- func (b *Board) NextAxis() tea.Cmd
- func (b *Board) Offset() int
- func (b *Board) Receive(msg tea.Msg) tea.Cmd
- func (b *Board) Refresh() tea.Cmd
- func (b *Board) Reload() tea.Cmd
- func (b *Board) Scope() string
- func (b *Board) Scroll(lanes int)
- func (b *Board) SetScope(scope string)
- func (b *Board) Title() string
- func (b *Board) ToggleCollapse() tea.Cmd
- func (b *Board) View(width, height int) string
- type Card
- type Chip
- type Column
- type Options
- type Result
Constants ¶
const Lane = "(none)"
Lane is the catch-all column: the cards with no value for the current axis. It always sorts last, where an empty bucket belongs.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Axis ¶
type Axis struct {
// Name is what the axis is called, in the caption and in the toast that
// refuses a move on a view-only one.
Name string
// Lanes returns the lane names a card belongs to. Returning several puts
// the card in each of them, which is how a board grouped by label reads;
// returning none puts it in the catch-all lane.
Lanes func(Card) []string
// Order sorts two lane names. Without one, lanes sort alphabetically —
// which is wrong for a workflow, where Done must not come first.
Order func(a, b string) int
// Move writes a card into another lane. Leaving it nil makes the axis
// view-only, and the board says so rather than appearing to do nothing.
Move func(c Card, from, to string) tea.Cmd
}
Axis is one way of grouping the cards.
type Board ¶
type Board struct {
// contains filtered or unexported fields
}
Board is the screen. Push it onto the shell and call Reload.
func New ¶
New builds a board. It fetches nothing until Reload is called, so an app can push it and load in one command.
func (*Board) Current ¶
Current is the card under the cursor. A folded lane draws no cards, so it has nothing under the cursor. Answering false there is what makes every card action — moving one, opening it, the application's own keys — a no-op on a folded lane without any of them having to learn about folding: they all already ask.
func (*Board) Key ¶
Key drives the board.
The arrows move around it and h/l move the card, which is the one pairing worth learning: on a kanban board the thing you do most is push a card one lane over, and it deserves the keys under your fingers.
func (*Board) Mouse ¶
Mouse drives the board with the pointer.
Terminals give no drag event, so moving a card is pick-then-place: click a card to select it, then click another lane's heading or empty space to send it there.
func (*Board) Move ¶
Move shifts the cursor by lanes and cards. Changing lane starts at its top: a lane is a list of its own, and landing halfway down one is disorienting.
func (*Board) NextAxis ¶
NextAxis cycles the grouping and re-fetches, because an axis may need different data — a status board needs statuses expanded, a plain one does not.
The cursor keeps the card it was on rather than returning to the first lane: regrouping is a different arrangement of the same things, and the card someone was looking at is the one they still want to be looking at. Only the sideways scroll resets, since the lanes it was showing are gone.
func (*Board) Title ¶
Title is the pane caption: what the board covers, what it is grouped by, and how many cards are on it.
func (*Board) ToggleCollapse ¶ added in v0.4.0
ToggleCollapse folds or unfolds the lane the cursor is in.
type Card ¶
type Card struct {
// ID identifies the card across a reload, so the cursor stays on the card
// someone was looking at rather than on whatever ends up in its position.
ID string
Head string
Title string
Style lipgloss.Style // how the head line is coloured; the zero value is plain
// Meta is what the card carries besides its title — labels, a milestone,
// whatever tells two cards apart without opening either. Drawn on a third
// line, in order, until the column runs out.
Meta []Chip
Payload any
}
Card is one thing on the board.
Head and Title are the two lines it shows — an identifier and a summary, in practice. Payload is the application's own object, which the axes read and the actions act on.
type Chip ¶ added in v0.4.0
Chip is one piece of a card's metadata, with its own colour: a label keeps the one the provider gave it, where a milestone is just dim.
type Options ¶
type Options struct {
// Title is the word in the caption — "board" unless an app has a better one.
Title string
// Scope is what the board covers, shown in the caption beside the axis.
Scope string
// Axes are the groupings, in the order the cycle key steps through them.
// The first is where the board opens.
Axes []Axis
// Load fetches the cards. The axis is passed because a provider may be able
// to filter or expand differently for each.
Load func(ctx context.Context, axis Axis) (Result, error)
// Open is what enter does to a card.
Open func(Card) tea.Cmd
// Link is the page `o` opens in a browser.
Link func(Card) string
}
Options is everything an application supplies.
type Result ¶
type Result struct {
Cards []Card
// Axis, when set, is the axis the cards were actually grouped by. An app
// that finds the asked-for axis empty can group by another and say so here
// rather than showing one useless lane.
Axis string
// Note is said in the status line once the cards land: why the axis
// changed, what was left out.
Note string
// Lanes is the full set of lanes to draw, whether or not a card landed in
// one — the statuses a project defines, the labels it has. A board whose
// lanes come only from its cards has no Done column until something is
// done, and nowhere to drag a card that would put it there.
//
// Empty means the lanes are the ones the cards imply, as before. The set
// is a floor rather than a filter: a lane a card carries is drawn whether
// or not it is named here, because a group board aggregates projects that
// define their own values.
Lanes []string
// Collapsed are the lanes to fold on sight — finished work, usually, which
// a board draws for completeness and nobody reads.
//
// It applies only to a lane the board has not drawn before, so a reload
// cannot undo a fold or unfold someone made by hand.
Collapsed []string
}
Result is what a load produced.