feat(components): add @vue-tui/components + Spinner (first component) (#229)

* feat(components): scaffold @vue-tui/components with spinner preset data

New private package (0.0.0) for high-level components composed from runtime
primitives. Ships the dots/line preset data + a pure resolveSpinner() with
edge-guards (empty frames / unknown type → dots; interval threads both modes),
fully unit-tested incl. a width-safety guard (string-width === 1 per frame).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(components): add the Spinner component

Spinner is a <Text> + useAnimation pure composition: `type` selects an inline
preset (dots/line), `frames`/`interval` is the escape hatch, and it always
animates (no interactivity gate — there is no public signal; matches Ink).
Renders a visible glyph non-interactively. Typed props via ExtractPublicPropTypes.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(components): Spinner color + label

`color` tints the glyph only (label stays default, matching ora/@inkjs/ui);
`label` renders after the glyph with a separating space (interpolated so Vue
whitespace-condense keeps it). Two <Text> spans share an outer <Text> context so
they render inline on one line rather than stacking vertically.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(components): add @vue-tui/components to the CI task graph

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(components): record Spinner decisions

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(components): refresh package status and clarify ink-spinner parity note

The design-principles status blockquote said the package was 'planned'
with no code yet; this branch ships Spinner, so mark it active. Also
reword the spinner Behavior note to name the third-party ink-spinner
explicitly and soften it to an unverified, un-run-checked observation.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(readme): list @vue-tui/components + <Spinner>

Add the new package to the hero line + Packages table, and <Spinner> to the
Components table. Marked "New; early".

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(readme): give @vue-tui/components its own section

Move <Spinner> out of the runtime Components table into a separate
"High-level Components" section so the package's API surface stays decoupled
from the runtime primitives. Add a ToC entry.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(readme): drop the "New; early" status tag for @vue-tui/components

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yunfei He
2026-06-28 16:42:01 +08:00
committed by GitHub
parent 7a8ccf3655
commit 8aea881ffa
14 changed files with 387 additions and 8 deletions
+16 -6
View File
@@ -6,7 +6,7 @@ The Vue framework for terminal UIs.
Build with components, develop with HMR, test with confidence.
<p align="center">
<a href="https://npmx.dev/@vue-tui/runtime"><code>@vue-tui/runtime</code></a> · <a href="https://npmx.dev/@vue-tui/vite"><code>@vue-tui/vite</code></a> · <a href="https://npmx.dev/@vue-tui/testing"><code>@vue-tui/testing</code></a>
<a href="https://npmx.dev/@vue-tui/runtime"><code>@vue-tui/runtime</code></a> · <a href="https://npmx.dev/@vue-tui/components"><code>@vue-tui/components</code></a> · <a href="https://npmx.dev/@vue-tui/vite"><code>@vue-tui/vite</code></a> · <a href="https://npmx.dev/@vue-tui/testing"><code>@vue-tui/testing</code></a>
</p>
- **Vue SFC & JSX** — write terminal interfaces with `<template>`, TSX, or both
@@ -82,6 +82,7 @@ For non-interactive output — snapshots, CI logs, piped commands — `renderToS
- [Packages](#packages)
- [Examples](#examples)
- [Components](#components)
- [High-level Components](#high-level-components)
- [Composables (Hooks)](#composables-hooks)
- [Testing](#testing)
- [Development](#development)
@@ -91,11 +92,12 @@ For non-interactive output — snapshots, CI logs, piped commands — `renderToS
## Packages
| Package | Description |
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`@vue-tui/runtime`](https://www.npmjs.com/package/@vue-tui/runtime) | The core framework — Vue 3 renderer for the terminal with components (`Box`, `Text`, `Static`, etc.), composables (`useInput`, `useFocus`, `useApp`, etc.), and yoga-based flexbox layout. _API stabilizing._ |
| [`@vue-tui/vite`](https://www.npmjs.com/package/@vue-tui/vite) | Vite plugin — add `vueTui()` to `vite.config.ts` for an in-process terminal dev server with HMR (`npm run dev`) plus a production build (`vite build`). _Experimental; may change._ |
| [`@vue-tui/testing`](https://www.npmjs.com/package/@vue-tui/testing) | Test harness — render in an isolated fake terminal, simulate input, assert output frame by frame |
| Package | Description |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`@vue-tui/runtime`](https://www.npmjs.com/package/@vue-tui/runtime) | The core framework — Vue 3 renderer for the terminal with components (`Box`, `Text`, `Static`, etc.), composables (`useInput`, `useFocus`, `useApp`, etc.), and yoga-based flexbox layout. _API stabilizing._ |
| [`@vue-tui/vite`](https://www.npmjs.com/package/@vue-tui/vite) | Vite plugin — add `vueTui()` to `vite.config.ts` for an in-process terminal dev server with HMR (`npm run dev`) plus a production build (`vite build`). _Experimental; may change._ |
| [`@vue-tui/testing`](https://www.npmjs.com/package/@vue-tui/testing) | Test harness — render in an isolated fake terminal, simulate input, assert output frame by frame |
| [`@vue-tui/components`](https://www.npmjs.com/package/@vue-tui/components) | High-level components built on the runtime primitives — currently `<Spinner>` (animated loading), with more to come. |
## Examples
@@ -117,6 +119,14 @@ For non-interactive output — snapshots, CI logs, piped commands — `renderToS
| [`<Static>`](./packages/runtime) | Renders a list of items once, above the redrawn region |
| [`<Transform>`](./packages/runtime) | Applies a string transform function to each rendered line |
## High-level Components
The [`@vue-tui/components`](./packages/components) package adds higher-level components composed from the runtime primitives — published separately from the core.
| Component | Description |
| ------------------------------------ | ------------------------------------------------------------------------------------------ |
| [`<Spinner>`](./packages/components) | Animated loading spinner — built-in `dots`/`line` presets or custom frames, optional label |
## Composables (Hooks)
| Composable | Description |