Components / AI interface

StreamingText

Streamed answer with inline sources, actions, and follow-ups.

Install

npx shadcn@latest add https://irisui.dev/r/streaming-text.json
import StreamingText from "@/components/iris/streaming-text/streaming-text";
Registry item streaming-textBrings in foundationRegistry JSON

Preview

StreamingText

A streamed assistant answer in which words resolve one by one, an inline source chip appears in context, and then the response actions, a sources list and follow-up prompts become usable.

When to use

  • Render an agent's answer with citations as it arrives, followed by copy, retry and feedback actions.
  • Offer follow-up prompts under a finished answer.
  • Not for the agent's intermediate reasoning — use ThinkingState. Not for retrieved passages shown as cards — use ContextCards. For a simple text reveal effect, use TextReveal or StreamText.

Usage

import StreamingText from "@/components/iris/streaming-text/streaming-text";

const words = (s) => s.split(" ").map((text) => ({ text }));

h(StreamingText, {
  loop: false,
  content: [
    ...words("Six sources cover the ECB story, and five agree on the rate path."),
    { text: "", cite: true },
    ...words("One quotes an older inflation figure."),
  ],
  sources: [{ name: "Wire", domain: "wire.example", href: "/sources/wire", image: "/icons/wire.svg" }],
  followUps: ["Which source disagrees on inflation"],
  labels: { sources: "6 sources" },
  onFollowUp: (text) => ask(text),
});

Props

Prop Type Default Description
content { text: string; cite?: boolean }[] an Entrolytics answer about weekly traffic Tokens streamed about every 55ms. A token with cite: true renders an inline chip for sources[0].
sources { name: string; domain: string; href: string; image: string }[] 3 demo sources Shown in the inline chip (the first one only), the avatar stack and the expandable list. image is a small square icon URL, rendered through the provider's image component (IrisProvider), a plain <img> by default.
followUps string[] 2 demo prompts Follow-up buttons shown once the stream completes.
labels Partial<{ sources: string; followUps: string }> 3 sources / Follow-ups Sources toggle label and the follow-ups heading.
loop boolean true Restarts the stream after a 3.4s hold. Set it to false in a real thread.
fill boolean false Fills the parent's width instead of the 380px measure and the minimum height.
onDone () => void — Called when the stream finishes (only when loop is false).
onFollowUp (text: string, index: number) => void — Called when a follow-up is chosen.
variant string — Accepted for gallery parity. It has no effect.

Notes

  • The default sources are placeholders on .example domains with # links. Pass your own sources.
  • Source links open in a new tab (target="_blank", rel="noreferrer").
  • The action icons (copy, retry, thumbs up and down) are decorative buttons with aria-label="Action" and no handlers. Wire them up or relabel them before shipping.
  • The sources toggle has aria-expanded. Actions and follow-ups stay non-interactive (pointer-events: none) until the stream completes.
  • Reads --ink, --ink-2, --ink-3, --inset, --hover, --hover-2, --line and --canvas.