šŸ“ Sign Up | šŸ” Log In

← Root | ↑ Up

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ šŸ“„ shadcn/directory/ibelick/prompt-kit/response-stream/page │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

╔══════════════════════════════════════════════════════════════════════════════════════════════╗
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘

import ComponentCodePreview from "@/components/app/component-code-preview" import { generateMetadata } from "../utils/metadata" import { ResponseStreamFade } from "./response-stream-fade" import { ResponseStreamTypewriter } from "./response-stream-typewriter" import { ResponseStreamWithMarkdown } from "./response-stream-with-markdown" import { UseTextStreamExample } from "./use-text-stream-example"

export const metadata = generateMetadata( "Response Stream", "A component to simulate streaming text on the client side, perfect for fake responses, or any controlled progressive text display." )

Response Stream (experimental)

A component to simulate streaming text on the client side, perfect for fake responses, or any controlled progressive text display.

We don't recommend to use it for LLM output.

Examples

Typewriter Mode

The default mode that types out text character by character, simulating a typing effect.

<ComponentCodePreview component={<ResponseStreamTypewriter />} filePath="app/docs/response-stream/response-stream-typewriter.tsx" classNameComponentContainer="p-8 justify-start items-start min-h-[150px]" hasReTrigger />

Fade Mode

The fade mode reveals text word by word with a smooth fade-in animation.

<ComponentCodePreview component={<ResponseStreamFade />} filePath="app/docs/response-stream/response-stream-fade.tsx" classNameComponentContainer="p-8 justify-start items-start min-h-[150px]" hasReTrigger />

With Markdown

ResponseStream can be combined with the Markdown component to create rich, animated content, for that you need to use the useTextStream hook directly.

Note: If you want to use mode="fade", you need to manually render the segments with appropriate CSS animations. It can be hard to get it done with markdown, the way is to write a custom remarkPlugins. We have a demo but it's a bit too experimental to be included here, happy to receive a PR if you have a good solution.

<ComponentCodePreview component={<ResponseStreamWithMarkdown />} filePath="app/docs/response-stream/response-stream-with-markdown.tsx" classNameComponentContainer="p-8 justify-start items-start min-h-[400px]" disableNotProse hasReTrigger />

Using the useTextStream Hook with fade mode

When using the useTextStream hook with fade mode, you need to manually render the segments with appropriate CSS animations.

<ComponentCodePreview component={<UseTextStreamExample />} filePath="app/docs/response-stream/use-text-stream-example.tsx" classNameComponentContainer="p-8 justify-start items-start min-h-[200px]" hasReTrigger />

Installation

<Tabs defaultValue="cli"> <TabsList> <TabsTrigger value="cli">CLI</TabsTrigger> <TabsTrigger value="manual">Manual</TabsTrigger> </TabsList> <TabsContent value="cli">

<CodeBlock code={npx shadcn add "https://prompt-kit.com/c/response-stream.json"} language="bash" />

</TabsContent> <TabsContent value="manual"> <Steps>

<Step>Copy and paste the following code into your project.</Step>

<CodeBlock filePath="components/prompt-kit/response-stream.tsx" language="tsx" />

<Step>Update the import paths to match your project setup.</Step>

</Steps> </TabsContent> </Tabs>

Component API

ResponseStream

| Prop | Type | Default | Description | | :----------------- | :-------------------------------- | :----------- | :----------------------------------------------------------- | | textStream | string | AsyncIterable<string> | | The text to stream or an async iterable of text chunks | | mode | "typewriter" | "fade" | "typewriter" | The animation mode to use | | speed | number | 20 | Speed from 1-100, where 1 is slowest and 100 is fastest | | className | string | "" | Additional CSS classes | | onComplete | () => void | | Callback function when streaming is complete | | as | string | "div" | Element type to render | | fadeDuration | number | | Custom fade duration in ms (overrides speed) | | segmentDelay | number | | Custom delay between segments in ms (overrides speed) | | characterChunkSize | number | | Custom characters per frame for typewriter (overrides speed) |

useTextStream Hook

Parameters

| Parameter | Type | Default | Description | | :----------------- | :-------------------------------- | :----------- | :----------------------------------------------------------- | | textStream | string | AsyncIterable<string> | | The text to stream or an async iterable of text chunks | | speed | number | 20 | Speed from 1-100, where 1 is slowest and 100 is fastest | | mode | "typewriter" | "fade" | "typewriter" | The animation mode to use | | onComplete | () => void | | Callback function when streaming is complete | | fadeDuration | number | | Custom fade duration in ms (overrides speed) | | segmentDelay | number | | Custom delay between segments in ms (overrides speed) | | characterChunkSize | number | | Custom characters per frame for typewriter (overrides speed) | | onError | (error: unknown) => void | | Callback function when an error occurs |

Return Value

| Property | Type | Description | | :-------------- | :---------------------------------- | :---------------------------------------- | | displayedText | string | The current text being displayed | | isComplete | boolean | Whether streaming is complete | | segments | { text: string; index: number }[] | Text segments for fade mode | | getFadeDuration | () => number | Function to get the current fade duration | | getSegmentDelay | () => number | Function to get the current segment delay | | reset | () => void | Function to reset the streaming state | | startStreaming | () => void | Function to start or restart streaming | | pause | () => void | Function to pause streaming | | resume | () => void | Function to resume streaming |

ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•

← Root | ↑ Up