AI Streaming Response
hextaui/ai-streaming-responseFreeComponent
Display streaming AI responses with token-by-token animation.
Install it
npx shadcn@latest add https://hextaui.com/r/ai-streaming-response.jsonSource
1"use client";23import { useEffect, useMemo, useRef, useState } from "react";4import { cn } from "@/lib/utils";5import AIMessage from "./ai-message";67const STREAMING_CONFIG = {8 TOKEN_DELAY: 30,9 PAUSE_AFTER_PERIOD: 200,10 PAUSE_AFTER_COMMA: 100,11 PAUSE_AFTER_PARAGRAPH: 300,12} as const;1314interface AIStreamingResponseProps {15 content: string;16 onComplete?: () => void;17 autoStart?: boolean;18 className?: string;19}2021function useTokens(content: string): string[] {22 const tokens = useMemo(() => {23 const tokenRegex = /(\S+|\s+)/g;24 return content.match(tokenRegex) || [];25 }, [content]);2627 return tokens;28}2930function useStreaming(31 tokens: string[],32 autoStart: boolean,33 onComplete?: () => void34) {35 const [displayedTokens, setDisplayedTokens] = useState<string[]>([]);36 const [isPaused, setIsPaused] = useState(!autoStart);37 const [isComplete, setIsComplete] = useState(false);38 const timeoutRef = useRef<NodeJS.Timeout | null>(null);39 const currentIndexRef = useRef(0);4041 useEffect(() => {42 if (tokens.length === 0) return;4344 if (timeoutRef.current) {45 clearTimeout(timeoutRef.current);46 timeoutRef.current = null;47 }4849 const timeoutId = setTimeout(() => {50 setDisplayedTokens([]);51 setIsComplete(false);52 setIsPaused(!autoStart);53 }, 0);54 currentIndexRef.current = 0;5556 return () => clearTimeout(timeoutId);57 }, [tokens, autoStart]);5859 useEffect(() => {60 if (tokens.length === 0) return;61 if (isPaused || isComplete || currentIndexRef.current >= tokens.length) {62 return;63 }6465 const streamNext = () => {66 if (currentIndexRef.current >= tokens.length) {67 setIsComplete(true);68 if (onComplete) {69 onComplete();70 }71 return;72 }7374 const token = tokens[currentIndexRef.current];75 setDisplayedTokens((prev) => [...prev, token]);76 currentIndexRef.current += 1;7778 const trimmedToken = token.trim();7980 let delay = STREAMING_CONFIG.TOKEN_DELAY;8182 if (83 trimmedToken.endsWith(".") ||84 trimmedToken.endsWith("!") ||85 trimmedToken.endsWith("?")86 ) {87 delay += STREAMING_CONFIG.PAUSE_AFTER_PERIOD;88 } else if (89 trimmedToken.endsWith(",") ||90 trimmedToken.endsWith(";") ||91 trimmedToken.endsWith(":")92 ) {93 delay += STREAMING_CONFIG.PAUSE_AFTER_COMMA;94 } else if (token.includes("\n\n")) {95 delay += STREAMING_CONFIG.PAUSE_AFTER_PARAGRAPH;96 }9798// … truncated
What it pulls in
Other registry items
Files it writes
More from HextaUI
All 139 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | HextaUI | Components | Free | 1 dep | |
| AI Chat Historyai-chat-history | HextaUI | Components | Free | no deps | |
| AI Citationsai-citations | HextaUI | Components | Free | no deps | |
| AI Conversationai-conversation | HextaUI | Components | Free | no deps | |
| AI Error Handlerai-error-handler | HextaUI | Components | Free | no deps | |
| AI File Uploadai-file-upload | HextaUI | Components | Free | no deps | |
| AI Messageai-message | HextaUI | Components | Free | 4 deps | |
| AI Model Selectorai-model-selector | HextaUI | Components | Free | no deps |
