Skip to content

Telas — Interface Declarativa

A palavra-chave tela permite declarar interfaces de usuário diretamente no código Jade DSL, sem HTML, sem CSS, sem frameworks externos. Você descreve o que quer mostrar — a Jade DSL cuida do como.

Sintaxe básica

jd
tela NomeDaTela "Título Exibido"
  // elementos aqui
fim

Elementos disponíveis

ElementoDescrição
tabelaExibe registros em grade com filtros
formularioFormulário para criar ou editar registros
botaoAção clicável
toolbarBarra de ações agrupadas (vários botões)
cartaoExibe informações resumidas de um registro
modalDiálogo de confirmação ou exibição de conteúdo
graficoGráfico de dados (linhas, barras, pizza)
abasNavegação por abas dentro de uma tela
listaLista com swipe para ações rápidas (mobile)
acordeaoSeções expansíveis/colapsáveis
navegarBarra de navegação inferior (mobile-first)
gavetaMenu lateral deslizante (drawer)
loginTela de login com usuário, senha e lembrar-me
divisorLinha divisória horizontal entre elementos
buscaCampo de pesquisa standalone com debounce

DSL 100% em português

Jade DSL bloqueia termos em inglês em tempo de compilação. Use sempre os nomes em português:

  • cardcartao
  • clickclique
  • submitenviar
  • buttonbotao
  • tabletabela
  • formformulario
  • chartgrafico
  • tabsabas
  • listlista
  • swipedeslizar
  • accordionacordeao
  • sectionsecao
  • drawer / sidebargaveta
  • navbar / navigationnavegar
  • iconicone

Tabela

Exibe uma lista de entidades em formato de grade:

jd
entidade Produto
  id: id
  nome: texto
  preco: decimal
  estoque: numero
  ativo: booleano
fim

tela Produtos "Catálogo de Produtos"
  tabela ListaProdutos
    entidade: Produto
    colunas: nome, preco, estoque
    filtravel: verdadeiro
  fim
fim

Propriedades da tabela:

PropriedadeTipoObrigatórioDescrição
entidadenome da entidade✅ simQual entidade popular na tabela
colunaslista de camposnãoQuais campos exibir como colunas
filtravelverdadeiro/falsonãoMostrar campo de busca acima da tabela
ordenavelverdadeiro/falsonãoPermite ordenar clicando nos cabeçalhos das colunas
paginacaoverdadeiro/falso ou númeronãoverdadeiro = 20 por página; número = linhas por página
alturavalor CSSnãoAltura máxima da tabela com scroll interno (ex: "400px")
acoeslista de açõesnãoBotões de ação por linha: editar, excluir (ou ambos)

Ações por linha — CRUD automático

Adicione acoes: editar, excluir para gerar botões de edição e exclusão em cada linha da tabela — sem nenhum código adicional:

jd
tela TelaProdutos "Produtos"
  toolbar AcoesProdutos
    botao: "Novo Produto|novoProduto|mais|primario"
    botao: "Exportar|exportarProduto|compartilhar|secundario"
  fim
  tabela ListaProdutos
    entidade: Produto
    colunas: nome, preco, estoque
    filtravel: verdadeiro
    acoes: editar, excluir
  fim
fim

O que acontece automaticamente ao declarar acoes:

AçãoÍconeComportamento
editareditar (lápis)Abre modal com formulário preenchido com os dados da linha
excluirexcluir (lixeira)Exibe diálogo de confirmação nativo antes de deletar

Ao confirmar a exclusão ou salvar a edição, os dados são persistidos no IndexedDB e todas as tabelas, cartões e gráficos da tela são atualizados reativamente — sem recarregar a página.

Botões novoXxx e exportar* no toolbar

O runtime reconhece padrões nos nomes dos botões do toolbar:

  • novoXxx (ex: novoProduto) → abre modal de criação para a entidade Xxx
  • exportar* (ex: exportarProduto, exportarCSV) → gera download do CSV da entidade ativa

Esses padrões funcionam automaticamente sem declarar funções JADE — o runtime gerencia tudo.

Entidade obrigatória

O compilador exige entidade: em tabelas. Sem ela, o código não compila:

jd
// ❌ ERRO — tabela sem entidade
tela Dashboard "Painel"
  tabela MinhaTabela
    filtravel: verdadeiro
  fim
fim
// Erro: Elemento 'tabela' 'MinhaTabela' deve declarar 'entidade: NomeDaEntidade'

Formulário

Gera um formulário completo ligado a uma entidade:

jd
funcao salvarProduto()
  // lógica de salvamento
fim

tela CadastroProduto "Novo Produto"
  formulario FormProduto
    entidade: Produto
    campos: nome, preco, estoque
    enviar: salvarProduto
  fim
fim

Propriedades do formulário:

PropriedadeTipoObrigatórioDescrição
entidadenome da entidade✅ simQual entidade o formulário edita
camposlista de camposnãoCampos que aparecem no form
enviarnome de funçãonãoFunção disparada ao submeter o formulário (Enter ou submit nativo)

enviar vs botao

enviar: responde ao submit nativo do formulário (tecla Enter). Para um botão visível de "Salvar", declare um botao separado com acao: apontando para a mesma função.

Campos com senha

O tipo senha renderiza um input[type=password] (conteúdo ocultado):

jd
tela AlterarSenha "Alterar Senha"
  formulario FormSenha
    entidade: Usuario
    campos: senhaAtual, novaSenha, confirmaSenha
    enviar: alterarSenha
  fim
fim

Login

O elemento login gera uma tela de autenticação completa com campos de usuário, senha e checkbox "lembrar-me". Não requer entidade — é dedicado ao fluxo de autenticação.

jd
tela TelaLogin "Entrar"
  login FormLogin
    enviar: fazerLogin
    titulo: "Acesse sua conta"
  fim
fim

Propriedades do login:

PropriedadeTipoObrigatórioDescrição
enviarnome de funçãonãoFunção disparada ao submeter. Padrão: login
titulotextonãoSubtítulo exibido no card de login

A função fazerLogin recebe as credenciais no detail do evento (não no store) e deve comunicar sucesso ou erro via ui.emitirResultadoAcao. Veja Autenticação para o fluxo completo.


Botão

Dispara uma ação ao ser clicado:

jd
funcao salvarProduto()
  // lógica de salvamento
fim

funcao voltar()
  // lógica de navegação
fim

tela CadastroProduto "Novo Produto"
  formulario FormProduto
    entidade: Produto
    campos: nome, preco, estoque
  fim
  botao Salvar
    acao: salvarProduto
  fim
  botao Cancelar
    clique: voltar
  fim
fim

Propriedades do botão:

PropriedadeTipoDescrição
acaonome de funçãoFunção chamada ao clicar
cliquenome de funçãoAlias para acao
iconenome do catálogo SVGÍcone exibido à esquerda do texto (veja catálogo completo)
tipoprimario, secundario, perigo ou sucessoVariante visual do botão (padrão: primario)

Variantes visuais — comparativo

jd
funcao salvar()
fim
funcao cancelar()
fim
funcao excluir()
fim
funcao confirmar()
fim

tela ExemplosBotoes "Variantes de Botão"
  botao BotaoPrimario
    tipo: primario      // fundo azul sólido — ação principal
    acao: salvar
    icone: salvar
  fim
  botao BotaoSecundario
    tipo: secundario    // só borda, fundo transparente — ação secundária
    acao: cancelar
    icone: fechar
  fim
  botao BotaoPerigo
    tipo: perigo        // fundo vermelho — ação destrutiva
    acao: excluir
    icone: excluir
  fim
  botao BotaoSucesso
    tipo: sucesso       // fundo verde — confirmação
    acao: confirmar
    icone: sucesso_icone
  fim
fim
tipo:VisualQuando usar
primarioFundo azul + texto branco (padrão)Ação principal da tela (salvar, criar)
secundarioSó borda, fundo transparenteAção secundária (cancelar, exportar)
perigoFundo vermelho + texto brancoAção destrutiva (excluir, desativar)
sucessoFundo verde + texto brancoConfirmação positiva (aprovar, confirmar)

Hierarquia visual

Use primario para a ação mais importante da tela e secundario para as demais. Isso cria hierarquia — o usuário sabe imediatamente qual botão é o principal. Evite ter dois botões primario na mesma tela.

Estado de carregamento automático

Ao clicar, o botão é desabilitado imediatamente e exibe um spinner giratório — prevenindo duplo clique acidental. Ele volta ao normal automaticamente quando a função JADE termina de executar.

Ação obrigatória

Todo botao deve ter acao: ou clique: — e a função referenciada deve estar declarada:

jd
// ❌ ERRO — botao sem acao
tela Dashboard "Painel"
  botao Salvar
    icone: "💾"
  fim
fim
// Erro: Botão 'Salvar' deve declarar 'acao: nomeDaFuncao' ou 'clique: nomeDaFuncao'

// ❌ ERRO — função não declarada
tela Dashboard "Painel"
  botao Salvar
    acao: funcaoInexistente
  fim
fim
// Erro: Função 'funcaoInexistente' não declarada

Toolbar

Agrupa vários botões de ação em uma barra horizontal. Ideal para ações de CRUD no topo de tabelas ou formulários.

jd
funcao criarProduto()
fim

funcao exportarCSV()
fim

funcao abrirFiltros()
fim

tela TelaProdutos "Produtos"
  toolbar AcoesProdutos
    botao: "Novo Produto|criarProduto|mais"
    botao: "Exportar CSV|exportarCSV|compartilhar|secundario"
    botao: "Filtros|abrirFiltros|busca|secundario"
  fim
  tabela ListaProdutos
    entidade: Produto
    colunas: nome, preco, estoque
    filtravel: verdadeiro
  fim
fim

Formato de cada botao: no toolbar:

"Label|acao|icone?|tipo?"
PosiçãoDescriçãoExemplo
LabelTexto exibido no botão"Novo Produto"
acaoNome da função a chamar (obrigatório)"criarProduto"
iconeÍcone SVG do catálogo (opcional)"mais"
tipoVariante visual (opcional, padrão: primario)"secundario"

Toolbar vs. Botões soltos

Use toolbar quando tiver 2+ ações relacionadas à mesma entidade/tela. Para uma ação isolada, use botao diretamente.


Divisor

Linha divisória horizontal para separar seções visuais dentro de uma tela. Pode ter um rótulo opcional centralizado.

jd
tela Dashboard "Painel"
  cartao TotalVendas
    titulo: "Total de Vendas"
    conteudo: soma(Venda.total)
  fim
  divisor LinhaMetricas
  fim
  grafico GraficoMensal
    tipo: barras
    entidade: Venda
    eixoX: mes
    eixoY: total
  fim
fim

Com rótulo:

jd
tela Config "Configurações"
  divisor SecaoSeguranca
    rotulo: "Segurança"
  fim
  formulario FormSenha
    entidade: Usuario
    campos: senhaAtual, novaSenha
    enviar: alterarSenha
  fim
fim

Propriedades do divisor:

PropriedadeTipoObrigatórioDescrição
rotulotextonãoTexto centralizado sobre a linha divisória

Busca

Campo de pesquisa independente (não ligado a uma tabela). Ideal para filtrar conteúdo customizado ou acionar buscas no servidor.

jd
funcao buscarProduto()
  Console.escrever("buscando...")
fim

tela Catalogo "Catálogo"
  busca CampoBusca
    acao: buscarProduto
    placeholder: "Buscar por nome ou código..."
  fim
  tabela ListaProdutos
    entidade: Produto
    colunas: nome, codigo
  fim
fim

Propriedades da busca:

PropriedadeTipoObrigatórioDescrição
acaonome de funçãonãoFunção chamada ao buscar
placeholdertextonãoTexto de dica no input (padrão: "Buscar...")
modoidentificadornãotempo-real = dispara a cada tecla com debounce de 300ms; padrão = só ao pressionar Enter/botão

Recebendo a query

A função declarada em acao: recebe automaticamente o texto digitado como parâmetro:

jd
funcao buscarProduto(dados: objeto)
  termo = dados.query
  // filtre e atualize a lista com base no termo
fim

Busca vs. tabela filtrável

Use busca quando precisar de controle total sobre o que acontece com a query (busca no servidor, filtros complexos). Para filtrar uma tabela local, prefira filtravel: verdadeiro na própria tabela — é mais simples e automático.


Cartão

Exibe métricas e resumos calculados diretamente das entidades — sem hardcode.

jd
entidade Venda
  id: id
  clienteNome: texto
  total: moeda
  criadaEm: data
fim

entidade Produto
  id: id
  nome: texto
  preco: moeda
  estoque: numero
fim

tela Dashboard "Painel"
  cartao TotalVendas
    titulo: "Total de Vendas"
    conteudo: soma(Venda.total)
    variante: sucesso
  fim
  cartao TotalProdutos
    titulo: "Produtos Cadastrados"
    conteudo: contagem(Produto)
    variante: info
  fim
  cartao TicketMedio
    titulo: "Ticket Médio"
    conteudo: media(Venda.total)
    variante: aviso
  fim
fim

Os cartões são reativos: sempre que um registro é criado, editado ou excluído via CRUD, os valores são recalculados e a tela atualiza instantaneamente — sem reload.

Propriedades do cartão:

PropriedadeTipoObrigatórioDescrição
titulotextonãoTítulo exibido no cabeçalho (padrão: nome do elemento)
conteudotexto literal ou agregaçãonãoValor ou cálculo sobre uma entidade
varianteprimario, sucesso, aviso, info, perigonãoEstilo visual semântico do cartão

Agregações disponíveis

FunçãoDescriçãoExemplo
soma(Entidade.campo)Soma todos os valores de um camposoma(Venda.total)
contagem(Entidade)Conta o total de registroscontagem(Produto)
media(Entidade.campo)Média aritmética de um campomedia(Venda.total)
maximo(Entidade.campo)Maior valor de um campomaximo(Produto.preco)
minimo(Entidade.campo)Menor valor de um campominimo(Produto.estoque)

Formatação automática

Campos do tipo moeda são formatados automaticamente como BRL (R$ 1.234,56). Campos numéricos inteiros usam separador de milhar (1.234).

Texto estático ainda é válido

Para mensagens fixas ou textos que não dependem de dados:

jd
cartao Versao
  titulo: "Versão"
  conteudo: "2.1.0"
  variante: info
fim

Diálogo de confirmação ou exibição de informações:

jd
tela GerenciamentoProdutos "Produtos"
  modal ConfirmarExclusao
    titulo: "Confirmar exclusão"
    mensagem: "Deseja excluir este produto? Esta ação não pode ser desfeita."
    variante: perigo
  fim
fim

Propriedades do modal:

PropriedadeTipoDescrição
titulotextoCabeçalho do modal
mensagemtextoCorpo do modal
varianteinfo, alerta ou perigoEstilo visual do cabeçalho (padrão: info)

Abrindo o modal por código

O modal é oculto por padrão. Para abri-lo, declare uma função JADE que chama ui.abrirModal:

jd
funcao confirmarExclusao()
  ui.abrirModal("ConfirmarExclusao")
fim

Gráfico

Visualização de dados em formato de gráfico:

jd
entidade Venda
  id: id
  data: data
  valor: decimal
fim

tela Dashboard "Painel de Vendas"
  grafico GraficoVendas
    tipo: linha
    entidade: Venda
    eixoX: data
    eixoY: valor
  fim
fim

Propriedades do gráfico:

PropriedadeTipoObrigatórioValores possíveis
tipoidentificadornãolinha, barras, pizza
entidadenome da entidade✅ simFonte dos dados
eixoXcamponãoCampo para o eixo X
eixoYcamponãoCampo para o eixo Y

Gráficos são reativos

Os gráficos re-renderizam automaticamente sempre que os dados da entidade mudam (CRUD, nova importação, atualização de seed). Nenhuma configuração extra necessária.

Tipo de gráfico restrito

O compilador aceita apenas linha, barras ou pizza. Termos em inglês (bar, pie, line) são rejeitados:

jd
// ❌ ERRO — tipo inválido (em inglês)
// grafico GraficoVendas
//   entidade: Venda
//   tipo: bar   <- use "barras" em português
// Erro: Tipo de gráfico 'bar' inválido. Use: linha, barras ou pizza

Tooltips nativos

Ao passar o mouse sobre barras, pontos de linha ou fatias de pizza, o browser exibe automaticamente o rótulo e o valor via tooltip nativo (<title> SVG) — sem JavaScript extra.


Abas

Navegação por abas dentro de uma tela. Ao trocar de aba, o evento jade:aba é despachado com o nome da aba e a referência do container — o app preenche o conteúdo via handler.

jd
tela DetalhePedido "Pedido #1042"
  abas NavPedido
    aba: Resumo
    aba: Itens
    aba: Histórico
  fim
fim

Propriedades das abas:

PropriedadeTipoObrigatórioDescrição
abatexto✅ sim (1+)Nome de cada aba (repetir uma por linha)

Preenchendo o conteúdo

Declare funções JADE para cada aba e nomeie-as igual ao rótulo da aba — o runtime chama automaticamente a função correspondente ao trocar de aba:

jd
funcao abaItens()
  // lógica de carregamento dos itens do pedido
fim

funcao abaHistorico()
  // lógica de carregamento do histórico
fim

Aba obrigatória

jd
// ❌ ERRO — abas sem nenhuma aba declarada
tela Detalhe "Detalhe"
  abas Nav
  fim
fim
// Erro: Elemento 'abas' 'Nav' deve declarar pelo menos uma aba com 'aba: NomeDaAba'

Lista

Lista otimizada para mobile com suporte a swipe para revelar ações rápidas (excluir, editar etc.). Em desktop, as ações são acessíveis via drag do mouse.

jd
entidade Pedido
  id: id
  descricao: texto
  status: texto
  valor: decimal
fim

tela Pedidos "Meus Pedidos"
  tabela ListaPedidos
    entidade: Pedido
    colunas: descricao, status, valor
  fim
fim

Propriedades da lista:

PropriedadeTipoObrigatórioDescrição
entidadenome da entidade✅ simFonte dos dados
camponome do camponãoCampo exibido como texto principal (padrão: primeiro campo)
subcamponome do camponãoCampo exibido como subtítulo
deslizarlista de açõesnãoAções reveladas ao deslizar: excluir, editar ou nome customizado

Respondendo às ações de swipe

Declare funções JADE com o mesmo nome das ações — elas são chamadas automaticamente:

jd
funcao excluir(itemId: id)
  produto = EntityManager.buscarPorId(Pedido, itemId)
  produto.ativo = falso
  salvar produto
fim

funcao editar(itemId: id)
  ui.abrirModal("FormEdicao")
fim

Entidade obrigatória

jd
// ❌ ERRO — lista sem entidade
tela Pedidos "Pedidos"
  lista ListaPedidos
    campo: descricao
  fim
fim
// Erro: Elemento 'lista' 'ListaPedidos' deve declarar 'entidade: NomeDaEntidade'

Acordeão

Seções expansíveis e colapsáveis — apenas uma aberta por vez. Ao expandir uma seção, o evento jade:acordeao é despachado para que o app preencha o conteúdo.

jd
tela AjudaApp "Central de Ajuda"
  acordeao Duvidas
    secao: "Como cancelar meu pedido?"
    secao: "Prazo de entrega"
    secao: "Formas de pagamento"
    secao: "Trocas e devoluções"
  fim
fim

Propriedades do acordeão:

PropriedadeTipoObrigatórioDescrição
secaotexto✅ sim (1+)Título de cada seção (repetir uma por linha)

Preenchendo o conteúdo de cada seção

Declare funções JADE com o conteúdo de cada seção — o runtime chama a função correspondente ao expandir:

jd
funcao secaoCancelarPedido()
  // retorna o conteúdo da seção
fim

Seção obrigatória

jd
// ❌ ERRO — acordeao sem nenhuma seção
tela Ajuda "Ajuda"
  acordeao FAQ
  fim
fim
// Erro: Elemento 'acordeao' 'FAQ' deve declarar pelo menos uma seção com 'secao: TítuloDaSeção'

Tela completa — exemplo real

CRUD completo de produtos com listagem reativa, ações por linha, criação via modal e exportação CSV — em ~15 linhas de DSL:

jd
entidade Produto
  id: id
  nome: texto
  preco: moeda
  estoque: numero
  estoqueMinimo: numero
  ativo: booleano
fim

tela TelaProdutos "Produtos"
  toolbar AcoesProdutos
    botao: "Novo Produto|novoProduto|mais|primario"
    botao: "Exportar CSV|exportarProduto|compartilhar|secundario"
  fim
  tabela ListaProdutos
    entidade: Produto
    colunas: nome, preco, estoque, estoqueMinimo, ativo
    filtravel: verdadeiro
    ordenavel: verdadeiro
    paginacao: 20
    acoes: editar, excluir
  fim
fim

O que você ganha sem escrever mais nenhum código:

FeatureComo acionar
Modal de criaçãoClicar em "Novo Produto"
Modal de ediçãoClicar no ícone editar (lápis) da linha
Confirmação de exclusãoClicar no ícone excluir (lixeira) da linha
Busca em tempo realCampo de busca acima da tabela
Busca no headerAutomática quando a tela tem filtravel: verdadeiro
Download CSVClicar em "Exportar CSV"
Cartões/gráficos atualizadosAutomático após qualquer CRUD

Dashboard + dados reativos

jd
tela Dashboard "Painel"
  cartao TotalVendas
    titulo: "Total de Vendas"
    conteudo: soma(Venda.total)
    variante: sucesso
  fim
  cartao TicketMedio
    titulo: "Ticket Médio"
    conteudo: media(Venda.total)
    variante: aviso
  fim
  grafico VendasMes
    tipo: barras
    entidade: Venda
    eixoX: criadaEm
    eixoY: total
  fim
  grafico DistribuicaoStatus
    tipo: pizza
    entidade: Venda
    eixoX: status
    eixoY: total
  fim
fim

Toda vez que uma venda é criada ou excluída em outra tela, ao voltar para o Dashboard os cartões e gráficos já mostram os valores atualizados.


Validações em tempo de compilação

O compilador Jade DSL verifica telas rigorosamente antes de gerar código:

jd
// ❌ ERRO — termo em inglês
tela Dashboard "Painel"
  card InfoVendas
    titulo: "Resumo"
  fim
fim
// Erro: Termo 'card' não é válido na DSL Jade — use 'cartao' (português)

// ❌ ERRO — botao sem acao
tela Dashboard "Painel"
  botao Salvar
    icone: "💾"
  fim
fim
// Erro: Botão 'Salvar' deve declarar 'acao: nomeDaFuncao' ou 'clique: nomeDaFuncao'

// ❌ ERRO — tabela sem entidade
tela Dashboard "Painel"
  tabela ListaItens
    filtravel: verdadeiro
  fim
fim
// Erro: Elemento 'tabela' 'ListaItens' deve declarar 'entidade: NomeDaEntidade'

// ❌ ERRO — entidade inexistente
tela Dashboard "Painel"
  tabela ListaVendas
    entidade: VendaNaoDeclarada
  fim
fim
// Erro: Entidade 'VendaNaoDeclarada' não declarada ou não encontrada

// ❌ ERRO — campo inexistente na entidade
entidade Produto
  id: id
  nome: texto
fim

tela Dashboard "Painel"
  tabela ListaProdutos
    entidade: Produto
    campos: nome, preco    // 'preco' não existe em Produto
  fim
fim
// Erro: Campo 'preco' não existe na entidade 'Produto'

Busca global no header

Quando a tela ativa contém uma tabela com filtravel: verdadeiro, o runtime exibe automaticamente um campo de busca centralizado no header da aplicação. O campo filtra a tabela em tempo real com debounce de 200ms — nenhuma configuração necessária.

jd
tela TelaProdutos "Produtos"
  tabela ListaProdutos
    entidade: Produto
    colunas: nome, preco, estoque
    filtravel: verdadeiro   // ← ativa a busca no header automaticamente
    acoes: editar, excluir
  fim
fim

O campo de busca aparece apenas quando a tela tem tabela filtrável e some automaticamente ao navegar para uma tela sem tabela.


Notificações

O runtime exibe notificações como um banner que desliza do topo e empurra o conteúdo para baixo — sem cobrir a interface. Desaparecem automaticamente após 4 segundos.

VarianteCorQuando usar
sucessoVerdeOperação concluída com êxito
erroVermelhoFalha ou dado inválido
avisoAmareloAtenção requerida
infoAzulInformação neutra

As notificações são disparadas automaticamente pelo runtime nas operações CRUD (criado com sucesso, atualizado, excluído) e podem ser emitidas manualmente via JADE:

jd
funcao salvarProduto()
  // lógica de salvamento...
  ui.notificar("Produto salvo com sucesso", "sucesso")
fim

Exibe uma barra de navegação fixa no rodapé da tela — o padrão de navegação principal em apps mobile. Persiste entre trocas de tela.

jd
tela AppPrincipal "Início"
  navegar MenuPrincipal
    aba: "Inicio|casa|TelaInicio"
    aba: "Produtos|caixa|TelaProdutos"
    aba: "Relatorios|grafico|TelaRelatorios"
    aba: "Perfil|usuario|TelaPerfil"
  fim
fim

Formato de cada aba: Label|icone|NomeDaTela (ícone é opcional: Label||NomeDaTela)

Persistência automática

O navegar é criado uma única vez e fica visível enquanto o app roda. Ao trocar de tela, apenas a aba ativa é atualizada — o elemento não é recriado.

Desktop

No desktop (≥ 640px), a barra inferior é automaticamente ocultada. A navegação por gaveta é mais adequada para telas maiores.


gaveta — menu lateral deslizante

Menu que desliza da esquerda ao clicar no ícone de menu (hambúrguer). Ideal para apps com muitas seções ou em desktop.

jd
tela AppPrincipal "Painel"
  gaveta MenuAdmin
    item: "Dashboard|grafico|TelaDashboard"
    item: "Produtos|caixa|TelaProdutos"
    item: "Clientes|usuarios|TelaClientes"
    item: "Configuracoes|configuracoes|TelaConfig"
    item: "Sair|sair|acao:fazerLogout"
  fim
fim

Formato de item: Label|icone|NomeDaTela para navegação, ou Label|icone|acao:nomeDaFuncao para chamar uma função.

Propriedades do item:

FormatoResultado
Label|icone|TelaNomeNavega para a tela declarada
Label|icone|acao:funcaoChama a função via jade:acao
separadorLinha divisória visual

Header fixo e hambúrguer automáticos

O runtime gera automaticamente um header fixo no topo da aplicação com o nome do app e o botão hambúrguer. No mobile, o hambúrguer abre a gaveta como drawer overlay. No desktop, ele colapsa/expande a sidebar. Nenhuma configuração extra necessária.


Ícones SVG — catálogo em português

JADE vem com 38 ícones SVG vetoriais embutidos — nenhuma dependência externa, nenhum emoji, zero bytes extras no bundle.

Todos os ícones herdam cor e tamanho do elemento pai via currentColor. Use o nome em português na propriedade icone: de qualquer botao, toolbar, navegar ou gaveta.

Autocomplete no VS Code

A extensão Jade DSL sugere automaticamente os nomes do catálogo ao digitar icone:. Digite o início do nome e pressione Ctrl+Space para ver as opções.

Catálogo disponível

NomeUso típicoNomeUso típico
casaHome / iníciousuarioUsuário / perfil
usuariosGrupo / clientesgraficoDashboard / relatório
relatorioDocumento / relatóriotabela_iconeTabela / lista
caixaEstoque / produtocarrinhoCarrinho / pedido
dinheiroFinanceiro / preçocartao_creditoPagamento
editarEditar / modificarexcluirRemover / deletar
salvarSalvar / confirmarcopiarDuplicar / copiar
maisAdicionar / novomenosRemover / colapsar
buscaPesquisar / filtrarnotificacaoAlerta / notificação
configuracoesConfigurações / ajustescadeadoSegurança / acesso
sairLogout / encerrarvoltarVoltar / anterior
proximoAvançar / próximofecharFechar / cancelar
menuMenu hambúrguercalendarioData / agendamento
relogioHora / duraçãolocalizacaoEndereço / mapa
telefoneContato / ligaçãoemailE-mail / mensagem
compartilharCompartilhar / enviaratualizarRecarregar / sincronizar
pastaPasta / categoriaimagemFoto / imagem
estrelaFavorito / destaquefavoritoCurtir / coração
infoInformaçãoavisoAlerta / cuidado
sucesso_iconeConfirmado / okerro_iconeErro / problema
etiquetaTag / categoriachaveAutenticação / API key
jd
// Ícones em botões
tela CadastroProduto "Novo Produto"
  botao PersistirProduto
    acao: salvarProduto
    icone: disco
  fim
  botao ExcluirProduto
    acao: excluirProduto
    tipo: perigo
    icone: lixo
  fim
fim

// Ícones em navegar
tela AppPrincipal "Início"
  navegar MenuPrincipal
    aba: "Inicio|casa|TelaInicio"
    aba: "Clientes|usuarios|TelaClientes"
    aba: "Financeiro|dinheiro|TelaFinanceiro"
  fim
fim

// Ícones em gaveta
tela AppAdmin "Painel"
  gaveta MenuLateral
    item: "Configuracoes|configuracoes|TelaConfig"
    item: "Sair|sair|acao:logout"
  fim
fim

Ícone não encontrado?

Se o nome do ícone não existir no catálogo, o runtime simplesmente não exibe nenhum ícone — sem erro, sem quebra. O nome de ação é abreviado para 3 letras como fallback na lista com swipe.


Como a Jade DSL renderiza as telas

Jade DSL não gera HTML diretamente. Em vez disso, a declaração tela é interpretada pelo UIEngine do runtime Jade DSL, que:

  1. Lê a estrutura da tela declarada no código
  2. Gera os componentes HTML correspondentes
  3. Liga automaticamente os dados da entidade aos campos
  4. Gerencia eventos de clique e envio de formulários

Isso significa que você nunca escreve <input>, <table> ou event listeners manualmente.

Propriedades desconhecidas

Se uma propriedade declarada não for reconhecida pelo elemento, o runtime emite um aviso no console do browser:

[JADE] tabela 'ListaProdutos': propriedade desconhecida 'cor' — será ignorada.

Isso facilita identificar erros de digitação em propriedades sem quebrar a aplicação.


Próximo passo

Padrões de Design

Feito com ❤️ para desenvolvedores brasileiros.