eddacraft-tui
Shared Ratatui component library for open-source TUIs that follow the eddacraft design system.
Modules
theme/— eddacraft Terminal Standard colour palette,Themetrait, semanticRoletokens, and brand themingkeyboard/— key binding definitions, action mapping, and introspectableBindingtablewidgets/— reusable TUI widgets (see Widgets below)pretext/— two-phase prepare/layout text engine for streaming AI output and dynamic reflowsurface.rs— baseSurfacetrait for TUI screensshell.rs— shared shell chrome renderer
Design System
Implements the eddacraft Terminal Standard:
| Token | Colour |
|---|---|
| Void | rgb(13, 13, 15) |
| Structure | rgb(42, 42, 46) |
| Off-White | rgb(235, 235, 235) |
| Ghost Grey | rgb(133, 133, 138) |
| anvil Ember | rgb(204, 85, 0) |
| edda Growth | rgb(46, 139, 87) |
| Brick Red | rgb(201, 74, 74) |
| Dull Amber | rgb(208, 140, 56) |
Usage
[]
= "0.2"
use *;
let theme = EddaCraftTheme;
let spinner = new.eddacraft.label;
let forge_spinner = new.anvil.label;
// Pass the consuming crate's version explicitly.
// render_shell(frame, area, ShellBranding::Anvil, "anvil", "Watch", "[q] quit", &theme, env!("CARGO_PKG_VERSION"));
ParallelProgress also uses the branded anvil spinner automatically for
running checks.
render_shell supports reusable shell marks for open-source apps:
ShellBranding::PlainShellBranding::EddaCraft->[■]ShellBranding::Edda->[=]ShellBranding::Anvil->[‡]
ProgressBar and ParallelProgress animate toward their target value. Your
event loop must call animate_tick each frame for the transition to play — see
docs/animations.md.
Widgets
The widgets/ module ships a curated component set. Highlights:
- Inputs —
TextInput,Editor,Select,Confirm - Status —
Spinner,ProgressBar,ParallelProgress,StatusBadge,StatusBar - Layout —
Container,Divider,Header - Data —
DataTable(sortable, themed▲/▼indicators),Tree(expand/collapse viaTreeState),LogPanel - Overlays —
OverlayStack+Layer+Placementfor layered modals;ModalandToast/ToastStackas ready-made consumers - Chrome —
HelpBarauto-renders key hints fromKeyHandler::default_bindings(), so help text stays in sync with the keymap - Text reflow —
PretextWidget+PretextStatefor cached two-phase layout (see Pretext layout below) - Wrappers —
Hideable,Disableable,Paddeddecorate anyWidget/StatefulWidgetwithout bloating each widget's API
Optional features
| Feature | Adds |
|---|---|
image |
ImagePane — themed wrapper around ratatui-image (Kitty / Sixel / iTerm2 / halfblocks) |
big-text |
BigBanner — themed wrapper around tui-big-text for branded splashes |
test-utils |
Snapshot testing helpers re-exported for downstream crates |
[]
= { = "0.2", = ["image", "big-text"] }
Pretext layout
pretext is a two-phase text layout engine inspired by Cheng Lou's
Pretext library for the browser. Measure
word widths once with unicode-width, cache the layout per container width, and
re-run only on resize — eliminating reflow stutter for streaming AI output and
animated layouts.
use *;
use StatefulWidget;
let theme = EddaCraftTheme;
let mut state = new;
let widget = themed;
// Each frame:
// widget.render(area, frame.buffer_mut(), &mut state);
// On new tokens:
state.append;
// Flow text around moving shapes:
state.set_exclusions;
The widget itself is zero-sized — all caching lives on PretextState. At
unchanged container width subsequent renders skip layout entirely; the cache is
invalidated by a width change, by any text mutation (set_text,
set_styled_text, append, append_styled), by set_exclusions, or by an
explicit invalidate_layout() call.
Documentation
Extended guides live in docs/. Contributor docs remain at the repo
root (CONTRIBUTING.md, RELEASE.md,
SECURITY.md).
Links
- eddacraft: https://eddacraft.ai
- anvil public repository: https://github.com/eddacraft/anvil
- Brand and design system: https://github.com/eddacraft/brand-and-design
- pretext-tui demos: https://github.com/joshuaboys/pretext-tui
Acknowledgements
Smooth progress and spinner animations are powered by
vyfor/animate, a minimal animation engine
for Ratatui.
The pretext module ports the layout engine and widget originally prototyped in
joshuaboys/pretext-tui, itself
inspired by Cheng Lou's Pretext for the
browser.
Licence
Apache-2.0