Guia Completo: Stepper (Wizard / Progress Steps)
Índice
- Introdução
- Estrutura Básica
- Estados dos Steps
- Stepper Horizontal
- Tamanhos
- Com Barra de Progresso
- Stepper Clicável
- JavaScript API
- Eventos
- Acessibilidade
- 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)
<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
| Classe | Descrição |
|---|---|
.stepper | Container principal |
.stepper-list | Lista de steps (ol ou ul) |
.stepper-item | Item individual (step) |
.stepper-icon | Container do ícone |
.stepper-content | Container do conteúdo (título + descrição) |
.stepper-title | Título do step |
.stepper-description | Descrição opcional do step |
Estados dos Steps
Step Pendente (Padrão)
<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
<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
<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
<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
| Estado | Classe | Ícone Comum | Cor | Uso |
|---|---|---|---|---|
| Pendente | (nenhuma) | info, more_horiz | Cinza | Steps futuros |
| Ativo | .active | edit, play_arrow | Azul | Step atual |
| Completo | .completed | check, done | Verde | Steps concluídos |
| Erro | .error | error, warning | Vermelho | Steps com problema |
Stepper Horizontal
<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)
<div class="stepper stepper-sm">
<!-- Steps menores (32px) -->
</div>Médio (Padrão)
<div class="stepper">
<!-- Tamanho padrão (40px) -->
</div>Grande (Large)
<div class="stepper stepper-lg">
<!-- Steps maiores (48px) -->
</div>Tabela de Tamanhos
| Classe | Ícone | Título | Descrição | Uso |
|---|---|---|---|---|
.stepper-sm | 32px | 14px | 12px | Mobile, sidebar |
| (padrão) | 40px | 16px | 14px | Uso geral |
.stepper-lg | 48px | 18px | 16px | Destaque, hero |
Com Barra de Progresso
<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:
<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:
<div class="stepper stepper-clickable" data-stepper data-clickable>
<ol class="stepper-list">
<!-- Steps clicáveis -->
</ol>
</div>Ou via JavaScript:
const stepper = window.createStepper('#meuStepper', {
clickable: true
});JavaScript API
Inicialização Automática
<!-- 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
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
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ícioMétodos de Consulta
// 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á completoEventos
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
<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>Navegação por Teclado
| Tecla | Ação |
|---|---|
| Tab | Navega entre steps (se clicável) |
| Enter / Space | Ativa step focado |
| Arrow Up/Down | Navega entre steps (vertical) |
| Arrow Left/Right | Navega entre steps (horizontal) |
Contraste de Cores
Todos os estados seguem WCAG AA (4.5:1):
| Elemento | Contraste | Status |
|---|---|---|
| Ícone ativo | 7.1:1 | ✅ AA |
| Título | 13.2:1 | ✅ AAA |
| Descrição | 6.8:1 | ✅ AA |
| Linha conectora | 5.2:1 | ✅ AA |
Boas Práticas
✅ Faça
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>Forneça feedback visual claro
javascript// Marque steps como completos stepper.completeStep(0); stepper.completeStep(1);Use ícones relevantes
html<li class="stepper-item"> <div class="stepper-icon"> <i class="material-icons">person</i> <!-- Dados pessoais --> </div> </li>Valide antes de avançar
javascriptconst stepper = createStepper('#wizard', { onStepValidate: (current, target) => { return validateForm(current); } });Limite a 5-7 steps
- Mais que isso, considere agrupar em seções
Use modo linear para processos sequenciais
javascript{ linear: true } // Não permite pular steps
❌ Não Faça
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>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>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 }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
<!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)