Docs›Componentes (Admin)›mad-modal
Componentes (Admin)

mad-modal

Modal centralizado (sm/md/lg/xl).

Overlay centralizado para confirmacoes, formularios curtos e visualizacoes rapidas. Para formularios longos prefira <mad-drawer>.

Props

Prop Tipo Default Descricao
name string '' Identificador unico (obrigatorio, usado para abrir/fechar)
title string '' Titulo do header. Sem title = sem header
size string 'md' sm (380px), md (520px), lg (680px), xl (900px) ou valor CSS custom
footer string '' HTML do footer — nao e slot nomeado, e prop string (monte o HTML em PHP e passe via :footer)
dismissible bool true Permite fechar clicando no overlay; o botao X (no header) so aparece se houver title
class string '' Classes CSS extras no elemento overlay (.mad-modal-overlay)

O conteudo (slot) do <mad-modal> vira o body.

Estrutura basica

<mad-modal name="confirmar" title="Confirmar" size="sm">
    Tem certeza que deseja continuar?
</mad-modal>

<mad-btn open-modal="confirmar" variant="danger">Excluir</mad-btn>
@php
    $footer = '<button type="button" class="mad-btn mad-btn-ghost" '
            . 'onclick="window.dispatchEvent(new CustomEvent(\'madmodal\','
            . '{detail:{name:\'meu-modal\',action:\'close\'}}))">Cancelar</button>'
            . '<button type="button" class="mad-btn mad-btn-primary">OK</button>';
@endphp
<mad-modal name="meu-modal" title="Titulo" size="md" :footer="$footer">
    Conteudo do modal aqui.
</mad-modal>

Para footers complexos, prefira botoes MAD direto no body (final do slot) e deixe footer vazio:

<mad-modal name="form-rapido" title="Editar" size="md">
    <mad-form submit="onSave">
        <mad-input-field name="nome" label="Nome" required />
        <mad-form-actions align="right">
            <mad-btn close-modal="form-rapido" variant="ghost">Cancelar</mad-btn>
            <mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
        </mad-form-actions>
    </mad-form>
</mad-modal>

Abrir / fechar via botao

<mad-btn open-modal="confirmar" variant="danger" icon="trash-2">Excluir</mad-btn>
<mad-btn close-modal="confirmar" variant="ghost">Cancelar</mad-btn>

Abrir via JavaScript

<script>
window.dispatchEvent(new CustomEvent('madmodal', { detail: { name: 'confirmar', action: 'open' } }));
window.dispatchEvent(new CustomEvent('madmodal', { detail: { name: 'confirmar', action: 'close' } }));
</script>

Abrir / fechar via MadResponse (PHP)

public function onValidar(): MadResponse
{
    if (!$this->podeProsseguir()) {
        return (new MadResponse())->openModal('confirmar');
    }
    return (new MadResponse())
        ->toast('OK!', 'success')
        ->closeModal('confirmar');
}

MadComponent como modal (wrapper = MODAL)

Quando um MadComponent inteiro deve renderizar como modal (form curto, detalhe rapido), declare $wrapper = self::MODAL. O navegacao via <mad-btn navigate="..."> detecta automaticamente e abre como modal.

class ConfirmarExclusaoForm extends MadComponent
{
    protected static string $wrapper = self::MODAL;
    protected static string $title   = 'Confirmar exclusao';
    protected static string $size    = 'sm';

    public function onConfirm(): MadResponse
    {
        // ... excluir ...
        return (new MadResponse())
            ->toast('Excluido!', 'success')
            ->closeModal();
    }
}
<mad-btn navigate="ConfirmarExclusaoForm" params="{id: 42}" variant="danger">Excluir</mad-btn>

Tamanhos

Size Largura
sm 380px
md 520px (padrao)
lg 680px
xl 900px
valor custom qualquer CSS (size="600px")
<mad-modal name="bloqueio" title="Acao obrigatoria" :dismissible="false">
    Voce precisa aceitar os termos antes de prosseguir.
    <mad-btn mad:click="onAceitar" variant="primary">Aceitar</mad-btn>
</mad-modal>

Para modal cujo conteudo depende da acao (ex: ver detalhe de uma linha), use placeholder + MadResponse::html() + openModal():

<mad-modal name="detalhe" title="Detalhes" size="lg">
    <div id="detalhe-content"></div>
</mad-modal>
public function onVer(int $id): MadResponse
{
    $html = '<pre>' . htmlspecialchars($dados) . '</pre>';
    return (new MadResponse())
        ->html('#detalhe-content', $html)
        ->openModal('detalhe');
}

Quando usar modal vs drawer

Cenario Usar
Confirmacao (sim/nao) <mad-modal size="sm">
Formulario curto (1-5 campos) <mad-modal size="md">
Formulario longo / multi-secao <mad-drawer>
Visualizacao rapida de detalhe <mad-modal size="lg">
Edicao detalhada de registro <mad-drawer>

NUNCA fazer

{{-- ERRADO: footer nao e um slot nomeado deste componente --}}
<mad-modal name="m" title="T">
    <x-slot name="footer">...</x-slot>
    Conteudo
</mad-modal>

{{-- CERTO: footer como prop --}}
@php $footer = '<button ...>OK</button>'; @endphp
<mad-modal name="m" title="T" :footer="$footer">Conteudo</mad-modal>

{{-- ERRADO: title com {{ }} (escapa aspas) --}}
<mad-modal name="m" title="{{ __('app.confirmar') }}">...</mad-modal>

{{-- CERTO: bind PHP --}}
<mad-modal name="m" :title="__('app.confirmar')">...</mad-modal>

{{-- ERRADO: montar overlay/modal manualmente com HTML+CSS --}}
<div class="overlay" onclick="this.style.display='none'">
    <div class="modal">...</div>
</div>

{{-- CERTO --}}
<mad-modal name="meu">...</mad-modal>

{{-- ERRADO: instanciar um plugin JS de modal externo (Bootstrap Modal, SweetAlert2 cru) --}}
<script>
    new bootstrap.Modal(document.getElementById('meuModal')).show();
</script>

{{-- CERTO: MadComponent com wrapper=MODAL ou <mad-modal> direto --}}

{{-- ERRADO: open-modal apontando para name inexistente --}}
<mad-btn open-modal="modal-x">Abrir</mad-btn>
{{-- (sem <mad-modal name="modal-x"> declarado em lugar nenhum) --}}

{{-- ERRADO: usar mad-modal para form longo (use drawer) --}}
<mad-modal name="cadastro" size="xl">
    <mad-form>... 30 campos ...</mad-form>
</mad-modal>

{{-- CERTO --}}
<mad-drawer name="cadastro" size="lg">...</mad-drawer>