Uranus® Design System
AI

CodeBlock

Bloco de código com label de linguagem e botão "Copiar" — sem highlighter embutido.

CodeBlock deliberadamente não embrulha um syntax highlighter. Você controla a renderização via renderCode: passe Shiki, Prism, Highlight.js ou qualquer outro. Isso mantém o pacote leve e evita decisões de tema que invariavelmente brigam com o branding.

No site de docs, o preview usa Shiki com tema github-dark e várias gramáticas carregadas de uma vez (TypeScript/TSX, JavaScript/JSX, JSON, SQL, YAML, Markdown, Bash, Python, Ruby, HTML, CSS, SCSS, Vue e plaintext). Rótulos curtos como ts, json e sql são aceitos no language.

ts
import { useUranusChat } from '@uranus-workspace/ai';

const chat = useUranusChat({ api: '/api/chat' });
chat.sendMessage({ text: 'Olá' });
json
{
  "model": "gpt-4.1-mini",
  "messages": [{ "role": "user", "content": "Olá" }],
  "stream": true
}
sql
SELECT u.id, u.email, COUNT(o.id) AS orders
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2025-01-01'
GROUP BY u.id, u.email
ORDER BY orders DESC
LIMIT 10;
'use client';

import { CodeBlock } from '@uranus-workspace/ai';
import { ShikiCodeBody } from '../../components/shiki-code-body';

const tsSample = `import { useUranusChat } from '@uranus-workspace/ai';

const chat = useUranusChat({ api: '/api/chat' });
chat.sendMessage({ text: 'Olá' });`;

const jsonSample = `{
  "model": "gpt-4.1-mini",
  "messages": [{ "role": "user", "content": "Olá" }],
  "stream": true
}`;

const sqlSample = `SELECT u.id, u.email, COUNT(o.id) AS orders
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2025-01-01'
GROUP BY u.id, u.email
ORDER BY orders DESC
LIMIT 10;`;

export default function CodeBlockDefault() {
  return (
    <div className="mx-auto flex w-full max-w-2xl flex-col gap-4">
      <CodeBlock
        language="ts"
        code={tsSample}
        renderCode={(src) => <ShikiCodeBody code={src} language="ts" />}
      />
      <CodeBlock
        language="json"
        code={jsonSample}
        renderCode={(src) => <ShikiCodeBody code={src} language="json" />}
      />
      <CodeBlock
        language="sql"
        code={sqlSample}
        renderCode={(src) => <ShikiCodeBody code={src} language="sql" />}
      />
    </div>
  );
}

Uso

import { CodeBlock } from '@uranus-workspace/ai';

<CodeBlock
  language="ts"
  code={`const ok: boolean = true;`}
/>

Com seu próprio highlighter

Instale por exemplo shiki (e, no React, hast-util-to-jsx-runtime se quiser converter codeToHast em JSX sem HTML cru). O próprio site de docs inclui uma referência em apps/docs/components/shiki-code-body.tsx.

import { CodeBlock } from '@uranus-workspace/ai';

<CodeBlock
  code={code}
  language="json"
  renderCode={(source) => <YourHighlighter code={source} language="json" />}
/>

YourHighlighter é seu componente (Shiki, Prism, Highlight.js, …): ele recebe a string source e devolve um ReactNode. O slot renderCode é só essa porta.

API

  • code — string do código.
  • language — label exibido no topo. Default 'plaintext'.
  • renderCode — slot opcional para o highlighter.
  • hideCopy — esconde o botão de copiar quando o conteúdo é interativo.