Documentation
¶
Overview ¶
Package tuigo is a declarative, component-based terminal UI framework.
Index ¶
- Constants
- Variables
- func Clamp01(t float64) float64
- func EaseInCubic(t float64) float64
- func EaseOutCubic(t float64) float64
- func Global() func(Option) Option
- func Lerp(a, b, t float64) float64
- func Render(component Component) (err error)
- func SetTheme(t ThemeColors)
- func UseReducer[S, A any](ctx *Ctx, reducer func(S, A) S, initial S) (S, func(A))
- func UseState[T any](ctx *Ctx, initial T) (T, func(T))
- type BorderStyle
- type Color
- type Component
- type Ctx
- type Element
- func Badge(text string, bg Color) Element
- func Box(opts ...Option) Element
- func Clock(layout string) Element
- func Dialog(viewportW, viewportH, dialogW, dialogH int, title string, bodyOpts ...Option) Element
- func Divider(width int) Element
- func Fragment(children ...Element) Element
- func Menu(items []MenuItem, selected int, onSelect func(index int)) Element
- func Panel(title string, opts ...Option) Element
- func ProgressBar(fraction float64, width int) Element
- func Spinner(frame int) Element
- func Text(format string, args ...any) Element
- func With(e Element, opts ...Option) Element
- type FlexDirection
- type Key
- type MenuItem
- type MouseButton
- type MouseEvent
- type Option
- func Bold() Option
- func Border(b BorderStyle) Option
- func Children(children ...Element) Option
- func ColorBg(c Color) Option
- func ColorFg(c Color) Option
- func FlexColumn() Option
- func FlexRow() Option
- func Focusable() Option
- func Gap(n int) Option
- func Height(n int) Option
- func Italic() Option
- func Margin(n int) Option
- func MarginBottom(n int) Option
- func MarginLeft(n int) Option
- func MarginRight(n int) Option
- func MarginTop(n int) Option
- func MinHeight(n int) Option
- func MinWidth(n int) Option
- func OnAnyKey(handler func(Key)) Option
- func OnClick(handler func(MouseEvent)) Option
- func OnKey(r rune, handler func()) Option
- func OnMouse(handler func(MouseEvent)) Option
- func OnScroll(handler func(delta int)) Option
- func OnSpecialKey(k SpecialKey, handler func()) Option
- func Padding(n int) Option
- func PaddingBottom(n int) Option
- func PaddingLeft(n int) Option
- func PaddingRight(n int) Option
- func PaddingTop(n int) Option
- func Truncate() Option
- func Underline() Option
- func Width(n int) Option
- func WithKey(key string) Option
- type Overlay
- type SpecialKey
- type ThemeColors
Constants ¶
const ( KeyNone = types.KeyNone KeyEnter = types.KeyEnter KeyEsc = types.KeyEsc KeyTab = types.KeyTab KeyBackspace = types.KeyBackspace KeyDelete = types.KeyDelete KeyUp = types.KeyUp KeyDown = types.KeyDown KeyLeft = types.KeyLeft KeyRight = types.KeyRight KeyHome = types.KeyHome KeyEnd = types.KeyEnd KeyCtrlC = types.KeyCtrlC )
const ( MouseLeft = types.MouseLeft MouseMiddle = types.MouseMiddle MouseRight = types.MouseRight MouseWheelUp = types.MouseWheelUp MouseWheelDown = types.MouseWheelDown )
const ( BorderNone = types.BorderNone BorderSingle = types.BorderSingle BorderDouble = types.BorderDouble BorderRounded = types.BorderRounded )
Variables ¶
var DarkTheme = ThemeColors{ Background: RGB(16, 17, 22), Surface: RGB(28, 29, 36), SurfaceAlt: RGB(42, 44, 54), TextPrimary: ColorBrightWhite, TextMuted: ColorGray, Accent: RGB(0, 180, 216), AccentAlt: RGB(0, 216, 180), Success: ColorGreen, Warning: ColorYellow, Error: ColorRed, }
var LightTheme = ThemeColors{ Background: RGB(245, 245, 245), Surface: RGB(255, 255, 255), SurfaceAlt: RGB(225, 225, 225), TextPrimary: RGB(20, 20, 20), TextMuted: RGB(90, 90, 90), Accent: RGB(0, 110, 170), AccentAlt: RGB(0, 140, 120), Success: RGB(20, 130, 60), Warning: RGB(160, 110, 0), Error: RGB(180, 30, 30), }
var NamedThemes = map[string]ThemeColors{ "dark": DarkTheme, "light": LightTheme, }
NamedThemes indexes the built-in themes for cycling/lookup (e.g. a "/theme" command).
var RGB = types.RGB
var Theme = DarkTheme
Theme is the active palette. It starts as DarkTheme; call SetTheme to switch it — every subsequent render that reads Theme.* picks up the change immediately, since it's read fresh each render, not cached.
Functions ¶
func Clamp01 ¶ added in v0.1.8
Clamp01 clamps t to [0, 1] — animation progress is almost always a t := elapsed/duration computation that can overshoot past 1 once the animation has finished but before the caller notices and stops ticking.
func EaseInCubic ¶ added in v0.1.8
EaseInCubic is the mirror of EaseOutCubic: slow start, fast finish.
func EaseOutCubic ¶ added in v0.1.8
EaseOutCubic is a common UI motion curve: fast start, slow finish. Pass a Clamp01'd t in [0, 1].
func Lerp ¶ added in v0.1.8
Lerp linearly interpolates between a and b by t. t is not clamped — pass Clamp01(t) yourself if you need that, since some callers deliberately extrapolate (e.g. an overshoot bounce).
func UseReducer ¶
Types ¶
type BorderStyle ¶
type BorderStyle = types.BorderStyle
Re-exported so callers only ever import the tuigo package for TUIML.
type Color ¶
Re-exported so callers only ever import the tuigo package for TUIML.
const ( ColorBlack Color = 16 ColorRed Color = 1 ColorGreen Color = 2 ColorYellow Color = 3 ColorBlue Color = 4 ColorMagenta Color = 5 ColorCyan Color = 6 ColorWhite Color = 7 ColorGray Color = 8 ColorBrightRed Color = 9 ColorBrightGreen Color = 10 ColorBrightYellow Color = 11 ColorBrightBlue Color = 12 ColorBrightMagenta Color = 13 ColorBrightCyan Color = 14 ColorBrightWhite Color = 15 )
Named xterm-256 colors. Color's zero value means "unset/inherit" (see types.Color), so plain black lives at the extended-palette index 16 rather than the ambiguous 0.
type Ctx ¶
type Ctx struct {
// contains filtered or unexported fields
}
type Element ¶
Element is the tree node produced by Box, Text, and Fragment.
func Clock ¶
Clock renders the current wall-clock time formatted per the time package layout convention (e.g. "15:04:05"). Render's main loop ticks once a second specifically so a Clock element updates on its own without any user input driving a re-render.
func Dialog ¶
Dialog centers a titled Panel of exactly dialogW x dialogH within a viewportW x viewportH screen, using flex spacers on every side. It's a full-viewport takeover, not a true floating overlay — tuigo has no z-order/absolute-positioning compositing yet (see TODO.md), so a Dialog is meant to fully replace the tree it's shown in while open, not draw on top of other content.
func Divider ¶
Divider draws a horizontal rule width cells wide, e.g. to separate sections inside a Panel without a full nested border.
func Menu ¶
Menu renders a selectable list — a dropdown/popup style widget for things like a "/" slash-command palette in a chat input. It occupies its own row(s) in normal flow layout (tuigo has no floating overlays yet), so the idiomatic use is to conditionally insert it as a sibling just above/below the input it's triggered from, pushing other content rather than floating over it. Menu renders items with items[selected] highlighted. onSelect, if non-nil, fires with a row's index when it's clicked — pass nil for a keyboard-only menu.
func Panel ¶
Panel is a titled, bordered container in the spirit of a Turbo Vision / Borland-era window frame: a full-width colored title bar rather than a plain text line, so the title reads as a window's chrome instead of just another content row. The bar uses Theme.Accent — a Box, not a bare Text, since a standalone Text's ColorBg only paints behind its own characters (see renderer/draw.go's drawText), not the full row; a Box's fillBackground paints its entire rect. Pass Children(...) and any other Box options (Width, Height, Padding, ...) as opts; Border defaults to BorderRounded and FlexColumn if not overridden by a later option.
func ProgressBar ¶
ProgressBar renders a fraction in [0,1] as a two-tone bar of the given width plus a percentage label. Zero-width segments are omitted rather than passed as Width(0), since Style's zero value means "unset" (see types.Style) and would otherwise be treated as a flex child instead of literally zero-width.
func Spinner ¶
Spinner returns one frame of a braille spinner glyph. It's pure — the caller drives animation by incrementing frame (e.g. once per received key, or once per tick once TODO.md item 3's timers land) and re-rendering.
type FlexDirection ¶
type FlexDirection = types.FlexDirection
Re-exported so callers only ever import the tuigo package for TUIML.
type MenuItem ¶
type MenuItem struct {
Label string
Hint string // shown dim/right-aligned-ish after Label, e.g. a shortcut or description
}
MenuItem is one row in a Menu.
type MouseButton ¶
type MouseButton = types.MouseButton
MouseButton identifies which button (or wheel direction) a MouseEvent reports.
type MouseEvent ¶
type MouseEvent = types.MouseEvent
MouseEvent is a single mouse report: a button/wheel action at a 0-indexed cell coordinate, delivered by OnClick/OnMouse/OnScroll.
type Option ¶
type Option func(*Element)
Option mutates an Element during construction. Options apply in the order they're passed and never mutate a shared Element.
func FlexRow ¶
func FlexRow() Option
FlexRow lays out children left-to-right. It's the zero-value direction, so this option exists mainly for explicitness.
func MarginBottom ¶
func MarginLeft ¶
func MarginRight ¶
func OnClick ¶
func OnClick(handler func(MouseEvent)) Option
OnClick calls handler when the left mouse button is pressed anywhere within this Element's rendered rect. The dispatcher hit-tests using the last computed layout, so it works for Box and Text alike.
func OnMouse ¶
func OnMouse(handler func(MouseEvent)) Option
OnMouse calls handler for every mouse event that hits this Element's rendered rect, regardless of button.
func OnScroll ¶
OnScroll calls handler with -1 for wheel-up or +1 for wheel-down when the scroll wheel is used over this Element's rendered rect.
func OnSpecialKey ¶
func OnSpecialKey(k SpecialKey, handler func()) Option
func PaddingBottom ¶
func PaddingLeft ¶
func PaddingRight ¶
func PaddingTop ¶
type Overlay ¶
Overlay is one floating panel — a Picture-in-Picture widget, a toast, a popup — composited on top of the main frame at a fixed screen position. Element must carry explicit Width/Height (e.g. via the Width/Height options) since it's laid out and drawn independently of the main tree, with no parent to size it.
tuigo has no z-order/absolute-positioning support in the layout tree itself (see ARCHITECTURE.md) — Overlay is the escape hatch: it renders its own small Element tree into its own Buffer, then stamps that buffer onto the main frame after the main Draw call and before the cell diff, so only the overlay's actually-changed cells get re-flushed like anything else. It does not participate in flow layout, hit-testing, or focus; call OnClick/OnScroll on its own Element if it needs input.
type SpecialKey ¶
type SpecialKey = types.SpecialKey
type ThemeColors ¶
type ThemeColors struct {
// Surfaces
Background Color
Surface Color
SurfaceAlt Color
// Text
TextPrimary Color
TextMuted Color
// Accents
Accent Color
AccentAlt Color
// Semantic
Success Color
Warning Color
Error Color
}
ThemeColors is a small, intentional color palette for tuigo applications. Prefer theme colors over raw palette indices; use RGB only for one-off visual effects that don't belong in the theme.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
_examples
|
|
|
chat
command
Command chat is a mock two-sided chat UI demonstrating TUIML's state management (UseState), event handling (OnAnyKey/OnSpecialKey/OnScroll), and widget layer (Panel/Badge/Clock/Spinner/ProgressBar/Menu/Dialog) on top of the style/flex system.
|
Command chat is a mock two-sided chat UI demonstrating TUIML's state management (UseState), event handling (OnAnyKey/OnSpecialKey/OnScroll), and widget layer (Panel/Badge/Clock/Spinner/ProgressBar/Menu/Dialog) on top of the style/flex system. |
|
static-counter
command
Command static-counter builds a small TUIML element tree and prints its structure.
|
Command static-counter builds a small TUIML element tree and prints its structure. |
|
style-showcase
command
Command style-showcase exercises every style option (colors, text attributes, border, flex row vs column) as a reference for TUIML's style system.
|
Command style-showcase exercises every style option (colors, text attributes, border, flex row vs column) as a reference for TUIML's style system. |
|
Package asciiart decodes images (anything image.Decode supports — png/jpeg/gif via blank imports below) into terminal-friendly grids, either a grayscale character ramp or per-cell averaged RGB for truecolor block rendering.
|
Package asciiart decodes images (anything image.Decode supports — png/jpeg/gif via blank imports below) into terminal-friendly grids, either a grayscale character ramp or per-cell averaged RGB for truecolor block rendering. |
|
Package audio plays and records audio by shelling out to platform-native tools rather than linking a CGo audio backend — no C toolchain, no cross-compile headaches, consistent with tuigo's "boring, testable layers" philosophy (see the root STYLEGUIDE.md).
|
Package audio plays and records audio by shelling out to platform-native tools rather than linking a CGo audio backend — no C toolchain, no cross-compile headaches, consistent with tuigo's "boring, testable layers" philosophy (see the root STYLEGUIDE.md). |
|
Package layout computes pure Go flexbox geometry for an Element tree.
|
Package layout computes pure Go flexbox geometry for an Element tree. |
|
Package renderer turns a laid-out Element tree into a cell buffer, diffs it against the previous frame, and flushes only the changed cells to a terminal.
|
Package renderer turns a laid-out Element tree into a cell buffer, diffs it against the previous frame, and flushes only the changed cells to a terminal. |
|
Package types defines the declarative element tree shared by tuigo's layout, renderer, and reconciler packages.
|
Package types defines the declarative element tree shared by tuigo's layout, renderer, and reconciler packages. |
