Luca Perullo
Components

Component

LiveNew

AI Chat Bubble

Render Markdown via react-markdown + remark-gfm con safe-fence per stream incompleti (chiude automaticamente ``` lasciate aperte mid-stream). Caret blinkante quando streaming=true. Tre varianti: user (right, dense), assistant (border + bg-alt), system (pill).

AIChatStreamingMarkdownClient
Open in ClaudeSorgente

Esempio01

ai-chat-bubble.tsx

Come gestisco il caching di Next.js 16?

Ottima domanda. Next 16 abbandona il caching aggressivo by-default. Le opzioni:

  • fetch(url, { cache: "force-cache" }) per opt-in
  • unstable_cache() per dati custom

Sto pensando alla risposta su React 19 actions

Note Durante lo streaming il caret blinka e i code-block restano in classe pre default (zero highlighting per evitare flashing mentre il linguaggio viene rilevato). Dopo lo stream, lo stesso contenuto re-renderizza normale. useTypewriter è esportato come helper per simulare streaming da una stringa.

Prompt LLM02

Incolla in Claude o ChatGPT per generare la tua variante. Include il contesto del brand, i token e i vincoli del progetto.

Prompt · ai-chat-bubble
Open in Claude
Sei un senior frontend engineer. Stai lavorando su un sito Next.js 16 + React 19 + Tailwind v4 in italiano, look chanhdai-inspired: colonna stretta 672px, Geist Sans + Geist Mono, hairline 1px, divisori a stripe diagonale, palette zinc.

Token CSS disponibili: --bg, --bg-alt, --fg, --fg-muted, --fg-soft, --border, --border-strong, --accent. Usa SEMPRE queste variabili tramite le utility tailwind generate (bg-bg, text-fg-muted, border-border, ecc.). Helper "cn" da "@/lib/utils". Niente librerie UI extra: solo lucide-react e tailwind-merge.

Genera un componente <AiChatBubble> production-grade per chat con LLM.
Type:
- AiChatBubbleRole = "user" | "assistant" | "system"
Props:
- role: AiChatBubbleRole.
- children: string | ReactNode (string = markdown).
- streaming?: boolean.
- avatar?: ReactNode.
- timestamp?: string.
- showCopy?: boolean (default true).
- className?: string.

Implementazione:
- "use client", react-markdown + remark-gfm.
- system → pill centrato, niente avatar.
- user → flex-row-reverse, bubble bg-fg text-bg, rounded-br-[4px].
- assistant → bubble border-border bg-bg-alt, rounded-bl-[4px], CopyButton on hover (se !streaming && string).
- Streaming caret: span animato con keyframe ai-caret-blink (50% opacity 0).
- Markdown safe-fence: se streaming && (count("```")) % 2 === 1 → append "\n```" per chiudere il fence rotto.
- prose styling per markdown via classi prose prose-sm + tweaks code/pre.
- Esporta useTypewriter(target, charsPerSec) per simulare streaming.

Output: file completo src/components/ai-chat-bubble.tsx.

Uso tipico03

tsx
<AiChatBubble role="assistant" streaming={isStreaming}>
  {assistantText}
</AiChatBubble>

Dipendenze04

npm
  • react-markdown
  • remark-gfm
  • lucide-react
  • tailwind-merge
  • clsx
Interno
  • @/lib/utils#cn
  • @/components/copy-button

Ti è servito? Dimmelo, oppure proponi il prossimo componente.