Skip to content
Extensões

Guia Completo: Stepper (Wizard / Progress Steps)

Índice

  1. Introdução
  2. Estrutura Básica
  3. Estados dos Steps
  4. Stepper Horizontal
  5. Tamanhos
  6. Com Barra de Progresso
  7. Stepper Clicável
  8. JavaScript API
  9. Eventos
  10. Acessibilidade
  11. Boas Práticas

Introdução

O componente Stepper fornece navegação por etapas/passos, ideal para wizards, processos multi-etapa e fluxos sequenciais.

Características Principais

  • ✅ Vertical e horizontal
  • ✅ 4 estados (pendente, ativo, completo, erro)
  • ✅ Com ícones personalizados
  • ✅ Barra de progresso opcional
  • ✅ Clicável ou linear
  • ✅ 3 tamanhos
  • ✅ Navegação programática
  • ✅ Validação de steps
  • ✅ Dark mode completo
  • ✅ Totalmente responsivo
  • ✅ WCAG 2.1 AA compliant

Estrutura Básica

Stepper Vertical (Padrão)

html
<div class="stepper" data-stepper>
  <ol class="stepper-list">
    <!-- Step 1 - Completo -->
    <li class="stepper-item completed" data-icon="check">
      <div class="stepper-icon">
        <i class="material-icons">check</i>
      </div>
      <div class="stepper-content">
        <h3 class="stepper-title">Etapa 01</h3>
      </div>
    </li>

    <!-- Step 2 - Ativo -->
    <li class="stepper-item active" data-icon="place">
      <div class="stepper-icon">
        <i class="material-icons">place</i>
      </div>
      <div class="stepper-content">
        <h3 class="stepper-title">Etapa 02</h3>
        <p class="stepper-description">Descrição da etapa.</p>
      </div>
    </li>

    <!-- Step 3 - Pendente -->
    <li class="stepper-item" data-icon="refresh">
      <div class="stepper-icon">
        <i class="material-icons">refresh</i>
      </div>
      <div class="stepper-content">
        <h3 class="stepper-title">Etapa 03</h3>
      </div>
    </li>
  </ol>
</div>

Classes Principais

ClasseDescrição
.stepperContainer principal
.stepper-listLista de steps (ol ou ul)
.stepper-itemItem individual (step)
.stepper-iconContainer do ícone
.stepper-contentContainer do conteúdo (título + descrição)
.stepper-titleTítulo do step
.stepper-descriptionDescrição opcional do step

Estados dos Steps

Step Pendente (Padrão)

html
<li class="stepper-item">
  <div class="stepper-icon">
    <i class="material-icons">description</i>
  </div>
  <div class="stepper-content">
    <h3 class="stepper-title">Etapa Pendente</h3>
  </div>
</li>

Step Ativo

html
<li class="stepper-item active">
  <div class="stepper-icon">
    <i class="material-icons">edit</i>
  </div>
  <div class="stepper-content">
    <h3 class="stepper-title">Etapa Atual</h3>
    <p class="stepper-description">Você está aqui.</p>
  </div>
</li>

Step Completo

html
<li class="stepper-item completed">
  <div class="stepper-icon">
    <i class="material-icons">check</i>
  </div>
  <div class="stepper-content">
    <h3 class="stepper-title">Etapa Concluída</h3>
  </div>
</li>

Step com Erro

html
<li class="stepper-item error">
  <div class="stepper-icon">
    <i class="material-icons">error</i>
  </div>
  <div class="stepper-content">
    <h3 class="stepper-title">Etapa com Erro</h3>
    <p class="stepper-description">Corrija os erros para continuar.</p>
  </div>
</li>

Tabela de Estados

EstadoClasseÍcone ComumCorUso
Pendente(nenhuma)info, more_horizCinzaSteps futuros
Ativo.activeedit, play_arrowAzulStep atual
Completo.completedcheck, doneVerdeSteps concluídos
Erro.errorerror, warningVermelhoSteps com problema

Stepper Horizontal

html
<div class="stepper stepper-horizontal">
  <ol class="stepper-list">
    <li class="stepper-item completed">
      <div class="stepper-icon">
        <i class="material-icons">check</i>
      </div>
      <div class="stepper-content">
        <h3 class="stepper-title">Dados Básicos</h3>
      </div>
    </li>

    <li class="stepper-item active">
      <div class="stepper-icon">
        <i class="material-icons">person</i>
      </div>
      <div class="stepper-content">
        <h3 class="stepper-title">Informações</h3>
      </div>
    </li>

    <li class="stepper-item">
      <div class="stepper-icon">
        <i class="material-icons">description</i>
      </div>
      <div class="stepper-content">
        <h3 class="stepper-title">Documentos</h3>
      </div>
    </li>

    <li class="stepper-item">
      <div class="stepper-icon">
        <i class="material-icons">done_all</i>
      </div>
      <div class="stepper-content">
        <h3 class="stepper-title">Revisão</h3>
      </div>
    </li>
  </ol>
</div>

Tamanhos

Pequeno (Small)

html
<div class="stepper stepper-sm">
  <!-- Steps menores (32px) -->
</div>

Médio (Padrão)

html
<div class="stepper">
  <!-- Tamanho padrão (40px) -->
</div>

Grande (Large)

html
<div class="stepper stepper-lg">
  <!-- Steps maiores (48px) -->
</div>

Tabela de Tamanhos

ClasseÍconeTítuloDescriçãoUso
.stepper-sm32px14px12pxMobile, sidebar
(padrão)40px16px14pxUso geral
.stepper-lg48px18px16pxDestaque, hero

Com Barra de Progresso

html
<div class="stepper" data-stepper data-show-progress>
  <!-- Barra de progresso será adicionada automaticamente -->
  <ol class="stepper-list">
    <!-- Steps aqui -->
  </ol>
</div>

Ou adicione manualmente:

html
<div class="stepper">
  <div class="stepper-progress-text">
    <span class="stepper-progress-current">2</span> de
    <span class="stepper-progress-total">5</span>
  </div>
  <div class="stepper-progress">
    <div class="stepper-progress-bar" style="width: 40%"></div>
  </div>

  <ol class="stepper-list">
    <!-- Steps aqui -->
  </ol>
</div>

Stepper Clicável

Permite navegar entre steps clicando neles:

html
<div class="stepper stepper-clickable" data-stepper data-clickable>
  <ol class="stepper-list">
    <!-- Steps clicáveis -->
  </ol>
</div>

Ou via JavaScript:

javascript
const stepper = window.createStepper('#meuStepper', {
  clickable: true
});

JavaScript API

Inicialização Automática

html
<!-- Inicialização automática via data attributes -->
<div class="stepper"
     data-stepper
     data-current-step="2"
     data-clickable
     data-show-progress>
  <!-- ... -->
</div>

Inicialização Manual

javascript
const stepper = window.createStepper('#meuStepper', {
  currentStep: 1,        // Step inicial (1-based)
  clickable: false,      // Permite clicar em steps
  linear: true,          // Modo linear (não pode pular steps)
  showProgress: false,   // Mostra barra de progresso
  onStepChange: (current, previous) => {
    console.log(`Mudou de ${previous} para ${current}`);
  },
  onComplete: () => {
    console.log('Wizard completo!');
  },
  onStepValidate: (currentStep, targetStep) => {
    // Retorna true para permitir, false para bloquear
    return validateStep(currentStep);
  }
});

Métodos de Navegação

javascript
const stepper = window.getStepper('#meuStepper');

// Navegação básica
stepper.next();           // Próximo step
stepper.previous();       // Step anterior
stepper.first();          // Primeiro step
stepper.last();           // Último step

// Navegar para step específico (0-based)
stepper.goToStep(2);      // Vai para 3º step

// Marcar step como completo
stepper.completeStep();   // Marca step atual
stepper.completeStep(1);  // Marca 2º step

// Marcar step com erro
stepper.setStepError(1, true);   // Adiciona erro
stepper.setStepError(1, false);  // Remove erro

// Reset
stepper.reset();          // Volta ao início

Métodos de Consulta

javascript
// Obter informações
stepper.getCurrentStep();      // Índice do step atual (0-based)
stepper.getTotalSteps();       // Total de steps
stepper.getProgress();         // Porcentagem (0-100)

// Verificações
stepper.isFirstStep();         // true se no primeiro
stepper.isLastStep();          // true se no último
stepper.isStepCompleted(2);    // Verifica se step está completo

Eventos

javascript
const stepperElement = document.querySelector('#meuStepper');

// Inicialização
stepperElement.addEventListener('stepper:init', (e) => {
  console.log('Stepper inicializado', e.detail.stepper);
});

// Mudança de step
stepperElement.addEventListener('stepper:change', (e) => {
  console.log('Step mudou:', e.detail.currentStep);
  console.log('Step anterior:', e.detail.previousStep);
});

// Step completado
stepperElement.addEventListener('stepper:step-complete', (e) => {
  console.log('Step completado:', e.detail.stepIndex);
});

// Wizard completo
stepperElement.addEventListener('stepper:complete', (e) => {
  console.log('Todos os steps concluídos!');
});

// Reset
stepperElement.addEventListener('stepper:reset', (e) => {
  console.log('Stepper resetado');
});

Acessibilidade

ARIA Attributes

html
<div class="stepper" role="tablist" aria-label="Wizard de cadastro">
  <ol class="stepper-list">
    <li class="stepper-item active"
        role="tab"
        aria-selected="true"
        aria-label="Etapa 1 de 3: Dados Básicos">
      <div class="stepper-icon">
        <i class="material-icons" aria-hidden="true">person</i>
      </div>
      <div class="stepper-content">
        <h3 class="stepper-title">Dados Básicos</h3>
      </div>
    </li>
    <!-- Outros steps -->
  </ol>
</div>
TeclaAção
TabNavega entre steps (se clicável)
Enter / SpaceAtiva step focado
Arrow Up/DownNavega entre steps (vertical)
Arrow Left/RightNavega entre steps (horizontal)

Contraste de Cores

Todos os estados seguem WCAG AA (4.5:1):

ElementoContrasteStatus
Ícone ativo7.1:1✅ AA
Título13.2:1✅ AAA
Descrição6.8:1✅ AA
Linha conectora5.2:1✅ AA

Boas Práticas

✅ Faça

  1. Use títulos claros e concisos

    html
    <!-- ✅ Bom -->
    <h3 class="stepper-title">Dados Pessoais</h3>
    
    <!-- ❌ Ruim -->
    <h3 class="stepper-title">Preencha o formulário com seus dados pessoais</h3>
  2. Forneça feedback visual claro

    javascript
    // Marque steps como completos
    stepper.completeStep(0);
    stepper.completeStep(1);
  3. Use ícones relevantes

    html
    <li class="stepper-item">
      <div class="stepper-icon">
        <i class="material-icons">person</i> <!-- Dados pessoais -->
      </div>
    </li>
  4. Valide antes de avançar

    javascript
    const stepper = createStepper('#wizard', {
      onStepValidate: (current, target) => {
        return validateForm(current);
      }
    });
  5. Limite a 5-7 steps

    • Mais que isso, considere agrupar em seções
  6. Use modo linear para processos sequenciais

    javascript
    { linear: true } // Não permite pular steps

❌ Não Faça

  1. Não use para navegação principal

    html
    <!-- ❌ Stepper não é menu -->
    <div class="stepper">
      <li>Home</li>
      <li>Sobre</li>
      <li>Contato</li>
    </div>
  2. Não omita estados visuais

    html
    <!-- ❌ Sem indicação de progresso -->
    <li class="stepper-item">...</li>
    
    <!-- ✅ Com estado claro -->
    <li class="stepper-item completed">...</li>
  3. Não force usuário a completar linearmente se não necessário

    javascript
    // ❌ Linear quando não precisa
    { linear: true }
    
    // ✅ Clicável para navegação livre
    { clickable: true, linear: false }
  4. Não use texto muito longo

    html
    <!-- ❌ Título longo -->
    <h3 class="stepper-title">
      Preencha todos os campos do formulário...
    </h3>
    
    <!-- ✅ Título curto + descrição -->
    <h3 class="stepper-title">Formulário</h3>
    <p class="stepper-description">Preencha todos os campos.</p>

Exemplo Completo

html
<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Wizard de Cadastro</title>
  <link rel="stylesheet" href="/css/design-system/design-system.css">
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
  <div class="container">
    <div class="stepper-card">
      <!-- Stepper -->
      <div class="stepper" id="wizardCadastro" data-stepper data-show-progress>
        <ol class="stepper-list">
          <li class="stepper-item" data-icon="person">
            <div class="stepper-icon">
              <i class="material-icons">person</i>
            </div>
            <div class="stepper-content">
              <h3 class="stepper-title">Dados Pessoais</h3>
              <p class="stepper-description">Nome, CPF, data de nascimento</p>
            </div>
          </li>

          <li class="stepper-item" data-icon="home">
            <div class="stepper-icon">
              <i class="material-icons">home</i>
            </div>
            <div class="stepper-content">
              <h3 class="stepper-title">Endereço</h3>
              <p class="stepper-description">CEP, rua, número, complemento</p>
            </div>
          </li>

          <li class="stepper-item" data-icon="phone">
            <div class="stepper-icon">
              <i class="material-icons">phone</i>
            </div>
            <div class="stepper-content">
              <h3 class="stepper-title">Contato</h3>
              <p class="stepper-description">Telefone e e-mail</p>
            </div>
          </li>

          <li class="stepper-item" data-icon="done_all">
            <div class="stepper-icon">
              <i class="material-icons">done_all</i>
            </div>
            <div class="stepper-content">
              <h3 class="stepper-title">Revisão</h3>
              <p class="stepper-description">Confira seus dados</p>
            </div>
          </li>
        </ol>

        <!-- Navegação -->
        <div class="stepper-navigation">
          <div class="stepper-nav-left">
            <button class="btn btn-outline" id="btnVoltar" disabled>
              Voltar
            </button>
          </div>
          <div class="stepper-nav-right">
            <button class="btn btn-primary" id="btnProximo">
              Próximo
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <script src="/css/design-system/components/stepper.js"></script>
  <script>
    const stepper = window.getStepper('#wizardCadastro');
    const btnVoltar = document.getElementById('btnVoltar');
    const btnProximo = document.getElementById('btnProximo');

    // Atualiza botões
    function updateButtons() {
      btnVoltar.disabled = stepper.isFirstStep();
      btnProximo.textContent = stepper.isLastStep() ? 'Finalizar' : 'Próximo';
    }

    // Evento de mudança
    document.querySelector('#wizardCadastro').addEventListener('stepper:change', () => {
      updateButtons();
      stepper.completeStep(stepper.getCurrentStep() - 1);
    });

    // Navegação
    btnVoltar.addEventListener('click', () => {
      stepper.previous();
    });

    btnProximo.addEventListener('click', () => {
      if (stepper.isLastStep()) {
        alert('Cadastro finalizado!');
      } else {
        stepper.next();
      }
    });

    updateButtons();
  </script>
</body>
</html>

Conclusão

O componente Stepper do SIDASP Design System oferece:

  • ✅ Navegação por etapas intuitiva
  • ✅ Vertical e horizontal
  • ✅ API JavaScript completa
  • ✅ Validação de steps
  • ✅ Barra de progresso
  • ✅ Modo linear e livre
  • ✅ Acessibilidade WCAG 2.1 AA
  • ✅ Dark mode

Para mais informações sobre outros componentes, consulte os guias específicos.


Versão: 1.0.0 Última atualização: 2025-10-31 Compatibilidade: Navegadores modernos (Chrome, Firefox, Safari, Edge)

Design System interno do GALES