Code Block
Superfície de código com syntax highlighting movida a shiki. Faz lazy-load do highlighting de tokens no mount, distribui temas escuro e claro combinados, e se combina com um botão de cópia ciente de contexto.
Visão geral
CodeBlock renderiza código-fonte com highlighting para qualquer uma das linguagens empacotadas do shiki. Ele carrega codeToHtml no mount (para que o bundle fique pequeno), produz uma variante clara e uma escura em paralelo, e alterna entre elas via o seletor dark: do Tailwind em vez de remontar.
Um pequeno context React expõe a string code crua aos descendentes. Isso permite que CodeBlockCopyButton (e qualquer child customizado que você colocar no slot de ação posicionado absolutamente) copie o source subjacente sem prop drilling.
Use para artefatos de código em streaming, snippets MDX dentro de saída de ferramenta, diffs gerados por agente e qualquer outro lugar onde você precisa de um bloco inline com highlighting.
Preview
Padrão
'use client';import { CodeBlock } from '@gremorie/rx-artifacts';const SAMPLE = `import { Message, MessageContent } from "@gremorie/rx-ai";export function Demo() { return ( <Message from="assistant"> <MessageContent>Hi from Gremorie</MessageContent> </Message> );}`;export function CodeBlockPreview() { return <CodeBlock code={SAMPLE} language="tsx" showLineNumbers />;}Com botão de cópia
'use client';import { CodeBlock, CodeBlockCopyButton } from '@gremorie/rx-artifacts';const SAMPLE = `import { Message, MessageContent } from "@gremorie/rx-ai";export function Demo() { return ( <Message from="assistant"> <MessageContent>Hi from Gremorie</MessageContent> </Message> );}`;export function CodeBlockCopyPreview() { return ( <CodeBlock code={SAMPLE} language="tsx"> <CodeBlockCopyButton /> </CodeBlock> );}Anatomia
CodeBlock Shiki-highlighted code container; exposes the raw code via context
└── CodeBlockCopyButton Optional action-slot child; copies the context code to the clipboardInstalação
bash npx gremorie@latest add rx-code-block bash pnpm dlx gremorie@latest add rx-code-block bash yarn dlx gremorie@latest add rx-code-block bash bunx --bun gremorie@latest add rx-code-block
Requer shiki e @gremorie/rx-forms (para Button) como dependências transitivas. Ambos são trazidos automaticamente pelo registry.
Uso
import { CodeBlock, CodeBlockCopyButton } from "@gremorie/rx-artifacts";
export function Example({ source }) {
return (
<CodeBlock code={source} language="tsx" showLineNumbers>
<CodeBlockCopyButton />
</CodeBlock>
);
}import { Component, input } from "@angular/core";
import { CodeBlock, CodeBlockCopyButton } from "@gremorie/ng-artifacts";
@Component({
selector: "app-example",
standalone: true,
imports: [CodeBlock, CodeBlockCopyButton],
template: ` <code-block [code]="source()" language="tsx" [showLineNumbers]="true">
<code-block-copy-button />
</code-block>
`,
})
export class ExampleComponent {
readonly source = input.required<string>();
}
API
<CodeBlock>
| Prop | Type | Default | Descrição |
|---|---|---|---|
code | string | - | A string de source para dar highlight. Obrigatório. |
language | BundledLanguage | - | Qualquer linguagem empacotada do shiki ("tsx", "json", "bash", "python", etc.). |
showLineNumbers | boolean | false | Quando true, prepende um gutter de número de linha muted via um transformer do shiki. |
children | ReactNode | - | Renderizado em um slot superior direito posicionado absolutamente. Use para o botão de cópia ou ações customizadas. |
className | string | - | Classes extras no div raiz. |
Estende todos os HTMLAttributes<HTMLDivElement>.
Temas usados internamente:
- Claro:
github-light-default(upgrade da auditoria final do Odo. O temagithub-lightsimples não passava no AA nos tokens de operador e pontuação.) - Escuro:
github-dark-defaultpara contraste AA simétrico.
<CodeBlockCopyButton>
| Prop | Type | Default | Descrição |
|---|---|---|---|
onCopy | () => void | - | Dispara após uma escrita bem-sucedida no clipboard. |
onError | (error: Error) => void | - | Dispara quando a Clipboard API está ausente ou é rejeitada. |
timeout | number | 2000 | Por quanto tempo (ms) o botão permanece no estado "copiado" antes de reverter. |
children | ReactNode | ícone copy / check | Sobrescreve o ícone. O botão ainda troca para o ícone check no sucesso, a menos que você o substitua totalmente. |
Puxa a string code do CodeBlockContext, então deve ser renderizado dentro de um <CodeBlock>.
highlightCode(code, language, showLineNumbers?)
Helper assíncrono exposto para fluxos SSR / prerender que querem computar o HTML claro e escuro de antemão. Retorna Promise<[lightHtml, darkHtml]>.
Composição
<CodeBlock>monta um bloco<pre>claro e um escuro. O seletordark:do Tailwind alterna a visibilidade, então as trocas de tema são instantâneas (sem re-highlight).- O
CodeBlockContextfornececodeaos descendentes. - Children (tipicamente
CodeBlockCopyButton) se posicionam absolutamente no canto superior direito. O slot suporta qualquer node, então você pode colocar múltiplos botões (ex. copiar + abrir no editor) envolvendo-os na sua própria flex row. - Números de linha são produzidos pelo
lineNumberTransformerpara que participem da saída HTML do shiki, não como uma coluna separada.
Variações
Com números de linha
Útil para snippets longos onde os usuários precisam de um ponto de referência. O gutter é muted para que não compita com as cores dos tokens.
<CodeBlock code={longSnippet} language="tsx" showLineNumbers />Cópia mais ação customizada
O slot de ação aceita qualquer node. Componha múltiplos botões aninhando seu próprio container flex.
<CodeBlock code={source} language="tsx">
<CodeBlockCopyButton />
<Button size="icon" variant="ghost" onClick={openInEditor}>
<ExternalLinkIcon />
</Button>
</CodeBlock>JSON para saída de ferramenta
Combine com Tool. ToolInput e ToolOutput ambos renderizam através de CodeBlock, então as chamadas de ferramenta JSON herdam o mesmo highlighting e tematização.
<CodeBlock code={JSON.stringify(toolResult, null, 2)} language="json" />Acessibilidade
- Teclado: O botão de cópia é um
Buttonreal, então participa da ordem normal de Tab e responde a Enter / Space. - Contraste: Ambos os temas
github-light-defaultegithub-dark-defaultpassam no WCAG AA 4.5:1 em cada token. A auditoria do Odo rejeitou explicitamente o tema mais antigogithub-lightporque os tokens de operador caíam abaixo do limite. - Reduced motion: Não há animação na superfície em si. O botão de cópia alterna entre dois ícones sem transição.
- Leitores de tela: Quando o botão de cópia é apenas de ícone, forneça um nome acessível através da sua própria composição (ex. envolva em um Tooltip com
aria-label). Internamente o botão é umButtonde íconeghost, então as regras padrão de a11y para botões de ícone se aplicam.
Relacionados
- Artifact - o chrome de card que hospeda um
CodeBlockpara artefatos de código gerados - Tool - usa
CodeBlockinternamente para renderizar input e output de ferramenta - Web Preview - a superfície de iframe combinada com
CodeBlockpara preview de HTML ao vivo