WebInk — introdução
WebInk é o framework de frontend web do NeoObjectPascal — o análogo web do TerminalInk. Com uses webink; você constrói uma interface web profissional em código NeoObjectPascal, estilizada com Tailwind CSS e com gráficos via Chart.js, e navega entre telas com URLs reais.
Diferente de um gerador estático, o WebInk é um app vivo: render(...) sobe um servidor local e abre o navegador. O estado vive nas variáveis; a cada interação (clique, digitação, envio) um callback roda no servidor, muda o estado e a tela é redesenhada — uma UI dirigida pelo servidor, exatamente como o loop reativo do TerminalInk, mas na web.
TerminalInk e WebInk não se misturam
Um programa é totalmente TerminalInk ou totalmente WebInk. Usar uses terminalink e uses webink no mesmo programa gera um erro claro.
Primeiro app
uses webink;
var cliques: Integer;
function registrar(): Boolean
begin
cliques := cliques + 1;
return true;
end;
function home(): Object
begin
return Page(#{}, [
Navbar(#{}, [
Heading(#{ level: 3 }, "Acme Inc."),
Link(#{ href: "/relatorio" }, "Relatório")
]),
Container(#{ className: "py-8 space-y-6" }, [
Heading(#{ level: 1 }, "Painel"),
Grid(#{ cols: 3 }, [
StatCard(#{ label: "Receita", value: "R$ 128k", delta: "+12%" }),
StatCard(#{ label: "Usuários", value: "3.420" }),
StatCard(#{ label: "Cliques", value: cliques })
]),
Card(#{}, [
Heading(#{ level: 4 }, "Vendas por mês"),
Chart(#{ type: "line", data: #{
labels: ["Jan", "Fev", "Mar", "Abr"],
datasets: [ #{ label: "R$ mil", data: [30, 45, 38, 52] } ]
} })
]),
Button(#{ onClick: registrar }, "Registrar clique")
])
]);
end;
begin
cliques := 0;
render(#{ "/": home });
end.Rode e o navegador abre com o painel; clicar no botão incrementa o contador ao vivo.
Como funciona
render(rotas)inicia um servidor HTTP local single-thread e abre o navegador.- O navegador carrega um shell com Tailwind + Chart.js (embutidos, offline) e um runtime JS pequeno.
- O runtime pede ao servidor a tela da rota atual; o servidor chama a função de build, gera o HTML e devolve.
- Numa interação, o runtime envia o evento ao servidor, que chama o callback NeoObjectPascal, atualiza o estado, redesenha a tela e devolve o novo HTML.
O estado vive em variáveis globais, como no TerminalInk. Os callbacks mudam o estado; a função da tela atual relê e redesenha.
Estado e eventos
Widgets interativos recebem callbacks por props: onClick, onChange, onSubmit. O callback é uma função que muda o estado e retorna:
var nome: String;
function onNome(v): Boolean
begin
nome := v;
return true;
end;
// ...
TextInput(#{ placeholder: "Seu nome", value: nome, onChange: onNome })Props e palavras reservadas
class e to são palavras reservadas — por isso os widgets usam className (estilo React) e href (no Link). Qualquer outra chave "reservada" pode ser passada como string: #{ "class": "..." }.
Rodar, buildar e depurar
- Rodar:
java -jar neoobjectpascal.jar app.npassobe o servidor e abre o navegador; encerra com Ctrl+C. No VS Code, use Run. - Buildar nativo:
--buildempacota o app (com os assets embutidos) — o executável autocontido sobe o servidor e abre o navegador, offline. Veja Gerar executáveis nativos. - Depurar: WebInk tem a melhor experiência de debug. O servidor é single-thread e o navegador é apenas um cliente — sem a janela Swing do terminal. Ponha um breakpoint numa função de tela ou num callback: ele dispara quando você interage no navegador, a pausa é determinística e o Step Into (F7) entra nas suas funções normalmente. Veja Debugger, VS Code e nuvem.
Próximos passos
Conheça os componentes do WebInk — layout, tipografia, formulários, tabelas, gráficos Chart.js e navegação com rotas.