Documentation
¶
Overview ¶
Package blit is a pragmatic TUI toolkit for shipping Go CLI tools fast.
It wraps Bubble Tea and Lip Gloss with reusable components (Table, ListView, Tabs, Picker, Form, Tree, LogViewer), a layout engine (DualPane, HBox, VBox, Split), a keybinding registry with auto-generated help, a dark/light theme system with hot-reload, and built-in binary self-update.
All bubbletea and lipgloss types are re-exported so consumers only need to import blit: Msg, Cmd, KeyMsg, Color, Style, NewStyle, JoinVertical, etc.
Quick start:
app := blit.NewApp(
blit.WithTheme(blit.DefaultTheme()),
blit.WithComponent("main", myTable),
blit.WithHelp(),
)
app.Run()
See https://blitui.github.io/blit/ for guides and examples.
Package blit provides TUI components and update utilities.
Cosign signature verification — implementation notes:
We deliberately avoid the full sigstore/cosign library (github.com/sigstore/cosign) because it pulls in hundreds of transitive dependencies (OCI registry clients, Fulcio/Rekor TLS stacks, OIDC flows) that would bloat every consumer binary.
Instead we implement the narrow subset that covers the common offline case: a detached ed25519 signature over the raw asset bytes, stored as a <asset>.sig release attachment and signed with `cosign sign-blob --key <ed25519.key>`. The corresponding public key (PEM or bare base64) is embedded in UpdateConfig.
If CosignPublicKey is empty the verification step is skipped entirely, keeping the feature strictly opt-in and zero-cost for existing consumers.
Index ¶
- Constants
- Variables
- func ApplyDeltaPatch(exePath string, patch []byte) ([]byte, error)
- func Badge(text string, fg lipgloss.Color, bold bool) string
- func CleanupOldBinary()
- func ClearSkippedVersions(cfg UpdateConfig) error
- func Consumed() tea.Cmd
- func Contrast(bg, fg lipgloss.Color) float64
- func CopyToClipboardCmd(text string) tea.Cmd
- func CopyToClipboardWithNotify(text string) tea.Cmd
- func DefaultConfigPath(appName string) (string, error)
- func DevConsoleToggleCmd() tea.Cmd
- func Divider(width int, theme Theme) string
- func EaseInCubic(t float64) float64
- func EaseInOut(t float64) float64
- func EaseOutCubic(t float64) float64
- func EaseOutExpo(t float64) float64
- func EnsureConfigDir(appName string) (string, error)
- func ExtractBinary(archive []byte, binaryName, format string) ([]byte, error)
- func GitHubAPIURL(endpoint string, perPage, page int) string
- func HealthDot(label string, ok bool, theme Theme) string
- func HealthDotUnknown(label string, theme Theme) string
- func Hyperlink(url, text string) string
- func Interpolate[T any](from, to T, t float64, e Ease) T
- func IsBackspace(msg Msg) bool
- func IsEnter(msg Msg) bool
- func IsEscape(msg Msg) bool
- func IsKey(msg Msg, key string) bool
- func IsRateLimited(err error) bool
- func IsRunes(msg Msg) bool
- func IsTab(msg Msg) bool
- func IsVersionSkipped(cfg UpdateConfig, v string) bool
- func KeyString(msg Msg) string
- func Linear(t float64) float64
- func LoadYAML(path string, dst any) error
- func LogAppendCmd(line LogLine) tea.Cmd
- func LogRedact(v any) slog.LogValuer
- func Markdown(md string, theme Theme) string
- func NotifyCmd(text string, duration time.Duration) tea.Cmd
- func OSC8Link(url, text string) string
- func OpenURL(url string)
- func ParseJSONObject[T any]() func(body []byte) (any, error)
- func ParseJSONSlice[T any]() func(body []byte) (any, error)
- func Presets() map[string]Theme
- func Register(name string, t Theme)
- func RelativeTime(t time.Time, now time.Time) string
- func RenderGradient(text string, g Gradient) string
- func RetryCmd(fn func() (tea.Msg, error), opts RetryOpts) tea.Cmd
- func Runes(msg Msg) []rune
- func SaveYAML(path string, src any) error
- func SelfUpdate(cfg UpdateConfig) error
- func SelfUpdateRollback() error
- func Serve(ctx context.Context, cfg ServeConfig) error
- func SetThemeCmd(t Theme) func() tea.Msg
- func SkipVersion(cfg UpdateConfig, v string) error
- func Sparkline(data []float64, maxWidth int, opts *SparklineOpts) (string, int)
- func ToastCmd(severity ToastSeverity, title, body string, duration time.Duration, ...) tea.Cmd
- func ToastError(title, body string) tea.Cmd
- func ToastInfo(title, body string) tea.Cmd
- func ToastSuccess(title, body string) tea.Cmd
- func ToastWarn(title, body string) tea.Cmd
- func Truncate(s string, maxWidth int) string
- func ValidateConfig(cfg UpdateConfig) error
- func VerifyChecksum(data []byte, assetName string, checksumFile []byte) error
- func VerifyCosignSignature(assetData []byte, sigData []byte, pubKeyPEM string) error
- func VerifyInstalled(expectedTag string) error
- func WriteCache(path string, cache UpdateCache) error
- type Accordion
- func (a *Accordion) CursorIndex() int
- func (a *Accordion) Focused() bool
- func (a *Accordion) Init() tea.Cmd
- func (a *Accordion) KeyBindings() []KeyBind
- func (a *Accordion) Sections() []AccordionSection
- func (a *Accordion) SetFocused(f bool)
- func (a *Accordion) SetSize(w, h int)
- func (a *Accordion) SetTheme(theme Theme)
- func (a *Accordion) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (a *Accordion) View() string
- type AccordionOpts
- type AccordionSection
- type Activatable
- type Alignment
- type AnySignal
- type App
- func (a *App) AddKeyBind(kb KeyBind)
- func (a *App) Done() <-chan struct{}
- func (a *App) Model() tea.Model
- func (a *App) Notify(msg string, duration time.Duration)
- func (a *App) Run() (UpdateAction, error)
- func (a *App) Send(msg tea.Msg)
- func (a *App) ToastError(title, body string)
- func (a *App) ToastInfo(title, body string)
- func (a *App) ToastSuccess(title, body string)
- func (a *App) ToastWarn(title, body string)
- type BackoffStrategy
- type Border
- type BorderSet
- type Breadcrumb
- func (b *Breadcrumb) CursorIndex() int
- func (b *Breadcrumb) Focused() bool
- func (b *Breadcrumb) Init() tea.Cmd
- func (b *Breadcrumb) Items() []BreadcrumbItem
- func (b *Breadcrumb) KeyBindings() []KeyBind
- func (b *Breadcrumb) Pop() BreadcrumbItem
- func (b *Breadcrumb) Push(item BreadcrumbItem)
- func (b *Breadcrumb) SetFocused(f bool)
- func (b *Breadcrumb) SetItems(items []BreadcrumbItem)
- func (b *Breadcrumb) SetSize(w, h int)
- func (b *Breadcrumb) SetTheme(theme Theme)
- func (b *Breadcrumb) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (b *Breadcrumb) View() string
- type BreadcrumbItem
- type BreadcrumbOpts
- type Breadcrumbs
- func (b *Breadcrumbs) Focused() bool
- func (b *Breadcrumbs) Init() tea.Cmd
- func (b *Breadcrumbs) KeyBindings() []KeyBind
- func (b *Breadcrumbs) SetFocused(f bool)
- func (b *Breadcrumbs) SetSize(w, h int)
- func (b *Breadcrumbs) SetTheme(th Theme)
- func (b *Breadcrumbs) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (b *Breadcrumbs) View() string
- type CLIApp
- type CLIAppOpts
- type CLICommand
- type CellRenderer
- type ChartPanel
- func (c *ChartPanel) ActiveIndex() int
- func (c *ChartPanel) Focused() bool
- func (c *ChartPanel) Init() tea.Cmd
- func (c *ChartPanel) KeyBindings() []KeyBind
- func (c *ChartPanel) SetActive(idx int)
- func (c *ChartPanel) SetFocused(f bool)
- func (c *ChartPanel) SetSize(w, h int)
- func (c *ChartPanel) SetTheme(theme Theme)
- func (c *ChartPanel) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (c *ChartPanel) View() string
- type ChartPanelOpts
- type Clock
- type Cmd
- type CollapsibleSection
- func (s *CollapsibleSection) Focused() bool
- func (s *CollapsibleSection) Init() Cmd
- func (s *CollapsibleSection) KeyBindings() []KeyBind
- func (s *CollapsibleSection) Render(theme Theme, contentFunc func() string) string
- func (s *CollapsibleSection) SetFocused(f bool)
- func (s *CollapsibleSection) SetSize(w, h int)
- func (s *CollapsibleSection) SetTheme(t Theme)
- func (s *CollapsibleSection) Toggle()
- func (s *CollapsibleSection) Update(msg Msg, ctx Context) (Component, Cmd)
- func (s *CollapsibleSection) View() string
- type Color
- type Column
- type Command
- type CommandBar
- func (c *CommandBar) Close()
- func (c *CommandBar) Focused() bool
- func (c *CommandBar) Init() tea.Cmd
- func (c *CommandBar) Inline() bool
- func (c *CommandBar) IsActive() bool
- func (c *CommandBar) KeyBindings() []KeyBind
- func (c *CommandBar) SetActive(v bool)
- func (c *CommandBar) SetFocused(f bool)
- func (c *CommandBar) SetSize(w, h int)
- func (c *CommandBar) SetTheme(t Theme)
- func (c *CommandBar) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (c *CommandBar) View() string
- type Component
- type ComponentHeader
- type Config
- func (c *Config[T]) AsSignal() *Signal[T]
- func (c *Config[T]) CLICommands() map[string]CLICommand
- func (c *Config[T]) Defaults() T
- func (c *Config[T]) Editor() *ConfigEditor
- func (c *Config[T]) IsDirty() bool
- func (c *Config[T]) Path() string
- func (c *Config[T]) Reset() error
- func (c *Config[T]) Save() error
- func (c *Config[T]) SetValue(fn func(*T)) error
- func (c *Config[T]) WatchFile(ctx context.Context, onChange func(T)) error
- type ConfigEditor
- func (c *ConfigEditor) Close()
- func (c *ConfigEditor) Focused() bool
- func (c *ConfigEditor) Init() tea.Cmd
- func (c *ConfigEditor) IsActive() bool
- func (c *ConfigEditor) KeyBindings() []KeyBind
- func (c *ConfigEditor) SetFocused(f bool)
- func (c *ConfigEditor) SetSize(w, h int)
- func (c *ConfigEditor) SetTheme(t Theme)
- func (c *ConfigEditor) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (c *ConfigEditor) View() string
- type ConfigField
- type ConfigOption
- type ConfirmField
- func (f *ConfirmField) FieldID() string
- func (f *ConfirmField) Init() tea.Cmd
- func (f *ConfirmField) Label() string
- func (f *ConfirmField) SetFocused(_ bool)
- func (f *ConfirmField) SetValue(v string)
- func (f *ConfirmField) Update(msg tea.Msg) tea.Cmd
- func (f *ConfirmField) Validate() error
- func (f *ConfirmField) Value() string
- func (f *ConfirmField) View(focused bool, theme Theme, _ int) string
- func (f *ConfirmField) WithDefault(v bool) *ConfirmField
- func (f *ConfirmField) WithHint(hint string) *ConfirmField
- type Context
- type CopyToClipboardMsg
- type CursorChangeHandler
- type CursorStyle
- type DebugDataProvider
- type DebugProvider
- type DebugProviderWithLifecycle
- type DetailOverlay
- func (d *DetailOverlay[T]) Close()
- func (d *DetailOverlay[T]) Focused() bool
- func (d *DetailOverlay[T]) Init() tea.Cmd
- func (d *DetailOverlay[T]) IsActive() bool
- func (d *DetailOverlay[T]) Item() T
- func (d *DetailOverlay[T]) KeyBindings() []KeyBind
- func (d *DetailOverlay[T]) SetActive(v bool)
- func (d *DetailOverlay[T]) SetFocused(f bool)
- func (d *DetailOverlay[T]) SetSize(w, h int)
- func (d *DetailOverlay[T]) SetTheme(t Theme)
- func (d *DetailOverlay[T]) Show(item T)
- func (d *DetailOverlay[T]) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (d *DetailOverlay[T]) View() string
- type DetailOverlayOpts
- type DetailRenderer
- type Dialog
- func (d *Dialog) Close()
- func (d *Dialog) CursorIndex() int
- func (d *Dialog) Focused() bool
- func (d *Dialog) Init() tea.Cmd
- func (d *Dialog) IsActive() bool
- func (d *Dialog) KeyBindings() []KeyBind
- func (d *Dialog) SetFocused(f bool)
- func (d *Dialog) SetSize(w, h int)
- func (d *Dialog) SetTheme(theme Theme)
- func (d *Dialog) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (d *Dialog) View() string
- type DialogButton
- type DialogOpts
- type DualPane
- type Ease
- type FeatureFlag
- type Field
- type FilePicker
- func (fp *FilePicker) Focused() bool
- func (fp *FilePicker) Init() tea.Cmd
- func (fp *FilePicker) KeyBindings() []KeyBind
- func (fp *FilePicker) SetFocused(f bool)
- func (fp *FilePicker) SetSize(w, h int)
- func (fp *FilePicker) SetTheme(t Theme)
- func (fp *FilePicker) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (fp *FilePicker) View() string
- type FilePickerOpts
- type FilterFunc
- type FlagDef
- type Flex
- type FlexAlign
- type FlexJustify
- type FloatingOverlay
- type Focus
- type ForcedChoice
- type ForcedUpdateScreen
- type Form
- func (f *Form) Focused() bool
- func (f *Form) Init() tea.Cmd
- func (f *Form) KeyBindings() []KeyBind
- func (f *Form) Reset()
- func (f *Form) SetFocused(focused bool)
- func (f *Form) SetSize(width, height int)
- func (f *Form) SetTheme(th Theme)
- func (f *Form) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (f *Form) Values() map[string]string
- func (f *Form) View() string
- type FormGroup
- type FormOpts
- type FormSubmitMsg
- type Glyphs
- type Gradient
- type HBox
- func (h *HBox) Focused() bool
- func (h *HBox) Init() tea.Cmd
- func (h *HBox) KeyBindings() []KeyBind
- func (h *HBox) SetFocused(focused bool)
- func (h *HBox) SetSize(width, height int)
- func (h *HBox) SetTheme(th Theme)
- func (h *HBox) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (h *HBox) View() string
- type HTTPResource
- type HTTPResourceOpts
- type HTTPResultMsg
- type HeaderStatusPart
- type Help
- func (h *Help) Close()
- func (h *Help) Focused() bool
- func (h *Help) Init() tea.Cmd
- func (h *Help) IsActive() bool
- func (h *Help) KeyBindings() []KeyBind
- func (h *Help) SetFocused(f bool)
- func (h *Help) SetSize(w, ht int)
- func (h *Help) SetTheme(t Theme)
- func (h *Help) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (h *Help) View() string
- type InlineOverlay
- type InputCapture
- type InstallMethod
- type Kanban
- func (k *Kanban) ActiveCard() int
- func (k *Kanban) ActiveColumn() int
- func (k *Kanban) Columns() []KanbanColumn
- func (k *Kanban) Focused() bool
- func (k *Kanban) Init() tea.Cmd
- func (k *Kanban) KeyBindings() []KeyBind
- func (k *Kanban) SetFocused(f bool)
- func (k *Kanban) SetSize(w, h int)
- func (k *Kanban) SetTheme(theme Theme)
- func (k *Kanban) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (k *Kanban) View() string
- type KanbanCard
- type KanbanColumn
- type KanbanOpts
- type Key
- type KeyBind
- type KeyGroup
- type KeyMsg
- type KeyType
- type Layout
- type ListView
- func (l *ListView[T]) CursorIndex() int
- func (l *ListView[T]) CursorItem() *T
- func (l *ListView[T]) Focused() bool
- func (l *ListView[T]) HandleKey(msg tea.KeyMsg) tea.Cmd
- func (l *ListView[T]) Init() tea.Cmd
- func (l *ListView[T]) IsAtBottom() bool
- func (l *ListView[T]) IsAtTop() bool
- func (l *ListView[T]) ItemCount() int
- func (l *ListView[T]) Items() []T
- func (l *ListView[T]) KeyBindings() []KeyBind
- func (l *ListView[T]) Refresh()
- func (l *ListView[T]) ScrollToBottom()
- func (l *ListView[T]) ScrollToTop()
- func (l *ListView[T]) SetCursor(idx int)
- func (l *ListView[T]) SetFocused(f bool)
- func (l *ListView[T]) SetItems(items []T)
- func (l *ListView[T]) SetSize(w, h int)
- func (l *ListView[T]) SetTheme(th Theme)
- func (l *ListView[T]) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (l *ListView[T]) View() string
- type ListViewOpts
- type LogAppendMsg
- type LogLevel
- type LogLine
- type LogViewer
- func (lv *LogViewer) Append(line LogLine)
- func (lv *LogViewer) Clear()
- func (lv *LogViewer) Focused() bool
- func (lv *LogViewer) Init() tea.Cmd
- func (lv *LogViewer) KeyBindings() []KeyBind
- func (lv *LogViewer) Lines() []LogLine
- func (lv *LogViewer) SetFocused(f bool)
- func (lv *LogViewer) SetSize(w, h int)
- func (lv *LogViewer) SetTheme(th Theme)
- func (lv *LogViewer) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (lv *LogViewer) View() string
- type LoggingMetrics
- type Menu
- func (m *Menu) Close()
- func (m *Menu) CursorIndex() int
- func (m *Menu) Focused() bool
- func (m *Menu) Init() tea.Cmd
- func (m *Menu) IsActive() bool
- func (m *Menu) KeyBindings() []KeyBind
- func (m *Menu) SetFocused(f bool)
- func (m *Menu) SetSize(w, h int)
- func (m *Menu) SetTheme(theme Theme)
- func (m *Menu) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (m *Menu) View() string
- type MenuItem
- type MenuOpts
- type MetricsCollector
- type Module
- type ModuleWithKeybinds
- type ModuleWithProviders
- type MouseMsg
- type Msg
- type MultiSelectField
- func (f *MultiSelectField) FieldID() string
- func (f *MultiSelectField) Init() tea.Cmd
- func (f *MultiSelectField) Label() string
- func (f *MultiSelectField) SetFocused(_ bool)
- func (f *MultiSelectField) SetValue(v string)
- func (f *MultiSelectField) Update(msg tea.Msg) tea.Cmd
- func (f *MultiSelectField) Validate() error
- func (f *MultiSelectField) Value() string
- func (f *MultiSelectField) View(focused bool, theme Theme, _ int) string
- func (f *MultiSelectField) WithHint(hint string) *MultiSelectField
- func (f *MultiSelectField) WithRequired() *MultiSelectField
- type Node
- type NodeRenderFunc
- type NotifyMsg
- type NumberField
- func (f *NumberField) FieldID() string
- func (f *NumberField) Init() tea.Cmd
- func (f *NumberField) Label() string
- func (f *NumberField) SetFocused(focused bool)
- func (f *NumberField) SetValue(v string)
- func (f *NumberField) Update(msg tea.Msg) tea.Cmd
- func (f *NumberField) Validate() error
- func (f *NumberField) Value() string
- func (f *NumberField) View(focused bool, theme Theme, width int) string
- func (f *NumberField) WithDefault(v float64) *NumberField
- func (f *NumberField) WithHint(hint string) *NumberField
- func (f *NumberField) WithMax(max float64) *NumberField
- func (f *NumberField) WithMin(min float64) *NumberField
- func (f *NumberField) WithPlaceholder(p string) *NumberField
- func (f *NumberField) WithRequired() *NumberField
- type Option
- func WithAnimations(enabled bool) Option
- func WithAutoUpdate(cfg UpdateConfig) Option
- func WithClock(c Clock) Option
- func WithComponent(name string, c Component) Option
- func WithDebugProvider(p DebugProvider) Option
- func WithDevConsole() Option
- func WithFeatureFlags(ff *FeatureFlag) Option
- func WithFocusCycleKey(key string) Option
- func WithHelp() Option
- func WithKeyBind(kb KeyBind) Option
- func WithLayout(l *DualPane) Option
- func WithLogger(l *slog.Logger) Option
- func WithMetrics(collector MetricsCollector) Option
- func WithModule(m Module) Option
- func WithMouseSupport() Option
- func WithOnError(fn func(component string, recovered any)) Option
- func WithOverlay(name string, triggerKey string, o Overlay) Option
- func WithSlot(name SlotName, c Component) Option
- func WithSlotOverlay(name, triggerKey string, o Overlay) Option
- func WithStatusBar(left, right func() string) Option
- func WithStatusBarSignal(left, right *Signal[string]) Option
- func WithTheme(t Theme) Option
- func WithThemeHotReload(path string) Option
- func WithTickInterval(d time.Duration) Option
- type Orientation
- type Overlay
- type PasswordField
- func (f *PasswordField) FieldID() string
- func (f *PasswordField) Init() tea.Cmd
- func (f *PasswordField) Label() string
- func (f *PasswordField) SetFocused(focused bool)
- func (f *PasswordField) SetValue(v string)
- func (f *PasswordField) Update(msg tea.Msg) tea.Cmd
- func (f *PasswordField) Validate() error
- func (f *PasswordField) Value() string
- func (f *PasswordField) View(focused bool, theme Theme, width int) string
- func (f *PasswordField) WithHint(hint string) *PasswordField
- func (f *PasswordField) WithPlaceholder(p string) *PasswordField
- func (f *PasswordField) WithRequired() *PasswordField
- func (f *PasswordField) WithValidator(v Validator) *PasswordField
- type Picker
- func (p *Picker) Close()
- func (p *Picker) CursorItem() *PickerItem
- func (p *Picker) Focused() bool
- func (p *Picker) Init() tea.Cmd
- func (p *Picker) IsActive() bool
- func (p *Picker) Items() []PickerItem
- func (p *Picker) KeyBindings() []KeyBind
- func (p *Picker) Open()
- func (p *Picker) SetFocused(f bool)
- func (p *Picker) SetItems(items []PickerItem)
- func (p *Picker) SetSize(w, h int)
- func (p *Picker) SetTheme(t Theme)
- func (p *Picker) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (p *Picker) View() string
- type PickerItem
- type PickerOpts
- type Poller
- func (p *Poller) Check(msg TickMsg) tea.Cmd
- func (p *Poller) ClearRateLimit()
- func (p *Poller) DebugProvider() DebugDataProvider
- func (p *Poller) ForceRefresh()
- func (p *Poller) IsPaused() bool
- func (p *Poller) LastPoll() time.Time
- func (p *Poller) NextPoll() time.Time
- func (p *Poller) Pause()
- func (p *Poller) Resume()
- func (p *Poller) SetInterval(d time.Duration)
- func (p *Poller) SetRateLimited(resetAt time.Time)
- func (p *Poller) Stats() PollerStats
- func (p *Poller) Stop()
- func (p *Poller) TogglePause()
- type PollerErrorMsg
- type PollerOpts
- type PollerRateLimitedMsg
- type PollerStartMsg
- type PollerStats
- type PollerSuccessMsg
- type Position
- type ProgressBar
- func (p *ProgressBar) Focused() bool
- func (p *ProgressBar) Increment(delta float64)
- func (p *ProgressBar) Init() tea.Cmd
- func (p *ProgressBar) KeyBindings() []KeyBind
- func (p *ProgressBar) SetFocused(f bool)
- func (p *ProgressBar) SetSize(w, h int)
- func (p *ProgressBar) SetTheme(theme Theme)
- func (p *ProgressBar) SetValue(v float64)
- func (p *ProgressBar) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (p *ProgressBar) Value() float64
- func (p *ProgressBar) View() string
- type ProgressBarOpts
- type ProgressFunc
- type RateLimitError
- type RateLimitInfo
- type Registry
- type Release
- type ReleaseAsset
- func MatchAsset(assets []ReleaseAsset, binaryName, goos, goarch string) (ReleaseAsset, error)
- func MatchChecksumAsset(assets []ReleaseAsset) (ReleaseAsset, error)
- func MatchDeltaAsset(assets []ReleaseAsset, binaryName, fromVersion, toVersion, goos, goarch string) (ReleaseAsset, error)
- func MatchSigAsset(assets []ReleaseAsset, assetName string) (ReleaseAsset, error)
- type ReleaseNotesOverlay
- func (o *ReleaseNotesOverlay) Init() tea.Cmd
- func (o *ReleaseNotesOverlay) MaxOffset() int
- func (o *ReleaseNotesOverlay) SetTheme(t Theme)
- func (o *ReleaseNotesOverlay) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (o *ReleaseNotesOverlay) View() string
- func (o *ReleaseNotesOverlay) VisibleLines() int
- type RetryErrorMsg
- type RetryOpts
- type Row
- type RowClickHandler
- type RowStyler
- type SelectField
- func (f *SelectField) FieldID() string
- func (f *SelectField) Init() tea.Cmd
- func (f *SelectField) Label() string
- func (f *SelectField) SetFocused(_ bool)
- func (f *SelectField) SetValue(v string)
- func (f *SelectField) Update(msg tea.Msg) tea.Cmd
- func (f *SelectField) Validate() error
- func (f *SelectField) Value() string
- func (f *SelectField) View(focused bool, theme Theme, _ int) string
- func (f *SelectField) WithDefault(v string) *SelectField
- func (f *SelectField) WithHint(hint string) *SelectField
- func (f *SelectField) WithRequired() *SelectField
- func (f *SelectField) WithValidator(v Validator) *SelectField
- type SelectionMode
- type ServeConfig
- type SetThemeMsg
- type Signal
- type Size
- type Sized
- type SlotName
- type SortFunc
- type SourceHealth
- type SparklineOpts
- type Spinner
- func (s *Spinner) Active() bool
- func (s *Spinner) Focused() bool
- func (s *Spinner) Frame() int
- func (s *Spinner) Init() tea.Cmd
- func (s *Spinner) KeyBindings() []KeyBind
- func (s *Spinner) Label() string
- func (s *Spinner) SetActive(active bool)
- func (s *Spinner) SetFocused(f bool)
- func (s *Spinner) SetLabel(label string)
- func (s *Spinner) SetSize(w, h int)
- func (s *Spinner) SetTheme(theme Theme)
- func (s *Spinner) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (s *Spinner) View() string
- type SpinnerOpts
- type Split
- func (s *Split) Focused() bool
- func (s *Split) Init() tea.Cmd
- func (s *Split) KeyBindings() []KeyBind
- func (s *Split) SetFocused(f bool)
- func (s *Split) SetSize(w, h int)
- func (s *Split) SetTheme(th Theme)
- func (s *Split) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (s *Split) View() string
- type StatsCollector
- func (s *StatsCollector) Data() map[string]any
- func (s *StatsCollector) DebugProvider() DebugDataProvider
- func (s *StatsCollector) Name() string
- func (s *StatsCollector) RecordCached(source string, count int)
- func (s *StatsCollector) RecordFailure(source string, _ error)
- func (s *StatsCollector) RecordSuccess(source string, count int)
- func (s *StatsCollector) SetRateLimit(remaining, limit int)
- func (s *StatsCollector) Snapshot() StatsSnapshot
- func (s *StatsCollector) View(width, height int, theme Theme) string
- type StatsSnapshot
- type StatusBar
- func (s *StatusBar) Focused() bool
- func (s *StatusBar) Init() tea.Cmd
- func (s *StatusBar) KeyBindings() []KeyBind
- func (s *StatusBar) SetFocused(f bool)
- func (s *StatusBar) SetSize(w, h int)
- func (s *StatusBar) SetTheme(t Theme)
- func (s *StatusBar) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (s *StatusBar) View() string
- type StatusBarOpts
- type Step
- type StepStatus
- type Stepper
- func (s *Stepper) Current() int
- func (s *Stepper) Focused() bool
- func (s *Stepper) Init() tea.Cmd
- func (s *Stepper) KeyBindings() []KeyBind
- func (s *Stepper) Next()
- func (s *Stepper) Prev()
- func (s *Stepper) SetCurrent(idx int)
- func (s *Stepper) SetFocused(f bool)
- func (s *Stepper) SetSize(w, h int)
- func (s *Stepper) SetTheme(theme Theme)
- func (s *Stepper) Status(idx int) StepStatus
- func (s *Stepper) Steps() []Step
- func (s *Stepper) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (s *Stepper) View() string
- type StepperOpts
- type StringSource
- type Style
- type StyleSet
- type Styles
- type Subcommand
- type TabItem
- type Table
- func (t *Table) CapturesInput() bool
- func (t *Table) CursorIndex() int
- func (t *Table) CursorRow() Row
- func (t *Table) FilterQuery() string
- func (t *Table) Focused() bool
- func (t *Table) Init() tea.Cmd
- func (t *Table) KeyBindings() []KeyBind
- func (t *Table) RowCount() int
- func (t *Table) SetCursor(idx int)
- func (t *Table) SetFilter(fn FilterFunc)
- func (t *Table) SetFocused(f bool)
- func (t *Table) SetRows(rows []Row)
- func (t *Table) SetSize(w, h int)
- func (t *Table) SetSort(col int, asc bool)
- func (t *Table) SetTheme(th Theme)
- func (t *Table) SortAsc() bool
- func (t *Table) SortCol() int
- func (t *Table) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (t *Table) View() string
- func (t *Table) VisibleRowCount() int
- type TableOpts
- type TableRowProvider
- type TableRowProviderFunc
- type Tabs
- func (t *Tabs) ActiveIndex() int
- func (t *Tabs) Focused() bool
- func (t *Tabs) Init() tea.Cmd
- func (t *Tabs) KeyBindings() []KeyBind
- func (t *Tabs) OnChange(fn func(int))
- func (t *Tabs) SetActive(i int)
- func (t *Tabs) SetFocused(focused bool)
- func (t *Tabs) SetSize(w, h int)
- func (t *Tabs) SetTheme(th Theme)
- func (t *Tabs) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (t *Tabs) View() string
- type TabsOpts
- type TextField
- func (f *TextField) FieldID() string
- func (f *TextField) Init() tea.Cmd
- func (f *TextField) Label() string
- func (f *TextField) SetFocused(focused bool)
- func (f *TextField) SetValue(v string)
- func (f *TextField) Update(msg tea.Msg) tea.Cmd
- func (f *TextField) Validate() error
- func (f *TextField) Value() string
- func (f *TextField) View(focused bool, theme Theme, width int) string
- func (f *TextField) WithDefault(v string) *TextField
- func (f *TextField) WithHint(hint string) *TextField
- func (f *TextField) WithPlaceholder(p string) *TextField
- func (f *TextField) WithRequired() *TextField
- func (f *TextField) WithValidator(v Validator) *TextField
- type Theme
- func CatppuccinMochaTheme() Theme
- func DefaultTheme() Theme
- func DraculaTheme() Theme
- func EverforestTheme() Theme
- func FromAlacritty(data []byte) (Theme, error)
- func FromGogh(data []byte) (Theme, error)
- func FromIterm2(data []byte) (Theme, error)
- func GruvboxDarkTheme() Theme
- func KanagawaTheme() Theme
- func LightTheme() Theme
- func NightfoxTheme() Theme
- func NordTheme() Theme
- func OneDarkTheme() Theme
- func ParseThemeYAML(data []byte) (Theme, error)
- func RosePineTheme() Theme
- func SolarizedDarkTheme() Theme
- func ThemeFromMap(m map[string]string) Theme
- func TokyoNightTheme() Theme
- type ThemeHotReload
- type ThemeHotReloadErrMsg
- type ThemeHotReloadMsg
- type Themed
- type TickMsg
- type Timeline
- func (t *Timeline) CursorIndex() int
- func (t *Timeline) Events() []TimelineEvent
- func (t *Timeline) Focused() bool
- func (t *Timeline) Init() tea.Cmd
- func (t *Timeline) KeyBindings() []KeyBind
- func (t *Timeline) SetEvents(events []TimelineEvent)
- func (t *Timeline) SetFocused(f bool)
- func (t *Timeline) SetSize(w, h int)
- func (t *Timeline) SetTheme(theme Theme)
- func (t *Timeline) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (t *Timeline) View() string
- type TimelineEvent
- type TimelineOpts
- type ToastAction
- type ToastManagerOpts
- type ToastMsg
- type ToastSeverity
- type Tooltip
- func (t *Tooltip) Close()
- func (t *Tooltip) FloatView(background string) string
- func (t *Tooltip) Focused() bool
- func (t *Tooltip) Init() tea.Cmd
- func (t *Tooltip) Inline() bool
- func (t *Tooltip) IsActive() bool
- func (t *Tooltip) KeyBindings() []KeyBind
- func (t *Tooltip) SetAnchor(x, y int)
- func (t *Tooltip) SetFocused(f bool)
- func (t *Tooltip) SetSize(w, h int)
- func (t *Tooltip) SetText(text string)
- func (t *Tooltip) SetTheme(theme Theme)
- func (t *Tooltip) Show()
- func (t *Tooltip) Text() string
- func (t *Tooltip) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (t *Tooltip) View() string
- type TooltipOpts
- type Tree
- func (t *Tree) ClearFilter()
- func (t *Tree) CursorNode() *Node
- func (t *Tree) DeselectAll()
- func (t *Tree) Filter() string
- func (t *Tree) Focused() bool
- func (t *Tree) Init() tea.Cmd
- func (t *Tree) KeyBindings() []KeyBind
- func (t *Tree) Roots() []*Node
- func (t *Tree) SelectAll()
- func (t *Tree) SelectedNodes() []*Node
- func (t *Tree) SetFilter(query string)
- func (t *Tree) SetFocused(f bool)
- func (t *Tree) SetRoots(roots []*Node)
- func (t *Tree) SetSize(w, h int)
- func (t *Tree) SetTheme(theme Theme)
- func (t *Tree) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (t *Tree) View() string
- type TreeOpts
- type Tween
- type Unsubscribe
- type UpdateAction
- type UpdateCache
- type UpdateConfig
- type UpdateMode
- type UpdateProgress
- type UpdateProgressMsg
- type UpdateResult
- type VBox
- func (v *VBox) Focused() bool
- func (v *VBox) Init() tea.Cmd
- func (v *VBox) KeyBindings() []KeyBind
- func (v *VBox) SetFocused(focused bool)
- func (v *VBox) SetSize(width, height int)
- func (v *VBox) SetTheme(th Theme)
- func (v *VBox) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (v *VBox) View() string
- type Validator
- type Version
- type Viewport
- func (v *Viewport) AtBottom() bool
- func (v *Viewport) AtTop() bool
- func (v *Viewport) Focused() bool
- func (v *Viewport) GotoBottom()
- func (v *Viewport) GotoTop()
- func (v *Viewport) HandleKey(msg tea.KeyMsg) tea.Cmd
- func (v *Viewport) Init() tea.Cmd
- func (v *Viewport) KeyBindings() []KeyBind
- func (v *Viewport) ScrollBy(delta int)
- func (v *Viewport) SetContent(content string)
- func (v *Viewport) SetFocused(f bool)
- func (v *Viewport) SetSize(w, h int)
- func (v *Viewport) SetTheme(th Theme)
- func (v *Viewport) Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
- func (v *Viewport) View() string
- func (v *Viewport) YOffset() int
- type ViewportGlyphs
- type WindowSizeMsg
Examples ¶
Constants ¶
const ( ChannelStable = "stable" ChannelBeta = "beta" ChannelPrerelease = "prerelease" )
Update channels.
const DeltaPatchSuffix = ".bsdiff"
DeltaPatchSuffix is appended to the binary name when building a delta patch asset name. A patch asset is expected to be named:
<binary>_<fromVersion>_to_<toVersion>_<goos>_<goarch>.bsdiff
The <fromVersion> is the version the patch applies against (the caller's current version) and <toVersion> is the version the release publishes.
const EnvDisableUpdate = "BLIT_UPDATE_DISABLE"
EnvDisableUpdate is the environment variable name that, when set to "1", "true", or "yes" (case-insensitive), short-circuits CheckForUpdate and SelfUpdate without making any network calls. Intended as a kill switch for CI, tests, and users who want to disable updates temporarily without changing code.
Variables ¶
var ( KeyUp = tea.KeyUp KeyDown = tea.KeyDown KeyLeft = tea.KeyLeft KeyRight = tea.KeyRight KeyHome = tea.KeyHome KeyEnd = tea.KeyEnd KeyPgUp = tea.KeyPgUp KeyPgDown = tea.KeyPgDown KeyDelete = tea.KeyDelete KeyInsert = tea.KeyInsert KeyBackspace = tea.KeyBackspace KeySpace = tea.KeySpace KeyTab = tea.KeyTab KeyShiftTab = tea.KeyShiftTab KeyEnter = tea.KeyEnter KeyEscape = tea.KeyEscape KeyRunes = tea.KeyRunes )
Arrow and navigation keys.
var ( KeyCtrlA = tea.KeyCtrlA KeyCtrlB = tea.KeyCtrlB KeyCtrlC = tea.KeyCtrlC KeyCtrlD = tea.KeyCtrlD KeyCtrlE = tea.KeyCtrlE KeyCtrlF = tea.KeyCtrlF KeyCtrlG = tea.KeyCtrlG KeyCtrlH = tea.KeyCtrlH KeyCtrlJ = tea.KeyCtrlJ KeyCtrlK = tea.KeyCtrlK KeyCtrlL = tea.KeyCtrlL KeyCtrlN = tea.KeyCtrlN KeyCtrlO = tea.KeyCtrlO KeyCtrlP = tea.KeyCtrlP KeyCtrlQ = tea.KeyCtrlQ KeyCtrlR = tea.KeyCtrlR KeyCtrlS = tea.KeyCtrlS KeyCtrlT = tea.KeyCtrlT KeyCtrlU = tea.KeyCtrlU KeyCtrlV = tea.KeyCtrlV KeyCtrlW = tea.KeyCtrlW KeyCtrlX = tea.KeyCtrlX KeyCtrlY = tea.KeyCtrlY KeyCtrlZ = tea.KeyCtrlZ )
Control keys.
var ( F1 = tea.KeyF1 F2 = tea.KeyF2 F3 = tea.KeyF3 F4 = tea.KeyF4 F5 = tea.KeyF5 F6 = tea.KeyF6 F7 = tea.KeyF7 F8 = tea.KeyF8 F9 = tea.KeyF9 F10 = tea.KeyF10 F11 = tea.KeyF11 F12 = tea.KeyF12 )
Function keys.
var ( KeyCtrlBackslash = tea.KeyCtrlBackslash KeyShiftDown = tea.KeyShiftDown KeyShiftUp = tea.KeyShiftUp KeyShiftLeft = tea.KeyShiftLeft KeyShiftRight = tea.KeyShiftRight )
Special keys.
var ( // Batch performs the given commands simultaneously with no ordering // guarantees about the results. Batch = tea.Batch // Quit is a command that tells the Bubble Tea runtime to exit. Quit = tea.Quit // Sequence runs the given commands one at a time, in order. Sequence = tea.Sequence )
var ( // NewStyle creates a new Style. NewStyle = lipgloss.NewStyle // Width measures the visual width of a string, accounting for ANSI // escape sequences and double-width runes. Width = lipgloss.Width // Height measures the visual height of a string (number of newlines). Height = lipgloss.Height // JoinVertical joins strings vertically, aligned along the given // position. JoinVertical = lipgloss.JoinVertical // JoinHorizontal joins strings horizontally, aligned along the given // position. JoinHorizontal = lipgloss.JoinHorizontal // Place places a string or text block in a box of the given dimensions. Place = lipgloss.Place )
var ( // PosCenter is lipgloss.Center, for use with Place and JoinVertical. PosCenter = lipgloss.Center // PosTop is lipgloss.Top, for use with Place and JoinVertical. PosTop = lipgloss.Top // PosBottom is lipgloss.Bottom, for use with Place and JoinVertical. PosBottom = lipgloss.Bottom // PosLeft is lipgloss.Left, for use with Place and JoinHorizontal. PosLeft = lipgloss.Left // PosRight is lipgloss.Right, for use with Place and JoinHorizontal. PosRight = lipgloss.Right )
var ( RoundedBorder = lipgloss.RoundedBorder DoubleBorder = lipgloss.DoubleBorder ThickBorder = lipgloss.ThickBorder ASCIIBorder = lipgloss.ASCIIBorder NormalBorder = lipgloss.NormalBorder )
var ( // StringWidth measures the visual width of a string, accounting for // ANSI escape sequences and East Asian wide characters. StringWidth = ansi.StringWidth // TruncateWith truncates a string to the given visual width, appending // the tail string if truncation occurs. Use this when you need a custom // tail indicator. For the common case (tail = "…"), use blit.Truncate. TruncateWith = ansi.Truncate )
Functions ¶
func ApplyDeltaPatch ¶
ApplyDeltaPatch reconstructs the new binary by applying a bsdiff patch to the current on-disk binary at exePath. The returned bytes are the new binary contents ready for checksum verification and replacement. On any failure the caller should fall back to a full download.
func Badge ¶
Badge renders a short text label with foreground color and optional bold. Useful for category tags in detail bars and status displays.
func CleanupOldBinary ¶
func CleanupOldBinary()
CleanupOldBinary removes a leftover .old binary from a previous update. Call this early in main() or in the update check flow.
func ClearSkippedVersions ¶
func ClearSkippedVersions(cfg UpdateConfig) error
ClearSkippedVersions removes all skip entries. Useful for tests and for a "reset" menu item in a consumer app.
func Consumed ¶
Consumed returns a tea.Cmd that signals the App that a key was handled. When a component's Update returns this, the App stops dispatching the key to other components.
func Contrast ¶
Contrast computes the WCAG 2.1 contrast ratio between bg and fg colors. Returns a value in [1, 21]; 4.5 satisfies WCAG AA for normal text.
func CopyToClipboardCmd ¶ added in v0.1.1
CopyToClipboardCmd returns a tea.Cmd that copies text to the system clipboard using the OSC 52 escape sequence. This works over SSH and in most modern terminal emulators without requiring external tools.
func CopyToClipboardWithNotify ¶ added in v0.1.1
CopyToClipboardWithNotify returns a tea.Batch that copies text to the clipboard and sends a CopyToClipboardMsg so the app can show feedback.
func DefaultConfigPath ¶ added in v0.1.1
DefaultConfigPath returns the default configuration file path for an application: <UserConfigDir>/<appName>/config.yaml. On Linux this is typically ~/.config/<appName>/config.yaml.
func DevConsoleToggleCmd ¶
DevConsoleToggleCmd returns a tea.Cmd that toggles the dev console.
func Divider ¶
Divider renders a horizontal line of ─ characters at the given width, styled with the theme's Border color.
func EnsureConfigDir ¶ added in v0.1.1
EnsureConfigDir creates the configuration directory for appName if it does not already exist. Returns the directory path.
func ExtractBinary ¶
ExtractBinary extracts the named binary from a tar.gz or zip archive.
func GitHubAPIURL ¶ added in v0.2.24
GitHubAPIURL builds a GitHub API URL for the given endpoint with per_page and page parameters. This is the most common use case for TUI apps that poll GitHub.
func HealthDot ¶ added in v0.2.24
HealthDot renders a coloured dot indicator for a status line. ok=true shows a positive (green) dot, ok=false shows a negative (red) dot, and unknown shows a muted dot. The label is rendered in Muted after the dot.
func HealthDotUnknown ¶ added in v0.2.24
HealthDotUnknown renders a muted empty dot for an unknown/unchecked status.
func Hyperlink ¶
Hyperlink is an alias for OSC8Link — wraps text in a clickable terminal hyperlink. Supported in modern terminals (iTerm2, Kitty, WezTerm, Windows Terminal, etc.).
func Interpolate ¶
Interpolate interpolates between from and to using easing e at progress t in [0,1]. Supported types: float64, int, lipgloss.Color.
func IsBackspace ¶ added in v0.2.24
IsBackspace reports whether msg is the Backspace key.
func IsKey ¶ added in v0.2.24
IsKey reports whether msg is a KeyMsg whose string representation equals key.
func IsRateLimited ¶
IsRateLimited reports whether err is a RateLimitError.
func IsRunes ¶ added in v0.2.24
IsRunes reports whether msg is a KeyRunes event (regular character input).
func IsVersionSkipped ¶
func IsVersionSkipped(cfg UpdateConfig, v string) bool
IsVersionSkipped reports whether v has been previously passed to SkipVersion for this cfg. Missing file or unreadable file returns false.
func KeyString ¶ added in v0.2.24
KeyString returns the string representation of a KeyMsg, or "" if msg is not a KeyMsg.
func LoadYAML ¶ added in v0.1.1
LoadYAML reads a YAML file at path and unmarshals it into dst. dst must be a pointer to the target struct. If the file does not exist, dst is left unchanged and no error is returned, allowing callers to rely on struct zero values as defaults.
func LogAppendCmd ¶
LogAppendCmd returns a tea.Cmd that appends a LogLine to any LogViewer that receives it via Update.
func LogRedact ¶ added in v0.2.24
LogRedact wraps a value so that slog emits "[REDACTED]" instead of the actual content. Use it when logging sensitive data (tokens, keys, paths) that should not appear in log output.
func Markdown ¶
Markdown renders md as a terminal-formatted string styled using the semantic color tokens from theme. Headings use theme.Accent, code block backgrounds use theme.Muted, body text uses theme.Text.
The rendered string includes trailing newlines added by glamour; callers may trim with strings.TrimSpace if needed.
func OSC8Link ¶
OSC8Link wraps text in an OSC8 terminal hyperlink escape sequence. If url is empty, the plain text is returned unchanged.
func OpenURL ¶
func OpenURL(url string)
OpenURL opens a URL in the user's default browser. It runs the command asynchronously and does not block.
func ParseJSONObject ¶ added in v0.2.24
ParseJSONObject is a convenience Parse function for APIs that return a single JSON object of type T.
func ParseJSONSlice ¶ added in v0.2.24
ParseJSONSlice is a convenience Parse function for APIs that return a JSON array of type T.
func RelativeTime ¶
RelativeTime returns a short human-readable duration string like "3m ago" or "2h ago". If the duration is negative (future time), it returns "now".
func RenderGradient ¶
RenderGradient renders text with the given gradient. Convenience wrapper for Gradient.RenderText.
func RetryCmd ¶ added in v0.1.1
RetryCmd wraps a fallible function with exponential backoff retry. On the first successful call, the resulting tea.Msg is returned. If all attempts fail, a RetryErrorMsg is returned.
Usage with Poller:
poller := NewPoller(30*time.Second, func() tea.Cmd {
return RetryCmd(fetchData, RetryOpts{MaxAttempts: 3, Backoff: 500 * time.Millisecond})
})
func Runes ¶ added in v0.2.24
Runes returns the typed rune characters if msg is a KeyRunes event, or nil otherwise.
func SaveYAML ¶ added in v0.1.1
SaveYAML marshals src to YAML and writes it atomically to path. The file is written to a temporary location first, then renamed to avoid partial writes on crash.
func SelfUpdate ¶
func SelfUpdate(cfg UpdateConfig) error
SelfUpdate downloads the latest release and replaces the current binary. Only works for manual installs (not Homebrew/Scoop). Honors the BLIT_UPDATE_DISABLE env var, cfg.Disabled, and cfg.Mode == UpdateDryRun (which logs every step without writing anything). Before/After/Error hooks on cfg are called at the corresponding points.
func SelfUpdateRollback ¶
func SelfUpdateRollback() error
SelfUpdateRollback restores the previous binary from <exePath>.old. Returns an error if no .old file exists or the restore fails. Used when a post-install verification step detects a broken new binary.
func Serve ¶
func Serve(ctx context.Context, cfg ServeConfig) error
Serve hosts a blit App over SSH via Charm Wish. It blocks until ctx is cancelled or the server exits.
Each inbound SSH session receives a fresh *App produced by cfg.Factory, ensuring per-connection state isolation.
blit.Serve(ctx, blit.ServeConfig{
Addr: ":2222",
Factory: func() *blit.App { return blit.NewApp(...) },
})
func SetThemeCmd ¶
SetThemeCmd returns a tea.Cmd that emits a SetThemeMsg.
func SkipVersion ¶
func SkipVersion(cfg UpdateConfig, v string) error
SkipVersion marks v as skipped so future CheckForUpdate calls return Available=false for that exact tag. Writes to <CacheDir>/skipped-versions.json. Errors are returned but not logged.
func Sparkline ¶
func Sparkline(data []float64, maxWidth int, opts *SparklineOpts) (string, int)
Sparkline renders a Unicode block sparkline from a slice of float64 values. The output is trimmed or sampled to fit within maxWidth characters. Each bar uses one of ▁▂▃▄▅▆▇█ based on the value's position in the min-max range. Returns the styled string and the number of characters rendered.
func ToastCmd ¶
func ToastCmd(severity ToastSeverity, title, body string, duration time.Duration, actions ...ToastAction) tea.Cmd
ToastCmd returns a tea.Cmd that sends a ToastMsg.
func ToastError ¶ added in v0.1.1
ToastError returns a tea.Cmd that shows an error toast with a 6s duration.
func ToastInfo ¶ added in v0.1.1
ToastInfo returns a tea.Cmd that shows an informational toast with a 4s duration.
func ToastSuccess ¶ added in v0.1.1
ToastSuccess returns a tea.Cmd that shows a success toast with a 4s duration.
func ToastWarn ¶ added in v0.1.1
ToastWarn returns a tea.Cmd that shows a warning toast with a 6s duration.
func Truncate ¶
Truncate shortens s to maxWidth characters, appending "…" if truncated. Uses visual width (lipgloss.Width) so ANSI sequences are handled correctly. If s fits within maxWidth, it is returned unchanged.
func ValidateConfig ¶
func ValidateConfig(cfg UpdateConfig) error
ValidateConfig checks that cfg has all required fields set. Returns a descriptive error if any required field is missing.
func VerifyChecksum ¶
VerifyChecksum verifies the SHA256 checksum of data against a GoReleaser checksums.txt file. The checksums file format is: "<hex> <filename>\n" per line.
func VerifyCosignSignature ¶
VerifyCosignSignature verifies a detached ed25519 signature over assetData.
sigData is the raw content of the <asset>.sig file as produced by `cosign sign-blob --key <ed25519.key>` — a base64-encoded signature. pubKeyPEM is the signer's public key in PEM or bare base64 format.
func VerifyInstalled ¶
VerifyInstalled spawns the newly-installed binary with "--version" and checks its output contains the expected tag. If it does not, the update is rolled back via SelfUpdateRollback. Intended to run immediately after SelfUpdate in modes that can recover from a bad install.
func WriteCache ¶
func WriteCache(path string, cache UpdateCache) error
WriteCache writes the update check result to disk.
Types ¶
type Accordion ¶ added in v0.2.12
type Accordion struct {
// contains filtered or unexported fields
}
Accordion is a vertically stacked set of collapsible sections. Implements Component and Themed.
func NewAccordion ¶ added in v0.2.12
func NewAccordion(sections []AccordionSection, opts AccordionOpts) *Accordion
NewAccordion creates an Accordion with the given sections and options.
func (*Accordion) CursorIndex ¶ added in v0.2.12
CursorIndex returns the currently highlighted section index.
func (*Accordion) KeyBindings ¶ added in v0.2.12
KeyBindings implements Component.
func (*Accordion) Sections ¶ added in v0.2.12
func (a *Accordion) Sections() []AccordionSection
Sections returns the current sections.
func (*Accordion) SetFocused ¶ added in v0.2.12
SetFocused implements Component.
type AccordionOpts ¶ added in v0.2.12
type AccordionOpts struct {
// Exclusive limits expansion to one section at a time (true = only one open).
Exclusive bool
// OnToggle is called when a section is expanded or collapsed.
OnToggle func(index int, expanded bool)
}
AccordionOpts configures an Accordion.
type AccordionSection ¶ added in v0.2.12
type AccordionSection struct {
// Title is the header text.
Title string
// Content is the body text shown when expanded.
Content string
// Expanded controls whether this section is open.
Expanded bool
}
AccordionSection is a collapsible section in an Accordion.
type Activatable ¶
type Activatable interface {
SetActive(bool)
}
Activatable is implemented by overlays that can be explicitly activated.
type AnySignal ¶
type AnySignal interface {
// contains filtered or unexported methods
}
AnySignal is the untyped interface implemented by every *Signal[T]. It is used as the dependency type for Computed so that signals of mixed element types can be combined.
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the main entry point for a blit application.
func NewApp ¶
NewApp creates a new App with the given options.
Example ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
app := blit.NewApp(
blit.WithTheme(blit.DefaultTheme()),
blit.WithHelp(),
)
// app.Run() starts the TUI event loop.
_ = app
}
Output:
Example (WithStatusBar) ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
app := blit.NewApp(
blit.WithTheme(blit.DefaultTheme()),
blit.WithStatusBar(
func() string { return " ? help q quit" },
func() string { return "" },
),
blit.WithHelp(),
)
_ = app
}
Output:
func (*App) AddKeyBind ¶
AddKeyBind adds a global keybinding after construction. The binding appears in the help screen and its Handler is called on key press.
func (*App) Done ¶ added in v0.2.24
func (a *App) Done() <-chan struct{}
Done returns a channel that is closed when the App finishes running. Use this to orchestrate clean shutdown of background goroutines:
go func() {
<-app.Done()
close(dbConn)
}()
func (*App) Model ¶
Model returns the underlying tea.Model for use with btest or other testing frameworks that need a tea.Model directly.
func (*App) Run ¶
func (a *App) Run() (UpdateAction, error)
Run starts the TUI application. It blocks until the user quits.
If WithAutoUpdate is configured, Run may return with an UpdateAction requesting the caller to restart or exit instead of running the TUI. Check the returned UpdateAction:
action, err := app.Run()
if action == blit.UpdateActionRestart {
// Binary was replaced; advise user to relaunch.
}
func (*App) Send ¶
Send pushes a message into the running App from outside the Bubble Tea event loop. Use this to push data from background goroutines (WebSocket streams, API polling, etc.). The message will be delivered to all components via Update.
func (*App) ToastError ¶ added in v0.2.24
ToastError sends an error toast with a 6s duration.
func (*App) ToastSuccess ¶ added in v0.2.24
ToastSuccess sends a success toast with a 4s duration.
type BackoffStrategy ¶ added in v0.1.3
type BackoffStrategy interface {
// NextBackoff returns the delay before the next retry attempt.
// A negative return value means no more retries.
NextBackoff(attempt int) time.Duration
}
BackoffStrategy defines retry behavior on transient errors.
func ExponentialBackoff ¶ added in v0.1.3
func ExponentialBackoff(initial, max time.Duration) BackoffStrategy
ExponentialBackoff returns a strategy starting at initial, doubling each attempt, capped at max.
Example ¶
package main
import (
"fmt"
"time"
blit "github.com/blitui/blit"
)
func main() {
backoff := blit.ExponentialBackoff(time.Second, 5*time.Minute)
fmt.Println(backoff.NextBackoff(0)) // 1s
fmt.Println(backoff.NextBackoff(1)) // 2s
fmt.Println(backoff.NextBackoff(2)) // 4s
}
Output: 1s 2s 4s
func FixedBackoff ¶ added in v0.1.3
func FixedBackoff(delay time.Duration, maxAttempts int) BackoffStrategy
FixedBackoff returns a strategy with constant delay for up to maxAttempts.
Example ¶
package main
import (
"fmt"
"time"
blit "github.com/blitui/blit"
)
func main() {
backoff := blit.FixedBackoff(2*time.Second, 3)
fmt.Println(backoff.NextBackoff(0)) // 2s
fmt.Println(backoff.NextBackoff(2)) // 2s
fmt.Println(backoff.NextBackoff(3)) // -1ns (no more retries)
}
Output: 2s 2s -1ns
func NoBackoff ¶ added in v0.1.3
func NoBackoff() BackoffStrategy
NoBackoff returns a strategy that never retries.
type BorderSet ¶
type BorderSet struct {
Rounded lipgloss.Border
Double lipgloss.Border
Thick lipgloss.Border
Ascii lipgloss.Border
Minimal lipgloss.Border
}
BorderSet groups named lipgloss border styles for consistent component use.
func DefaultBorders ¶
func DefaultBorders() BorderSet
DefaultBorders returns the standard lipgloss border set.
type Breadcrumb ¶ added in v0.2.12
type Breadcrumb struct {
// contains filtered or unexported fields
}
Breadcrumb is an interactive, cursor-driven breadcrumb navigation component with selection support. It displays a navigable path of items and allows the user to move between them with keyboard input and invoke an OnSelect callback. It implements Component and Themed.
For a simple display-only path trail, see Breadcrumbs.
func NewBreadcrumb ¶ added in v0.2.12
func NewBreadcrumb(items []BreadcrumbItem, opts BreadcrumbOpts) *Breadcrumb
NewBreadcrumb creates a Breadcrumb with the given items and options.
func (*Breadcrumb) CursorIndex ¶ added in v0.2.12
func (b *Breadcrumb) CursorIndex() int
CursorIndex returns the currently highlighted item index.
func (*Breadcrumb) Focused ¶ added in v0.2.12
func (b *Breadcrumb) Focused() bool
Focused implements Component.
func (*Breadcrumb) Init ¶ added in v0.2.12
func (b *Breadcrumb) Init() tea.Cmd
Init implements Component.
func (*Breadcrumb) Items ¶ added in v0.2.12
func (b *Breadcrumb) Items() []BreadcrumbItem
Items returns the current breadcrumb items.
func (*Breadcrumb) KeyBindings ¶ added in v0.2.12
func (b *Breadcrumb) KeyBindings() []KeyBind
KeyBindings implements Component.
func (*Breadcrumb) Pop ¶ added in v0.2.12
func (b *Breadcrumb) Pop() BreadcrumbItem
Pop removes and returns the last item, moving the cursor back. Returns the zero value if there are no items.
func (*Breadcrumb) Push ¶ added in v0.2.12
func (b *Breadcrumb) Push(item BreadcrumbItem)
Push appends an item and moves the cursor to it.
func (*Breadcrumb) SetFocused ¶ added in v0.2.12
func (b *Breadcrumb) SetFocused(f bool)
SetFocused implements Component.
func (*Breadcrumb) SetItems ¶ added in v0.2.12
func (b *Breadcrumb) SetItems(items []BreadcrumbItem)
SetItems replaces the items and resets the cursor to the last item.
func (*Breadcrumb) SetSize ¶ added in v0.2.12
func (b *Breadcrumb) SetSize(w, h int)
SetSize implements Component.
func (*Breadcrumb) SetTheme ¶ added in v0.2.12
func (b *Breadcrumb) SetTheme(theme Theme)
SetTheme implements Themed.
func (*Breadcrumb) View ¶ added in v0.2.12
func (b *Breadcrumb) View() string
View implements Component.
type BreadcrumbItem ¶ added in v0.2.12
type BreadcrumbItem struct {
// Label is the display text.
Label string
// Data is an arbitrary payload the caller can attach.
Data any
}
BreadcrumbItem is a single segment in a Breadcrumb path.
type BreadcrumbOpts ¶ added in v0.2.12
type BreadcrumbOpts struct {
// Separator is the string between items. Defaults to " > ".
Separator string
// OnSelect is called when enter is pressed on an item.
OnSelect func(item BreadcrumbItem, index int)
}
BreadcrumbOpts configures a Breadcrumb.
type Breadcrumbs ¶
type Breadcrumbs struct {
// Segments are the individual path parts, e.g. []string{"home", "docs", "api"}.
Segments []string
// Separator is placed between segments. Defaults to " / ".
Separator string
// MaxWidth is the maximum render width in columns. 0 means unlimited.
MaxWidth int
// contains filtered or unexported fields
}
Breadcrumbs is a passive, display-only path trail. It renders a horizontal sequence of path segments separated by a configurable separator. When the rendered width exceeds MaxWidth the leading segments are replaced with "…" until it fits.
For an interactive breadcrumb with cursor navigation and selection, see Breadcrumb.
func NewBreadcrumbs ¶
func NewBreadcrumbs(segments []string) *Breadcrumbs
NewBreadcrumbs creates a Breadcrumbs component with default separator " / ".
func (*Breadcrumbs) Focused ¶
func (b *Breadcrumbs) Focused() bool
Focused reports whether the Breadcrumbs is focused.
func (*Breadcrumbs) Init ¶
func (b *Breadcrumbs) Init() tea.Cmd
Init initializes the Breadcrumbs component. It returns nil.
func (*Breadcrumbs) KeyBindings ¶
func (b *Breadcrumbs) KeyBindings() []KeyBind
KeyBindings returns the key bindings for the Breadcrumbs.
func (*Breadcrumbs) SetFocused ¶
func (b *Breadcrumbs) SetFocused(f bool)
SetFocused sets the focus state of the Breadcrumbs.
func (*Breadcrumbs) SetSize ¶
func (b *Breadcrumbs) SetSize(w, h int)
SetSize sets the width and height of the Breadcrumbs.
func (*Breadcrumbs) SetTheme ¶
func (b *Breadcrumbs) SetTheme(th Theme)
SetTheme updates the theme used by the Breadcrumbs.
func (*Breadcrumbs) View ¶
func (b *Breadcrumbs) View() string
View renders the Breadcrumbs as a string.
type CLIApp ¶ added in v0.2.24
type CLIApp struct {
Name string
Version string
Commands []Subcommand
RunTUI func() error
}
CLIApp is a lightweight subcommand router for TUI applications. Many TUI apps need a CLI layer for config management (add/remove/list) alongside the main TUI. CLIApp handles this pattern uniformly.
Usage:
app := blit.NewCLIApp(blit.CLIAppOpts{
Name: "myapp",
Version: "1.0.0",
Commands: []blit.Subcommand{
{Name: "add", Usage: "add <item>", Run: func(args []string) error { ... }},
{Name: "list", Aliases: []string{"ls"}, Run: func(args []string) error { ... }},
},
RunTUI: func() error { return runTUI() },
})
os.Exit(app.Execute(os.Args[1:]))
func NewCLIApp ¶ added in v0.2.24
func NewCLIApp(opts CLIAppOpts) *CLIApp
NewCLIApp creates a CLIApp with the given options.
type CLIAppOpts ¶ added in v0.2.24
type CLIAppOpts struct {
Name string
Version string
Commands []Subcommand
RunTUI func() error
}
CLIAppOpts configures a CLIApp.
type CLICommand ¶ added in v0.1.13
CLICommand is a config subcommand that can be invoked from a CLI.
type CellRenderer ¶
CellRenderer renders a single cell with full styling control. Parameters: row data, column index, whether this row has cursor, theme. Return a styled string (use lipgloss). If nil, the table uses plain text.
type ChartPanel ¶ added in v0.2.12
type ChartPanel struct {
// contains filtered or unexported fields
}
ChartPanel is a container that displays one of several chart Components with a title bar and tab-style switcher. Implements Component and Themed.
func NewChartPanel ¶ added in v0.2.12
func NewChartPanel(opts ChartPanelOpts) *ChartPanel
NewChartPanel creates a ChartPanel with the given options.
func (*ChartPanel) ActiveIndex ¶ added in v0.2.12
func (c *ChartPanel) ActiveIndex() int
ActiveIndex returns the index of the currently displayed chart.
func (*ChartPanel) Focused ¶ added in v0.2.12
func (c *ChartPanel) Focused() bool
Focused implements Component.
func (*ChartPanel) Init ¶ added in v0.2.12
func (c *ChartPanel) Init() tea.Cmd
Init implements Component.
func (*ChartPanel) KeyBindings ¶ added in v0.2.12
func (c *ChartPanel) KeyBindings() []KeyBind
KeyBindings implements Component.
func (*ChartPanel) SetActive ¶ added in v0.2.12
func (c *ChartPanel) SetActive(idx int)
SetActive switches to the chart at the given index (clamped).
func (*ChartPanel) SetFocused ¶ added in v0.2.12
func (c *ChartPanel) SetFocused(f bool)
SetFocused implements Component.
func (*ChartPanel) SetSize ¶ added in v0.2.12
func (c *ChartPanel) SetSize(w, h int)
SetSize implements Component.
func (*ChartPanel) SetTheme ¶ added in v0.2.12
func (c *ChartPanel) SetTheme(theme Theme)
SetTheme implements Themed.
func (*ChartPanel) View ¶ added in v0.2.12
func (c *ChartPanel) View() string
View implements Component.
type ChartPanelOpts ¶ added in v0.2.12
type ChartPanelOpts struct {
// Title is optional text shown above the chart.
Title string
// Charts are the available chart components. The panel shows one at a time.
Charts []Component
// Labels are optional display names for each chart (e.g., "Line", "Bar").
// If shorter than Charts, indices are used for unlabelled charts.
Labels []string
}
ChartPanelOpts configures a ChartPanel.
type Clock ¶
Clock abstracts time.Now so Poller can be tested deterministically. Production code uses realClock (via NewPoller). Tests can pass a FakeClock from the blit package (or any type that implements this interface).
type CollapsibleSection ¶
type CollapsibleSection struct {
Title string
Collapsed bool
// Content is the text rendered below the header when expanded.
// Set this directly or use Render() with a contentFunc for lazy evaluation.
Content string
// contains filtered or unexported fields
}
CollapsibleSection is a render helper for collapsible panel sections. It can be used in two ways:
- As a render helper: call Render() directly from a parent component.
- As a Component: embed it in a layout and let the App manage it.
When used as a Component, it handles its own key events (enter/space to toggle), focus, size, and theming.
func NewCollapsibleSection ¶
func NewCollapsibleSection(title string) *CollapsibleSection
NewCollapsibleSection creates an expanded section with the given title.
func (*CollapsibleSection) Focused ¶ added in v0.2.24
func (s *CollapsibleSection) Focused() bool
Focused implements Component.
func (*CollapsibleSection) Init ¶ added in v0.2.24
func (s *CollapsibleSection) Init() Cmd
Init implements Component.
func (*CollapsibleSection) KeyBindings ¶ added in v0.2.24
func (s *CollapsibleSection) KeyBindings() []KeyBind
KeyBindings implements Component.
func (*CollapsibleSection) Render ¶
func (s *CollapsibleSection) Render(theme Theme, contentFunc func() string) string
Render returns the section header and, if expanded, the content. contentFunc is only called when expanded to avoid wasted work.
func (*CollapsibleSection) SetFocused ¶ added in v0.2.24
func (s *CollapsibleSection) SetFocused(f bool)
SetFocused implements Component.
func (*CollapsibleSection) SetSize ¶ added in v0.2.24
func (s *CollapsibleSection) SetSize(w, h int)
SetSize implements Component.
func (*CollapsibleSection) SetTheme ¶ added in v0.2.24
func (s *CollapsibleSection) SetTheme(t Theme)
SetTheme implements Themed.
func (*CollapsibleSection) Toggle ¶
func (s *CollapsibleSection) Toggle()
Toggle flips the collapsed state.
func (*CollapsibleSection) Update ¶ added in v0.2.24
func (s *CollapsibleSection) Update(msg Msg, ctx Context) (Component, Cmd)
Update implements Component.
func (*CollapsibleSection) View ¶ added in v0.2.24
func (s *CollapsibleSection) View() string
View implements Component.
type Column ¶
type Column struct {
Title string // Column header text
Width int // Proportional width weight
MaxWidth int // Cap column at this many characters (0 = no cap)
MinWidth int // Hide column when terminal width is below this (0 = always show)
Align Alignment // Text alignment within the column
Sortable bool // Whether this column supports sorting
NoRowStyle bool // Exempt this column from row-level background styling
}
Column defines a table column with responsive visibility.
type Command ¶
type Command struct {
Name string // Primary name: "quit", "sort", "go"
Aliases []string // Alternatives: ["q"] for "quit"
Args bool // Whether it takes an argument
Hint string // Help text
Run func(string) tea.Cmd // Handler, receives args string
}
Command defines a single command for the CommandBar.
type CommandBar ¶
type CommandBar struct {
// contains filtered or unexported fields
}
CommandBar is a vim-style : command input overlay.
func NewCommandBar ¶
func NewCommandBar(commands []Command) *CommandBar
NewCommandBar creates a command bar with the given commands.
func (*CommandBar) Close ¶
func (c *CommandBar) Close()
Close deactivates the CommandBar and resets its state.
func (*CommandBar) Focused ¶
func (c *CommandBar) Focused() bool
Focused reports whether the CommandBar is focused.
func (*CommandBar) Init ¶
func (c *CommandBar) Init() tea.Cmd
Init initializes the CommandBar component.
func (*CommandBar) Inline ¶
func (c *CommandBar) Inline() bool
Inline returns true — the CommandBar renders as a line at the bottom, not a fullscreen overlay.
func (*CommandBar) IsActive ¶
func (c *CommandBar) IsActive() bool
IsActive reports whether the CommandBar overlay is currently visible.
func (*CommandBar) KeyBindings ¶
func (c *CommandBar) KeyBindings() []KeyBind
KeyBindings returns the key bindings for the CommandBar.
func (*CommandBar) SetActive ¶
func (c *CommandBar) SetActive(v bool)
SetActive shows or hides the CommandBar overlay.
func (*CommandBar) SetFocused ¶
func (c *CommandBar) SetFocused(f bool)
SetFocused sets the focus state of the CommandBar.
func (*CommandBar) SetSize ¶
func (c *CommandBar) SetSize(w, h int)
SetSize sets the width and height of the CommandBar.
func (*CommandBar) SetTheme ¶
func (c *CommandBar) SetTheme(t Theme)
SetTheme implements the Themed interface.
func (*CommandBar) View ¶
func (c *CommandBar) View() string
View renders the CommandBar as a string.
type Component ¶
type Component interface {
// Init returns an initial command, like tea.Model.
Init() tea.Cmd
// Update handles a message and returns the updated component and command.
// Return Consumed() to signal the App that this key was handled.
// ctx carries the ambient Theme, Size, Focus, Hotkeys, Clock, and Logger
// for the current dispatch.
Update(msg tea.Msg, ctx Context) (Component, tea.Cmd)
// View renders the component to a string.
View() string
// KeyBindings returns the keybindings this component handles.
KeyBindings() []KeyBind
// SetSize sets the available width and height for rendering.
SetSize(width, height int)
// Focused returns whether this component currently has focus.
Focused() bool
// SetFocused sets the focus state of this component.
SetFocused(focused bool)
}
Component is the core interface for all blit UI elements. It extends Bubble Tea's Model with size, focus, and keybinding support.
type ComponentHeader ¶ added in v0.2.24
type ComponentHeader struct {
Title string
Subtitle string
StatusParts []HeaderStatusPart
}
ComponentHeader renders a structured header with title, subtitle, and status line parts. This is a common pattern in TUI components that display a title bar with health indicators, filter state, or sparklines.
Usage:
h := ComponentHeader{
Title: "myapp",
Subtitle: "Watching: owner/repo-a, owner/repo-b",
StatusParts: []HeaderStatusPart{
{Text: "Poll 5s ago"},
{Text: "● repo-a", Color: theme.Positive},
{Text: "API 4500/5000", Color: theme.Warn},
},
}
header := h.Render(width, theme)
type Config ¶ added in v0.1.3
type Config[T any] struct { // Value holds the current configuration state. Value T // contains filtered or unexported fields }
Config manages loading, saving, and editing application configuration. T must be a struct type with exported fields. Fields are discovered via reflection and configured with `blit:"..."` struct tags.
func LoadConfig ¶ added in v0.1.3
func LoadConfig[T any](appName string, opts ...ConfigOption) (*Config[T], error)
LoadConfig loads configuration for the named app from the platform-appropriate config directory. Missing files use struct defaults. Fields with `default` tags are populated if the loaded value is zero.
Config file paths follow os.UserConfigDir():
- Linux: ~/.config/<appName>/config.yaml
- macOS: ~/Library/Application Support/<appName>/config.yaml
- Windows: %APPDATA%\<appName>\config.yaml
Example ¶
package main
import (
"fmt"
blit "github.com/blitui/blit"
)
func main() {
type AppConfig struct {
Interval int `yaml:"interval" blit:"label=Interval (sec),group=Polling,default=30,min=5"`
Theme string `yaml:"theme" blit:"label=Theme,group=Appearance,default=dark"`
}
cfg, err := blit.LoadConfig[AppConfig]("myapp")
if err != nil {
// Handle missing or invalid config file.
fmt.Println("config error:", err)
}
_ = cfg
}
Output:
func (*Config[T]) AsSignal ¶ added in v0.1.13
AsSignal returns a reactive Signal that tracks the config value. The signal is created lazily on first call and emits whenever the config changes via SetValue or WatchFile reload. Components can Subscribe to the returned signal for reactive updates.
Example ¶
package main
import (
"fmt"
blit "github.com/blitui/blit"
)
func main() {
type AppConfig struct {
Interval int `yaml:"interval" blit:"label=Interval (sec),group=Polling,default=30,min=5"`
Theme string `yaml:"theme" blit:"label=Theme,group=Appearance,default=dark"`
}
cfg := &blit.Config[AppConfig]{
Value: AppConfig{Interval: 30, Theme: "dark"},
}
// AsSignal returns a reactive signal that tracks config changes.
sig := cfg.AsSignal()
fmt.Println(sig.Get().Theme)
// SetValue updates both cfg.Value and the signal.
_ = cfg.SetValue(func(v *AppConfig) { v.Theme = "light" })
fmt.Println(sig.Get().Theme)
}
Output: dark light
func (*Config[T]) CLICommands ¶ added in v0.1.13
func (c *Config[T]) CLICommands() map[string]CLICommand
CLICommands returns a command registry for config CLI integration. Commands use the yaml tag name (or lowercased Go field name) as keys.
Supported commands:
- get <field>: print the current value of a field
- set <field> <value>: update a field and save
- list: print all fields and their current values
func (*Config[T]) Defaults ¶ added in v0.1.3
func (c *Config[T]) Defaults() T
Defaults returns a new T with all `default` tags applied.
func (*Config[T]) Editor ¶ added in v0.1.3
func (c *Config[T]) Editor() *ConfigEditor
Editor returns a ConfigEditor auto-generated from the struct tags. Each exported field with a `blit` tag becomes a ConfigField entry.
Example ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
type AppConfig struct {
Interval int `yaml:"interval" blit:"label=Interval (sec),group=Polling,default=30,min=5"`
Theme string `yaml:"theme" blit:"label=Theme,group=Appearance,default=dark"`
}
cfg := &blit.Config[AppConfig]{
Value: AppConfig{Interval: 30, Theme: "dark"},
}
// Editor auto-generates a ConfigEditor from struct tags.
editor := cfg.Editor()
_ = editor
}
Output:
func (*Config[T]) Reset ¶ added in v0.1.3
Reset restores all fields to their default values and saves.
func (*Config[T]) SetValue ¶ added in v0.1.3
SetValue updates the config via a mutator function and marks it dirty.
func (*Config[T]) WatchFile ¶ added in v0.1.13
WatchFile watches the config file for changes and reloads automatically. On each detected change, the YAML is re-read and Value is updated in place. The onChange callback (if non-nil) is invoked after a successful reload. WatchFile blocks until ctx is cancelled; run it in a goroutine.
File events are debounced by 200ms to avoid flicker from editors that save in multiple steps (write tmp + rename).
type ConfigEditor ¶
type ConfigEditor struct {
// contains filtered or unexported fields
}
ConfigEditor is an overlay for editing application settings. Fields are declared with getter/setter closures for config-format-agnostic editing.
func NewConfigEditor ¶
func NewConfigEditor(fields []ConfigField) *ConfigEditor
NewConfigEditor creates a config editor overlay with the given fields.
func (*ConfigEditor) Close ¶
func (c *ConfigEditor) Close()
Close deactivates the ConfigEditor and resets its state.
func (*ConfigEditor) Focused ¶
func (c *ConfigEditor) Focused() bool
Focused reports whether the ConfigEditor is focused.
func (*ConfigEditor) Init ¶
func (c *ConfigEditor) Init() tea.Cmd
Init initializes the ConfigEditor component.
func (*ConfigEditor) IsActive ¶
func (c *ConfigEditor) IsActive() bool
IsActive reports whether the ConfigEditor overlay is currently visible.
func (*ConfigEditor) KeyBindings ¶
func (c *ConfigEditor) KeyBindings() []KeyBind
KeyBindings returns the key bindings for the ConfigEditor.
func (*ConfigEditor) SetFocused ¶
func (c *ConfigEditor) SetFocused(f bool)
SetFocused sets the focus state of the ConfigEditor.
func (*ConfigEditor) SetSize ¶
func (c *ConfigEditor) SetSize(w, h int)
SetSize sets the width and height of the ConfigEditor.
func (*ConfigEditor) SetTheme ¶
func (c *ConfigEditor) SetTheme(t Theme)
SetTheme implements the Themed interface.
func (*ConfigEditor) View ¶
func (c *ConfigEditor) View() string
View renders the ConfigEditor as a string.
type ConfigField ¶
type ConfigField struct {
Label string // Display label
Group string // Group heading (e.g., "General", "Display")
Hint string // Help text shown below the field
Get func() string // Legacy getter. Ignored when Source is set.
Source any // Optional: func() string, *Signal[string], or StringSource.
Set func(string) error // Sets a new value, returns error if invalid
Validate func(string) error // Optional: validates input before Set is called
}
ConfigField defines a single editable field in the config editor.
Get accepts either the legacy `func() string` getter or a `*Signal[string]` (v0.10+). The Source field takes precedence when both are set. Setting Source with a signal lets background updates (e.g., a value polled from disk) appear in the editor without wiring a manual refresh.
type ConfigOption ¶ added in v0.1.3
type ConfigOption func(*configOpts)
ConfigOption configures LoadConfig behavior.
func WithConfigPath ¶ added in v0.1.3
func WithConfigPath(path string) ConfigOption
WithConfigPath overrides the default config file path.
type ConfirmField ¶
type ConfirmField struct {
// contains filtered or unexported fields
}
ConfirmField is a yes/no boolean field.
func NewConfirmField ¶
func NewConfirmField(id, label string) *ConfirmField
NewConfirmField creates a new yes/no confirm field.
func (*ConfirmField) Init ¶
func (f *ConfirmField) Init() tea.Cmd
Init initializes the ConfirmField component.
func (*ConfirmField) SetFocused ¶
func (f *ConfirmField) SetFocused(_ bool)
SetFocused sets the focus state of the ConfirmField.
func (*ConfirmField) SetValue ¶
func (f *ConfirmField) SetValue(v string)
SetValue sets the current value of the ConfirmField.
func (*ConfirmField) Update ¶
func (f *ConfirmField) Update(msg tea.Msg) tea.Cmd
Update handles incoming messages and updates ConfirmField state.
func (*ConfirmField) Validate ¶
func (f *ConfirmField) Validate() error
Validate checks the current value against the field's validation rules.
func (*ConfirmField) Value ¶
func (f *ConfirmField) Value() string
Value returns the current value of the ConfirmField.
func (*ConfirmField) View ¶
func (f *ConfirmField) View(focused bool, theme Theme, _ int) string
View renders the ConfirmField as a string.
func (*ConfirmField) WithDefault ¶
func (f *ConfirmField) WithDefault(v bool) *ConfirmField
WithDefault sets the initial boolean value.
func (*ConfirmField) WithHint ¶
func (f *ConfirmField) WithHint(hint string) *ConfirmField
WithHint sets the hint text.
type Context ¶
type Context struct {
// Theme is the currently active theme. Components can pull semantic
// colors from it without needing a separate SetTheme call per frame.
Theme Theme
// Size is the viewport size at the time of dispatch (width, height).
Size Size
// Focus describes which component currently holds focus. Components
// can compare against their own identity / index to decide whether to
// react to key input.
Focus Focus
// Hotkeys exposes the app-wide keybinding registry. Components can
// consult it to resolve chord conflicts or render inline hints.
Hotkeys *Registry
// Clock abstracts time.Now so components can be tested with a fake
// clock. It is nil-safe: if unset, callers should fall back to
// time.Now directly.
Clock Clock
// Logger is an optional structured logger. Components should treat a
// nil Logger as "logging disabled" rather than panicking.
Logger *slog.Logger
// Flags exposes the app-wide feature flag registry. Components can
// check flags to conditionally enable or disable behavior at runtime.
// Nil means no flags are configured — callers should treat this as
// "all features at their defaults".
Flags *FeatureFlag
// TraceID identifies the current message dispatch cycle. Every call
// to App.Update generates a unique trace ID so that components can
// correlate log entries and metrics across the dispatch chain.
// Components can log it or pass it to downstream systems for
// end-to-end message tracing.
TraceID uint64
}
Context carries ambient state that every Component.Update call receives. It is constructed by the App on each dispatch and passed down through the focused-component chain. Prefer reading values from Context over stashing copies on the component itself — Context always reflects the latest frame.
type CopyToClipboardMsg ¶ added in v0.1.1
type CopyToClipboardMsg struct {
Text string
}
CopyToClipboardMsg is sent after a successful clipboard copy to notify the application. Components can listen for this to show confirmation.
type CursorChangeHandler ¶
CursorChangeHandler is called when the cursor moves to a different row.
type CursorStyle ¶
type CursorStyle int
CursorStyle controls how the cursor is rendered in a table.
const ( // CursorRow highlights the entire row. CursorRow CursorStyle = iota )
type DebugDataProvider ¶ added in v0.1.3
type DebugDataProvider interface {
DebugProvider
// Data returns structured key-value data for this provider.
Data() map[string]any
}
DebugDataProvider is an optional extension of DebugProvider that exposes structured data for machine consumption (JSON export, alternative renders).
type DebugProvider ¶ added in v0.1.3
type DebugProvider interface {
// Name returns the display name for this provider (used as tab label or section header).
Name() string
// View renders the provider's content. width and height are the available space.
View(width, height int, theme Theme) string
}
DebugProvider supplies a named debug section for the DevConsole overlay. Providers are queried each frame when the console is visible.
type DebugProviderWithLifecycle ¶ added in v0.1.13
type DebugProviderWithLifecycle interface {
DebugProvider
// Init is called once when the provider is registered.
Init() error
// Destroy is called when the App is shutting down.
Destroy() error
}
DebugProviderWithLifecycle is an optional extension of DebugProvider that supports initialization and cleanup. Init is called when the provider is registered with the DevConsole. Destroy is called when the App shuts down.
type DetailOverlay ¶
type DetailOverlay[T any] struct { // contains filtered or unexported fields }
DetailOverlay is a generic full-screen overlay for displaying item details.
func NewDetailOverlay ¶
func NewDetailOverlay[T any](opts DetailOverlayOpts[T]) *DetailOverlay[T]
NewDetailOverlay creates a detail overlay with the given options.
func (*DetailOverlay[T]) Close ¶
func (d *DetailOverlay[T]) Close()
Close deactivates the DetailOverlay and resets its state.
func (*DetailOverlay[T]) Focused ¶
func (d *DetailOverlay[T]) Focused() bool
Focused reports whether the DetailOverlay is focused.
func (*DetailOverlay[T]) Init ¶
func (d *DetailOverlay[T]) Init() tea.Cmd
Init initializes the DetailOverlay component.
func (*DetailOverlay[T]) IsActive ¶
func (d *DetailOverlay[T]) IsActive() bool
IsActive reports whether the DetailOverlay overlay is currently visible.
func (*DetailOverlay[T]) Item ¶
func (d *DetailOverlay[T]) Item() T
Item returns the currently displayed item.
func (*DetailOverlay[T]) KeyBindings ¶
func (d *DetailOverlay[T]) KeyBindings() []KeyBind
KeyBindings returns the key bindings for the DetailOverlay.
func (*DetailOverlay[T]) SetActive ¶
func (d *DetailOverlay[T]) SetActive(v bool)
SetActive shows or hides the DetailOverlay overlay.
func (*DetailOverlay[T]) SetFocused ¶
func (d *DetailOverlay[T]) SetFocused(f bool)
SetFocused sets the focus state of the DetailOverlay.
func (*DetailOverlay[T]) SetSize ¶
func (d *DetailOverlay[T]) SetSize(w, h int)
SetSize sets the width and height of the DetailOverlay.
func (*DetailOverlay[T]) SetTheme ¶
func (d *DetailOverlay[T]) SetTheme(t Theme)
SetTheme implements the Themed interface.
func (*DetailOverlay[T]) Show ¶
func (d *DetailOverlay[T]) Show(item T)
Show opens the overlay with the given item.
func (*DetailOverlay[T]) View ¶
func (d *DetailOverlay[T]) View() string
View renders the DetailOverlay as a string.
type DetailOverlayOpts ¶
type DetailOverlayOpts[T any] struct { // Render draws the item detail content. Required. Render func(item T, width, height int, theme Theme) string // Title is shown at the top of the overlay. Optional. Title string // KeyBindings are extra bindings shown in help. Optional. KeyBindings []KeyBind // OnKey handles custom key events. Optional. // Return Consumed() if handled, nil to let the App handle it. OnKey func(item T, key tea.KeyMsg) tea.Cmd }
DetailOverlayOpts configures a DetailOverlay.
type DetailRenderer ¶
DetailRenderer renders a detail bar for the selected row. Parameters: row data, row index, available width, theme. Return a styled multi-line string. Shown below the table rows when focused.
type Dialog ¶ added in v0.2.12
type Dialog struct {
// contains filtered or unexported fields
}
Dialog is a modal overlay that displays a message with action buttons. It implements the Overlay interface.
func NewDialog ¶ added in v0.2.12
func NewDialog(opts DialogOpts) *Dialog
NewDialog creates and opens a Dialog with the given options.
func (*Dialog) CursorIndex ¶ added in v0.2.12
CursorIndex returns the currently highlighted button index.
func (*Dialog) KeyBindings ¶ added in v0.2.12
KeyBindings implements Component.
func (*Dialog) SetFocused ¶ added in v0.2.12
SetFocused implements Component.
type DialogButton ¶ added in v0.2.12
type DialogButton struct {
// Label is the text shown on the button.
Label string
// Action is called when the button is activated. Optional.
Action func()
}
DialogButton represents a button in a Dialog.
type DialogOpts ¶ added in v0.2.12
type DialogOpts struct {
// Title is optional text rendered in the top border.
Title string
// Body is the main content of the dialog.
Body string
// Buttons are the action buttons shown at the bottom.
// If empty, a single "OK" button that closes the dialog is added.
Buttons []DialogButton
// OnClose is called when the dialog is dismissed (Esc or button action).
OnClose func()
}
DialogOpts configures a Dialog.
type DualPane ¶
type DualPane struct {
Main Component // Main pane component
Side Component // Sidebar component
MainName string // Display name for focus badge (default: "Main")
SideName string // Display name for focus badge (default: "Side")
SideWidth int // Fixed width of the sidebar
MinMainWidth int // Sidebar auto-hides below this main width
SideRight bool // true = sidebar on right, false = on left
ToggleKey string // Key to toggle sidebar visibility
// contains filtered or unexported fields
}
DualPane is a layout with a main component and a collapsible sidebar.
type FeatureFlag ¶ added in v0.2.24
type FeatureFlag struct {
// contains filtered or unexported fields
}
FeatureFlag provides runtime feature toggling for blit applications.
Use feature flags to gate experimental components, A/B test UI behavior, or conditionally enable functionality without rebuilding. Flags can be set programmatically or via environment variables (BLIT_FLAG_<NAME>=1).
Flag resolution order (first match wins):
- Explicit override set via Set or WithFeatureFlags
- Environment variable BLIT_FLAG_<NAME> (1 = enabled, 0 = disabled)
- Default value from the flag definition
func NewFeatureFlag ¶ added in v0.2.24
func NewFeatureFlag(defs ...FlagDef) *FeatureFlag
NewFeatureFlag creates a flag registry with the given definitions. Each entry is (name, defaultValue, description).
func (*FeatureFlag) Clear ¶ added in v0.2.24
func (ff *FeatureFlag) Clear(name string)
Clear removes an explicit override, reverting to env/default resolution.
func (*FeatureFlag) Describe ¶ added in v0.2.24
func (ff *FeatureFlag) Describe(name string) string
Describe returns the description for a flag, or "" if undefined.
func (*FeatureFlag) Enabled ¶ added in v0.2.24
func (ff *FeatureFlag) Enabled(name string) bool
Enabled returns whether the named flag is active.
Resolution: explicit override → env var BLIT_FLAG_<NAME> → default. Returns false for unknown flag names.
func (*FeatureFlag) Names ¶ added in v0.2.24
func (ff *FeatureFlag) Names() []string
Names returns all defined flag names.
func (*FeatureFlag) Set ¶ added in v0.2.24
func (ff *FeatureFlag) Set(name string, enabled bool)
Set overrides a flag value. The value persists until Clear is called.
func (*FeatureFlag) Snapshot ¶ added in v0.2.24
func (ff *FeatureFlag) Snapshot() map[string]bool
Snapshot returns a map of all flags and their current resolved values.
type Field ¶
type Field interface {
FieldID() string
Label() string
Value() string
SetValue(v string)
Validate() error
Init() tea.Cmd
Update(msg tea.Msg) tea.Cmd
View(focused bool, theme Theme, width int) string
SetFocused(focused bool)
}
Field is the interface all form field types implement.
type FilePicker ¶
type FilePicker struct {
// contains filtered or unexported fields
}
FilePicker wraps a Tree over the local filesystem with lazy-loaded children and a Picker-style fuzzy search box.
func NewFilePicker ¶
func NewFilePicker(opts FilePickerOpts) *FilePicker
NewFilePicker creates a FilePicker rooted at opts.Root (defaults to ".").
func (*FilePicker) KeyBindings ¶
func (fp *FilePicker) KeyBindings() []KeyBind
KeyBindings implements Component.
func (*FilePicker) SetFocused ¶
func (fp *FilePicker) SetFocused(f bool)
SetFocused implements Component.
type FilePickerOpts ¶
type FilePickerOpts struct {
// Root is the starting directory. Defaults to the current directory.
Root string
// PreviewPane renders a file preview pane on the right when true.
PreviewPane bool
// ShowHidden shows hidden files (dot-prefixed) when true.
ShowHidden bool
// OnSelect is called when the user presses Enter on a file node. Optional.
OnSelect func(path string)
// OnCancel is called when the user cancels. Optional.
OnCancel func()
}
FilePickerOpts configures FilePicker behaviour.
type FilterFunc ¶
FilterFunc returns true if a row should be visible. Used for predicate-based filtering (e.g., show only gainers, filter by type).
type FlagDef ¶ added in v0.2.24
type FlagDef struct {
// Name is the flag identifier. Must be uppercase snake_case (e.g. "NEW_TABLE").
Name string
// Default is the value when no override or env var is set.
Default bool
// Description explains what the flag controls.
Description string
}
FlagDef describes a single feature flag.
type Flex ¶
Flex wraps a Component that grows proportionally to fill remaining space. Grow is the relative weight — a child with Grow=2 gets twice as much space as one with Grow=1.
func (Flex) KeyBindings ¶
KeyBindings returns the key bindings for the Flex.
func (Flex) SetFocused ¶
SetFocused sets the focus state of the Flex.
func (Flex) SetTheme ¶ added in v0.1.3
SetTheme implements Themed by delegating to the wrapped component.
type FlexAlign ¶
type FlexAlign int
FlexAlign controls cross-axis alignment for HBox/VBox children.
const ( // FlexAlignStart aligns children to the start of the cross axis. FlexAlignStart FlexAlign = iota // FlexAlignCenter centers children on the cross axis. FlexAlignCenter // FlexAlignEnd aligns children to the end of the cross axis. FlexAlignEnd // FlexAlignStretch stretches children to fill the cross axis. FlexAlignStretch )
type FlexJustify ¶
type FlexJustify int
FlexJustify controls main-axis distribution for HBox/VBox children.
const ( // FlexJustifyStart packs children toward the start. FlexJustifyStart FlexJustify = iota // FlexJustifyCenter packs children in the center. FlexJustifyCenter // FlexJustifyEnd packs children toward the end. FlexJustifyEnd // FlexJustifySpaceBetween distributes children with equal gaps between them. FlexJustifySpaceBetween // FlexJustifySpaceAround distributes children with equal space around each. FlexJustifySpaceAround )
type FloatingOverlay ¶
type FloatingOverlay interface {
Overlay
// FloatView receives the fully-rendered background content and returns
// the composited result with the floating panel drawn on top.
FloatView(background string) string
}
FloatingOverlay is an overlay that composites on top of the main content rather than replacing it. The App renders the normal content first, then calls FloatView with the rendered content so the overlay can composite its panel over it (e.g., a dev console, tooltip, or pop-over).
type Focus ¶
type Focus struct {
// Index is the position of the focused component in the app's focus
// order. -1 means no component has focus (e.g., an overlay is active).
Index int
// Name is an optional human-readable name for the focused component,
// sourced from WithComponent / DualPane.MainName / DualPane.SideName.
Name string
}
Focus identifies the currently focused component in the app's focus chain.
type ForcedChoice ¶
type ForcedChoice int
ForcedChoice records the user's decision on the forced gate.
const ( // ForcedChoicePending means the user has not chosen yet. ForcedChoicePending ForcedChoice = iota // ForcedChoiceUpdate means the user accepted the update. ForcedChoiceUpdate // ForcedChoiceQuit means the user declined and wants to quit. ForcedChoiceQuit )
type ForcedUpdateScreen ¶
type ForcedUpdateScreen struct {
Result *UpdateResult
Cfg UpdateConfig
Choice ForcedChoice
Width int
Height int
Message string // post-action status (e.g., "updating...", "failed: ...")
}
ForcedUpdateScreen is the full-screen gate shown when an update is Required (minimum_version marker set). The app cannot proceed until the user either updates or quits.
Wiring:
gate := NewForcedUpdateScreen(result, cfg)
if result.Required {
program := tea.NewProgram(gate)
program.Run()
}
func NewForcedUpdateScreen ¶
func NewForcedUpdateScreen(result *UpdateResult, cfg UpdateConfig) *ForcedUpdateScreen
NewForcedUpdateScreen returns a gate for the given update result and config.
func (*ForcedUpdateScreen) Init ¶
func (f *ForcedUpdateScreen) Init() tea.Cmd
Init implements tea.Model.
func (*ForcedUpdateScreen) Update ¶
Update implements tea.Model. Accepts y/u/enter to update, q/esc/ctrl+c to quit.
func (*ForcedUpdateScreen) View ¶
func (f *ForcedUpdateScreen) View() string
View implements tea.Model. Renders a centered dialog box that fills the terminal with a title, release info, and action hint line.
type Form ¶
type Form struct {
// contains filtered or unexported fields
}
Form is a TUI component that renders a collection of fields with keyboard navigation, inline validation, optional grouping, and a wizard step mode. It implements Component and Themed.
func NewForm ¶
NewForm creates a Form from the given options.
Example ¶
package main
import (
"fmt"
blit "github.com/blitui/blit"
)
func main() {
form := blit.NewForm(blit.FormOpts{
Groups: []blit.FormGroup{
{
Title: "Settings",
Fields: []blit.Field{
blit.NewTextField("name", "Name"),
blit.NewSelectField("role", "Role", []string{"admin", "user", "viewer"}),
blit.NewConfirmField("active", "Active"),
},
},
},
OnSubmit: func(values map[string]string) {
fmt.Println("submitted")
},
})
_ = form
}
Output:
func (*Form) Reset ¶
func (f *Form) Reset()
Reset clears the form submission state and returns focus to the first field.
type FormSubmitMsg ¶
FormSubmitMsg is emitted when the form is submitted successfully.
type Glyphs ¶
type Glyphs struct {
// List / tree connectors
TreeBranch string
TreeLast string
TreePipe string
TreeEmpty string
// Cursor / selection
CursorMarker string
FlashMarker string
SelectedBullet string
UnselectedBullet string
CollapsedArrow string
ExpandedArrow string
// Progress bar
BarFilled string
BarEmpty string
// Spinner frames (cycled sequentially)
SpinnerFrames []string
// Status / feedback
Check string
Cross string
Info string
Warn string
Star string
Dot string
}
Glyphs defines terminal symbols used by blit components. Two packs are provided: DefaultGlyphs (Unicode) and AsciiGlyphs. Attach a Glyphs instance to a Theme to customise all component symbols at once.
func AsciiGlyphs ¶
func AsciiGlyphs() Glyphs
AsciiGlyphs returns a pure-ASCII glyph set for terminals without Unicode support.
func DefaultGlyphs ¶
func DefaultGlyphs() Glyphs
DefaultGlyphs returns the standard Unicode glyph set.
type Gradient ¶
Gradient defines a linear color gradient between two lipgloss colors.
func (Gradient) RenderText ¶
RenderText applies the gradient across each character of the string.
type HBox ¶
type HBox struct {
Gap int // Gap in columns between children.
Align FlexAlign // Cross-axis (vertical) alignment.
Justify FlexJustify // Main-axis (horizontal) distribution.
Items []Component // Children — may be plain Component, Sized, or Flex.
// contains filtered or unexported fields
}
HBox lays out children horizontally (left → right). It implements the full Component interface and can be nested.
type HTTPResource ¶ added in v0.2.24
type HTTPResource struct {
// contains filtered or unexported fields
}
HTTPResource manages API polling with ETag caching, rate-limit parsing, and response fallback. It integrates with blit.Poller for timing and StatsCollector for observability.
Create one with NewHTTPResource, then call PollCmd to get a tea.Cmd suitable for use with Poller.
func NewHTTPResource ¶ added in v0.2.24
func NewHTTPResource(opts HTTPResourceOpts) *HTTPResource
NewHTTPResource creates a new HTTPResource with the given options.
func (*HTTPResource) DebugProvider ¶ added in v0.2.24
func (r *HTTPResource) DebugProvider() DebugDataProvider
DebugProvider returns a DebugDataProvider for this HTTPResource.
func (*HTTPResource) PollCmd ¶ added in v0.2.24
func (r *HTTPResource) PollCmd() Cmd
PollCmd returns a tea.Cmd that fetches all configured pages and returns an HTTPResultMsg. Use this as the Poller's fetch function.
func (*HTTPResource) SetStatsCollector ¶ added in v0.2.24
func (r *HTTPResource) SetStatsCollector(sc *StatsCollector)
SetStatsCollector wires a StatsCollector so that fetch results are automatically tracked. Optional but recommended.
func (*HTTPResource) Stats ¶ added in v0.2.24
func (r *HTTPResource) Stats() StatsSnapshot
HTTPResourceStats returns the stats snapshot for this resource.
type HTTPResourceOpts ¶ added in v0.2.24
type HTTPResourceOpts struct {
// Name identifies this resource in DevConsole and log messages.
Name string
// BuildURL returns the URL to fetch for the given page number (1-indexed).
BuildURL func(page int) string
// Parse decodes the response body into an arbitrary result.
// The returned value is typically wrapped in a tea.Msg by the caller.
Parse func(body []byte) (any, error)
// ExtraHeaders returns additional HTTP headers for each request.
// Use this for authentication tokens.
ExtraHeaders func() map[string]string
// Pages is the number of pages to fetch per poll cycle. Default: 1.
Pages int
// PageSize is the per_page query parameter. Default: 30.
PageSize int
// Parallel fetches pages concurrently when Pages > 1. Default: true.
Parallel bool
// CacheResponses enables caching the last successful response per URL
// and falling back to it on failure. Default: true.
CacheResponses bool
// OnRateLimit is called when rate limit info is parsed from response
// headers. Optional.
OnRateLimit func(remaining, limit int)
}
HTTPResourceOpts configures an HTTPResource for API polling with ETag caching, rate-limit awareness, and fallback.
type HTTPResultMsg ¶ added in v0.2.24
type HTTPResultMsg struct {
Name string
Results []any
Errors []string
NotModifiedCount int
RateRemaining int
RateLimit int
}
HTTPResultMsg is the tea.Msg returned by HTTPResource.PollCmd.
func (HTTPResultMsg) HasData ¶ added in v0.2.24
func (m HTTPResultMsg) HasData() bool
HasData reports whether any page returned fresh data (not all 304s).
func (HTTPResultMsg) IsAllNotModified ¶ added in v0.2.24
func (m HTTPResultMsg) IsAllNotModified() bool
IsAllNotModified reports whether all pages returned 304 Not Modified.
type HeaderStatusPart ¶ added in v0.2.24
HeaderStatusPart is a single segment in the status line.
func StatusPaused ¶ added in v0.2.24
func StatusPaused(theme Theme) HeaderStatusPart
StatusPaused renders a "[PAUSED]" indicator in the warn color.
func StatusPollAgo ¶ added in v0.2.24
func StatusPollAgo(ago string) HeaderStatusPart
StatusPollAgo renders a "Poll X ago" indicator in muted color.
func StatusRateLimit ¶ added in v0.2.24
func StatusRateLimit(remaining, limit int, theme Theme) HeaderStatusPart
StatusRateLimit renders a rate limit indicator with color based on remaining percentage.
type Help ¶
type Help struct {
// contains filtered or unexported fields
}
Help is an overlay that auto-generates a keybinding reference from the registry. It requires zero configuration — just call NewHelp() and register it with the App.
func (*Help) KeyBindings ¶
KeyBindings returns the key bindings for the Help.
func (*Help) SetFocused ¶
SetFocused sets the focus state of the Help.
type InlineOverlay ¶
InlineOverlay is an overlay that renders as a single line at the bottom of the screen instead of replacing all content. The App renders the normal content behind it with the overlay's View appended at the bottom.
type InputCapture ¶
type InputCapture interface {
CapturesInput() bool
}
InputCapture is implemented by components that can enter text-input mode (e.g., search, filter). When CapturesInput returns true, the App skips global keybindings and sends keys directly to the component.
type InstallMethod ¶
type InstallMethod int
InstallMethod describes how the binary was installed.
const ( // InstallManual means the binary was installed manually or via go install. InstallManual InstallMethod = iota // InstallHomebrew means the binary was installed via Homebrew. InstallHomebrew // InstallScoop means the binary was installed via Scoop. InstallScoop )
func DetectInstallMethod ¶
func DetectInstallMethod(path string) InstallMethod
DetectInstallMethod inspects a binary path to determine how it was installed.
type Kanban ¶ added in v0.2.12
type Kanban struct {
// contains filtered or unexported fields
}
Kanban is a multi-column board component for organizing cards. Implements Component and Themed.
func NewKanban ¶ added in v0.2.12
func NewKanban(columns []KanbanColumn, opts KanbanOpts) *Kanban
NewKanban creates a Kanban board with the given columns and options.
func (*Kanban) ActiveCard ¶ added in v0.2.12
ActiveCard returns the index of the focused card within the active column.
func (*Kanban) ActiveColumn ¶ added in v0.2.12
ActiveColumn returns the index of the focused column.
func (*Kanban) Columns ¶ added in v0.2.12
func (k *Kanban) Columns() []KanbanColumn
Columns returns the current columns.
func (*Kanban) KeyBindings ¶ added in v0.2.12
KeyBindings implements Component.
func (*Kanban) SetFocused ¶ added in v0.2.12
SetFocused implements Component.
type KanbanCard ¶ added in v0.2.12
type KanbanCard struct {
// ID is a unique identifier for the card.
ID string
// Title is the display text.
Title string
// Description is optional secondary text.
Description string
// Tag is an optional label shown as a badge (e.g. "bug", "feat").
Tag string
}
KanbanCard is a single card in a Kanban column.
type KanbanColumn ¶ added in v0.2.12
type KanbanColumn struct {
// Title is the column header.
Title string
// Cards are the items in this column.
Cards []KanbanCard
}
KanbanColumn is a named column containing cards.
type KanbanOpts ¶ added in v0.2.12
type KanbanOpts struct {
// OnMove is called when a card is moved between columns.
// It receives the card, source column index, and destination column index.
OnMove func(card KanbanCard, from, to int)
// OnSelect is called when enter is pressed on a card.
OnSelect func(card KanbanCard, col int)
}
KanbanOpts configures a Kanban board.
type KeyBind ¶
type KeyBind struct {
Key string // Key name: "q", "ctrl+c", "?", "/", "up", "down"
Label string // Human-readable label: "Quit", "Search", "Help"
Group string // Grouping for help screen: "NAVIGATION", "DATA", "OTHER"
Handler func() // Optional handler for app-level keybindings (nil for component bindings)
HandlerCmd func() tea.Cmd // Optional handler that returns a tea.Cmd
}
KeyBind defines a keyboard shortcut with its label and group. Components return slices of KeyBind from their KeyBindings() method. The App collects these for dispatch and auto-generates the help screen.
type Layout ¶
type Layout interface {
// contains filtered or unexported methods
}
Layout defines how components are arranged within the terminal.
type ListView ¶
type ListView[T any] struct { // contains filtered or unexported fields }
ListView is a generic scrollable list with cursor navigation, header, detail bar, and flash highlighting. It implements Component and Themed.
Use it standalone as a registered component, or embed it inside a custom component and delegate via HandleKey and View.
func NewListView ¶
func NewListView[T any](opts ListViewOpts[T]) *ListView[T]
NewListView creates a new ListView with the given options.
func (*ListView[T]) CursorIndex ¶
CursorIndex returns the current cursor position.
func (*ListView[T]) CursorItem ¶
func (l *ListView[T]) CursorItem() *T
CursorItem returns a pointer to the item at the cursor, or nil if empty.
func (*ListView[T]) HandleKey ¶
HandleKey processes navigation keys. Use this when embedding ListView in another component. Returns Consumed() if handled, nil otherwise.
func (*ListView[T]) IsAtBottom ¶
IsAtBottom returns true if the viewport is scrolled to the bottom.
func (*ListView[T]) KeyBindings ¶
KeyBindings returns the key bindings for the ListView.
func (*ListView[T]) Refresh ¶
func (l *ListView[T]) Refresh()
Refresh re-renders the list content without changing items. Use this to update flash effects or dynamic rendering.
func (*ListView[T]) ScrollToBottom ¶
func (l *ListView[T]) ScrollToBottom()
ScrollToBottom moves the cursor and viewport to the bottom.
func (*ListView[T]) ScrollToTop ¶
func (l *ListView[T]) ScrollToTop()
ScrollToTop moves the cursor and viewport to the top.
func (*ListView[T]) SetFocused ¶
SetFocused sets the focus state of the ListView.
func (*ListView[T]) SetItems ¶
func (l *ListView[T]) SetItems(items []T)
SetItems replaces the list data and rebuilds the view.
type ListViewOpts ¶
type ListViewOpts[T any] struct { // RenderItem renders a single item to a string. // Parameters: item, index in the list, whether this item has cursor, theme. RenderItem func(item T, idx int, isCursor bool, theme Theme) string // HeaderFunc renders a header above the list content. Optional. // The returned string can be multi-line. ListView accounts for its height. HeaderFunc func(theme Theme) string // DetailFunc renders a detail bar below the list for the selected item. Optional. // Only shown when the list is focused and there is a cursor item. // The returned string can be multi-line. ListView accounts for its height. DetailFunc func(item T, theme Theme) string // FlashFunc returns true if an item should show the flash marker. Optional. // Called during render with the current time for duration-based flash effects. FlashFunc func(item T, now time.Time) bool // OnSelect is called when Enter is pressed on an item. Optional. OnSelect func(item T, idx int) // DetailHeight is the number of lines to reserve for the detail bar. // When DetailFunc is set, this space is always reserved (blank when unfocused) // to prevent viewport jitter on focus change. Default: 3. DetailHeight int // EmptyText is displayed when the list has no items. If empty, the list // renders blank when there are no items (preserving existing behavior). EmptyText string }
ListViewOpts configures a ListView component.
type LogAppendMsg ¶
type LogAppendMsg struct{ Line LogLine }
LogAppendMsg is a Bubble Tea message that appends a line to the LogViewer. Use LogAppendCmd to produce this from a tea.Cmd.
type LogViewer ¶
type LogViewer struct {
// contains filtered or unexported fields
}
LogViewer is an append-only, auto-scrolling log display with level filtering, substring search, pause/resume, and goroutine-safe Append.
It implements Component and Themed.
func NewLogViewer ¶
func NewLogViewer() *LogViewer
NewLogViewer creates a new LogViewer with default settings.
Example ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
lv := blit.NewLogViewer()
lv.Append(blit.LogLine{Level: blit.LogInfo, Message: "Application started"})
lv.Append(blit.LogLine{Level: blit.LogInfo, Message: "Connected to database"})
_ = lv
}
Output:
func (*LogViewer) KeyBindings ¶
KeyBindings implements Component.
func (*LogViewer) SetFocused ¶
SetFocused implements Component.
type LoggingMetrics ¶ added in v0.2.24
LoggingMetrics is a MetricsCollector that emits structured log entries for each event. Useful for development and debugging without an external metrics backend.
func (*LoggingMetrics) OnDispatch ¶ added in v0.2.24
func (m *LoggingMetrics) OnDispatch(component string, duration time.Duration)
OnDispatch logs the dispatch duration at debug level.
func (*LoggingMetrics) OnPanic ¶ added in v0.2.24
func (m *LoggingMetrics) OnPanic(component string, recovered any)
OnPanic logs a recovered panic at error level.
func (*LoggingMetrics) OnRender ¶ added in v0.2.24
func (m *LoggingMetrics) OnRender(duration time.Duration)
OnRender logs the render duration at debug level.
type Menu ¶ added in v0.2.12
type Menu struct {
// contains filtered or unexported fields
}
Menu is a popup overlay that displays a list of selectable items. It implements the Overlay interface.
func (*Menu) CursorIndex ¶ added in v0.2.12
CursorIndex returns the currently highlighted item index.
func (*Menu) KeyBindings ¶ added in v0.2.12
KeyBindings implements Component.
func (*Menu) SetFocused ¶ added in v0.2.12
SetFocused implements Component.
type MenuItem ¶ added in v0.2.12
type MenuItem struct {
// Label is the display text.
Label string
// Shortcut is an optional key hint shown right-aligned (e.g. "ctrl+s").
Shortcut string
// Action is called when the item is activated. Optional.
Action func()
// Disabled greys out the item and prevents activation.
Disabled bool
// Separator, when true, renders this item as a horizontal divider.
// Label, Shortcut, Action, and Disabled are ignored.
Separator bool
}
MenuItem is a single entry in a Menu.
type MenuOpts ¶ added in v0.2.12
type MenuOpts struct {
// Items are the menu entries.
Items []MenuItem
// OnClose is called when the menu is dismissed.
OnClose func()
// MinWidth sets a minimum width for the menu. 0 means auto.
MinWidth int
}
MenuOpts configures a Menu.
type MetricsCollector ¶ added in v0.2.24
type MetricsCollector interface {
// OnRender is called after each frame render with the time it took
// to produce the View output for all visible components.
OnRender(duration time.Duration)
// OnDispatch is called after a tea.Msg is dispatched to a component,
// with the component name and the time taken by its Update method.
OnDispatch(component string, duration time.Duration)
// OnPanic is called when a component panics during Update or View
// and is recovered by the App's error boundary.
OnPanic(component string, recovered any)
}
MetricsCollector receives timing and event data from the App's internal lifecycle. Implement this interface to integrate with Prometheus, Datadog, OpenTelemetry, or any custom metrics backend.
All methods are optional — nil receivers are safe. The App never blocks on metric emission; collectors should offload work if needed.
type Module ¶ added in v0.1.3
type Module interface {
// Name returns a unique identifier for this module (e.g., "devConsole", "poller").
Name() string
// Init is called once before the first frame, after all modules are registered.
// Return a tea.Cmd for background initialization work (or nil).
Init() tea.Cmd
// Update receives every message the App processes. Return the updated module
// and an optional command. Modules see messages after overlays but before
// components in the dispatch order.
Update(msg tea.Msg, ctx Context) (Module, tea.Cmd)
}
Module is the interface for pluggable app extensions that participate in the App lifecycle. Modules receive messages, can emit commands, and optionally provide debug information and keybindings.
type ModuleWithKeybinds ¶ added in v0.1.3
type ModuleWithKeybinds interface {
Module
// Keybinds returns the keybindings this module contributes.
Keybinds() []KeyBind
}
ModuleWithKeybinds is an optional extension of Module that contributes keybindings to the app's registry.
type ModuleWithProviders ¶ added in v0.1.3
type ModuleWithProviders interface {
Module
// Providers returns the debug providers this module contributes.
Providers() []DebugProvider
}
ModuleWithProviders is an optional extension of Module that contributes debug providers to the DevConsole.
type MultiSelectField ¶
type MultiSelectField struct {
// contains filtered or unexported fields
}
MultiSelectField is a multi-choice field where users toggle options with space.
func NewMultiSelectField ¶
func NewMultiSelectField(id, label string, options []string) *MultiSelectField
NewMultiSelectField creates a new multi-select field.
func (*MultiSelectField) Init ¶
func (f *MultiSelectField) Init() tea.Cmd
Init initializes the MultiSelectField component.
func (*MultiSelectField) SetFocused ¶
func (f *MultiSelectField) SetFocused(_ bool)
SetFocused sets the focus state of the MultiSelectField.
func (*MultiSelectField) SetValue ¶
func (f *MultiSelectField) SetValue(v string)
SetValue sets the current value of the MultiSelectField.
func (*MultiSelectField) Update ¶
func (f *MultiSelectField) Update(msg tea.Msg) tea.Cmd
Update handles incoming messages and updates MultiSelectField state.
func (*MultiSelectField) Validate ¶
func (f *MultiSelectField) Validate() error
Validate checks the current value against the field's validation rules.
func (*MultiSelectField) Value ¶
func (f *MultiSelectField) Value() string
Value returns the current value of the MultiSelectField.
func (*MultiSelectField) View ¶
func (f *MultiSelectField) View(focused bool, theme Theme, _ int) string
View renders the MultiSelectField as a string.
func (*MultiSelectField) WithHint ¶
func (f *MultiSelectField) WithHint(hint string) *MultiSelectField
WithHint sets the hint text.
func (*MultiSelectField) WithRequired ¶
func (f *MultiSelectField) WithRequired() *MultiSelectField
WithRequired marks the field as required (at least one option must be selected).
type Node ¶
type Node struct {
// Title is the display label for this node.
Title string
// Glyph is an optional icon prefix shown before the title.
Glyph string
// Detail is optional secondary text rendered after the title.
Detail string
// Children are the child nodes. Non-nil means this node is expandable.
Children []*Node
// Data is an arbitrary payload the caller can attach.
Data any
// Expanded controls whether children are visible.
Expanded bool
// Selected marks this node as selected (used in Single/Multi selection modes).
Selected bool
}
Node is a single node in a Tree.
type NodeRenderFunc ¶ added in v0.2.12
NodeRenderFunc customises how a single node is rendered. It receives the node and whether it is currently highlighted by the cursor. Return the string that should appear in the tree line (connectors and selection indicators are still drawn by the Tree itself).
type NumberField ¶
type NumberField struct {
// contains filtered or unexported fields
}
NumberField is a text field that validates numeric input.
func NewNumberField ¶
func NewNumberField(id, label string) *NumberField
NewNumberField creates a new numeric input field.
func (*NumberField) Init ¶
func (f *NumberField) Init() tea.Cmd
Init initializes the NumberField component.
func (*NumberField) SetFocused ¶
func (f *NumberField) SetFocused(focused bool)
SetFocused sets the focus state of the NumberField.
func (*NumberField) SetValue ¶
func (f *NumberField) SetValue(v string)
SetValue sets the current value of the NumberField.
func (*NumberField) Update ¶
func (f *NumberField) Update(msg tea.Msg) tea.Cmd
Update handles incoming messages and updates NumberField state.
func (*NumberField) Validate ¶
func (f *NumberField) Validate() error
Validate checks the current value against the field's validation rules.
func (*NumberField) Value ¶
func (f *NumberField) Value() string
Value returns the current value of the NumberField.
func (*NumberField) View ¶
func (f *NumberField) View(focused bool, theme Theme, width int) string
View renders the NumberField as a string.
func (*NumberField) WithDefault ¶
func (f *NumberField) WithDefault(v float64) *NumberField
WithDefault sets the initial numeric value.
func (*NumberField) WithHint ¶
func (f *NumberField) WithHint(hint string) *NumberField
WithHint sets the hint text.
func (*NumberField) WithMax ¶
func (f *NumberField) WithMax(max float64) *NumberField
WithMax sets the maximum numeric value.
func (*NumberField) WithMin ¶
func (f *NumberField) WithMin(min float64) *NumberField
WithMin sets the minimum numeric value.
func (*NumberField) WithPlaceholder ¶
func (f *NumberField) WithPlaceholder(p string) *NumberField
WithPlaceholder sets the placeholder text.
func (*NumberField) WithRequired ¶
func (f *NumberField) WithRequired() *NumberField
WithRequired marks the field as required.
type Option ¶
type Option func(*appModel)
Option configures an App.
func WithAnimations ¶
WithAnimations enables or disables the internal animation tick bus (~60fps). Setting BLIT_NO_ANIM=1 in the environment overrides this to false.
func WithAutoUpdate ¶
func WithAutoUpdate(cfg UpdateConfig) Option
WithAutoUpdate enables automatic update checking on app startup. In UpdateNotify mode, a notification is shown if an update is available. In UpdateBlocking mode, the user is prompted in stdout before the TUI starts.
func WithClock ¶ added in v0.2.24
WithClock sets the Clock implementation available to all components via Context.Clock. Useful for testing with a FakeClock. If not set, components should fall back to time.Now directly.
func WithComponent ¶
WithComponent registers a named component with the App.
Slot mapping: the first call populates SlotMain; subsequent calls stack additional components that share focus cycling with Main.
func WithDebugProvider ¶ added in v0.1.3
func WithDebugProvider(p DebugProvider) Option
WithDebugProvider registers a standalone debug provider with the DevConsole. For providers that are part of a module, implement ModuleWithProviders instead.
func WithDevConsole ¶
func WithDevConsole() Option
WithDevConsole enables the dev console overlay on an App. The console is also auto-enabled when BLIT_DEVCONSOLE=1 is set in the environment. When this option is not provided and the env var is not set, the console costs nothing at runtime.
func WithFeatureFlags ¶ added in v0.2.24
func WithFeatureFlags(ff *FeatureFlag) Option
WithFeatureFlags registers a FeatureFlag registry with the App. Components can check flags via Context.Flags to conditionally enable or disable behavior at runtime.
func WithFocusCycleKey ¶
WithFocusCycleKey changes the key used to cycle focus between panes. Default is "tab". Set to "" to disable focus cycling entirely.
func WithHelp ¶
func WithHelp() Option
WithHelp enables the auto-generated help overlay (toggle with '?').
func WithKeyBind ¶
WithKeyBind adds a global keybinding with an optional handler. If Handler is set, it's called when the key is pressed. The binding also appears in the auto-generated help screen.
func WithLayout ¶
WithLayout sets a dual-pane layout.
Slot mapping: DualPane.Main -> SlotMain, DualPane.Side -> SlotSidebar.
func WithLogger ¶ added in v0.2.24
WithLogger sets a structured logger that is available to all components via Context.Logger. If not set, Context.Logger is nil (components should treat nil as "logging disabled").
func WithMetrics ¶ added in v0.2.24
func WithMetrics(collector MetricsCollector) Option
WithMetrics attaches a MetricsCollector that receives timing and event data from the App's internal lifecycle. Use it to integrate with Prometheus, Datadog, OpenTelemetry, or the built-in LoggingMetrics.
func WithModule ¶ added in v0.1.3
WithModule registers a module with the App. Modules are initialized in registration order during Init and receive all messages during Update.
Example ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
// Modules extend the App with custom lifecycle behavior.
// Built-in modules include the DevConsole and Poller.
app := blit.NewApp(
blit.WithTheme(blit.DefaultTheme()),
blit.WithDevConsole(),
)
_ = app
}
Output:
func WithMouseSupport ¶
func WithMouseSupport() Option
WithMouseSupport enables mouse event tracking.
func WithOnError ¶ added in v0.2.24
WithOnError registers a callback invoked when a component panics during Update or View and is recovered by the App's error boundary. The hook receives the component name and the recovered panic value. Use it to integrate with Sentry, Bugsnag, Rollbar, or any error tracking backend.
func WithOverlay ¶
WithOverlay registers a named overlay with an explicit trigger key. Press triggerKey to open the overlay; Esc closes it.
Slot mapping: the overlay is pushed onto SlotOverlay.
func WithSlot ¶
WithSlot binds a component to a named slot. This is the canonical way to compose an App shell in v0.10+.
Behaviour per slot:
- SlotMain, SlotSidebar, SlotHeader, SlotFooter, SlotToast — single occupant; calling WithSlot twice replaces the previous value.
- SlotOverlay — stacks; each WithSlot call pushes another overlay. Use WithSlotOverlay to attach a trigger key.
When both SlotMain and SlotSidebar are populated, the App implicitly wires them into a DualPane. Use WithLayout directly if you need to customise widths, toggle keys, or side placement.
func WithSlotOverlay ¶
WithSlotOverlay pushes an overlay into SlotOverlay with an associated trigger key and display name. It is the slot-native equivalent of WithOverlay.
func WithStatusBar ¶
WithStatusBar adds a status bar at the bottom of the screen.
left and right are legacy `func() string` closures. For reactive status bar content driven by signals, use WithStatusBarSignal.
Slot mapping: the resulting StatusBar is bound to SlotFooter.
func WithStatusBarSignal ¶
WithStatusBarSignal adds a status bar whose left and right content are driven by *Signal[string]. Either may be nil. Prefer this over WithStatusBar when the values change asynchronously (background polling, websocket streams, etc.) — updates collapse into one notification per frame thanks to Signal's dirty-bit coalescing.
func WithThemeHotReload ¶
WithThemeHotReload returns an AppOption that watches the YAML file at path and live-reloads the theme whenever the file changes. The reload is debounced by 200 ms. If the file cannot be parsed the current theme is kept and an error toast is shown.
func WithTickInterval ¶
WithTickInterval enables periodic tick messages at the given interval. Components receive TickMsg in their Update method.
type Orientation ¶
type Orientation int
Orientation controls whether Split divides the space horizontally or vertically.
const ( // Horizontal splits left/right (A on left, B on right). Horizontal Orientation = iota // Vertical splits top/bottom (A on top, B on bottom). Vertical )
type Overlay ¶
type Overlay interface {
Component
// IsActive returns whether this overlay is currently visible.
IsActive() bool
// Close hides this overlay.
Close()
}
Overlay is a modal view that stacks on top of the main UI. The App manages an overlay stack — Esc pops the top overlay.
type PasswordField ¶
type PasswordField struct {
// contains filtered or unexported fields
}
PasswordField is a single-line text input that masks its value.
func NewPasswordField ¶
func NewPasswordField(id, label string) *PasswordField
NewPasswordField creates a new password input field.
func (*PasswordField) Init ¶
func (f *PasswordField) Init() tea.Cmd
Init initializes the PasswordField component.
func (*PasswordField) SetFocused ¶
func (f *PasswordField) SetFocused(focused bool)
SetFocused sets the focus state of the PasswordField.
func (*PasswordField) SetValue ¶
func (f *PasswordField) SetValue(v string)
SetValue sets the current value of the PasswordField.
func (*PasswordField) Update ¶
func (f *PasswordField) Update(msg tea.Msg) tea.Cmd
Update handles incoming messages and updates PasswordField state.
func (*PasswordField) Validate ¶
func (f *PasswordField) Validate() error
Validate checks the current value against the field's validation rules.
func (*PasswordField) Value ¶
func (f *PasswordField) Value() string
Value returns the current value of the PasswordField.
func (*PasswordField) View ¶
func (f *PasswordField) View(focused bool, theme Theme, width int) string
View renders the PasswordField as a string.
func (*PasswordField) WithHint ¶
func (f *PasswordField) WithHint(hint string) *PasswordField
WithHint sets the hint text.
func (*PasswordField) WithPlaceholder ¶
func (f *PasswordField) WithPlaceholder(p string) *PasswordField
WithPlaceholder sets the placeholder text.
func (*PasswordField) WithRequired ¶
func (f *PasswordField) WithRequired() *PasswordField
WithRequired marks the field as required.
func (*PasswordField) WithValidator ¶
func (f *PasswordField) WithValidator(v Validator) *PasswordField
WithValidator attaches a validator function.
type Picker ¶
type Picker struct {
// contains filtered or unexported fields
}
Picker is a fuzzy-searchable command palette that can be used as either a full-screen Overlay (Cmd-K style) or as an embedded Component.
func NewPicker ¶
func NewPicker(items []PickerItem, opts PickerOpts) *Picker
NewPicker creates a Picker with the given items and options.
Example ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
items := []blit.PickerItem{
{Title: "Dark", Value: "dark"},
{Title: "Light", Value: "light"},
{Title: "Retro", Value: "retro"},
}
picker := blit.NewPicker(items, blit.PickerOpts{
Placeholder: "Choose a theme...",
})
_ = picker
}
Output:
func (*Picker) CursorItem ¶
func (p *Picker) CursorItem() *PickerItem
CursorItem returns the currently highlighted item, or nil if there are none.
func (*Picker) Items ¶
func (p *Picker) Items() []PickerItem
Items returns the full (unfiltered) item list.
func (*Picker) KeyBindings ¶
KeyBindings implements Component.
func (*Picker) SetItems ¶
func (p *Picker) SetItems(items []PickerItem)
SetItems replaces the item list and re-runs the filter.
type PickerItem ¶
type PickerItem struct {
// Title is the primary display label.
Title string
// Subtitle is secondary text shown below the title. Optional.
Subtitle string
// Glyph is an optional icon/glyph prefix.
Glyph string
// Preview returns content shown in the preview pane when this item is
// highlighted. Called lazily on cursor change. Optional.
Preview func() string
// Value is an arbitrary payload the caller can attach.
Value any
}
PickerItem is a single entry in a Picker.
type PickerOpts ¶
type PickerOpts struct {
// Placeholder text shown in the filter input when empty.
Placeholder string
// Preview enables the right-side preview pane (40% width).
Preview bool
// OnConfirm is called when the user presses Enter on an item. Optional.
OnConfirm func(item PickerItem)
// OnCancel is called when the user closes the picker without confirming.
OnCancel func()
}
PickerOpts configures Picker behaviour.
type Poller ¶
type Poller struct {
// contains filtered or unexported fields
}
Poller manages periodic command execution on top of blit's TickMsg. Create one with NewPoller, then call Check from your component's Update when it receives a TickMsg. The Poller handles interval timing, pause/resume, and force-refresh.
For enhanced features (rate limiting, backoff, DevConsole integration), use NewPollerWithOpts.
func NewPoller ¶
NewPoller creates a Poller that runs cmd at the given interval using the real system clock. For deterministic tests, use NewPollerWithClock.
Example ¶
package main
import (
"time"
tea "github.com/charmbracelet/bubbletea"
blit "github.com/blitui/blit"
)
func main() {
fetchData := func() tea.Cmd {
return func() tea.Msg {
return "fetched"
}
}
poller := blit.NewPoller(30*time.Second, fetchData)
// In your component's Update:
// case blit.TickMsg:
// return m, poller.Check(msg.(blit.TickMsg))
_ = poller
}
Output:
func NewPollerWithClock ¶
NewPollerWithClock creates a Poller that uses the supplied Clock for all timing decisions. Pass a FakeClock in tests to advance time deterministically. A nil clock is treated as the real clock.
func NewPollerWithOpts ¶ added in v0.1.3
func NewPollerWithOpts(opts PollerOpts) *Poller
NewPollerWithOpts creates an enhanced Poller configured via PollerOpts. The enhanced Poller supports rate limiting, backoff strategies, error tracking, and DevConsole integration. The returned Poller is fully compatible with the existing Check/Pause/Resume API.
Example ¶
package main
import (
"time"
tea "github.com/charmbracelet/bubbletea"
blit "github.com/blitui/blit"
)
func main() {
poller := blit.NewPollerWithOpts(blit.PollerOpts{
Name: "api-events",
Interval: 30 * time.Second,
Fetch: func() (tea.Msg, error) {
return "events fetched", nil
},
Backoff: blit.ExponentialBackoff(time.Second, 5*time.Minute),
MaxRetries: 3,
})
_ = poller
}
Output:
Example (FetchCtx) ¶
package main
import (
"context"
"time"
tea "github.com/charmbracelet/bubbletea"
blit "github.com/blitui/blit"
)
func main() {
poller := blit.NewPollerWithOpts(blit.PollerOpts{
Name: "api-events",
Interval: 30 * time.Second,
FetchCtx: func(ctx context.Context) (tea.Msg, error) {
// Use ctx for HTTP request cancellation, timeouts, etc.
return "events fetched", nil
},
Backoff: blit.ExponentialBackoff(time.Second, 5*time.Minute),
MaxRetries: 3,
})
_ = poller
}
Output:
func (*Poller) Check ¶
Check should be called from your component's Update when receiving a TickMsg. Returns a tea.Cmd if it's time to poll, nil otherwise. ForceRefresh takes priority and works even when paused. For enhanced pollers, rate limiting is respected (except on ForceRefresh). Enhanced pollers emit a PollerStartMsg before the fetch begins.
func (*Poller) ClearRateLimit ¶ added in v0.1.3
func (p *Poller) ClearRateLimit()
ClearRateLimit removes the rate limit flag.
func (*Poller) DebugProvider ¶ added in v0.1.3
func (p *Poller) DebugProvider() DebugDataProvider
DebugProvider returns a DebugDataProvider for this Poller suitable for registration with the DevConsole. Returns nil for non-enhanced pollers.
func (*Poller) ForceRefresh ¶
func (p *Poller) ForceRefresh()
ForceRefresh triggers a poll on the next Check call, even if paused.
func (*Poller) NextPoll ¶ added in v0.1.3
NextPoll returns the estimated time of the next poll. Returns the zero value if the poller is paused or has never polled.
func (*Poller) Pause ¶
func (p *Poller) Pause()
Pause stops periodic polling. ForceRefresh still works when paused.
func (*Poller) SetInterval ¶
SetInterval changes the polling interval.
func (*Poller) SetRateLimited ¶ added in v0.1.3
SetRateLimited marks this poller as rate limited until resetAt. While rate limited, Check will not fire. The OnRateLimit callback is invoked if set.
func (*Poller) Stats ¶ added in v0.1.3
func (p *Poller) Stats() PollerStats
Stats returns the current state of this Poller for DevConsole display. For pollers created with NewPoller (non-enhanced), Stats returns a minimal PollerStats with interval and pause state.
func (*Poller) Stop ¶ added in v0.2.24
func (p *Poller) Stop()
Stop cancels any in-flight context-aware fetch and prevents further retries. It is safe to call Stop multiple times.
func (*Poller) TogglePause ¶
func (p *Poller) TogglePause()
TogglePause toggles between paused and active.
type PollerErrorMsg ¶ added in v0.1.3
PollerErrorMsg is sent when all retries are exhausted. When AutoToast is enabled, Toast is populated with a pre-built ToastMsg that the consumer can return as a Cmd for automatic toast display.
type PollerOpts ¶ added in v0.1.3
type PollerOpts struct {
// Name identifies this poller in DevConsole and log messages.
Name string
// Interval between poll attempts. Must be >= 100ms. Default: 30s.
Interval time.Duration
// Fetch is called on each poll. Returns a tea.Msg on success or error.
Fetch func() (tea.Msg, error)
// FetchCtx is an optional context-aware fetch function. When set, it takes
// priority over Fetch. The context is cancelled when the Poller is stopped
// or the App quits. Use this when your fetch logic needs cancellation
// support (e.g., HTTP requests with timeouts).
FetchCtx func(ctx context.Context) (tea.Msg, error)
// OnRateLimit is called when rate limiting is detected. Optional.
OnRateLimit func(resetAt time.Time)
// OnError is called when a fetch fails after all retries. Optional.
OnError func(err error)
// Backoff configures retry behavior. Default: ExponentialBackoff(1s, 5m).
Backoff BackoffStrategy
// MaxRetries is the maximum number of retry attempts. Default: 3.
MaxRetries int
// AutoToast enables automatic toast notifications on fetch errors and
// rate limiting. When true, PollerErrorMsg and PollerRateLimitedMsg
// include a pre-built Toast field that can be returned as a Cmd.
AutoToast bool
// Clock for testing. Default: real clock.
Clock Clock
}
PollerOpts configures an enhanced Poller with rate limiting and backoff.
type PollerRateLimitedMsg ¶ added in v0.1.3
PollerRateLimitedMsg is sent on rate limit detection. When AutoToast is enabled, Toast is populated with a pre-built ToastMsg that the consumer can return as a Cmd for automatic toast display.
type PollerStartMsg ¶ added in v0.1.3
type PollerStartMsg struct{ Name string }
PollerStartMsg is sent when a fetch begins.
type PollerStats ¶ added in v0.1.3
type PollerStats struct {
Name string
LastPoll time.Time
NextPoll time.Time
Interval time.Duration
IsPaused bool
ErrorCount int
ConsecutiveErrors int
LastError error
IsRateLimited bool
RateLimitReset time.Time
}
PollerStats contains the current state of a Poller for DevConsole display.
type PollerSuccessMsg ¶ added in v0.1.3
PollerSuccessMsg wraps the successful fetch result.
type Position ¶ added in v0.2.24
Position is an alias for lipgloss.Position, used for layout placement.
type ProgressBar ¶ added in v0.2.12
type ProgressBar struct {
// contains filtered or unexported fields
}
ProgressBar is a horizontal bar that fills proportionally to a value in [0,1]. It implements Component and Themed.
func NewProgressBar ¶ added in v0.2.12
func NewProgressBar(opts ProgressBarOpts, value float64) *ProgressBar
NewProgressBar creates a ProgressBar with the given options and initial value. The value is clamped to [0, 1].
func (*ProgressBar) Focused ¶ added in v0.2.12
func (p *ProgressBar) Focused() bool
Focused implements Component.
func (*ProgressBar) Increment ¶ added in v0.2.12
func (p *ProgressBar) Increment(delta float64)
Increment adds delta to the current value (clamped to [0, 1]).
func (*ProgressBar) Init ¶ added in v0.2.12
func (p *ProgressBar) Init() tea.Cmd
Init implements Component.
func (*ProgressBar) KeyBindings ¶ added in v0.2.12
func (p *ProgressBar) KeyBindings() []KeyBind
KeyBindings implements Component. ProgressBar has no key bindings.
func (*ProgressBar) SetFocused ¶ added in v0.2.12
func (p *ProgressBar) SetFocused(f bool)
SetFocused implements Component.
func (*ProgressBar) SetSize ¶ added in v0.2.12
func (p *ProgressBar) SetSize(w, h int)
SetSize implements Component.
func (*ProgressBar) SetTheme ¶ added in v0.2.12
func (p *ProgressBar) SetTheme(theme Theme)
SetTheme implements Themed.
func (*ProgressBar) SetValue ¶ added in v0.2.12
func (p *ProgressBar) SetValue(v float64)
SetValue updates the progress. The value is clamped to [0, 1].
func (*ProgressBar) Update ¶ added in v0.2.12
Update implements Component. ProgressBar is display-only and does not consume any messages.
func (*ProgressBar) Value ¶ added in v0.2.12
func (p *ProgressBar) Value() float64
Value returns the current progress value in [0, 1].
func (*ProgressBar) View ¶ added in v0.2.12
func (p *ProgressBar) View() string
View implements Component.
type ProgressBarOpts ¶ added in v0.2.12
type ProgressBarOpts struct {
// Label is optional text shown to the left of the bar.
Label string
// ShowPercent displays the percentage to the right of the bar.
ShowPercent bool
// Width overrides the bar width. If 0, the component uses its SetSize width.
Width int
}
ProgressBarOpts configures a ProgressBar.
type ProgressFunc ¶
type ProgressFunc func(received, total int64)
ProgressFunc is called during download with bytes received and total bytes. If total is -1, the content length is unknown.
type RateLimitError ¶
RateLimitError is returned when GitHub's rate limiter rejects a request. ResetAt is the wall-clock time at which the rate limit window resets (parsed from the X-RateLimit-Reset header); zero if unknown.
func (*RateLimitError) Error ¶
func (e *RateLimitError) Error() string
Error returns the error message.
type RateLimitInfo ¶ added in v0.2.24
RateLimitInfo holds rate limit status for an API.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry collects keybindings from all components and provides grouped access for the help screen and conflict detection.
type Release ¶
type Release struct {
TagName string `json:"tag_name"`
HTMLURL string `json:"html_url"`
Body string `json:"body"`
Assets []ReleaseAsset `json:"assets"`
Prerelease bool `json:"prerelease"`
}
Release represents a GitHub release.
func FetchLatestRelease ¶
FetchLatestRelease fetches the latest release from GitHub. baseURL is the API base (e.g. "https://api.github.com" or a test server URL).
func FetchLatestReleaseForChannel ¶
FetchLatestReleaseForChannel selects the appropriate release for the configured channel. Stable falls through to FetchLatestRelease for backward compatibility; non-stable channels walk /releases.
func FetchReleases ¶
FetchReleases returns the full list of releases for the repo, newest first, using the rate-limited fetcher.
func PickReleaseForChannel ¶
PickReleaseForChannel filters releases according to the update channel:
- stable: first non-prerelease release (tag without a pre-release suffix)
- beta: first release whose tag contains "-beta"
- prerelease: first release marked Prerelease=true or tag containing "-"
Returns nil if no matching release is found.
type ReleaseAsset ¶
type ReleaseAsset struct {
Name string `json:"name"`
DownloadURL string `json:"browser_download_url"`
}
ReleaseAsset represents a single asset in a GitHub release.
func MatchAsset ¶
func MatchAsset(assets []ReleaseAsset, binaryName, goos, goarch string) (ReleaseAsset, error)
MatchAsset finds the release asset matching the given binary name, OS, and architecture.
func MatchChecksumAsset ¶
func MatchChecksumAsset(assets []ReleaseAsset) (ReleaseAsset, error)
MatchChecksumAsset finds the checksums.txt asset in a release.
func MatchDeltaAsset ¶
func MatchDeltaAsset(assets []ReleaseAsset, binaryName, fromVersion, toVersion, goos, goarch string) (ReleaseAsset, error)
MatchDeltaAsset looks for a delta patch asset that upgrades fromVersion to toVersion for the given binary, OS, and architecture. Both version strings are normalized by stripping a leading "v" so callers can pass either form. Returns an error if no matching asset exists.
func MatchSigAsset ¶
func MatchSigAsset(assets []ReleaseAsset, assetName string) (ReleaseAsset, error)
MatchSigAsset finds the detached signature asset for the given asset name. GoReleaser cosign integration appends ".sig" to each asset name.
type ReleaseNotesOverlay ¶
type ReleaseNotesOverlay struct {
Title string
Version string
Lines []string
Offset int
Width int
Height int
Closed bool
// contains filtered or unexported fields
}
ReleaseNotesOverlay is a scrollable overlay that displays release notes text from an UpdateResult. It is meant to be opened from the notify banner or the forced update screen via a keybind ("n" by convention).
The overlay is self-contained: it tracks scroll offset, renders a bordered box, and closes itself when the user presses q/esc.
When a Theme has been set via SetTheme, release notes are rendered through Markdown() so that headings, code spans, and lists are styled. BREAKING and SECURITY section headings are additionally highlighted using the theme's Negative and Flash color tokens.
func NewReleaseNotesOverlay ¶
func NewReleaseNotesOverlay(version, notes string) *ReleaseNotesOverlay
NewReleaseNotesOverlay constructs an overlay for the given release notes text. Width/height default to 80x24.
func NewReleaseNotesOverlayThemed ¶
func NewReleaseNotesOverlayThemed(version, notes string, t Theme) *ReleaseNotesOverlay
NewReleaseNotesOverlayThemed is like NewReleaseNotesOverlay but immediately applies a theme so the notes are rendered through Markdown from the start.
func (*ReleaseNotesOverlay) Init ¶
func (o *ReleaseNotesOverlay) Init() tea.Cmd
Init implements tea.Model.
func (*ReleaseNotesOverlay) MaxOffset ¶
func (o *ReleaseNotesOverlay) MaxOffset() int
MaxOffset clamps scroll position to the last full page.
func (*ReleaseNotesOverlay) SetTheme ¶
func (o *ReleaseNotesOverlay) SetTheme(t Theme)
SetTheme implements the Themed interface. When set, release notes are rendered through Markdown() with BREAKING/SECURITY section highlighting.
func (*ReleaseNotesOverlay) View ¶
func (o *ReleaseNotesOverlay) View() string
View implements tea.Model.
func (*ReleaseNotesOverlay) VisibleLines ¶
func (o *ReleaseNotesOverlay) VisibleLines() int
VisibleLines returns the number of content rows rendered per frame. Two lines are reserved for the header and one for the footer, plus the border/padding (4). Minimum of 1.
type RetryErrorMsg ¶ added in v0.1.1
RetryErrorMsg is returned when all retry attempts are exhausted.
type RetryOpts ¶ added in v0.1.1
type RetryOpts struct {
// MaxAttempts is the total number of attempts (including the first).
// Must be >= 1. Default: 3.
MaxAttempts int
// Backoff is the initial delay between retries. Each subsequent retry
// doubles the delay (exponential backoff). Default: 500ms.
Backoff time.Duration
}
RetryOpts configures retry behavior for RetryCmd.
type RowClickHandler ¶
RowClickHandler is called when a row is clicked or Enter is pressed.
type RowStyler ¶
RowStyler returns an optional lipgloss.Style to apply to an entire row. Use this for full-row highlights (cursor, flash effects, alerts) when a CellRenderer is also in use. Return nil for no row-level styling.
type SelectField ¶
type SelectField struct {
// contains filtered or unexported fields
}
SelectField is a single-choice field rendered as a cycling selector.
func NewSelectField ¶
func NewSelectField(id, label string, options []string) *SelectField
NewSelectField creates a new select field with the given options.
func (*SelectField) Init ¶
func (f *SelectField) Init() tea.Cmd
Init initializes the SelectField component.
func (*SelectField) SetFocused ¶
func (f *SelectField) SetFocused(_ bool)
SetFocused sets the focus state of the SelectField.
func (*SelectField) SetValue ¶
func (f *SelectField) SetValue(v string)
SetValue sets the current value of the SelectField.
func (*SelectField) Update ¶
func (f *SelectField) Update(msg tea.Msg) tea.Cmd
Update handles incoming messages and updates SelectField state.
func (*SelectField) Validate ¶
func (f *SelectField) Validate() error
Validate checks the current value against the field's validation rules.
func (*SelectField) Value ¶
func (f *SelectField) Value() string
Value returns the current value of the SelectField.
func (*SelectField) View ¶
func (f *SelectField) View(focused bool, theme Theme, _ int) string
View renders the SelectField as a string.
func (*SelectField) WithDefault ¶
func (f *SelectField) WithDefault(v string) *SelectField
WithDefault sets the initially-selected option by value.
func (*SelectField) WithHint ¶
func (f *SelectField) WithHint(hint string) *SelectField
WithHint sets the hint text.
func (*SelectField) WithRequired ¶
func (f *SelectField) WithRequired() *SelectField
WithRequired marks the field as required.
func (*SelectField) WithValidator ¶
func (f *SelectField) WithValidator(v Validator) *SelectField
WithValidator attaches a validator.
type SelectionMode ¶ added in v0.2.12
type SelectionMode int
SelectionMode controls how node selection behaves in a Tree.
const ( // SelectionNone disables selection state tracking. Enter triggers OnSelect only. SelectionNone SelectionMode = iota // SelectionSingle allows at most one selected node at a time. SelectionSingle // SelectionMulti allows any number of selected nodes (checkbox style). SelectionMulti )
type ServeConfig ¶
type ServeConfig struct {
// Addr is the host:port to listen on. Defaults to ":2222".
Addr string
// HostKeyPath is the path to the ED25519 host key file.
// If empty, defaults to ~/.ssh/blit_host_ed25519 and is auto-generated
// with 0600 permissions on first run.
HostKeyPath string
// Middleware is a list of additional Wish middleware to apply after the
// built-in bubbletea and activeterm middlewares.
Middleware []wish.Middleware
// AuthorizedKeys is the path to an SSH authorized_keys file used to
// restrict access. If empty, all connections are accepted (use only in
// trusted networks).
AuthorizedKeys string
// Factory is called once per incoming SSH session to produce a fresh *App.
// Each connection gets its own App instance so state is per-connection.
Factory func() *App
}
ServeConfig configures the SSH server started by Serve.
type SetThemeMsg ¶
type SetThemeMsg struct {
Theme Theme
}
SetThemeMsg is a Bubble Tea message that asks the App to swap its theme.
type Signal ¶
type Signal[T any] struct { // contains filtered or unexported fields }
Signal is a reactive, race-safe container for a value of type T.
Writers call Set from any goroutine; Subscribers are always invoked on the UI goroutine (inside the App's tea.Msg dispatch). Multiple Set calls that land within the same frame collapse into a single notification per subscriber thanks to a dirty-bit + generation counter that coalesces pending flushes.
Signals are typically created at App construction time and passed to components that accept a *Signal[T]. Components re-read Get() in their View() method; the App schedules a re-render whenever a signal flush is processed.
Example:
status := blit.NewSignal("starting...")
app := blit.NewApp(
blit.WithStatusBarSignal(status, nil),
)
go func() {
time.Sleep(time.Second)
status.Set("ready") // safe from any goroutine
}()
func Computed ¶
Computed derives a new signal from deps. calc is re-run on the UI goroutine whenever any dep flushes; the derived signal then notifies its own subscribers.
func NewSignal ¶
NewSignal creates a signal with the given initial value.
Example ¶
package main
import (
"fmt"
blit "github.com/blitui/blit"
)
func main() {
status := blit.NewSignal("starting...")
// Read from any goroutine.
fmt.Println(status.Get())
// Write from any goroutine; subscribers fire on the UI goroutine.
status.Set("ready")
fmt.Println(status.Get())
}
Output: starting... ready
func (*Signal[T]) Get ¶
func (s *Signal[T]) Get() T
Get returns the current value. Safe to call from any goroutine.
func (*Signal[T]) Set ¶
func (s *Signal[T]) Set(v T)
Set stores v and schedules a single coalesced notification on the next flush. Safe to call from any goroutine; subscribers still run on the UI goroutine.
func (*Signal[T]) Subscribe ¶
func (s *Signal[T]) Subscribe(fn func(T)) Unsubscribe
Subscribe registers fn to receive the signal's value on every flush after Set. The callback is always invoked on the UI goroutine. The returned Unsubscribe removes the registration.
Example ¶
package main
import (
"fmt"
blit "github.com/blitui/blit"
)
func main() {
count := blit.NewSignal(0)
unsub := count.Subscribe(func(v int) {
fmt.Println("count is now", v)
})
defer unsub()
// Set triggers the subscriber on the next signal flush.
count.Set(42)
_ = count
}
Output:
type Sized ¶
type Sized struct {
W int // Fixed width (HBox) or height (VBox) in columns/rows.
C Component // The wrapped component.
}
Sized wraps a Component with a fixed size on the main axis. In HBox the size is a fixed width; in VBox it is a fixed height.
func (Sized) KeyBindings ¶
KeyBindings returns the key bindings for the Sized.
func (Sized) SetFocused ¶
SetFocused sets the focus state of the Sized.
func (Sized) SetTheme ¶ added in v0.2.24
SetTheme delegates theme propagation to the inner component if it implements Themed. This ensures runtime theme switching reaches children inside HBox/VBox layouts.
type SlotName ¶
type SlotName string
SlotName identifies a named region in the App shell.
Slots are the canonical way to assemble an App as of v0.10. Instead of juggling separate options for components, layouts, status bars, and overlays, you declare each region by name:
app := blit.NewApp(
blit.WithSlot(blit.SlotMain, table),
blit.WithSlot(blit.SlotSidebar, panel),
blit.WithSlot(blit.SlotFooter, statusBar),
blit.WithSlot(blit.SlotOverlay, configEditor),
)
The legacy options (WithComponent, WithLayout, WithStatusBar, WithOverlay) continue to work and are routed through the slot registry internally, so both styles can be mixed freely during migration. Legacy mapping:
WithComponent(name, c) -> SlotMain (first call) or stacked component list
WithLayout(&DualPane{Main:m,Side:s}) -> SlotMain = m, SlotSidebar = s
WithStatusBar(l, r) -> SlotFooter = StatusBar
WithStatusBarSignal(l, r) -> SlotFooter = StatusBar
WithOverlay(name, key, o) -> SlotOverlay (keyed by name)
Slot names are stable identifiers. Use the SlotXxx constants below rather than hard-coding strings so a typo surfaces at compile time.
const ( // SlotHeader renders above the main content area. SlotHeader SlotName = "header" // SlotMain holds the primary component. When combined with SlotSidebar, // the two form a DualPane automatically. SlotMain SlotName = "main" // SlotSidebar holds the side panel, paired with SlotMain in a DualPane. SlotSidebar SlotName = "sidebar" // areas. The built-in StatusBar is placed here by WithStatusBar. SlotFooter SlotName = "footer" // SlotOverlay holds stacked modal overlays. Multiple WithSlot calls to // SlotOverlay push additional overlays onto the stack in order. SlotOverlay SlotName = "overlay" // SlotToast is the toast stack region. Currently drives the existing // toastManager; adding a custom component here is reserved for a // future release. SlotToast SlotName = "toast" )
type SortFunc ¶
SortFunc compares two rows for custom sorting. sortCol is the current sort column index, sortAsc is the sort direction. Return true if row a should come before row b.
type SourceHealth ¶ added in v0.2.24
type SourceHealth struct {
LastSuccess bool
FailStreak int
UsingCache bool
LastFetchAt time.Time
ItemCount int
}
SourceHealth tracks the health of a single data source.
type SparklineOpts ¶
type SparklineOpts struct {
// UpStyle styles bars that are higher than the previous bar.
// If zero value, defaults to green (#00ff88).
UpStyle lipgloss.Style
// DownStyle styles bars that are lower than the previous bar.
// If zero value, defaults to red (#ff4444).
DownStyle lipgloss.Style
// NeutralStyle styles bars with no change from the previous bar.
// If zero value, defaults to dim gray (#666666).
NeutralStyle lipgloss.Style
// Mono renders all bars in a single style (NeutralStyle) instead of
// coloring by direction. Useful for detail views.
Mono bool
}
SparklineOpts configures sparkline rendering.
type Spinner ¶ added in v0.2.12
type Spinner struct {
// contains filtered or unexported fields
}
Spinner is an animated loading indicator that cycles through glyph frames. Implements Component and Themed.
func NewSpinner ¶ added in v0.2.12
func NewSpinner(opts SpinnerOpts) *Spinner
NewSpinner creates a Spinner with the given options.
func (*Spinner) KeyBindings ¶ added in v0.2.12
KeyBindings implements Component.
func (*Spinner) SetActive ¶ added in v0.2.12
SetActive starts or stops the animation. When restarted, call Init() again to schedule the next tick.
func (*Spinner) SetFocused ¶ added in v0.2.12
SetFocused implements Component.
type SpinnerOpts ¶ added in v0.2.12
type SpinnerOpts struct {
// Label is displayed next to the spinner animation.
Label string
// Interval is the time between frame advances. Defaults to 80ms.
Interval time.Duration
}
SpinnerOpts configures a Spinner.
type Split ¶
type Split struct {
// Orientation controls whether the split is left/right or top/bottom.
Orientation Orientation
// Ratio is the fraction of space given to pane A (0.0–1.0, default 0.5).
Ratio float64
// Resizable enables alt+arrow key (and mouse drag) divider movement.
Resizable bool
// A is the first child component (left or top).
A Component
// B is the second child component (right or bottom).
B Component
// contains filtered or unexported fields
}
Split is a Component that divides its space between two child components with a visible divider. When Resizable is true the divider can be moved with alt+arrow keys (or mouse drag when mouse support is enabled).
func NewSplit ¶
func NewSplit(o Orientation, ratio float64, a, b Component) *Split
NewSplit creates a Split with the given orientation, ratio, and children.
Example ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
// Create a vertical split with 30/70 ratio.
left := blit.NewLogViewer()
right := blit.NewLogViewer()
split := blit.NewSplit(blit.Vertical, 0.3, left, right)
_ = split
}
Output:
func (*Split) KeyBindings ¶
KeyBindings returns the key bindings for the Split.
func (*Split) SetFocused ¶
SetFocused sets the focus state of the Split.
type StatsCollector ¶ added in v0.2.24
type StatsCollector struct {
// contains filtered or unexported fields
}
StatsCollector is a thread-safe structured stats accumulator for API-backed TUIs. It tracks per-source success/failure counts, rate limits, and cache status, and can auto-wire into the DevConsole as a DebugDataProvider.
func NewStatsCollector ¶ added in v0.2.24
func NewStatsCollector() *StatsCollector
NewStatsCollector creates a new StatsCollector ready for use.
func (*StatsCollector) Data ¶ added in v0.2.24
func (s *StatsCollector) Data() map[string]any
Data implements DebugDataProvider.
func (*StatsCollector) DebugProvider ¶ added in v0.2.24
func (s *StatsCollector) DebugProvider() DebugDataProvider
DebugProvider returns this StatsCollector as a DebugDataProvider suitable for registration with the DevConsole.
func (*StatsCollector) Name ¶ added in v0.2.24
func (s *StatsCollector) Name() string
Name implements DebugProvider.
func (*StatsCollector) RecordCached ¶ added in v0.2.24
func (s *StatsCollector) RecordCached(source string, count int)
RecordCached records that cached data was returned for source.
func (*StatsCollector) RecordFailure ¶ added in v0.2.24
func (s *StatsCollector) RecordFailure(source string, _ error)
RecordFailure records a failed fetch from source.
func (*StatsCollector) RecordSuccess ¶ added in v0.2.24
func (s *StatsCollector) RecordSuccess(source string, count int)
RecordSuccess records a successful fetch from source with the given item count.
func (*StatsCollector) SetRateLimit ¶ added in v0.2.24
func (s *StatsCollector) SetRateLimit(remaining, limit int)
SetRateLimit updates the current rate limit info.
func (*StatsCollector) Snapshot ¶ added in v0.2.24
func (s *StatsCollector) Snapshot() StatsSnapshot
Snapshot returns a copy of the current stats.
type StatsSnapshot ¶ added in v0.2.24
type StatsSnapshot struct {
TotalCalls int
SuccessCalls int
FailedCalls int
TotalItems int
LastActivity time.Time
Sources map[string]*SourceHealth
RateLimit RateLimitInfo
}
StatsSnapshot holds a point-in-time view of all collected stats.
type StatusBar ¶
type StatusBar struct {
// contains filtered or unexported fields
}
StatusBar renders a footer bar with left and right aligned sections.
func NewStatusBar ¶
func NewStatusBar(opts StatusBarOpts) *StatusBar
NewStatusBar creates a new StatusBar with the given options.
Left and Right in opts accept either a `func() string` closure or a `*Signal[string]`. See StatusBarOpts for details.
func (*StatusBar) KeyBindings ¶
KeyBindings returns the key bindings for the StatusBar.
func (*StatusBar) SetFocused ¶
SetFocused sets the focus state of the StatusBar.
type StatusBarOpts ¶
StatusBarOpts configures a StatusBar.
Left and Right accept any value that can be converted into a StringSource: a plain `func() string` closure (legacy), a `*Signal[string]` (reactive, v0.10+), or an explicit StringSource. Nil means "empty". The overload is intentional so existing call sites keep working while new code can hand in a signal for per-frame reactivity without plumbing a getter closure that captures the signal.
type Step ¶ added in v0.2.12
type Step struct {
// Title is the step label.
Title string
// Description is optional detail text.
Description string
}
Step is a single stage in a Stepper.
type StepStatus ¶ added in v0.2.12
type StepStatus int
StepStatus describes the state of a step.
const ( // StepPending is a step that has not yet been reached. StepPending StepStatus = iota // StepActive is the step currently in progress. StepActive // StepDone is a completed step. StepDone )
type Stepper ¶ added in v0.2.12
type Stepper struct {
// contains filtered or unexported fields
}
Stepper is a multi-step progress indicator with forward/back navigation. Implements Component and Themed.
func NewStepper ¶ added in v0.2.12
func NewStepper(steps []Step, opts StepperOpts) *Stepper
NewStepper creates a Stepper with the given steps and options.
func (*Stepper) KeyBindings ¶ added in v0.2.12
KeyBindings implements Component.
func (*Stepper) Next ¶ added in v0.2.12
func (s *Stepper) Next()
Next advances to the next step. If already at the last step, calls OnComplete.
func (*Stepper) Prev ¶ added in v0.2.12
func (s *Stepper) Prev()
Prev moves back to the previous step.
func (*Stepper) SetCurrent ¶ added in v0.2.12
SetCurrent sets the active step index, clamped to valid range.
func (*Stepper) SetFocused ¶ added in v0.2.12
SetFocused implements Component.
func (*Stepper) Status ¶ added in v0.2.12
func (s *Stepper) Status(idx int) StepStatus
Status returns the status of a step at the given index.
type StepperOpts ¶ added in v0.2.12
type StepperOpts struct {
// OnComplete is called when the user advances past the last step.
OnComplete func()
// OnChange is called when the current step changes.
OnChange func(step int)
}
StepperOpts configures a Stepper.
type StringSource ¶
type StringSource interface {
Value() string
}
StringSource is a read-only source of a string value. Both plain `func() string` closures and `*Signal[string]` satisfy this contract via the adapters below, letting components like StatusBar and ConfigEditor accept either style without a breaking API change.
Use SignalString to wrap a *Signal[string] as a StringSource, or call FuncString for an explicit adapter around a closure (usually unnecessary since raw closures already satisfy the contract via toStringSource).
func FuncString ¶
func FuncString(fn func() string) StringSource
FuncString adapts a func() string closure into a StringSource.
func SignalString ¶
func SignalString(s *Signal[string]) StringSource
SignalString adapts a *Signal[string] into a StringSource so it can be passed anywhere a func() string is accepted.
type StyleSet ¶
type StyleSet struct {
Base lipgloss.Style
Hover lipgloss.Style
Focus lipgloss.Style
Disabled lipgloss.Style
Active lipgloss.Style
}
StyleSet groups the visual variants of a named component style. Components select the appropriate variant based on their current interaction state.
type Styles ¶ added in v0.2.24
type Styles struct {
// Text variants
Text Style // primary text
TextBold Style // bold primary text
Muted Style // secondary/dimmed text
Accent Style // highlighted/active text
AccentBold Style // bold accent text
// Semantic
Positive Style // green: success, online, gains
Negative Style // red: errors, offline, losses
Warn Style // yellow: warnings, caution
Info Style // blue/cyan: informational
// Structural
Title Style // bold text, left-padded
Subtitle Style // muted text, left-padded
Label Style // muted label prefix (e.g. "Type: ")
Detail Style // detail content
Hint Style // keyboard hints, dimmed
// Interactive
Cursor Style // cursor highlight row (bg)
Selected Style // selected row (bg)
Flash Style // flash background row (bg)
Border Style // border foreground
Header Style // section header, accent+bold
// Badge presets (foreground-only)
BadgePositive Style // positive badge
BadgeNegative Style // negative badge
BadgeWarn Style // warn badge
BadgeAccent Style // accent badge
BadgeMuted Style // muted badge
}
Styles holds a curated set of pre-built styles derived from a Theme. Consumers should call ThemeStyles(theme) to construct one and replace it on SetTheme.
func ThemeStyles ¶ added in v0.2.24
ThemeStyles returns a curated set of commonly-needed styles derived from the theme's semantic color tokens. Call this once on component init and again whenever the theme changes (in SetTheme).
The returned Styles struct covers the most common rendering patterns: text variants, semantic colors, structural styles, interactive states, and badge presets. Consumers can extend it with domain-specific styles using the Extra map on the Theme.
type Subcommand ¶ added in v0.2.24
type Subcommand struct {
Name string // Primary name: "add", "remove"
Aliases []string // Alternatives: ["rm"] for "remove"
Usage string // Usage text: "add <owner/repo>"
Run func(args []string) error // Handler, receives remaining args
}
Subcommand defines a single CLI subcommand.
type TabItem ¶
type TabItem struct {
// Title is the label shown in the tab bar.
Title string
// Glyph is an optional icon prefix shown before the title.
Glyph string
// Content is the component rendered when this tab is active.
Content Component
}
TabItem is a single tab entry with a title, optional glyph, and content component.
type Table ¶
type Table struct {
// contains filtered or unexported fields
}
Table is an adaptive table component with sorting, filtering, and responsive columns.
func NewTable ¶
NewTable creates a new Table component.
When opts.Virtual is true and opts.RowProvider is non-nil, the table uses a lazy windowed render path: only rows in the visible viewport are fetched from the provider per frame. The rows argument is ignored in virtual mode.
Example ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
columns := []blit.Column{
{Title: "Name", Width: 20, Sortable: true},
{Title: "Value", Width: 10, Align: blit.Right},
{Title: "Status", Width: 10},
}
rows := []blit.Row{
{"Alice", "100", "Active"},
{"Bob", "200", "Inactive"},
{"Carol", "300", "Active"},
}
table := blit.NewTable(columns, rows, blit.TableOpts{
Sortable: true,
Filterable: true,
})
_ = table
}
Output:
func (*Table) CapturesInput ¶
CapturesInput implements InputCapture. Returns true when the table is in filtering mode so that global keybindings (like q-to-quit) are bypassed and keystrokes are routed directly to the filter input.
func (*Table) CursorIndex ¶
CursorIndex returns the current cursor position.
func (*Table) CursorRow ¶
CursorRow returns the row at the current cursor position, or nil if empty.
func (*Table) FilterQuery ¶
FilterQuery returns the active built-in text search query.
func (*Table) KeyBindings ¶
KeyBindings returns the key bindings for the Table.
func (*Table) RowCount ¶
RowCount returns the total number of rows (before filtering). In virtual mode this is the provider's Len.
func (*Table) SetCursor ¶
SetCursor moves the cursor to the given index and scrolls to keep it visible.
func (*Table) SetFilter ¶
func (t *Table) SetFilter(fn FilterFunc)
SetFilter sets a predicate filter function. Pass nil to clear. This works alongside text search — both must pass for a row to be visible. No-op in virtual mode: filter inside the TableRowProvider instead.
func (*Table) SetFocused ¶
SetFocused sets the focus state of the Table.
func (*Table) SetRows ¶
SetRows replaces the table data and rebuilds the view. In virtual mode this is a no-op; update the underlying TableRowProvider instead.
func (*Table) SetSort ¶
SetSort sets the sort column and direction, then rebuilds the view. Pass col=-1 to clear sorting.
func (*Table) VisibleRowCount ¶
VisibleRowCount returns the number of rows after filtering. In virtual mode filtering is provider-driven, so this matches RowCount.
type TableOpts ¶
type TableOpts struct {
Sortable bool // Enable sort cycling with 's'
Filterable bool // Enable '/' search mode
CursorStyle CursorStyle // How the cursor is rendered
HeaderStyle lipgloss.Style // Override header style (zero value = use theme)
CellRenderer CellRenderer // Custom cell renderer (nil = plain text)
RowStyler RowStyler // Optional full-row style (applied after cell rendering)
SortFunc SortFunc // Custom sort function (nil = lexicographic)
OnRowClick RowClickHandler // Called on Enter or mouse click on a row
DetailFunc DetailRenderer // Renders inline detail bar for cursor row (nil = no detail bar)
DetailHeight int // Lines reserved for detail bar (default 3 when DetailFunc set)
OnCursorChange CursorChangeHandler // Called when cursor moves to a different row
// Virtual enables the virtualized render path. When true, only the visible
// slice of rows is materialized per frame and RowProvider supplies data
// lazily. Default false for backwards compatibility.
Virtual bool
// RowProvider supplies rows for the virtualized path. Required when
// Virtual is true. Sorting is disabled in virtual mode; implement sorting
// inside the provider if needed.
RowProvider TableRowProvider
// OnFilterChange fires whenever the built-in filter query changes. In
// virtual mode the consumer should use this to re-query the provider or
// swap in a filtered provider; the table does not filter rows itself
// when Virtual is true.
OnFilterChange func(query string)
}
TableOpts configures a Table component.
type TableRowProvider ¶
TableRowProvider lazily supplies rows for a virtualized Table. Implementations must be cheap for windowed access — only the visible slice is ever fetched per frame, enabling tables over millions of rows.
Len returns the total logical row count. Rows returns up to limit rows starting at offset; the returned slice length may be shorter at the end. Implementations should not return nil; an empty slice is acceptable.
A TableRowProvider is used only when TableOpts.Virtual is true and TableOpts.RowProvider is non-nil.
type TableRowProviderFunc ¶
TableRowProviderFunc adapts a plain function into a TableRowProvider for callers that already hold the total row count separately.
func (TableRowProviderFunc) Len ¶
func (f TableRowProviderFunc) Len() int
Len returns the configured total row count.
func (TableRowProviderFunc) Rows ¶
func (f TableRowProviderFunc) Rows(offset, limit int) []Row
Rows delegates to the underlying Fetch function.
type Tabs ¶
type Tabs struct {
// contains filtered or unexported fields
}
Tabs is a Component that shows a row or column of named tabs with switchable content panes. Keybinds: tab/shift+tab to cycle, 1-9 to jump, left-click to select.
func (*Tabs) ActiveIndex ¶
ActiveIndex returns the currently active tab index.
func (*Tabs) SetFocused ¶
SetFocused implements Component. When focused, the active content is also focused.
type TabsOpts ¶
type TabsOpts struct {
// Orientation is Horizontal (default) or Vertical.
Orientation Orientation
// OnChange is called whenever the active tab changes.
OnChange func(int)
}
TabsOpts configures a Tabs component.
type TextField ¶
type TextField struct {
// contains filtered or unexported fields
}
TextField is a single-line text input field.
func NewTextField ¶
NewTextField creates a new single-line text field.
func (*TextField) SetFocused ¶
SetFocused sets the focus state of the TextField.
func (*TextField) Validate ¶
Validate checks the current value against the field's validation rules.
func (*TextField) WithDefault ¶
WithDefault sets the initial value.
func (*TextField) WithPlaceholder ¶
WithPlaceholder sets the placeholder text.
func (*TextField) WithRequired ¶
WithRequired marks the field as required.
func (*TextField) WithValidator ¶
WithValidator attaches a validator function.
type Theme ¶
type Theme struct {
Positive lipgloss.Color // Green: gains, success, online
Negative lipgloss.Color // Red: losses, errors, offline
Accent lipgloss.Color // Highlights, active elements
Muted lipgloss.Color // Dimmed text, secondary info
Text lipgloss.Color // Primary text
TextInverse lipgloss.Color // Text on colored backgrounds
Cursor lipgloss.Color // Cursor/selection highlight
Border lipgloss.Color // Borders, separators
Flash lipgloss.Color // Temporary notification background
Warn lipgloss.Color // Warnings, caution states (yellow/amber)
Extra map[string]lipgloss.Color // App-specific color tokens
Glyphs *Glyphs // Optional glyph override; nil uses DefaultGlyphs
Borders *BorderSet // Optional border override; nil uses DefaultBorders
// contains filtered or unexported fields
}
Theme defines semantic color tokens for consistent styling across components. Components reference these tokens instead of raw colors.
func CatppuccinMochaTheme ¶
func CatppuccinMochaTheme() Theme
CatppuccinMochaTheme returns the Catppuccin Mocha colour theme.
func DefaultTheme ¶
func DefaultTheme() Theme
DefaultTheme returns a dark theme suitable for most terminal backgrounds.
Example ¶
package main
import (
"fmt"
blit "github.com/blitui/blit"
)
func main() {
theme := blit.DefaultTheme()
fmt.Println("Theme accent:", theme.Accent)
_ = theme
}
Output:
func EverforestTheme ¶ added in v0.2.22
func EverforestTheme() Theme
EverforestTheme returns the Everforest Dark colour theme.
func FromAlacritty ¶
FromAlacritty imports a Theme from an Alacritty TOML config file.
func FromIterm2 ¶
FromIterm2 imports a Theme from an iTerm2 color preset XML (.itermcolors) file.
func GruvboxDarkTheme ¶
func GruvboxDarkTheme() Theme
GruvboxDarkTheme returns the Gruvbox Dark colour theme.
func LightTheme ¶
func LightTheme() Theme
LightTheme returns a light theme for light terminal backgrounds.
func NightfoxTheme ¶ added in v0.2.22
func NightfoxTheme() Theme
NightfoxTheme returns the Nightfox colour theme.
func ParseThemeYAML ¶
ParseThemeYAML reads a YAML-encoded theme definition and returns a Theme. Missing keys fall back to DefaultTheme values. Extra keys are placed in Theme.Extra.
func SolarizedDarkTheme ¶ added in v0.2.22
func SolarizedDarkTheme() Theme
SolarizedDarkTheme returns the Solarized Dark colour theme.
func ThemeFromMap ¶
ThemeFromMap creates a Theme from a map of color names to hex values. Missing keys fall back to DefaultTheme values. Keys not matching a built-in token are placed in the Extra map.
func TokyoNightTheme ¶
func TokyoNightTheme() Theme
TokyoNightTheme returns the Tokyo Night colour theme.
func (Theme) Color ¶
Color returns an app-specific color from Extra by key, falling back to the provided default if the key does not exist.
func (*Theme) RegisterStyle ¶
RegisterStyle stores a custom StyleSet override for name on this Theme instance. Subsequent calls to Style(name) will return this override.
func (Theme) SemanticColor ¶ added in v0.2.24
SemanticColor resolves a well-known semantic color name via the Theme's Extra map, falling back to a sensible default from the base tokens when the name is not present. This lets consumers define domain-specific colors (like "info", "create", "local") in Theme.Extra and have them resolve automatically, while still working with themes that don't define them.
Well-known names and their defaults:
info → Accent create → Positive delete → Negative review → Cursor comment → Muted issue → Warn release → Flash local → Accent
type ThemeHotReload ¶
type ThemeHotReload struct {
// contains filtered or unexported fields
}
ThemeHotReload watches a YAML theme file and pushes updates to an App via the Bubble Tea program sender. It debounces rapid filesystem events by 200 ms to avoid flicker on editors that save in multiple steps. Most callers should use WithThemeHotReload; this type is exposed for testing.
func NewThemeHotReload ¶
func NewThemeHotReload(path string, sender func(msg interface{})) (*ThemeHotReload, error)
NewThemeHotReload starts a filesystem watcher on path and calls sender with ThemeHotReloadMsg or ThemeHotReloadErrMsg on every change. Call Stop when done. This is exported so tests and custom runners can use it directly; most callers should use WithThemeHotReload instead.
func (*ThemeHotReload) Stop ¶
func (hr *ThemeHotReload) Stop()
Stop shuts down the watcher and waits for the goroutine to exit.
type ThemeHotReloadErrMsg ¶
type ThemeHotReloadErrMsg struct {
Err error
}
ThemeHotReloadErrMsg is sent when the YAML file cannot be re-parsed. The App shows it as an error toast so the user sees it inline.
type ThemeHotReloadMsg ¶
type ThemeHotReloadMsg struct {
Theme Theme
}
ThemeHotReloadMsg is a Bubble Tea message used to deliver a newly parsed theme to the App on the UI goroutine after a successful file reload.
type Themed ¶
type Themed interface {
SetTheme(Theme)
}
Themed is an optional interface for components that accept a theme. The App automatically calls SetTheme on any Component or Overlay that implements this interface. Built-in components (Table, StatusBar, Help, ConfigEditor) all implement Themed. Custom components should too if they need access to the theme's semantic color tokens.
type TickMsg ¶
TickMsg is sent to all components at the configured tick interval. Use it for animations, countdowns, polling, and flash effects.
type Timeline ¶ added in v0.2.12
type Timeline struct {
// contains filtered or unexported fields
}
Timeline is a vertical or horizontal sequence of events with connectors. Implements Component and Themed.
func NewTimeline ¶ added in v0.2.12
func NewTimeline(events []TimelineEvent, opts TimelineOpts) *Timeline
NewTimeline creates a Timeline with the given events and options.
func (*Timeline) CursorIndex ¶ added in v0.2.12
CursorIndex returns the currently highlighted event index.
func (*Timeline) Events ¶ added in v0.2.12
func (t *Timeline) Events() []TimelineEvent
Events returns the current events.
func (*Timeline) KeyBindings ¶ added in v0.2.12
KeyBindings implements Component.
func (*Timeline) SetEvents ¶ added in v0.2.12
func (t *Timeline) SetEvents(events []TimelineEvent)
SetEvents replaces the events and resets the cursor.
func (*Timeline) SetFocused ¶ added in v0.2.12
SetFocused implements Component.
type TimelineEvent ¶ added in v0.2.12
type TimelineEvent struct {
// Time is the display label for the timestamp (e.g. "2024-01-15", "3:00 PM").
Time string
// Title is the event headline.
Title string
// Description is optional detail text.
Description string
// Status controls the icon/color: "done", "active", "pending", or custom.
Status string
}
TimelineEvent is a single entry in a Timeline.
type TimelineOpts ¶ added in v0.2.12
type TimelineOpts struct {
// OnSelect is called when enter is pressed on an event.
OnSelect func(event TimelineEvent, index int)
// Horizontal renders events left-to-right instead of top-to-bottom.
Horizontal bool
}
TimelineOpts configures a Timeline.
type ToastAction ¶
type ToastAction struct {
Label string
Handler func()
}
ToastAction is a labelled action button on a toast.
type ToastManagerOpts ¶
ToastManagerOpts configures the ToastManager.
type ToastMsg ¶
type ToastMsg struct {
Severity ToastSeverity
Title string
Body string
Duration time.Duration
Actions []ToastAction
}
ToastMsg triggers a toast notification via the App ToastManager.
type ToastSeverity ¶
type ToastSeverity int
ToastSeverity classifies a toast notification.
const ( SeverityInfo ToastSeverity = iota SeveritySuccess SeverityWarn SeverityError )
type Tooltip ¶ added in v0.2.12
type Tooltip struct {
// contains filtered or unexported fields
}
Tooltip is a floating text hint that composites over background content. Implements FloatingOverlay and Themed.
func NewTooltip ¶ added in v0.2.12
func NewTooltip(opts TooltipOpts) *Tooltip
NewTooltip creates a Tooltip with the given options.
func (*Tooltip) FloatView ¶ added in v0.2.12
FloatView implements FloatingOverlay. Composites the tooltip over background.
func (*Tooltip) KeyBindings ¶ added in v0.2.12
KeyBindings implements Component.
func (*Tooltip) SetAnchor ¶ added in v0.2.12
SetAnchor sets the position where the tooltip should appear.
func (*Tooltip) SetFocused ¶ added in v0.2.12
SetFocused implements Component.
type TooltipOpts ¶ added in v0.2.12
type TooltipOpts struct {
// Text is the tooltip content.
Text string
// MaxWidth limits the tooltip width. Defaults to 40.
MaxWidth int
}
TooltipOpts configures a Tooltip.
type Tree ¶
type Tree struct {
// contains filtered or unexported fields
}
Tree is a recursive Component that renders a tree of Nodes with indent connector glyphs pulled from the theme glyph pack.
func NewTree ¶
NewTree creates a Tree with the given root nodes and options.
Example ¶
package main
import (
blit "github.com/blitui/blit"
)
func main() {
nodes := []*blit.Node{
{Title: "src", Children: []*blit.Node{
{Title: "main.go"},
{Title: "app.go"},
}},
{Title: "go.mod"},
{Title: "README.md"},
}
tree := blit.NewTree(nodes, blit.TreeOpts{})
_ = tree
}
Output:
func (*Tree) ClearFilter ¶ added in v0.2.12
func (t *Tree) ClearFilter()
ClearFilter removes the active filter and rebuilds the flat view.
func (*Tree) CursorNode ¶
CursorNode returns the currently highlighted node, or nil if the tree is empty.
func (*Tree) DeselectAll ¶ added in v0.2.12
func (t *Tree) DeselectAll()
DeselectAll clears the Selected flag on every node.
func (*Tree) Filter ¶ added in v0.2.12
Filter returns the current filter query, or "" if no filter is active.
func (*Tree) SelectAll ¶ added in v0.2.12
func (t *Tree) SelectAll()
SelectAll marks every node as Selected. Only meaningful in SelectionMulti mode.
func (*Tree) SelectedNodes ¶ added in v0.2.12
SelectedNodes returns all nodes that have Selected == true, in tree order.
func (*Tree) SetFilter ¶ added in v0.2.12
SetFilter applies a search filter. Only nodes whose Title contains the query (case-insensitive) are shown, along with their ancestors. An empty query clears the filter.
type TreeOpts ¶
type TreeOpts struct {
// OnSelect is called when the user presses Enter on a node. Optional.
OnSelect func(node *Node)
// OnToggle is called when the user expands or collapses a node. Optional.
OnToggle func(node *Node)
// OnContext is called when the user triggers the context action on a node
// (default key: "c"). Optional.
OnContext func(node *Node)
// LoadChildren, if non-nil, is called the first time a node with nil
// Children is expanded. It should return the children to attach.
// This enables lazy loading of deep or dynamic trees.
LoadChildren func(node *Node) []*Node
// Selection sets the selection mode. Default is SelectionNone.
Selection SelectionMode
// RenderNode, if non-nil, overrides the default node label rendering.
// The returned string replaces the glyph+title portion of each line.
RenderNode NodeRenderFunc
}
TreeOpts configures Tree behaviour.
type Tween ¶
Tween tracks animation progress over a fixed duration. When BLIT_NO_ANIM=1, Start is a no-op and Progress always returns 1.
type Unsubscribe ¶
type Unsubscribe func()
Unsubscribe removes a previously registered Subscribe callback.
type UpdateAction ¶ added in v0.2.24
type UpdateAction int
UpdateAction represents an action the update system requests the caller to perform. Because a library must never call os.Exit, the update system returns these actions and Run() carries them out in the main function context.
const ( // UpdateActionNone means no action is required; the app starts normally. UpdateActionNone UpdateAction = iota // UpdateActionRestart means the binary was replaced and the process // should exit so the user can relaunch. UpdateActionRestart // UpdateActionAbort means the update gate or blocking prompt chose not // to update and the app should exit without starting the TUI. UpdateActionAbort )
type UpdateCache ¶
type UpdateCache struct {
CheckedAt time.Time `json:"checked_at"`
LatestVersion string `json:"latest_version"`
ReleaseURL string `json:"release_url"`
ReleaseNotes string `json:"release_notes"`
}
UpdateCache is the cached result of an update check.
func ReadCache ¶
func ReadCache(path string) (UpdateCache, error)
ReadCache reads the cached update check from disk.
type UpdateConfig ¶
type UpdateConfig struct {
Owner string // GitHub repo owner
Repo string // GitHub repo name
BinaryName string // Binary name in release assets (e.g. "cryptstream")
Version string // Current version (set via ldflags; "dev" or "" skips check)
Mode UpdateMode // UpdateNotify, UpdateBlocking, UpdateSilent, UpdateForced, UpdateDryRun
CacheTTL time.Duration // How long to cache the check result (default: 1h)
CacheDir string // Override cache directory (default: os.UserConfigDir()/<BinaryName>)
// Disabled short-circuits every update call (same effect as the
// BLIT_UPDATE_DISABLE environment variable). Useful in tests and CI.
Disabled bool
// Channel selects which releases to consider. "" or "stable" uses
// /releases/latest (GitHub's latest stable marker). "beta" and
// "prerelease" fetch /releases and filter by tag suffix so consumers
// can opt into pre-release tracks.
Channel string
// OnProgress is called during binary asset download with bytes received and total bytes.
// If nil, no progress reporting occurs.
OnProgress ProgressFunc
// OnBeforeUpdate is called immediately before SelfUpdate performs any
// write. Returning a non-nil error aborts the update with that error.
// Useful for pre-flight checks (disk space, feature flags, user confirm).
OnBeforeUpdate func() error
// OnAfterUpdate is called after a successful binary replace, before
// the process exits. Receives the old and new version strings.
OnAfterUpdate func(oldVersion, newVersion string)
// OnUpdateError is called when any update step fails. The error is
// still returned from SelfUpdate; this hook just lets consumers
// observe/telemetry the failure in-process.
OnUpdateError func(err error)
// CosignPublicKey is an optional ed25519 public key used to verify the
// detached signature (<asset>.sig) before replacing the binary. The key
// may be PEM-encoded ("-----BEGIN PUBLIC KEY-----") or bare base64.
// When empty, signature verification is skipped.
CosignPublicKey string
// APIBaseURL overrides the GitHub API URL. Leave empty for production.
// Exported for testing; not intended for consumer use.
APIBaseURL string
// EnableDeltaUpdates opts in to the bsdiff-based delta update path.
// When true, SelfUpdate first looks for a patch asset matching the
// current version and applies it locally, falling back to a full
// archive download on any failure. Default is false.
EnableDeltaUpdates bool
}
UpdateConfig configures the auto-update system.
type UpdateMode ¶
type UpdateMode int
UpdateMode controls how the update prompt behaves.
const ( // UpdateNotify shows a non-blocking notification in the TUI after startup. UpdateNotify UpdateMode = iota // UpdateBlocking prompts the user in stdout before the TUI starts. UpdateBlocking // UpdateSilent downloads and replaces the binary in the background. // The app continues running; a "restart required" banner is shown on the // next launch via the update cache. UpdateSilent // UpdateForced shows a full-screen gate that blocks app launch until the // user either updates or quits. Also triggered implicitly when a release // sets a minimum_version higher than the current version. UpdateForced // UpdateDryRun logs every action the updater would take via log.Printf // but performs no writes. Useful for debugging without risk. UpdateDryRun )
func (UpdateMode) String ¶
func (m UpdateMode) String() string
String returns the mode name for logging.
type UpdateProgress ¶
type UpdateProgress struct {
Binary string
Version string
Total int64
Downloaded int64
StartedAt time.Time
Width int
Done bool
Err error
// contains filtered or unexported fields
}
UpdateProgress is a reusable tea.Model component that renders a download progress bar for a self-update. Consumers drive it by sending UpdateProgressMsg updates; the model handles its own render.
Typical wiring inside UpdateBlocking mode:
p := NewUpdateProgress("tool", "v2.0.0", totalBytes)
// ... each time OnProgress fires:
prog.Update(UpdateProgressMsg{Downloaded: n})
fmt.Println(prog.View())
func NewUpdateProgress ¶
func NewUpdateProgress(binary, version string, total int64) *UpdateProgress
NewUpdateProgress constructs a progress component for binary/version with an expected total byte count. If total is zero or unknown, the bar degrades gracefully to an indeterminate spinner-like view.
func (*UpdateProgress) ETA ¶
func (p *UpdateProgress) ETA() time.Duration
ETA returns the estimated time remaining based on current speed. Returns 0 if speed is 0 or total is unknown.
func (*UpdateProgress) Percent ¶
func (p *UpdateProgress) Percent() float64
Percent returns the download completion ratio in [0, 1]. If total is unknown, returns 0.
func (*UpdateProgress) Speed ¶
func (p *UpdateProgress) Speed() float64
Speed returns the average bytes/sec since StartedAt.
func (*UpdateProgress) View ¶
func (p *UpdateProgress) View() string
View implements tea.Model. Renders a styled progress bar with bytes, percent, speed, and ETA.
type UpdateProgressMsg ¶
UpdateProgressMsg carries incremental progress updates into the model.
type UpdateResult ¶
type UpdateResult struct {
Available bool
CurrentVersion string
LatestVersion string
ReleaseURL string
ReleaseNotes string
InstallMethod InstallMethod
// Required is true when the release advertises a minimum_version marker
// that is newer than the current version. Consumers in UpdateForced
// mode MUST block until updated or quit when Required is true.
Required bool
}
UpdateResult holds the result of an update check.
func CheckForUpdate ¶
func CheckForUpdate(cfg UpdateConfig) (*UpdateResult, error)
CheckForUpdate checks GitHub Releases for a newer version. If the version is "dev" or empty, it attempts to read the module version from Go's embedded build info (set by go install). Returns a zero-value UpdateResult (Available=false) if no version can be determined. Network/API errors return a zero-value result with no error (fail-silent).
type VBox ¶
type VBox struct {
Gap int // Gap in rows between children.
Align FlexAlign // Cross-axis (horizontal) alignment.
Justify FlexJustify // Main-axis (vertical) distribution.
Items []Component // Children — may be plain Component, Sized, or Flex.
// contains filtered or unexported fields
}
VBox lays out children vertically (top → bottom). It implements the full Component interface and can be nested.
type Validator ¶
Validator is a function that validates a field value. Return nil if valid, or an error describing the problem.
func ComposeValidators ¶
ComposeValidators returns a Validator that runs all validators in order. The first error encountered is returned.
func EmailValidator ¶
func EmailValidator() Validator
EmailValidator returns a Validator that checks for a basic email format.
func MinLength ¶
MinLength returns a Validator that fails if the value is shorter than n characters.
func RegexValidator ¶
RegexValidator returns a Validator that checks the value against a pattern.
func Required ¶
func Required() Validator
Required returns a Validator that fails if the value is empty.
func URLValidator ¶
func URLValidator() Validator
URLValidator returns a Validator that checks for http/https URL format.
type Version ¶
Version represents a parsed semantic version.
func ParseMinimumVersion ¶
ParseMinimumVersion extracts a "minimum_version: vX.Y.Z" marker from a release body (typically Markdown). Returns the parsed Version and true on match, zero Version and false otherwise. Supports both "minimum_version" and "minimum-version", and the marker is case-insensitive.
func ParseVersion ¶
ParseVersion parses a semver string like "v1.2.3" or "1.2.3". Pre-release (-rc.1) and build metadata (+dirty, +incompatible) suffixes are stripped.
type Viewport ¶
type Viewport struct {
// Content is the full text to display (may contain newlines).
Content string
// contains filtered or unexported fields
}
Viewport is a themed scroll container for arbitrary string content. It renders a right-side scrollbar (track + thumb) pulled from the theme. Keybinds: j/k, pgup/pgdn, home/end, ctrl+u/ctrl+d, mouse wheel.
func (*Viewport) KeyBindings ¶
KeyBindings returns the key bindings for the Viewport.
func (*Viewport) ScrollBy ¶
ScrollBy moves the viewport by delta lines (positive = down, negative = up).
func (*Viewport) SetContent ¶
SetContent sets the text content and resets the scroll position.
func (*Viewport) SetFocused ¶
SetFocused sets the focus state of the Viewport.
type ViewportGlyphs ¶
ViewportGlyphs holds the scrollbar track and thumb symbols for Viewport. Falls back to defaults when nil.
type WindowSizeMsg ¶ added in v0.2.24
type WindowSizeMsg = tea.WindowSizeMsg
WindowSizeMsg is an alias for tea.WindowSizeMsg, sent on terminal resize.
Source Files
¶
- accordion.go
- anim.go
- app.go
- breadcrumb.go
- breadcrumbs.go
- chartpanel.go
- cli_router.go
- clipboard.go
- collapsible.go
- commandbar.go
- component.go
- component_helpers.go
- config.go
- config_module.go
- configeditor.go
- context.go
- detailoverlay.go
- devconsole.go
- dialog.go
- doc.go
- featureflag.go
- filepicker.go
- form.go
- glyphs.go
- gradient.go
- help.go
- http_poller.go
- kanban.go
- key_helpers.go
- keybind.go
- layout.go
- listview.go
- logviewer.go
- markdown.go
- menu.go
- metrics.go
- module.go
- notify.go
- notify_helpers.go
- overlay.go
- picker.go
- poller.go
- progressbar.go
- reexport.go
- serve.go
- signal.go
- slot.go
- spinner.go
- split.go
- stats.go
- statusbar.go
- stepper.go
- style_registry.go
- table.go
- tabs.go
- theme.go
- theme_hot_reload.go
- theme_importers.go
- theme_presets.go
- theme_styles.go
- timeline.go
- tooltip.go
- tree.go
- update_forced.go
- update_notes_overlay.go
- update_progress.go
- updater.go
- updater_channel.go
- updater_cosign.go
- updater_delta.go
- updater_minversion.go
- updater_ratelimit.go
- updater_skip.go
- utils.go
- viewport.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package btest accessibility helpers.
|
Package btest accessibility helpers. |
|
Package charts provides terminal chart components for blit.
|
Package charts provides terminal chart components for blit. |
|
Package cli provides interactive CLI primitives for tools that need more than plain stdout but less than a full Bubble Tea TUI.
|
Package cli provides interactive CLI primitives for tools that need more than plain stdout but less than a full Bubble Tea TUI. |
|
cmd
|
|
|
blit
command
Coverage overlay for btest.
|
Coverage overlay for btest. |
|
sess2tape
command
Command sess2tape converts a .tuisess file (produced by btest.SessionRecorder) into a VHS .tape script that can be fed to `vhs` to produce a GIF.
|
Command sess2tape converts a .tuisess file (produced by btest.SessionRecorder) into a VHS .tape script that can be fed to `vhs` to produce a GIF. |
|
examples
|
|
|
bigtable
command
Package main demonstrates the virtualized Table over 1,000,000 rows.
|
Package main demonstrates the virtualized Table over 1,000,000 rows. |
|
charts
command
Package main demonstrates all blit chart types in a single dashboard.
|
Package main demonstrates all blit chart types in a single dashboard. |
|
cli-demo
command
Package main demonstrates blit's cli/ package — interactive CLI primitives that work without a full-screen TUI.
|
Package main demonstrates blit's cli/ package — interactive CLI primitives that work without a full-screen TUI. |
|
dashboard
command
Package main demonstrates a full-featured blit dashboard.
|
Package main demonstrates a full-featured blit dashboard. |
|
filetree
command
|
|
|
flex
command
Package main demonstrates HBox/VBox flex layout with mixed fixed and flex children.
|
Package main demonstrates HBox/VBox flex layout with mixed fixed and flex children. |
|
form
command
Package main demonstrates the blit Form component with validators and wizard mode.
|
Package main demonstrates the blit Form component with validators and wizard mode. |
|
logview
command
Package main demonstrates the LogViewer component streaming fake logs at 50 Hz.
|
Package main demonstrates the LogViewer component streaming fake logs at 50 Hz. |
|
minimal
command
Package main demonstrates the simplest possible blit application.
|
Package main demonstrates the simplest possible blit application. |
|
monitor
command
Package main demonstrates a full-featured blit service monitor dashboard.
|
Package main demonstrates a full-featured blit service monitor dashboard. |
|
picker
command
Package main demonstrates the blit Picker as a file browser.
|
Package main demonstrates the blit Picker as a file browser. |
|
splitpane
command
Package main demonstrates the Split, Viewport, and Breadcrumbs components.
|
Package main demonstrates the Split, Viewport, and Breadcrumbs components. |
|
ssh-serve
command
Package main demonstrates hosting a blit dashboard over SSH via Charm Wish.
|
Package main demonstrates hosting a blit dashboard over SSH via Charm Wish. |
|
tabs
command
Package main demonstrates the blit Tabs component.
|
Package main demonstrates the blit Tabs component. |
|
theme-dev
command
Package main demonstrates blit's theme hot-reload feature.
|
Package main demonstrates blit's theme hot-reload feature. |
|
internal
|
|
|
fuzzy
Package fuzzy implements an fzf-inspired fuzzy scorer for command pickers.
|
Package fuzzy implements an fzf-inspired fuzzy scorer for command pickers. |
|
scaffold
Package scaffold generates blit boilerplate for a given package path.
|
Package scaffold generates blit boilerplate for a given package path. |
|
tape
Package tape converts a btest.Session into a VHS .tape script.
|
Package tape converts a btest.Session into a VHS .tape script. |
|
Package updatetest provides HTTP mocks and fake binaries for testing code that uses blit's auto-update system.
|
Package updatetest provides HTTP mocks and fake binaries for testing code that uses blit's auto-update system. |