sugarcraft / sugar-table
PHP port of Evertras/bubble-table — customizable interactive table component for terminal UIs. Supports column definitions with keys/titles/widths, rows as key-value maps, styled cells, selection, pagination, sorting, filtering, frozen columns, horizontal scrolling, zebra striping, and ANSI border s
v0.2.0
2026-05-07 01:29 UTC
Requires
- php: ^8.1
Requires (Dev)
- phpunit/phpunit: ^10.5
This package is not auto-updated.
Last update: 2026-05-07 14:46:28 UTC
README
SugarTable
PHP port of Evertras/bubble-table — customizable interactive table component for terminal UIs.
Features
- Column definitions: unique key, title, width (fixed or flexible), optional style
- Row data: key-value map (
RowData), arbitrary values rendered viafmt.Sprintf("%v") - Styled cells:
StyledCellwraps value + ANSI style, overrides row/column/base styles - Row styles: zebra striping, bold rows, per-row ANSI styling
- Selection: single-row cursor, up/down navigation
- Pagination: page size, page navigation, auto footer
- Sorting: asc/desc, multi-column sort, numeric + string sort
- Filtering: filter by column text
- Frozen columns: pin columns from the left
- Horizontal scroll: max width with overflow, frozen columns stay visible
- Missing data indicator: configurable placeholder for absent cells
- Border styling: customizable border chars + ANSI color
Install
composer require sugarcraft/sugar-table
Quick Start
use SugarCraft\Table\{Column, Row, RowData, Table}; $t = Table::withColumns([ Column::new('id', 'ID', 5), Column::new('name', 'Name', 20), Column::new('city', 'City', 15), ])->withRows([ Row::new(RowData::from(['id' => '1', 'name' => 'Alice', 'city' => 'NYC'])), Row::new(RowData::from(['id' => '2', 'name' => 'Bob', 'city' => 'LA'])), Row::new(RowData::from(['id' => '3', 'name' => 'Carol', 'city' => 'CHI'])), ]); echo $t->View();
Columns
Column::new($key, $title, $width) // key, display title, fixed width ->withFlexibleWidth($flex) // flexible width share ->withMaxWidth($max) // horizontal scroll cap ->withStyle('1;34') // ANSI SGR style ->withFilterable() // enable built-in filter ->withAlignLeft() // left-align (default is right)
Rows
Row::new($rowData) ->withStyle('1') // bold entire row ->withZebra() // alternating style // Styled cell (overrides row+column style) StyledCell::new('value', '31;1') // red bold cell
Navigation & Sorting
$t = $t->SortBy('name', ascending: true); $t = $t->Filter('name', 'alice'); // filter column by text $t = $t->SelectNext(); // move cursor down $t = $t->SelectPrevious(); // move cursor up $t = $t->CurrentRow(); // get selected RowData
Pagination
$t = $t->WithPageSize(25) // 25 rows per page ->WithPage(2); // show page 2 echo $t->PageFooter(); // 'Page 2 of 4'