Overflow & Sizing Model (P1)
This repo renders into a fixed cell grid (cols × rows). “Overflow” means more content than available cells in a component’s rect.
Terms
- wrap: break long lines into multiple visual lines (cell-width aware).
- clip: truncate content that exceeds available width/height (no scroll state).
- scroll: keep a viewport with persistent offsets (
scrollX/scrollY) so content can move within a fixed rect. - auto height: component derives
hfrom content; fixed height:his provided.
Current per-component defaults
TText- Width:
woptional; if omitted, computed from the longest line (cell-width). - Height:
hoptional; if omitted, derived from rendered line count (incl. explicit\n/ wrap). - Overflow:
wrap=false(default): clip horizontally (cell-width), multi-line via explicit\n.wrap=true: wrap by cell width; never emits control chars toterminal.write.
- Width:
TBox- Width/height required (
w,h). - Overflow: children paint within the content rect;
TBoxcan clear its own rect (clear=truedefault).
- Width/height required (
TInput- Width required; height defaults to
1. - Overflow:
h=1: horizontal scroll (internalscrollX) with a fixed single line.h>1: wrap-mode editing with vertical scroll (internalscrollY) and cell-aware cursor mapping.
- Paste: inserts text as-is (including
\n). For single-line inputs, sanitize in@paste/@beforeinput.
- Width required; height defaults to
TSelect/TList- Width/height required.
- Overflow: items are clipped per row (cell-width) and vertically scroll via
scrollTop.
TDialog- Width/height required.
- Overflow: content is clipped to its rect; focus/blur and close behavior are managed by the dialog wrapper.
Auto-height semantics (today)
- Only
TTextsupports true “auto height” (content-driven) by omittingh. - Layout containers (
TView,TBox, dialogs, list/select/input) expect explicit sizing; the recommended pattern is:- use
TTextto measure/format content (wrap, compute lines), - then choose a fixed
hand render inside aTBox/TView.
- use
Why there is no unified overflow prop set (yet)
Some components already have internal scroll models (e.g. TInput, TList) and others are pure paint (TText). Unifying props like scrollX/scrollY/maxHeight/truncate across all components is doable, but it is an API design choice that affects:
- how scroll state is persisted across remounts/route switches
- keyboard/mouse bindings and focus management
- deterministic record/replay parity (important for this repo)
The current approach is to keep behavior explicit per component and document it, then iteratively unify once the shared model is agreed.