Ir al contenido

Componentes · Ola 4 · Editorial

Prose

Voz de lectura para el HTML de un texto largo: párrafos, títulos, citas, listas, código y tablas. Aplica la voz de lectura de Arche (Piazzolla a 17 px, interlineado 1,6, hasta 55ch) al HTML que genera un procesador de Markdown. Todos sus selectores tienen especificidad cero: el producto los ajusta con una sola clase.

import { Prose } from '@archeblack/ui';

Ejemplos

Un ensayo

Títulos, párrafos, énfasis, un link con <strong> adentro, una lista y los espacios entre bloques: 20 px de flujo, 48 antes de un h2, 40 antes de un h3 y 32 antes de un h4. Los títulos son los h2, h3 y h4 que genera marked en un post real, donde el h1 es el de la cabecera; en esta página rompen a propósito el esquema de encabezados (quedan al nivel de «Ejemplos»), porque el estilo de cada título sale de su etiqueta.

La mesa

Una reunión de eruditos. Hombres sentados alrededor de una mesa con sus méritos sobre la madera, hablando, midiendo, sosteniendo cada afirmación con su prueba. No hay impostura en la escena. Cada uno hizo el trabajo: leyó, revisó, se corrigió, aprendió a no afirmar más de lo que podía demostrar.

Conviene decirlo antes que nada, porque de otro modo todo lo que sigue se malinterpreta. La mesa no está equivocada. Aprendimos a mirar así por razones buenas, como recuerda Byung-Chul Han cuando habla de la sociedad del rendimiento.

Lo que la prueba no alcanza

Hay una sed ahí que el saber no calma. No porque sea poco, sino porque es de otro orden:

  • los sueños, que nadie archiva;
  • las certezas que llegan antes que sus razones;
  • las coincidencias, de las que nadie lleva registro.

Un error de categoría

Pedirle a un sueño su bibliografía no es rigor. Es pedirle a un mapa que te diga cómo huele el bosque, y concluir que el bosque no huele.

Svelte
<script lang="ts">
	import { Prose } from '@archeblack/ui';

	// El HTML que genera marked para un fragmento de «El Alma Pide Locura», de Hermes. En el post, el
	// h1 es el titular de la cabecera y el texto empieza en h2; en la documentación estos títulos
	// rompen a propósito el esquema de la página, porque el estilo de cada uno sale de su etiqueta.
	const html = `<h2>La mesa</h2>
<p>Una reunión de eruditos. Hombres sentados alrededor de una mesa con sus méritos sobre la madera, hablando, midiendo, sosteniendo cada afirmación con su prueba. No hay impostura en la escena. Cada uno hizo el trabajo: leyó, revisó, se corrigió, aprendió a no afirmar más de lo que podía demostrar.</p>
<p>Conviene decirlo antes que nada, porque de otro modo todo lo que sigue se malinterpreta. <em>La mesa no está equivocada.</em> Aprendimos a mirar así por razones buenas, como recuerda <a href="#han"><strong>Byung-Chul Han</strong></a> cuando habla de la sociedad del rendimiento.</p>
<h3>Lo que la prueba no alcanza</h3>
<p>Hay una sed ahí que el saber no calma. No porque sea poco, sino porque es de otro orden:</p>
<ul>
<li>los sueños, que nadie archiva;</li>
<li>las certezas que llegan antes que sus razones;</li>
<li>las coincidencias, de las que nadie lleva registro.</li>
</ul>
<h4>Un error de categoría</h4>
<p>Pedirle a un sueño su bibliografía no es rigor. Es pedirle a un mapa que te diga cómo huele el bosque, y concluir que el bosque no huele.</p>`;
</script>

<div style="width: 100%">
	<Prose {html} />
</div>

Citas

La regla de acento (D9a). Varias estrofas con <br>, énfasis que sigue en itálica y el autor en un <footer>.

Sé que pendí de ese árbol mecido por el viento
nueve noches enteras,
herido por la lanza, ofrecido a Odín,
yo mismo a mí mismo.

Pan no me dieron ni cuerno;
escruté las profundidades,
tomé las runas, las tomé gritando,
y caí del árbol.

El que cuelga no está castigado: está mirando el mundo al revés, y desde ahí ve lo que desde arriba no se ve.

«Soy la Bruja Ranni. Robé la Muerte hace mucho tiempo, y busco ahora el camino oscuro.»

Ranni, en Elden Ring
Svelte
<script lang="ts">
	import { Prose } from '@archeblack/ui';

	// Citas de Hermes: estrofas con <br>, énfasis adentro y el autor en un <footer>.
	const html = `<blockquote>
<p><em>Sé que pendí de ese árbol mecido por el viento</em><br><em>nueve noches enteras,</em><br><em>herido por la lanza, ofrecido a Odín,</em><br><em>yo mismo a mí mismo.</em></p>
<p><em>Pan no me dieron ni cuerno;</em><br><em>escruté las profundidades,</em><br><em>tomé las runas, las tomé gritando,</em><br><em>y caí del árbol.</em></p>
</blockquote>
<p>El que cuelga no está castigado: está mirando el mundo al revés, y desde ahí ve lo que desde arriba no se ve.</p>
<blockquote>
<p><em>«Soy la Bruja Ranni. Robé la Muerte hace mucho tiempo, y busco ahora el camino oscuro.»</em></p>
<footer>Ranni, en <cite>Elden Ring</cite></footer>
</blockquote>`;
</script>

<div style="width: 100%">
	<Prose {html} />
</div>

Separador, código y tabla

El <hr> es una línea. El código en línea va sobre la capa elevada y el bloque, en typography.code. La tabla usa la letra de la interfaz, al ras de la columna, y respeta el align de las columnas de GFM: las cifras, al final.

Cada ensayo se escribe en Markdown y se convierte con marked antes de publicarse.


La conversión es una sola línea:

const html = marked.parse(post.body, { gfm: true, breaks: false });
Tiempo de lectura de los ensayos de 2026
EnsayoTemaMinutos
El Alma Pide LocuraFilosofía14
Lo que cambia cuando alguien escuchaCultura11
El Doctor que Bailó con el TiempoCultura9
Svelte
<script lang="ts">
	import { Prose } from '@archeblack/ui';

	// Separador, código en línea, un bloque de código y una tabla con su pie. La columna de cifras
	// va alineada al final, como la escribe marked para `| ---: |`.
	const html = `<p>Cada ensayo se escribe en Markdown y se convierte con <code>marked</code> antes de publicarse.</p>
<hr>
<p>La conversión es una sola línea:</p>
<pre><code>const html = marked.parse(post.body, { gfm: true, breaks: false });</code></pre>
<table>
<caption>Tiempo de lectura de los ensayos de 2026</caption>
<thead><tr><th>Ensayo</th><th>Tema</th><th align="right">Minutos</th></tr></thead>
<tbody>
<tr><td>El Alma Pide Locura</td><td>Filosofía</td><td align="right">14</td></tr>
<tr><td>Lo que cambia cuando alguien escucha</td><td>Cultura</td><td align="right">11</td></tr>
<tr><td>El Doctor que Bailó con el Tiempo</td><td>Cultura</td><td align="right">9</td></tr>
</tbody>
</table>`;
</script>

<div style="width: 100%">
	<Prose {html} />
</div>

Resaltado y japonés

Con children. <mark> usa el fondo de selección (D8b). El japonés, con lang="ja", cae en la fuente del sistema y no se inclina, tampoco dentro de una cita.

Ma (間) es la palabra japonesa para el espacio entre las cosas: la pausa que permite que aparezca lo que no aparecería de otro modo.

間とは、物と物とのあいだにある空白のことです。沈黙がなければ、旋律は生まれません。

Sin silencios no hay melodía. 間がなければ音楽はない。

Svelte
<script lang="ts">
	import { Prose } from '@archeblack/ui';
</script>

<!-- Con children: el texto en japonés lleva lang="ja" y cae en la fuente del sistema. -->
<div style="width: 100%">
	<Prose>
		<p>
			<em>Ma</em> (<span lang="ja">間</span>) es la palabra japonesa para el espacio entre las
			cosas: la pausa que permite que aparezca lo <mark>que no aparecería</mark> de otro modo.
		</p>
		<p lang="ja">
			間とは、物と物とのあいだにある空白のことです。沈黙がなければ、旋律は生まれません。
		</p>
		<blockquote>
			<p><em>Sin silencios no hay melodía.</em> <span lang="ja">間がなければ音楽はない。</span></p>
		</blockquote>
	</Prose>
</div>

La cita en cada producto

El rol quote sigue al acento: blanco en Arche y el acento de Hermes con data-product="hermes".

«Hay caminos fuera de este jardín.»

Arche

«Hay caminos fuera de este jardín.»

Hermes
Svelte
<script lang="ts">
	import '@archeblack/ui/products/hermes.css';
	import { Prose } from '@archeblack/ui';
</script>

<!-- La regla de la cita usa el rol quote: blanca en Arche y el acento en cada producto. -->
<div
	style="display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: var(--arche-spacing-8); width: 100%"
>
	<Prose>
		<blockquote>
			<p><em>«Hay caminos fuera de este jardín.»</em></p>
			<footer>Arche</footer>
		</blockquote>
	</Prose>
	<Prose data-product="hermes">
		<blockquote>
			<p><em>«Hay caminos fuera de este jardín.»</em></p>
			<footer>Hermes</footer>
		</blockquote>
	</Prose>
</div>

Props

Props de Prose
PropDescripción
html? string HTML ya generado (con marked, por ejemplo), que se muestra con {@html}. Tiene que ser de confianza o estar saneado: Prose no lo limpia. Cada <table> se envuelve en un contenedor con scroll propio.
children? Snippet Contenido escrito en Svelte, en lugar de html. Una tabla ancha va dentro de <div class="arche-prose__scroll">. Un componente de Arche escrito adentro (CodeBlock, Table, Figure) conserva sus estilos: Prose solo le da el espacio del ritmo cuando es un hijo directo.
as? 'div' | 'article' | 'section' Por defecto 'div'Elemento raíz.
codeLabel? string Por defecto 'Código'Nombre de un bloque de código que no entra y se vuelve una región con scroll. Con más de un bloque, cada uno lleva su número («Código 2»).
tableLabel? string Por defecto 'Tabla'Nombre de una tabla sin <caption> que no entra. Con <caption>, la región toma su texto. Con más de una tabla, cada una lleva su número («Tabla 2»).
class? ClassValue Se suma a arche-prose.
...rest HTMLAttributes Van a la raíz (lang, id…).

Accesibilidad

  • La medida de 55ch (unos 75 caracteres en Piazzolla a 17 px) y el interlineado de 1,6 cumplen el espaciado de texto de WCAG 1.4.12: la prosa aguanta el espaciado que imponga el lector sin cortar texto.
  • Los links tienen subrayado: no dependen solo del color. En hover el subrayado pasa al color pleno y a 2 px, y el foco es el anillo de Arche.
  • Los títulos del texto (h2 a h4) siguen el esquema de la página: el h1 es el de la cabecera. Tienen scroll-margin-top para llegar por un ancla bajo una cabecera fija.
  • Un bloque de código o una tabla que no entra se vuelve una región con nombre que recibe el foco (tabindex="0"), para desplazarla con el teclado (WCAG 2.1.1). Si entra, no suma una parada de Tab. Con varios bloques, cada región lleva su número («Código 1», «Código 2») para distinguirlas en la lista de regiones del lector de pantalla; una tabla con <caption> toma su texto.
  • El texto en otro idioma lleva su lang (<span lang="ja">): el lector cambia la voz y el japonés cae en la fuente del sistema, sin itálica falsa.
  • En colores forzados la regla de la cita y el separador son bordes y se ven; el resaltado usa los colores del sistema para <mark>.

Qué evitar

  • Pasar a html texto que escribió un visitante sin sanearlo. Sanearlo antes (DOMPurify, sanitize-html) o usar children.
  • Una regla de cita gris, comillas grandes de adorno o una letra capital. La regla de 2 px en el rol quote (D9a), sin comillas de adorno.
  • «· · ·» como separador de secciones. Un <hr>: una línea de todo el ancho (D9b).
  • Subrayado punteado para los términos de glosario. El link de siempre (D9c).
  • Brillo en el texto de lectura o itálica sintética en japonés. El brillo solo en los títulos display; el japonés con lang="ja".
  • Ensanchar la prosa hasta el ancho de la página. La medida de lectura. Una imagen puede sangrar con Figure en un Container en grilla.