Code block
Artifact de código com syntax highlight e copy-to-clipboard, feito streaming pelo modelo.
Visão geral
Um artifact de código para quando o modelo produz código-fonte. Construído sobre o
primitivo CodeBlock de @gremorie/rx-artifacts (Shiki por baixo dos panos)
com um overlay CodeBlockCopyButton. O modelo emite { code, language, filename }; o artifact cuida do highlight, da quebra de linha e da
affordance de copiar.
Este é o artifact que você quer sempre que o modelo "escreve um snippet" no chat — markup production-grade, botão de copiar acessível, sem fiação manual.
Preview
Schema
O LLM retorna output estruturado que segue este shape:
{
type: "code-block",
code: string,
language: string, // "tsx", "ts", "js", "py", "rs", ...
filename?: string,
}Anatomia
Card
├─ CardHeader filename + Badge (outline) — artifact type
└─ CodeBlock rx-artifacts primitive (Shiki highlight against `code`)
└─ CodeBlockCopyButton overlay copy-to-clipboard controlInstalação
npx gremorie@latest add artifact-code-blockpnpm dlx gremorie@latest add artifact-code-blockyarn dlx gremorie@latest add artifact-code-blockbunx --bun gremorie@latest add artifact-code-blockExemplos de prompt
Prompts de exemplo que produzem output válido para este artifact:
- "Me escreva um componente React de save-bar em TSX."
- "Mostre o SQL para criar uma tabela de users com email + role."
- "Me dê um snippet Python que chama a API da OpenAI."
Código
'use client';
import {
Badge,
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@gremorie/rx-display';
import { CodeBlock, CodeBlockCopyButton } from '@gremorie/rx-artifacts';
const CODE = `import { Button } from "@gremorie/rx-forms";
export function SaveBar() {
return (
<div className="sticky bottom-0 flex justify-end gap-3 border-t bg-background/90 p-3 backdrop-blur">
<Button variant="ghost">Cancel</Button>
<Button>Save changes</Button>
</div>
);
}`;
export function CodeBlockArtifact() {
return (
<Card>
<CardHeader>
<div className="flex items-center justify-between gap-3">
<div>
<CardTitle>SaveBar.tsx</CardTitle>
<CardDescription>
Streamed code emitted by the model with Shiki highlighting.
</CardDescription>
</div>
<Badge variant="outline">TSX + Shiki</Badge>
</div>
</CardHeader>
<CardContent>
<CodeBlock code={CODE} language="tsx">
<CodeBlockCopyButton />
</CodeBlock>
</CardContent>
</Card>
);
}npx gremorie@latest add ng-code-blockimport { Component } from '@angular/core';
import {
Badge,
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
} from '@gremorie/ng-display';
import { CodeBlock, CodeBlockCopyButton } from '@gremorie/ng-artifacts';
@Component({
selector: 'app-code-artifact',
standalone: true,
imports: [
Badge,
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CodeBlock,
CodeBlockCopyButton,
],
template: `
<gr-card class="w-full max-w-2xl">
<gr-card-header>
<div class="flex items-center justify-between gap-2">
<div>
<gr-card-title>SaveBar.tsx</gr-card-title>
<gr-card-description>
Streamed code emitted by the model with Shiki highlighting.
</gr-card-description>
</div>
<gr-badge variant="outline">TSX + Shiki</gr-badge>
</div>
</gr-card-header>
<gr-card-content>
<code-block [code]="code" language="tsx">
<code-block-copy-button />
</code-block>
</gr-card-content>
</gr-card>
`,
})
export class CodeArtifactComponent {
readonly code = 'import { Button } from "@gremorie/rx-forms";';
}Comportamento de streaming
Este artifact suporta schema parcial. Conforme o modelo faz streaming do código, o Shiki refaz o highlight a cada chunk para que o usuário veja o output colorido aparecer progressivamente. O botão de copiar permanece armado contra o valor bufferizado mais recente.