Componentes · Ola 4 · Editorial
Byline
La firma de un texto: avatar, el nombre del autor (con «por» si el producto lo pide), la fecha, el tiempo de lectura y un espacio final para compartir. En Archivo de 13 px y en texto sutil, con el nombre en blanco semibold; las piezas se separan con « · » en texto sutil y la línea se parte si no entra; el final, si no entra, baja a su propia fila, al inicio.
import { Byline } from '@archeblack/ui';
Ejemplos
Firma de un post
Avatar, el autor como link, la fecha, la lectura y compartir al final. En Hermes, los links de compartir toman su acento. En el teléfono, compartir baja a su propia fila, al inicio.
<script lang="ts">
import '@archeblack/ui/products/hermes.css';
import { Byline } from '@archeblack/ui';
const url = 'https://ejemplo.com/posts/el-alma-pide-locura';
const text = encodeURIComponent(`El Alma Pide Locura ${url}`);
let copied = $state(false);
async function copy() {
try {
await navigator.clipboard.writeText(url);
copied = true;
setTimeout(() => (copied = false), 2000);
} catch {
// Sin permiso para el portapapeles: no cambia nada.
}
}
</script>
<!-- La firma de un post, en Hermes: avatar, el autor como link, la fecha, la lectura y compartir
al final. Los links y botones propios del final toman el aspecto de link de Arche; «Copiado» se
anuncia en una región viva. Si compartir no entra en la línea, baja a su propia fila, al
inicio. -->
<Byline
data-product="hermes"
name="Jimmy Mora Vinces"
href="#autor"
avatar
avatarInitials="JM"
date="2026-07-27T21:45:16Z"
readingTime={14}
style="width: 100%"
>
{#snippet end()}
<span>Compartir:</span>
<a href={`https://mastodon.social/share?text=${text}`} rel="noopener noreferrer">Mastodon</a>
<span class="arche-byline__separator" aria-hidden="true">·</span>
<a href={`https://bsky.app/intent/compose?text=${text}`} rel="noopener noreferrer">Bluesky</a>
<span class="arche-byline__separator" aria-hidden="true">·</span>
<button type="button" onclick={copy}>{copied ? 'Copiado' : 'Copiar link'}</button>
<span
role="status"
style="position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap"
>{copied ? 'Link copiado' : ''}</span
>
{/snippet}
</Byline> En una tarjeta o un listado
Sin avatar: el nombre y la lectura, y la fecha si el listado no la muestra en otro lugar.
<script lang="ts">
import { Byline } from '@archeblack/ui';
</script>
<!-- En una tarjeta: sin avatar, el nombre y la lectura. En un listado, con la fecha. -->
<div style="display: grid; gap: var(--arche-spacing-5); width: 100%">
<Byline name="Jimmy Mora Vinces" readingTime={12} />
<Byline name="Jimmy Mora Vinces" date="2026-05-03T01:33:44Z" readingTime={12} />
</div> Con «por»
prefix="por" pone la palabra antes del nombre (por defecto no va), y el tiempo de lectura como texto propio.
<script lang="ts">
import { Byline } from '@archeblack/ui';
</script>
<!-- Con «por» (prefix="por"; por defecto no va) y el tiempo de lectura como texto propio. -->
<Byline
name="Jimmy Mora Vinces"
prefix="por"
avatar
avatarInitials="JM"
date="2026-01-28"
readingTime="9 min de lectura"
/> Props
| Prop | Descripción |
|---|---|
name string | El nombre del autor. |
href? string | La página del autor. Con href, el nombre es un link en text-strong con el subrayado de Arche. |
prefix? string Por defecto '' | La palabra antes del nombre. Por defecto no hay ninguna: el nombre solo. Un producto que la quiere la pide con prefix="por". |
avatar? boolean Por defecto false | Muestra el avatar del autor (Avatar md, 32 px). Es decorativo: el nombre está al lado. |
avatarSrc? string | La foto del autor. Con ella, el avatar se muestra aunque falte avatar. |
avatarInitials? string | Iniciales del avatar en lugar de las de name (primera y última palabra). Con dos apellidos, el nombre y el primer apellido: «Jimmy Mora Vinces» → JM. |
date? Date | string | La fecha, en un <time>: un texto ISO va tal cual en datetime y una Date, con toISOString(). Se ve como «27 jul 2026». |
locale? string Por defecto 'es' | Idioma de la fecha. |
timeZone? string Por defecto 'UTC' | Zona horaria de la fecha: con UTC, el servidor y el navegador coinciden. |
readingTime? number | string | El tiempo de lectura: un número son minutos («14 min»); un texto va tal cual («9 min de lectura»). |
readingLabel? (minutes: number) => string Por defecto «N minutos de lectura» | Cómo lo lee un lector de pantalla cuando readingTime es un número: se ve «14 min» y se lee «14 minutos de lectura». |
end? Snippet | Al final de la línea, empujado al borde: compartir, o la llamada de una portada. Si no entra, baja a su propia fila, alineado al inicio. Sus links y botones propios toman el aspecto de link de Arche en 13 px. |
class? ClassValue | Se suma a arche-byline. |
...rest HTMLAttributes | Van al <div> de la firma. |
Accesibilidad
- Se lee en el orden en que se ve: «Jimmy Mora Vinces 27 jul 2026 14 minutos de lectura». Los separadores « · » son decorativos (
aria-hidden). - La fecha es un
<time datetime>: el dato exacto queda en el código aunque se vea abreviado. - El avatar es decorativo (
alt=""): el nombre ya está escrito al lado y no se anuncia dos veces. - El nombre como link lleva subrayado: blanco contra el texto sutil no llega a 3:1 y el color solo no alcanza para distinguir un link (WCAG 1.4.1). El área táctil de los links mide unos 28 px de alto sin mover la línea (WCAG 2.5.8).
- Compartir: un aviso como «Link copiado» va en una región
role="status", que el lector anuncia sin mover el foco.
Qué evitar
- Una línea o un fondo que separe la firma de la bajada. La firma debajo, en 13 px y
text-subtle, sin línea. - El nombre del autor en el color de link o en mayúsculas mono. El nombre en
text-strongsemibold; el color de link queda para compartir. - Dos links al mismo destino en una tarjeta que ya es un link (la llamada «Leer el ensayo →»). La llamada como texto, dentro del link de la tarjeta.