Documentation
¶
Overview ¶
Package tui provides terminal user interface components.
Package tui provides terminal user interface components.
Index ¶
- Constants
- Variables
- func AnimateWordmark(w io.Writer, theme Theme)
- func AnimateWordmarkAsync(w io.Writer, theme Theme) (io.Writer, func())
- func AnimateWordmarkWith(w io.Writer, theme Theme, strategy string)
- func AnimationNames() []string
- func Confirm(message string, defaultValue bool) (bool, error)
- func ConfirmDangerous(message string) (bool, error)
- func ConfirmSetDefault(valueName string) (bool, error)
- func DetectDark() bool
- func Form(title string, fields []FormField) (map[string]string, error)
- func Input(title, placeholder string) (string, error)
- func InputRequired(title, placeholder string) (string, error)
- func MultiSelect(title string, options []SelectOption) ([]string, error)
- func Note(title, body string) error
- func RenderSnowglobe(theme Theme) string
- func RenderWordmark(theme Theme) string
- func RunWithSpinner(w io.Writer, theme Theme, message string, task func() error) error
- func Select(title string, options []SelectOption) (string, error)
- func SelectScope() (string, error)
- func SelectWithDescription(title, description string, options []SelectOption) (string, error)
- func TextArea(title, placeholder string) (string, error)
- func ThemeFilePath() string
- type AnimWriter
- type FormField
- type ItemLoader
- type Picker
- type PickerItem
- func Pick(title string, items []PickerItem) (*PickerItem, error)
- func PickAccount(accounts []PickerItem) (*PickerItem, error)
- func PickHost(hosts []PickerItem) (*PickerItem, error)
- func PickPerson(people []PickerItem) (*PickerItem, error)
- func PickProject(projects []PickerItem) (*PickerItem, error)
- func PickTodolist(todolists []PickerItem) (*PickerItem, error)
- type PickerItemsLoadedMsg
- type PickerOption
- func WithAutoSelectSingle() PickerOption
- func WithEmptyMessage(msg string) PickerOption
- func WithHelp(show bool) PickerOption
- func WithLoading(msg string) PickerOption
- func WithMaxVisible(n int) PickerOption
- func WithPickerTitle(title string) PickerOption
- func WithRecentItems(items []PickerItem) PickerOption
- type SelectOption
- type Styles
- func (s *Styles) RenderCheckbox(checked bool, label string) string
- func (s *Styles) RenderKeyValue(key, value string) string
- func (s *Styles) RenderStatus(ok bool, message string) string
- func (s *Styles) RenderTitle(title string, subtitle ...string) string
- func (s *Styles) Theme() Theme
- func (s *Styles) UpdateTheme(theme Theme)
- type Theme
- type TraceFunc
Constants ¶
const DefaultAnimation = "outline-in"
DefaultAnimation is the animation used when none is specified.
const Wordmark = "" +
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣶⣶⣶⣶⣶⣶⣦⣤⣀\n" +
"⠀⠀⠀⠀⠀⠀⠀⢀⣴⣾⣿⣿⣿⠿⠿⠛⠛⠛⠻⠿⣿⣿⣿⣦⣀\n" +
"⠀⠀⠀⠀⠀⢀⣴⣿⣿⡿⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⣿⣿⣦⡀\n" +
"⠀⠀⠀⠀⣴⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣄\n" +
"⠀⠀⢀⣼⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⡀⠀⠀⠀⠀⢻⣿⣿⣆\n" +
"⠀⢀⣾⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⠃⠀⠀⠀⠀⠀⢻⣿⣿⡄\n" +
"⠀⣼⣿⣿⠃⠀⠀⣠⣶⣿⣷⣦⣄⠀⠀⢀⣼⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⡀\n" +
"⢸⣿⣿⠇⠀⢠⣾⣿⡿⠛⠻⣿⣿⣷⣤⣾⣿⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣇\n" +
"⠈⠉⠉⠀⢠⣿⣿⡟⠁⠀⠀⠈⠻⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿\n" +
"⠀⠀⠀⢠⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡇\n" +
"⠀⠀⠀⢻⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⠇\n" +
"⠀⠀⠀⠀⠙⠿⣿⣿⣷⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣶⣿⣿⡿⠋\n" +
"⠀⠀⠀⠀⠀⠀⠈⠛⠿⣿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⡿⠟⠉\n" +
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠛⠛⠿⠿⠿⠿⠿⠿⠟⠛⠛⠉⠉"
Wordmark is a braille-art rendering of the Basecamp mountain logo.
const WordmarkLines = 14
WordmarkLines is the number of lines in the Wordmark.
const WordmarkWidth = 32
WordmarkWidth is the display width (rune count of widest line) of the Wordmark.
Variables ¶
var BrandColor = lipgloss.Color("#e8a217")
BrandColor is the fixed Basecamp brand yellow, independent of theme.
var ErrCanceled = errors.New("prompt canceled")
ErrCanceled is returned when the user dismissed a prompt — Escape or Ctrl+C. It is an answer, and callers are right to treat it as "no" rather than as a failure.
It exists so they can do that *precisely*. huh returns ErrUserAborted only for a real dismissal; a timeout, or a bubbletea or runtime failure, comes back as an ordinary error. Callers that treat every prompt error as cancellation therefore report an answer nobody gave, and exit 0 having done nothing — the same mistake as claiming an install was canceled when the prompt never appeared. Translate once here so no caller has to know huh's error values.
var ErrNotInteractive = errors.New("not an interactive terminal")
ErrNotInteractive is returned instead of launching a form when stdio cannot drive one. huh runs the form as a bubbletea program, and redirecting stdin does not make that program fail: bubbletea v1 sees a non-terminal stdin and silently opens /dev/tty instead (tea.go:590-613), so the prompt sits waiting on the real terminal — a hang for a caller that redirected stdin precisely because nobody is there to type. Where there is no controlling terminal it fails instead, but only partway through, after the earlier steps have run. Neither outcome is usable, so refuse rather than launch.
The floor lives here rather than at the call sites because a call-site audit is exactly what missed `basecamp setup`: huh calls tea.NewProgram inside form.go, so grepping for the launcher cannot see these functions at all. Gating the constructor bounds where a prompt can be reached, and covers the prompts nobody has written yet.
Functions ¶
func AnimateWordmark ¶ added in v0.3.0
AnimateWordmark draws the wordmark with a paint animation. Honors BASECAMP_ANIM to override the default strategy.
func AnimateWordmarkAsync ¶ added in v0.3.0
AnimateWordmarkAsync starts the animation in a background goroutine and returns a writer for subsequent output plus a wait function. Output written through the returned writer appears below the animating logo. Call wait before any interactive prompts or output that bypasses the returned writer. Falls back to static render (returning w unchanged and no-op wait) when not a TTY or NO_COLOR is active.
func AnimateWordmarkWith ¶ added in v0.3.0
AnimateWordmarkWith draws the wordmark using the named animation strategy. Unknown strategy names fall back to DefaultAnimation. Falls back to static render if w is not a TTY or NO_COLOR is active.
func AnimationNames ¶ added in v0.3.0
func AnimationNames() []string
AnimationNames returns the registered animation strategy names.
func ConfirmDangerous ¶
ConfirmDangerous shows a confirmation prompt for dangerous actions. Escape or Ctrl+C cancels.
func ConfirmSetDefault ¶
ConfirmSetDefault asks the user if they want to save a value as the default. Escape or Ctrl+C cancels.
func DetectDark ¶ added in v0.3.0
func DetectDark() bool
DetectDark returns true if the terminal has a dark background. Non-TTY (piped, tests, CI) defaults to true for deterministic output.
func InputRequired ¶
InputRequired shows a required text input prompt. Escape or Ctrl+C cancels.
func MultiSelect ¶
func MultiSelect(title string, options []SelectOption) ([]string, error)
MultiSelect shows a multi-select prompt. Escape or Ctrl+C cancels.
func Note ¶
Note shows an informational note. It takes no input, but huh still runs it as a bubbletea program reading os.Stdin, so it needs the same floor.
func RenderSnowglobe ¶ added in v0.10.0
RenderSnowglobe renders the current Basecamp snowglobe mark as static terminal art. Colored terminals use half-block pixels for the blue glass and green mountain; NO_COLOR uses a two-tone text rendering.
func RenderWordmark ¶ added in v0.3.0
RenderWordmark renders the wordmark in Basecamp brand yellow with "Basecamp" to the right of the logo. Returns plain text with NoColorTheme.
func RunWithSpinner ¶ added in v0.10.0
RunWithSpinner displays message while task runs on a terminal, clears the transient line when task finishes, and returns the task error. Fast tasks and non-terminal writers complete without transient output.
func Select ¶
func Select(title string, options []SelectOption) (string, error)
Select shows a single-select prompt. Escape or Ctrl+C cancels.
func SelectScope ¶
SelectScope shows a prompt for selecting the config scope (global or local). It inherits Select's floor, so it returns ErrNotInteractive off a terminal.
func SelectWithDescription ¶
func SelectWithDescription(title, description string, options []SelectOption) (string, error)
SelectWithDescription shows a select prompt with descriptions. Escape or Ctrl+C cancels.
func ThemeFilePath ¶ added in v0.2.0
func ThemeFilePath() string
ThemeFilePath returns the resolved path to the active theme file, or "" if using defaults or NO_COLOR is set.
Types ¶
type AnimWriter ¶ added in v0.3.0
type AnimWriter struct {
// contains filtered or unexported fields
}
AnimWriter is a mutex-protected io.Writer that tracks terminal rows written below the animation area. The animation goroutine uses this count to cursor-up past both the logo and any caller output, then cursor-down to restore the caller's write position. When cols > 0, it accounts for soft-wrapping at the terminal width.
func (*AnimWriter) Wait ¶ added in v0.3.0
func (aw *AnimWriter) Wait()
Wait blocks until the animation goroutine finishes. Idempotent.
type ItemLoader ¶
type ItemLoader func() ([]PickerItem, error)
ItemLoader is a function that loads items asynchronously.
type Picker ¶
type Picker struct {
// contains filtered or unexported fields
}
Picker shows a fuzzy-search picker and returns the selected item.
func NewPicker ¶
func NewPicker(items []PickerItem, opts ...PickerOption) *Picker
NewPicker creates a new picker.
func NewPickerWithLoader ¶
func NewPickerWithLoader(loader ItemLoader, opts ...PickerOption) *Picker
NewPickerWithLoader creates a picker that loads items asynchronously.
func (*Picker) Run ¶
func (p *Picker) Run() (*PickerItem, error)
Run shows the picker and returns the selected item. Returns nil if the user canceled, and ErrNotInteractive when stdio cannot drive a TUI at all — except for the single-item WithAutoSelectSingle fast path, which resolves without a TUI and so works anywhere.
type PickerItem ¶
PickerItem represents an item in a picker.
func Pick ¶
func Pick(title string, items []PickerItem) (*PickerItem, error)
Pick is a convenience function for simple picking.
func PickAccount ¶
func PickAccount(accounts []PickerItem) (*PickerItem, error)
PickAccount shows a picker for accounts.
func PickHost ¶
func PickHost(hosts []PickerItem) (*PickerItem, error)
PickHost shows a picker for hosts/environments.
func PickPerson ¶
func PickPerson(people []PickerItem) (*PickerItem, error)
PickPerson shows a picker for people.
func PickProject ¶
func PickProject(projects []PickerItem) (*PickerItem, error)
PickProject shows a picker for projects.
func PickTodolist ¶
func PickTodolist(todolists []PickerItem) (*PickerItem, error)
PickTodolist shows a picker for todolists.
func (PickerItem) FilterValue ¶
func (i PickerItem) FilterValue() string
FilterValue returns the string to filter on.
func (PickerItem) String ¶
func (i PickerItem) String() string
type PickerItemsLoadedMsg ¶
type PickerItemsLoadedMsg struct {
Items []PickerItem
Err error
}
PickerItemsLoadedMsg is sent when items are loaded asynchronously.
type PickerOption ¶
type PickerOption func(*pickerModel)
PickerOption configures a picker.
func WithAutoSelectSingle ¶
func WithAutoSelectSingle() PickerOption
WithAutoSelectSingle automatically selects and returns if only one item exists.
func WithEmptyMessage ¶
func WithEmptyMessage(msg string) PickerOption
WithEmptyMessage sets a custom message shown when no items are available.
func WithHelp ¶
func WithHelp(show bool) PickerOption
WithHelp shows keyboard shortcuts in the picker.
func WithLoading ¶
func WithLoading(msg string) PickerOption
WithLoading sets the picker to start in loading state.
func WithMaxVisible ¶
func WithMaxVisible(n int) PickerOption
WithMaxVisible sets the maximum number of visible items.
func WithPickerTitle ¶
func WithPickerTitle(title string) PickerOption
WithPickerTitle sets the picker title.
func WithRecentItems ¶
func WithRecentItems(items []PickerItem) PickerOption
WithRecentItems prepends recently used items to the list, marked with a prefix.
type SelectOption ¶
SelectOption represents an option in a select prompt.
type Styles ¶
type Styles struct {
// Text styles
Title lipgloss.Style
Subtitle lipgloss.Style
Heading lipgloss.Style
Body lipgloss.Style
Muted lipgloss.Style
Bold lipgloss.Style
Success lipgloss.Style
Warning lipgloss.Style
Error lipgloss.Style
// Container styles
Box lipgloss.Style
Card lipgloss.Style
Panel lipgloss.Style
// Interactive styles
Focused lipgloss.Style
Selected lipgloss.Style
Cursor lipgloss.Style
// Status styles
StatusOK lipgloss.Style
StatusError lipgloss.Style
StatusInfo lipgloss.Style
// contains filtered or unexported fields
}
Styles holds the styled components for the TUI.
func NewStyles ¶
func NewStyles() *Styles
NewStyles creates a new Styles with the default dark theme.
func NewStylesWithTheme ¶
NewStylesWithTheme creates a new Styles with a custom theme.
func (*Styles) RenderCheckbox ¶
RenderCheckbox renders a checkbox item.
func (*Styles) RenderKeyValue ¶
RenderKeyValue renders a key-value pair.
func (*Styles) RenderStatus ¶
RenderStatus renders a status message with appropriate styling.
func (*Styles) RenderTitle ¶
RenderTitle renders a title with optional subtitle.
func (*Styles) UpdateTheme ¶ added in v0.2.0
UpdateTheme re-applies a theme to the existing Styles in place. Because all components hold a *Styles pointer, the next View() call picks up the new colors with zero propagation.
type Theme ¶
type Theme struct {
Dark bool // how this theme was resolved (for downstream LightDark calls)
Primary color.Color
Secondary color.Color
Success color.Color
Warning color.Color
Error color.Color
Muted color.Color
Background color.Color
Foreground color.Color
Border color.Color
RoomColors []color.Color
}
Theme defines the color palette for the TUI.
func DefaultTheme ¶
DefaultTheme returns the default basecamp theme resolved for the given background.
func LoadThemeFromFile ¶
LoadThemeFromFile parses a colors.toml file and returns a Theme.
func LoadUserTheme ¶
LoadUserTheme attempts to load a theme from the user's basecamp config. The theme directory can be a symlink to another theme system.
func NoColorTheme ¶
func NoColorTheme() Theme
NoColorTheme returns a theme with empty colors (honors NO_COLOR standard). lipgloss.NoColor{} means "no styling", resulting in plain text output.
func ResolveTheme ¶
ResolveTheme loads a theme with the following precedence:
- NO_COLOR env var set → returns NoColorTheme (industry standard)
- BASECAMP_THEME env var → parse custom colors.toml file
- User theme from ~/.config/basecamp/theme/colors.toml
- Default basecamp theme
On systems like Omarchy, users can symlink to their system theme:
ln -s ~/.config/omarchy/current/theme ~/.config/basecamp/theme
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package empty provides empty state messages for TUI components.
|
Package empty provides empty state messages for TUI components. |
|
Package format provides formatting helpers for TUI components.
|
Package format provides formatting helpers for TUI components. |
|
Package recents provides a store for tracking recently used items.
|
Package recents provides a store for tracking recently used items. |
|
Package resolve provides interactive prompts for resolving missing CLI options.
|
Package resolve provides interactive prompts for resolving missing CLI options. |
|
Package workspace provides the persistent TUI application.
|
Package workspace provides the persistent TUI application. |
|
chrome
Package chrome provides always-visible shell components for the workspace.
|
Package chrome provides always-visible shell components for the workspace. |
|
views
Package views provides the individual screens for the workspace TUI.
|
Package views provides the individual screens for the workspace TUI. |
|
widget
Package widget provides reusable TUI components.
|
Package widget provides reusable TUI components. |