generative-loaders: React Loading States for Generative UI

Description:

generative-loaders is a React component package that generates animated loading states for streamed text, inline activity, and image generation.

It ships a stylesheet, typed props and variants, polite live status behavior for text, reduced-motion handling, and stable server markup for SSR applications.

Preview

generative-loaders

Features

  • Animates the text suffix that arrives after a streamed response grows.
  • Adds compact activity indicators for buttons and status rows.
  • Reserves image space with generation placeholders.
  • Supports speed control and paused states.
  • Uses accessible labels for standalone inline and image loaders.
  • Respects prefers-reduced-motion.
  • Falls back to speed 1 for invalid, zero, or negative speed values.

How To Use It

Install and Import the Stylesheet

Install the package and import the CSS once near the application root.

npm install generative-loaders
import { ImageLoader, InlineLoader, TextLoader } from "generative-loaders";
import "generative-loaders/styles.css";

Basic Usage

Use the three primitives according to the content state.

export function GeneratingAnswer({ text }: { text: string }) {
  return <TextLoader text={text} variant="decode" />;
}
export function PendingStatus() {
  return (
    <span>
      <InlineLoader variant="orbit" /> Thinking...
    </span>
  );
}
export function PendingImage() {
  return (
    <ImageLoader
      variant="tiles"
      size={192}
      label="Generating product image"
    />
  );
}

Stream Text From a Response

Pass the complete response received so far to TextLoader. Pass the newest token as an append to your own state. The component preserves the existing prefix and animates the newly appended suffix.

"use client";
import { useState } from "react";
import { TextLoader } from "generative-loaders";
import "generative-loaders/styles.css";
export function StreamingAnswer() {
  const [text, setText] = useState("");
  async function generate() {
    setText("");
    const response = await fetch("/api/generate", { method: "POST" });
    if (!response.ok || !response.body) {
      throw new Error("Generation failed");
    }
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    while (true) {
      const { value, done } = await reader.read();
      if (done) break;
      setText((current) => current + decoder.decode(value, { stream: true }));
    }
  }
  return (
    <div>
      <button type="button" onClick={generate}>
        Generate
      </button>
      <TextLoader text={text} variant="cascade" />
    </div>
  );
}

UI Components

ComponentUse it forVariants
TextLoaderResponses that grow as tokens or chunks arrive.16
InlineLoaderButtons, status rows, and the wait before text arrives.18
ImageLoaderReserved image frames while generation is in progress.12

Text Variants

decode, typewriter, skeleton, cascade, focus, wipe, flip, redact, line, terminal, wave, dissolve, slice, tracking, coalesce, and fragments.

Inline Variants

glyph, matrix, orbit, ripple, signal, spark, rotor, pixel-drift, chomp, snake, fold, gravity, domino, aperture, dot-pulse, vortex, halo, and count-up.

Image Variants

skeleton, bands, tiles, scan, pixel-grid, resolution, coalesce, diffusion, raster, bloom, focus, and shutter.

API Reference

TextLoader Props

PropTypeDefault
textstringRequired
variantTextLoaderVariantRequired
colorCSS color string#111111
speedPositive number1
pausedbooleanfalse
classNamestringNot specified
aria-labelstringNormalized text

InlineLoader Props

InlineLoader accepts variant, size, color, speed, paused, className, and an optional accessible label.

Add label when the indicator stands alone. Keep adjacent status text when it already explains the activity. The component avoids duplicate announcements in that layout.

ImageLoader Props

ImageLoader accepts variant, size, color, radius, speed, paused, className, and label. Its default label is Generating image..

Accessibility and SSR Notes

TextLoader exposes the received text through a polite live status. Decorative animation layers stay hidden from assistive technology.

InlineLoader avoids duplicate announcements when nearby text already describes the activity. Add a label for a standalone indicator.

Every loader respects prefers-reduced-motion and retains a meaningful static state. Text updates are append-aware, which keeps previously received content from reanimating. The package documents stable server markup for SSR applications.

Add Comment