Code Block
Bloques de código pensados para respuestas de IA. Resaltado de sintaxis que sigue el ritmo del streaming, copiar, descargar y ajustar líneas, números de línea y líneas resaltadas, diffs con aceptar y rechazar, y una terminal para comandos.
El código de una respuesta de IA llega unos pocos caracteres cada vez, a menudo como un diff que alguien tiene que aprobar. Code Block resalta mientras llega, sigue las líneas nuevas salvo que el lector se haya desplazado hacia arriba, y mantiene copiar, descargar y ajustar fuera del camino hasta que el código está completo.
El resaltado usa Shiki con los temas claro y oscuro de GitHub, cargados por lenguaje bajo demanda. Solo se tokenizan las líneas nuevas a medida que llega el texto, así que los archivos largos siguen siendo rápidos, y ambos temas se renderizan a la vez para que cambiar el esquema de color nunca parpadee. Los bloques de más de 16 líneas se pliegan tras «Show all».
Pasa un diff unificado y obtienes números de línea antiguos y nuevos, un recuento de cambios y filas teñidas; al copiar se obtiene la versión nueva, no el diff. Añade una revisión y el lector puede aceptar o rechazar el cambio, con ⌘↵ y ⌘⌫ mientras el bloque tiene el foco. CodeFence conecta el mismo bloque a Streamdown, y CodeTerminal muestra comandos con su salida y código de salida.
Añade el registro Pro a components.json
components.json Añade tu token
Crea un token en tu página de cuenta y colócalo en
.env.localcomoHEXTAUI_PRO_TOKEN.Añade el bloque
pnpm dlx shadcn@latest add @hextaui-pro/code-block
En Markdown con Streamdown
Registra CodeFence como renderizador. Lee el lenguaje y los ajustes del bloque como title="app/page.tsx", {2,4-6} y showLineNumbers, y mantiene el resaltado mientras el bloque aún está en streaming.
Revisar un cambio
Muestra una edición propuesta como diff y deja que el lector la acepte o la rechace, con ⌘↵ y ⌘⌫ mientras el bloque tiene el foco.
Por sí solo
Pasa el código y el lenguaje directamente, por ejemplo cuando una llamada a herramienta devuelve el contenido de un archivo.
Anatomía
Las partes que compones, de fuera hacia dentro.
| Parte | Descripción |
|---|---|
CodeBlock | El bloque en sí: encabezado, acciones, código y la barra de revisión opcional. |
CodeFence | Un renderizador de Streamdown que convierte el código delimitado en un CodeBlock. |
CodeTerminal | Un comando con su salida en streaming y su estado de salida. |
CopyButton, DownloadButton, WrapToggle | Las acciones del encabezado, exportadas para tus propios encabezados. |
LanguageIcon | La marca de lenguaje usada en el encabezado. |
| Prop | Tipo | Predeterminado |
|---|---|---|
codeEl código fuente, o un diff unificado cuando diff está definido. | string | – |
languageId o alias de lenguaje de Shiki, como tsx, py o bash. Los ids desconocidos se renderizan como texto plano. | string | – |
filenameSe muestra en el encabezado y se usa para las descargas. | string | – |
streamingMantiene el resaltado incremental, sigue las líneas nuevas y deshabilita las acciones. | boolean | false |
diffTrata el código como un diff unificado. | boolean | false |
lineNumbersMuestra números de línea. Los diffs los muestran salvo que se establezca en false. | boolean | – |
startLineNúmero de la primera línea. | number | 1 |
highlightNúmeros de línea que marcar. | number[] | [] |
defaultWrapEmpieza con las líneas largas ajustadas. | boolean | false |
collapseAfterSe colapsa cuando supera este número de líneas. 0 nunca colapsa. | number | 16 |
actionsControles adicionales en el encabezado, antes de los integrados. | ReactNode | – |
onApplyMuestra un botón Apply que confirma con «Applied». | () => unknown | – |
reviewMuestra la barra de revisión mientras está pendiente, y una insignia una vez aceptado o rechazado. | CodeBlockReview | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
statusLa decisión actual. | "pending" | "accepted" | "rejected" | – |
onAcceptSe llama desde Accept o ⌘↵. | () => void | – |
onRejectSe llama desde Reject o ⌘⌫. | () => void | – |
CodeFence
Regístralo con Streamdown: plugins={{ renderers: [{ language: codeFenceLanguages, component: CodeFence }] }}.
| Prop | Tipo | Predeterminado |
|---|---|---|
codeContenido del bloque delimitado, desde Streamdown. | string | – |
languageLenguaje del bloque delimitado, desde Streamdown. | string | – |
metaTodo lo que sigue al lenguaje: title="…", {1,3-5}, showLineNumbers, startLine=10. | string | – |
isIncompleteTrue mientras el bloque delimitado sigue abierto. | boolean | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
commandEl comando que se ejecutó. | string | – |
outputSalida hasta ahora. Añade a medida que llega. | string | "" |
runningMuestra un spinner y sigue la salida nueva. | boolean | false |
exitCodeSe muestra al terminar. Cualquier valor distinto de 0 se marca como fallido. | number | – |
titleEtiqueta del encabezado. | string | "Terminal" |
| Key | Acción |
|---|---|
| Tab | Recorre las acciones del encabezado, el área de código y Show all. |
| ⌘↵ | Acepta una revisión pendiente mientras el foco está dentro del bloque. |
| ⌘⌫ | Rechaza una revisión pendiente mientras el foco está dentro del bloque. |
| ←→ | Desplaza las líneas largas cuando el área de código tiene el foco. |
- El área de código es una región enfocable con el nombre del archivo, por ejemplo «app/page.tsx code», para que los usuarios de teclado puedan desplazarla.
- Las líneas modificadas no dependen del color. Los marcadores + y − son solo visuales, y los lectores de pantalla oyen «added» o «removed» antes de cada línea modificada.
- Copy anuncia «Copied» y cada botón de icono tiene una etiqueta y un tooltip.
- Los atajos de revisión se ignoran mientras se escribe en un campo, así que nunca roban pulsaciones.
Construido con
Los componentes gratuitos de HextaUI con los que está hecho Code Block. Cada uno se instala por separado.
Código
9 archivos, añadidos a components/blocks/code-block.