Skip to content

Repository files navigation

opentui-aestheta

A monorepo of small, opinionated UI components for OpenTUI: animations, overlays, and one-off pieces. Sibling library to opentui-glyphfit and opentui-tape.

unified gallery

Status: Sprints 1–4 shipped, CP24 (Sprint 4 batch 10). Every package below has a running demo and a recorded showcase. 307/307 tests passing. See HANDOFF.md if you're picking this up cold; DEVLOG.md for the dated checkpoint history.


Showcase

Package Demo
shimmer @aestheta/shimmer Time-keyed cell intensity — Pulse · Wave · custom paint
loaders @aestheta/loaders Spinner catalog — frame-cycle + shape-driven
skeleton @aestheta/skeleton Loading placeholders — Skeleton + SkeletonBlock
drawer @aestheta/drawer Slide-in panel — translateX overlay, no layout reflow
diff-flash @aestheta/diff-flash Row-keyed ticker — atomic uptick/downtick flashes
marquee @aestheta/marquee Scrolling viewports — wrap + bounce + easing
glow @aestheta/glow Breathing borders — line + block, any colour
confetti @aestheta/confetti One-shot deterministic particle burst

Why this exists

@opentui/core ships static primitives (Text, Input, Select, Slider, Markdown). opentui-glyphfit ships static rasterisation. opentui-tape ships streaming domain renderables that update on tick deltas — but with no time-based animation. @opentui-ui covers dialogs and toasts.

What's missing is the time axis — primitives that pulse, fade, sweep, and decay. Aestheta provides that layer:

  • A Shimmer Renderable that drives phase-keyed cell repaint.
  • A catalog of indicators (Dots, Bars, Eclipse, PulseRing, …) built either as frame-cycle strings or as shape-driven intensity fields composed on top of Shimmer + glyphfit.
  • One mutable allocation per frame ceiling. No Math.random in the library — all motion is deterministic given a phase value, so visual snapshots stay stable.

See DESIGN.md for the full rationale and roadmap.


Packages

Package What it does Status
@aestheta/shimmer Time-keyed cell-intensity primitive. Shimmer Renderable + Pulse/Wave/TextShimmer presets + pure phase/easings helpers. Sprint 1
@aestheta/loaders Curated indicator catalog. Six frame-cycle loaders + three shape-driven loaders. pulsePeriod compound (CP24). Sprint 1
@aestheta/skeleton Shimmer-backed placeholder. Skeleton, SkeletonBlock, SkeletonReveal (CP23). Sprint 2
@aestheta/drawer Slide-in side panel via translateX/Y. setSide runtime swap (CP23). Sprint 2
@aestheta/diff-flash Cell-level flash decay. Row/cell modes, keyed-row API, FLASH_THEMES palette (CP22). Sprint 2
@aestheta/marquee Scrolling viewport with bounce + gradient (CP24) + pause/resume (CP21). Sprint 3
@aestheta/glow Breathing border with directional pulse origin (CP21). Sprint 3
@aestheta/confetti One-shot deterministic burst. gravity option (CP22). Sprint 3
@aestheta/cli shadcn-style aestheta {list,info,add} (CP19). Sprint 4

The shadcn-style endgame

Long-term goal: a copy-into-your-project workflow modelled on shadcn/ui. Run a single command, pick the components you want, and the source files drop into your repo — owned and modifiable by you, no version-pinning friction.

# shipped in CP19
bunx @aestheta/cli list
bunx @aestheta/cli add diff-flash --dest ./src/ui

The CLI rewrites cross-component imports as it copies, so add diff-flash also installs shimmer and rewrites from "@aestheta/shimmer"from "../shimmer/index.ts". Foreign imports (@opentui/core, etc.) pass through untouched. See packages/cli for full usage.

Each component is its own publishable package for users who prefer versioned dependencies, and its own copyable source tree for users who want to adapt it. The two distribution modes share one source of truth.


Repository layout

opentui-aestheta/
├── DESIGN.md         ← purpose / problem / non-goals / approach / API
├── DEVLOG.md         ← dated checkpoint history
├── packages/
│   ├── shimmer/      ← time-keyed cell-intensity primitive
│   └── loaders/      ← indicator catalog
├── registry/         ← shadcn-style component manifest (Sprint 4)
└── apps/
    └── demo/         ← end-to-end demo composing every component

Each packages/<name>/ follows the same conventions as opentui-glyphfit and opentui-tape: Bun build, ESM exports, peer dep on @opentui/core, strict TypeScript, snapshot tests.


Stuck terminal? (recovery procedure)

If a previous run (CP1–CP3) left your terminal in mouse-tracking mode and your shell is still receiving stray ^[[<35;…M sequences or other escape garbage, reset it:

# Disable SGR 1006 + any-event + button-event + X10 mouse modes
printf '\033[?1006l\033[?1003l\033[?1002l\033[?1000l'

# Or full reset:
tput reset

The Sprint 1 demos in this repo all pass useMouse: false so this shouldn't recur. If it does after running a current demo, please file an issue with your terminal emulator + version.

Quick start

bun install
bun run typecheck     # all packages
bun test              # all packages
bun run demo          # gallery in your terminal

Per-package demos:

bun run d:shimmer
bun run d:loaders

Roadmap

All four sprints shipped — see HANDOFF.md for the detailed state and DEVLOG.md for the dated checkpoint history. The "Next (≤5)" block at the top of the DEVLOG captures the open follow-ups (registry hosting, real-terminal verification, cross-repo adoption in opentui-tape).

Component Status Notes
shimmer Sprint 1 (CP1) Time-keyed cell-intensity primitive.
loaders Sprint 1 (CP1) Frame-cycle + shape-driven indicators. pulsePeriod compound in CP24.
skeleton Sprint 2 (CP~5) Shimmer-backed placeholder rect. SkeletonReveal in CP23.
drawer Sprint 2 (CP~5) Slide-in side panel via translate. setSide runtime swap in CP23.
diff-flash Sprint 2 (CP~5) Cell-level flash decay. FLASH_THEMES in CP22.
marquee Sprint 3 (CP~9) Scrolling viewport. pauseFor/pause/resume in CP21, gradientFrom/To in CP24.
glow Sprint 3 (CP~9) Breathing border. Directional origin in CP21.
confetti Sprint 3 (CP~9) Deterministic seeded burst. gravity in CP22.
tui-test Sprint 3.5 (CP~12) PTY + xterm-headless harness with semantic locators.
cli + registry Sprint 4 (CP19) Manifest generator + aestheta {list,info,add}.

Relationship to other packages in this org

  • @opentui/core (upstream) — rendering primitives. We are a consumer.
  • opentui-glyphfit (sibling) — glyph rendering and charsets. Used by aestheta's shape-driven loaders only; frame-cycle loaders do not depend on it.
  • opentui-tape (sibling) — financial domain primitives. Tape's demos compose aestheta components but tape itself does not depend on them.
  • @opentui-ui (sibling) — dialog/toast. Orthogonal to aestheta.

License

MIT (per package).

About

opentui component lib for fynance --wip

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages