MeStepsModal
Modal com navegação em etapas, barra de progresso e botão de ação configurável por step.
Playground
Importação
vue
<script setup>
import { MeStepsModal } from '@me/ui-vue3'
</script>vue
<script>
import { MeStepsModal } from '@me/ui-vue2'
export default {
components: { MeStepsModal }
}
</script>Uso Básico
Com mais de um step, o modal exibe a barra de progresso e o contador X / N. O botão mostra Continuar nos steps intermediários e Confirmar no último.
vue
<script setup>
import { ref, markRaw, defineComponent } from 'vue'
const isOpen = ref(false)
const StepConta = markRaw(defineComponent({ template: `<div>...</div>` }))
const StepPrefs = markRaw(defineComponent({ template: `<div>...</div>` }))
const StepRevisao = markRaw(defineComponent({ template: `<div>...</div>` }))
</script>
<template>
<MeStepsModal
:visible="isOpen"
titleHeader="Cadastro"
:steps="[
{ title: 'Conta', component: StepConta },
{ title: 'Preferências', component: StepPrefs },
{ title: 'Revisão', component: StepRevisao },
]"
@close="isOpen = false"
@finish="isOpen = false"
/>
</template>Step Bloqueado
Use button.canContinue para controlar se o botão de ação está habilitado. Útil para validar formulários antes de avançar.
vue
<script setup>
import { ref, markRaw, defineComponent } from 'vue'
const isOpen = ref(false)
const formularioValido = ref(false)
const MeuFormStep = markRaw(defineComponent({
template: `<div>
<input type="checkbox" v-model="formularioValido" />
Aceito os termos
</div>`,
setup() {
return { formularioValido }
}
}))
const MeuResumoStep = markRaw(defineComponent({
template: `<div>Revise e confirme.</div>`
}))
</script>
<template>
<MeStepsModal
:visible="isOpen"
:steps="[
{
title: 'Validação',
component: MeuFormStep,
button: { canContinue: () => formularioValido.value },
},
{ title: 'Confirmação', component: MeuResumoStep },
]"
@close="isOpen = false"
@finish="isOpen = false"
/>
</template>Barra de Progresso Clicável
Com clickableProgressBar, o usuário pode navegar para qualquer step clicando nos segmentos da barra.
vue
<script setup>
import { ref, markRaw, defineComponent } from 'vue'
const isOpen = ref(false)
const StepConta = markRaw(defineComponent({ template: `<div>Informações da conta.</div>` }))
const StepPrefs = markRaw(defineComponent({ template: `<div>Preferências do usuário.</div>` }))
const StepRevisao = markRaw(defineComponent({ template: `<div>Revisão final.</div>` }))
</script>
<template>
<MeStepsModal
:visible="isOpen"
clickableProgressBar
:steps="[
{ title: 'Conta', component: StepConta },
{ title: 'Preferências', component: StepPrefs },
{ title: 'Revisão', component: StepRevisao },
]"
@close="isOpen = false"
@finish="isOpen = false"
/>
</template>Evento step-change
O evento step-change é emitido ao avançar ou navegar entre steps. O payload é o índice (0-based) do novo step.
Step atual: 0
vue
<script setup>
import { ref } from 'vue'
const isOpen = ref(false)
const currentStep = ref(0)
</script>
<template>
<MeStepsModal
:visible="isOpen"
:steps="steps"
@step-change="currentStep = $event"
@close="isOpen = false"
@finish="isOpen = false"
/>
</template>API
Props
| Prop | Tipo | Padrão | Descrição |
|---|---|---|---|
visible | boolean | false | Controla a visibilidade do modal |
steps | StepItem[] | [] | Lista de etapas |
titleHeader | string | '' | Título do cabeçalho. Se omitido em múltiplos steps, usa o título do step atual |
width | string | '600px' | Largura do modal |
minHeight | string | '200px' | Altura mínima do modal |
containerStyle | object | {} | Estilos adicionais do container |
clickableProgressBar | boolean | false | Permite navegar clicando na barra de progresso |
closeOnClickOutside | boolean | false | Fecha ao clicar fora do modal |
dontShowIfAnyModalOpened | boolean | false | Não exibe se já houver outro modal aberto |
Eventos
| Evento | Payload | Descrição |
|---|---|---|
close | string | Emitido ao fechar o modal. Payload = motivo do fechamento |
finish | — | Emitido ao clicar em Confirmar no último step |
step-change | number | Emitido ao navegar para outro step. Payload = índice do novo step (0-based) |
Tipos
StepItem
| Campo | Tipo | Descrição |
|---|---|---|
title | string | Título da etapa (exibido no header e na barra) |
component | Component | Componente Vue a renderizar no corpo do step |
props | object? | Props repassadas ao componente via v-bind |
button | StepButton? | Configuração do botão de ação |
StepButton
| Campo | Tipo | Descrição |
|---|---|---|
label | string? | Texto do botão. Padrão: 'Continuar' ou 'Confirmar' |
icon | string? | Ícone Material do botão |
canContinue | () => boolean | Função que retorna se o botão está habilitado |
onClick | () => void | Handler customizado (substitui o comportamento padrão de nextStep/finish) |
Componentes como markRaw
Ao armazenar definições de componente em estado reativo (ex: ref, reactive), envolva-os com markRaw() para evitar que o Vue tente torná-los reativos.
typescript
import { markRaw, defineComponent } from 'vue'
const MeuStep = markRaw(defineComponent({ ... }))
// ou ao importar um .vue
import MinhaView from './MinhaView.vue'
const steps = ref([
{ title: 'Etapa', component: markRaw(MinhaView) }
])