ui

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
 |  _ \ | __ )
 | |_) ||  _ \
 |  __/ | |_) |
 |_|    |____/ `

PBLogo is the small "PB" ASCII mark shown in the top-right of the HeaderStrip. Five lines, matches the mock in terminal/page.tsx.

Variables

View Source
var Active = LoadTheme()

Active is the process-wide palette. Set once at TUI startup.

View Source
var ActiveType = NewTypography(Active)

ActiveType is the process-wide Typography. Rebuilt on SetActive.

View Source
var Dark = Palette{
	Bg:       "#0B0B12",
	Panel:    "#13131F",
	PanelAlt: "#1A1A2A",
	EditorBg: "#1B1B1F",

	Border:     "#4A4A5C",
	BorderSoft: "#2A2A3D",
	BorderHi:   "#7878E0",

	Text:  "#F4F4F5",
	Body:  "#E4E4E7",
	Mute:  "#B5B5BE",
	Dim:   "#9595A0",
	Faint: "#7E7E8A",
	Ghost: "#525260",

	Accent:     "#9E9EF0",
	Accent2:    "#8484C8",
	AccentSoft: "#2A2A4E",
	Active:     "#38BDF8",

	Ok:       "#34D399",
	OkSoft:   "#6EE7B7",
	OkSoftBg: "#1A3D3A",
	Warn:     "#FB923C",
	Err:      "#F87171",

	String: "#5EEAD4",
	Number: "#C084FC",

	SelRow:       "#25253A",
	Cursor:       "#9E9EF0",
	EditorActive: "#26262C",
	InvertText:   "#0B0B12",

	Overlay: "#070710",
	BadgeBg: "#1E1E28",
}
View Source
var Light = Palette{
	Bg:       "#FBFBFD",
	Panel:    "#FFFFFF",
	PanelAlt: "#F1F1F5",
	EditorBg: "#F4F4F5",

	Border:     "#D1D5DB",
	BorderSoft: "#E5E7EB",
	BorderHi:   "#5A5AC8",

	Text:  "#09090B",
	Body:  "#18181B",
	Mute:  "#3F3F46",
	Dim:   "#52525B",
	Faint: "#71717A",
	Ghost: "#A8A8AE",

	Accent:     "#3A3A8C",
	Accent2:    "#5151A0",
	AccentSoft: "#E5E5FF",
	Active:     "#0284C7",

	Ok:       "#047857",
	OkSoft:   "#047857",
	OkSoftBg: "#DCEEE7",
	Warn:     "#C2410C",
	Err:      "#B91C1C",

	String: "#047857",
	Number: "#7E22CE",

	SelRow:       "#EEEEF9",
	Cursor:       "#3A3A8C",
	EditorActive: "#EAEAEC",
	InvertText:   "#FFFFFF",

	Overlay: "#F1F1F5",
	BadgeBg: "#EDEDEF",
}

Functions

func ASCIIChart

func ASCIIChart(series []float64, width, height int, caption string) string

ASCIIChart renders a single-series time chart using guptarohit/asciigraph. Multi-series rendering is intentionally left to the caller — overlay passes work better with explicit color control.

width / height are in cells. Caller should pre-fill or downsample series so len(series) <= width-10 (left margin for y-axis labels).

func Adapt

func Adapt(pick func(p Palette) lipgloss.Color) lipgloss.AdaptiveColor

Adapt is an alias for Adaptive — kept for backwards compatibility with existing callers.

func Adaptive

func Adaptive(pick func(p Palette) lipgloss.Color) lipgloss.AdaptiveColor

Adaptive builds a lipgloss.AdaptiveColor where the light/dark sides come from Light/Dark via the given picker. Use for vars declared at package init time, before SetActive runs.

func Breadcrumbs(width int, items []Breadcrumb) string

Breadcrumbs renders the bottom navigation row. Active item gets an accent fill with inverted text; the rest are accent-fg on transparent.

func Card

func Card(title string, width, height int, focused bool, body string) string

Card renders a bordered surface with an uppercase title strip. Focused = BorderHi outline + accent title; idle = Border + dim title. Width is total cells including borders; Height is rows inside body.

Use Card for every pane in a view — editor, preview, time, results — so the TUI reads as one visual system.

func CardWithMeta

func CardWithMeta(title, meta string, width, height int, focused bool, body string) string

CardWithMeta is Card with an optional meta string rendered right of the title (e.g. "FRONTEND · SQL · UNSAVED"). Meta is always Faint.

┌─ EDITOR ────────────────  FRONTEND · SQL · UNSAVED ┐
│ ...body...                                          │
└─────────────────────────────────────────────────────┘

func FormatStat

func FormatStat(label, value string) string

FormatStat renders a small label/value stat tile.

func HeaderStrip

func HeaderStrip(width int, ctx []KV, keys []KeyHint) string

HeaderStrip renders the top context strip:

[ KV context | keybind grid | PB logo ]

All three columns are visible at >=90 cols. Below that the logo is dropped first, then the keybind grid collapses to two columns.

func HighlightPromQL

func HighlightPromQL(src string) string

HighlightPromQL highlights PromQL queries (chroma calls the lexer `promql`).

func HighlightSQL

func HighlightSQL(src string) string

HighlightSQL returns the given SQL string colored using ANSI truecolor escapes, painted with the active pb palette. Output safe to render inside any lipgloss block — chroma only emits SGR sequences, no cursor moves or clears.

Caller is responsible for sizing — chroma does no wrapping.

func KeyGrid

func KeyGrid(keys []KeyHint, cols, availW int) string

KeyGrid renders key hints using the same column layout as HeaderStrip.

func LogoLines

func LogoLines() int

LogoLines reports the number of rows in PBLogo. Used to set column height when stacking next to the KV / keybind columns.

func PaneTitle

func PaneTitle(width int, title, right string) string

PaneTitle is a small uppercase title strip used at the top of result panes (preview, detail, etc).

func Pill

func Pill(label string, active bool) string

Pill renders a small toggle pill — used by PromQL toolbar.

func RenderLogo() string

RenderLogo paints the PB mark in the active palette's accent color.

func SelectionRail

func SelectionRail(selected bool) string

SelectionRail returns a row prefix consisting of a 1-cell rail in the active palette's accent color when selected, transparent otherwise.

func SetActive

func SetActive(p Palette)

SetActive replaces the process-wide palette.

func SetActiveIcons

func SetActiveIcons(s IconSet)

SetActiveIcons replaces the process-wide icon set.

func Truncate

func Truncate(s string, n int) string

Truncate clips s to n visible cells, appending "…" if needed.

Types

type App

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

App is the root bubbletea model. It owns the View map, the active view ID, and the AppCtx shared across views.

func NewApp

func NewApp(profile config.Profile, views map[ViewID]View) App

NewApp wires the App with the given views map.

func (App) Init

func (a App) Init() tea.Cmd

func (App) Update

func (a App) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (App) View

func (a App) View() string

type AppCtx

type AppCtx struct {
	Profile   config.Profile
	Datasets  []string
	Dataset   string
	Latency   string
	RowsLabel string
	// contains filtered or unexported fields
}

AppCtx is the shared mutable state passed to every view's Update. Views read from it (current dataset, profile) and write to it via the helper setters (e.g. SelectDataset switches the active view).

func (*AppCtx) SelectDataset

func (c *AppCtx) SelectDataset(name string)

SelectDataset records the dataset and switches to the query view.

func (*AppCtx) SetError

func (c *AppCtx) SetError(s string)

SetError records a status-bar error (cleared on next view switch).

func (*AppCtx) SwitchTo

func (c *AppCtx) SwitchTo(v ViewID)

SwitchTo asks the App to display the named view on the next tick.

type Breadcrumb struct {
	ID     string
	Label  string
	Active bool
}

Breadcrumb is one tab/crumb in the bottom navigation.

type IconSet

type IconSet struct {
	// Selection rail / row markers
	Cursor string // selected row marker — ▸ or
	Pin    string // pinned item — ★ or
	Bullet string // idle row marker — · or empty
	// Status / segments
	Cluster string //  in nerd
	User    string //  in nerd
	Dataset string //  in nerd
	Time    string //  in nerd
	Live    string // ● both sets
	Search  string //  / >
	Help    string //  / ?
	// Separators
	VSep string // │ both sets
	Sep  string // · / ·
}

IconSet holds every glyph that varies between Nerd Font and plain ASCII. View code should reference Icons() — never hardcode a glyph.

Default is ASCII-safe (Unicode box-drawing + common bullets). Users who run a Nerd Font–patched terminal can opt in with PB_ICONS=nerd.

func Icons

func Icons() IconSet

Icons returns the active set — use this in every view.

func LoadIcons

func LoadIcons() IconSet

LoadIcons reads PB_ICONS and returns the matching set. ASCII by default — Nerd is opt-in to avoid broken glyphs on stock terminals.

PB_ICONS=nerd   → nerdIcons
PB_ICONS=ascii  → asciiIcons (default)

type KV

type KV struct {
	Key     string
	Value   string
	Variant KVVariant
}

KV is one row in the HeaderStrip context block.

type KVVariant

type KVVariant int
const (
	KVNormal KVVariant = iota
	KVAccent
	KVMute
)

KVNormal, KVAccent, KVMute control the color variant of a KV row in HeaderStrip.

type KeyHint

type KeyHint struct {
	Key   string
	Label string
}

KeyHint is one entry in the HeaderStrip keybind grid.

type Palette

type Palette struct {
	// ── Surfaces ────────────────────────────────────────────────────────────
	Bg       lipgloss.Color // outermost terminal background
	Panel    lipgloss.Color // header strip, statusbar, pane titles
	PanelAlt lipgloss.Color // cards, sidebar alt rows
	EditorBg lipgloss.Color // SQL / PromQL textarea surface

	// ── Borders ─────────────────────────────────────────────────────────────
	Border     lipgloss.Color // standard divider — between panels, table rows
	BorderSoft lipgloss.Color // subtle — table row separator, inner dividers
	BorderHi   lipgloss.Color // focus ring, active pane outline

	// ── Text ramp ───────────────────────────────────────────────────────────
	Text  lipgloss.Color
	Body  lipgloss.Color
	Mute  lipgloss.Color
	Dim   lipgloss.Color
	Faint lipgloss.Color
	Ghost lipgloss.Color

	// ── Brand / Accent ───────────────────────────────────────────────────────
	Accent     lipgloss.Color
	Accent2    lipgloss.Color
	AccentSoft lipgloss.Color
	// Active — bright sky-blue reserved for "cursor here, will edit"
	// state (sidebar sub-section rails, code|builder toggle). Picked
	// to contrast with Accent (purple) so users can distinguish
	// "selection on a list" from "field is the editing target".
	Active lipgloss.Color

	// ── Semantic ─────────────────────────────────────────────────────────────
	Ok       lipgloss.Color
	OkSoft   lipgloss.Color
	OkSoftBg lipgloss.Color
	Warn     lipgloss.Color
	Err      lipgloss.Color

	// ── Syntax ───────────────────────────────────────────────────────────────
	String lipgloss.Color
	Number lipgloss.Color

	// ── Interaction ──────────────────────────────────────────────────────────
	SelRow       lipgloss.Color
	Cursor       lipgloss.Color
	EditorActive lipgloss.Color
	InvertText   lipgloss.Color

	// ── Overlay / Badge ──────────────────────────────────────────────────────
	Overlay lipgloss.Color
	BadgeBg lipgloss.Color
}

func LoadTheme

func LoadTheme() Palette

LoadTheme reads $PB_THEME (light | dark | auto). Auto sniffs $COLORFGBG, then falls back to lipgloss's terminal background probe (OSC 11 / termenv). Default: dark.

type Typography

type Typography struct {
	// Structural labels — column headers, pane titles
	Label lipgloss.Style

	// Key chips — <ctrl-r>, <enter>, keymap display
	KeyChip lipgloss.Style

	// Standard text levels
	Body  lipgloss.Style
	Mute  lipgloss.Style
	Dim   lipgloss.Style
	Ghost lipgloss.Style

	// Semantic
	Accent lipgloss.Style
	Err    lipgloss.Style
	Warn   lipgloss.Style
	Ok     lipgloss.Style

	// Monospace values
	Timestamp lipgloss.Style
	TraceID   lipgloss.Style

	// Breadcrumb
	Crumb       lipgloss.Style
	CrumbActive lipgloss.Style

	// Badges
	BadgeSQL    lipgloss.Style
	BadgePromQL lipgloss.Style
	BadgeOk     lipgloss.Style
	BadgeErr    lipgloss.Style
	BadgeWarn   lipgloss.Style

	// Status bar
	StatusMode    lipgloss.Style
	StatusSegment lipgloss.Style
	StatusLive    lipgloss.Style
}

func NewTypography

func NewTypography(p Palette) Typography

NewTypography builds all styles from a palette.

func Type

func Type() Typography

Type returns the active Typography — sugar for ActiveType.

type View

type View interface {
	Init() tea.Cmd
	Update(msg tea.Msg, ctx *AppCtx) tea.Cmd
	Render(width, height int, ctx *AppCtx) string
	// HeaderKeys returns the keybind hints shown in the top HeaderStrip
	// while this view is active. Empty slice = no hints (fall back to
	// the global set).
	HeaderKeys() []KeyHint
}

View is the minimal contract every page implements. Each implementation lives in pkg/ui/views/<name>.go.

Width/height are the inner body cells (chrome already subtracted).

type ViewID

type ViewID int

ViewID identifies one of the seven top-level views described in the spec (§5). Each is rendered by exactly one View implementation under pkg/ui/views/. Modals (picker, time, help) are also reachable as top-level views per the mock breadcrumb row — the same code renders both as a centered modal (overlay) and as a full-bleed view.

const (
	ViewQuery ViewID = iota
	ViewResults
	ViewMetrics
	ViewPicker
	ViewTime
	ViewSaved
	ViewHelp
)

ViewQuery through ViewHelp enumerate the top-level views reachable from the navigation bar.

func (ViewID) Label

func (v ViewID) Label() string

Label returns the breadcrumb label for a view.

Directories

Path Synopsis
Package views holds the per-screen render + Update logic.
Package views holds the per-screen render + Update logic.

Jump to

Keyboard shortcuts

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