MeModal
Modal com overlay, suporte a posicionamento, slots de header/body/footer, fechamento por ESC, clique fora e botão de fechar.
Playground
Importação
vue
<script>
import { MeModal } from '@/components/global/utils/export/index'
</script>Uso Básico
vue
<script setup>
import { ref } from 'vue'
const isOpen = ref(false)
</script>
<template>
<MeButton label="Abrir Modal" @click="isOpen = true" />
<MeModal :visible="isOpen" title-header="Título do Modal" @close="isOpen = false">
<template #body>
Conteúdo do modal.
</template>
<template #footer>
<MeButton label="Fechar" variant="gray" flat @click="isOpen = false" />
</template>
</MeModal>
</template>Posicionamento
A prop position controla onde o modal aparece na tela.
vue
<MeModal
:visible="isOpen"
position="top-right"
width="360px"
title-header="Top Right"
@close="isOpen = false"
>
<template #body>Conteúdo</template>
</MeModal>Body com Scroll
Use body-max-height para limitar a altura do body e ativar scroll automático.
vue
<MeModal
:visible="isOpen"
title-header="Body com Scroll"
body-max-height="200px"
@close="isOpen = false"
>
<template #body>
<!-- conteúdo longo -->
</template>
</MeModal>Conteúdo Customizado
Com custom-content, o slot default substitui toda a estrutura de header/body/footer.
vue
<MeModal :visible="isOpen" :custom-content="true" width="400px" @close="isOpen = false">
<div style="padding: 40px; text-align: center">
<h2>Conteúdo Livre</h2>
<MeButton label="Fechar" @click="isOpen = false" />
</div>
</MeModal>Controle de Fechamento
Por padrão o modal fecha por ESC, clique fora e botão de fechar. Cada comportamento pode ser desabilitado individualmente.
vue
<MeModal
:visible="isOpen"
title-header="Modal Restrito"
:close-on-esc="false"
:close-on-click-outside="false"
@close="isOpen = false"
>
<template #body>Conteúdo</template>
</MeModal>Evento close
O payload do evento indica o motivo do fechamento.
vue
<MeModal :visible="isOpen" @close="handleClose">
<template #body>Conteúdo</template>
</MeModal>
<script setup>
function handleClose(reason) {
// reason: 'close-button' | 'click-outside' | 'esc-key' | 'normal'
console.log('Fechado por:', reason)
isOpen.value = false
}
</script>API
Props
| Prop | Tipo | Padrão | Descrição |
|---|---|---|---|
visible | boolean | false | Controla a visibilidade do modal |
titleHeader | string | — | Título exibido no header padrão |
width | string | '800px' | Largura máxima do container |
minHeight | string | '80px' | Altura mínima do container |
position | MeModalPosition | 'center' | Posição do modal na tela |
showCloseButton | boolean | true | Exibe o botão de fechar no canto superior direito |
closeOnClickOutside | boolean | true | Fecha ao clicar fora do container |
closeOnEsc | boolean | true | Fecha ao pressionar ESC |
customContent | boolean | false | Usa o slot default como conteúdo livre |
bodyMaxHeight | string | — | Altura máxima do body (ativa overflow: auto) |
containerStyle | object | {} | Estilo inline adicional para o container |
headerStyle | object | {} | Estilo inline adicional para o header |
bodyStyle | object | {} | Estilo inline adicional para o body |
footerStyle | object | {} | Estilo inline adicional para o footer |
MeModalPosition
typescript
type MeModalPosition =
| 'center' | 'top-center' | 'top-right' | 'top-left'
| 'bottom-center' | 'bottom-right' | 'bottom-left'
| 'center-left' | 'center-right'Eventos
| Evento | Payload | Descrição |
|---|---|---|
close | string | Emitido ao fechar. Motivo: 'close-button', 'click-outside', 'esc-key' ou 'normal' |
Slots
| Nome | Descrição |
|---|---|
#header | Conteúdo adicional no header. O header só é renderizado se titleHeader ou este slot forem fornecidos |
#body | Conteúdo principal do modal |
#footer | Rodapé do modal. Só é renderizado quando preenchido |
default | Conteúdo livre quando customContent=true |
Acessibilidade
- O container do modal tem
role="dialog"earia-modal="true" - Navegação por teclado: ESC fecha o modal (controlado por
closeOnEsc) - O scroll do
document.bodyé bloqueado enquanto o modal está aberto e restaurado ao fechar