O Manifesto WrapNative

O WrapNative não é um "construtor de apps genérico". É uma ferramenta de produtividade extrema para desenvolvedores que valorizam seu tempo.

Nós odiamos configurar Webpack, lutar contra o Gradle ou esperar 10 minutos para um build em React Native apenas para validar uma ideia simples. O WrapNative existe para eliminar esse atrito.

Filosofia Zero Config: Se você sabe HTML e JavaScript, você já sabe WrapNative. Nós cuidamos da "mágica chata" (PWA, Safe Areas, Gestos, Roteamento) para você focar na lógica de negócios.

Por que usar WrapNative?

O mercado está cheio de ferramentas que prometem "Zero Code" e entregam apps engessados, ou frameworks corporativos que exigem um time inteiro de engenharia.

Web Puro

HTML / JS

Rápido, mas a UX sofre. Falta a sensação de "peso", transições nativas e integração com o hardware.

Falta Polimento
Dev Utility

WrapNative

Delivers a ready-to-use native UX (Safe Areas, Haptics, Router). You just inject your code. Ideal for freelancers and MVPs

Maximum Productivity
Big Frameworks

Ionic / React Native

Excellent for large teams, but overkill for validating agile ideas or projects

Config Hell

File Structure

When exporting from the Builder, you receive a .zip file with the following production-optimized structure:

/project-name ├── css/ │ └── wrapnative.css # Estilos Core da Engine (Não edite / Do not edit) ├── js/ │ ├── app.js # Sua Lógica (Edite aqui) / Your Logic (Edit here) │ └── wrapnative.js # Engine Core (Não edite / Do not edit) ├── index.html # Estrutura HTML das telas / Screens HTML ├── manifest.json # Metadados PWA / PWA Metadata └── sw.js # Service Worker (Cache/Offline)

Roteamento Declarativo

O roteamento no WrapNative é baseado em atributos HTML. Não é necessário configurar arquivos de rotas JS complexos. A Engine varre o DOM e gerencia a visibilidade automaticamente.

1. Definindo Telas

<div id="home" data-wn-screen> <!-- Home Content --> </div> <!-- Telas secundárias começam ocultas --> <div id="explore" data-wn-screen class="wn-hidden"> ... </div>

2. Criando Links

Use data-wn-link em qualquer elemento para navegar. Suporta View Transitions API automaticamente.

<a href="#explore" data-wn-link>Ir para Explorar</a>

Sub-rotas & Navegação Profunda

No WrapNative, uma Sub-rota é qualquer tela que não possui um link direto na barra de navegação principal (Tabbar).

Quando o usuário clica em um link que leva a uma sub-rota, a Engine entende que é uma navegação profunda e automaticamente:

  • Adiciona a tela anterior à Pilha de Histórico.
  • Exibe o botão Voltar na Toolbar superior.
  • Habilita o gesto físico de "Voltar" (Android Back Button).

Exemplo de Estrutura

<!-- 1. Tela Principal (Na Tabbar) --> <div id="feed" data-wn-screen> <a href="#post-detail" data-wn-link>Ver Post</a> </div> <!-- 2. Sub-rota (Oculta por padrão) --> <!-- A engine mostrará o botão voltar aqui automaticamente --> <div id="post-detail" data-wn-screen class="wn-hidden"> <h1>Detalhes do Post</h1> <!-- Conteúdo --> </div>

Sistema de Toolbar

A Toolbar é dinâmica. Você controla o título e os botões da barra superior diretamente do HTML de cada tela, sem precisar escrever JS para manipular o DOM.

Definir Título

<div id="cart" data-wn-screen
data-wn-title="Carrinho">

Esconder Toolbar

<div id="story" data-wn-screen
data-wn-toolbar="hidden">

Injetar Ações (Botões)

Use um template com classe wn-actions dentro da tela para adicionar ícones à direita da toolbar.

<div id="docs" data-wn-screen> <template class="wn-actions"> <button id="btn-search"><i class="ph ph-magnifying-glass"></i></button> </template> </div>

Eventos & Escopo

Por padrão, o código no app.js roda dentro de um listener DOMContentLoaded. Isso cria um escopo local. Funções definidas lá não são visíveis para o onclick do HTML.

Opção 1: Declarativa (Window)

Exponha sua função ao objeto global. Rápido para prototipar.

// JS window.openCamera = async () => { ... }; // HTML <button onclick="openCamera()">Foto</button>

Opção 2: Estrita (Listener)

Use addEventListener. Mais limpo e seguro para produção.

// JS document.getElementById('btn').addEventListener('click', fn); // HTML <button id="btn">Foto</button>

Reatividade & Estado

O WrapNative segue a filosofia Zero Config. Porém, para quem precisa de mais dinamismo, oferecemos uma abstração leve sobre o Proxy nativo do JS.

Use WrapNative.state.reactive() para criar um objeto que atualiza automaticamente o HTML quando seus valores mudam.

const store = wrapnative.state.reactive({ count: 0, user: 'Guest' }); // HTML: <span data-bind="count">0</span> // JS: store.count++ (Updates automatically)

Async & Skeleton Loading

O WrapNative não usa middlewares complexos para dados assíncronos. Utilize o padrão try/catch/finally padrão do JavaScript junto com o estado reativo para criar experiências de carregamento fluidas.

O Padrão de Carregamento

  1. State: Create variables in the store (`isLoading`, `data`).
  2. Start: Set `isLoading = true` before the fetch.
  3. Await: Wait for the API/Database Promise.
  4. Finally: Set `isLoading = false` in the finally block to ensure the spinner disappears even with an error.

Visual (Skeleton UI)

Exemplo de Código (App.js)

//1. Store with state flags const store = wrapnative.state.reactive({ isLoading: false, hasData: false, userName: '' }); //2. Async Function window.loadingProfile = async () => { store.isLoading = true; store.hasData = false; try { //API Simulation await new Promise(r => setTimeout(r, 2000)); store.userName = "Jane Doe"; store.hasData = true; // Show content WN.bridge.haptic('light'); } catch (error) { WN.bridge.toast('Error loading'); } finally { store.isLoading = false; // Hidden Skeleton } };

Exemplo de Código (HTML)

Use as classes animate-pulse do Tailwind para criar o efeito de esqueleto.

<!-- Botão Trigger --> <button onclick="loadingProfile()">Load</button> <!-- 1. SKELETON (Appears if isLoading is true) --> <div data-if="isLoading" class="wn-hidden animate-pulse flex gap-3"> <div class="w-12 h-12 bg-gray-300 rounded-full"></div> <div class="flex-1 space-y-2"> <div class="h-4 bg-gray-300 rounded w-3/4"></div> <div class="h-4 bg-gray-300 rounded w-1/2"></div> </div> </div> <!-- 2. REAL CONTENT (Appears if hasData is true) --> <div data-if="hasData" class="wn-hidden flex gap-3 items-center"> <img src="avatar.jpg" class="w-12 h-12 rounded-full"> <h3 data-bind="userName" class="font-bold"></h3> </div>

Referência de Atributos (Data Props)

Lista completa de atributos especiais que controlam o comportamento da Engine WrapNative.

data-wn-screen

Define um contêiner como uma "Tela" gerenciável pelo Router.

<div id="home" data-wn-screen>...</div>

data-wn-link

Link de navegação SPA. Use com `href="#id"`.

<a href="#detalhes" data-wn-link>Ir</a>

data-wn-title="..."

Define o título da Toolbar quando a tela está ativa.

<div id="perfil" data-wn-screen data-wn-title="Meu Perfil">

Reatividade & Estado

data-if="key"

Renderização Condicional: Mostra o elemento apenas se o valor da chave na store for `true`. Remove a classe `.wn-hidden` automaticamente.

<!-- Store: { isLoading: true } --> <div data-if="isLoading" class="wn-hidden"> Carregando... </div>

data-bind="key"

Texto Dinâmico: Sincroniza o conteúdo de texto (`innerText`) com a store.

<!-- Store: { nome: 'Ana' } --> Olá, <span data-bind="nome"></span>

data-model="key"

Two-Way Binding: Liga o valor de um input à store e vice-versa.

<input type="text" data-model="nome" placeholder="Seu nome">

Pull to Refresh

Adicione data-wn-ptr na tela e ouça o evento:

document.addEventListener('wrapnative-refresh', () => { // ... fetch data ... wrapnative.ui.completePTR(); });

Modais & Swipe

O sistema de modais suporta o gesto de "Swipe-to-Dismiss" (arrastar para baixo para fechar), nativo em iOS.

// Open Modal by ID wrapnative.ui.openModal('myModal');
<div id="meuModal" class="wn-modal-overlay wn-hidden" onclick="if(event.target===this) nativify.ui.closeModal('meuModal')"> <div class="wn-modal-content"> <!-- Handle visual para indicar swipe --> <div class="w-12 h-1.5 bg-gray-300 rounded-full mx-auto mb-4"></div> <h2>Título do Modal</h2> <p>Conteúdo aqui...</p> </div> </div>

2. Controle via JS

// Abrir wrapnative.ui.openModal('meuModal'); // Fechar wrapnative.ui.closeModal('meuModal');

Diálogos & Alertas

Substitua o feio window.alert() por diálogos modernos, centralizados e responsivos com suporte a callbacks.

wrapnative.ui.alert({ title: 'Confirmar', message: 'Deseja excluir este item?', buttons: [ { text: 'Cancelar', role: 'cancel' }, { text: 'Sim', handler: () => deleteItem() } ] });

Smart PWA

A Engine detecta automaticamente o sistema operacional e apresenta o fluxo de instalação correto:

  • Android: Captura o evento beforeinstallprompt e mostra um banner nativo.
  • iOS: Exibe um Modal Tela Cheia com guia visual de instalação (Share -> Add to Home).