Timeline

Pronto

Sequência cronológica vertical de eventos. Ideal para andamentos processuais, histórico de mudanças, auditoria.

Usar quando

Andamentos do processo, histórico de comunicação, log de auditoria, etapas concluídas vs pendentes.

Não usar quando

Lista plana sem ordem temporal (use list). Sequência horizontal (use Stepper).

Variantes

Padrão (andamentos do processo)
  1. Sentença publicada

    Procedente. Indenização R$ 45.000 + custas.

  2. Audiência de instrução realizada

    Depoimento de 2 testemunhas. Razões finais orais.

  3. Citação realizada

    AR recebido pelo réu (CPF ***.***.***-**)

  4. Petição inicial protocolada

    Distribuída para 3ª Vara Cível Central.

Compacto (histórico inline)
  1. Sentença publicada

  2. Audiência de instrução realizada

  3. Citação realizada

Stepper vertical (etapas concluídas/pendentes)
  1. Petição inicial

    Protocolada e distribuída.

  2. Citação

    AR positivo.

  3. Instrução

    Audiência marcada para 03/06.

  4. Sentença

  5. Recurso

Microinterações

MicrointeraçãoDisparada porComportamentoTiming
Mount staggerlista montaCada item aparece 60ms após o anterior, fade-incumulativo (60ms × N)
Active pulseitem currentBullet expande sutilmente (1→1.1→1)2s ease infinite
Hover itemmouseenterBackground do conteúdo → surfaceHover150ms ease
Expand detailsclick no itemConteúdo expande accordion-style250ms cubic-bezier(0.32,0.72,0,1)

Acessibilidade

Acessibilidade — checklist

ARIA esperado
  • <ol> em vez de <ul> (ordem importa)
  • <li> com <time dateTime="ISO" /> em cada item
  • role="list" implícito
  • Item current: aria-current="step" ou aria-current="true"
Notas
  • Use <ol> (ordered list) — ordem temporal importa.
  • <time dateTime="2026-05-15T14:30"> em cada timestamp para SEO/acessibilidade.
  • Status (concluído, em andamento, pendente) com cor + ícone (não só cor).
  • Em mobile, mantenha indentação reduzida para conteúdo respirar.

Código

'use client';
import { CheckCircle2, Circle } from 'lucide-react';
import { T, TYPE, SP } from '@/lib/tokens';

interface TimelineItem {
  date: string;
  title: string;
  description?: string;
  icon?: React.ComponentType;
  status?: 'done' | 'current' | 'pending';
}

export function Timeline({ items }: { items: TimelineItem[] }) {
  return (
    <ol style={{ listStyle: 'none', padding: 0, margin: 0 }}>
      {items.map((item, i) => {
        const Icon = item.icon ?? Circle;
        const isLast = i === items.length - 1;
        return (
          <li key={i} style={{ position: 'relative', paddingLeft: SP[8], paddingBottom: isLast ? 0 : SP[5] }}>
            {!isLast && (
              <span style={{ position: 'absolute', left: 11, top: 24, bottom: 0,
                width: 1, background: T.borderFaint }} />
            )}
            <div style={{ position: 'absolute', left: 0, top: 2, width: 24, height: 24,
              borderRadius: 980, background: T.surface, border: `1.5px solid ${T.border}`,
              display: 'grid', placeItems: 'center', color: T.inkMuted }}>
              <Icon size={12} />
            </div>
            <time dateTime={item.date} style={{ fontSize: TYPE.xs, color: T.inkSubtle, fontFamily: 'var(--lb-font-mono)' }}>
              {item.date}
            </time>
            <p style={{ fontSize: TYPE.base, color: T.ink, fontWeight: 500, margin: '2px 0 0 0' }}>
              {item.title}
            </p>
            {item.description && (
              <p style={{ fontSize: TYPE.sm, color: T.inkMuted, margin: '4px 0 0 0' }}>
                {item.description}
              </p>
            )}
          </li>
        );
      })}
    </ol>
  );
}

Regras

Faça

  • Use <ol> (ordem temporal importa).
  • <time dateTime="ISO"> em cada timestamp.
  • Linha vertical conecta itens (não desenha no último).
  • Bullet 24×24 com ícone de status semântico.
  • Status com cor + ícone (não só cor).
  • Mais recente em cima OU embaixo — escolha um e mantenha.

Não faça

  • Não use <ul> (sequência precisa de <ol>).
  • Não esconda timestamps (data é o ponto).
  • Não mostre mais que ~10 itens visíveis sem paginação/expand.
  • Não use horizontal para muitos itens (use Stepper limitado a 5-7).
  • Não force ícones decorativos (use só se semântico).

Tokens usados

TokenValorPapel
T.surface#FFFFFFbackground do bullet
T.border#E3DFD2borda do bullet
T.borderFaint#F0EEE5linha vertical conectora
T.ink#0A0A0Abullet quando current/done
T.brass#A47C2Bring sutil em current
T.verde#2F6B3Ccheck de done
FONT.monoJetBrains Monotimestamps