Docs›Exemplos›Kitchen sink (demo)
Exemplos

Kitchen sink (demo)

Demonstração de todos os componentes em uma única página.

Tour consolidado por boa parte dos componentes do MAD em ação: form com dezenas de campos diferentes, listagem com agrupamento, drawer com mestre/detalhe e chips pivot, dashboard com KPIs/charts/pivot, calendário/kanban/gantt, os widgets ERP da linha 5.x (mad-sheet, mad-reconcile, mad-org-chart, mad-pdv) e os blocos de feedback (toast, modal, drawer, alert, steps). Use como referência visual e ponto de partida para copiar/colar.

Como ler esta página

Cada bloco abaixo é independente — copie só a seção que precisa, ajuste name/model/método PHP, e funciona isolado. Para a lista completa de props de qualquer tag, use a referência de Components.

1. Form com diversos tipos de campo

<mad-form submit="onSave">
    <mad-form-section title="Texto" icon="type">
        <mad-form-grid :cols="3">
            <mad-input-field name="nome" label="Nome" required />
            <mad-input-field name="cpf" label="CPF" mask="cpf" strip-mask />
            <mad-input-field name="placa" label="Placa" mask="placa" force-case="upper" />
            <mad-input-field name="email" label="Email" type="email" icon="mail" />
            <mad-password-field name="senha" label="Senha" :strong-password="true" />
            <mad-otp-field name="codigo" label="Código de verificação" :length="6" />
        </mad-form-grid>
        <mad-textarea-field name="observacoes" label="Observações" :rows="4" />
        <mad-html-editor-field name="conteudo" label="Conteúdo HTML" :height="240" />
    </mad-form-section>

    <mad-separator />

    <mad-form-section title="Endereço (autopreenchido)" icon="map-pin">
        <mad-form-grid :cols="3">
            <mad-cep-field name="cep" label="CEP"
                :fill-fields="['rua'=>'rua','cidade_id'=>'cidade_id','estado_id'=>'estado_id']" />
            <mad-cnpj-field name="cnpj" label="CNPJ"
                :fill-fields="['razao_social'=>'razao_social']" />
            <mad-scanner-field name="cod_barras" label="EAN" type="both" />
        </mad-form-grid>
    </mad-form-section>

    <mad-separator />

    <mad-form-section title="Números" icon="hash">
        <mad-form-grid :cols="3">
            <mad-number-field name="quantidade" label="Quantidade" :min="1" step="1" />
            <mad-numeric-field name="peso" label="Peso (kg)" :decimals="3" />
            <mad-money-field name="preco" label="Preço" />
            <mad-spinner-field name="qtd_itens" label="Itens" :min="1" :max="99" />
            <mad-range-field name="desconto" label="Desconto" :min="0" :max="100" suffix="%" />
        </mad-form-grid>
    </mad-form-section>

    <mad-separator />

    <mad-form-section title="Data e hora" icon="calendar">
        <mad-form-grid :cols="3">
            <mad-date-field name="dt_nascimento" label="Nascimento" />
            <mad-time-field name="hora_entrega" label="Hora de entrega" />
            <mad-datetime-field name="dt_evento" label="Data + hora" />
        </mad-form-grid>
        <mad-daterange-field name_start="dt_ini" name_end="dt_fim" label="Período" presets />
    </mad-form-section>

    <mad-separator />

    <mad-form-section title="Seleção" icon="check-square">
        <mad-form-grid :cols="3">
            <mad-select-field name="status" label="Status" :items="['A'=>'Ativo','I'=>'Inativo']" />
            <mad-dbcombo-field name="categoria_id" label="Categoria" model="Categoria" display="nome" />
            <mad-radio-field name="tipo" label="Tipo" :options="['F'=>'Física','J'=>'Jurídica']" inline />
            <mad-checkbox-field name="ativo" label="Ativo" />
            <mad-switch-field name="marketing" label="Marketing" />
            <mad-color-field name="cor" label="Cor" />
        </mad-form-grid>
        <mad-checkbox-group-field name="permissoes" label="Permissões"
            :options="['read'=>'Ler','write'=>'Escrever','delete'=>'Excluir']" layout="horizontal" />
        <mad-multi-entry-field name="tags" label="Tags" placeholder="Digite e Enter..." />
        <mad-sort-list-field name="ordem"
            :items="['nome'=>'Nome','email'=>'Email','fone'=>'Telefone']" />
    </mad-form-section>

    <mad-separator />

    <mad-form-section title="Upload" icon="upload">
        <mad-form-grid :cols="2">
            <mad-file-field name="contrato" label="Contrato"
                storage="disk" folder="uploads/contratos" accept=".pdf" />
            <mad-image-field name="foto" label="Foto" crop aspect-ratio="1:1"
                storage="disk" folder="uploads/fotos" />
            <mad-avatar-field name="avatar" label="Avatar"
                storage="disk" folder="uploads/avatars" />
            <mad-signature-field name="assinatura" label="Assinatura" modes="draw,type,upload"
                storage="disk" folder="uploads/assinaturas" />
        </mad-form-grid>
        <mad-multi-file-field name="anexos" label="Anexos"
            storage="disk" folder="uploads/docs" mode="comma" :max-files="5" />
    </mad-form-section>

    <mad-separator />

    <mad-form-actions>
        <mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
        <mad-btn variant="ghost" close-drawer>Cancelar</mad-btn>
    </mad-form-actions>
</mad-form>

2. Listagem com agrupamento, busca e export

<mad-grid self per-page="20" searchable :search-columns="['nome','email']"
    sticky card-view
    :group-by="['categoria.nome']" group-mask="{categoria_nome}" group-total
    export-title="Lista de Clientes">

    <mad-columns>
        <mad-col field="id" label="Cod." width="70" center sort />
        <mad-col field="nome" label="Nome" sort filter card-role="title" />
        <mad-col field="email" label="Email" filter />
        <mad-col field="cidade->nome" label="Cidade" sort filter />
        <mad-col field="dt_cadastro" label="Cadastro" date="d/m/Y" card-role="subtitle" />
        <mad-col field="status" label="Status"
            badge="A:success:Ativo|I:danger:Inativo|P:warning:Pendente" card-role="badge" />
        <mad-col field="valor_total" label="Total" right money="R$" total="sum" card-role="highlight" />
    </mad-columns>

    <mad-actions>
        <mad-nav icon="eye" label="Ver" target="ClienteDetalhe::onShow({id})" />
        <mad-nav icon="pencil" label="Editar" target="ClienteForm::onEdit({id})" />
        <mad-action-group icon="more-horizontal" label="Ações">
            <mad-act method="onAprovar" icon="check-circle" label="Aprovar" primary
                when-field="status" when-value="P" />
            <mad-act method="onCancelar" icon="ban" label="Cancelar" danger
                confirm="Tem certeza?" when-field="status" when-nin="cancelado" />
        </mad-action-group>
    </mad-actions>
</mad-grid>

3. Drawer com mestre/detalhe + chips pivot

<mad-form submit="onSave">
    <mad-form-section title="Pedido" icon="file-text">
        <mad-form-grid :cols="2">
            <mad-dbcombo-field name="cliente_id" label="Cliente" model="Pessoa" display="nome" required />
            <mad-date-field name="dt_pedido" label="Data" required />
        </mad-form-grid>
    </mad-form-section>

    <mad-separator />

    <mad-form-section title="Itens" icon="package">
        <mad-detail-form name="dfPedidoItem" model="PedidoItem" foreign-key="pedido_id" mode="drawer">
            <mad-detail-fields>
                <mad-form-grid :cols="2">
                    <mad-dbcombo-field name="produto_id" label="Produto" model="Produto" display="nome" required />
                    <mad-numeric-field name="quantidade" label="Qtd" :decimals="3" required />
                </mad-form-grid>
                <mad-money-field name="valor" label="Valor" />
            </mad-detail-fields>
            <mad-columns>
                <mad-col field="produto->nome" label="Produto" />
                <mad-col field="quantidade" label="Qtd" right />
                <mad-col field="valor" label="Valor" right money="R$" total="sum" />
            </mad-columns>
        </mad-detail-form>
    </mad-form-section>

    <mad-separator />

    <mad-form-section title="Tags" icon="tag">
        <mad-db-blocks name="tags" mode="flat" pivot-model="Tag"
            row-view="components.partials.tag-chip" on-add="onTagCreate">
            <mad-db-blocks-form>
                <mad-input-field name="name" required />
                <mad-color-field name="color" />
            </mad-db-blocks-form>
        </mad-db-blocks>
    </mad-form-section>

    <mad-form-actions>
        <mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
    </mad-form-actions>
</mad-form>
// No controller (MadComponent) — db-blocks exige o trait dedicado.
use Mad\Form\MadDbBlocksTrait;

class PedidoForm extends \Mad\Component\MadComponent
{
    use MadDbBlocksTrait;

    public function onTagCreate(Tag $tag): void
    {
        $tag->created_by = session('userid');
    }
}

4. Dashboard com KPIs + charts + pivot

<mad-form-grid :cols="4">
    <mad-db-metric-card model="PedidoVenda" :query="$that->queryPedidos()"
        total="count" label="Pedidos" icon="shopping-cart" format="integer" />
    <mad-db-metric-card model="PedidoVenda" :query="$that->queryPedidos()"
        field="valor_total" total="sum" label="Faturamento" variant="success" format="money:R$ " />
    <mad-db-metric-card model="Cliente" total="count" label="Clientes" icon="users" format="integer" />
    <mad-db-metric-card model="Produto" total="count" :filters="[['ativo','=','1']]"
        label="Produtos ativos" icon="package" format="integer" />
</mad-form-grid>

<mad-form-grid :cols="2">
    <mad-db-chart type="line" model="PedidoVenda" :query="$that->queryPedidos()"
        group-by="dt_pedido" field="valor_total" total="sum"
        title="Vendas por dia" format="currency:R$" area />
    <mad-db-chart type="donut" model="PedidoVenda" :query="$that->queryPedidos()"
        group-by="status" total="count" title="Por status" legend percentage />
</mad-form-grid>

<mad-pivot-table model="PedidoVenda" title="Detalhamento" subtotals>
    <mad-pivot-row field="vendedor.nome" />
    <mad-pivot-col field="status" />
    <mad-pivot-value field="valor_total" aggregation="sum" format="currency" />
</mad-pivot-table>

Ver Dashboard real para o controller completo (MadDashboard + baseQuery()) por trás deste $that.

5. Calendário, Kanban e Gantt

Os três têm modo 100% declarativo: a tag sozinha já faz auto-query no Eloquent a partir de model + mapeamento de campos — sem subclasse PHP dedicada. Para customizar comportamento (hooks de drag/resize, cards custom), existe a variante via subclasse (Mad\Calendar\MadCalendarComponent, Mad\Calendar\MadKanban, Mad\Calendar\MadGanttComponent) — ver Calendários, Kanban e Gantt.


<mad-calendar model="Evento" database="business"
    title-field="titulo" start-field="dt_inicio" end-field="dt_fim"
    color-field="cor" default-view="agendaWeek" editable
    click-target="EventoForm::onEdit({id})"
    period-type="date-range" date-field="dt_inicio" remember-filters />


<mad-kanban model="Negociacao" database="business"
    stage-model="EtapaNegociacao" stage-field="etapa_negociacao_id"
    value-field="valor_total" click-target="NegociacaoForm::onEdit({id})" />


<mad-gantt model="ProjetoTarefa" database="business"
    name-field="titulo" start-field="dt_inicio" end-field="dt_fim"
    parent-field="parent_id" progress-field="percentual" color-field="cor" />

6. Widgets ERP: sheet, reconcile, org-chart e PDV

Quatro componentes de tela inteira que nasceram na linha 5.x e seguem o mesmo padrao dos widgets grandes (compiler em compile-time + MadComponent de runtime + config cacheada em sessao + client Alpine dedicado). Todos funcionam embutidos numa blade qualquer; so as acoes que falam com o servidor (lazy-load, re-parent, finalizacao de venda) exigem que o host da pagina seja subclasse do componente.

TagPara que serveClasse de runtime
mad-sheetPlanilha de lancamento em lote (entry-first): nasce vazia, existe para digitar registros NOVOS (inventario, lancamentos contabeis). Listar existentes continua sendo mad-grid.Mad\Sheet\MadSheet
mad-reconcileConciliacao two-panel (extrato x lancamentos) com auto-match e grupos N:M persistidos em mad_reconcile_group/mad_reconcile_item.Mad\Reconcile\MadReconcile
mad-org-chartHierarquia auto-referente (FK parent-field) como arvore grafica: pan, zoom, collapse, busca, lazy-load e drag re-parent.Mad\OrgChart\MadOrgChart
mad-pdvFrente de caixa (POS): scan bar, carrinho, formas de pagamento com troco/parcelamento, vendas em espera e cupom nao-fiscal.Mad\Pdv\MadPdvComponent

<mad-sheet model="StockCount" database="business" rows-min="10" max-rows="2000">
    <mad-sheet-col field="produto_id" type="combo" source="Produto" source-label="nome"
                   label="Produto" required width="220px" />
    <mad-sheet-col field="quantidade" type="number" label="Qtd" total="sum" decimals="0" required />
    <mad-sheet-col field="valor" type="money" label="Valor unit." total="sum" width="140px" />
    <mad-sheet-col field="data" type="date" label="Data" :default="date('Y-m-d')" width="150px" />
</mad-sheet>


<mad-reconcile left-model="BankStatementLine" right-model="LedgerEntry"
    database="business" match-on="amount,date:3,document"
    left-amount="valor"   right-amount="valor"
    left-date="data"      right-date="data_lancamento"
    left-doc="documento"  right-doc="numero_doc"
    left-label="descricao" right-label="historico"
    left-title="Extrato bancario" right-title="Lancamentos"
    tolerance="0.01" max-rows="500" context="banco-conta1" />


<mad-org-chart model="Employee" parent-field="manager_id"
    title="nome" subtitle="cargo" avatar-field="foto"
    metric="equipe_count" metric-label="equipe"
    order-field="nome" lazy-depth="2" max-nodes="1000"
    click-target="EmployeeForm::onShow({id})" />


<mad-pdv model="Produto" database="business"
    name-field="nome" price-field="preco" code-field="codigo" barcode-field="ean"
    sale-model="Venda" item-model="VendaItem" payment-model="VendaPagamento"
    customer-model="Cliente" customer-display="nome"
    currency-symbol="R$ " hold-sales ask-document>

    <mad-pdv-column field="{categoria->nome}" label="Categoria" width="140px" />
    <mad-pdv-column mode="input" item-field="vendedor" label="Vendedor" required maxlength="40" />

    <mad-pdv-payment method="dinheiro" label="Dinheiro" allow-change entra-no-caixa hotkey="F5" />
    <mad-pdv-payment method="cartao_credito" label="Credito"
        gera-titulo sacado="adquirente" max-parcelas="12" />

    <mad-pdv-action label="Abrir gaveta" icon="archive" method="onOpenDrawer" />
</mad-pdv>
Atributo mad-* nao aceita {{ }}

Os compilers desses quatro componentes rodam antes do Blade, sobre o texto cru. Expressao PHP entra com o prefixo dois-pontos — :rows-min="$that->rowsMin()", :default="date('Y-m-d')", :where="$filtro" — nunca com chaves duplas. O mesmo vale para condicional Blade dentro do bloco: @if em volta de <mad-pdv-payment> some no render, porque a sub-tag e extraida por expressao regular antes da condicional existir.

7. Toast, modal, drawer, alert, badge

<mad-form-grid :cols="3">
    <mad-btn variant="success" mad:click="onSucesso">Toast Success</mad-btn>
    <mad-btn variant="danger" mad:click="onErro">Toast Error</mad-btn>
    <mad-btn variant="primary" open-modal="confirmar">Abrir Modal</mad-btn>
    <mad-btn variant="primary" open-drawer="form">Abrir Drawer</mad-btn>
</mad-form-grid>

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

<mad-drawer name="form" title="Editar" size="md">
    <mad-form submit="onSave">
        <mad-input-field name="nome" label="Nome" />
        <mad-form-actions>
            <mad-btn type="submit" variant="primary">Salvar</mad-btn>
        </mad-form-actions>
    </mad-form>
</mad-drawer>

<mad-alert type="info" title="Atenção">Mensagem informativa.</mad-alert>
<mad-alert type="success">Operação bem-sucedida.</mad-alert>
<mad-alert type="warning">Verifique os dados.</mad-alert>
<mad-alert type="danger">Algo deu errado.</mad-alert>

<mad-badge variant="success">Ativo</mad-badge>
<mad-badge variant="danger" icon="x">Cancelado</mad-badge>

<mad-steps variant="dots" :current="2">
    <mad-step icon="user" label="Dados" />
    <mad-step icon="credit-card" label="Pagamento" />
    <mad-step icon="check" label="Confirmação" />
</mad-steps>
public function onSucesso(): \Mad\Http\MadResponse
{
    return \Mad\Ui\MadToast::success('Deu certo!');
}

public function onErro(): \Mad\Http\MadResponse
{
    return \Mad\Ui\MadToast::danger('Falhou — tente de novo.');
}

8. Geração de PDF

Mad\Doc\MadDocPdf::fromView() renderiza uma view Blade via DOMPDF e retorna os bytes do PDF — não um objeto com ->stream(). Como o endpoint reativo (_mad-wire) só fala JSON, o download roda numa rota HTTP comum, fora do ciclo do MadComponent:

// app/Http/Controllers/PedidoPdfController.php
namespace App\Http\Controllers;

use App\Models\PedidoVenda;
use Illuminate\Http\Response;
use Mad\Doc\MadDocPdf;

class PedidoPdfController extends Controller
{
    public function show(int $id): Response
    {
        $pedido = PedidoVenda::with('itens')->findOrFail($id);

        $pdf = MadDocPdf::fromView('pdf.pedido', ['pedido' => $pedido]);

        return response($pdf, 200, [
            'Content-Type'        => 'application/pdf',
            'Content-Disposition' => 'inline; filename="pedido-' . $pedido->id . '.pdf"',
        ]);
    }
}
// routes/modules/admin.php
Route::middleware(['mad.auth', 'mad.permission'])->group(function () {
    Route::get('/pedidos/{id}/pdf', [\App\Http\Controllers\PedidoPdfController::class, 'show'])
        ->name('pedidos.pdf');
});
<mad-btn icon="file-text" href="@{{ route('pedidos.pdf', $pedido->id) }}" target="_blank">
    Baixar PDF
</mad-btn>
Use isto como playground

Copie qualquer trecho desta página, cole numa view nova, ajuste o model e o método PHP, rode. Cada bloco funciona isolado, sem dependência entre si.