8aea881ffa
* 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>
27 lines
1.1 KiB
Vue
27 lines
1.1 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from "vue";
|
|
import { useAnimation, Text } from "@vue-tui/runtime";
|
|
import { spinnerProps } from "./spinner-props.ts";
|
|
import { resolveSpinner } from "./spinners.ts";
|
|
|
|
defineOptions({ name: "Spinner" });
|
|
const props = defineProps(spinnerProps);
|
|
|
|
const set = computed(() => resolveSpinner(props));
|
|
const { frame } = useAnimation({ interval: () => set.value.interval });
|
|
const glyph = computed(() => set.value.frames[frame.value % set.value.frames.length]);
|
|
</script>
|
|
|
|
<template>
|
|
<!-- The outer <Text> establishes a shared text context (runtime TextContextKey) so
|
|
both inner spans render INLINE as <tui-virtual-text> (one line, `⠋ Loading`).
|
|
Two bare sibling top-level <Text> would each be a block <tui-text> node and stack
|
|
vertically under the root's column direction. The outer Text carries no color, so
|
|
only the glyph span is tinted; the label span stays default. The separating space
|
|
is an interpolation so Vue's whitespace:'condense' keeps it. -->
|
|
<Text
|
|
><Text :color="color">{{ glyph }}</Text
|
|
><Text v-if="label">{{ " " + label }}</Text></Text
|
|
>
|
|
</template>
|