@rettangoli/tui
v0.0.1
Published
Terminal UI framework using Rettangoli FE contracts
Maintainers
Readme
@rettangoli/tui
Proof-of-concept Terminal UI package that keeps the Rettangoli FE component contract (.view.yaml, .schema.yaml, .store.js, .handlers.js) and provides built-in TUI renderers.
Goals
- Mirror
@rettangoli/fepackage structure for compatibility. - Provide UI + FE behavior in one package for TUI rendering.
- Keep component authoring style close to
@rettangoli/uiand@rettangoli/fe. - Keep TUI core minimal and terminal-native.
Core API
import { createComponent, createTuiRuntime } from "@rettangoli/tui";createComponent(componentFiles, deps)creates a TUI component class using FE contracts.createTuiRuntime({ componentRegistry })renders registered components to terminal strings.
Default TUI Primitives
Included core primitives:
rtgl-viewrtgl-textrtgl-inputrtgl-listrtgl-tablertgl-textareartgl-dividerrtgl-dialog
rtgl-divider supports:
- horizontal (default):
rtgl-divider w=40 - vertical:
rtgl-divider o=v h=3
rtgl-list supports:
:items=${array}(string or object items)- object items can include
label/textanddonefor checkbox rendering :selectedIndex=${index}for highlighted roww=ffor full terminal width
rtgl-table supports:
:data=${{ columns, rows }}(same shape as@rettangoli/uitable data)- columns:
{ key, label }[] - rows: object array (supports nested keys like
user.name) :selectedIndex=${index}for highlighted roww=ffor full terminal width
rtgl-dialog supports:
open/open=true(show dialog)title="Dialog title"w=56(dialog width)x=8(left indent; floating offset)y=12(top row offset)
Dialog renders as a floating overlay layer and does not consume normal layout flow.
For rich multiline input you can either:
use
rtgl-textareafor native in-dialog editingor use external editor piggyback for larger content:
call
deps.openExternalEditor({ initialValue, fileName })from handlersruntime suspends TUI, opens
$VISUAL/$EDITOR(fallback:nvim,vim,vi,nano)edited content is read back, TUI resumes, and state can be updated
You can extend with custom component renderers through deps.components or runtime components.
CLI
# build bundle from component directories
node -e "import('@rettangoli/tui/cli').then(({build}) => build({ dirs:['./components'], setup:'./setup.js' }))"build emits a Node ESM bundle exporting:
registrycreateRuntime()
Setup helper
import { deps } from "@rettangoli/tui/setup";This provides default TUI primitive renderers for common categories (components, pages, layouts).
Proof Of Concept
cd packages/rettangoli-tui
bun install
bun run pocInteractive controls:
rrefresh metric queue depthArrowUpincrement queue depthArrowDowndecrement queue depthqquit
For non-interactive environments:
bun run poc:staticComponent Showcase
Run the interactive primitive showcase:
bun run showcaseShowcase controls:
qquitrreset demo stated/topen title editor dialogeopen task content in external editorArrowUp/ArrowDownmove selected task row- inside title dialog: type (auto-wrap),
Enter,Backspace, arrows Ctrl+Ssave title,Esccancel
Static render:
bun run showcase:static