widget

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Mar 11, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package widget provides reusable TUI components.

Package widget provides reusable composable sub-models for workspace views.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BoostLabel added in v0.4.0

func BoostLabel(n int) string

BoostLabel returns "1 boost" or "N boosts".

func Truncate

func Truncate(s string, maxWidth int) string

Truncate truncates s to maxWidth, appending "…" if truncated. Uses lipgloss.Width for accurate ANSI-aware width measurement.

Types

type AttachFileRequestMsg

type AttachFileRequestMsg struct{}

AttachFileRequestMsg is sent when the user presses ctrl+f to attach a file. The containing view should display a hint (e.g. "Paste a file path or drag a file into the terminal").

type AttachStatus

type AttachStatus int

AttachStatus tracks upload progress for a single attachment.

const (
	AttachPending   AttachStatus = iota // queued, not yet uploading
	AttachUploading                     // upload in progress
	AttachUploaded                      // upload complete, SGID available
	AttachFailed                        // upload failed
)

type Attachment

type Attachment struct {
	Path        string
	Filename    string
	ContentType string
	SGID        string       // populated after upload
	Status      AttachStatus // current upload state
	Err         error        // set when Status == AttachFailed
}

Attachment represents a file being attached to the composed content.

type Composer

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

Composer is a reusable Markdown editing widget with attachment support.

func NewComposer

func NewComposer(styles *tui.Styles, opts ...ComposerOption) *Composer

NewComposer creates a new Composer widget.

func (*Composer) AddAttachment

func (c *Composer) AddAttachment(path string) tea.Cmd

AddAttachment queues a file for attachment and triggers upload if an upload function is set.

func (*Composer) Attachments

func (c *Composer) Attachments() []Attachment

Attachments returns the current attachment list.

func (*Composer) Blur

func (c *Composer) Blur()

Blur removes focus from the composer.

func (*Composer) Focus

func (c *Composer) Focus() tea.Cmd

Focus gives the composer focus.

func (*Composer) HandleEditorReturn

func (c *Composer) HandleEditorReturn(msg EditorReturnMsg) tea.Cmd

HandleEditorReturn populates the composer with the editor's output.

func (*Composer) HasContent

func (c *Composer) HasContent() bool

HasContent returns true if there is text or attachments.

func (*Composer) InputActive

func (c *Composer) InputActive() bool

InputActive returns true if the composer is capturing text input.

func (*Composer) InsertPaste

func (c *Composer) InsertPaste(text string)

InsertPaste appends pasted text at the current cursor position. If the text contains newlines or markdown, the composer auto-expands to rich mode.

func (*Composer) Mode

func (c *Composer) Mode() ComposerMode

Mode returns the current composer mode.

func (*Composer) OpenEditor

func (c *Composer) OpenEditor() tea.Cmd

OpenEditor launches $EDITOR with the current content. The containing view must handle the returned EditorReturnMsg by calling HandleEditorReturn.

func (*Composer) ProcessPaste

func (c *Composer) ProcessPaste(text string) (string, tea.Cmd)

ProcessPaste handles pasted text, detecting file paths and adding them as attachments. Returns remaining text that should be inserted, and any commands to execute.

func (*Composer) Reset

func (c *Composer) Reset()

Reset clears all content, attachments, and returns to quick mode.

func (*Composer) SetSize

func (c *Composer) SetSize(w, h int)

SetSize updates the composer dimensions.

func (*Composer) SetValue

func (c *Composer) SetValue(s string)

SetValue sets the text content (useful for pre-populating).

func (*Composer) ShortHelp

func (c *Composer) ShortHelp() []key.Binding

ShortHelp returns context-appropriate key bindings for the status bar. The send binding adapts: in rich mode with only attachments (empty text), it shows "enter" since plain Enter sends; otherwise it shows "ctrl/alt+enter".

func (*Composer) Submit

func (c *Composer) Submit() tea.Cmd

Submit creates a tea.Cmd that uploads any pending attachments and returns ComposerSubmitMsg. If the content is a single file path (e.g. typed or dragged without bracketed paste), it is intercepted and attached rather than sent as text.

func (*Composer) Update

func (c *Composer) Update(msg tea.Msg) tea.Cmd

Update processes messages for the composer.

func (*Composer) Value

func (c *Composer) Value() string

Value returns the current text content.

func (*Composer) View

func (c *Composer) View() string

View renders the composer.

type ComposerContent

type ComposerContent struct {
	Markdown    string
	Attachments []Attachment
	IsPlain     bool // true when no formatting and no attachments
}

ComposerContent is the structured output from the composer.

type ComposerMode

type ComposerMode int

ComposerMode determines the input style.

const (
	// ComposerQuick uses a single-line textinput; Enter sends.
	ComposerQuick ComposerMode = iota
	// ComposerRich uses a multi-line textarea; Enter inserts newline, ctrl+enter sends.
	ComposerRich
)

type ComposerOption

type ComposerOption func(*Composer)

ComposerOption configures a Composer.

func WithAttachmentsDisabled added in v0.3.0

func WithAttachmentsDisabled() ComposerOption

WithAttachmentsDisabled prevents the composer from accepting file attachments. Used for views like Campfire where the BC3 API does not support file uploads.

func WithAutoExpand

func WithAutoExpand(auto bool) ComposerOption

WithAutoExpand enables auto-switching from quick to rich mode.

func WithContext

func WithContext(ctx context.Context) ComposerOption

WithContext sets the cancellable context for upload operations. Uploads started with this context will abort if the context is canceled (e.g., on account switch). Defaults to context.Background().

func WithMode

func WithMode(mode ComposerMode) ComposerOption

WithMode sets the initial composer mode.

func WithPlaceholder

func WithPlaceholder(text string) ComposerOption

WithPlaceholder sets the placeholder text for both input widgets.

func WithUploadFn

func WithUploadFn(fn UploadFunc) ComposerOption

WithUploadFn sets the file upload callback.

type ComposerSubmitMsg

type ComposerSubmitMsg struct {
	Content ComposerContent
	Err     error
}

ComposerSubmitMsg is sent when the composer finishes processing a submission.

type Content

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

Content renders HTML or Markdown content as terminal-styled text. It handles the HTML→Markdown→glamour pipeline and provides scrolling.

func NewContent

func NewContent(styles *tui.Styles) *Content

NewContent creates a new content renderer.

func (*Content) ScrollDown

func (c *Content) ScrollDown(n int)

ScrollDown scrolls the content down by n lines.

func (*Content) ScrollUp

func (c *Content) ScrollUp(n int)

ScrollUp scrolls the content up by n lines.

func (*Content) SetContent

func (c *Content) SetContent(html string)

SetContent sets the raw HTML or Markdown content and renders it. Skips re-render if content is unchanged.

func (*Content) SetSize

func (c *Content) SetSize(w, h int)

SetSize updates dimensions and re-renders only if width changed. Height changes affect the viewport but don't require re-rendering.

func (*Content) View

func (c *Content) View() string

View renders the visible portion of the content.

type EditorReturnMsg

type EditorReturnMsg struct {
	Content string
	Err     error
}

EditorReturnMsg is sent when the external editor process exits. Containing views must handle this and call HandleEditorReturn.

type Kanban

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

Kanban renders a horizontal multi-column kanban board.

func NewKanban

func NewKanban(styles *tui.Styles) *Kanban

NewKanban creates a new kanban board widget.

func (*Kanban) FocusColumn

func (k *Kanban) FocusColumn(colIdx int)

FocusColumn sets focus to the given column index and clamps cardIdx.

func (*Kanban) FocusedCard

func (k *Kanban) FocusedCard() *KanbanCard

FocusedCard returns the focused card, or nil.

func (*Kanban) FocusedColumn

func (k *Kanban) FocusedColumn() int

FocusedColumn returns the index of the focused column.

func (*Kanban) MoveDown

func (k *Kanban) MoveDown()

MoveDown moves focus to the next card in the current column.

func (*Kanban) MoveLeft

func (k *Kanban) MoveLeft()

MoveLeft moves focus to the previous column, saving/restoring per-column cardIdx.

func (*Kanban) MoveRight

func (k *Kanban) MoveRight()

MoveRight moves focus to the next column, saving/restoring per-column cardIdx.

func (*Kanban) MoveUp

func (k *Kanban) MoveUp()

MoveUp moves focus to the previous card in the current column.

func (*Kanban) SetColumns

func (k *Kanban) SetColumns(cols []KanbanColumn)

SetColumns replaces all columns, preserving cursor by identity.

func (*Kanban) SetFocused

func (k *Kanban) SetFocused(focused bool)

SetFocused sets focus state.

func (*Kanban) SetSize

func (k *Kanban) SetSize(w, h int)

SetSize updates dimensions.

func (*Kanban) View

func (k *Kanban) View() string

View renders the kanban board. When all columns don't fit at minColWidth, shows a window of columns centered on the focused one.

type KanbanCard

type KanbanCard struct {
	ID            string
	Title         string
	Assignees     string
	DueOn         string
	StepsProgress string // e.g. "3/5"
	CommentsCount int
	Completed     bool
	Boosts        int // number of boosts
}

KanbanCard represents a card within a column.

type KanbanColumn

type KanbanColumn struct {
	ID       string
	Title    string
	Color    string // Basecamp color name (red, blue, green, etc.)
	Deferred bool   // true for Done/NotNow columns (no cards fetched)
	Count    int    // total card count (including deferred)
	Items    []KanbanCard
}

KanbanColumn represents a column in the kanban board.

type List

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

List is an async-capable list widget with filtering, scrolling, and selection.

func NewList

func NewList(styles *tui.Styles) *List

NewList creates a new list widget.

func (*List) Filtering

func (l *List) Filtering() bool

Filtering returns whether interactive filter mode is active.

func (*List) Items

func (l *List) Items() []ListItem

Items returns the current (possibly filtered) items.

func (*List) Len

func (l *List) Len() int

Len returns the number of visible items.

func (*List) SelectByID

func (l *List) SelectByID(id string) bool

SelectByID scans filtered items for a matching ID, sets cursor + adjusts offset. Returns true if found, false if not.

func (*List) SelectIndex

func (l *List) SelectIndex(idx int)

SelectIndex sets the cursor to the given index (clamped to bounds).

func (*List) Selected

func (l *List) Selected() *ListItem

Selected returns the currently highlighted item, or nil.

func (*List) SelectedIndex

func (l *List) SelectedIndex() int

SelectedIndex returns the cursor position.

func (*List) SetEmptyMessage

func (l *List) SetEmptyMessage(msg empty.Message)

SetEmptyMessage sets a structured empty state with title, body, and hints.

func (*List) SetEmptyText

func (l *List) SetEmptyText(text string)

SetEmptyText sets the message shown when no items exist.

func (*List) SetFocused

func (l *List) SetFocused(focused bool)

SetFocused sets focus state.

func (*List) SetItems

func (l *List) SetItems(items []ListItem)

SetItems replaces the item list and resets the cursor.

func (*List) SetLoading

func (l *List) SetLoading(loading bool)

SetLoading puts the list in loading state.

func (*List) SetSize

func (l *List) SetSize(w, h int)

SetSize updates dimensions.

func (*List) StartFilter

func (l *List) StartFilter()

StartFilter enters interactive filter mode.

func (*List) StopFilter

func (l *List) StopFilter()

StopFilter exits interactive filter mode and restores all items.

func (*List) Update

func (l *List) Update(msg tea.Msg) tea.Cmd

Update handles key events for list navigation.

func (*List) View

func (l *List) View() string

View renders the list.

type ListItem

type ListItem struct {
	ID          string
	Title       string
	Description string
	Extra       string // right-aligned detail (count, date, etc.)
	Boosts      int    // number of boosts
	Marked      bool   // visual mark (star, check, etc.)
	Header      bool   // section header (non-selectable, rendered differently)
}

ListItem represents a single item in an async list.

func (ListItem) FilterValue

func (i ListItem) FilterValue() string

FilterValue returns the string used for filtering.

type Preview

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

Preview renders a detail pane with key-value fields and an optional body.

func NewPreview

func NewPreview(styles *tui.Styles) *Preview

NewPreview creates a new preview pane.

func (*Preview) Fields

func (p *Preview) Fields() []PreviewField

Fields returns the current metadata fields.

func (*Preview) ScrollDown

func (p *Preview) ScrollDown(n int)

ScrollDown scrolls the body content down.

func (*Preview) ScrollUp

func (p *Preview) ScrollUp(n int)

ScrollUp scrolls the body content up.

func (*Preview) SetBody

func (p *Preview) SetBody(html string)

SetBody sets the HTML/Markdown body content.

func (*Preview) SetFields

func (p *Preview) SetFields(fields []PreviewField)

SetFields sets the key-value metadata fields.

func (*Preview) SetSize

func (p *Preview) SetSize(w, h int)

SetSize updates dimensions.

func (*Preview) SetTitle

func (p *Preview) SetTitle(title string)

SetTitle sets the preview title and clears any associated URL. Use SetTitleURL after SetTitle to make the title a clickable hyperlink.

func (*Preview) SetTitleURL added in v0.3.0

func (p *Preview) SetTitleURL(url string)

SetTitleURL sets a URL that makes the title a clickable OSC 8 hyperlink.

func (*Preview) View

func (p *Preview) View() string

View renders the preview pane.

type PreviewField

type PreviewField struct {
	Key   string
	Value string
}

PreviewField is a key-value pair shown in the preview header.

type SplitPane

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

SplitPane renders two panels side by side with a divider.

func NewSplitPane

func NewSplitPane(styles *tui.Styles, ratio float64) *SplitPane

NewSplitPane creates a new split pane with the given left:right ratio.

func (*SplitPane) IsCollapsed

func (s *SplitPane) IsCollapsed() bool

IsCollapsed returns true if the pane is showing single-panel mode.

func (*SplitPane) LeftWidth

func (s *SplitPane) LeftWidth() int

LeftWidth returns the left panel width (excluding divider).

func (*SplitPane) RightWidth

func (s *SplitPane) RightWidth() int

RightWidth returns the right panel width (excluding divider).

func (*SplitPane) SetContent

func (s *SplitPane) SetContent(left, right string)

SetContent sets the content for both panels.

func (*SplitPane) SetSize

func (s *SplitPane) SetSize(w, h int)

SetSize updates dimensions. Automatically collapses below 80 columns.

func (*SplitPane) View

func (s *SplitPane) View() string

View renders the split pane.

type UploadFunc

type UploadFunc func(ctx context.Context, path, filename, contentType string) (sgid string, err error)

UploadFunc is the callback for uploading a file. Called in a tea.Cmd goroutine. Returns the attachable SGID on success.

Jump to

Keyboard shortcuts

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