artisan-build/parfait
Composer 安装命令:
composer require artisan-build/parfait
包简介
A framework-agnostic, component-based TUI layout and rendering system for PHP terminal applications
README 文档
README
A framework-agnostic, component-based TUI layout and rendering system for PHP terminal applications.
Why Parfait?
Building a terminal UI usually means hand-managing ANSI codes, cursor math, and Unicode width edge cases. Parfait gives you a declarative, component-based API instead — you describe the UI as a tree of components, and Parfait renders it to a string.
- 🧩 Components —
Panel,Modal,Accordion,FileTree,SelectList,NodeCanvas,Text, and more, each with a fluent API. - 📐 Layouts — compose
Layout::columns()/Layout::rows()with ratio-based sizing. - 🎨 256-color theming — a semantic
Colorenum that emits correct ANSI codes. - 📏 Unicode-correct width — emoji, CJK, combining marks, and ANSI escapes are measured accurately.
- 🪟 Portals — dropdowns, modals, and toasts render onto higher layers instead of being clipped.
- 🧪 Effortless testing — components are pure functions: state in →
render()→ string out. No terminal required. - 🪶 Zero framework dependencies — needs only PHP 8.2+ and
soloterm/grapheme.
Parfait layers cleanly on top of Laravel Prompts for input/render loops, but depends on neither Laravel nor Prompts — you can drive it from any PHP terminal program.
Requirements
- PHP
^8.2 ext-mbstringandext-intl(for grapheme-aware width)
Installation
composer require artisan-build/parfait
Quick Start
Every component knows the space it has via a Container, and renders to a
string you print yourself:
use ArtisanBuild\Parfait\Components\Panel; use ArtisanBuild\Parfait\Components\Text; use ArtisanBuild\Parfait\Enums\Color; use ArtisanBuild\Parfait\Support\Container; $panel = Panel::make('welcome') ->bordered() ->title('Parfait') ->body(Text::make('greeting', 'Welcome to the TUI!')->fg(Color::Cyan)) ->setContainer(new Container(width: 40, height: 5)); echo $panel->render();
╭── Parfait ───────────────────────────╮
│Welcome to the TUI! │
│ │
│ │
╰──────────────────────────────────────╯
Composing a layout
Layout arranges child components and hands each one a correctly-sized
Container:
use ArtisanBuild\Parfait\Components\Panel; use ArtisanBuild\Parfait\Components\Text; use ArtisanBuild\Parfait\Layouts\Layout; use ArtisanBuild\Parfait\Support\Container; $ui = Layout::columns(1, 3) // sidebar : main = 1 : 3 ->add(Panel::make('sidebar')->sidebar()->title('Files')) ->add(Panel::make('main')->bordered()->body(Text::make('body', 'Editor'))) ->setContainer(new Container(width: 100, height: 30)); echo $ui->render();
Components
| Component | Purpose |
|---|---|
Text / Stack |
Inline styled text and vertical content composition |
Panel |
Bordered / sidebar / minimal containers with header, body, footer |
Modal |
Overlay dialogs with shadow rendering (via portals) |
Toast |
Transient notifications |
Accordion |
Expandable tree-style navigation |
SelectList |
Scrollable, selectable lists |
FileTree |
Filesystem browser with search and exclude patterns |
Input / TextArea |
Single- and multi-line text entry |
CommandLine |
Command-palette style input |
ProgressBar |
Determinate progress display |
StatusBar / AppHeader |
Chrome for the top and bottom of the screen |
NodeCanvas |
Node-graph visualization with automatic layout |
Each component lives in src/Components/ alongside a co-located *Renderer
where rendering is non-trivial — see Architecture.
Architecture
Parfait uses a co-located renderer pattern:
Component.phpholds state and props (public properties, fluent setters).ComponentRenderer.phpturns that state into a string.
This keeps rendering logic isolated and makes components trivial to test —
construct one, set its container, assert on the rendered string. The base
Component provides styling helpers (applyStyle, width/truncate utilities),
view-state storage, and the portal hook.
┌─────────────────────────────────────────────┐
│ Your program (owns data, handles events) │
├─────────────────────────────────────────────┤
│ Parfait (layout + components → string) │
├─────────────────────────────────────────────┤
│ Terminal │
└─────────────────────────────────────────────┘
See DESIGN.md for the full design rationale.
Documentation
The docs/ directory covers each subsystem in depth:
Testing
Components are pure functions, so tests need no terminal or framework:
use ArtisanBuild\Parfait\Components\Text; use ArtisanBuild\Parfait\Enums\Color; it('styles text', function () { expect(Text::make('t', 'hi')->fg(Color::Cyan)->render()) ->toBe("\e[38;5;81mhi\e[0m"); });
Run the suite:
composer test # pest composer analyse # phpstan composer lint # pint (use lint:test to check without fixing)
Contributing
Contributions are welcome — see CONTRIBUTING.md for the dev setup, coding standards, and quality gates.
License
Parfait is open-source software licensed under the MIT license.
统计信息
- 总下载量: 3
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 3
- 点击次数: 0
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-03
