Documentation
¶
Overview ¶
Package widgets is the component kit of tuigoff. Its components follow the Elm architecture of Bubble Tea: a component is a model with Update(tea.Msg) (T, tea.Cmd) and View() string, its state lives in the model, and what happens in it is reported to the parent as messages.
Conventions ¶
Every component follows the same shape as the models in charm.land/bubbles:
- a constructor returns a value: NewList(id, items);
- setters have pointer receivers (SetSize, SetItems, Focus, Blur), and Update has a value receiver and returns the updated model;
- the parent gives the component its size with SetSize, or by forwarding a tea.WindowSizeMsg to Update; View returns exactly that many lines of that many columns;
- a component ignores key presses until Focus is called, and mouse events are given in coordinates relative to its top-left cell;
- keys are key.Binding values collected in a KeyMap field, so an application can rebind them and a help bar can list them (each KeyMap implements help.KeyMap);
- colours come from the active theme (package theme) when View runs.
Messages instead of callbacks ¶
A component never calls back into its parent. It returns a command that delivers a message, and the parent handles the message in its own Update:
list, cmd = list.Update(msg)
...
case widgets.ItemSelectedMsg:
if msg.ID == "projects" { return m, openProject(msg.Item) }
Each message carries the ID the component was created with, so a screen with two lists can tell them apart. Asynchronous work is a tea.Cmd that returns a result message; components never start goroutines.
The catalogue of messages:
List ItemHighlightedMsg, ItemSelectedMsg Tree NodeHighlightedMsg, NodeSelectedMsg Form FieldChangedMsg, SubmitMsg, CancelMsg, ButtonPressedMsg Tabs TabChangedMsg, TabCloseMsg Modal ModalDoneMsg Breadcrumbs CrumbSelectedMsg
Focus movement ¶
A screen that wants the shell (package nav) to move focus with the arrow keys implements Boundary: the shell asks AtEdge before it turns Up at the top of a list into "go to the breadcrumbs". Components that edit text implement Editor, which suspends application-wide key bindings while a cursor is active.
Framing and layout ¶
Frame draws the bordered, titled box every panel sits in, with the focus colour on its border; Split divides a length into fixed and proportional parts; Fit, Overlay and Center are the string helpers behind them. All are pure functions of their arguments.
Index ¶
- Variables
- func AlignIn(s string, width int, align Align) string
- func Blank(width, height int) string
- func Center(base, top string, width, height int) string
- func DefaultListKeyMap() list.KeyMap
- func Emit(msg tea.Msg) tea.Cmd
- func Fit(s string, width, height int) string
- func Overlay(base, top string, x, y int) string
- func PadRight(s string, width int) string
- func Split(total int, parts ...Size) []int
- type Align
- type Boundary
- type Breadcrumbs
- func (b Breadcrumbs) AtEdge(dir Direction) bool
- func (b *Breadcrumbs) Blur()
- func (b Breadcrumbs) Crumbs() []Crumb
- func (b *Breadcrumbs) Focus()
- func (b Breadcrumbs) Focused() bool
- func (b Breadcrumbs) Selected() int
- func (b *Breadcrumbs) SetCrumbs(crumbs []Crumb)
- func (b *Breadcrumbs) SetSeparator(separator string)
- func (b *Breadcrumbs) SetSeparatorStart(i int)
- func (b *Breadcrumbs) SetSize(width, _ int)
- func (b Breadcrumbs) Update(msg tea.Msg) (Breadcrumbs, tea.Cmd)
- func (b Breadcrumbs) View() string
- type BreadcrumbsKeyMap
- type Button
- type ButtonPressedMsg
- type ButtonRole
- type CancelMsg
- type Crumb
- type CrumbSelectedMsg
- type Direction
- type Editor
- type Field
- type FieldChangedMsg
- type FieldKind
- type Form
- func (f Form) AtEdge(dir Direction) bool
- func (f *Form) Blur()
- func (f Form) Editing() bool
- func (f *Form) Focus()
- func (f *Form) FocusField(id string) bool
- func (f Form) Focused() bool
- func (f *Form) SetButtons(buttons []FormButton)
- func (f *Form) SetFields(fields []Field)
- func (f *Form) SetSize(width, height int)
- func (f *Form) SetValue(id, value string)
- func (f Form) Update(msg tea.Msg) (Form, tea.Cmd)
- func (f Form) Value(id string) string
- func (f Form) Values() map[string]string
- func (f Form) View() string
- type FormButton
- type FormKeyMap
- type Frame
- func (f Frame) Inner(width, height int) (w, h int)
- func (f Frame) Origin() (x, y int)
- func (f Frame) Render(content string, width, height int) string
- func (f Frame) WithFocus(focused bool) Frame
- func (f Frame) WithPadding(top, right, bottom, left int) Frame
- func (f Frame) WithTitle(title string) Frame
- func (f Frame) WithTitleAlign(align Align) Frame
- func (f Frame) WithoutBorders() Frame
- type ItemHighlightedMsg
- type ItemSelectedMsg
- type List
- func (l List) AtEdge(dir Direction) bool
- func (l *List) Blur()
- func (l List) Editing() bool
- func (l List) FilteringEnabled() bool
- func (l *List) Focus()
- func (l List) Focused() bool
- func (l List) FullHelp() [][]key.Binding
- func (l List) Index() int
- func (l List) Items() []list.Item
- func (l List) KeyMap() list.KeyMap
- func (l *List) Select(index int)
- func (l List) SelectedItem() list.Item
- func (l *List) SetFilteringEnabled(enabled bool)
- func (l *List) SetItems(items ...list.Item)
- func (l *List) SetKeyMap(km list.KeyMap)
- func (l *List) SetSize(width, height int)
- func (l List) ShortHelp() []key.Binding
- func (l List) Update(msg tea.Msg) (List, tea.Cmd)
- func (l List) View() string
- type MenuItem
- type Modal
- func (m Modal) Active() int
- func (m Modal) FullHelp() [][]key.Binding
- func (m *Modal) SetButtons(labels ...string)
- func (m *Modal) SetColors(colors ModalColors)
- func (m *Modal) SetMaxSize(maxWidth, maxHeight int)
- func (m *Modal) SetText(text string)
- func (m *Modal) SetTitle(title string)
- func (m Modal) ShortHelp() []key.Binding
- func (m Modal) Size() (w, h int)
- func (m Modal) Update(msg tea.Msg) (Modal, tea.Cmd)
- func (m Modal) View() string
- type ModalColors
- type ModalDoneMsg
- type ModalKeyMap
- type NodeHighlightedMsg
- type NodeSelectedMsg
- type Padding
- type Size
- type SubmitMsg
- type Tab
- type TabChangedMsg
- type TabCloseMsg
- type Tabs
- func (t Tabs) Active() int
- func (t *Tabs) AddTab(tab Tab)
- func (t Tabs) AtEdge(dir Direction) bool
- func (t *Tabs) Blur()
- func (t *Tabs) Focus()
- func (t Tabs) Focused() bool
- func (t Tabs) FullHelp() [][]key.Binding
- func (t *Tabs) RemoveTab(index int)
- func (t *Tabs) SetActive(index int)
- func (t *Tabs) SetLabel(label string)
- func (t *Tabs) SetSize(width, _ int)
- func (t Tabs) ShortHelp() []key.Binding
- func (t Tabs) Tabs() []Tab
- func (t Tabs) Update(msg tea.Msg) (Tabs, tea.Cmd)
- func (t Tabs) View() string
- type TabsKeyMap
- type TabsStyle
- type TextPane
- func (t *TextPane) AppendContent(s string)
- func (t TextPane) AtEdge(dir Direction) bool
- func (t *TextPane) Blur()
- func (t TextPane) Content() string
- func (t *TextPane) Focus()
- func (t TextPane) Focused() bool
- func (t TextPane) FullHelp() [][]key.Binding
- func (t *TextPane) GotoBottom()
- func (t *TextPane) GotoTop()
- func (t TextPane) ID() string
- func (t TextPane) LineCount() int
- func (t *TextPane) ScrollTo(y, x int)
- func (t *TextPane) SetContent(s string)
- func (t *TextPane) SetSize(width, height int)
- func (t *TextPane) SetTextColor(c color.Color)
- func (t *TextPane) SetWrap(wrap bool)
- func (t TextPane) ShortHelp() []key.Binding
- func (t TextPane) Update(msg tea.Msg) (TextPane, tea.Cmd)
- func (t TextPane) View() string
- func (t TextPane) XOffset() int
- func (t TextPane) YOffset() int
- type TextPaneKeyMap
- type Tree
- func (t Tree) AtEdge(dir Direction) bool
- func (t *Tree) Blur()
- func (t *Tree) Collapse(id string)
- func (t *Tree) CollapseAll()
- func (t Tree) Current() (TreeNode, bool)
- func (t *Tree) Expand(id string)
- func (t *Tree) ExpandAll()
- func (t Tree) Expanded(id string) bool
- func (t *Tree) Focus()
- func (t Tree) Focused() bool
- func (t Tree) Roots() []TreeNode
- func (t *Tree) Select(id string) bool
- func (t *Tree) SetChildren(id string, children []TreeNode) bool
- func (t *Tree) SetExpanded(id string, open bool) bool
- func (t *Tree) SetRoots(roots ...TreeNode)
- func (t *Tree) SetSize(width, height int)
- func (t Tree) Update(msg tea.Msg) (Tree, tea.Cmd)
- func (t Tree) View() string
- type TreeKeyMap
- type TreeNode
Constants ¶
This section is empty.
Variables ¶
var ( // UnderlineTabsStyle underlines the inactive tabs. UnderlineTabsStyle = TabsStyle{Underscore: true} // RadioTabsStyle marks the active tab with a filled circle. RadioTabsStyle = TabsStyle{Radio: true} )
Predefined tab strip styles.
Functions ¶
func AlignIn ¶
AlignIn fits s into exactly width columns: wider text is truncated with an ellipsis, narrower text is padded according to align.
func DefaultListKeyMap ¶
DefaultListKeyMap returns the key bindings of a List: bubbles' own map with j, k, h, l, g, G, u, d, b, f and the quit and help keys taken away, because letters belong to item shortcuts and Left and Right belong to the shell.
func Emit ¶
Emit returns a command that delivers msg to Update. Components report what happened with messages, and Emit is how they send them.
func Fit ¶
Fit reshapes s into exactly height lines of exactly width columns, padding short lines and blank rows and truncating what does not fit.
func Overlay ¶
Overlay draws top over base with its top-left corner at column x, row y. Both may carry ANSI styling. Parts of top that fall outside base are clipped.
func PadRight ¶
PadRight pads s with spaces on the right to width columns, or truncates it (with an ellipsis) when it is wider.
Types ¶
type Boundary ¶
Boundary is implemented by components that can tell whether the selection sits at an edge. The shell asks the focused screen before it turns an arrow key into a focus move: Up at the top edge goes to the breadcrumbs, Left at the left edge goes to the menu, and so on. A component that is not a Boundary keeps all arrow keys for itself.
AtEdge is a pure query of the model state, so it is as testable as View.
type Breadcrumbs ¶
type Breadcrumbs struct {
// KeyMap holds the key bindings.
KeyMap BreadcrumbsKeyMap
// contains filtered or unexported fields
}
Breadcrumbs is a one-line navigation trail. Left and Right move the selection along the trail and Enter activates the selected crumb, which is reported with a CrumbSelectedMsg.
The selection rests on the last crumb. When the trail receives focus the selection jumps to the crumb before it, the parent step, so that Enter goes one step back. The trail is a Boundary: Left is at the edge on the first crumb and Right on the last.
func NewBreadcrumbs ¶
func NewBreadcrumbs(id string, crumbs ...Crumb) Breadcrumbs
NewBreadcrumbs creates a trail. id identifies it in CrumbSelectedMsg.
func (Breadcrumbs) AtEdge ¶
func (b Breadcrumbs) AtEdge(dir Direction) bool
AtEdge implements Boundary.
func (*Breadcrumbs) Blur ¶
func (b *Breadcrumbs) Blur()
Blur returns the selection to the last crumb.
func (Breadcrumbs) Crumbs ¶
func (b Breadcrumbs) Crumbs() []Crumb
Crumbs returns a copy of the trail.
func (*Breadcrumbs) Focus ¶
func (b *Breadcrumbs) Focus()
Focus moves the selection to the parent crumb.
func (Breadcrumbs) Focused ¶
func (b Breadcrumbs) Focused() bool
Focused reports whether the trail holds focus.
func (Breadcrumbs) Selected ¶
func (b Breadcrumbs) Selected() int
Selected returns the index of the selected crumb.
func (*Breadcrumbs) SetCrumbs ¶
func (b *Breadcrumbs) SetCrumbs(crumbs []Crumb)
SetCrumbs replaces the trail and rests the selection on its last crumb.
func (*Breadcrumbs) SetSeparator ¶
func (b *Breadcrumbs) SetSeparator(separator string)
SetSeparator sets the text drawn between crumbs; the default is " > ".
func (*Breadcrumbs) SetSeparatorStart ¶
func (b *Breadcrumbs) SetSeparatorStart(i int)
SetSeparatorStart suppresses the separators before crumb i, for trails whose first crumbs form one visual unit.
func (*Breadcrumbs) SetSize ¶
func (b *Breadcrumbs) SetSize(width, _ int)
SetSize gives the trail its width; the height is always one row.
func (Breadcrumbs) Update ¶
func (b Breadcrumbs) Update(msg tea.Msg) (Breadcrumbs, tea.Cmd)
Update handles key presses while focused, clicks, and size messages.
func (Breadcrumbs) View ¶
func (b Breadcrumbs) View() string
View renders the trail on one row of the given width.
type BreadcrumbsKeyMap ¶
BreadcrumbsKeyMap holds the key bindings of Breadcrumbs.
func DefaultBreadcrumbsKeyMap ¶
func DefaultBreadcrumbsKeyMap() BreadcrumbsKeyMap
DefaultBreadcrumbsKeyMap returns the default key bindings.
func (BreadcrumbsKeyMap) FullHelp ¶
func (k BreadcrumbsKeyMap) FullHelp() [][]key.Binding
FullHelp implements help.KeyMap.
func (BreadcrumbsKeyMap) ShortHelp ¶
func (k BreadcrumbsKeyMap) ShortHelp() []key.Binding
ShortHelp implements help.KeyMap.
type Button ¶
type Button struct {
// Label is the caption.
Label string
// Shortcut, when not zero, is shown before the label.
Shortcut rune
// Focused draws the button highlighted.
Focused bool
// Disabled draws the button dimmed.
Disabled bool
// Background and Foreground override the colours of an unfocused button.
Background color.Color
Foreground color.Color
}
Button is the look of a push button: a label with an optional shortcut hint in front of it, "(l) Login". It is a plain value; components that contain buttons keep the state (which one is focused) and render them with View.
func (Button) Text ¶
Text is the plain caption: the shortcut hint, when there is one, and the label.
type ButtonPressedMsg ¶
ButtonPressedMsg reports that an ActionRole button was pressed.
type ButtonRole ¶
type ButtonRole int
ButtonRole says what pressing a FormButton reports.
const ( // SubmitRole buttons report SubmitMsg. SubmitRole ButtonRole = iota // CancelRole buttons report CancelMsg. CancelRole // ActionRole buttons report ButtonPressedMsg. ActionRole )
Button roles.
type CancelMsg ¶
CancelMsg reports that a CancelRole button was pressed, or Esc was, in which case ButtonID is empty.
type Crumb ¶
type Crumb struct {
// Title is the text of the step.
Title string
// Color colours the step; the theme's hotkey colour is used when nil.
Color color.Color
}
Crumb is one step of a navigation trail.
type CrumbSelectedMsg ¶
CrumbSelectedMsg reports that a crumb was activated with the keyboard or the mouse. Index is its position in the trail, 0 being the root.
type Editor ¶
type Editor interface {
Editing() bool
}
Editor is implemented by components that may currently own a text cursor. While Editing reports true the shell keeps application-wide key bindings out of the way so that text-editing keys keep their meaning.
type Field ¶
type Field struct {
// ID identifies the field in Value, SetValue and the messages; it must be
// unique in the form.
ID string
// Label is the caption in front of the control.
Label string
// Kind selects the control.
Kind FieldKind
// Value is the initial text, or for a SelectField the initially chosen
// option (empty or unknown: nothing chosen).
Value string
// Placeholder is shown in an empty text field.
Placeholder string
// Width is the width of the control in columns; zero fills the row (text) or
// fits the value (select).
Width int
// Options are the choices of a SelectField.
Options []string
// Text is the content of a StaticField; it may carry ANSI styling.
Text string
// Accept filters typed and pasted text. It receives the text the field would
// hold after an insertion and the inserted rune; returning false drops the
// insertion. It is the one function a Field holds: a pure input filter, that
// is validation data and not behaviour, so it must not have side effects.
Accept func(text string, last rune) bool
}
Field describes one labelled row of a Form.
type FieldChangedMsg ¶
FieldChangedMsg reports that the user changed the value of a field by typing, deleting, pasting or choosing an option. SetValue does not send it.
type Form ¶
type Form struct {
// KeyMap holds the key bindings.
KeyMap FormKeyMap
// contains filtered or unexported fields
}
Form is a vertical form of labelled fields above a row of buttons. Fields sit one per row with labels right-aligned to the widest one, then a blank row and the buttons, aligned left. When the height is too small the form scrolls so the focused row stays visible.
Text and password fields wrap charm.land/bubbles/v2/textinput (virtual cursor on, blinking off, so no timer messages). Select fields and layout are own code: bubbles has no select, and a form needs the option list to take rows from the layout while it is open (capped at eight, scrolling inside).
Messages: FieldChangedMsg when Update changes a value, SubmitMsg, CancelMsg and ButtonPressedMsg for buttons, and CancelMsg with an empty ButtonID for Esc.
Keys (FormKeyMap): Tab and Down move to the next control, Shift+Tab and Up to the previous one; Enter on a field moves on and on a button presses it; Left and Right move between buttons; Esc cancels. On a closed select Enter, Space and Down open the option list, Up and Down move in it, Enter picks and Esc closes it, and Left and Right step through the options. Ctrl+Q and Ctrl+C are never consumed. Clicks focus a field or press a button.
Boundary: AtEdge(Up) is true on the first control, Down on the buttons (or the last field when there are none), Left when the text cursor is at the start, on the first button, or on a select at its first option, and Right when the cursor is at the end, on the last button, or on a select at its last option. While a select list is open no edge is reached. Form is an Editor while a text or password field is focused.
func NewForm ¶
func NewForm(id string, fields []Field, buttons []FormButton) Form
NewForm creates a form. id identifies it in messages. It starts blurred, with the first field (or button) as the control that receives focus.
func (*Form) Blur ¶
func (f *Form) Blur()
Blur takes the keyboard away and closes an open select list.
func (*Form) FocusField ¶
FocusField moves the focus to the field id and reports whether it exists and can take focus.
func (*Form) SetButtons ¶
func (f *Form) SetButtons(buttons []FormButton)
SetButtons replaces the buttons, keeping the focus when its control survives.
func (*Form) SetFields ¶
SetFields replaces the fields. Typed values of fields whose ID and kind survive are kept, and so is the focus when its control survives.
func (*Form) SetValue ¶
SetValue sets the value of the field id without sending a message. A value that is not one of a select's options clears the choice.
func (Form) Update ¶
Update handles key presses while focused, clicks, the wheel, pastes and size messages.
func (Form) Value ¶
Value returns the value of the field id: the text, or the chosen option of a select. Unknown and static fields have none.
type FormButton ¶
type FormButton struct {
// ID identifies the button in the messages.
ID string
// Label is the caption.
Label string
// Role selects the message a press reports.
Role ButtonRole
}
FormButton is a push button below the fields of a Form.
type FormKeyMap ¶
type FormKeyMap struct {
Next key.Binding
Prev key.Binding
Submit key.Binding
Cancel key.Binding
Left key.Binding
Right key.Binding
// Open opens a closed select.
Open key.Binding
// Press presses the focused button.
Press key.Binding
}
FormKeyMap holds the key bindings of Form.
func DefaultFormKeyMap ¶
func DefaultFormKeyMap() FormKeyMap
DefaultFormKeyMap returns the default key bindings.
func (FormKeyMap) FullHelp ¶
func (k FormKeyMap) FullHelp() [][]key.Binding
FullHelp implements help.KeyMap.
func (FormKeyMap) ShortHelp ¶
func (k FormKeyMap) ShortHelp() []key.Binding
ShortHelp implements help.KeyMap.
type Frame ¶
type Frame struct {
// Title is drawn in the top border.
Title string
// Focused selects the focused border colour.
Focused bool
// Borders draws the border; without it the content fills the whole rectangle.
Borders bool
// Padding is the space between the border and the content.
Padding Padding
// TitleAlign positions the title along the top border.
TitleAlign Align
}
Frame is the bordered, titled box a panel is drawn in. The border takes the theme's focused colour while Focused is true and its blurred colour otherwise. Frame is a plain value: With... methods return a modified copy, and Render is a pure function of the frame and its arguments.
frame := widgets.NewFrame().WithTitle("Projects").WithFocus(true)
out := frame.Render(list.View(), 40, 12)
func NewFrame ¶
func NewFrame() Frame
NewFrame returns a bordered frame without padding and with a centred title.
func (Frame) Inner ¶
Inner returns the size of the content area of a frame drawn into width x height; a dimension is never negative.
func (Frame) Render ¶
Render draws content, which should be Inner(width, height) cells, inside the frame and returns exactly height lines of width columns.
func (Frame) WithPadding ¶
WithPadding sets the padding between the border and the content.
func (Frame) WithTitleAlign ¶
WithTitleAlign positions the title along the top border.
func (Frame) WithoutBorders ¶
WithoutBorders removes the border.
type ItemHighlightedMsg ¶
ItemHighlightedMsg reports that the highlighted item of a List changed because of a message passed to Update. Index is the position among the visible items (those matching the filter, when there is one).
type ItemSelectedMsg ¶
ItemSelectedMsg reports that the highlighted item of a List was chosen with Enter, with its shortcut key, or by a click on the already highlighted row.
type List ¶
type List struct {
// contains filtered or unexported fields
}
List is a compact vertical menu built on bubbles' list.Model, which supplies the cursor movement, paging and optional filtering. The wrapper turns off the title, status bar, help and pagination dots, draws its own theme-coloured rows, and reports what happens with messages.
Rows are one line high, or two when some item has a detail. The highlighted row is drawn across the full width in the theme's selected style. bubbles pages the list instead of scrolling it: moving past the last row of a page shows the next page.
Messages, returned as commands by Update:
- ItemHighlightedMsg when a key, a click or the wheel changes the highlighted item; SetItems and Select are setters and never emit
- ItemSelectedMsg on Enter, on the shortcut key of a MenuItem (after an ItemHighlightedMsg when that moved the highlight), and on a left click on the row that is already highlighted; a click on another row only highlights it
Keys, while focused: up, down, home, end, pgup and pgdown, all without wrapping around, and Enter. Letters are free for shortcuts. Unfocused, keys are ignored. Mouse clicks and the wheel work regardless of focus, with coordinates relative to the top-left cell; the wheel moves the highlight one row per notch.
Filtering is off until SetFilteringEnabled(true); then "/" starts it, and while the filter input is active the list is an Editor: Editing reports true and every key goes to bubbles unmodified. The parent must pass all messages, not only keys, to Update while filtering, because bubbles delivers the matches asynchronously. Enabling filtering costs one row for the filter input.
List is a Boundary: Up is at the edge when the first item is highlighted (or there are no items), Down when the last one is, and Left and Right always.
func (List) FilteringEnabled ¶
FilteringEnabled reports whether the filter is available.
func (*List) Focus ¶
func (l *List) Focus()
Focus makes the list handle keys and draws the highlight in the focused style.
func (*List) Select ¶
Select highlights the item at index among the visible items, clamped to the list. It emits no message.
func (List) SelectedItem ¶
SelectedItem returns the highlighted item, or nil when there is none.
func (*List) SetFilteringEnabled ¶
SetFilteringEnabled turns the "/" filter on or off; it is off by default.
func (*List) SetItems ¶
SetItems replaces the items, ending any filter and keeping the highlight at the same position, or on the last item when there are fewer. It emits no message.
type MenuItem ¶
type MenuItem struct {
// ID identifies the item for the parent.
ID string
// Label is the first line of the item.
Label string
// Detail, when not empty, is shown muted on a second line.
Detail string
// Shortcut, when not zero, is drawn as "(x) " before the label and selects
// the item when the key is typed.
Shortcut rune
// Ref is any value the parent wants to get back with the item.
Ref any
}
MenuItem is a ready-made list item: a label, an optional second line of detail, an optional shortcut key and an opaque reference the parent can use to find out what the item stands for.
func (MenuItem) Description ¶
Description implements list.DefaultItem.
func (MenuItem) FilterValue ¶
FilterValue implements list.Item.
type Modal ¶
type Modal struct {
// KeyMap holds the key bindings.
KeyMap ModalKeyMap
// contains filtered or unexported fields
}
Modal is a dialog: a bordered box with a title in its border, wrapped text and a row of buttons drawn with Button. View returns the box only, at its natural size; the shell overlays it on the screen with Center, so the modal need not know what is behind it. bubbles has no dialog, and Frame draws neither a background nor a custom border colour, so the box is drawn here.
A modal owns the input, so it is always focused and has no Focus or Blur: Left, Right, Tab and Shift+Tab move between the buttons (wrapping around), Enter presses the focused button, Esc answers with index -1, and every other key press is swallowed. Only Ctrl+C and Ctrl+Q are left alone, Update returning the model and no command, so that the shell can quit. A left click on a button presses it and every other click is swallowed. Mouse coordinates are relative to the top-left corner of the box, which is where the shell puts the box's top-left cell.
Messages: ModalDoneMsg. A tea.WindowSizeMsg sets the space the box must fit in, like SetMaxSize. Modal is neither a Boundary nor an Editor.
func (*Modal) SetButtons ¶
SetButtons replaces the buttons and focuses the first one.
func (*Modal) SetColors ¶
func (m *Modal) SetColors(colors ModalColors)
SetColors overrides the theme's colours; nil fields keep the theme's.
func (*Modal) SetMaxSize ¶
SetMaxSize sets the space the box must fit in. The text is wrapped at the smaller of maxWidth-4 and 60 columns, and text rows that do not fit the height are dropped. Zero or less means unlimited, which still wraps at 60 columns.
type ModalColors ¶
type ModalColors struct {
Background color.Color
Text color.Color
Border color.Color
ButtonBackground color.Color
ButtonText color.Color
}
ModalColors overrides the colours of a Modal. A nil colour uses the theme's: the focus colour for the border, the text colour for the text, no background, and the default look for unfocused buttons.
type ModalDoneMsg ¶
ModalDoneMsg reports that the modal was answered: a button was pressed with Enter or a click, or Esc was pressed, in which case Index is -1 and Label is empty. The parent removes the modal when it receives it.
type ModalKeyMap ¶
type ModalKeyMap struct {
Prev key.Binding
Next key.Binding
Confirm key.Binding
Cancel key.Binding
}
ModalKeyMap holds the key bindings of Modal.
func DefaultModalKeyMap ¶
func DefaultModalKeyMap() ModalKeyMap
DefaultModalKeyMap returns the default key bindings.
func (ModalKeyMap) FullHelp ¶
func (k ModalKeyMap) FullHelp() [][]key.Binding
FullHelp implements help.KeyMap.
func (ModalKeyMap) ShortHelp ¶
func (k ModalKeyMap) ShortHelp() []key.Binding
ShortHelp implements help.KeyMap.
type NodeHighlightedMsg ¶
NodeHighlightedMsg reports that the cursor moved to a node because of a key or a click. It is not sent for changes made with Select, SetRoots or SetChildren.
type NodeSelectedMsg ¶
NodeSelectedMsg reports that a node was activated: Enter on the cursor node, or a click on the node that already holds the cursor. The node is never changed by the message itself; Enter afterwards toggles a node that has children.
type Padding ¶
type Padding struct{ Top, Right, Bottom, Left int }
Padding is a space in rows and columns.
type Size ¶
type Size struct {
// contains filtered or unexported fields
}
Size is the share of a length one part of a layout takes: a fixed number of cells, or a weight in what remains.
type Tab ¶
type Tab struct {
// ID identifies the tab for the parent.
ID string
// Title is the text shown in the strip.
Title string
// Closable adds a close mark to the tab.
Closable bool
}
Tab is one entry of the tab strip.
type TabChangedMsg ¶
TabChangedMsg reports that the active tab changed because of a key press or a click. Index is the position of the new active tab.
type TabCloseMsg ¶
TabCloseMsg reports a click on the close mark of a closable tab. The parent decides whether to call RemoveTab.
type Tabs ¶
type Tabs struct {
// KeyMap holds the key bindings.
KeyMap TabsKeyMap
// contains filtered or unexported fields
}
Tabs is a one-row strip of tab titles, optionally preceded by a label. It draws the strip only: the parent keeps the pages and shows the content of the active tab itself, following TabChangedMsg. bubbles has no tab strip, so the rendering is our own.
Left and Right switch tabs (no wrapping) and Alt+1 to Alt+9 jump to a tab, while focused. A click on a tab activates it, and a click on the close mark of a closable tab reports it. The active tab is drawn in the theme's selected style when the strip is focused and bold when it is not; inactive tabs are muted, and underlined in the Underscore style. When the strip is wider than the space it is scrolled so that the active tab is visible.
Messages: TabChangedMsg when the active tab changes through Update (never for SetActive, AddTab or RemoveTab, which are setters), and TabCloseMsg on a click on a close mark. Mouse clicks work regardless of focus, with the x coordinate relative to the left edge of the strip and y 0.
Tabs is a Boundary: Left is at the edge when the first tab is active, Right when the last one is, and Up and Down always. It is not an Editor.
func (*Tabs) RemoveTab ¶
RemoveTab removes the tab at index, ignoring an index outside the strip. Removing the active tab activates its neighbour. It emits no message.
func (*Tabs) SetActive ¶
SetActive activates the tab at index, ignoring an index outside the strip. It emits no message.
type TabsKeyMap ¶
type TabsKeyMap struct {
Prev key.Binding
Next key.Binding
// Jump activates tab n with alt+n, for n from 1 to 9.
Jump key.Binding
}
TabsKeyMap holds the key bindings of Tabs.
func DefaultTabsKeyMap ¶
func DefaultTabsKeyMap() TabsKeyMap
DefaultTabsKeyMap returns the default key bindings.
func (TabsKeyMap) FullHelp ¶
func (k TabsKeyMap) FullHelp() [][]key.Binding
FullHelp implements help.KeyMap.
func (TabsKeyMap) ShortHelp ¶
func (k TabsKeyMap) ShortHelp() []key.Binding
ShortHelp implements help.KeyMap.
type TabsStyle ¶
type TabsStyle struct {
// Radio prefixes each tab with a filled circle when active, an empty one
// otherwise.
Radio bool
// Underscore underlines the inactive tabs.
Underscore bool
}
TabsStyle selects how the tab strip is drawn; the theme supplies colours.
type TextPane ¶
type TextPane struct {
// KeyMap holds the key bindings.
KeyMap TextPaneKeyMap
// contains filtered or unexported fields
}
TextPane shows scrollable, optionally wrapped text and is built on bubbles' viewport, which does the scrolling, the soft wrapping and the horizontal cropping. The wrapper adds the key map (arrows, page keys, home and end; letters are not bound), a default text colour, the Boundary queries, and the exact-size View.
The content may carry ANSI styling (lipgloss output, theme.RedText, highlight output). Styling survives soft wrapping because the viewport cuts every wrapped row out of the styled line with ansi.Cut, which re-opens the styles that are active at the start of the row and closes them at its end (the tests verify this). A style that stays open across a line break, which the viewport would otherwise lose on the next line, is closed at the end of the line and re-opened at the start of the next by carryStyles when the content is set.
Wrapping is on by default and breaks lines at exactly the width (the viewport does not break at word boundaries). With SetWrap(false), Left and Right scroll horizontally. The wheel scrolls three lines. The vertical position is kept when the pane is resized and clamped to the text; SetContent scrolls to the top and AppendContent keeps the position.
TextPane sends no messages. It is a Boundary: Up is at the edge when scrolled to the top, Down at the bottom, Left when scrolled fully left (always while wrapping) and Right when scrolled fully right (always while wrapping). It is not an Editor.
func NewTextPane ¶
NewTextPane creates an empty pane that wraps long lines.
func (*TextPane) AppendContent ¶
AppendContent adds s to the end of the text without moving the scroll position; call GotoBottom afterwards to follow a stream.
func (*TextPane) GotoBottom ¶
func (t *TextPane) GotoBottom()
GotoBottom scrolls so that the last line is visible.
func (TextPane) LineCount ¶
LineCount returns the number of lines at the current width, wrapped lines counted separately.
func (*TextPane) ScrollTo ¶
ScrollTo scrolls so that line y and column x are the first visible ones, clamped to the text.
func (*TextPane) SetContent ¶
SetContent replaces the text and scrolls to the top.
func (*TextPane) SetSize ¶
SetSize sets the size of the pane; the scroll position is kept and clamped.
func (*TextPane) SetTextColor ¶
SetTextColor sets the foreground colour of text that has no colour of its own.
func (*TextPane) SetWrap ¶
SetWrap turns soft wrapping on (the default) or off, which enables horizontal scrolling.
func (TextPane) Update ¶
Update handles key presses while focused, the mouse wheel, and size messages.
type TextPaneKeyMap ¶
type TextPaneKeyMap struct {
Up key.Binding
Down key.Binding
PageUp key.Binding
PageDown key.Binding
Top key.Binding
Bottom key.Binding
Left key.Binding
Right key.Binding
}
TextPaneKeyMap holds the key bindings of TextPane. Letters are not bound.
func DefaultTextPaneKeyMap ¶
func DefaultTextPaneKeyMap() TextPaneKeyMap
DefaultTextPaneKeyMap returns the default key bindings.
func (TextPaneKeyMap) FullHelp ¶
func (k TextPaneKeyMap) FullHelp() [][]key.Binding
FullHelp implements help.KeyMap.
func (TextPaneKeyMap) ShortHelp ¶
func (k TextPaneKeyMap) ShortHelp() []key.Binding
ShortHelp implements help.KeyMap.
type Tree ¶
type Tree struct {
// KeyMap holds the key bindings.
KeyMap TreeKeyMap
// contains filtered or unexported fields
}
Tree is a scrollable, data-driven hierarchy of TreeNode values. Several roots give the "hidden root" layout: they are drawn at the left edge.
Keys: Up, Down, PageUp, PageDown, Home and End move the cursor between visible selectable nodes. Right expands a collapsed node, or moves to the first selectable child of an expanded one. Left collapses an expanded node below the top level, or moves to its selectable parent; on a top-level node it does nothing. Enter reports NodeSelectedMsg and then toggles a node that has children, Space only toggles. A click selects the row (NodeSelectedMsg when it already held the cursor) and a click on the expand marker toggles it; the wheel scrolls without moving the cursor. Cursor moves made by Update are reported with NodeHighlightedMsg.
Boundary: AtEdge(Up) is true on the first selectable visible node, Down on the last, Left when Left would do nothing (a top-level node, or a node whose parent is a group header and that cannot collapse) and Right when Right would do nothing (a leaf, or an expanded node without a selectable child). Tree is not an Editor.
Why it does not wrap charm.land/bubbles/v2/tree: that component is built on a mutable *Node graph whose Open and Close mutate shared nodes, has no unselectable nodes, keys expansion by pointer rather than by ID, has no per-node colour, and renders the whole tree into a viewport on every move instead of exactly width x height rows. Tree needs all of those, so it draws the rows itself (with the guides and markers below) and reuses only key and help from bubbles.
func NewTree ¶
NewTree creates a tree. id identifies it in messages. The first selectable node holds the cursor; nothing is expanded.
func (*Tree) Select ¶
Select moves the cursor to the node id, opening its ancestors so it is visible, without sending a message. It reports false when the node does not exist or is unselectable.
func (*Tree) SetChildren ¶
SetChildren replaces the children of the node id, for lazy loading, and keeps the cursor. It reports whether the node exists.
func (*Tree) SetExpanded ¶
SetExpanded opens or closes the node id. It reports whether the node exists.
func (*Tree) SetRoots ¶
SetRoots replaces the data. Expansion is kept by ID, and so is the cursor when its node still exists; otherwise the first selectable node takes it.
type TreeKeyMap ¶
type TreeKeyMap struct {
Up key.Binding
Down key.Binding
PageUp key.Binding
PageDown key.Binding
Home key.Binding
End key.Binding
Expand key.Binding
Collapse key.Binding
Activate key.Binding
Toggle key.Binding
}
TreeKeyMap holds the key bindings of Tree.
func DefaultTreeKeyMap ¶
func DefaultTreeKeyMap() TreeKeyMap
DefaultTreeKeyMap returns the default key bindings.
func (TreeKeyMap) FullHelp ¶
func (k TreeKeyMap) FullHelp() [][]key.Binding
FullHelp implements help.KeyMap.
func (TreeKeyMap) ShortHelp ¶
func (k TreeKeyMap) ShortHelp() []key.Binding
ShortHelp implements help.KeyMap.
type TreeNode ¶
type TreeNode struct {
// ID identifies the node and must be unique in the tree.
ID string
// Text is the caption; it may carry ANSI styling and emoji.
Text string
// Ref is an arbitrary value the application attaches to the node.
Ref any
// Color colours the caption when the node is not the selected row; nil keeps
// the terminal default.
Color color.Color
// Children are the nodes below this one.
Children []TreeNode
// Unselectable marks a group header: it is drawn (and can be expanded with
// SetExpanded, ExpandAll or a click on its marker) but the cursor never rests
// on it.
Unselectable bool
}
TreeNode is one node of a Tree. Nodes are plain data: the tree keeps no pointers into them, and expansion and the cursor are tracked by ID.