Tree / list view with box-drawing prefixes + cursor nav
Tree and flat list views with customizable box-drawing prefixes, cursor navigation, and word-wrap. Composeable with any bubbletea model.
composer require sugarcraft/candy-lister
use SugarCraft\Lister\{Model, StringItem, DefaultPrefixer};
$model = Model::new();
$model->setWidth(80)->setHeight(24);
$model->addItem(new StringItem('src/main.php'));
$model->addItem(new StringItem('src/Model.php'));
$model->addItem(new StringItem('tests/MainTest.php'));
$model->setPrefixer(new DefaultPrefixer());
echo $model->View();
// Renders the list with ╭ ├ │ prefixes and > cursor marker
| Class | Method | Description |
|---|---|---|
| Model | new() | Create model with defaults |
| Model | withFilterFn(\Closure) | Filter items; returns new Model; filterState → filtering → filtered |
| Model | withoutFilter() | Clear filter; restore original items; filterState → unfiltered |
| Model | addItem(\Stringable) | Append a list item |
| Model | setWidth(int) | Set viewport width in cells |
| Model | setHeight(int) | Set viewport height in lines |
| Model | setPrefixer(Prefixer) | Attach a prefixer instance |
| Model | setSuffixer(Suffixer) | Attach a suffixer instance |
| Model | lines() | Return visible lines as array |
| Model | View() | Render list as ANSI string |
| Model | filterState | Current FilterState (unfiltered / filtering / filtered) |
| FilterState | unfiltered | No filter active |
| FilterState | filtering | Filter function set, applying |
| FilterState | filtered | Filtering complete, results shown |
| FuzzyMatch | score(query, candidate) | Smith-Waterman alignment score (int, higher = better) |
| FuzzyMatch | match(query, list<\Stringable>) | Filter and rank items by score; returns list of [item, score] pairs |
| Item | value | The underlying \Stringable |
| StringItem | new(string) | Wrap a plain string as a list item |
VHS-recorded GIFs of every example shipped with the library. Regenerated automatically on every push that touches the source.