A comprehensive TUI component library for PHP 8.3+, ported from the Charmbracelet ecosystem (bubbletea, bubble-grid, lipgloss). Provides 200+ components organized into 13 namespaces for building rich terminal user interfaces.
composer require sugarcraft/sugar-dash| Namespace | Description |
|---|---|
Foundation\ |
Pure interfaces + low-level primitives (Item, Sizer, Style, Theme, Color, Rect, Drawable, Buffer, Cell) |
Layout\ |
Layout primitives (Stack, VStack, HStack, ZStack, FlexLayout, GridLayout, Frame, Panel, Split, Spacer, Window, etc.) |
Components\ |
UI components (Modal, Select, Toast, Tabs, StatusBar, Form, Feedback, Nav, Card, Calendar, Tree, Table, etc.) |
Plot\ |
Charts and plotting (Chart, Sparkline, Gauge, Donut, Heatmap, RadarChart, TreeViz, Graph, etc.) |
Module\ |
Module interface + base implementations |
Registry\ |
Registry pattern for modules |
Plugin\ |
Plugin system with JSON protocol |
Modules\ |
Built-in modules (Clock, System, Weather, etc.) |
Events\ |
Input/event plumbing (Event, KeyEvent, MouseEvent, FocusEvent, etc.) |
Keys\ |
Key registry and mappings |
Position\ |
ANSI-aware geometry helpers |
Output\ |
Extracted helpers (truncate, render bar) |
State\ |
State management |
| Type | Description | Key Methods |
|---|---|---|
Item |
Anything that can be rendered as a string | render(): string |
Sizer |
An Item that knows its own dimensions (extends Item) | setSize(int $width, int $height): Sizer, render(): string |
Drawable |
Universal draw contract with GetRect/SetRect/Draw | getRect(): Rect, setRect(Rect): void, draw(Buffer): void |
| Type | Description | Key Properties |
|---|---|---|
Options |
Grid-level configuration options | $fitScreen: bool (default: true) |
ItemOptions |
Per-item placement options within StackedGrid | $column: int (0-based), $expandVertical: bool |
ItemWithOptions |
Internal pairing of Item + ItemOptions | $item: Item, $options: ItemOptions |
| Type | Description | Key Methods |
|---|---|---|
Cell |
Single terminal cell (rune + Style) — sugar-dash SSOT, distinct from \SugarCraft\Vt\Cell\Cell |
|
Buffer |
Cell grid buffer for drawing — sugar-dash SSOT, distinct from \SugarCraft\Vt\Buffer\Buffer |
getCell(x,y), setCell(x,y,Cell), fill(rect,Cell) |
Rect |
Rectangle geometry (rectmath bounds model: minX/minY/maxX/maxY) — distinct from \SugarCraft\Core\Rect (offset+size model) |
contains(), intersect(), dx(), dy() |
Style |
Terminal styling (inline foreground/background Color slots) — sugar-dash SSOT, distinct from \SugarCraft\Sprinkles\Style (lipgloss padding/margin/borders) |
fg(), bg(), bold(), etc. |
StyleParser |
Parses [text](fg:red,bg:blue) into Dash Cell arrays — sugar-dash SSOT, NOT drop-in compatible with \SugarCraft\Sprinkles\StyleParser |
|
Color |
Backward-compat alias for \SugarCraft\Core\Util\Color (true duplicate, replaced by class_alias shim — prefer Core import in new code) |
|
Theme |
Pre-defined theme palettes (10 colour slots + helpers) — sugar-dash SSOT, distinct from \SugarCraft\Sprinkles\Theme (13 slots, readonly only) |
dark(), dracula(), oneDark(), githubDark(), light() |
Dual-SSOT note. Five Foundation primitives (
Style/Theme/Rect/Buffer/Cell) plusStyleParserare intentionally distinct from same-named canonical types incandy-sprinkles/candy-core/candy-vt. The lineage differs (charmbracelet/inline-termui for sugar-dash, lipgloss/ratatui/VT-emulator for the others) and the API shapes diverge. OnlyColorwas a true duplicate and is now aclass_aliasto\SugarCraft\Core\Util\Color. SeeCALIBER_LEARNINGS.mdentries[pattern:dual-foundation-ssot],[pattern:dual-style-ssot],[pattern:dual-theme-ssot],[pattern:dual-rect-models],[pattern:dual-buffer-roles],[pattern:dual-cell-shapes].
| Type | Values |
|---|---|
LayoutDirection |
Horizontal, Vertical |
SplitDirection |
Horizontal, Vertical |
AlignItems |
Start, End, FlexStart, FlexEnd, Center, Stretch, Baseline |
FlexDirection |
Row, Column, RowReverse, ColumnReverse |
FlexWrap |
NoWrap, Wrap, WrapReverse |
HAlign |
Left, Right, Center |
VAlign |
Top, Middle, Bottom |
JustifyContent |
Start, End, FlexStart, FlexEnd, Center, SpaceBetween, SpaceAround, SpaceEvenly |
| Type | Description | Key Methods/Factories | GIF |
|---|---|---|---|
StatusBar |
Status bar with left/right zones | new(), withLeft(), withRight(), withSeparator() |
|
StatusIndicator |
Status indicator dot | ![]() |
| Type | Description | Key Methods/Factories | GIF |
|---|---|---|---|
Calendar |
Calendar view | ![]() |
|
ListComponent |
List renderer | ![]() |
| Type | Description | Key Properties |
|---|---|---|
Event |
Base event class | |
EventHandler |
Event handler callback | |
EventDispatcher |
Event dispatcher | |
FocusEvent |
Focus event | |
KeyEvent |
Keyboard event | |
MouseEvent |
Mouse event | |
PasteEvent |
Paste event | |
ResizeEvent |
Resize event | |
Focus |
Focus state management |
| Type | Description | Key Properties |
|---|---|---|
Key |
Key representation | |
KeyAction |
Key action | |
KeyMap |
Key mapping |
| Type | Description | Key Methods |
|---|---|---|
State |
Application state diagram | |
Persistence |
Atomic tmp+rename state save/load | save(path, data), load(path): ?array |
Note:
TransitionType,StateNode,StateTransition, andStateMachinemoved toComponents\Tree\namespace (PSR-4 one-class-per-file). TheState\*classes are retained as@internalbackward-compatibility re-exports viaclass_alias.
| Type | Description | Key Methods |
|---|---|---|
Center |
Calculate centered position | |
HAlign |
Left, Right, Center |
|
VAlign |
Top, Middle, Bottom |
| Type | Description | Key Methods |
|---|---|---|
Truncate |
String truncation with ANSI awareness | |
RenderBar |
Bar rendering helper | |
WrapCells |
Cell-aware text wrapping |
| Type | Description | Key Methods |
|---|---|---|
Module |
Elm-arch interface aligned with Core\Model: init(): ?Closure, update(Msg): array{0:Module,1:?Cmd}, view(): string, plus name(): string, minSize(): array{0:int,1:int} |
|
BaseModule |
Abstract helper — withState(array): static for immutable state, default update() returns [self,null] |
|
LegacyModule |
Deprecated array-state interface — superseded by Module |
|
LegacyModuleAdapter |
@internal wrapper that adapts LegacyModule to the Module contract |
|
ModuleConfig |
Module configuration | |
ImagePlacer |
Optional interface for image placements | |
ImagePlacement |
Image placement data | |
TickEpoch |
Focus-regain epoch counter |
| Type | Description | Key Methods |
|---|---|---|
Registry |
Static register/get/list/reset for modules; auto-wraps LegacyModule via LegacyModuleAdapter |
| Type | Description | Key Methods |
|---|---|---|
Request |
Plugin request DTO | |
Response |
Plugin response DTO | |
PluginSdk |
Plugin runner loop | |
ExternalModule |
Wraps binary into Module interface | |
Discovery |
Plugin discovery from filesystem |
All built-in modules extend BaseModule and use withState() for immutable state updates.
| Type | Description |
|---|---|
Clock\ClockModule |
Single-line clock |
System\SystemModule |
CPU/mem/disk stats |
Uptime\UptimeModule |
System uptime |
Greeting\GreetingModule |
Time-of-day greeting |
Generic\GenericModule |
Arbitrary shell command runner |
Weather\WeatherModule |
Live weather from wttr.in + 30min cache + stale fallback |
Weather\WttrInClient |
wttr.in J1 JSON API client implementing HttpClient |
Weather\HttpClient |
Interface for weather fetch — allows test doubles |
Weather\WeatherSnapshot |
Readonly DTO: tempC, condition, location, fetchedAt |
use SugarCraft\Dash\Layout\{Frame, VStack, Panel};
use SugarCraft\Dash\Layout\{StackedGrid, Options, ItemOptions};
use SugarCraft\Dash\Components\Text;
// Create a stacked grid layout
$grid = new StackedGrid(new Options(fitScreen: true));
// Add items to columns
$grid->addItem(
Frame::new(
VStack::centered(
Text::new('Welcome to SugarDash'),
Text::new('Build beautiful TUIs')
)
)->withPadding(1),
new ItemOptions(column: 0, expandVertical: true)
);
// Add a panel to the second column
$grid->addItem(
Panel::titled(
Text::new('This is a panel'),
'Dashboard'
),
new ItemOptions(column: 1)
);
// Set size and render
$grid->setSize(80, 24);
echo $grid->render();cd sugar-dash && composer install && vendor/bin/phpunitThe examples/ directory contains standalone demo files that showcase individual components and combinations:
| Demo | Description |
|---|---|
dashboard-live.php |
Interactive dashboard — the headline demo. Program event loop, raw mode, Clock/System/Weather modules, Boxer layout, FocusManager, per-panel tick, keyboard navigation (Tab/arrows), quit (q/Ctrl-C). Run with php examples/dashboard-live.php |
dashboard-showcase.php |
Multi-component server dashboard with gauges, charts, timeline, breadcrumb, avatar group |
dashboard-complex.php |
Full-featured analytics dashboard with charts, stats, funnel, sparkline |
dashboard-accordion-timeline.php |
Accordion and timeline components |
dashboard-metrics.php |
Key statistics and status indicators |
dashboard-status.php |
Spinners, progress bars, gauges, alerts |
dashboard-charts.php |
Chart components including area, donut, radar, heatmap |
dashboard-form.php |
Form components demo |
dashboard-ui.php |
UI components demo |
dashboard-nav.php |
Navigation components demo |
dashboard-text.php |
Text components demo |
dashboard-time.php |
Time components demo |
dashboard-media.php |
Media components demo |
dashboard-data.php |
Data display components demo |
dashboard-devtools.php |
Devtools components demo |
dashboard-layout.php |
Layout containers demo |
MIT License - See LICENSE file for details.





































































































































