AI Component
Artifact Card
Expandable container for AI-generated content — code blocks, charts, and documents that live alongside chat.
Preview
async function fetchAI(prompt: string) {
const res = await fetch("/api/chat", {
method: "POST",
body: JSON.stringify({ prompt }),
});
return res.json();
}Source
Full component implementation using the design system tokens.
"use client";
import { useState } from "react";
import { Code2, BarChart3, FileText, ChevronDown } from "lucide-react";
const typeIcons = {
code: Code2,
chart: BarChart3,
document: FileText,
};
export function DSArtifactCard({
type = "document",
title,
description,
defaultExpanded = false,
children,
}: {
type?: "code" | "chart" | "document";
title: string;
description?: string;
defaultExpanded?: boolean;
children?: React.ReactNode;
}) {
const [expanded, setExpanded] = useState(defaultExpanded);
const Icon = typeIcons[type];
return (
<div className="border border-overlay/10 rounded-xl bg-surface overflow-hidden w-full">
<button
onClick={() => setExpanded(!expanded)}
className="w-full flex items-center gap-3 px-4 py-3 hover:bg-overlay/5 transition-colors text-left"
>
<Icon className="w-4 h-4 text-accent shrink-0" />
<div className="flex-1 min-w-0">
<p className="text-xs font-semibold uppercase tracking-widest text-accent mb-0.5">
Artifact
</p>
<p className="text-sm font-medium text-foreground truncate">{title}</p>
{description && (
<p className="text-xs text-tertiary truncate">{description}</p>
)}
</div>
<ChevronDown
className={`w-4 h-4 text-tertiary transition-transform duration-200 shrink-0 ${
expanded ? "rotate-180" : ""
}`}
/>
</button>
{expanded && children && (
<div className="border-t border-overlay/5 px-4 py-4">{children}</div>
)}
</div>
);
}Props
All available props with types and defaults.
| Prop | Type | Default | Description |
|---|---|---|---|
title* | string | — | Artifact title |
type | 'code' | 'chart' | 'document' | 'document' | Content type — determines icon |
description | string | — | Brief description of the artifact content |
defaultExpanded | boolean | false | Whether the card starts expanded |
children | ReactNode | — | Expanded content |
Variants
Code artifact
Collapsed code block with expand interaction.
Expanded content area for the code artifact.
<DSArtifactCard
type="code"
title="API Integration"
description="fetch wrapper with error handling"
>
<pre className="text-sm font-mono text-secondary">
{codeContent}
</pre>
</DSArtifactCard>Chart artifact
Data visualization container.
Expanded content area for the chart artifact.
<DSArtifactCard
type="chart"
title="Revenue Breakdown"
description="Q4 2024 by region"
>
<ChartComponent data={data} />
</DSArtifactCard>Document artifact
Long-form generated content.
Expanded content area for the document artifact.
<DSArtifactCard
type="document"
title="Project Brief"
description="3 sections, 450 words"
>
<div className="prose">{content}</div>
</DSArtifactCard>Prompt Guide
Prompt Guide — Artifact Card
Use for
- AI-generated code blocks alongside chat
- Data visualizations created by AI
- Generated documents, summaries, and reports
- Any structured output that needs its own container
Don't use for
- Static content cards — use Card component
- Image galleries — artifacts are for generated content
- Settings panels — use Card with form elements
AI Context
Artifact cards solve the 'content alongside conversation' problem. When an AI generates a code block, chart, or document, it lives in an artifact card — expandable, labeled by type, and visually distinct from chat messages. The collapsed state shows type icon + title + description so users can scan what was generated. The expanded state reveals the full content. In Claude-style interfaces, artifacts can be pinned to a side panel.