Documentation
¶
Overview ¶
Package tui provides a declarative terminal user interface framework for building interactive command-line applications in Go.
Philosophy ¶
Wonton TUI is designed around declarative UI principles similar to SwiftUI and React. Applications describe what the UI should look like in terms of the current state, and the framework handles rendering and updates efficiently. This eliminates manual terminal manipulation and focus on application logic.
Quick Start ¶
A minimal TUI application implements the Application interface with a View() method that returns the UI tree:
type App struct {
count int
}
func (a *App) View() tui.View {
return tui.Stack(
tui.Text("Count: %d", a.count),
tui.Button("Increment", func() { a.count++ }),
)
}
func (a *App) HandleEvent(event tui.Event) []tui.Cmd {
if key, ok := event.(tui.KeyEvent); ok && key.Rune == 'q' {
return []tui.Cmd{tui.Quit()}
}
return nil
}
func main() {
tui.Run(&App{})
}
Core Concepts ¶
View Tree: The UI is built as a tree of View components. Containers like Stack, Group, and ZStack arrange children, while leaf views like Text, Button, and Input display content.
Event Loop: The Runtime manages a single-threaded event loop that processes events sequentially. This eliminates race conditions in application code - no locks needed for state management.
Commands: Async operations are handled through the Cmd system. Commands execute in separate goroutines and send their results back as events.
Layout System ¶
Views are arranged in two phases:
- Measurement: Each view calculates its preferred size given constraints
- Rendering: Each view draws itself within its allocated space
Layout containers (Stack, Group, etc.) coordinate child sizing:
Stack( // Vertical stack
Text("Header"),
Spacer(), // Expands to fill space
Text("Footer"),
).Gap(1) // Space between children
Flex Inheritance: Containers automatically inherit flexibility from their children. If a Stack or Group contains flexible views (like Canvas or Spacer), the container itself becomes flexible. This allows nested layouts to work intuitively without explicitly setting .Flex() at every level:
Stack(
Text("Header"),
Group(Canvas()), // Group inherits flex from Canvas
Text("Footer"),
)
The Canvas will expand to fill available space because Group automatically becomes flexible when it contains flexible children.
View Components ¶
Text and Styling:
Text("Hello").Fg(ColorGreen).Bold()
Text("Error: %s", err).Error() // Semantic styling
Layout Containers:
Stack(children...) // Vertical layout Group(children...) // Horizontal layout ZStack(children...) // Layered (z-axis) layout
Interactive Elements:
Button("Submit", func() { ... }) // Keyboard + mouse
Clickable("Link", func() { ... }) // Mouse-only
InputField(&app.name).Placeholder("Enter name")
Modifiers:
Padding(2, content) // Add space around view
Bordered(content).Title("Box") // Draw border with optional title
Width(40, content) // Fixed width
MaxWidth(80, content) // Maximum width constraint
Event Handling ¶
Applications can optionally implement EventHandler to process events:
func (a *App) HandleEvent(event tui.Event) []tui.Cmd {
switch e := event.(type) {
case tui.KeyEvent:
if e.Rune == 'q' {
return []tui.Cmd{tui.Quit()}
}
case tui.ResizeEvent:
// Handle terminal resize
}
return nil
}
Event Types:
- KeyEvent: Keyboard input with modifiers
- MouseEvent: Mouse clicks, movement, scrolling
- TickEvent: Periodic timer for animations (based on FPS)
- ResizeEvent: Terminal size changed
- QuitEvent: Application should exit
Async Operations ¶
Long-running operations use the Cmd system to avoid blocking the UI:
func fetchData() tui.Cmd {
return func() tui.Event {
data, err := http.Get("...")
return DataEvent{data, err}
}
}
func (a *App) HandleEvent(event tui.Event) []tui.Cmd {
if _, ok := event.(tui.KeyEvent); ok {
return []tui.Cmd{fetchData()}
}
if data, ok := event.(DataEvent); ok {
a.data = data
}
return nil
}
Focus Management ¶
Interactive elements like Button and InputField are automatically focusable. Users navigate with Tab/Shift+Tab, activate with Enter/Space:
Stack(
InputField(&app.name).ID("name"),
InputField(&app.email).ID("email"),
Button("Submit", func() { app.submit() }),
)
Views can respond to focus state:
Bordered(content).
FocusID("name").
FocusBorderFg(ColorCyan)
Mouse Support ¶
Mouse tracking is opt-in via WithMouseTracking:
tui.Run(&App{}, tui.WithMouseTracking(true))
Applications receive MouseEvent events for clicks, movement, and scrolling. Interactive elements (Button, Clickable) automatically handle mouse clicks.
Animations ¶
Animations are driven by TickEvent, which fires at the configured FPS:
type App struct {
frame uint64
}
func (a *App) HandleEvent(event tui.Event) []tui.Cmd {
if tick, ok := event.(tui.TickEvent); ok {
a.frame = tick.Frame
}
return nil
}
func (a *App) View() tui.View {
return Text("Frame %d", a.frame)
}
Text views support built-in animations:
Text("Rainbow").Rainbow(5)
Text("Pulse").Pulse(tui.NewRGB(255, 0, 0), 10)
Text("Type").Typewriter(3, textColor, cursorColor)
Advanced Features ¶
Collections: ForEach renders slices of data:
ForEach(app.items, func(item Item) tui.View {
return Text(item.Name)
})
Conditional Rendering: If/IfElse for dynamic UI:
If(app.showHelp, func() tui.View {
return Text("Help text...")
})
Scrolling: ScrollView for content larger than viewport:
Scroll(content, &app.scrollY).Height(20)
Tables: Table for tabular data:
Table(headers, &app.selected).Rows(rows)
Markdown: Markdown for rich formatted text:
Markdown(mdContent).Width(80)
Code Highlighting: CodeView with syntax highlighting:
CodeView(code, "go").Width(80)
Testing ¶
The terminal package provides TestTerminal for unit testing TUI applications:
func TestApp(t *testing.T) {
term := tui.NewTestTerminal(80, 24)
runtime := tui.NewRuntime(term, &App{}, 30)
// Send events and verify output
}
Thread Safety ¶
The Runtime guarantees that View() and HandleEvent() are NEVER called concurrently. All state mutations happen in the single-threaded event loop, eliminating the need for locks in application code.
Commands execute in separate goroutines but communicate back via events, maintaining the single-threaded guarantee for application logic.
Performance ¶
The framework uses double-buffering and dirty region tracking to minimize terminal I/O. Only changed cells are sent to the terminal, enabling smooth 60 FPS animations even in large UIs.
Package Organization ¶
This package re-exports types from the terminal package (Style, Color, etc.) for convenience. Applications typically only need to import "tui".
Related packages:
- terminal: Low-level terminal control and rendering
- termtest: Testing utilities for TUI applications
For detailed examples, see the examples directory in the repository.
Index ¶
- Constants
- Variables
- func AlignText(text string, width int, align Alignment) string
- func AnimatedBordered(inner View, animation BorderAnimation) *animatedBorderedView
- func ApplyConstraints(size image.Point, constraints SizeConstraints) image.Point
- func AvailableLanguages() []string
- func AvailableThemes() []string
- func Bordered(inner View) *borderedView
- func Button(label string, callback func()) *buttonView
- func Canvas(draw func(frame RenderFrame, bounds image.Rectangle)) *canvasView
- func CanvasContext(draw func(ctx *RenderContext)) *canvasView
- func CellGrid(cols, rows int) *gridView
- func CharGrid(data [][]rune) *charGridView
- func CheckboxList(items []ListItem, checked []bool, cursor *int) *checkboxListView
- func CheckboxListStrings(labels []string, checked []bool, cursor *int) *checkboxListView
- func ClearLine(cfg ...CursorConfig)
- func ClearLines(n int, cfg ...CursorConfig)
- func ClearLinesDown(n int, cfg ...CursorConfig)
- func ClearScreen(cfg ...CursorConfig)
- func ClearToEndOfLine(cfg ...CursorConfig)
- func ClearToEndOfScreen(cfg ...CursorConfig)
- func ClearToStartOfLine(cfg ...CursorConfig)
- func ClearToStartOfScreen(cfg ...CursorConfig)
- func Clickable(label string, callback func()) *clickableView
- func Code(code string, language string) *codeView
- func ColorGrid(cols, rows int, state [][]int, colors []Color) *colorGridView
- func CoordinatedView(inner View, effectName string, transformFunc func(View, float64) View) *coordinatedView
- func Debug(info *DebugInfo) *debugView
- func DiffView(diff *Diff, language string, scrollY *int) *diffView
- func DiffViewFromText(diffText, language string, scrollY *int) (*diffView, error)
- func Divider() *dividerView
- func EaseInBack(t float64) float64
- func EaseInBounce(t float64) float64
- func EaseInCirc(t float64) float64
- func EaseInCubic(t float64) float64
- func EaseInElastic(t float64) float64
- func EaseInExpo(t float64) float64
- func EaseInOutBack(t float64) float64
- func EaseInOutBounce(t float64) float64
- func EaseInOutCirc(t float64) float64
- func EaseInOutCubic(t float64) float64
- func EaseInOutElastic(t float64) float64
- func EaseInOutExpo(t float64) float64
- func EaseInOutQuad(t float64) float64
- func EaseInOutQuart(t float64) float64
- func EaseInOutSine(t float64) float64
- func EaseInQuad(t float64) float64
- func EaseInQuart(t float64) float64
- func EaseInSine(t float64) float64
- func EaseLinear(t float64) float64
- func EaseOutBack(t float64) float64
- func EaseOutBounce(t float64) float64
- func EaseOutCirc(t float64) float64
- func EaseOutCubic(t float64) float64
- func EaseOutElastic(t float64) float64
- func EaseOutExpo(t float64) float64
- func EaseOutQuad(t float64) float64
- func EaseOutQuart(t float64) float64
- func EaseOutSine(t float64) float64
- func FilePicker(items []ListItem, filter *string, selected *int) *filePickerView
- func Fill(char rune) *fillView
- func FilterableList(items []ListItem, selected *int) *listView
- func FilterableListStrings(labels []string, selected *int) *listView
- func FocusText(content string, focusID string) *focusTextView
- func ForEach[T any](items []T, mapper func(item T, index int) View) *forEachView[T]
- func Fprint(w io.Writer, view View, cfgs ...PrintConfig) error
- func FuzzyMatch(pattern, text string) bool
- func FuzzySearch(pattern string, candidates []string) []string
- func Group(children ...View) *group
- func HForEach[T any](items []T, mapper func(item T, index int) View) *hForEachView[T]
- func HeaderBar(text string) *headerBarView
- func HideCursor(cfg ...CursorConfig)
- func InlineLinks(separator string, links ...Hyperlink) *inlineLinkView
- func Input(binding *string) *inputView
- func InputField(binding *string) *inputFieldView
- func KeyValue(label, value string) *keyValueView
- func Link(url, text string) *hyperlinkView
- func LinkList(links ...Hyperlink) *linkListView
- func LinkRow(label, url, linkText string) *linkRowView
- func Live(fn func(update func(View)), cfgs ...PrintConfig) error
- func Loading(frame uint64) *loadingView
- func Markdown(content string, scrollY *int) *markdownView
- func MeasureText(text string) (width, height int)
- func MeasureWidget(w ComposableWidget, c SizeConstraints) image.Point
- func Meter(label string, value, max int) *meterView
- func MoveCursorDown(n int, cfg ...CursorConfig)
- func MoveCursorLeft(n int, cfg ...CursorConfig)
- func MoveCursorRight(n int, cfg ...CursorConfig)
- func MoveCursorUp(n int, cfg ...CursorConfig)
- func MoveToColumn(col int, cfg ...CursorConfig)
- func MoveToLineStart(cfg ...CursorConfig)
- func Newline(cfg ...CursorConfig)
- func Panel(content View) *panelView
- func Print(view View, cfgs ...PrintConfig) error
- func Progress(current, total int) *progressView
- func Prompt(prompt string, opts ...PromptOption) (string, error)
- func PromptChoice(selected *int, inputText *string) *promptChoiceView
- func RadioList(items []ListItem, selected *int) *radioListView
- func RadioListStrings(labels []string, selected *int) *radioListView
- func ReadPassword(prompt string) (string, error)
- func ReadSimple(prompt string) (string, error)
- func RestoreCursor(cfg ...CursorConfig)
- func Run(app any, opts ...RunOption) error
- func RunInline(app any, cfg func(*InlineApp)) error
- func SaveCursor(cfg ...CursorConfig)
- func Scroll(inner View, scrollY *int) *scrollView
- func SelectList(items []ListItem, selected *int) *selectListView
- func SelectListStrings(labels []string, selected *int) *selectListView
- func ShowCursor(cfg ...CursorConfig)
- func Sine(x float64) float64
- func Spacer() *spacerView
- func Sprint(view View, cfgs ...PrintConfig) string
- func SprintScreen(view View, cfgs ...PrintConfig) *termtest.Screen
- func Stack(children ...View) *stack
- func StatusBar(text string) *headerBarView
- func StyledButton(label string, callback func()) *styledButtonView
- func Table(columns []TableColumn, selected *int) *tableView
- func Text(format string, args ...any) *textView
- func TextArea(binding *string) *textAreaView
- func Toggle(value *bool) *toggleView
- func Tree(root *TreeNode) *treeView
- func WrapText(text string, width int) string
- func ZStack(children ...View) *zStack
- type Alignment
- type AnimatedElement
- type AnimatedMultiLine
- func (aml *AnimatedMultiLine) AddLine(text string, animation TextAnimation)
- func (aml *AnimatedMultiLine) ClearLines()
- func (aml *AnimatedMultiLine) Dimensions() (width, height int)
- func (aml *AnimatedMultiLine) Draw(frame RenderFrame)
- func (aml *AnimatedMultiLine) Position() (x, y int)
- func (aml *AnimatedMultiLine) SetLine(index int, text string, animation TextAnimation)
- func (aml *AnimatedMultiLine) SetPosition(x, y int)
- func (aml *AnimatedMultiLine) SetWidth(width int)
- func (aml *AnimatedMultiLine) Update(frame uint64)
- type AnimatedStatusBar
- func (asb *AnimatedStatusBar) AddItem(key, value, icon string, animation TextAnimation, style Style)
- func (asb *AnimatedStatusBar) Dimensions() (width, height int)
- func (asb *AnimatedStatusBar) Draw(frame RenderFrame)
- func (asb *AnimatedStatusBar) Position() (x, y int)
- func (asb *AnimatedStatusBar) SetPosition(x, y int)
- func (asb *AnimatedStatusBar) Update(frame uint64)
- func (asb *AnimatedStatusBar) UpdateItem(index int, key, value string)
- type AnimatedStatusItem
- type AnimatedText
- type Animation
- func NewAnimation(duration uint64) *Animation
- func PresetAttention(duration uint64) *Animation
- func PresetBounce(duration uint64) *Animation
- func PresetElastic(duration uint64) *Animation
- func PresetFadeIn(duration uint64) *Animation
- func PresetFadeOut(duration uint64) *Animation
- func PresetPulse(duration uint64) *Animation
- func PresetSlideIn(duration uint64) *Animation
- func (a *Animation) IsRunning() bool
- func (a *Animation) Lerp(from, to float64) float64
- func (a *Animation) LerpRGB(from, to RGB) RGB
- func (a *Animation) Start(frame uint64)
- func (a *Animation) Stop()
- func (a *Animation) Update(frame uint64)
- func (a *Animation) Value() float64
- func (a *Animation) WithEasing(easing Easing) *Animation
- func (a *Animation) WithLoop(loop bool) *Animation
- func (a *Animation) WithPingPong(pingPong bool) *Animation
- type AnimationBuilder
- func (ab *AnimationBuilder) Add(duration uint64, easing Easing) *AnimationBuilder
- func (ab *AnimationBuilder) AddAnimation(anim *Animation) *AnimationBuilder
- func (ab *AnimationBuilder) Build() interface{}
- func (ab *AnimationBuilder) Parallel() *AnimationBuilder
- func (ab *AnimationBuilder) Sequence() *AnimationBuilder
- func (ab *AnimationBuilder) Stagger() *AnimationBuilder
- type AnimationController
- type AnimationCoordinator
- func (ac *AnimationCoordinator) CurrentFrame() uint64
- func (ac *AnimationCoordinator) GetEffect(name string) *GlobalEffect
- func (ac *AnimationCoordinator) GetSubscribers(effectName string) []AnimationSubscriber
- func (ac *AnimationCoordinator) RegisterEffect(name string, effect *GlobalEffect)
- func (ac *AnimationCoordinator) Subscribe(effectName string, subscriber AnimationSubscriber)
- func (ac *AnimationCoordinator) Unsubscribe(effectName string, subscriber AnimationSubscriber)
- func (ac *AnimationCoordinator) Update(frame uint64)
- type AnimationGroup
- func (ag *AnimationGroup) CombineAverage() *AnimationGroup
- func (ag *AnimationGroup) CombineMax() *AnimationGroup
- func (ag *AnimationGroup) CombineMin() *AnimationGroup
- func (ag *AnimationGroup) Start(frame uint64)
- func (ag *AnimationGroup) Update(frame uint64)
- func (ag *AnimationGroup) Value() float64
- func (ag *AnimationGroup) WithCombiner(combiner func(values []float64) float64) *AnimationGroup
- type AnimationMode
- type AnimationSequence
- type AnimationStep
- type AnimationSubscriber
- type Application
- type AutocompleteFunc
- type BaseWidget
- func (bw *BaseWidget) ClearDirty()
- func (bw *BaseWidget) Destroy()
- func (bw *BaseWidget) GetBounds() image.Rectangle
- func (bw *BaseWidget) GetLayoutParams() LayoutParams
- func (bw *BaseWidget) GetMinSize() image.Point
- func (bw *BaseWidget) GetParent() ComposableWidget
- func (bw *BaseWidget) GetPreferredSize() image.Point
- func (bw *BaseWidget) Init()
- func (bw *BaseWidget) IsVisible() bool
- func (bw *BaseWidget) MarkDirty()
- func (bw *BaseWidget) NeedsRedraw() bool
- func (bw *BaseWidget) SetBounds(bounds image.Rectangle)
- func (bw *BaseWidget) SetLayoutParams(params LayoutParams)
- func (bw *BaseWidget) SetMinSize(size image.Point)
- func (bw *BaseWidget) SetParent(parent ComposableWidget)
- func (bw *BaseWidget) SetPreferredSize(size image.Point)
- func (bw *BaseWidget) SetVisible(visible bool)
- type BatchEvent
- type BorderAnimation
- type BorderPart
- type BorderStyle
- type Box
- type CaseView
- type Cell
- type ChainedAnimation
- func (ca *ChainedAnimation) AddBorderAnimation(anim BorderAnimation, duration uint64) *ChainedAnimation
- func (ca *ChainedAnimation) AddTextAnimation(anim TextAnimation, duration uint64) *ChainedAnimation
- func (ca *ChainedAnimation) AddTransform(transform func(View) View, duration uint64) *ChainedAnimation
- func (ca *ChainedAnimation) GetCurrentStep(frame uint64) *AnimationStep
- type Cmd
- type Color
- type ComposableWidget
- type ConstraintLayoutManager
- type CornerHighlightAnimation
- type CursorConfig
- type CursorStyle
- type DebugInfo
- type DebugPosition
- type DebugWrapper
- type Destroyable
- type Diff
- type DiffFile
- type DiffHunk
- type DiffLine
- type DiffLineType
- type DiffRenderer
- type DiffTheme
- type DirtyRegion
- type Easing
- type ErrorEvent
- type Event
- type EventHandler
- type FireBorderAnimation
- type FlexAlignItems
- type FlexDirection
- type FlexJustify
- type FlexLayout
- func (fl *FlexLayout) CalculateMinSize(children []ComposableWidget) image.Point
- func (fl *FlexLayout) CalculatePreferredSize(children []ComposableWidget) image.Point
- func (fl *FlexLayout) Layout(containerBounds image.Rectangle, children []ComposableWidget)
- func (fl *FlexLayout) WithAlignItems(alignItems FlexAlignItems) *FlexLayout
- func (fl *FlexLayout) WithDirection(direction FlexDirection) *FlexLayout
- func (fl *FlexLayout) WithJustify(justify FlexJustify) *FlexLayout
- func (fl *FlexLayout) WithLineSpacing(lineSpacing int) *FlexLayout
- func (fl *FlexLayout) WithSpacing(spacing int) *FlexLayout
- func (fl *FlexLayout) WithWrap(wrap FlexWrap) *FlexLayout
- type FlexWrap
- type Flexible
- type FocusHandler
- type FocusManager
- func (fm *FocusManager) Clear()
- func (fm *FocusManager) FocusNext()
- func (fm *FocusManager) FocusPrev()
- func (fm *FocusManager) GetFocused() Focusable
- func (fm *FocusManager) GetFocusedID() string
- func (fm *FocusManager) HandleClick(x, y int) bool
- func (fm *FocusManager) HandleKey(event KeyEvent) bool
- func (fm *FocusManager) Register(f Focusable)
- func (fm *FocusManager) SetFocus(id string)
- type FocusNextEvent
- type FocusPrevEvent
- type FocusSetEvent
- type Focusable
- type Footer
- type Frame
- type GlitchAnimation
- type GlobalEffect
- func (ge *GlobalEffect) ColorValue() RGB
- func (ge *GlobalEffect) Start(frame uint64)
- func (ge *GlobalEffect) Type() GlobalEffectType
- func (ge *GlobalEffect) Update(frame uint64)
- func (ge *GlobalEffect) Value() float64
- func (ge *GlobalEffect) WithColorValue(color RGB) *GlobalEffect
- func (ge *GlobalEffect) WithEasing(easing Easing) *GlobalEffect
- func (ge *GlobalEffect) WithWaveParams(amplitude, frequency float64) *GlobalEffect
- type GlobalEffectType
- type GradientBorderAnimation
- type HBoxLayout
- func (hb *HBoxLayout) CalculateMinSize(children []ComposableWidget) image.Point
- func (hb *HBoxLayout) CalculatePreferredSize(children []ComposableWidget) image.Point
- func (hb *HBoxLayout) Layout(containerBounds image.Rectangle, children []ComposableWidget)
- func (hb *HBoxLayout) LayoutWithConstraints(children []ComposableWidget, constraints SizeConstraints, ...)
- func (hb *HBoxLayout) Measure(children []ComposableWidget, constraints SizeConstraints) image.Point
- func (hb *HBoxLayout) WithAlignment(align LayoutAlignment) *HBoxLayout
- func (hb *HBoxLayout) WithDistribute(distribute bool) *HBoxLayout
- type Header
- type Hyperlink
- type Initializable
- type InlineApp
- type InlineAppConfig
- type InlineApplication
- type InputCursorStyle
- type InputSource
- type Key
- type KeyDecoder
- type KeyEvent
- type Layout
- func (l *Layout) Close() error
- func (l *Layout) ContentArea() (y, height int)
- func (l *Layout) DisableAutoRefresh()
- func (l *Layout) Draw()
- func (l *Layout) DrawTo(frame RenderFrame)
- func (l *Layout) EnableAutoRefresh(interval time.Duration) *Layout
- func (l *Layout) PrintInContent(text string)
- func (l *Layout) Refresh()
- func (l *Layout) SetFooter(footer *Footer) *Layout
- func (l *Layout) SetHeader(header *Header) *Layout
- type LayoutAlignment
- type LayoutManager
- type LayoutParams
- type List
- func (l *List) Draw(frame RenderFrame)
- func (l *List) GetSelected() *ListItem
- func (l *List) HandleKey(event KeyEvent) bool
- func (l *List) HandleMouse(event MouseEvent) bool
- func (l *List) SelectNext()
- func (l *List) SelectPrev()
- func (l *List) SetItems(items []ListItem)
- func (l *List) SetStyles(normal, selected Style)
- type ListItem
- type ListItemRenderer
- type LivePrinter
- type MarkdownRenderer
- type MarkdownTheme
- type MarqueeBorderAnimation
- type Measurable
- type MetricsSnapshot
- type MouseAware
- type MouseButton
- type MouseEvent
- type MouseEventType
- type MouseHandler
- func (h *MouseHandler) AddRegion(region *MouseRegion)
- func (h *MouseHandler) CancelDrag()
- func (h *MouseHandler) ClearRegions()
- func (h *MouseHandler) DisableDebug()
- func (h *MouseHandler) EnableDebug()
- func (h *MouseHandler) HandleEvent(event *MouseEvent)
- func (h *MouseHandler) RemoveRegion(region *MouseRegion)
- type MouseModifiers
- type MouseRegion
- type PasswordInput
- func (p *PasswordInput) ConfirmPaste(confirm bool) *PasswordInput
- func (p *PasswordInput) DisableClipboard(disable bool) *PasswordInput
- func (p *PasswordInput) EnableSecureMode(enable bool) *PasswordInput
- func (p *PasswordInput) Read() (*SecureString, error)
- func (p *PasswordInput) ShowCharacters(show bool) *PasswordInput
- func (p *PasswordInput) WithMaskChar(char rune) *PasswordInput
- func (p *PasswordInput) WithMaxLength(length int) *PasswordInput
- func (p *PasswordInput) WithPlaceholder(placeholder string) *PasswordInput
- func (p *PasswordInput) WithPrompt(prompt string, style Style) *PasswordInput
- type PasteDisplayMode
- type PasteHandler
- type PasteHandlerDecision
- type PasteInfo
- type PlaybackController
- func (p *PlaybackController) GetDuration() float64
- func (p *PlaybackController) GetHeader() RecordingHeader
- func (p *PlaybackController) GetPosition() float64
- func (p *PlaybackController) GetProgress() float64
- func (p *PlaybackController) IsPaused() bool
- func (p *PlaybackController) Pause()
- func (p *PlaybackController) Play(terminal *Terminal) error
- func (p *PlaybackController) Resume()
- func (p *PlaybackController) Seek(seconds float64)
- func (p *PlaybackController) SetLoop(loop bool)
- func (p *PlaybackController) SetSpeed(speed float64)
- func (p *PlaybackController) Speed() float64
- func (p *PlaybackController) Stop()
- func (p *PlaybackController) TogglePause()
- type PrintConfig
- type ProgressBardeprecated
- type PromptOption
- func WithAutocomplete(fn AutocompleteFunc) PromptOption
- func WithHistory(history *[]string) PromptOption
- func WithInputStyle(style Style) PromptOption
- func WithMask(char string) PromptOption
- func WithMaxLength(n int) PromptOption
- func WithMultiLine(enabled bool) PromptOption
- func WithPlaceholder(text string) PromptOption
- func WithPromptOutput(w io.Writer) PromptOption
- func WithPromptStyle(style Style) PromptOption
- func WithValidator(fn func(string) error) PromptOption
- type PulseAnimation
- type PulseBorderAnimation
- type QuitEvent
- type RGB
- type RainbowAnimation
- type RainbowBorderAnimation
- type Recorder
- type RecordingEvent
- type RecordingHeader
- type RecordingOptions
- type RenderContext
- func (c *RenderContext) AbsoluteBounds() image.Rectangle
- func (c *RenderContext) Bounds() image.Rectangle
- func (c *RenderContext) Fill(char rune, style Style)
- func (c *RenderContext) FillStyled(x, y, width, height int, char rune, style Style)
- func (c *RenderContext) FocusManager() *FocusManager
- func (c *RenderContext) Frame() uint64
- func (c *RenderContext) PrintHyperlink(x, y int, link Hyperlink)
- func (c *RenderContext) PrintHyperlinkFallback(x, y int, link Hyperlink)
- func (c *RenderContext) PrintStyled(x, y int, text string, style Style)
- func (c *RenderContext) PrintTruncated(x, y int, text string, style Style)
- func (c *RenderContext) RenderFrame() RenderFrame
- func (c *RenderContext) SetCell(x, y int, char rune, style Style)
- func (c *RenderContext) Size() (width, height int)
- func (c *RenderContext) SubContext(bounds image.Rectangle) *RenderContext
- func (c *RenderContext) WithFocusManager(fm *FocusManager) *RenderContext
- func (c *RenderContext) WithFrame(frame RenderFrame) *RenderContext
- type RenderFrame
- type RenderMetrics
- type RenderedDiffLine
- type RenderedMarkdown
- type ResizeEvent
- type RunOption
- func WithAlternateScreen(enabled bool) RunOption
- func WithBracketedPaste(enabled bool) RunOption
- func WithFPS(fps int) RunOption
- func WithHideCursor(hide bool) RunOption
- func WithInput(source InputSource) RunOption
- func WithMouseTracking(enabled bool) RunOption
- func WithPasteTabWidth(width int) RunOption
- type Runtime
- type ScrollAnchor
- type SecureString
- type SizeConstraints
- type SlideAnimation
- type SparkleAnimation
- type SparkleBorderAnimation
- type Spinnerdeprecated
- func (s *Spinner) Bg(c Color) *Spinner
- func (s *Spinner) Bold() *Spinner
- func (s *Spinner) Dim() *Spinner
- func (s *Spinner) Draw(frame RenderFrame, x, y int)
- func (s *Spinner) Fg(c Color) *Spinner
- func (s *Spinner) Update(now time.Time)
- func (s *Spinner) WithMessage(message string) *Spinner
- func (s *Spinner) WithStyle(style Style) *Spinner
- type SpinnerStyle
- type StatusItem
- type Style
- type StyledLine
- type StyledSegment
- type TableColumn
- type Terminal
- type TextAnimation
- type TextInput
- func (t *TextInput) Clear()
- func (t *TextInput) DisplayText() string
- func (t *TextInput) Draw(frame RenderFrame)
- func (t *TextInput) HandleKey(event KeyEvent) bool
- func (t *TextInput) HandleMouse(event MouseEvent) bool
- func (t *TextInput) HandlePaste(content string) bool
- func (t *TextInput) SetFocused(focused bool)
- func (t *TextInput) SetValue(value string)
- func (t *TextInput) Value() string
- func (t *TextInput) WithCursorBlink(enabled bool) *TextInput
- func (t *TextInput) WithCursorBlinkInterval(interval time.Duration) *TextInput
- func (t *TextInput) WithCursorColor(color Color) *TextInput
- func (t *TextInput) WithCursorShape(shape InputCursorStyle) *TextInput
- func (t *TextInput) WithMask(char rune) *TextInput
- func (t *TextInput) WithMaxHeight(lines int) *TextInput
- func (t *TextInput) WithMaxLength(n int) *TextInput
- func (t *TextInput) WithMultilineMode(enabled bool) *TextInput
- func (t *TextInput) WithPastePlaceholderMode(enabled bool) *TextInput
- func (t *TextInput) WithPlaceholder(placeholder string) *TextInput
- func (t *TextInput) WithStyle(style Style) *TextInput
- func (t *TextInput) WithSubmitOnEnter(enabled bool) *TextInput
- type TickEvent
- type TreeBranchChars
- type TreeNode
- func (n *TreeNode) AddChild(child *TreeNode) *TreeNode
- func (n *TreeNode) AddChildren(children ...*TreeNode) *TreeNode
- func (n *TreeNode) CollapseAll()
- func (n *TreeNode) ExpandAll()
- func (n *TreeNode) IsLeaf() bool
- func (n *TreeNode) SetData(data any) *TreeNode
- func (n *TreeNode) SetExpanded(expanded bool) *TreeNode
- type TypewriterAnimation
- type VBoxLayout
- func (vb *VBoxLayout) CalculateMinSize(children []ComposableWidget) image.Point
- func (vb *VBoxLayout) CalculatePreferredSize(children []ComposableWidget) image.Point
- func (vb *VBoxLayout) Layout(containerBounds image.Rectangle, children []ComposableWidget)
- func (vb *VBoxLayout) LayoutWithConstraints(children []ComposableWidget, constraints SizeConstraints, ...)
- func (vb *VBoxLayout) Measure(children []ComposableWidget, constraints SizeConstraints) image.Point
- func (vb *VBoxLayout) WithAlignment(align LayoutAlignment) *VBoxLayout
- func (vb *VBoxLayout) WithDistribute(distribute bool) *VBoxLayout
- type View
- func Background(char rune, style Style, inner View) View
- func Empty() View
- func FocusableView(inner View, handler *FocusHandler) View
- func Height(h int, inner View) View
- func If(condition bool, view View) View
- func IfElse(condition bool, thenView, elseView View) View
- func MaxHeight(h int, inner View) View
- func MaxWidth(w int, inner View) View
- func MinHeight(h int, inner View) View
- func MinSize(w, h int, inner View) View
- func MinWidth(w int, inner View) View
- func Padding(n int, inner View) View
- func PaddingHV(h, v int, inner View) View
- func PaddingLTRB(left, top, right, bottom int, inner View) View
- func Size(w, h int, inner View) View
- func Switch[T comparable](value T, cases ...CaseView[T]) View
- func Width(w int, inner View) View
- type ViewProviderdeprecated
- type WaveAnimation
- type WaveBorderAnimation
- type Widget
Examples ¶
Constants ¶
const ( DiffLineContext = unidiff.LineContext DiffLineAdded = unidiff.LineAdded DiffLineRemoved = unidiff.LineRemoved DiffLineHeader = unidiff.LineHeader DiffLineHunkHeader = unidiff.LineHunkHeader )
Re-export DiffLineType constants with tui naming convention
const ( KeyUnknown = terminal.KeyUnknown KeyEnter = terminal.KeyEnter KeyTab = terminal.KeyTab KeyBackspace = terminal.KeyBackspace KeyEscape = terminal.KeyEscape KeyArrowUp = terminal.KeyArrowUp KeyArrowDown = terminal.KeyArrowDown KeyArrowLeft = terminal.KeyArrowLeft KeyArrowRight = terminal.KeyArrowRight KeyHome = terminal.KeyHome KeyEnd = terminal.KeyEnd KeyPageUp = terminal.KeyPageUp KeyPageDown = terminal.KeyPageDown KeyDelete = terminal.KeyDelete KeyInsert = terminal.KeyInsert KeyF1 = terminal.KeyF1 KeyF2 = terminal.KeyF2 KeyF3 = terminal.KeyF3 KeyF4 = terminal.KeyF4 KeyF5 = terminal.KeyF5 KeyF6 = terminal.KeyF6 KeyF7 = terminal.KeyF7 KeyF8 = terminal.KeyF8 KeyF9 = terminal.KeyF9 KeyF10 = terminal.KeyF10 KeyF11 = terminal.KeyF11 KeyF12 = terminal.KeyF12 KeyCtrlA = terminal.KeyCtrlA KeyCtrlB = terminal.KeyCtrlB KeyCtrlC = terminal.KeyCtrlC KeyCtrlD = terminal.KeyCtrlD KeyCtrlE = terminal.KeyCtrlE KeyCtrlF = terminal.KeyCtrlF KeyCtrlG = terminal.KeyCtrlG KeyCtrlH = terminal.KeyCtrlH KeyCtrlI = terminal.KeyCtrlI KeyCtrlJ = terminal.KeyCtrlJ KeyCtrlK = terminal.KeyCtrlK KeyCtrlL = terminal.KeyCtrlL KeyCtrlM = terminal.KeyCtrlM KeyCtrlN = terminal.KeyCtrlN KeyCtrlO = terminal.KeyCtrlO KeyCtrlP = terminal.KeyCtrlP KeyCtrlQ = terminal.KeyCtrlQ KeyCtrlR = terminal.KeyCtrlR KeyCtrlS = terminal.KeyCtrlS KeyCtrlT = terminal.KeyCtrlT KeyCtrlU = terminal.KeyCtrlU KeyCtrlV = terminal.KeyCtrlV KeyCtrlW = terminal.KeyCtrlW KeyCtrlX = terminal.KeyCtrlX KeyCtrlY = terminal.KeyCtrlY KeyCtrlZ = terminal.KeyCtrlZ )
Key constants
const ( PasteAccept = terminal.PasteAccept PasteReject = terminal.PasteReject PasteModified = terminal.PasteModified )
Paste constants
const ( PasteDisplayNormal = terminal.PasteDisplayNormal PasteDisplayPlaceholder = terminal.PasteDisplayPlaceholder PasteDisplayHidden = terminal.PasteDisplayHidden )
const ( MouseButtonLeft = terminal.MouseButtonLeft MouseButtonMiddle = terminal.MouseButtonMiddle MouseButtonRight = terminal.MouseButtonRight MouseButtonNone = terminal.MouseButtonNone MouseButtonWheelUp = terminal.MouseButtonWheelUp MouseButtonWheelDown = terminal.MouseButtonWheelDown MouseButtonWheelLeft = terminal.MouseButtonWheelLeft MouseButtonWheelRight = terminal.MouseButtonWheelRight )
MouseButton constants
const ( MousePress = terminal.MousePress MouseRelease = terminal.MouseRelease MouseClick = terminal.MouseClick MouseDoubleClick = terminal.MouseDoubleClick MouseTripleClick = terminal.MouseTripleClick MouseDrag = terminal.MouseDrag MouseDragStart = terminal.MouseDragStart MouseDragEnd = terminal.MouseDragEnd MouseDragCancel = terminal.MouseDragCancel MouseMove = terminal.MouseMove MouseEnter = terminal.MouseEnter MouseLeave = terminal.MouseLeave MouseScroll = terminal.MouseScroll )
MouseEventType constants
const ( ModShift = terminal.ModShift ModAlt = terminal.ModAlt ModCtrl = terminal.ModCtrl ModMeta = terminal.ModMeta )
MouseModifiers constants
const ( CursorDefault = terminal.CursorDefault CursorPointer = terminal.CursorPointer CursorText = terminal.CursorText CursorResizeEW = terminal.CursorResizeEW CursorResizeNS = terminal.CursorResizeNS CursorResizeNESW = terminal.CursorResizeNESW CursorResizeNWSE = terminal.CursorResizeNWSE CursorMove = terminal.CursorMove CursorNotAllowed = terminal.CursorNotAllowed )
CursorStyle constants
const ( BorderNone borderStyleType = iota BorderSingle BorderDouble BorderRounded BorderHeavy )
const ( ColorDefault = terminal.ColorDefault ColorBlack = terminal.ColorBlack ColorRed = terminal.ColorRed ColorGreen = terminal.ColorGreen ColorYellow = terminal.ColorYellow ColorBlue = terminal.ColorBlue ColorMagenta = terminal.ColorMagenta ColorCyan = terminal.ColorCyan ColorWhite = terminal.ColorWhite ColorBrightBlack = terminal.ColorBrightBlack ColorBrightRed = terminal.ColorBrightRed ColorBrightGreen = terminal.ColorBrightGreen ColorBrightYellow = terminal.ColorBrightYellow ColorBrightBlue = terminal.ColorBrightBlue ColorBrightMagenta = terminal.ColorBrightMagenta ColorBrightCyan = terminal.ColorBrightCyan ColorBrightWhite = terminal.ColorBrightWhite )
Re-export color constants from terminal
const ( AlignLeft = terminal.AlignLeft AlignCenter = terminal.AlignCenter AlignRight = terminal.AlignRight )
Re-export alignment constants from terminal
Variables ¶
var ( // ErrInterrupted is returned when the user presses Ctrl+C. ErrInterrupted = errors.New("interrupted") // ErrEOF is returned when the user presses Ctrl+D on empty input. ErrEOF = errors.New("end of input") )
Common errors returned by Prompt
var ( SpinnerDots = SpinnerStyle{ Frames: []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}, Interval: 80 * time.Millisecond, } SpinnerLine = SpinnerStyle{ Frames: []string{"-", "\\", "|", "/"}, Interval: 100 * time.Millisecond, } SpinnerArrows = SpinnerStyle{ Frames: []string{"←", "↖", "↑", "↗", "→", "↘", "↓", "↙"}, Interval: 100 * time.Millisecond, } SpinnerCircle = SpinnerStyle{ Frames: []string{"◐", "◓", "◑", "◒"}, Interval: 120 * time.Millisecond, } SpinnerSquare = SpinnerStyle{ Frames: []string{"◰", "◳", "◲", "◱"}, Interval: 100 * time.Millisecond, } SpinnerBounce = SpinnerStyle{ Frames: []string{"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"}, Interval: 80 * time.Millisecond, } SpinnerBar = SpinnerStyle{ Frames: []string{ "[ ]", "[= ]", "[== ]", "[=== ]", "[====]", "[ ===]", "[ ==]", "[ =]", }, Interval: 80 * time.Millisecond, } SpinnerStars = SpinnerStyle{ Frames: []string{ "✶", "✸", "✹", "✺", "✹", "✷", }, Interval: 120 * time.Millisecond, } SpinnerStarField = SpinnerStyle{ Frames: []string{ "· ", "*· ", "✦*· ", "✧✦*·", "·✧✦*", " ·✧✦", " ·✧", " ·", }, Interval: 100 * time.Millisecond, } SpinnerAsterisk = SpinnerStyle{ Frames: []string{ "*", "⁎", "✱", "✲", "✳", "✴", "✵", "✶", "✷", "✸", "✹", "✺", }, Interval: 100 * time.Millisecond, } SpinnerSparkle = SpinnerStyle{ Frames: []string{ "✨", "💫", "⭐", "🌟", "✨", "💫", }, Interval: 150 * time.Millisecond, } )
Predefined spinner styles
var ( NewRGB = terminal.NewRGB Gradient = terminal.Gradient RainbowGradient = terminal.RainbowGradient SmoothRainbow = terminal.SmoothRainbow MultiGradient = terminal.MultiGradient )
Re-export color functions from terminal
var ( SingleBorder = terminal.SingleBorder DoubleBorder = terminal.DoubleBorder RoundedBorder = terminal.RoundedBorder ThickBorder = terminal.ThickBorder ASCIIBorder = terminal.ASCIIBorder )
Re-export border styles from terminal
var ( NewTerminal = terminal.NewTerminal NewTestTerminal = terminal.NewTestTerminal NewRenderMetrics = terminal.NewRenderMetrics NewHyperlink = terminal.NewHyperlink OSC8Start = terminal.OSC8Start OSC8End = terminal.OSC8End NewFrame = terminal.NewFrame )
Re-export terminal functions
var ( ErrOutOfBounds = terminal.ErrOutOfBounds ErrNotInRawMode = terminal.ErrNotInRawMode ErrClosed = terminal.ErrClosed ErrInvalidFrame = terminal.ErrInvalidFrame ErrAlreadyActive = terminal.ErrAlreadyActive )
Re-export error types from terminal
var AnimationPresets = struct { FadeIn func(uint64) *Animation FadeOut func(uint64) *Animation Pulse func(uint64) *Animation Bounce func(uint64) *Animation Elastic func(uint64) *Animation SlideIn func(uint64) *Animation Attention func(uint64) *Animation }{ FadeIn: PresetFadeIn, FadeOut: PresetFadeOut, Pulse: PresetPulse, Bounce: PresetBounce, Elastic: PresetElastic, SlideIn: PresetSlideIn, Attention: PresetAttention, }
AnimationPresets provides common animation presets.
var BorderAnimationPresets = struct { Pulsing func(RGB, int) BorderAnimation Rainbow func(int, bool) BorderAnimation Marquee func(RGB, RGB, int, int) BorderAnimation Fire func(int) BorderAnimation }{ Pulsing: PresetPulsingBorder, Rainbow: PresetRainbowBorder, Marquee: PresetMarqueeBorder, Fire: PresetFireBorder, }
BorderAnimationPresets provides common border animation presets.
var GlobalAnimationCoordinator = NewAnimationCoordinator()
GlobalAnimationCoordinator manages cross-view animations and global effects. It allows views to opt into synchronized animations and global effects.
var NewKeyDecoder = terminal.NewKeyDecoder
NewKeyDecoder creates a new key decoder
var NewStyle = terminal.NewStyle
Re-export style constructor
var ParseMouseEvent = terminal.ParseMouseEvent
ParseMouseEvent parses a mouse event from terminal input
Functions ¶
func AlignText ¶
AlignText aligns the given text within the specified width. It processes each line of the text individually.
func AnimatedBordered ¶ added in v0.0.2
func AnimatedBordered(inner View, animation BorderAnimation) *animatedBorderedView
AnimatedBordered wraps a view with an animated border.
func ApplyConstraints ¶
func ApplyConstraints(size image.Point, constraints SizeConstraints) image.Point
ApplyConstraints applies size constraints to a size, returning the constrained size
func AvailableLanguages ¶
func AvailableLanguages() []string
AvailableLanguages returns a list of available language lexers.
func AvailableThemes ¶
func AvailableThemes() []string
AvailableThemes returns a list of available syntax highlighting themes.
func Bordered ¶
func Bordered(inner View) *borderedView
Bordered wraps a view with a border and optional title. The border consumes 2 cells of width and height (1 on each side).
Use the builder pattern to customize the border:
Bordered(content).
Border(&RoundedBorder).
Title("Box Title").
BorderFg(ColorCyan)
Focus-aware borders change color when a watched element is focused:
Bordered(InputField(&app.input)).
FocusID("my-input").
FocusBorderFg(ColorGreen)
Example ¶
ExampleBordered demonstrates bordered views.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
content := tui.Text("Inside box")
// Simple border
_ = tui.Bordered(content)
// Border with title and styling
_ = tui.Bordered(content).
Border(&tui.RoundedBorder).
Title("Box Title").
BorderFg(tui.ColorCyan)
// Focus-aware border
_ = tui.Bordered(content).
FocusID("my-element").
FocusBorderFg(tui.ColorGreen)
}
func Button ¶ added in v0.0.2
func Button(label string, callback func()) *buttonView
Button creates a focusable button element. The callback is invoked when the button is clicked or activated with Enter/Space.
Example:
Button("Submit", func() { app.submit() })
Example ¶
ExampleButton demonstrates interactive buttons.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
type App struct {
count int
}
app := &App{}
// Button with callback
button := tui.Button("Click Me", func() {
app.count++
})
// Styled button
_ = tui.Button("Submit", func() {}).
Fg(tui.ColorGreen).
Bold()
_ = button
}
func Canvas ¶
func Canvas(draw func(frame RenderFrame, bounds image.Rectangle)) *canvasView
Canvas creates a view that calls a custom draw function. This is the escape hatch for imperative drawing within declarative UI.
Example:
Canvas(func(frame RenderFrame, bounds image.Rectangle) {
// Custom imperative drawing
frame.PrintStyled(0, 0, "Custom content", style)
})
func CanvasContext ¶ added in v0.0.2
func CanvasContext(draw func(ctx *RenderContext)) *canvasView
CanvasContext creates a view with access to the full RenderContext. Use this when you need access to context information like the animation frame counter (ctx.Frame()) for custom animations.
Example:
CanvasContext(func(ctx *RenderContext) {
w, h := ctx.Size()
frame := ctx.Frame() // Animation frame counter
// Custom drawing using frame for animation timing
x := int(frame) % w
ctx.SetCell(x, 0, '█', style)
})
func CellGrid ¶
func CellGrid(cols, rows int) *gridView
CellGrid creates a grid of clickable cells.
Example:
CellGrid(5, 5).CellSize(6, 3).Gap(1).OnClick(func(c, r int) { ... })
func CharGrid ¶
func CharGrid(data [][]rune) *charGridView
CharGrid creates a grid displaying characters.
Example:
CharGrid([][]rune{
{'X', 'O', 'X'},
{'O', 'X', 'O'},
{'X', 'O', 'X'},
})
func CheckboxList ¶
CheckboxList creates a list with checkable items. checked should be a slice tracking which items are checked. cursor should be a pointer to the current cursor position.
The component handles keyboard navigation (arrow keys) and toggling (space) automatically when focused. Use Tab to focus the list.
For focus management to work, you must set an ID using the ID() method. Without an ID, the list will not be focusable via Tab key navigation.
Example:
CheckboxList(items, app.checked, &app.cursor).
ID("my-checkbox-list").
OnToggle(func(i int, c bool) { ... })
func CheckboxListStrings ¶
CheckboxListStrings creates a checkbox list from string labels.
func ClearLine ¶ added in v0.0.18
func ClearLine(cfg ...CursorConfig)
ClearLine clears the entire current line.
func ClearLines ¶ added in v0.0.18
func ClearLines(n int, cfg ...CursorConfig)
ClearLines clears n lines starting from the current cursor position, moving upward. Useful for clearing multi-line input areas. After clearing, the cursor is positioned at the start of the top-most cleared line.
func ClearLinesDown ¶ added in v0.0.18
func ClearLinesDown(n int, cfg ...CursorConfig)
ClearLinesDown clears n lines starting from current position, moving downward. After clearing, cursor is at the start of the last cleared line.
func ClearScreen ¶ added in v0.0.18
func ClearScreen(cfg ...CursorConfig)
ClearScreen clears the entire screen and moves cursor to top-left.
func ClearToEndOfLine ¶ added in v0.0.18
func ClearToEndOfLine(cfg ...CursorConfig)
ClearToEndOfLine clears from cursor to end of current line.
func ClearToEndOfScreen ¶ added in v0.0.18
func ClearToEndOfScreen(cfg ...CursorConfig)
ClearToEndOfScreen clears from cursor to end of screen.
func ClearToStartOfLine ¶ added in v0.0.18
func ClearToStartOfLine(cfg ...CursorConfig)
ClearToStartOfLine clears from cursor to start of current line.
func ClearToStartOfScreen ¶ added in v0.0.18
func ClearToStartOfScreen(cfg ...CursorConfig)
ClearToStartOfScreen clears from cursor to start of screen.
func Clickable ¶
func Clickable(label string, callback func()) *clickableView
Clickable creates a mouse-only clickable element (not keyboard focusable). For keyboard-accessible buttons, use Button() instead.
Example:
Clickable("Link", func() { app.openLink() })
func Code ¶
Code creates a code view with syntax highlighting.
Example:
Code(`func main() {
fmt.Println("Hello")
}`, "go")
func ColorGrid ¶
ColorGrid creates a grid where clicking cycles through colors. state should be a 2D slice tracking the color index for each cell.
Example:
ColorGrid(5, 5, app.gridState, []Color{ColorBlack, ColorRed, ColorGreen, ColorBlue})
func CoordinatedView ¶ added in v0.0.2
func CoordinatedView(inner View, effectName string, transformFunc func(View, float64) View) *coordinatedView
CoordinatedView wraps a view to participate in a global animation effect. transformFunc is called with the current effect value to transform the view.
func Debug ¶
func Debug(info *DebugInfo) *debugView
Debug creates a debug overlay view that displays runtime statistics.
Example:
type MyApp struct {
debug *tui.DebugInfo
}
func (app *MyApp) View() tui.View {
return tui.ZStack(
app.mainContent(),
tui.Debug(&app.debug).Position(tui.DebugTopRight),
)
}
func (app *MyApp) HandleEvent(event tui.Event) []tui.Cmd {
app.debug.Update(event) // Call this to track events
// ...
}
func DiffView ¶
DiffView creates a diff view from a parsed Diff. scrollY should be a pointer to the scroll position (optional, can be nil).
Example:
diff, _ := tui.ParseUnifiedDiff(diffText) DiffView(diff, "go", &app.scrollY)
func DiffViewFromText ¶
DiffViewFromText creates a diff view from diff text. Returns an error if the diff cannot be parsed.
func Divider ¶
func Divider() *dividerView
Divider creates a horizontal line separator that fills available width.
Example:
Divider()
Divider().Char('═')
Divider().Title("Section")
func EaseInBack ¶ added in v0.0.2
EaseInBack overshoots then returns.
func EaseInBounce ¶ added in v0.0.2
EaseInBounce creates a bouncing effect at the start.
func EaseInCirc ¶ added in v0.0.2
EaseInCirc accelerates using circular function.
func EaseInCubic ¶ added in v0.0.2
EaseInCubic accelerates from zero velocity (cubic).
func EaseInElastic ¶ added in v0.0.2
EaseInElastic creates an elastic/spring effect at the start.
func EaseInExpo ¶ added in v0.0.2
EaseInExpo accelerates exponentially.
func EaseInOutBack ¶ added in v0.0.2
EaseInOutBack overshoots in both directions.
func EaseInOutBounce ¶ added in v0.0.2
EaseInOutBounce creates a bouncing effect in both directions.
func EaseInOutCirc ¶ added in v0.0.2
EaseInOutCirc accelerates and decelerates using circular function.
func EaseInOutCubic ¶ added in v0.0.2
EaseInOutCubic accelerates until halfway, then decelerates (cubic).
func EaseInOutElastic ¶ added in v0.0.2
EaseInOutElastic creates an elastic effect in both directions.
func EaseInOutExpo ¶ added in v0.0.2
EaseInOutExpo accelerates and decelerates exponentially.
func EaseInOutQuad ¶ added in v0.0.2
EaseInOutQuad accelerates until halfway, then decelerates (quadratic).
func EaseInOutQuart ¶ added in v0.0.2
EaseInOutQuart accelerates until halfway, then decelerates (quartic).
func EaseInOutSine ¶ added in v0.0.2
EaseInOutSine accelerates and decelerates using sine wave.
func EaseInQuad ¶ added in v0.0.2
EaseInQuad accelerates from zero velocity (quadratic).
func EaseInQuart ¶ added in v0.0.2
EaseInQuart accelerates from zero velocity (quartic).
func EaseInSine ¶ added in v0.0.2
EaseInSine accelerates using sine wave.
func EaseLinear ¶ added in v0.0.2
EaseLinear provides constant speed (no easing).
func EaseOutBack ¶ added in v0.0.2
EaseOutBack overshoots then settles.
func EaseOutBounce ¶ added in v0.0.2
EaseOutBounce creates a bouncing effect at the end.
func EaseOutCirc ¶ added in v0.0.2
EaseOutCirc decelerates using circular function.
func EaseOutCubic ¶ added in v0.0.2
EaseOutCubic decelerates to zero velocity (cubic).
func EaseOutElastic ¶ added in v0.0.2
EaseOutElastic creates an elastic/spring effect at the end.
func EaseOutExpo ¶ added in v0.0.2
EaseOutExpo decelerates exponentially.
func EaseOutQuad ¶ added in v0.0.2
EaseOutQuad decelerates to zero velocity (quadratic).
func EaseOutQuart ¶ added in v0.0.2
EaseOutQuart decelerates to zero velocity (quartic).
func EaseOutSine ¶ added in v0.0.2
EaseOutSine decelerates using sine wave.
func FilePicker ¶
FilePicker creates a file picker view with filter and list. items should contain the files/directories to display. filter should be a pointer to the filter text. selected should be a pointer to the selected index.
The filter input and list are keyboard navigable. Use Tab to switch between them, type to filter, and arrow keys to navigate the list.
Example:
FilePicker(app.files, &app.filter, &app.selected).
CurrentPath(app.currentDir).
OnSelect(func(item ListItem, index int) { app.handleSelect(item, index) })
func Fill ¶
func Fill(char rune) *fillView
Fill creates a view that fills its available space with the given character.
func FilterableList ¶ added in v0.0.2
FilterableList creates a new filterable list view with the given items. selected is a pointer to the currently selected index (cursor position) in the filtered list.
The component handles keyboard navigation (arrow keys), filtering (typing), and selection (Enter) automatically when focused. Use Tab to focus the list.
For focus management to work, you must set an ID using the ID() method. Without an ID, the list will not be focusable via Tab key navigation.
To track chosen items (items confirmed with Enter), use Chosen() to bind an external slice. Use MultiSelect(true) to allow multiple items to be chosen, or leave as single-select mode (default) where choosing a new item clears the previous choice. Use Markers() to display chosen/unchosen indicators on the right side of each item.
Example:
FilterableList(items, &app.selected).
ID("my-list").
Filter(&app.filterText).
Height(10).
MultiSelect(true).
Chosen(&app.chosen).
Markers("[ ]", "[x]").
OnSelect(func(item tui.ListItem, idx int) { ... })
func FilterableListStrings ¶ added in v0.0.2
FilterableListStrings creates a filterable list from string labels.
func FocusText ¶ added in v0.0.2
FocusText creates a text view that changes style based on a watched focus ID. This is useful for labels that should highlight when their associated input is focused.
Example:
FocusText("Name: ", "name-input").
Style(dimStyle).
FocusStyle(brightStyle)
func ForEach ¶
ForEach maps a slice of items to views using a mapper function. The resulting views are arranged in a Stack by default.
Example:
ForEach(app.items, func(item Item, i int) View {
return Text("%d. %s", i+1, item.Name)
})
func Fprint ¶ added in v0.0.2
func Fprint(w io.Writer, view View, cfgs ...PrintConfig) error
Fprint renders a view to the specified writer.
func FuzzyMatch ¶
FuzzyMatch checks if pattern matches text (subsequence match)
func FuzzySearch ¶
FuzzySearch returns the top matches for pattern in candidates
func Group ¶ added in v0.0.2
func Group(children ...View) *group
Group creates a group that arranges children left-to-right (horizontal layout).
Children are laid out horizontally with optional spacing and alignment. Flexible children (like Spacer) will expand to fill available space.
Example:
Group(
Text("Left"),
Spacer(),
Text("Right"),
).Gap(2).Align(AlignCenter)
func HForEach ¶
HForEach is like ForEach but arranges items horizontally in a Group.
Example:
HForEach(app.tabs, func(tab Tab, i int) View {
return Text(tab.Title).Padding(1)
})
func HeaderBar ¶
func HeaderBar(text string) *headerBarView
HeaderBar creates a full-width header bar with centered text.
Example:
HeaderBar("My App").Bg(ColorBlue).Fg(ColorWhite)
func HideCursor ¶ added in v0.0.18
func HideCursor(cfg ...CursorConfig)
HideCursor hides the cursor.
func InlineLinks ¶
InlineLinks creates a horizontal row of hyperlinks with separators.
Example:
InlineLinks(" | ",
NewHyperlink("https://go.dev", "Go"),
NewHyperlink("https://github.com", "GitHub"),
)
func Input ¶
func Input(binding *string) *inputView
Input creates a text input view bound to a string pointer. Changes to the input will update the bound string.
Example:
Input(&app.name).Placeholder("Enter name...")
func InputField ¶ added in v0.0.2
func InputField(binding *string) *inputFieldView
InputField creates a high-level input component with optional label and border. Focus styling is handled automatically - the label and border change appearance when the input is focused.
Example:
InputField(&app.name).
Label("Name:").
Placeholder("Enter your name").
Bordered().
Width(40)
Example ¶
ExampleInputField demonstrates text input fields.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
type App struct {
name string
email string
}
app := &App{}
// Basic input field
input := tui.InputField(&app.name).
Label("Name:").
Placeholder("Enter your name")
// Input with border and custom styling
_ = tui.InputField(&app.email).
Label("Email").
Placeholder("[email protected]").
Bordered().
FocusBorderFg(tui.ColorCyan).
Width(40)
_ = input
}
func KeyValue ¶
func KeyValue(label, value string) *keyValueView
KeyValue creates a key-value pair display.
Example:
KeyValue("Name", "John Doe")
KeyValue("Status", "Active").LabelFg(ColorYellow).ValueFg(ColorGreen)
func Link ¶
func Link(url, text string) *hyperlinkView
Link creates a declarative hyperlink view. If text is empty, the URL will be used as the display text.
Example:
Link("https://github.com", "GitHub")
Link("https://example.com", "").Fg(ColorCyan) // uses URL as text
func LinkList ¶
func LinkList(links ...Hyperlink) *linkListView
LinkList creates a vertical list of hyperlinks.
Example:
LinkList(
NewHyperlink("https://go.dev", "Go"),
NewHyperlink("https://github.com", "GitHub"),
)
func LinkRow ¶
func LinkRow(label, url, linkText string) *linkRowView
LinkRow creates a label + hyperlink pair, useful for tables of links.
Example:
LinkRow("Documentation", "https://docs.example.com", "docs.example.com")
func Live ¶ added in v0.0.2
func Live(fn func(update func(View)), cfgs ...PrintConfig) error
Live is a convenience function for simple live updates with a callback. It creates a LivePrinter, calls the provided function with an update callback, and automatically stops when done.
Example:
tui.Live(func(update func(tui.View)) {
for i := 0; i <= 100; i++ {
update(tui.Text("Loading... %d%%", i))
time.Sleep(50 * time.Millisecond)
}
}, tui.PrintConfig{Width: 40})
func Loading ¶
func Loading(frame uint64) *loadingView
Loading creates an animated loading spinner view. The frame parameter should come from TickEvent.Frame for animation.
Example:
Loading(app.frame).Label("Loading...")
Loading(app.frame).CharSet(SpinnerDots.Frames)
func Markdown ¶
Markdown creates a markdown view with the given content. scrollY should be a pointer to the scroll position (optional, can be nil).
Example:
Markdown(content, &app.scrollY).Theme(tui.DefaultMarkdownTheme())
func MeasureText ¶
MeasureText returns the width and height (number of lines) of the text.
func MeasureWidget ¶
func MeasureWidget(w ComposableWidget, c SizeConstraints) image.Point
MeasureWidget is a helper to measure a widget whether it implements Measurable or not. If the widget is Measurable, it calls Measure. Otherwise, it calls GetPreferredSize and applies the constraints.
func MoveCursorDown ¶ added in v0.0.18
func MoveCursorDown(n int, cfg ...CursorConfig)
MoveCursorDown moves the cursor down n lines.
func MoveCursorLeft ¶ added in v0.0.18
func MoveCursorLeft(n int, cfg ...CursorConfig)
MoveCursorLeft moves the cursor left n columns.
func MoveCursorRight ¶ added in v0.0.18
func MoveCursorRight(n int, cfg ...CursorConfig)
MoveCursorRight moves the cursor right n columns.
func MoveCursorUp ¶ added in v0.0.18
func MoveCursorUp(n int, cfg ...CursorConfig)
MoveCursorUp moves the cursor up n lines.
func MoveToColumn ¶ added in v0.0.18
func MoveToColumn(col int, cfg ...CursorConfig)
MoveToColumn moves the cursor to the specified column (1-based).
func MoveToLineStart ¶ added in v0.0.18
func MoveToLineStart(cfg ...CursorConfig)
MoveToLineStart moves the cursor to the beginning of the current line.
func Newline ¶ added in v0.0.18
func Newline(cfg ...CursorConfig)
Newline prints a newline character.
func Panel ¶
func Panel(content View) *panelView
Panel creates a filled box/panel view with optional content.
Example:
Panel(nil).Width(20).Height(5).Bg(ColorBlue)
Panel(Text("Hello")).Border(BorderSingle)
func Print ¶ added in v0.0.2
func Print(view View, cfgs ...PrintConfig) error
Print renders a view to the terminal without taking over the screen. This outputs the view inline, preserving scroll history and existing content.
Unlike Run(), Print does not:
- Enable alternate screen mode
- Enable raw mode or handle keyboard input
- Clear the screen
- Start an event loop
This is useful for CLI tools that want to display styled output once and then exit, without the full TUI experience.
Example:
view := tui.Stack(
tui.Text("Hello").Bold(),
tui.Text("World").Foreground(tui.ColorRed),
)
tui.Print(view)
With configuration:
tui.Print(view, tui.PrintConfig{Width: 60})
func Progress ¶
func Progress(current, total int) *progressView
Progress creates a declarative progress bar view. current is the current progress value, total is the maximum value.
Example:
Progress(50, 100).Width(30).ShowPercent()
func Prompt ¶ added in v0.0.19
func Prompt(prompt string, opts ...PromptOption) (string, error)
Prompt reads a line of input from the user with rich editing support. It temporarily enables raw mode, handles input, and restores terminal state. Returns the entered text (trimmed) or an error.
Errors:
- ErrInterrupted: User pressed Ctrl+C
- ErrEOF: User pressed Ctrl+D on empty input
- Other errors from terminal operations
Example:
input, err := tui.Prompt("> ",
tui.WithHistory(&history),
tui.WithAutocomplete(completeFn),
tui.WithMultiLine(true),
)
func PromptChoice ¶ added in v0.0.22
PromptChoice creates a prompt choice view with selectable options.
This component creates a Claude Code-style selection interface with numbered options and optional inline text input. It's ideal for confirmation dialogs, action menus, and prompts that need both preset choices and custom input.
Parameters ¶
- selected: Pointer to track the currently selected index (0-based). This value updates as the user navigates.
- inputText: Pointer to store custom input text. Can be nil if no input option is needed. When an InputOption is added, typed text is stored here.
Basic Example ¶
var selected int
var customText string
view := PromptChoice(&selected, &customText).
Option("Yes").
Option("No").
OnSelect(func(idx int, text string) {
if idx == 0 {
// User selected "Yes"
}
})
With Input Option ¶
view := PromptChoice(&selected, &customText).
Option("Approve").
Option("Reject").
InputOption("Provide feedback...").
OnSelect(func(idx int, text string) {
if idx == 2 {
// User typed custom feedback in 'text'
fmt.Println("Feedback:", text)
}
}).
OnCancel(func() {
fmt.Println("Cancelled")
})
Customization Example ¶
view := PromptChoice(&selected, nil).
Option("Option A").
Option("Option B").
CursorChar(">").
ShowNumbers(false).
HintText("Press Enter to confirm").
Style(tui.NewStyle().WithForeground(tui.ColorCyan))
InlineApp Integration ¶
In an InlineApp, include PromptChoice in your LiveView:
func (app *App) LiveView() tui.View {
return tui.Stack(
tui.Text("Do you want to proceed?").Bold(),
tui.Text(""),
tui.PromptChoice(&app.selected, &app.input).
Option("Yes").
Option("No").
InputOption("Other...").
OnSelect(app.handleSelection).
OnCancel(app.handleCancel),
)
}
func RadioList ¶
RadioList creates a list with radio button items (single selection). selected should be a pointer to the currently selected index.
The component handles keyboard navigation (arrow keys) and selection (Enter/Space) automatically when focused. Use Tab to focus the list.
For focus management to work, you must set an ID using the ID() method. Without an ID, the list will not be focusable via Tab key navigation.
Example:
RadioList(items, &app.selected).
ID("my-radio-list").
OnSelect(func(i int) { ... })
func RadioListStrings ¶
RadioListStrings creates a radio list from string labels.
func ReadPassword ¶
ReadPassword reads a password with no echo to the terminal.
func ReadSimple ¶
ReadSimple reads a single line of input from stdin.
func RestoreCursor ¶ added in v0.0.18
func RestoreCursor(cfg ...CursorConfig)
RestoreCursor restores the cursor to the last saved position.
func Run ¶
Run is the simplest way to start a Wonton application. It creates a terminal, configures it, runs the application, and cleans up.
The app parameter must implement Application.
Example:
type MyApp struct {
count int
}
func (app *MyApp) View() tui.View {
return tui.Stack(
tui.Text("Count: %d", app.count),
tui.Clickable("[+]", func() { app.count++ }),
)
}
func (app *MyApp) HandleEvent(event tui.Event) []tui.Cmd {
if key, ok := event.(tui.KeyEvent); ok && key.Rune == 'q' {
return []tui.Cmd{tui.Quit()}
}
return nil
}
func main() {
if err := tui.Run(&MyApp{}); err != nil {
log.Fatal(err)
}
}
Options can be passed to customize behavior:
tui.Run(&MyApp{},
tui.WithFPS(60),
tui.WithMouseTracking(true),
)
Example ¶
ExampleRun demonstrates running a TUI application with options.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
type App struct{}
app := &App{}
// Run with default options
// tui.Run(app)
// Run with custom options
_ = tui.Run(app,
tui.WithFPS(60), // 60 FPS for smooth animations
tui.WithMouseTracking(true), // Enable mouse events
tui.WithAlternateScreen(true), // Use alternate screen buffer
tui.WithBracketedPaste(true), // Handle pasted text properly
)
}
func RunInline ¶ added in v0.0.19
RunInline is a convenience function that creates and runs an InlineApp. You can configure it by passing a configuration function that receives the app.
Example:
err := tui.RunInline(&MyApp{}, func(app *tui.InlineApp) {
app.Width(80).BracketedPaste(true)
})
func SaveCursor ¶ added in v0.0.18
func SaveCursor(cfg ...CursorConfig)
SaveCursor saves the current cursor position. Use RestoreCursor to return to this position later.
Example:
tui.SaveCursor()
fmt.Println("This text appears below")
tui.RestoreCursor()
fmt.Print("Cursor is back!")
func Scroll ¶
Scroll creates a scrollable viewport around the inner view. If scrollY is provided, it controls the scroll offset externally.
Example:
Scroll(content, &app.scrollY).Anchor(ScrollAnchorBottom) Scroll(content, nil).Bottom() // auto-scroll to bottom
func SelectList ¶
SelectList creates a selectable list view using the existing ListItem type. selected should be a pointer to the currently selected index.
The component handles keyboard navigation (arrow keys) and selection (Enter) automatically when focused. Use Tab to focus the list.
Example:
SelectList(items, &app.selectedIndex).OnSelect(func(item, idx) { app.handleSelect(item, idx) })
func SelectListStrings ¶
SelectListStrings creates a list from string labels.
func ShowCursor ¶ added in v0.0.18
func ShowCursor(cfg ...CursorConfig)
ShowCursor shows the cursor.
func Spacer ¶
func Spacer() *spacerView
Spacer returns a flexible view that expands to fill available space. In a Stack, it fills vertical space. In a Group, it fills horizontal space.
Spacers are useful for pushing content to edges or distributing space:
Stack(
Text("Top"),
Spacer(), // Pushes footer to bottom
Text("Bottom"),
)
Group(
Text("Left"),
Spacer(), // Pushes right content to edge
Text("Right"),
)
Example ¶
ExampleSpacer demonstrates flexible space distribution.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
// Push content to opposite edges
view := tui.Stack(
tui.Text("Top"),
tui.Spacer(), // Fills all available space
tui.Text("Bottom"),
)
_ = view
}
func Sprint ¶ added in v0.0.2
func Sprint(view View, cfgs ...PrintConfig) string
Sprint renders a view to a string with ANSI escape codes.
func SprintScreen ¶ added in v0.0.2
func SprintScreen(view View, cfgs ...PrintConfig) *termtest.Screen
SprintScreen renders a view and returns a termtest.Screen for assertions. This is a convenience function for testing that combines Sprint with termtest.Screen parsing, making it easy to write precise visual tests.
Example:
func TestButton(t *testing.T) {
btn := Button("Submit", func() {})
screen := SprintScreen(btn, PrintConfig{Width: 20})
termtest.AssertRowContains(t, screen, 0, "Submit")
}
func Stack ¶ added in v0.0.2
func Stack(children ...View) *stack
Stack creates a vertical stack that arranges children top-to-bottom. This is one of the primary layout containers in TUI applications.
Children are laid out vertically with optional spacing and alignment. Flexible children (like Spacer) will expand to fill available space.
Example:
Stack(
Text("Header").Bold(),
Spacer(),
Text("Footer"),
).Gap(1).Align(AlignCenter)
Example ¶
ExampleStack demonstrates vertical layout of views.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
// Stack arranges children vertically
view := tui.Stack(
tui.Text("Header").Bold(),
tui.Text("Body content"),
tui.Spacer(),
tui.Text("Footer").Dim(),
).Gap(1) // 1 row between children
_ = view
}
func StatusBar ¶
func StatusBar(text string) *headerBarView
StatusBar creates a full-width status bar (same as HeaderBar but defaults to bottom style).
func StyledButton ¶
func StyledButton(label string, callback func()) *styledButtonView
StyledButton creates a styled button with dimensions. Unlike Clickable, this draws a filled box with centered text.
Example:
StyledButton("Submit", func() { app.submit() }).Width(20).Height(3).Bg(ColorBlue)
func Table ¶
func Table(columns []TableColumn, selected *int) *tableView
Table creates a new table view with the given columns. selected should be a pointer to the currently selected row index.
The component handles keyboard navigation (arrow keys) and selection (Enter) automatically when focused. Use Tab to focus the table.
Example:
Table([]TableColumn{{Title: "Name"}, {Title: "Age"}}, &app.selected).
Rows([][]string{{"Alice", "30"}, {"Bob", "25"}})
func Text ¶
Text creates a text view with optional Printf-style formatting. This is the fundamental component for displaying text in TUI applications.
The text view supports:
- Styling methods (Fg, Bg, Bold, Italic, etc.)
- Semantic styling (Success, Error, Warning, Info, Muted, Hint)
- Animation effects (Rainbow, Pulse, Typewriter, Glitch, etc.)
Example:
Text("Hello, %s!", userName).Fg(ColorGreen).Bold()
Text("Error: %s", err).Error()
Text("Loading...").Pulse(tui.NewRGB(0, 255, 0), 10)
Example ¶
ExampleText demonstrates text rendering with styling.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
// Basic text
_ = tui.Text("Hello, World!")
// Text with formatting
name := "Alice"
_ = tui.Text("Hello, %s!", name)
// Text with styling
_ = tui.Text("Success").Fg(tui.ColorGreen).Bold()
// Semantic styling
_ = tui.Text("Error occurred").Error()
_ = tui.Text("Warning message").Warning()
_ = tui.Text("Helpful hint").Hint()
}
func TextArea ¶ added in v0.0.2
func TextArea(binding *string) *textAreaView
TextArea creates a scrollable text display component. It's focusable, supports keyboard scrolling, and has focus-aware border styling.
Example:
TextArea(&app.output).
ID("output-view").
Title("Output").
Bordered().
Size(60, 10)
func Toggle ¶
func Toggle(value *bool) *toggleView
Toggle creates an on/off toggle switch. value should be a pointer to a bool controlling the toggle state.
The component handles keyboard input (Space/Enter to toggle) automatically when focused. Use Tab to focus the toggle.
Example:
Toggle(&app.darkMode).OnChange(func(v bool) { app.updateTheme() })
func Tree ¶
func Tree(root *TreeNode) *treeView
Tree creates a tree view with the given root node.
The component handles keyboard navigation (arrow keys) and expand/collapse (Enter/Space) automatically when focused. Use Tab to focus the tree.
Example:
root := tui.NewTreeNode("Root").SetExpanded(true).AddChildren(
tui.NewTreeNode("Child 1"),
tui.NewTreeNode("Child 2").AddChildren(
tui.NewTreeNode("Grandchild"),
),
)
Tree(root).OnSelect(func(node *tui.TreeNode) {
fmt.Println("Selected:", node.Label)
})
func WrapText ¶
WrapText wraps the given text to fit within the specified width. It respects existing newlines and wraps on word boundaries where possible.
func ZStack ¶
func ZStack(children ...View) *zStack
ZStack creates a stack that layers children on top of each other (z-axis). The first child is at the bottom layer, the last child is on top.
This is useful for overlays, backgrounds, and layered effects. The stack sizes to the largest child.
Example:
ZStack(
// Background layer
Bordered(Empty()).Border(&SingleBorder),
// Foreground content
Padding(2, Text("Overlay")),
).Align(AlignCenter)
Types ¶
type AnimatedElement ¶
type AnimatedElement interface {
Update(frame uint64)
Draw(frame RenderFrame)
Position() (x, y int)
Dimensions() (width, height int)
}
AnimatedElement represents any element that can be animated
type AnimatedMultiLine ¶
type AnimatedMultiLine struct {
// contains filtered or unexported fields
}
AnimatedMultiLine represents multiple lines of animated content
func NewAnimatedMultiLine ¶
func NewAnimatedMultiLine(x, y, width int) *AnimatedMultiLine
NewAnimatedMultiLine creates a new multi-line animated element
func (*AnimatedMultiLine) AddLine ¶
func (aml *AnimatedMultiLine) AddLine(text string, animation TextAnimation)
AddLine adds a new line with animation
func (*AnimatedMultiLine) ClearLines ¶
func (aml *AnimatedMultiLine) ClearLines()
ClearLines removes all lines
func (*AnimatedMultiLine) Dimensions ¶
func (aml *AnimatedMultiLine) Dimensions() (width, height int)
Dimensions returns the element's dimensions
func (*AnimatedMultiLine) Draw ¶
func (aml *AnimatedMultiLine) Draw(frame RenderFrame)
Draw renders all animated lines
func (*AnimatedMultiLine) Position ¶
func (aml *AnimatedMultiLine) Position() (x, y int)
Position returns the element's position
func (*AnimatedMultiLine) SetLine ¶
func (aml *AnimatedMultiLine) SetLine(index int, text string, animation TextAnimation)
SetLine sets the content and animation for a specific line
func (*AnimatedMultiLine) SetPosition ¶
func (aml *AnimatedMultiLine) SetPosition(x, y int)
SetPosition updates the element's position
func (*AnimatedMultiLine) SetWidth ¶
func (aml *AnimatedMultiLine) SetWidth(width int)
SetWidth updates the element's width
func (*AnimatedMultiLine) Update ¶
func (aml *AnimatedMultiLine) Update(frame uint64)
Update updates the animation frame
type AnimatedStatusBar ¶
type AnimatedStatusBar struct {
// contains filtered or unexported fields
}
AnimatedStatusBar represents an animated status bar
func NewAnimatedStatusBar ¶
func NewAnimatedStatusBar(x, y, width int) *AnimatedStatusBar
NewAnimatedStatusBar creates a new animated status bar
func (*AnimatedStatusBar) AddItem ¶
func (asb *AnimatedStatusBar) AddItem(key, value, icon string, animation TextAnimation, style Style)
AddItem adds a status item with optional animation
func (*AnimatedStatusBar) Dimensions ¶
func (asb *AnimatedStatusBar) Dimensions() (width, height int)
Dimensions returns the status bar dimensions
func (*AnimatedStatusBar) Draw ¶
func (asb *AnimatedStatusBar) Draw(frame RenderFrame)
Draw renders the animated status bar
func (*AnimatedStatusBar) Position ¶
func (asb *AnimatedStatusBar) Position() (x, y int)
Position returns the status bar position
func (*AnimatedStatusBar) SetPosition ¶
func (asb *AnimatedStatusBar) SetPosition(x, y int)
SetPosition updates the status bar position
func (*AnimatedStatusBar) Update ¶
func (asb *AnimatedStatusBar) Update(frame uint64)
Update updates the animation frame
func (*AnimatedStatusBar) UpdateItem ¶
func (asb *AnimatedStatusBar) UpdateItem(index int, key, value string)
UpdateItem updates an existing status item
type AnimatedStatusItem ¶
type AnimatedStatusItem struct {
Key string
Value string
Icon string
Animation TextAnimation
Style Style
}
AnimatedStatusItem represents a single status item with animation
type AnimatedText ¶
type AnimatedText struct {
// contains filtered or unexported fields
}
AnimatedText represents text with color animation
func NewAnimatedText ¶
func NewAnimatedText(x, y int, text string, animation TextAnimation) *AnimatedText
NewAnimatedText creates a new animated text element
func (*AnimatedText) Dimensions ¶
func (at *AnimatedText) Dimensions() (width, height int)
Dimensions returns the element's dimensions
func (*AnimatedText) Draw ¶
func (at *AnimatedText) Draw(frame RenderFrame)
Draw renders the animated text
func (*AnimatedText) Position ¶
func (at *AnimatedText) Position() (x, y int)
Position returns the element's position
func (*AnimatedText) SetPosition ¶
func (at *AnimatedText) SetPosition(x, y int)
SetPosition updates the position
func (*AnimatedText) SetText ¶
func (at *AnimatedText) SetText(text string)
SetText updates the text content
func (*AnimatedText) Update ¶
func (at *AnimatedText) Update(frame uint64)
Update updates the animation frame
type Animation ¶ added in v0.0.2
type Animation struct {
// contains filtered or unexported fields
}
Animation represents a time-based animation with duration, easing, and looping.
func NewAnimation ¶ added in v0.0.2
NewAnimation creates a new animation with the given duration in frames.
func PresetAttention ¶ added in v0.0.2
PresetAttention creates an attention-grabbing animation.
func PresetBounce ¶ added in v0.0.2
PresetBounce creates a bouncing animation.
func PresetElastic ¶ added in v0.0.2
PresetElastic creates an elastic animation.
func PresetFadeIn ¶ added in v0.0.2
PresetFadeIn creates a fade-in animation.
func PresetFadeOut ¶ added in v0.0.2
PresetFadeOut creates a fade-out animation.
func PresetPulse ¶ added in v0.0.2
PresetPulse creates a pulsing animation.
func PresetSlideIn ¶ added in v0.0.2
PresetSlideIn creates a slide-in animation.
func (*Animation) IsRunning ¶ added in v0.0.2
IsRunning returns whether the animation is currently running.
func (*Animation) Lerp ¶ added in v0.0.2
Lerp performs linear interpolation between two values using the animation value.
func (*Animation) LerpRGB ¶ added in v0.0.2
LerpRGB performs linear interpolation between two RGB colors.
func (*Animation) Update ¶ added in v0.0.2
Update updates the animation value based on the current frame.
func (*Animation) WithEasing ¶ added in v0.0.2
WithEasing sets the easing function for the animation.
func (*Animation) WithPingPong ¶ added in v0.0.2
WithPingPong enables ping-pong looping (reverses direction on loop).
type AnimationBuilder ¶ added in v0.0.2
type AnimationBuilder struct {
// contains filtered or unexported fields
}
AnimationBuilder provides a fluent API for composing complex animations.
func NewAnimationBuilder ¶ added in v0.0.2
func NewAnimationBuilder() *AnimationBuilder
NewAnimationBuilder creates a new animation builder.
func (*AnimationBuilder) Add ¶ added in v0.0.2
func (ab *AnimationBuilder) Add(duration uint64, easing Easing) *AnimationBuilder
Add adds an animation to the builder.
func (*AnimationBuilder) AddAnimation ¶ added in v0.0.2
func (ab *AnimationBuilder) AddAnimation(anim *Animation) *AnimationBuilder
AddAnimation adds a pre-configured animation to the builder.
func (*AnimationBuilder) Build ¶ added in v0.0.2
func (ab *AnimationBuilder) Build() interface{}
Build constructs the final animation based on the mode.
func (*AnimationBuilder) Parallel ¶ added in v0.0.2
func (ab *AnimationBuilder) Parallel() *AnimationBuilder
Parallel sets the mode to parallel (animations play simultaneously).
func (*AnimationBuilder) Sequence ¶ added in v0.0.2
func (ab *AnimationBuilder) Sequence() *AnimationBuilder
Sequence sets the mode to sequence (animations play one after another).
func (*AnimationBuilder) Stagger ¶ added in v0.0.2
func (ab *AnimationBuilder) Stagger() *AnimationBuilder
Stagger sets the mode to staggered (each animation starts with a delay).
type AnimationController ¶ added in v0.0.2
type AnimationController struct {
// contains filtered or unexported fields
}
AnimationController coordinates multiple animations and provides timing control. It can be used to create synchronized animations across different views.
func NewAnimationController ¶ added in v0.0.2
func NewAnimationController() *AnimationController
NewAnimationController creates a new animation controller.
func (*AnimationController) Get ¶ added in v0.0.2
func (ac *AnimationController) Get(name string) *Animation
Get retrieves a registered animation by name.
func (*AnimationController) GlobalTime ¶ added in v0.0.2
func (ac *AnimationController) GlobalTime() uint64
GlobalTime returns the current global frame counter.
func (*AnimationController) Register ¶ added in v0.0.2
func (ac *AnimationController) Register(name string, anim *Animation)
Register adds an animation to the controller with a unique name.
func (*AnimationController) Update ¶ added in v0.0.2
func (ac *AnimationController) Update(frame uint64)
Update updates all managed animations.
type AnimationCoordinator ¶ added in v0.0.2
type AnimationCoordinator struct {
// contains filtered or unexported fields
}
AnimationCoordinator coordinates animations across multiple views.
func NewAnimationCoordinator ¶ added in v0.0.2
func NewAnimationCoordinator() *AnimationCoordinator
NewAnimationCoordinator creates a new animation coordinator.
func (*AnimationCoordinator) CurrentFrame ¶ added in v0.0.2
func (ac *AnimationCoordinator) CurrentFrame() uint64
CurrentFrame returns the current frame counter.
func (*AnimationCoordinator) GetEffect ¶ added in v0.0.2
func (ac *AnimationCoordinator) GetEffect(name string) *GlobalEffect
GetEffect retrieves a registered global effect.
func (*AnimationCoordinator) GetSubscribers ¶ added in v0.0.2
func (ac *AnimationCoordinator) GetSubscribers(effectName string) []AnimationSubscriber
GetSubscribers returns all subscribers for a given effect.
func (*AnimationCoordinator) RegisterEffect ¶ added in v0.0.2
func (ac *AnimationCoordinator) RegisterEffect(name string, effect *GlobalEffect)
RegisterEffect registers a global effect with a unique name.
func (*AnimationCoordinator) Subscribe ¶ added in v0.0.2
func (ac *AnimationCoordinator) Subscribe(effectName string, subscriber AnimationSubscriber)
Subscribe allows a view to subscribe to a global effect.
func (*AnimationCoordinator) Unsubscribe ¶ added in v0.0.2
func (ac *AnimationCoordinator) Unsubscribe(effectName string, subscriber AnimationSubscriber)
Unsubscribe removes a subscriber from a global effect.
func (*AnimationCoordinator) Update ¶ added in v0.0.2
func (ac *AnimationCoordinator) Update(frame uint64)
Update updates all global effects and notifies subscribers.
type AnimationGroup ¶ added in v0.0.2
type AnimationGroup struct {
// contains filtered or unexported fields
}
AnimationGroup represents multiple animations that play simultaneously.
func NewAnimationGroup ¶ added in v0.0.2
func NewAnimationGroup(animations ...*Animation) *AnimationGroup
NewAnimationGroup creates a new animation group.
func (*AnimationGroup) CombineAverage ¶ added in v0.0.2
func (ag *AnimationGroup) CombineAverage() *AnimationGroup
CombineAverage averages all animation values.
func (*AnimationGroup) CombineMax ¶ added in v0.0.2
func (ag *AnimationGroup) CombineMax() *AnimationGroup
CombineMax takes the maximum of all animation values.
func (*AnimationGroup) CombineMin ¶ added in v0.0.2
func (ag *AnimationGroup) CombineMin() *AnimationGroup
CombineMin takes the minimum of all animation values.
func (*AnimationGroup) Start ¶ added in v0.0.2
func (ag *AnimationGroup) Start(frame uint64)
Start starts all animations in the group.
func (*AnimationGroup) Update ¶ added in v0.0.2
func (ag *AnimationGroup) Update(frame uint64)
Update updates all animations in the group.
func (*AnimationGroup) Value ¶ added in v0.0.2
func (ag *AnimationGroup) Value() float64
Value returns the combined value from all animations.
func (*AnimationGroup) WithCombiner ¶ added in v0.0.2
func (ag *AnimationGroup) WithCombiner(combiner func(values []float64) float64) *AnimationGroup
WithCombiner sets how to combine values from multiple animations.
type AnimationMode ¶ added in v0.0.2
type AnimationMode int
AnimationMode determines how multiple animations are combined.
const ( AnimationModeSequence AnimationMode = iota // Play one after another AnimationModeParallel // Play simultaneously AnimationModeStagger // Start each with a delay )
type AnimationSequence ¶ added in v0.0.2
type AnimationSequence struct {
// contains filtered or unexported fields
}
AnimationSequence represents a sequence of animations that play one after another.
func NewAnimationSequence ¶ added in v0.0.2
func NewAnimationSequence(animations ...*Animation) *AnimationSequence
NewAnimationSequence creates a new animation sequence.
func (*AnimationSequence) IsComplete ¶ added in v0.0.2
func (as *AnimationSequence) IsComplete() bool
IsComplete returns whether all animations in the sequence have finished.
func (*AnimationSequence) Reset ¶ added in v0.0.2
func (as *AnimationSequence) Reset()
Reset resets the sequence to the beginning.
func (*AnimationSequence) Update ¶ added in v0.0.2
func (as *AnimationSequence) Update(frame uint64)
Update updates the current animation in the sequence.
func (*AnimationSequence) Value ¶ added in v0.0.2
func (as *AnimationSequence) Value() float64
Value returns the current animation value.
type AnimationStep ¶ added in v0.0.2
type AnimationStep struct {
// contains filtered or unexported fields
}
AnimationStep represents one step in a chained animation.
type AnimationSubscriber ¶ added in v0.0.2
AnimationSubscriber represents a view that can subscribe to global effects.
type Application ¶
type Application interface {
// View returns the declarative view tree representing the current UI.
// This is called automatically after each event is processed.
View() View
}
Application is the main interface for declarative UI applications. Implementations provide a View that describes the current UI state.
The View method is called after every event to render the UI. The framework efficiently diffs the view tree and only updates changed terminal regions.
Thread Safety: View and HandleEvent (if implemented) are NEVER called concurrently. The Runtime ensures these methods run sequentially in a single goroutine, eliminating the need for locks in application code.
Example:
type CounterApp struct {
count int
}
func (a *CounterApp) View() tui.View {
return tui.Stack(
tui.Text("Count: %d", a.count),
tui.Button("Increment", func() { a.count++ }),
)
}
Example ¶
ExampleApplication demonstrates the basic Application interface for building declarative TUI applications.
package main
import ()
func main() {
type CounterApp struct{}
// View returns the UI tree based on current state
// func (app *CounterApp) View() tui.View {
// return tui.Stack(
// tui.Text("Count: %d", app.count),
// tui.Button("Increment", func() { app.count++ }),
// )
// }
app := &CounterApp{}
_ = app
// Run the application
// tui.Run(app)
}
type AutocompleteFunc ¶ added in v0.0.19
AutocompleteFunc is called when the user presses Tab to get completion suggestions. It receives the current input and cursor position, and returns a list of completions and the index in the input string where replacement should start from.
Example for file completion:
func(input string, cursorPos int) ([]string, int) {
// Find @ before cursor
atIdx := strings.LastIndex(input[:cursorPos], "@")
if atIdx == -1 {
return nil, 0
}
prefix := input[atIdx+1 : cursorPos]
matches := findFiles(prefix)
return matches, atIdx
}
type BaseWidget ¶
type BaseWidget struct {
// contains filtered or unexported fields
}
BaseWidget provides a default implementation of ComposableWidget that other widgets can embed to get composition support. This handles the boilerplate of bounds management, parent tracking, and visibility.
func NewBaseWidget ¶
func NewBaseWidget() BaseWidget
NewBaseWidget creates a new BaseWidget with sensible defaults
func (*BaseWidget) Destroy ¶
func (bw *BaseWidget) Destroy()
Destroy cleans up the widget (default: no-op)
func (*BaseWidget) GetBounds ¶
func (bw *BaseWidget) GetBounds() image.Rectangle
GetBounds returns the widget's current bounds
func (*BaseWidget) GetLayoutParams ¶
func (bw *BaseWidget) GetLayoutParams() LayoutParams
GetLayoutParams returns the layout parameters
func (*BaseWidget) GetMinSize ¶
func (bw *BaseWidget) GetMinSize() image.Point
GetMinSize returns the minimum size (can be overridden)
func (*BaseWidget) GetParent ¶
func (bw *BaseWidget) GetParent() ComposableWidget
GetParent returns the parent widget
func (*BaseWidget) GetPreferredSize ¶
func (bw *BaseWidget) GetPreferredSize() image.Point
GetPreferredSize returns the preferred size (can be overridden)
func (*BaseWidget) IsVisible ¶
func (bw *BaseWidget) IsVisible() bool
IsVisible returns whether the widget is visible
func (*BaseWidget) MarkDirty ¶
func (bw *BaseWidget) MarkDirty()
MarkDirty marks the widget as needing redraw
func (*BaseWidget) NeedsRedraw ¶
func (bw *BaseWidget) NeedsRedraw() bool
NeedsRedraw returns whether the widget needs to be redrawn
func (*BaseWidget) SetBounds ¶
func (bw *BaseWidget) SetBounds(bounds image.Rectangle)
SetBounds sets the widget's position and size
func (*BaseWidget) SetLayoutParams ¶
func (bw *BaseWidget) SetLayoutParams(params LayoutParams)
SetLayoutParams sets the layout parameters
func (*BaseWidget) SetMinSize ¶
func (bw *BaseWidget) SetMinSize(size image.Point)
SetMinSize sets the minimum size
func (*BaseWidget) SetParent ¶
func (bw *BaseWidget) SetParent(parent ComposableWidget)
SetParent sets the parent widget
func (*BaseWidget) SetPreferredSize ¶
func (bw *BaseWidget) SetPreferredSize(size image.Point)
SetPreferredSize sets the preferred size
func (*BaseWidget) SetVisible ¶
func (bw *BaseWidget) SetVisible(visible bool)
SetVisible sets the widget's visibility
type BatchEvent ¶
BatchEvent contains multiple events that should be processed together. The runtime will unpack this and process each event individually in order.
This is typically returned by Sequence() to group related command results.
func (BatchEvent) Timestamp ¶
func (e BatchEvent) Timestamp() time.Time
type BorderAnimation ¶ added in v0.0.2
type BorderAnimation interface {
GetBorderStyle(frame uint64, borderPart BorderPart, position int, length int) Style
}
BorderAnimation defines how a border should be animated.
func PresetFireBorder ¶ added in v0.0.2
func PresetFireBorder(speed int) BorderAnimation
PresetFireBorder creates a fire border animation preset.
func PresetMarqueeBorder ¶ added in v0.0.2
func PresetMarqueeBorder(onColor, offColor RGB, speed, segmentLength int) BorderAnimation
PresetMarqueeBorder creates a marquee border animation preset.
func PresetPulsingBorder ¶ added in v0.0.2
func PresetPulsingBorder(color RGB, speed int) BorderAnimation
PresetPulsingBorder creates a pulsing border animation preset.
func PresetRainbowBorder ¶ added in v0.0.2
func PresetRainbowBorder(speed int, reversed bool) BorderAnimation
PresetRainbowBorder creates a rainbow border animation preset.
type BorderPart ¶ added in v0.0.2
type BorderPart int
BorderPart identifies which part of the border is being rendered.
const ( BorderPartTop BorderPart = iota BorderPartRight BorderPartBottom BorderPartLeft BorderPartTopLeft BorderPartTopRight BorderPartBottomLeft BorderPartBottomRight )
type BorderStyle ¶
type BorderStyle = terminal.BorderStyle
BorderStyle defines the characters used for drawing borders
type CaseView ¶
type CaseView[T comparable] struct { // contains filtered or unexported fields }
CaseView represents a case in a Switch statement.
func Case ¶
func Case[T comparable](value T, view View) CaseView[T]
Case creates a case for use with Switch.
func Default ¶
func Default[T comparable](view View) CaseView[T]
Default creates a default case for use with Switch.
type ChainedAnimation ¶ added in v0.0.2
type ChainedAnimation struct {
// contains filtered or unexported fields
}
ChainedAnimation allows chaining different animation types together.
func NewChainedAnimation ¶ added in v0.0.2
func NewChainedAnimation() *ChainedAnimation
NewChainedAnimation creates a new chained animation.
func (*ChainedAnimation) AddBorderAnimation ¶ added in v0.0.2
func (ca *ChainedAnimation) AddBorderAnimation(anim BorderAnimation, duration uint64) *ChainedAnimation
AddBorderAnimation adds a border animation step.
func (*ChainedAnimation) AddTextAnimation ¶ added in v0.0.2
func (ca *ChainedAnimation) AddTextAnimation(anim TextAnimation, duration uint64) *ChainedAnimation
AddTextAnimation adds a text animation step.
func (*ChainedAnimation) AddTransform ¶ added in v0.0.2
func (ca *ChainedAnimation) AddTransform(transform func(View) View, duration uint64) *ChainedAnimation
AddTransform adds a view transformation step.
func (*ChainedAnimation) GetCurrentStep ¶ added in v0.0.2
func (ca *ChainedAnimation) GetCurrentStep(frame uint64) *AnimationStep
GetCurrentStep returns the current animation step based on frame.
type Cmd ¶
type Cmd func() Event
Cmd is a function that performs async work and returns an event. Commands are executed in separate goroutines by the Runtime, and their results are sent back to the event loop as events.
This pattern enables non-blocking async operations (HTTP requests, timers, file I/O) while maintaining the single-threaded event loop guarantee for application state.
Example:
func fetchData() Cmd {
return func() Event {
data, err := http.Get("https://api.example.com/data")
if err != nil {
return ErrorEvent{Err: err, Cause: "fetch"}
}
return DataReceivedEvent{Data: data}
}
}
func (a *App) HandleEvent(event Event) []Cmd {
if _, ok := event.(KeyEvent); ok {
return []Cmd{fetchData()}
}
return nil
}
Example ¶
ExampleCmd demonstrates async command execution.
package main
import ()
func main() {
// type DataEvent struct {
// Time time.Time
// Data string
// }
// Custom event type needs Timestamp method
// func (e DataEvent) Timestamp() time.Time { return e.Time }
// Command that performs async work
// fetchData := func() tui.Cmd {
// return func() tui.Event {
// // Simulate async operation
// data := "fetched data"
// return DataEvent{Time: time.Now(), Data: data}
// }
// }
}
func After ¶
After returns a command that waits for the specified duration, executes the provided function, and returns a TickEvent. If fn is nil, it simply waits and returns a TickEvent.
func Batch ¶
Batch combines multiple commands into a single list. This is a convenience function for returning multiple commands from HandleEvent.
Example:
return Batch(
fetchUserData(),
fetchSettings(),
startTimer(),
)
Example ¶
ExampleBatch demonstrates running multiple commands.
package main
import (
"fmt"
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
cmd1 := func() tui.Cmd {
return func() tui.Event {
return tui.TickEvent{}
}
}
cmd2 := func() tui.Cmd {
return func() tui.Event {
return tui.TickEvent{}
}
}
// Run multiple commands in parallel
cmds := tui.Batch(
cmd1(),
cmd2(),
)
fmt.Printf("Queued %d commands", len(cmds))
}
Output: Queued 2 commands
func Focus ¶
Focus returns a command that sets focus to the specified element ID. The command produces a FocusSetEvent that the Runtime or InlineApp processes to update the focus state.
Use this in HandleEvent to programmatically focus an element:
func (app *App) HandleEvent(e Event) []Cmd {
if key, ok := e.(KeyEvent); ok && key.Rune == 'n' {
return []Cmd{Focus("name-input")}
}
return nil
}
The element ID must match the ID used when creating the focusable component (e.g., Input("id"), Button("id", ...), etc.).
func FocusNext ¶
func FocusNext() Cmd
FocusNext returns a command that moves focus to the next element in Tab order. The command produces a FocusNextEvent that the Runtime or InlineApp processes. This is equivalent to pressing Tab.
func FocusPrev ¶ added in v0.0.2
func FocusPrev() Cmd
FocusPrev returns a command that moves focus to the previous element in Tab order. The command produces a FocusPrevEvent that the Runtime or InlineApp processes. This is equivalent to pressing Shift+Tab.
func None ¶
func None() []Cmd
None returns an empty command list. This is a convenience function for when HandleEvent needs to return an empty slice explicitly (useful for readability).
func Quit ¶
func Quit() Cmd
Quit returns a command that triggers application shutdown. The application will clean up and exit gracefully.
Example:
func (a *App) HandleEvent(event Event) []Cmd {
if key, ok := event.(KeyEvent); ok && key.Rune == 'q' {
return []Cmd{Quit()}
}
return nil
}
func Sequence ¶
Sequence returns a command that executes multiple commands in order, collecting their results into a BatchEvent.
Unlike Batch (which runs commands in parallel), Sequence runs them sequentially in a single goroutine. Use this when commands depend on each other or when parallel execution would cause issues.
Example:
return []Cmd{Sequence(
authenticate(),
fetchData(),
processResults(),
)}
type ComposableWidget ¶
type ComposableWidget interface {
Widget // Embed basic Widget interface (Draw, HandleKey)
// Lifecycle methods
Init() // Called when widget is first created or added to parent
Destroy() // Called when widget is removed or screen is closing
// Bounds management - enables relative positioning within containers
SetBounds(bounds image.Rectangle) // Parent/container sets the widget's position and size
GetBounds() image.Rectangle // Returns current bounds
GetMinSize() image.Point // Returns minimum size needed to render properly
GetPreferredSize() image.Point // Returns preferred size (may be larger than minimum)
// Parent-child tree structure for event propagation
GetParent() ComposableWidget // Returns parent widget (nil for root)
SetParent(ComposableWidget) // Sets parent widget
// Visibility and layout participation
IsVisible() bool // Whether widget should be rendered and included in layout
SetVisible(bool) // Show/hide the widget
NeedsRedraw() bool // Whether widget needs to be redrawn
MarkDirty() // Mark widget as needing redraw
ClearDirty() // Clear dirty flag after redraw
}
ComposableWidget extends the basic Widget interface with composition capabilities. This interface enables bounds-based positioning, parent-child relationships, and lifecycle management necessary for complex, nested layouts.
Components implementing this interface can be nested inside containers and will have their bounds managed by layout managers instead of using absolute positioning.
type ConstraintLayoutManager ¶
type ConstraintLayoutManager interface {
LayoutManager // Embed legacy interface for compatibility
// Measure calculates the size of the container given the constraints.
// It should also measure children recursively.
Measure(children []ComposableWidget, constraints SizeConstraints) image.Point
// LayoutWithConstraints positions children.
// It is similar to Layout but provides the constraints used during measurement.
LayoutWithConstraints(children []ComposableWidget, constraints SizeConstraints, containerBounds image.Rectangle)
}
ConstraintLayoutManager is an enhanced LayoutManager that supports constraint-based layout.
type CornerHighlightAnimation ¶ added in v0.0.2
type CornerHighlightAnimation struct {
Speed int
BaseColor RGB
HighlightColor RGB
Duration int // How long each corner stays highlighted (in frames)
}
CornerHighlightAnimation highlights corners in sequence.
func (*CornerHighlightAnimation) GetBorderStyle ¶ added in v0.0.2
func (c *CornerHighlightAnimation) GetBorderStyle(frame uint64, part BorderPart, position int, length int) Style
GetBorderStyle returns the style for a border position at a given frame.
type CursorConfig ¶ added in v0.0.22
type CursorConfig struct {
Output io.Writer // nil = os.Stdout. Specify where to write cursor commands.
}
CursorConfig configures cursor control functions. The zero value is acceptable and will use sensible defaults (os.Stdout for output).
type DebugInfo ¶
type DebugInfo struct {
// FPS is the current frames per second.
FPS float64
// FrameTime is the time taken for the last frame.
FrameTime time.Duration
// FrameCount is the total number of frames rendered.
FrameCount uint64
// TerminalSize is the current terminal dimensions.
TerminalSize image.Point
// LastEvent is a description of the most recent event.
LastEvent string
// LastEventTime is when the last event occurred.
LastEventTime time.Time
// EventCount is the total number of events processed.
EventCount uint64
// Custom allows applications to add custom debug values.
Custom map[string]string
}
DebugInfo holds runtime debug information.
func (*DebugInfo) SetFrameTime ¶
SetFrameTime sets the frame time.
type DebugPosition ¶
type DebugPosition int
DebugPosition specifies where the debug overlay appears.
const ( DebugTopLeft DebugPosition = iota DebugTopRight DebugBottomLeft DebugBottomRight )
type DebugWrapper ¶
type DebugWrapper struct {
Info *DebugInfo
// contains filtered or unexported fields
}
DebugWrapper wraps an Application to automatically track debug info.
func WrapWithDebug ¶
func WrapWithDebug(app Application) *DebugWrapper
WrapWithDebug wraps an application to automatically collect debug info.
Example:
wrapper := tui.WrapWithDebug(&MyApp{})
// Use wrapper.Info in your View to display debug overlay
tui.Run(wrapper)
func (*DebugWrapper) Enable ¶
func (w *DebugWrapper) Enable(enabled bool)
Enable enables or disables debug tracking.
func (*DebugWrapper) HandleEvent ¶
func (w *DebugWrapper) HandleEvent(event Event) []Cmd
HandleEvent implements EventHandler.
type Destroyable ¶
type Destroyable interface {
Destroy()
}
Destroyable is an optional interface that applications can implement to perform cleanup when the runtime stops.
type Diff ¶
type Diff struct {
Files []DiffFile
}
Diff represents a complete diff (may contain multiple files)
func ParseUnifiedDiff ¶
ParseUnifiedDiff parses a unified diff format string into a Diff structure
type DiffFile ¶
type DiffFile struct {
OldPath string // Path to old file (before change)
NewPath string // Path to new file (after change)
Hunks []DiffHunk
}
DiffFile represents changes to a single file
type DiffHunk ¶
type DiffHunk struct {
OldStart int // Starting line in old file
OldCount int // Number of lines in old file
NewStart int // Starting line in new file
NewCount int // Number of lines in new file
Header string // The @@ line content
Lines []DiffLine
}
DiffHunk represents a contiguous block of changes
type DiffLine ¶
type DiffLine struct {
Type DiffLineType
OldLineNum int // Line number in old file (0 if added)
NewLineNum int // Line number in new file (0 if removed)
Content string // Line content without the leading +/- marker
RawLine string // Original line including marker
}
DiffLine represents a single line in a diff
type DiffLineType ¶
DiffLineType represents the type of a diff line
type DiffRenderer ¶
type DiffRenderer struct {
Theme DiffTheme
ShowLineNums bool
SyntaxHighlight bool
LineNumWidth int // Width reserved for line numbers
TabWidth int // Number of spaces to expand tabs to (default 4)
}
DiffRenderer renders diff content with syntax highlighting
func NewDiffRenderer ¶
func NewDiffRenderer() *DiffRenderer
NewDiffRenderer creates a new diff renderer with default settings
func (*DiffRenderer) RenderDiff ¶
func (dr *DiffRenderer) RenderDiff(diff *Diff, language string) []RenderedDiffLine
RenderDiff renders a diff to styled output
func (*DiffRenderer) WithTheme ¶
func (dr *DiffRenderer) WithTheme(theme DiffTheme) *DiffRenderer
WithTheme sets a custom theme
type DiffTheme ¶
type DiffTheme struct {
AddedBg RGB // Background for added lines
AddedFg RGB // Foreground for added lines
RemovedBg RGB // Background for removed lines
RemovedFg RGB // Foreground for removed lines
ContextStyle Style // Style for context lines
HeaderStyle Style // Style for file headers
HunkStyle Style // Style for hunk headers
LineNumStyle Style // Style for line numbers
SyntaxTheme string // Chroma theme for syntax highlighting
}
DiffTheme defines colors and styles for diff rendering
func DefaultDiffTheme ¶
func DefaultDiffTheme() DiffTheme
DefaultDiffTheme returns a default diff theme
type DirtyRegion ¶
type DirtyRegion = terminal.DirtyRegion
DirtyRegion tracks the rectangular area that has been modified
type Easing ¶ added in v0.0.2
Easing represents an easing function that maps input [0,1] to output [0,1]. Easing functions control the rate of change over time for animations.
func EaseChain ¶ added in v0.0.2
EaseChain chains multiple easing functions sequentially. Each function is applied to an equal portion of the total time.
func EaseMirror ¶ added in v0.0.2
EaseMirror creates a mirrored easing (goes up then down).
func EaseReverse ¶ added in v0.0.2
EaseReverse reverses an easing function (mirrors it).
type ErrorEvent ¶
type ErrorEvent struct {
Time time.Time
Err error
Cause string // Optional description of what caused the error
}
ErrorEvent represents an error that occurred during async command execution. Applications should handle these events to display errors to users.
Example:
func (a *App) HandleEvent(event Event) []Cmd {
if err, ok := event.(ErrorEvent); ok {
a.errorMsg = err.Error()
}
return nil
}
func (ErrorEvent) Error ¶
func (e ErrorEvent) Error() string
func (ErrorEvent) Timestamp ¶
func (e ErrorEvent) Timestamp() time.Time
type Event ¶
Event represents any event that can occur in the application. All events must provide a timestamp indicating when they occurred.
The Runtime processes events sequentially in a single-threaded loop, calling HandleEvent (if implemented) and then View() to render updates.
Built-in event types include:
- KeyEvent: Keyboard input
- MouseEvent: Mouse clicks, movement, scrolling
- TickEvent: Periodic timer for animations
- ResizeEvent: Terminal size changed
- QuitEvent: Application shutdown request
- ErrorEvent: Error from async command
- BatchEvent: Multiple events to process together
Applications can define custom event types for command results:
type DataReceivedEvent struct {
Time time.Time
Data []byte
}
func (e DataReceivedEvent) Timestamp() time.Time { return e.Time }
type EventHandler ¶
type EventHandler interface {
// HandleEvent processes an event and optionally returns commands for async execution.
// This is called in a single-threaded event loop, so state can be mutated freely
// without locks. Return commands for async operations (HTTP requests, timers, etc.).
HandleEvent(event Event) []Cmd
}
EventHandler is an optional interface that applications can implement to handle events and trigger async operations.
Applications implementing both Application and EventHandler get full control: HandleEvent processes the event (potentially mutating state and returning commands), then View is called to render the updated UI.
Example:
func (a *App) HandleEvent(event Event) []Cmd {
switch e := event.(type) {
case KeyEvent:
if e.Rune == 'q' {
return []Cmd{Quit()}
}
if e.Rune == 'r' {
a.loading = true
return []Cmd{a.fetchData()}
}
case DataEvent:
a.data = e.Data
a.loading = false
}
return nil
}
type FireBorderAnimation ¶ added in v0.0.2
type FireBorderAnimation struct {
Speed int
CoolColors []RGB // Cooler fire colors (base)
HotColors []RGB // Hotter fire colors (peaks)
}
FireBorderAnimation creates a flickering fire effect around the border.
func (*FireBorderAnimation) GetBorderStyle ¶ added in v0.0.2
func (f *FireBorderAnimation) GetBorderStyle(frame uint64, part BorderPart, position int, length int) Style
GetBorderStyle returns the style for a border position at a given frame.
type FlexAlignItems ¶
type FlexAlignItems int
FlexAlignItems specifies how items are aligned along cross axis
const ( FlexAlignItemsStart FlexAlignItems = iota // Items aligned to start of cross axis FlexAlignItemsEnd // Items aligned to end of cross axis FlexAlignItemsCenter // Items centered on cross axis FlexAlignItemsStretch // Items stretched to fill cross axis )
type FlexDirection ¶
type FlexDirection int
FlexDirection specifies the direction in which flex items are placed
const ( FlexRow FlexDirection = iota // Horizontal, left to right FlexColumn // Vertical, top to bottom )
type FlexJustify ¶
type FlexJustify int
FlexJustify specifies how items are distributed along main axis
const ( FlexJustifyStart FlexJustify = iota // Items packed to start FlexJustifyEnd // Items packed to end FlexJustifyCenter // Items centered FlexJustifySpaceBetween // Even spacing between items FlexJustifySpaceAround // Even spacing around items FlexJustifySpaceEvenly // Equal spacing between and around items )
type FlexLayout ¶
type FlexLayout struct {
// contains filtered or unexported fields
}
FlexLayout implements a flexbox-style layout manager with support for flexible sizing, wrapping, and sophisticated alignment options.
This provides capabilities similar to CSS Flexbox: - Flexible item sizing with grow/shrink factors - Multiple justification options (start, end, center, space-between, etc.) - Cross-axis alignment - Support for row and column directions - Optional wrapping
func NewFlexLayout ¶
func NewFlexLayout() *FlexLayout
NewFlexLayout creates a new flex layout with default settings
func (*FlexLayout) CalculateMinSize ¶
func (fl *FlexLayout) CalculateMinSize(children []ComposableWidget) image.Point
CalculateMinSize returns minimum size needed for flex layout
func (*FlexLayout) CalculatePreferredSize ¶
func (fl *FlexLayout) CalculatePreferredSize(children []ComposableWidget) image.Point
CalculatePreferredSize returns preferred size for flex layout
func (*FlexLayout) Layout ¶
func (fl *FlexLayout) Layout(containerBounds image.Rectangle, children []ComposableWidget)
Layout positions children using flexbox algorithm
func (*FlexLayout) WithAlignItems ¶
func (fl *FlexLayout) WithAlignItems(alignItems FlexAlignItems) *FlexLayout
WithAlignItems sets the cross axis alignment
func (*FlexLayout) WithDirection ¶
func (fl *FlexLayout) WithDirection(direction FlexDirection) *FlexLayout
WithDirection sets the flex direction
func (*FlexLayout) WithJustify ¶
func (fl *FlexLayout) WithJustify(justify FlexJustify) *FlexLayout
WithJustify sets the main axis justification
func (*FlexLayout) WithLineSpacing ¶
func (fl *FlexLayout) WithLineSpacing(lineSpacing int) *FlexLayout
WithLineSpacing sets the spacing between wrapped lines
func (*FlexLayout) WithSpacing ¶
func (fl *FlexLayout) WithSpacing(spacing int) *FlexLayout
WithSpacing sets the spacing between items
func (*FlexLayout) WithWrap ¶
func (fl *FlexLayout) WithWrap(wrap FlexWrap) *FlexLayout
WithWrap sets the flex wrap behavior
type Flexible ¶
type Flexible interface {
// contains filtered or unexported methods
}
Flexible is implemented by views that can expand to fill available space. Views implementing Flexible will share remaining space proportionally based on their flex factor.
type FocusHandler ¶ added in v0.0.2
type FocusHandler struct {
// ID is the unique identifier for this focusable element.
ID string
// OnKey is called when a key event occurs while this element is focused.
// Return true to consume the event.
OnKey func(event KeyEvent) bool
}
FocusHandler defines callbacks for custom focusable behavior.
type FocusManager ¶ added in v0.0.2
type FocusManager struct {
// contains filtered or unexported fields
}
FocusManager manages focus state for all focusable elements. It handles Tab/Shift+Tab navigation and routes keyboard events.
Each Runtime or InlineApp instance has its own FocusManager, avoiding global state and allowing multiple independent TUI applications.
func NewFocusManager ¶ added in v0.0.22
func NewFocusManager() *FocusManager
NewFocusManager creates a new focus manager instance.
func (*FocusManager) Clear ¶ added in v0.0.2
func (fm *FocusManager) Clear()
Clear clears all registered focusables (called before each render).
func (*FocusManager) FocusNext ¶ added in v0.0.2
func (fm *FocusManager) FocusNext()
FocusNext moves focus to the next element in registration order.
func (*FocusManager) FocusPrev ¶ added in v0.0.2
func (fm *FocusManager) FocusPrev()
FocusPrev moves focus to the previous element in registration order.
func (*FocusManager) GetFocused ¶ added in v0.0.2
func (fm *FocusManager) GetFocused() Focusable
GetFocused returns the currently focused element, or nil if none.
func (*FocusManager) GetFocusedID ¶ added in v0.0.2
func (fm *FocusManager) GetFocusedID() string
GetFocusedID returns the ID of the currently focused element.
func (*FocusManager) HandleClick ¶ added in v0.0.2
func (fm *FocusManager) HandleClick(x, y int) bool
HandleClick checks if a click hit any focusable element and focuses it. Returns true if a focusable was clicked.
func (*FocusManager) HandleKey ¶ added in v0.0.2
func (fm *FocusManager) HandleKey(event KeyEvent) bool
HandleKey routes a key event to the focused element. Returns true if the event was handled.
func (*FocusManager) Register ¶ added in v0.0.2
func (fm *FocusManager) Register(f Focusable)
Register adds a focusable element to the manager. Elements are registered in render order, which determines Tab navigation order.
func (*FocusManager) SetFocus ¶ added in v0.0.2
func (fm *FocusManager) SetFocus(id string)
SetFocus sets focus to a specific element by ID.
type FocusNextEvent ¶ added in v0.0.22
FocusNextEvent is produced by the FocusNext command and processed by the Runtime or InlineApp to move focus to the next element in Tab order.
func (FocusNextEvent) Timestamp ¶ added in v0.0.22
func (e FocusNextEvent) Timestamp() time.Time
Timestamp implements Event.
type FocusPrevEvent ¶ added in v0.0.22
FocusPrevEvent is produced by the FocusPrev command and processed by the Runtime or InlineApp to move focus to the previous element in Tab order.
func (FocusPrevEvent) Timestamp ¶ added in v0.0.22
func (e FocusPrevEvent) Timestamp() time.Time
Timestamp implements Event.
type FocusSetEvent ¶ added in v0.0.22
type FocusSetEvent struct {
ID string // The ID of the element to focus
Time time.Time // When the event was created
}
FocusSetEvent is produced by the Focus command and processed by the Runtime or InlineApp to set focus to a specific element. This event flows through the command/event system rather than directly manipulating focus state, allowing proper integration with the event loop.
func (FocusSetEvent) Timestamp ¶ added in v0.0.22
func (e FocusSetEvent) Timestamp() time.Time
Timestamp implements Event.
type Focusable ¶
type Focusable interface {
// FocusID returns a unique identifier for this focusable element.
// This ID is used for programmatic focus control via Focus(id).
FocusID() string
// IsFocused returns whether this element currently has focus.
IsFocused() bool
// SetFocused is called when focus changes to or from this element.
SetFocused(focused bool)
// HandleKeyEvent processes a key event while this element has focus.
// Returns true if the event was consumed and should not propagate.
HandleKeyEvent(event KeyEvent) bool
// FocusBounds returns the screen bounds of this focusable element.
// Used for mouse click focus detection.
FocusBounds() image.Rectangle
}
Focusable is implemented by views that can receive keyboard focus. Views implementing this interface participate in Tab navigation and can handle keyboard events when focused.
type Footer ¶
type Footer struct {
}
Footer represents the bottom section of the terminal
func SimpleFooter ¶
SimpleFooter creates a simple footer
func StatusBarFooter ¶
func StatusBarFooter(items []StatusItem) *Footer
StatusBarFooter creates a status bar footer
type GlitchAnimation ¶ added in v0.0.2
type GlitchAnimation struct {
Speed int // Base speed for glitch timing
BaseColor RGB
GlitchColor RGB // Color during glitch
Intensity int // How often glitches occur (1-10, higher = more glitches)
}
GlitchAnimation creates a cyberpunk-style digital glitch effect
func Glitch ¶ added in v0.0.7
func Glitch(speed int, baseColor, glitchColor RGB) *GlitchAnimation
Glitch creates a new glitch animation with a cyberpunk-style digital effect. Speed controls glitch timing (lower = faster).
Example:
Text("SYSTEM ERROR").Animate(Glitch(2, gray, red))
Text("SYSTEM ERROR").Animate(Glitch(2, gray, red).WithIntensity(8))
func (*GlitchAnimation) GetStyle ¶ added in v0.0.2
func (g *GlitchAnimation) GetStyle(frame uint64, charIndex int, totalChars int) Style
GetStyle returns the style for a character at a given frame
func (*GlitchAnimation) WithIntensity ¶ added in v0.0.7
func (g *GlitchAnimation) WithIntensity(intensity int) *GlitchAnimation
WithIntensity sets how often glitches occur (1-10, higher = more glitches).
type GlobalEffect ¶ added in v0.0.2
type GlobalEffect struct {
// contains filtered or unexported fields
}
GlobalEffect represents a global animation effect that views can subscribe to.
func NewGlobalEffect ¶ added in v0.0.2
func NewGlobalEffect(effectType GlobalEffectType, duration uint64) *GlobalEffect
NewGlobalEffect creates a new global effect.
func (*GlobalEffect) ColorValue ¶ added in v0.0.2
func (ge *GlobalEffect) ColorValue() RGB
ColorValue returns the current color value (for color effects).
func (*GlobalEffect) Start ¶ added in v0.0.2
func (ge *GlobalEffect) Start(frame uint64)
Start starts the global effect.
func (*GlobalEffect) Type ¶ added in v0.0.2
func (ge *GlobalEffect) Type() GlobalEffectType
Type returns the effect type.
func (*GlobalEffect) Update ¶ added in v0.0.2
func (ge *GlobalEffect) Update(frame uint64)
Update updates the global effect.
func (*GlobalEffect) Value ¶ added in v0.0.2
func (ge *GlobalEffect) Value() float64
Value returns the current effect value.
func (*GlobalEffect) WithColorValue ¶ added in v0.0.2
func (ge *GlobalEffect) WithColorValue(color RGB) *GlobalEffect
WithColorValue sets a color value for color-based effects.
func (*GlobalEffect) WithEasing ¶ added in v0.0.2
func (ge *GlobalEffect) WithEasing(easing Easing) *GlobalEffect
WithEasing sets the easing function for the effect.
func (*GlobalEffect) WithWaveParams ¶ added in v0.0.2
func (ge *GlobalEffect) WithWaveParams(amplitude, frequency float64) *GlobalEffect
WithWaveParams sets wave parameters for wave-based effects.
type GlobalEffectType ¶ added in v0.0.2
type GlobalEffectType int
GlobalEffectType defines the type of global effect.
const ( GlobalEffectBrightness GlobalEffectType = iota GlobalEffectColorShift GlobalEffectWave GlobalEffectPulse GlobalEffectShake )
type GradientBorderAnimation ¶ added in v0.0.2
GradientBorderAnimation creates a gradient that rotates around the border.
func (*GradientBorderAnimation) GetBorderStyle ¶ added in v0.0.2
func (g *GradientBorderAnimation) GetBorderStyle(frame uint64, part BorderPart, position int, length int) Style
GetBorderStyle returns the style for a border position at a given frame.
type HBoxLayout ¶
type HBoxLayout struct {
// contains filtered or unexported fields
}
HBoxLayout arranges children horizontally in a row, left to right. Each child gets its preferred/minimum width, and height fills the container.
func NewHBoxLayout ¶
func NewHBoxLayout(spacing int) *HBoxLayout
NewHBoxLayout creates a new horizontal box layout with the specified spacing
func (*HBoxLayout) CalculateMinSize ¶
func (hb *HBoxLayout) CalculateMinSize(children []ComposableWidget) image.Point
CalculateMinSize returns the minimum size needed for all children
func (*HBoxLayout) CalculatePreferredSize ¶
func (hb *HBoxLayout) CalculatePreferredSize(children []ComposableWidget) image.Point
CalculatePreferredSize returns the preferred size for all children
func (*HBoxLayout) Layout ¶
func (hb *HBoxLayout) Layout(containerBounds image.Rectangle, children []ComposableWidget)
Layout positions children horizontally within the container bounds
func (*HBoxLayout) LayoutWithConstraints ¶
func (hb *HBoxLayout) LayoutWithConstraints(children []ComposableWidget, constraints SizeConstraints, containerBounds image.Rectangle)
LayoutWithConstraints implements ConstraintLayoutManager.LayoutWithConstraints
func (*HBoxLayout) Measure ¶
func (hb *HBoxLayout) Measure(children []ComposableWidget, constraints SizeConstraints) image.Point
Measure implements ConstraintLayoutManager.Measure
func (*HBoxLayout) WithAlignment ¶
func (hb *HBoxLayout) WithAlignment(align LayoutAlignment) *HBoxLayout
WithAlignment sets the vertical alignment for children
func (*HBoxLayout) WithDistribute ¶
func (hb *HBoxLayout) WithDistribute(distribute bool) *HBoxLayout
WithDistribute enables distributing extra horizontal space among children
type Header ¶
type Header struct {
Left string
Center string
Right string
Style Style
Background Style
Border bool
BorderStyle BorderStyle
Height int
}
Header represents the top section of the terminal
func BorderedHeader ¶
BorderedHeader creates a bordered header
func SimpleHeader ¶
SimpleHeader creates a simple header with title
type Initializable ¶
type Initializable interface {
Init() error
}
Initializable is an optional interface that applications can implement to perform initialization before the event loop starts.
type InlineApp ¶ added in v0.0.19
type InlineApp struct {
// contains filtered or unexported fields
}
InlineApp manages the runtime for inline terminal applications. It provides the same event-driven architecture as tui.Run() but renders inline rather than taking over the screen.
Architecture:
- Goroutine 1: Main event loop (processes events sequentially, calls HandleEvent/LiveView)
- Goroutine 2: Input reader (blocks on stdin, sends KeyEvents)
- Goroutine 3: Command executor (runs async commands, sends results as events)
This design eliminates race conditions in application code while maintaining responsive UI through non-blocking async operations.
func NewInlineApp ¶ added in v0.0.19
func NewInlineApp(cfgs ...InlineAppConfig) *InlineApp
NewInlineApp creates a new inline application runner.
Example:
runner := tui.NewInlineApp(tui.InlineAppConfig{
Width: 80,
BracketedPaste: true,
})
if err := runner.Run(&MyApp{}); err != nil {
log.Fatal(err)
}
func (*InlineApp) ClearScrollback ¶ added in v0.0.19
func (r *InlineApp) ClearScrollback()
ClearScrollback clears the terminal scrollback history. This sends the ANSI escape sequence to clear the scrollback buffer. Safe to call from HandleEvent.
func (*InlineApp) Print ¶ added in v0.0.19
Print renders a View to the scrollback history. The view can be any tui.View: Text, Stack, Group, Bordered, etc.
This method temporarily clears the live region, prints the view to scrollback, and restores the live region below.
Thread-safe: Can be called from HandleEvent (recommended) or from a Cmd goroutine via the app reference.
func (*InlineApp) Printf ¶ added in v0.0.19
Printf is a convenience method that prints formatted text to scrollback. Equivalent to: r.Print(tui.Text(format, args...))
func (*InlineApp) Run ¶ added in v0.0.19
Run starts the inline application and blocks until it exits. This is the main entry point, similar to tui.Run().
The app parameter must implement InlineApplication (LiveView method). Optionally implement EventHandler, Initializable, Destroyable.
Lifecycle:
- Call Init() if implemented
- Enter raw mode, enable configured terminal features
- Start event loop, input reader, and command executor goroutines
- Render initial LiveView()
- Process events until Quit command
- Restore terminal state
- Call Destroy() if implemented
type InlineAppConfig ¶ added in v0.0.22
type InlineAppConfig struct {
Width int // 0 = auto (terminal width or 80). Rendering width.
Output io.Writer // nil = os.Stdout. Where to write output.
Input io.Reader // nil = os.Stdin. Where to read input.
FPS int // 0 = no ticks. Frames per second for TickEvents.
MouseTracking bool // Enable mouse event tracking.
BracketedPaste bool // Enable bracketed paste mode.
PasteTabWidth int // 0 = preserve tabs. Convert tabs to N spaces in pastes.
KittyKeyboard bool // Enable Kitty keyboard protocol.
}
InlineAppConfig configures an InlineApp. All fields are optional with sensible zero-value defaults.
type InlineApplication ¶ added in v0.0.19
type InlineApplication interface {
// LiveView returns the view for the live region.
// Called after each event is processed to re-render the live region.
// The view should represent the current state of the interactive area.
LiveView() View
}
InlineApplication is the interface for inline applications. Applications implementing this interface render a live region that updates in place, while supporting scrollback output via the runner's Print() method.
Thread Safety: LiveView and HandleEvent (if implemented) are NEVER called concurrently. The InlineApp ensures these methods run sequentially in a single goroutine, eliminating the need for locks in application code.
Optional Interfaces:
- EventHandler: Implement HandleEvent(Event) []Cmd for event handling
- Initializable: Implement Init() error for setup before the event loop
- Destroyable: Implement Destroy() for cleanup after the event loop
type InputCursorStyle ¶ added in v0.0.2
type InputCursorStyle int
InputCursorStyle represents different cursor rendering styles for text input
const ( // InputCursorBlock renders a block cursor (default) InputCursorBlock InputCursorStyle = iota // InputCursorUnderline renders an underline cursor InputCursorUnderline // InputCursorBar renders a vertical bar/beam cursor InputCursorBar )
type InputSource ¶ added in v0.0.2
InputSource abstracts the source of input events.
type KeyDecoder ¶
type KeyDecoder = terminal.KeyDecoder
KeyDecoder handles key event decoding from a byte stream
type Layout ¶
type Layout struct {
// contains filtered or unexported fields
}
Layout manages the overall terminal layout with header, footer, and content area
func (*Layout) ContentArea ¶
ContentArea returns the Y position and height of the content area
func (*Layout) DisableAutoRefresh ¶
func (l *Layout) DisableAutoRefresh()
DisableAutoRefresh stops automatic refresh
func (*Layout) DrawTo ¶
func (l *Layout) DrawTo(frame RenderFrame)
DrawTo renders the layout to the provided frame
func (*Layout) EnableAutoRefresh ¶
EnableAutoRefresh enables automatic refresh of header/footer
func (*Layout) PrintInContent ¶
PrintInContent prints text in the content area
type LayoutAlignment ¶
type LayoutAlignment int
LayoutAlignment specifies how content should be aligned within available space
const ( LayoutAlignStart LayoutAlignment = iota // Align to top (vertical) or left (horizontal) LayoutAlignCenter // Center content LayoutAlignEnd // Align to bottom (vertical) or right (horizontal) LayoutAlignStretch // Stretch to fill available space )
type LayoutManager ¶
type LayoutManager interface {
// Layout positions and sizes all children within the container's bounds.
// The container bounds represent the available space for children.
// This method should call SetBounds() on each child widget.
Layout(containerBounds image.Rectangle, children []ComposableWidget)
// CalculateMinSize determines the minimum size needed to layout all children.
// This enables containers to know their own minimum size based on their contents.
CalculateMinSize(children []ComposableWidget) image.Point
// CalculatePreferredSize determines the preferred size for the container.
// This may be larger than minimum if children want more space.
CalculatePreferredSize(children []ComposableWidget) image.Point
}
LayoutManager defines strategies for positioning and sizing child widgets within a container. Different implementations provide different layout behaviors (vertical stack, horizontal stack, grid, flexbox-style, etc.).
type LayoutParams ¶
type LayoutParams struct {
// Flex/grow factor - how much extra space this widget should take relative to siblings
// 0 means don't grow, 1 means grow proportionally with others, 2 means grow twice as much, etc.
Grow int
// Shrink factor - how much this widget should shrink when space is constrained
// 0 means don't shrink, 1 means shrink proportionally
Shrink int
// Alignment within the container
Align LayoutAlignment
// Margin around the widget (space outside the widget)
MarginTop int
MarginRight int
MarginBottom int
MarginLeft int
// Padding inside the widget (space inside borders, outside content)
PaddingTop int
PaddingRight int
PaddingBottom int
PaddingLeft int
// Size constraints
Constraints SizeConstraints
}
LayoutParams holds layout-specific parameters that widgets can use to influence how their parent container positions them.
func DefaultLayoutParams ¶
func DefaultLayoutParams() LayoutParams
DefaultLayoutParams returns sensible defaults for layout parameters
type List ¶
type List struct {
BaseWidget
Items []ListItem
SelectedIndex int
ScrollOffset int
// Styles
NormalStyle Style
SelectedStyle Style
// Callbacks
OnSelect func(item ListItem)
}
List is a scrollable list widget
func (*List) GetSelected ¶
GetSelected returns the currently selected item
func (*List) HandleMouse ¶
func (l *List) HandleMouse(event MouseEvent) bool
HandleMouse handles mouse events
type ListItemRenderer ¶ added in v0.0.2
ListItemRenderer is a function that renders a list item. It receives the item, whether it's selected, and returns a View.
type LivePrinter ¶ added in v0.0.2
type LivePrinter struct {
// contains filtered or unexported fields
}
LivePrinter renders views to a fixed region of the terminal that updates in place. This is useful for progress bars, status displays, and loading indicators that need to update without scrolling the terminal.
Rendering Optimization ¶
LivePrinter uses several techniques to minimize flicker and improve performance:
Line-level diffing: Each frame is compared line-by-line against the previous frame. Only lines that actually changed are redrawn. This is similar to how the Terminal package uses cell-level diffing, but operates at a coarser granularity for simpler inline updates.
Synchronized output mode: Updates are wrapped in DEC private mode 2026 escape sequences (\033[?2026h ... \033[?2026l). This tells the terminal to buffer all changes and render them atomically, eliminating partial-frame flicker. Supported by most modern terminals (iTerm2, kitty, alacritty, Windows Terminal, WezTerm, foot). Terminals that don't support it simply ignore the escape sequences.
Cursor hiding: The cursor is hidden during updates and restored on Stop().
Thread Safety ¶
LivePrinter is NOT thread-safe. All calls to Update, Clear, and Stop should be made from the same goroutine, or protected by external synchronization. For thread-safe live updates, use InlineApp which handles synchronization.
Example ¶
live := tui.NewLivePrinter(tui.PrintConfig{Width: 60})
defer live.Stop()
for i := 0; i <= 100; i++ {
live.Update(tui.Text("Progress: %d%%", i))
time.Sleep(50 * time.Millisecond)
}
func NewLivePrinter ¶ added in v0.0.2
func NewLivePrinter(cfgs ...PrintConfig) *LivePrinter
NewLivePrinter creates a new LivePrinter for updating a region in place.
func (*LivePrinter) Clear ¶ added in v0.0.2
func (lp *LivePrinter) Clear()
Clear removes the live region content and resets state.
func (*LivePrinter) SetWidth ¶ added in v0.0.24
func (lp *LivePrinter) SetWidth(w int)
SetWidth updates the width of the live printer. This is useful when the terminal is resized. The next Update() will use the new width.
func (*LivePrinter) Stop ¶ added in v0.0.2
func (lp *LivePrinter) Stop()
Stop finalizes the live region, moving the cursor below the content and restoring cursor visibility.
func (*LivePrinter) Update ¶ added in v0.0.2
func (lp *LivePrinter) Update(view View) error
Update renders a new view, replacing the previous content in place. The cursor moves back to overwrite the previous output.
Optimization: Uses line-level diffing to only update lines that changed, similar to how the Terminal package uses cell-level diffing. This reduces the amount of data written and minimizes flicker.
func (*LivePrinter) UpdateNoSync ¶ added in v0.0.19
func (lp *LivePrinter) UpdateNoSync(view View) error
UpdateNoSync is like Update but without synchronized output mode wrapping. This is useful when the caller is already managing sync mode to avoid nested escape sequences.
Use cases:
- InlineApp.Print() uses this to atomically clear, print, and re-render
- Batch operations that need to wrap multiple updates in a single sync block
Most users should use Update() instead, which handles sync mode automatically.
func (*LivePrinter) UpdateWithFocus ¶ added in v0.0.22
func (lp *LivePrinter) UpdateWithFocus(view View, fm *FocusManager) error
UpdateWithFocus renders a view with focus management support. The focus manager is passed through the render context to focusable components.
type MarkdownRenderer ¶
type MarkdownRenderer struct {
Theme MarkdownTheme
MaxWidth int // Maximum width for text wrapping (0 = no limit)
TabWidth int // Width of tab character in spaces
// contains filtered or unexported fields
}
MarkdownRenderer renders markdown content to styled terminal output
func NewMarkdownRenderer ¶
func NewMarkdownRenderer() *MarkdownRenderer
NewMarkdownRenderer creates a new markdown renderer with the default theme
func (*MarkdownRenderer) Render ¶
func (mr *MarkdownRenderer) Render(markdown string) (*RenderedMarkdown, error)
Render parses and renders markdown content
func (*MarkdownRenderer) WithMaxWidth ¶
func (mr *MarkdownRenderer) WithMaxWidth(width int) *MarkdownRenderer
WithMaxWidth sets the maximum width for text wrapping
func (*MarkdownRenderer) WithTheme ¶
func (mr *MarkdownRenderer) WithTheme(theme MarkdownTheme) *MarkdownRenderer
WithTheme sets a custom theme for the renderer
type MarkdownTheme ¶
type MarkdownTheme struct {
// Heading styles by level (1-6)
H1Style Style
H2Style Style
H3Style Style
H4Style Style
H5Style Style
H6Style Style
// Text styles
BoldStyle Style
ItalicStyle Style
CodeStyle Style
LinkStyle Style
StrikethroughStyle Style
// Block styles
BlockQuoteStyle Style
CodeBlockStyle Style
// List styles
BulletChar string
NumberFmt string // Format string for numbered lists, e.g., "%d. "
// Other
HorizontalRuleChar string
HorizontalRuleStyle Style
// Syntax highlighting theme name for code blocks
SyntaxTheme string
// Table styles
TableBorderStyle Style
TableHeaderStyle Style
TableCellStyle Style
}
MarkdownTheme defines the colors and styles for markdown rendering
func DefaultMarkdownTheme ¶
func DefaultMarkdownTheme() MarkdownTheme
DefaultMarkdownTheme returns a default markdown theme with good contrast
type MarqueeBorderAnimation ¶ added in v0.0.2
type MarqueeBorderAnimation struct {
Speed int
OnColor RGB
OffColor RGB
SegmentLength int // Length of each on/off segment
Reversed bool // Direction of movement
}
MarqueeBorderAnimation creates a moving pattern around the border.
func (*MarqueeBorderAnimation) GetBorderStyle ¶ added in v0.0.2
func (m *MarqueeBorderAnimation) GetBorderStyle(frame uint64, part BorderPart, position int, length int) Style
GetBorderStyle returns the style for a border position at a given frame.
type Measurable ¶
type Measurable interface {
ComposableWidget
// Measure calculates the desired size of the widget given the constraints.
// The returned size should respect the constraints (be within min/max).
Measure(constraints SizeConstraints) image.Point
}
Measurable interface allows widgets to participate in a constraint-based layout pass. This is the "first pass" of a Flutter-style layout system, where parents pass constraints down to children, and children return their desired size.
type MetricsSnapshot ¶
type MetricsSnapshot = terminal.MetricsSnapshot
MetricsSnapshot is a point-in-time snapshot of rendering metrics
type MouseAware ¶
type MouseAware interface {
HandleMouse(event MouseEvent) bool
}
MouseAware is an optional interface for widgets that handle mouse events
type MouseEvent ¶
type MouseEvent = terminal.MouseEvent
MouseEvent is a mouse event from the terminal package
type MouseHandler ¶
type MouseHandler struct {
// Configuration
DoubleClickThreshold time.Duration
TripleClickThreshold time.Duration
ClickMoveThreshold int
DragStartThreshold int
// contains filtered or unexported fields
}
MouseHandler manages mouse regions and events with advanced features. This is a higher-level UI component that tracks regions, handles click detection, drag state, and dispatches events to handlers.
func NewMouseHandler ¶
func NewMouseHandler() *MouseHandler
NewMouseHandler creates a new mouse handler
func (*MouseHandler) AddRegion ¶
func (h *MouseHandler) AddRegion(region *MouseRegion)
AddRegion adds a clickable region
func (*MouseHandler) CancelDrag ¶
func (h *MouseHandler) CancelDrag()
CancelDrag cancels an active drag (e.g., on Escape key)
func (*MouseHandler) ClearRegions ¶
func (h *MouseHandler) ClearRegions()
ClearRegions removes all regions
func (*MouseHandler) DisableDebug ¶
func (h *MouseHandler) DisableDebug()
DisableDebug disables debug logging
func (*MouseHandler) EnableDebug ¶
func (h *MouseHandler) EnableDebug()
EnableDebug enables debug logging for mouse events
func (*MouseHandler) HandleEvent ¶
func (h *MouseHandler) HandleEvent(event *MouseEvent)
HandleEvent processes a mouse event with full state machine
func (*MouseHandler) RemoveRegion ¶
func (h *MouseHandler) RemoveRegion(region *MouseRegion)
RemoveRegion removes a specific region
type MouseRegion ¶
type MouseRegion = terminal.MouseRegion
MouseRegion is a clickable region from the terminal package
type PasswordInput ¶
type PasswordInput struct {
// contains filtered or unexported fields
}
PasswordInput provides secure password input with advanced features. It supports: - iTerm2 secure input mode (prevents keylogging) - VS Code terminal integration - Clipboard disable during input - Memory zeroing on completion - Show/hide toggle - Paste confirmation
func NewPasswordInput ¶
func NewPasswordInput(terminal *Terminal) *PasswordInput
NewPasswordInput creates a new secure password input handler.
func (*PasswordInput) ConfirmPaste ¶
func (p *PasswordInput) ConfirmPaste(confirm bool) *PasswordInput
ConfirmPaste controls whether to require confirmation before accepting pasted content.
func (*PasswordInput) DisableClipboard ¶
func (p *PasswordInput) DisableClipboard(disable bool) *PasswordInput
DisableClipboard controls whether to disable clipboard access during password input.
func (*PasswordInput) EnableSecureMode ¶
func (p *PasswordInput) EnableSecureMode(enable bool) *PasswordInput
EnableSecureMode controls whether to enable terminal-specific secure input modes. When enabled (default), sends escape codes to iTerm2/VS Code to prevent keylogging.
func (*PasswordInput) Read ¶
func (p *PasswordInput) Read() (*SecureString, error)
Read reads a password with enhanced security features. The password is stored in a byte slice that is zeroed after use.
Example:
pwdInput := tui.NewPasswordInput(terminal)
pwdInput.WithPrompt("Enter password: ", tui.NewStyle())
password, err := pwdInput.Read()
if err != nil {
return err
}
defer password.Clear() // Zero memory when done
// Use password...
func (*PasswordInput) ShowCharacters ¶
func (p *PasswordInput) ShowCharacters(show bool) *PasswordInput
ShowCharacters enables showing masked characters (*) instead of no echo. This provides visual feedback while maintaining security.
func (*PasswordInput) WithMaskChar ¶
func (p *PasswordInput) WithMaskChar(char rune) *PasswordInput
WithMaskChar sets the character used to mask password input. Only used when ShowCharacters is enabled.
func (*PasswordInput) WithMaxLength ¶
func (p *PasswordInput) WithMaxLength(length int) *PasswordInput
WithMaxLength sets the maximum password length.
func (*PasswordInput) WithPlaceholder ¶
func (p *PasswordInput) WithPlaceholder(placeholder string) *PasswordInput
WithPlaceholder sets placeholder text.
func (*PasswordInput) WithPrompt ¶
func (p *PasswordInput) WithPrompt(prompt string, style Style) *PasswordInput
WithPrompt sets the password prompt.
type PlaybackController ¶
type PlaybackController struct {
// contains filtered or unexported fields
}
PlaybackController manages playback of recorded sessions
func LoadRecording ¶
func LoadRecording(filename string) (*PlaybackController, error)
LoadRecording loads a .cast file and returns a playback controller
func (*PlaybackController) GetDuration ¶
func (p *PlaybackController) GetDuration() float64
GetDuration returns the total duration of the recording in seconds
func (*PlaybackController) GetHeader ¶
func (p *PlaybackController) GetHeader() RecordingHeader
GetHeader returns the recording metadata
func (*PlaybackController) GetPosition ¶
func (p *PlaybackController) GetPosition() float64
GetPosition returns the current playback position in seconds
func (*PlaybackController) GetProgress ¶
func (p *PlaybackController) GetProgress() float64
GetProgress returns playback progress as a value between 0.0 and 1.0
func (*PlaybackController) IsPaused ¶
func (p *PlaybackController) IsPaused() bool
IsPaused returns true if playback is paused
func (*PlaybackController) Play ¶
func (p *PlaybackController) Play(terminal *Terminal) error
Play starts playback of the recording
func (*PlaybackController) Seek ¶
func (p *PlaybackController) Seek(seconds float64)
Seek jumps to a specific time offset in the recording
func (*PlaybackController) SetLoop ¶
func (p *PlaybackController) SetLoop(loop bool)
SetLoop enables or disables looping
func (*PlaybackController) SetSpeed ¶
func (p *PlaybackController) SetSpeed(speed float64)
SetSpeed sets the playback speed multiplier (1.0 = normal, 2.0 = 2x, 0.5 = half speed)
func (*PlaybackController) Speed ¶
func (p *PlaybackController) Speed() float64
Speed returns the current playback speed
func (*PlaybackController) Stop ¶
func (p *PlaybackController) Stop()
Stop stops playback completely
func (*PlaybackController) TogglePause ¶
func (p *PlaybackController) TogglePause()
TogglePause toggles pause/resume
type PrintConfig ¶ added in v0.0.22
type PrintConfig struct {
Width int // 0 = auto (terminal width or 80). Positive values set the width.
Height int // 0 = auto (based on view size). Positive values set a fixed height.
Output io.Writer // nil = os.Stdout. Specify where to write output.
RawMode bool // false = use \n line endings. true = use \r\n for raw terminal mode.
}
PrintConfig configures printing functions like Print, Fprint, and Sprint. All fields are optional with sensible zero-value defaults.
type ProgressBar
deprecated
type ProgressBar struct {
Total int
Current int
Width int
Style Style
FillChar string
EmptyChar string
ShowPercent bool
ShowNumbers bool
Message string
}
ProgressBar represents a progress bar widget
Deprecated: Use Progress() for declarative progress bar.
func NewProgressBar
deprecated
func NewProgressBar(total int) *ProgressBar
NewProgressBar creates a new progress bar widget
Deprecated: Use Progress() for declarative progress bar.
func (*ProgressBar) Draw ¶
func (p *ProgressBar) Draw(frame RenderFrame, x, y int)
Draw renders the progress bar at the specified position
func (*ProgressBar) SetProgress ¶
func (p *ProgressBar) SetProgress(current int)
SetProgress sets the current progress
func (*ProgressBar) WithChars ¶
func (p *ProgressBar) WithChars(fill, empty string) *ProgressBar
WithChars sets the fill and empty characters
func (*ProgressBar) WithStyle ¶
func (p *ProgressBar) WithStyle(style Style) *ProgressBar
WithStyle sets the progress bar style
func (*ProgressBar) WithWidth ¶
func (p *ProgressBar) WithWidth(width int) *ProgressBar
WithWidth sets the progress bar width
type PromptOption ¶ added in v0.0.19
type PromptOption func(*promptConfig)
PromptOption configures the Prompt function.
func WithAutocomplete ¶ added in v0.0.19
func WithAutocomplete(fn AutocompleteFunc) PromptOption
WithAutocomplete enables tab completion. The function receives the current input and cursor position, returns a list of completions and the start index to replace from.
func WithHistory ¶ added in v0.0.19
func WithHistory(history *[]string) PromptOption
WithHistory enables command history navigation with up/down arrows. The provided slice is updated with new entries.
func WithInputStyle ¶ added in v0.0.19
func WithInputStyle(style Style) PromptOption
WithInputStyle styles the user's input text.
func WithMask ¶ added in v0.0.19
func WithMask(char string) PromptOption
WithMask masks input (for passwords). Empty string = show nothing.
func WithMaxLength ¶ added in v0.0.19
func WithMaxLength(n int) PromptOption
WithMaxLength limits input length.
func WithMultiLine ¶ added in v0.0.19
func WithMultiLine(enabled bool) PromptOption
WithMultiLine allows multi-line input via Shift+Enter or Ctrl+J. Enter submits; Shift+Enter/Ctrl+J inserts newline.
func WithPlaceholder ¶ added in v0.0.19
func WithPlaceholder(text string) PromptOption
WithPlaceholder shows hint text when input is empty.
func WithPromptOutput ¶ added in v0.0.19
func WithPromptOutput(w io.Writer) PromptOption
WithPromptOutput sets the output writer for the prompt. Default is os.Stdout.
func WithPromptStyle ¶ added in v0.0.19
func WithPromptStyle(style Style) PromptOption
WithPromptStyle styles the prompt text.
func WithValidator ¶ added in v0.0.19
func WithValidator(fn func(string) error) PromptOption
WithValidator validates input before submission. Return non-nil error to prevent submission and show error message.
type PulseAnimation ¶
PulseAnimation creates a pulsing brightness effect
func Pulse ¶ added in v0.0.7
func Pulse(color RGB, speed int) *PulseAnimation
Pulse creates a new pulse animation with a pulsing brightness effect. Color is the base color, speed controls the pulse rate (lower = faster).
Example:
Text("Active").Animate(Pulse(green, 10))
Text("Active").Animate(Pulse(green, 10).Brightness(0.3, 1.0))
func (*PulseAnimation) Brightness ¶ added in v0.0.7
func (p *PulseAnimation) Brightness(minBrightness, maxBrightness float64) *PulseAnimation
Brightness sets the minimum and maximum brightness levels (0.0 to 1.0).
type PulseBorderAnimation ¶ added in v0.0.2
type PulseBorderAnimation struct {
Speed int
Color RGB
MinBrightness float64
MaxBrightness float64
Easing Easing // Optional easing function for the pulse
}
PulseBorderAnimation creates a pulsing brightness effect on the border.
func (*PulseBorderAnimation) GetBorderStyle ¶ added in v0.0.2
func (p *PulseBorderAnimation) GetBorderStyle(frame uint64, part BorderPart, position int, length int) Style
GetBorderStyle returns the style for a border position at a given frame.
type QuitEvent ¶
QuitEvent signals that the application should shut down. The Runtime will exit the event loop, call Destroy() if implemented, and return from Run().
type RainbowAnimation ¶
type RainbowAnimation struct {
Speed int // How fast the rainbow moves (frames per cycle)
Length int // How many characters the rainbow spans
Reversed bool
}
RainbowAnimation creates a moving rainbow effect
func Rainbow ¶ added in v0.0.7
func Rainbow(speed int) *RainbowAnimation
Rainbow creates a new rainbow animation with the specified speed. Speed controls how fast the rainbow moves (lower = faster).
Example:
Text("Hello").Animate(Rainbow(3))
Text("Hello").Animate(Rainbow(3).Reverse())
func (*RainbowAnimation) GetStyle ¶
func (r *RainbowAnimation) GetStyle(frame uint64, charIndex int, totalChars int) Style
GetStyle returns the style for a character at a given frame
func (*RainbowAnimation) Reverse ¶ added in v0.0.7
func (r *RainbowAnimation) Reverse() *RainbowAnimation
Reverse sets the rainbow to move in the opposite direction.
func (*RainbowAnimation) WithLength ¶ added in v0.0.7
func (r *RainbowAnimation) WithLength(length int) *RainbowAnimation
WithLength sets how many characters the rainbow spans. If not set, defaults to the text length.
type RainbowBorderAnimation ¶ added in v0.0.2
type RainbowBorderAnimation struct {
Speed int // How fast the rainbow moves (frames per cycle)
Reversed bool // Direction of movement
}
RainbowBorderAnimation creates a rainbow that cycles around the border.
func (*RainbowBorderAnimation) GetBorderStyle ¶ added in v0.0.2
func (r *RainbowBorderAnimation) GetBorderStyle(frame uint64, part BorderPart, position int, length int) Style
GetBorderStyle returns the style for a border position at a given frame.
type RecordingEvent ¶
type RecordingEvent = terminal.RecordingEvent
RecordingEvent represents a single recording event
type RecordingHeader ¶
type RecordingHeader = terminal.RecordingHeader
RecordingHeader represents asciinema v2 header
type RecordingOptions ¶
type RecordingOptions = terminal.RecordingOptions
RecordingOptions configures recording behavior
type RenderContext ¶ added in v0.0.2
type RenderContext struct {
// contains filtered or unexported fields
}
RenderContext provides drawing capabilities and contextual information to views. It flows through the view tree during rendering, giving views access to:
- Drawing operations (via the embedded RenderFrame)
- Animation frame counter
- Focus management
Views should use SubContext() when rendering children to properly scope the drawing area while preserving context information.
func NewRenderContext ¶ added in v0.0.2
func NewRenderContext(frame RenderFrame, frameCount uint64) *RenderContext
NewRenderContext creates a new render context. This is typically called by the Runtime at the start of each render cycle.
func (*RenderContext) AbsoluteBounds ¶ added in v0.0.2
func (c *RenderContext) AbsoluteBounds() image.Rectangle
AbsoluteBounds returns the absolute screen bounds of this context. Use this for registering interactive regions (click handlers, etc.).
func (*RenderContext) Bounds ¶ added in v0.0.2
func (c *RenderContext) Bounds() image.Rectangle
Bounds returns the current drawing bounds.
func (*RenderContext) Fill ¶ added in v0.0.2
func (c *RenderContext) Fill(char rune, style Style)
Fill fills the entire context area with a character and style.
func (*RenderContext) FillStyled ¶ added in v0.0.2
func (c *RenderContext) FillStyled(x, y, width, height int, char rune, style Style)
FillStyled fills a rectangular area with a character and style.
func (*RenderContext) FocusManager ¶ added in v0.0.22
func (c *RenderContext) FocusManager() *FocusManager
FocusManager returns the focus manager for this context, or nil if none.
func (*RenderContext) Frame ¶ added in v0.0.2
func (c *RenderContext) Frame() uint64
Frame returns the current animation frame counter. Use this for time-based animations - it increments each tick (typically 30-60 FPS).
func (*RenderContext) PrintHyperlink ¶ added in v0.0.2
func (c *RenderContext) PrintHyperlink(x, y int, link Hyperlink)
PrintHyperlink prints a clickable hyperlink.
func (*RenderContext) PrintHyperlinkFallback ¶ added in v0.0.2
func (c *RenderContext) PrintHyperlinkFallback(x, y int, link Hyperlink)
PrintHyperlinkFallback prints a hyperlink in fallback format: "Text (URL)".
func (*RenderContext) PrintStyled ¶ added in v0.0.2
func (c *RenderContext) PrintStyled(x, y int, text string, style Style)
PrintStyled prints text at the given position with a style. Text wraps at the frame edge.
func (*RenderContext) PrintTruncated ¶ added in v0.0.2
func (c *RenderContext) PrintTruncated(x, y int, text string, style Style)
PrintTruncated prints text at the given position, truncating at the frame edge.
func (*RenderContext) RenderFrame ¶ added in v0.0.2
func (c *RenderContext) RenderFrame() RenderFrame
RenderFrame returns the underlying RenderFrame. This is useful for views that need to create custom frame wrappers.
func (*RenderContext) SetCell ¶ added in v0.0.2
func (c *RenderContext) SetCell(x, y int, char rune, style Style)
SetCell sets a character at the given position with a style.
func (*RenderContext) Size ¶ added in v0.0.2
func (c *RenderContext) Size() (width, height int)
Size returns the width and height of the current drawing area.
func (*RenderContext) SubContext ¶ added in v0.0.2
func (c *RenderContext) SubContext(bounds image.Rectangle) *RenderContext
SubContext creates a child context with a sub-region of the drawing area. The bounds are relative to the current context's origin. All context information (frame counter, focus manager, etc.) is preserved.
func (*RenderContext) WithFocusManager ¶ added in v0.0.22
func (c *RenderContext) WithFocusManager(fm *FocusManager) *RenderContext
WithFocusManager returns a new context with the given focus manager.
func (*RenderContext) WithFrame ¶ added in v0.0.2
func (c *RenderContext) WithFrame(frame RenderFrame) *RenderContext
WithFrame creates a new context using a different RenderFrame but preserving the frame counter and focus manager. This is useful for views that need custom frame wrappers (like scroll views).
type RenderFrame ¶
type RenderFrame = terminal.RenderFrame
RenderFrame represents a rendering surface for a single frame
type RenderMetrics ¶
type RenderMetrics = terminal.RenderMetrics
RenderMetrics tracks performance statistics for the rendering system
type RenderedDiffLine ¶
type RenderedDiffLine struct {
LineNumOld string // Old line number (formatted)
LineNumNew string // New line number (formatted)
Segments []StyledSegment // Styled content segments
BgColor *RGB // Background color for the entire line
}
RenderedDiffLine represents a single rendered diff line with styling
type RenderedMarkdown ¶
type RenderedMarkdown struct {
Lines []StyledLine
}
RenderedMarkdown contains the fully rendered markdown content
type ResizeEvent ¶
type ResizeEvent struct {
Time time.Time
Width int // Terminal width in columns
Height int // Terminal height in rows
}
ResizeEvent is emitted when the terminal window is resized. Applications receive an initial ResizeEvent on startup with the current terminal dimensions.
Example:
func (a *App) HandleEvent(event Event) []Cmd {
if resize, ok := event.(ResizeEvent); ok {
a.width = resize.Width
a.height = resize.Height
}
return nil
}
func (ResizeEvent) Timestamp ¶
func (e ResizeEvent) Timestamp() time.Time
type RunOption ¶
type RunOption func(*runConfig)
RunOption is a functional option for configuring Run.
func WithAlternateScreen ¶
WithAlternateScreen controls whether to use the alternate screen buffer. When enabled (default), the terminal switches to a separate buffer and restores the original content on exit.
func WithBracketedPaste ¶ added in v0.0.2
WithBracketedPaste enables bracketed paste mode. When enabled, the terminal can distinguish pasted text from typed text, allowing proper handling of multi-line pastes.
func WithFPS ¶
WithFPS sets the frames per second for TickEvents. Default is 30 FPS. Use 60 for smoother animations.
func WithHideCursor ¶
WithHideCursor controls whether to hide the cursor during rendering. Default is true. Set to false if your application manages cursor visibility.
func WithInput ¶ added in v0.0.2
func WithInput(source InputSource) RunOption
WithInput sets a custom input source for the runtime. This is primarily used for testing.
func WithMouseTracking ¶
WithMouseTracking enables mouse event tracking. When enabled, the application will receive MouseEvent events.
func WithPasteTabWidth ¶
WithPasteTabWidth configures how tabs in pasted content are handled. If width is 0 (default), tabs are preserved as-is. If width > 0, each tab is converted to that many spaces.
type Runtime ¶
type Runtime struct {
// contains filtered or unexported fields
}
Runtime manages the event-driven execution of an Application. It provides a race-free, single-threaded event loop while supporting async operations through the command system.
Architecture:
- Goroutine 1: Main event loop (processes events sequentially, calls HandleEvent/View)
- Goroutine 2: Input reader (blocks on stdin, sends KeyEvents)
- Goroutine 3: Command executor (runs async commands, sends results as events)
This design eliminates race conditions in application code while maintaining responsive UI through non-blocking async operations.
func NewRuntime ¶
NewRuntime creates a new Runtime for the given application.
Parameters:
- terminal: The Terminal instance to use for rendering and input
- app: The Application to run
- fps: Frames per second for TickEvents (30 recommended, 60 for smooth animations)
The runtime does not start automatically. Call Run() to start the event loop.
func (*Runtime) Run ¶
Run starts the runtime's event loop and blocks until the application quits. This method is the main entry point for message-driven applications.
Execution flow:
- Initialize application (if it implements Initializable)
- Register resize handler with terminal
- Start three goroutines: event loop, input reader, command executor
- Block until QuitEvent is received
- Clean up and call Destroy (if implemented)
Returns error if initialization fails.
func (*Runtime) SendEvent ¶
SendEvent sends an event to the runtime's event loop. This is useful for custom event sources or testing. It's safe to call from any goroutine.
func (*Runtime) SetInputSource ¶ added in v0.0.2
func (r *Runtime) SetInputSource(source InputSource)
SetInputSource sets the input source for the runtime.
func (*Runtime) SetPasteTabWidth ¶
SetPasteTabWidth configures how tabs in pasted content are handled. If width is 0 (default), tabs are preserved as-is. If width > 0, each tab is converted to that many spaces. Must be called before Run().
type ScrollAnchor ¶
type ScrollAnchor int
ScrollAnchor determines which part of content to show when content exceeds viewport.
const ( // ScrollAnchorTop shows content from the top (default scroll behavior). ScrollAnchorTop ScrollAnchor = iota // ScrollAnchorBottom shows content from the bottom (chat-style, newest at bottom). ScrollAnchorBottom )
type SecureString ¶
type SecureString struct {
// contains filtered or unexported fields
}
SecureString provides a wrapper around password data with automatic memory zeroing.
func NewSecureString ¶
func NewSecureString(data []byte) *SecureString
NewSecureString creates a new SecureString from a byte slice.
func (*SecureString) Bytes ¶
func (s *SecureString) Bytes() []byte
Bytes returns the underlying byte slice. Do not modify the returned slice.
func (*SecureString) Clear ¶
func (s *SecureString) Clear()
Clear zeros the password data in memory. After calling Clear, the SecureString should not be used.
func (*SecureString) IsEmpty ¶
func (s *SecureString) IsEmpty() bool
IsEmpty returns true if the password is empty.
func (*SecureString) String ¶
func (s *SecureString) String() string
String returns the password as a string. Note: This creates a copy in memory. Use with caution.
type SizeConstraints ¶
type SizeConstraints struct {
MinWidth int
MinHeight int
MaxWidth int // 0 means no maximum
MaxHeight int // 0 means no maximum
}
SizeConstraints defines minimum and maximum size constraints for a widget. Zero values for MaxWidth/MaxHeight indicate no maximum constraint (unconstrained).
func (SizeConstraints) Constrain ¶
func (sc SizeConstraints) Constrain(size image.Point) image.Point
Constrain applies the constraints to a given size
func (SizeConstraints) HasMaxHeight ¶
func (sc SizeConstraints) HasMaxHeight() bool
HasMaxHeight returns true if there is a maximum height constraint
func (SizeConstraints) HasMaxWidth ¶
func (sc SizeConstraints) HasMaxWidth() bool
HasMaxWidth returns true if there is a maximum width constraint
func (SizeConstraints) IsTight ¶
func (sc SizeConstraints) IsTight() bool
IsTight returns true if min and max are equal (and max > 0)
type SlideAnimation ¶ added in v0.0.2
type SlideAnimation struct {
Speed int
BaseColor RGB
HighlightColor RGB
Width int // Width of the highlight in characters
Reverse bool // True = right to left, false = left to right
}
SlideAnimation creates a highlight that slides across the text
func Slide ¶ added in v0.0.7
func Slide(speed int, baseColor, highlightColor RGB) *SlideAnimation
Slide creates a new slide animation with a highlight that moves across text. Speed controls how fast the highlight moves (lower = faster).
Example:
Text("Loading").Animate(Slide(2, gray, white))
Text("Loading").Animate(Slide(2, gray, white).Reversed())
func (*SlideAnimation) GetStyle ¶ added in v0.0.2
func (s *SlideAnimation) GetStyle(frame uint64, charIndex int, totalChars int) Style
GetStyle returns the style for a character at a given frame
func (*SlideAnimation) Reversed ¶ added in v0.0.7
func (s *SlideAnimation) Reversed() *SlideAnimation
Reversed sets the slide to move from right to left.
func (*SlideAnimation) WithWidth ¶ added in v0.0.7
func (s *SlideAnimation) WithWidth(width int) *SlideAnimation
WithWidth sets the width of the highlight in characters.
type SparkleAnimation ¶ added in v0.0.2
type SparkleAnimation struct {
Speed int // How often sparkles update
BaseColor RGB
SparkColor RGB
Density int // Higher = more sparkles (1-10 recommended)
}
SparkleAnimation creates a twinkling star-like effect where random characters briefly brighten
func Sparkle ¶ added in v0.0.7
func Sparkle(speed int, baseColor, sparkColor RGB) *SparkleAnimation
Sparkle creates a new sparkle animation with twinkling star-like effects. Speed controls animation timing (lower = faster).
Example:
Text("Stars").Animate(Sparkle(3, gray, white))
Text("Stars").Animate(Sparkle(3, gray, white).WithDensity(5))
func (*SparkleAnimation) GetStyle ¶ added in v0.0.2
func (s *SparkleAnimation) GetStyle(frame uint64, charIndex int, totalChars int) Style
GetStyle returns the style for a character at a given frame
func (*SparkleAnimation) WithDensity ¶ added in v0.0.7
func (s *SparkleAnimation) WithDensity(density int) *SparkleAnimation
WithDensity sets how many sparkles appear (1-10 recommended, higher = more sparkles).
type SparkleBorderAnimation ¶ added in v0.0.2
type SparkleBorderAnimation struct {
Speed int
BaseColor RGB
SparkColor RGB
Density int // Probability of sparkle (1-10)
SparkleSize int // Size of each sparkle in characters
}
SparkleBorderAnimation creates random sparkles around the border.
func (*SparkleBorderAnimation) GetBorderStyle ¶ added in v0.0.2
func (s *SparkleBorderAnimation) GetBorderStyle(frame uint64, part BorderPart, position int, length int) Style
GetBorderStyle returns the style for a border position at a given frame.
type Spinner
deprecated
type Spinner struct {
// contains filtered or unexported fields
}
Spinner represents an animated loading spinner widget
Deprecated: Use Loading() for declarative spinner.
func NewSpinner
deprecated
func NewSpinner(style SpinnerStyle) *Spinner
NewSpinner creates a new spinner widget
Deprecated: Use Loading() for declarative spinner.
func (*Spinner) Draw ¶
func (s *Spinner) Draw(frame RenderFrame, x, y int)
Draw renders the spinner at the specified position
func (*Spinner) Update ¶
Update advances the spinner animation based on elapsed time. Call this from HandleEvent on TickEvent.
func (*Spinner) WithMessage ¶
WithMessage sets the spinner message
type SpinnerStyle ¶
SpinnerStyle defines different spinner animations
type StatusItem ¶
StatusItem represents an item in the status bar
type StyledLine ¶
type StyledLine struct {
Segments []StyledSegment
Indent int // Indentation level in spaces
}
StyledLine represents a single line of rendered markdown with styled segments
type StyledSegment ¶
StyledSegment represents a portion of text with a specific style
type TableColumn ¶
type TableColumn struct {
Title string
Width int // If 0, auto-calculated based on content
MinWidth int // Minimum width (won't shrink below this)
}
TableColumn represents a table column configuration.
type TextAnimation ¶
TextAnimation defines how text should be animated
type TextInput ¶
type TextInput struct {
BaseWidget
Placeholder string
CursorPos int // Cursor position in display text
// Styles
Style Style
PlaceholderStyle Style
CursorStyle Style
PasteStyle Style // Style for paste placeholders
OverflowStyle Style // Style for overflow indicators (▲/▼)
// Callbacks
OnChange func(value string)
OnSubmit func(value string)
// Password/masking support
MaskChar rune // If non-zero, display this character instead of actual text
MaxLength int // If non-zero, limit input to this many runes
// Paste placeholder mode
PastePlaceholderMode bool // When true, multi-line pastes show as "[pasted N lines]"
// Multiline mode
MultilineMode bool // When true, Shift+Enter inserts newlines
SubmitOnEnter bool // When true, Enter triggers OnSubmit (default: true)
// Scrolling (for multiline with MaxHeight)
MaxHeight int // Maximum visible lines (0 = unlimited)
ScrollOffset int // First visible line (0-indexed)
// Cursor appearance
CursorBlink bool // When true, cursor blinks
CursorBlinkInterval time.Duration // Blink interval (default 530ms)
CursorShape InputCursorStyle // Shape of the cursor (block, underline, bar)
CursorColor *Color // Custom cursor color (nil = use default style)
// contains filtered or unexported fields
}
TextInput is a simple single-line text input widget
func (*TextInput) DisplayText ¶
DisplayText returns the text shown to the user (with placeholders for pastes)
func (*TextInput) HandleMouse ¶
func (t *TextInput) HandleMouse(event MouseEvent) bool
HandleMouse handles mouse events
func (*TextInput) HandlePaste ¶
HandlePaste handles pasted content, using placeholder mode if enabled for multi-line pastes. Returns true if the paste was handled.
func (*TextInput) SetFocused ¶
SetFocused sets focus state
func (*TextInput) Value ¶
Value returns the actual value (with full paste content, not placeholders)
func (*TextInput) WithCursorBlink ¶ added in v0.0.2
WithCursorBlink enables or disables cursor blinking.
func (*TextInput) WithCursorBlinkInterval ¶ added in v0.0.2
WithCursorBlinkInterval sets the cursor blink interval. Default is 530ms if not set.
func (*TextInput) WithCursorColor ¶ added in v0.0.2
WithCursorColor sets a custom cursor color. If not set, uses the CursorStyle colors (default: white background, black foreground).
func (*TextInput) WithCursorShape ¶ added in v0.0.2
func (t *TextInput) WithCursorShape(shape InputCursorStyle) *TextInput
WithCursorShape sets the cursor shape/style. Options are: InputCursorBlock (default), InputCursorUnderline, InputCursorBar.
func (*TextInput) WithMask ¶
WithMask sets a mask character for password input. When set, all characters are displayed as this character instead of the actual text.
func (*TextInput) WithMaxHeight ¶ added in v0.0.2
WithMaxHeight sets the maximum visible height in lines. When content exceeds this, the input becomes scrollable with overflow indicators.
func (*TextInput) WithMaxLength ¶
WithMaxLength sets the maximum number of runes allowed in the input.
func (*TextInput) WithMultilineMode ¶
WithMultilineMode enables multiline input where Shift+Enter inserts newlines. Newlines are displayed as the NewlineDisplay string (default "↵").
func (*TextInput) WithPastePlaceholderMode ¶
WithPastePlaceholderMode enables/disables paste placeholder mode
func (*TextInput) WithPlaceholder ¶
WithPlaceholder sets the placeholder text shown when input is empty.
func (*TextInput) WithSubmitOnEnter ¶
WithSubmitOnEnter sets whether Enter triggers OnSubmit. Default is true. Set to false if you want Enter to do nothing (useful with MultilineMode).
type TickEvent ¶
TickEvent is emitted periodically based on the runtime's FPS setting. Use this for animations and periodic updates.
The Frame counter increments with each tick, starting from 1. This is useful for frame-based animations that need consistent timing.
Example:
func (a *App) HandleEvent(event Event) []Cmd {
if tick, ok := event.(TickEvent); ok {
a.rotation = (a.rotation + 1) % 360
}
return nil
}
type TreeBranchChars ¶
type TreeBranchChars struct {
Vertical string // │
Corner string // └
Tee string // ├
Horizontal string // ─
}
TreeBranchChars defines the characters used for drawing tree branches.
func ASCIITreeBranchChars ¶
func ASCIITreeBranchChars() TreeBranchChars
ASCIITreeBranchChars returns ASCII tree branch characters.
func DefaultTreeBranchChars ¶
func DefaultTreeBranchChars() TreeBranchChars
DefaultTreeBranchChars returns the default unicode tree branch characters.
type TreeNode ¶
type TreeNode struct {
// Label is the display text for this node.
Label string
// Children contains the child nodes.
Children []*TreeNode
// Expanded indicates whether this node's children are visible.
Expanded bool
// Data holds arbitrary user data associated with this node.
Data any
}
TreeNode represents a node in a tree view.
func NewTreeNode ¶
NewTreeNode creates a new tree node with the given label.
func (*TreeNode) AddChildren ¶
AddChildren adds multiple child nodes.
func (*TreeNode) CollapseAll ¶
func (n *TreeNode) CollapseAll()
CollapseAll collapses this node and all descendants.
func (*TreeNode) ExpandAll ¶
func (n *TreeNode) ExpandAll()
ExpandAll expands this node and all descendants.
func (*TreeNode) SetExpanded ¶
SetExpanded sets the expanded state.
type TypewriterAnimation ¶ added in v0.0.2
type TypewriterAnimation struct {
Speed int // Frames per character reveal
TextColor RGB
CursorColor RGB
Loop bool // Whether to restart after fully revealed
HoldFrames int // Frames to hold before looping (if Loop is true)
}
TypewriterAnimation reveals text character by character with a blinking cursor
func Typewriter ¶ added in v0.0.7
func Typewriter(speed int, textColor, cursorColor RGB) *TypewriterAnimation
Typewriter creates a new typewriter animation that reveals text character by character. Speed controls how fast characters appear (lower = faster).
Example:
Text("Hello, World!").Animate(Typewriter(4, white, green))
Text("Hello, World!").Animate(Typewriter(4, white, green).WithLoop(true))
func (*TypewriterAnimation) GetStyle ¶ added in v0.0.2
func (t *TypewriterAnimation) GetStyle(frame uint64, charIndex int, totalChars int) Style
GetStyle returns the style for a character at a given frame
func (*TypewriterAnimation) WithHoldFrames ¶ added in v0.0.7
func (t *TypewriterAnimation) WithHoldFrames(frames int) *TypewriterAnimation
WithHoldFrames sets how many frames to hold before looping (if Loop is true).
func (*TypewriterAnimation) WithLoop ¶ added in v0.0.7
func (t *TypewriterAnimation) WithLoop(loop bool) *TypewriterAnimation
WithLoop sets whether the animation should restart after fully revealed.
type VBoxLayout ¶
type VBoxLayout struct {
// contains filtered or unexported fields
}
VBoxLayout arranges children vertically in a column, top to bottom. Each child gets its preferred/minimum height, and width fills the container.
func NewVBoxLayout ¶
func NewVBoxLayout(spacing int) *VBoxLayout
NewVBoxLayout creates a new vertical box layout with the specified spacing
func (*VBoxLayout) CalculateMinSize ¶
func (vb *VBoxLayout) CalculateMinSize(children []ComposableWidget) image.Point
CalculateMinSize returns the minimum size needed for all children
func (*VBoxLayout) CalculatePreferredSize ¶
func (vb *VBoxLayout) CalculatePreferredSize(children []ComposableWidget) image.Point
CalculatePreferredSize returns the preferred size for all children
func (*VBoxLayout) Layout ¶
func (vb *VBoxLayout) Layout(containerBounds image.Rectangle, children []ComposableWidget)
Layout positions children vertically within the container bounds
func (*VBoxLayout) LayoutWithConstraints ¶
func (vb *VBoxLayout) LayoutWithConstraints(children []ComposableWidget, constraints SizeConstraints, containerBounds image.Rectangle)
LayoutWithConstraints implements ConstraintLayoutManager.LayoutWithConstraints
func (*VBoxLayout) Measure ¶
func (vb *VBoxLayout) Measure(children []ComposableWidget, constraints SizeConstraints) image.Point
Measure implements ConstraintLayoutManager.Measure
func (*VBoxLayout) WithAlignment ¶
func (vb *VBoxLayout) WithAlignment(align LayoutAlignment) *VBoxLayout
WithAlignment sets the horizontal alignment for children
func (*VBoxLayout) WithDistribute ¶
func (vb *VBoxLayout) WithDistribute(distribute bool) *VBoxLayout
WithDistribute enables distributing extra vertical space among children
type View ¶
type View interface {
// contains filtered or unexported methods
}
View is the core interface for declarative UI. Views form a tree structure where containers measure and position children.
Methods are unexported - users compose views using builder functions like Text(), Stack(), Group(), etc. rather than implementing View directly.
For custom focusable components, use FocusableView() to wrap any view with focus handling capabilities.
func Background ¶
Background wraps a view with a background fill.
func Empty ¶
func Empty() View
Empty returns a view that renders nothing. Useful for conditional rendering.
func FocusableView ¶ added in v0.0.2
func FocusableView(inner View, handler *FocusHandler) View
FocusableView wraps any view to make it participate in focus navigation. The handler defines the focus ID and optional key event handling.
Example:
FocusableView(
myScrollView,
&tui.FocusHandler{
ID: "content-viewer",
OnKey: func(e tui.KeyEvent) bool {
if e.Key == tui.KeyArrowDown { scrollY++; return true }
return false
},
},
)
func Height ¶
Height wraps a view with a fixed height in rows. The view will be exactly this height, clipping or padding as needed.
Example:
Height(10, content) // Exactly 10 rows tall
func If ¶
If returns the view if condition is true, otherwise returns Empty. Use this for conditional rendering in declarative UI.
Example:
Stack(
Text("Always shown"),
If(app.showWarning, Text("Warning!").Fg(ColorYellow)),
)
func IfElse ¶
IfElse returns thenView if condition is true, otherwise returns elseView. Use this for conditional rendering with an alternative.
Example:
IfElse(app.isLoggedIn,
Text("Welcome back!"),
Text("Please log in"),
)
func MaxHeight ¶
MaxHeight wraps a view with a maximum height constraint. The view can be smaller but will not exceed this height.
Example:
MaxHeight(20, content) // Won't exceed 20 rows
func MaxWidth ¶
MaxWidth wraps a view with a maximum width constraint. The view can be smaller but will not exceed this width.
Example:
MaxWidth(80, Text("Long text...")) // Won't exceed 80 cells
func MinHeight ¶ added in v0.0.7
MinHeight wraps a view with a minimum height constraint. The view can be larger but will not be smaller than this height.
Example:
MinHeight(10, content) // At least 10 rows tall
func MinSize ¶ added in v0.0.7
MinSize wraps a view with minimum width and height constraints.
Example:
MinSize(40, 10, content) // At least 40x10 cells
func MinWidth ¶ added in v0.0.7
MinWidth wraps a view with a minimum width constraint. The view can be larger but will not be smaller than this width.
Example:
MinWidth(40, content) // At least 40 cells wide
func Padding ¶
Padding wraps a view with equal padding on all sides. Padding adds empty space around content, measured in character cells.
Example:
Padding(2, Text("Content")) // 2 cells of padding on all sides
Example ¶
ExamplePadding demonstrates adding space around views.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
content := tui.Text("Padded content")
// Equal padding on all sides
_ = tui.Padding(2, content)
// Different horizontal and vertical padding
_ = tui.PaddingHV(4, 1, content)
// Specific padding on each side
_ = tui.PaddingLTRB(1, 2, 3, 4, content)
}
func PaddingHV ¶
PaddingHV wraps a view with horizontal and vertical padding. The first parameter is horizontal (left and right), the second is vertical (top and bottom).
Example:
PaddingHV(4, 1, Text("Content")) // 4 cells horizontal, 1 cell vertical
func PaddingLTRB ¶
PaddingLTRB wraps a view with specific padding on each side. Parameters are in CSS order: left, top, right, bottom.
Example:
PaddingLTRB(1, 2, 3, 4, Text("Content")) // Different padding on each side
func Size ¶
Size wraps a view with fixed width and height. Combines Width and Height into a single modifier.
Example:
Size(80, 24, content) // Exactly 80x24 cells
func Switch ¶
func Switch[T comparable](value T, cases ...CaseView[T]) View
Switch returns the view associated with the matching case value. If no case matches and no Default is provided, returns Empty.
Example:
Switch(app.status,
Case("loading", Text("Loading...").Fg(ColorYellow)),
Case("error", Text("Error!").Fg(ColorRed)),
Case("ready", Text("Ready").Fg(ColorGreen)),
Default[string](Text("Unknown")),
)
func Width ¶
Width wraps a view with a fixed width in character cells. The view will be exactly this width, clipping or padding as needed.
Example:
Width(40, Text("This text will be exactly 40 cells wide"))
Example ¶
ExampleWidth demonstrates size constraints.
package main
import (
"github.com/deepnoodle-ai/wonton/tui"
)
func main() {
content := tui.Text("This is some text content")
// Fixed width
_ = tui.Width(40, content)
// Maximum width (can be smaller)
_ = tui.MaxWidth(80, content)
// Fixed width and height
_ = tui.Size(40, 10, content)
}
type ViewProvider
deprecated
type ViewProvider = Application
ViewProvider is an alias for Application for backward compatibility.
Deprecated: Use Application directly instead.
type WaveAnimation ¶
WaveAnimation creates a wave-like color effect that flows across text
func Wave ¶ added in v0.0.7
func Wave(speed int, colors ...RGB) *WaveAnimation
Wave creates a new wave animation with the specified speed and colors. Speed controls how fast the wave moves (lower = faster). Colors are the colors to cycle through; defaults to magenta/green/purple if none provided.
Example:
Text("Hello").Animate(Wave(5))
Text("Hello").Animate(Wave(5, NewRGB(255, 0, 0), NewRGB(0, 0, 255)))
func (*WaveAnimation) GetStyle ¶
func (w *WaveAnimation) GetStyle(frame uint64, charIndex int, totalChars int) Style
GetStyle returns the style for a character at a given frame
func (*WaveAnimation) WithAmplitude ¶ added in v0.0.7
func (w *WaveAnimation) WithAmplitude(amplitude float64) *WaveAnimation
WithAmplitude sets the wave amplitude.
type WaveBorderAnimation ¶ added in v0.0.2
type WaveBorderAnimation struct {
Speed int
Colors []RGB
WaveWidth int // Width of the color wave in characters
}
WaveBorderAnimation creates a wave that travels around the border.
func (*WaveBorderAnimation) GetBorderStyle ¶ added in v0.0.2
func (w *WaveBorderAnimation) GetBorderStyle(frame uint64, part BorderPart, position int, length int) Style
GetBorderStyle returns the style for a border position at a given frame.
type Widget ¶
type Widget interface {
Draw(frame RenderFrame)
HandleKey(event KeyEvent) bool
}
Widget represents a UI widget that can be rendered and handle input.
Source Files
¶
- animated_text_view.go
- animated_widgets.go
- animation_builders.go
- animation_coordinator.go
- animation_easing.go
- animation_timing.go
- animation_views.go
- application.go
- base_widget.go
- border_animations.go
- bordered_view.go
- button_view.go
- canvas_view.go
- code_view.go
- collection_views.go
- commands.go
- conditional_views.go
- context.go
- cursor.go
- debug_view.go
- diff_renderer.go
- diff_types.go
- diff_view.go
- divider_view.go
- doc.go
- events.go
- file_picker_view.go
- fill_view.go
- flex_layout.go
- focus.go
- focus_text_view.go
- fuzzy.go
- grid_view.go
- group.go
- hyperlink_view.go
- inline_app.go
- inline_app_unix.go
- inline_input.go
- inline_link_view.go
- input.go
- input_field.go
- input_view.go
- key_value_view.go
- layout.go
- layout_managers.go
- layout_params.go
- link_list_view.go
- link_row_view.go
- list.go
- list_view.go
- markdown.go
- markdown_view.go
- modifiers.go
- mouse.go
- padding_view.go
- panel_view.go
- password_input.go
- playback.go
- print.go
- progress_bar.go
- progress_view.go
- prompt_choice_view.go
- run.go
- runtime.go
- scroll_view.go
- select_list_view.go
- size_constraints.go
- size_view.go
- spinner.go
- stack.go
- style.go
- styled_button_view.go
- table_view.go
- text.go
- text_animations.go
- text_area.go
- text_input.go
- text_view.go
- toggle_view.go
- tree_view.go
- view.go
- widget.go
- zstack.go
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
reviewtests
command
reviewtests displays golden test code alongside their snapshots for LLM review.
|
reviewtests displays golden test code alongside their snapshots for LLM review. |