TermMosaic v1.0.0

v1.0.0 is the first release that makes a stability promise: the public API freezes here and Semantic Versioning applies in earnest — with one documented exception: widgets/widgettest is excluded from that promise, because it must evolve with the framework. Read the limitations before you rely on anything here.

Widgets widgets/basic

Text

A single line of styled spans, aligned within its rectangle.

A single line of styled spans, aligned within its rectangle.

Package widgets/basic. API reference: pkg.go.dev/widgets/basic.

Text renders styled spans on one line.

It is the smallest widget in the catalog and the one most often composed: a label in a form, a value beside it, a status line. It truncates rather than wraps, because wrapping is Paragraph’s job and a widget that both wrapped and did not would be two widgets.

Rendered output

Text rendered by cmd/capture through widgettest.Capture: colour at 3 widths (40, 80, 120 columns), and the exact plain-text cell grid at the widest of them.

MinSize() is not in the manifest for this widget, so this page does not claim a minimum. If you need one, call it.

40 columns × 3 rows

TermMosaic — 22 widgets, 2 dependencies 
                                        
                                        

80 columns × 3 rows

TermMosaic — 22 widgets, 2 dependencies                                         
                                                                                
                                                                                

120 columns × 3 rows

TermMosaic — 22 widgets, 2 dependencies                                                                                 
                                                                                                                        
                                                                                                                        

Plain text — the exact cell grid, trimmed per line. This is the honest form: Braille and block-element glyphs can take a different advance width in a web font than a terminal gives them, which breaks the alignment they depend on.

# Text — A single line of styled spans, aligned within its rectangle.
# package: widgets/basic
# constructor: basic.NewText(r buffer.Rect, spans []buffer.Span) *basic.Text
# 120 columns x 3 rows, rendered through widgettest.Capture

TermMosaic — 22 widgets, 2 dependencies


What you are looking at. This is the cell grid the renderer produced, in a web page. It is not a screenshot of a terminal, and it cannot show interaction, resize or animation — a capture is one settled frame after N frames of settling. Braille and Block Elements can take a different advance width in your browser's font than in a terminal, so if a gauge or a sparkline above looks wrong, the plain-text form below it is the exact output and the colour one is the decoration. The colour frames are at 40, 80, 120 columns; the plain-text frame is at 120. More on this.

Package context

Package basic provides the two text widgets: Text, which writes styled spans on one line, and Paragraph, which wraps them.

Both follow the same two rules, which are the rules every widget in the catalog follows:

  • The available space is Bounds(), never buf.Size(). The buffer is the screen; the rect is the widget’s space (ADR 0007 §1 rule 1).
  • Nothing derived from the size is built in Draw. Wrap and Truncate both allocate, so Paragraph caches its Wrapped and Text caches its truncation against the rect they were computed for, and recompute only when Bounds() differs (ADR 0007 §3, ADR 0008 §4).

Constructing it

basic.NewText(r buffer.Rect, spans []buffer.Span) *basic.Text

NewText takes the spans up front. Because the span list is parsed once rather than per frame, mutating the slice contents afterwards does not repaint — replace Text.Spans and call Invalidate().

  • Spans — []buffer.Span — the styled runs on the line. Parsed once at construction, which is why Draw allocates nothing.
  • Align — geometry.Align — start, centre or end within Bounds().
  • Ascii — bool — force ASCII for anything that would otherwise need a Unicode glyph.

When not to use it

Do not use it for text that must wrap. Text is one line and truncates with a marker; it will not reflow. Reflowing is Paragraph, and the difference is a real one — reaching for Text with a long string produces a silently truncated label rather than an error.

Do not use it for anything the user can edit. There is no caret and no key contract; it is a display widget. Editing is TextInput.

Do not use it to show a value whose length changes per frame without calling Invalidate(). Text caches its layout against its rect and its spans (ADR 0007 §3); a widget whose setter writes a field Draw reads must invalidate in that setter, or the old text stays on screen permanently. This is the caching bug ADR 0007’s 2026-10-04 amendment is about, and Text is not exempt from it.

Instead: Paragraph to wrap, TextInput to edit.