Tucano v0.37.2

Línea de tiempo

Historial en orden: el seguimiento de un pedido, lo que pasó con un contrato, las versiones de un changelog. Son solo clases sobre <ol> — el orden es parte del significado, y el lector de pantalla anuncia "elemento 2 de 5" sin que nadie escriba ARIA. El punto y el riel los dibuja la clase; la plantilla solo trae el contenido.

  1. Pedido confirmado

    Pago aprobado por Pix.
  2. Preparado en el almacén

  3. En tránsito

    Salió del centro de distribución de Campinas.
  4. En reparto

  5. Entregado

    Previsión: 12/09/2026.

Lo que ya pasó tiene punto relleno en el tono de éxito; la etapa actual, relleno en el acento; lo que aún viene queda hueco y neutro. Quien indica el estado es el punto — el texto queda libre para decir qué y cuándo.

Ejemplos

Todo lo de abajo es la misma lista, con tono, relleno, icono y etiqueta cambiados.

Historial de contrato, con iconos

tuc-timeline__icon como primer hijo del elemento pone el icono en lugar del punto.

  1. Contrato firmado

    Las dos partes firmaron en el portal.
  2. Enviado para firma

  3. Cláusula 4 revisada

    El recargo por retraso pasó del 2% al 1%.
  4. Borrador creado

Auditoría, con etiqueta

Una tuc-badge en el encabezado se alinea con el centro de la línea.

  1. Permiso retirado

    Acceso
    Ana Lima le quitó a Rafael Souza el acceso a finanzas.
  2. Inicio de sesión en un dispositivo nuevo

    Sesión
    Chrome en macOS, São Paulo.
  3. Informe exportado

    Datos

Los cinco tonos, huecos

Sin is-filled el punto es un anillo en el tono, sobre el fondo.

  1. is-accent

  2. is-success

  3. is-warning

  4. is-danger

  5. is-info

  6. sin tono

Los cinco tonos, rellenos

is-filled rellena el punto con el tono del elemento.

  1. is-accent is-filled

  2. is-success is-filled

  3. is-warning is-filled

  4. is-danger is-filled

  5. is-info is-filled

  6. is-filled, sin tono

Cómo usar

No hay JavaScript ni atributo data-*: escribe las clases y listo. Cada elemento tiene un encabezado con título y hora, y un cuerpo opcional.

<ol class="tuc-timeline">
  <li class="tuc-timeline__item is-success is-filled">
    <div class="tuc-timeline__head">
      <p class="tuc-timeline__title">Contrato firmado</p>
      <time class="tuc-timeline__time" datetime="2026-09-12">12/09/2026</time>
    </div>
    <div class="tuc-timeline__body">Las dos partes firmaron.</div>
  </li>
  <li class="tuc-timeline__item">
    <div class="tuc-timeline__head">
      <p class="tuc-timeline__title">Enviado para firma</p>
      <time class="tuc-timeline__time" datetime="2026-09-10">10/09/2026</time>
    </div>
  </li>
</ol>

Con icono

El icono va en un <span> como primer hijo del elemento. Cuando existe, el punto desaparece y el círculo recibe el fondo suave del tono; el SVG lo dimensiona la clase.

<li class="tuc-timeline__item is-success">
  <span class="tuc-timeline__icon"><svg viewBox="0 0 24 24" aria-hidden="true">...</svg></span>
  <div class="tuc-timeline__head">...</div>
</li>

En la plantilla de Django

El tono suele salir del tipo de evento. Un diccionario en el modelo, o un filtro, evita el if en cascada en la plantilla.

class Event(models.Model):
    TONES = {"signed": "is-success", "revised": "is-warning", "canceled": "is-danger"}
    kind = models.CharField(max_length=20)
    title = models.CharField(max_length=120)
    created_at = models.DateTimeField(auto_now_add=True)

    @property
    def tone(self):
        return self.TONES.get(self.kind, "")
<ol class="tuc-timeline">
  {% for event in contract.events.all %}
  <li class="tuc-timeline__item {{ event.tone }}{% if forloop.first %} is-filled{% endif %}">
    <div class="tuc-timeline__head">
      <p class="tuc-timeline__title">{{ event.title }}</p>
      <time class="tuc-timeline__time" datetime="{{ event.created_at|date:'c' }}">{{ event.created_at|date:"d/m/Y H:i" }}</time>
    </div>
  </li>
  {% endfor %}
</ol>

Ajustar la geometría

Tres variables en la propia lista controlan el cálculo del punto y del riel. La primera línea del encabezado tiene altura fija por el mismo motivo que el .tuc-choice: el centro del punto no puede depender de la fuente del proyecto.

.timeline-large {
  --tuc-timeline-gutter: 2rem;   /* columna del punto; el icono la ocupa entera */
  --tuc-timeline-dot: 1rem;      /* diámetro del punto */
  --tuc-timeline-line: 2rem;     /* altura de la primera línea del encabezado */
}

Accesibilidad

La estructura hace el trabajo. <ol> da la posición de cada elemento, <time datetime> da la fecha en un formato que la máquina lee, y el punto y el riel son pseudoelementos, invisibles para el lector de pantalla.

El color no puede ser la única información

El tono del punto no llega a quien no ve y confunde a quien no distingue los colores. Di el estado en el texto — "Cancelado", "En tránsito" — o en una tuc-badge en el encabezado, y marca el SVG del icono con aria-hidden="true".

Clases

Solo clases, sin componente en JavaScript.

ClaseDóndeQué hace
tuc-timeline<ol>La lista; quita el marcador y la sangría
tuc-timeline__item<li>Un evento; dibuja punto y riel. El último elemento no tiene riel
is-accent is-success is-warning is-danger is-infoelementoTono del punto y del icono; sin tono, --tuc-subtle
is-filledelementoPunto relleno en el tono; sin ella, hueco
tuc-timeline__iconprimer hijo del elementoIcono en lugar del punto, con fondo suave del tono
tuc-timeline__headelementoLínea del título, la hora y una etiqueta; salta de línea cuando no cabe
tuc-timeline__titleen el encabezadoTítulo en peso 600, sin margen — puede ser <p> o un <h2>/<h3>
tuc-timeline__timeen el encabezadoFecha u hora, más pequeña, en tono apagado y con dígitos de ancho fijo
tuc-timeline__bodyelementoTexto de apoyo en tono apagado
VariablePor defectoControla
--tuc-timeline-gutter1.5remAncho de la columna del punto y tamaño del icono
--tuc-timeline-dot0.75remDiámetro del punto
--tuc-timeline-line1.5remAltura de la primera línea del encabezado, donde se centra el punto