Saltar al contenido principal

tdn-timeline

Paquete: @tiendana/ngx-core/ui

Cronología vertical de lo que le pasó a un registro, en orden, y qué tan avanzado va: el ciclo de vida de un pedido, los intentos de un pago, la auditoría de una importación. tdn-timeline es el contenedor; cada tdn-timeline-step dibuja su marcador y el tramo de riel hasta el siguiente paso.

Disponible desde @tiendana/ngx-core 0.8.12. Úselo cuando la pantalla reporta eventos. Para un flujo que el usuario recorre use tdn-stepper; para un único estado sin historia use tdn-status.

Características​

✅ Seis estados con marcador propio: done, current, pending, warning, failed, neutral
✅ Hasta cuatro líneas por paso: título, detalle, vía y nota
✅ Modo dense para columnas angostas
✅ Modo grid para alinear acciones junto a cada título
✅ Nombre accesible que dice el estado con palabras, traducible

Selectores​

tdn-timeline y tdn-timeline-step. Ambos se importan de @tiendana/ngx-core/ui como TdnTimelineComponent y TdnTimelineStepComponent.

API de tdn-timeline​

Inputs​

InputTipoDefaultDescripción
densebooleanfalseGutter y espaciado más ajustados (--timeline-indent 19px, --timeline-step-pad 5px). Acepta el atributo sin valor
translationsPartial<TdnTimelineTranslations>undefinedReemplaza las palabras de estado del nombre accesible; solo cambian las claves dadas

Sin outputs. La señal pública text (computed) combina TDN_TIMELINE_TRANSLATIONS con translations y la leen los pasos.

API de tdn-timeline-step​

Inputs​

InputTipoDefaultDescripción
titlestring''Qué pasó, ya traducido. Primera línea y primera parte del nombre accesible. Déjelo vacío si usa el slot tdn-timeline-title
detailstring''Cuándo: una fecha formateada o una palabra como «Pendiente». En cifras tabulares
viastring''Qué lo originó: «por webhook», «desde Admin», un nombre de usuario. En cursiva
notestring''Línea extra en color de error bajo el paso, para el motivo de un fallo
stateTdnTimelineState'pending'Qué tan avanzado está el evento; elige el marcador y la palabra de estado
gridbooleanfalseDistribuye el paso en las columnas de --timeline-grid-cols. Acepta el atributo sin valor

Estados​

EstadoMarcadorPalabra habladaUso
doneRelleno natura«completado»Ocurrió y salió bien
currentRelleno azul info, pulsa«en curso»En curso ahora mismo; a lo sumo un paso y nunca un estado terminal
pendingHueco con anillo punteado gris«pendiente»Aún no ocurre
warningÁmbar«con novedad»Ocurrió con algo digno de revisar (reembolso parcial, reintento)
failedRojo«falló»Salió mal; acompáñelo de note con el motivo
neutralRelleno gris«registrado»Ocurrió y no hay resultado que reportar (nota, cancelación, edición manual)
Tipos TdnTimelineState y TdnTimelineTranslations
export type TdnTimelineState = 'done' | 'current' | 'pending' | 'warning' | 'failed' | 'neutral';

export type TdnTimelineTranslations = Record<TdnTimelineState, string>;

// Valores por defecto (TDN_TIMELINE_TRANSLATIONS), una constante y no un token de inyección
{
done: 'completado',
current: 'en curso',
pending: 'pendiente',
warning: 'con novedad',
failed: 'falló',
neutral: 'registrado',
}

Contenido proyectado​

Solo en tdn-timeline-step:

  • Contenido por defecto: se dibuja bajo el texto del paso (un enlace, un botón pequeño, una cita del payload).
  • [tdn-timeline-title]: un elemento con ese atributo se proyecta en lugar del título, para un título que es un badge o un control. Deje title vacío o se dibujan ambos.
<tdn-timeline-step detail="12 sep, 10:41" state="current">
<tdn-status tdn-timeline-title tone="pending" label="En revisión" />
</tdn-timeline-step>

Distribución en grid​

Con grid, el paso es una cuadrícula CSS sobre --timeline-grid-cols (por defecto 1fr). El texto propio del paso (slot o title, luego detail y via) es un solo bloque en la columna 1, fila 1; el contenido proyectado se coloca automáticamente en las columnas restantes de la fila 1. note ocupa la fila 2 en todas las columnas. Un elemento proyectado puede ubicarse por sí mismo con grid-column y grid-row. Cuando el paso mide 400px o menos (container query) vuelve a apilarse en el orden del código.

Propiedades CSS​

Se declaran en el host tdn-timeline y los pasos las heredan. Defínalas sobre el propio elemento tdn-timeline: un valor puesto en un ancestro queda tapado por la declaración del host. Ganan un style en línea o una regla más específica que :host, como tdn-timeline.mi-clase en la hoja del componente consumidor; una única clase global empata con :host y pierde.

PropiedadDefaultDescripción
--timeline-indent22px (19px con dense)Ancho del gutter de marcadores
--timeline-marker11pxDiámetro del marcador; el riel permanece centrado en él
--timeline-step-pad7px (5px con dense)Padding vertical de cada paso
--timeline-grid-cols1frgrid-template-columns de los pasos con grid. No la declara el host: puede ir en la línea de tiempo, en un paso o en cualquier ancestro

Clases: .tdn-timeline--dense en el host del contenedor; en cada paso .tdn-timeline__step, .tdn-timeline__step--{state} y .tdn-timeline__step--grid. Elementos internos: .tdn-timeline__marker, __head, __title, __detail, __via, __note, __body.

No requiere configuración para .scheme-dark: los anillos de los marcadores se mezclan hacia el color del texto (3:1, WCAG 1.4.11) y el riel es el color del texto al 22%.

Accesibilidad​

  • El host es role="list" y cada paso role="listitem".
  • Como los marcadores se distinguen solo por color y relleno (WCAG 1.4.1), el nombre accesible de cada paso dice el estado con palabras: «título. estado. detalle. vía. nota», por ejemplo «Pago. en curso. Esperando a la pasarela. por webhook».
  • Los marcadores son aria-hidden. El pulso de current se detiene con prefers-reduced-motion: reduce; con forced-colors marcadores y riel usan CanvasText.
  • Un title="…" estático no se vuelve tooltip: el paso retira ese atributo.
Trampas que fallan sin error
  • Los pasos deben ser hermanos directos dentro de tdn-timeline: qué paso dibuja el riel y cuál quita su padding se decide con :first-of-type y :last-of-type. Envolver cada paso en su propio elemento hace que todos sean primero y último, y el riel desaparece. @for y <ng-container> no agregan elemento y son seguros.
  • Un tdn-timeline-step fuera de un tdn-timeline no tiene gutter y su marcador queda fuera de su caja.
  • pending promete algo por venir. Para un evento ocurrido sin resultado que reportar use neutral.
  • Solo current pulsa. No lo use en un estado terminal.
  • El nombre accesible se arma solo con los inputs: lo proyectado en el slot tdn-timeline-title o en el cuerpo no forma parte de él.

Ejemplos y Demos​

Básico​

Cargando demo...
Ver código

Denso​

Cargando demo...
Ver código

Con acciones alineadas en columna​

Cargando demo...
Ver código

Intentos de pago con palabras de estado en inglés​

<tdn-timeline [translations]="{ done: 'completed', failed: 'failed', current: 'in progress' }">
@for (attempt of attempts(); track attempt.id) {
<tdn-timeline-step [title]="attempt.gateway" [detail]="attempt.createdAt | date: 'short'"
[state]="attempt.approved ? 'done' : 'failed'" [note]="attempt.error ?? ''" />
}
</tdn-timeline>