PHPackages                             tivins/tui - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. tivins/tui

ActiveLibrary[CLI &amp; Console](/categories/cli)

tivins/tui
==========

terminal user interface

1.4.1(2mo ago)04MIT

Since May 14Compare

[ Source](https://github.com/tivins/tui)[ Packagist](https://packagist.org/packages/tivins/tui)[ RSS](/packages/tivins-tui/feed)WikiDiscussions Synced 3w ago

READMEChangelogDependenciesVersions (4)Used By (0)

tivins/tui
==========

[](#tivinstui)

Small PHP helpers for terminal user interfaces: **cursor and screen control**, **Unicode bordered frames**, **side-by-side layout** of multiline blocks, **text progress bars**, **ANSI colors** (16-color and 256-color foregrounds), a lightweight **ASCII banner** renderer, **ANSI-aware** string utilities, and a **spinner** with optional **rotating grayscale** on messages.

Requires **PHP 8.1+** (typed `enum`). The **mbstring** extension is recommended for correct Unicode handling in banners and width calculations.

Install
-------

[](#install)

```
composer require tivins/tui
```

There are **no Composer runtime dependencies**.

Highlights
----------

[](#highlights)

AreaClassesWhat they doScreen &amp; cursor`Terminal`Clear/move cursor, CPR, `eraseLine`, alternate screen, `screenSize()`, `carriageReturn()`, `lineOverwritePrefix()` (réécrire une ligne), `cursorPreviousLine()` (CPL, colonne 1).Boxes`Frame`Multiline bordered panels: presets `single`, `double`, `rounded`, `heavy`, optional titles, padding, independent border/content/title colors, colored content with correct alignment.Layout`Layout``horizontal(array $blocks, int $gap = 1)` — place blocks side by side; each row is padded using `Ansi::displayWidth` so borders stay aligned.Progress`ProgressBar``render($percent, $width, ...)` — Unicode-filled bar (`█` / `░`) without a spinner; complements `Throbber`’s `{bar}` placeholder.Banners`AsciiText`Three-line glyphs (Future Smooth subset) via `AsciiText::get()` and `AsciiText::toString()`.Colors`TermColor``TermColor::*->fmt(string)` wraps text in SGR sequences.ANSI &amp; 256-color`Ansi``stripSgr()`, `displayWidth()`, `fmtForeground256(int $code, string)` for `\e[38;5;nm` foregrounds (e.g. grayscale 232–255).Text effect`RotatingColors`Shifting palette along a string: `render($text, $offset, $palette)`; default grayscale uses smooth 256-color steps; palette entries may be `TermColor` or 256-color indices (`int`).stdin`Console``stdinIsTty()` and `readLine()` for interactive pauses without mixing stdin with terminal inquiries.Activity`Throbber`Spinner (styles: braille, pipe, dots, line), template placeholders including `{message}`, `{rotating_message}` (grayscale wave; offset advances every `tick()` via internal `rotatingColorOffset`, independent of spinner wrap), `{bar}`, percent, elapsed, `registerStyle()`, `barWidth()`.Quick examples
--------------

[](#quick-examples)

### Rotating colors

[](#rotating-colors)

`RotatingColors::render()` applies a repeating palette along each UTF-8 character. The offset usually increases by one per animation frame. With `Throbber`, use `{rotating_message}` so the wave stays smooth when the spinner loops (the library uses a monotonic color offset, not the spinner frame index).

```
use Tivins\Tui\RotatingColors;
use Tivins\Tui\Throbber;

echo RotatingColors::render('thinking...', $offset) . "\n";

$th = (new Throbber())
    ->message('thinking...')
    ->template('{spinner} {rotating_message}');
// call $th->tick() each frame; optional: $th->rotatingColorOffset()
```

### Framed panel

[](#framed-panel)

```
