Layout de formulário
mad-form-section, mad-form-grid, mad-form-stack, mad-form-actions.
Componentes de layout organizam campos dentro de <mad-form> — todos
sem estado próprio, livres para combinar e aninhar conforme a estrutura do
formulário.
Hierarquia típica
<mad-form submit="onSave">
<mad-form-section title="..." icon="..."> ← agrupamento visual com título
<mad-form-grid :cols="2"> ← campos lado a lado
<mad-input-field ... />
<mad-input-field ... />
</mad-form-grid>
<mad-form-stack> ← campos empilhados
<mad-textarea-field ... />
</mad-form-stack>
</mad-form-section>
<mad-separator /> ← divisor visual
<mad-form-section title="..." icon="...">
...
</mad-form-section>
<mad-separator />
<mad-form-actions> ← botões de ação
<mad-btn perm-action="onSave" type="submit" variant="primary" icon="save">Salvar</mad-btn>
</mad-form-actions>
</mad-form>
<mad-form> — wrapper do formulário
Renderiza o <form> real com integração ao MadWire (submit via AJAX) e injeta o token de schema usado por getData()/validate().
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
submit | string | '' | Método PHP chamado no submit (ex: onSave) |
id | string | '' | ID do form |
class | string | '' | Classes CSS extras |
attrs | string | '' | Atributos HTML extras |
<mad-form submit="onSave">
...campos...
<mad-btn perm-action="onSave" type="submit" variant="primary" icon="save">Salvar</mad-btn>
</mad-form>
<mad-form-section> — agrupamento com título
Bloco semântico com header (ícone + título + linha divisória). Usar para separar áreas lógicas do formulário.
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
title | string | '' | Título da seção |
subtitle | string | null | Subtítulo (menor, cinza) |
icon | string | null | Ícone Lucide |
class | string | '' | Classes CSS extras |
style | string | '' | Estilos inline extras |
<mad-form-section title="Dados pessoais" icon="user">
<mad-form-grid :cols="2">
<mad-input-field name="nome" label="Nome" required />
<mad-input-field name="email" label="Email" />
</mad-form-grid>
</mad-form-section>
Com subtítulo:
<mad-form-section title="Endereço" subtitle="Endereço de entrega principal" icon="map-pin">
...
</mad-form-section>
<mad-form-grid> — grid de colunas
Distribui campos em colunas iguais via CSS grid. Responsivo — colapsa para 1 coluna em mobile.
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
cols | int | 2 | Número de colunas (1 a 6) |
template | string | null | grid-template-columns CSS bruto — sobrepõe cols quando informado (ex: "200px 1fr") |
gap | int | 4 | Espaçamento (índice): 0=0px, 1=4px, 2=8px, 3=12px, 4=16px, 5=20px, 6=24px, 8=32px |
class | string | '' | Classes CSS extras |
style | string | '' | Estilos inline extras |
<!-- 2 colunas (padrão) -->
<mad-form-grid :cols="2">
<mad-input-field name="nome" label="Nome" />
<mad-input-field name="email" label="Email" />
</mad-form-grid>
<!-- 3 colunas -->
<mad-form-grid :cols="3">
<mad-input-field name="cidade" label="Cidade" />
<mad-dbcombo-field name="estado_id" label="Estado" model="Estado" display="nome" />
<mad-input-field name="cep" label="CEP" />
</mad-form-grid>
<!-- 1 coluna (campo largo) -->
<mad-form-grid :cols="1">
<mad-textarea-field name="obs" label="Observações" />
</mad-form-grid>
Múltiplos grids numa seção
Use vários <mad-form-grid> consecutivos para mudar o número de colunas dentro da mesma seção:
<mad-form-section title="Produto" icon="package">
<mad-form-grid :cols="2">
<mad-input-field name="nome" label="Nome" required />
<mad-input-field name="cod_barras" label="Cód. Barras" />
</mad-form-grid>
<mad-form-grid :cols="3">
<mad-numeric-field name="valor" label="Valor" prefix="R$" />
<mad-numeric-field name="peso" label="Peso (kg)" />
<mad-input-field name="unidade" label="Unidade" />
</mad-form-grid>
</mad-form-section>
<mad-form-stack> — campos empilhados verticalmente
Flex column com gap. Usar quando cada campo deve ocupar 100% da largura — semanticamente equivalente a <mad-form-grid :cols="1">, mas indica explicitamente "lista vertical", não "grid".
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
gap | int | 4 | Espaçamento (mesmo índice do form-grid) |
class | string | '' | Classes CSS extras |
<mad-form-stack>
<mad-input-field name="titulo" label="Título" required />
<mad-textarea-field name="descricao" label="Descrição" />
<mad-html-editor-field name="conteudo" label="Conteúdo" />
</mad-form-stack>
<mad-form-actions> — footer de botões
Container flex para botões de ação do formulário — substitui <div style="display:flex;gap:8px;margin-top:16px;"> escrito à mão.
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
align | string | 'left' | left, right ou center |
class | string | '' | Classes CSS extras |
style | string | '' | Estilos inline extras |
<!-- Padrão: alinhado à esquerda -->
<mad-form-actions>
<mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
</mad-form-actions>
<!-- Com botão de limpar -->
<mad-form-actions>
<mad-btn type="submit" variant="primary" icon="search">Buscar</mad-btn>
<mad-btn variant="ghost" icon="x-circle" mad:click="onLimpar">Limpar</mad-btn>
</mad-form-actions>
<!-- Alinhado à direita -->
<mad-form-actions align="right">
<mad-btn variant="ghost" close-drawer>Cancelar</mad-btn>
<mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
</mad-form-actions>
<mad-separator> — divisor visual
Linha horizontal entre seções. Usar antes de <mad-form-actions> ou entre <mad-form-section>s.
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
label | string | '' | Texto central (divisor com label) |
vertical | bool | false | Separador vertical (<span> em vez de <hr>) |
class | string | '' | Classes CSS extras |
<mad-separator />
<!-- Com label -->
<mad-separator label="ou" />
Exemplos completos
CRUD simples (drawer)
<mad-form submit="onSave">
<mad-form-section title="Dados da unidade" icon="building-2">
<mad-form-grid :cols="1">
<mad-input-field name="name" label="Nome" required />
</mad-form-grid>
</mad-form-section>
<mad-separator />
<mad-form-actions>
<mad-btn variant="primary" type="submit" icon="save">Salvar</mad-btn>
</mad-form-actions>
</mad-form>
Filtro de listagem
<mad-form submit="onReload">
<mad-form-section title="Filtros" icon="sliders-horizontal">
<mad-form-grid :cols="2">
<mad-input-field name="busca" label="Busca" placeholder="Nome ou código..." />
<mad-dbcombo-field name="status" label="Status"
model="Estado" display="nome" placeholder="Todos" />
</mad-form-grid>
<mad-form-actions>
<mad-btn perm-action="onReload" type="submit" variant="primary" icon="search">Buscar</mad-btn>
<mad-btn variant="ghost" icon="x-circle" mad:click="onLimpar">Limpar</mad-btn>
</mad-form-actions>
</mad-form-section>
</mad-form>
Formulário com imagem + campos
<mad-form submit="onSave">
<mad-form-section title="Foto" icon="image">
<mad-image-field name="foto" label="Foto do produto"
storage="disk" folder="uploads/fotos"
crop aspect-ratio="4:3" />
</mad-form-section>
<mad-separator />
<mad-form-section title="Dados" icon="package">
<mad-form-grid :cols="2">
<mad-input-field name="nome" label="Nome" required />
<mad-numeric-field name="valor" label="Valor" prefix="R$" />
</mad-form-grid>
<mad-form-grid :cols="1">
<mad-textarea-field name="descricao" label="Descrição" />
</mad-form-grid>
</mad-form-section>
<mad-separator />
<mad-form-actions>
<mad-btn perm-action="onSave" variant="primary" type="submit" icon="save">Salvar</mad-btn>
</mad-form-actions>
</mad-form>
Quando usar o quê
| Preciso... | Usar |
|---|---|
| Agrupar campos com título | <mad-form-section> |
| Campos lado a lado (1 a 6 colunas) | <mad-form-grid :cols="N"> |
| Campos empilhados, 100% da largura | <mad-form-stack> ou <mad-form-grid :cols="1"> |
| Divisor entre seções | <mad-separator /> |
| Botões de ação (salvar, buscar, limpar) | <mad-form-actions> |
| Mudar número de colunas no meio da seção | Dois <mad-form-grid> consecutivos |
NUNCA fazer
// ERRADO: div com style inline para botões
<div style="display:flex;gap:8px;margin-top:16px;">
<mad-btn type="submit" ...>Salvar</mad-btn>
</div>
// CERTO
<mad-form-actions>
<mad-btn type="submit" ...>Salvar</mad-btn>
</mad-form-actions>
// ERRADO: div com style inline para grid
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
<mad-input-field ... />
<mad-input-field ... />
</div>
// CERTO
<mad-form-grid :cols="2">
<mad-input-field ... />
<mad-input-field ... />
</mad-form-grid>
// ERRADO: <hr> para separar seções
<hr style="margin:16px 0;">
// CERTO
<mad-separator />
// ERRADO: form nativo
<form data-mad-submit="onSave">...</form>
// CERTO
<mad-form submit="onSave">...</mad-form>