Componentes
Patrones canónicos con ejemplos y código copiable.
Patrón canónico de encabezado de página para periodismo2, comentario, editorial sebastián y lepp.
Primero el componente, después la variación de marca y finalmente su uso dentro de una página.
Patrones canónicos con ejemplos y código copiable.
Series, mapas y documentos publicados por COCHID.
Patrones canónicos con ejemplos y código copiable.
<header class="ui-sample ui-content" data-page-header="true"><h2>Componentes</h2><p>Patrones canónicos con ejemplos y código copiable.</p><nav aria-label="Acciones de página"><a class="btn btn--primary" href="#accion">Abrir inventario</a></nav></header>Cada cambio visible declara su autoridad; lo que permanece canónico no se vuelve a inventar en el producto.
Patrones canónicos con ejemplos y código copiable.
Series, mapas y documentos publicados por COCHID.
Compara la propuesta con cortes reales del repositorio. La ausencia de una muestra se declara y nunca se reconstruye de memoria.
Preparando comparación histórica…
La comparación convierte una regla abstracta en una diferencia visible y verificable.
Patrones canónicos con ejemplos y código copiable.
La prosa completa usa una voz técnica.La misma anatomía debe conservar lectura, foco y acciones sin cortar contenido ni crear scroll horizontal en la página.
Patrones canónicos con ejemplos y código copiable.
Series, mapas y documentos publicados por COCHID.
| Dimensión | Contrato |
|---|---|
| Propietario canónico | Sistema de diseño CIS y equipo editorial · core/core-style |
| Consumidores | Periodismo2, Comentario, Editorial Sebastián y LEPP |
| Dependencias | prosa canónica, metadatos editoriales |
| Estado | candidato |
Patrón observado. 43 implementaciones observadas en 13 repositorios.
La observación demuestra uso existente; la aceptación canónica sigue dependiendo de esta ficha y de su propietario.
| Dato | Resultado |
|---|---|
| Clasificación | Patrón observado |
| Implementaciones | 43 implementaciones observadas |
| Repositorios | cds/cds-www-next, cds/cds-www-staging, cds/cis/cis-ui, cds/cis/cis-usaia, cds/cis/firmasydocumentos, cds/cis/situacion-www, cis/cis-docs, cis/cis-matriz, cis/cis-procesos, cis/cis-proyectos, cis/cis-qualitas, cis/cis-www, cis/projects/lepp/lepp-frontend |
| Snapshot | kit/componentes/componentes-observados.json |
El inventario conserva repositorio, archivo fuente y criterio de asociación. Observar una implementación no la convierte automáticamente en canónica.
| Estado requerido |
|---|
| base |
| destacado |
| archivo |
| contenido largo |
Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
<header class="ui-sample ui-content" data-page-header="true"><h2>Componentes</h2><p>Patrones canónicos con ejemplos y código copiable.</p><nav aria-label="Acciones de página"><a class="btn btn--primary" href="#accion">Abrir inventario</a></nav></header>Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
<header class="ui-sample ui-content border border-slate-300 bg-white p-4 text-slate-950 flex flex-wrap items-center justify-between gap-3" data-page-header="true"><h2>Componentes</h2><p>Patrones canónicos con ejemplos y código copiable.</p><nav class="flex flex-wrap items-center gap-3" aria-label="Acciones de página"><a class="btn btn--primary underline underline-offset-4" href="#accion">Abrir inventario</a></nav></header>Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
import type { MouseEventHandler } from "react";
/** Peso visual de una acción: `primary` para la principal (una por página), `secondary` para alternativas y `quiet` para terciarias con aspecto de enlace. */
export type PageHeaderActionVariant = "primary" | "secondary" | "quiet";
export interface PageHeaderAction {
/** Texto del enlace; vacío omite la acción. */
label: string;
href: string;
/** Se llama al activar el enlace, antes de navegar. */
onClick?: MouseEventHandler<HTMLAnchorElement>;
/** Peso visual; por defecto la primera acción visible es `primary` y las demás `secondary`. */
variant?: PageHeaderActionVariant;
}
const ACTIONS: PageHeaderAction[] = [{ label: "Abrir inventario", href: "#accion" }];
export interface PageHeaderProps {
/** Título de la página. */
title?: string;
/** Una oración que dice qué contiene la página; vacía no se muestra. */
description?: string;
/** Enlaces de acción de la página; una lista vacía no emite la navegación y una acción sin texto se omite. */
actions?: PageHeaderAction[];
/** Nombre accesible de la navegación de acciones (`aria-label`). */
actionsLabel?: string;
className?: string;
}
/**
* Encabezado de página con título, descripción breve y enlaces de acción; va al inicio de una página de índice, catálogo o sección.
*
* Las acciones son enlaces con forma de botón: la primera es la principal y las demás, alternativas, salvo que `variant` diga otra cosa. Las partes vacías no se emiten: sin descripción no hay párrafo y sin acciones no hay navegación.
*
* @example <PageHeader title="Catálogo de datos" description="Series, mapas y documentos publicados por COCHID." actions={[{ label: "Descargar catálogo", href: "/catalogo.csv" }, { label: "Ver metodología", href: "/metodologia" }]} />
* @example <PageHeader title="Componentes" actions={[]} />
*/
export function PageHeader({
title = "Componentes",
description = "Patrones canónicos con ejemplos y código copiable.",
actions = ACTIONS,
actionsLabel = "Acciones de página",
className,
}: PageHeaderProps) {
const visibles = actions.filter((action) => action.label);
if (!title && !description && !visibles.length) return null;
return (
<header className={["ui-content", className].filter(Boolean).join(" ")} data-page-header>
{title ? <h2>{title}</h2> : null}
{description ? <p>{description}</p> : null}
{visibles.length ? (
<nav aria-label={actionsLabel}>
{visibles.flatMap((action, i) => {
const variante = action.variant ?? (i === 0 ? "primary" : "secondary");
const enlace = <a className={`btn btn--${variante}`} href={action.href} onClick={action.onClick} key={`${action.href}-${i}`}>{action.label}</a>;
return i ? [" ", enlace] : [enlace];
})}
</nav>
) : null}
</header>
);
}