O Manifesto WrapNative
The WrapNative Manifesto
O WrapNative não é um "construtor de apps genérico". É uma ferramenta de produtividade extrema para desenvolvedores que valorizam seu tempo.
WrapNative is not a "generic app builder". It is an extreme productivity tool for developers who value their time.
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.
We hate configuring Webpack, fighting Gradle, or waiting 10 minutes for a React Native build just to validate a simple idea. WrapNative exists to eliminate this friction.
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.
Zero Config Philosophy: If you know HTML and JavaScript, you already know WrapNative. We handle the "boring magic" (PWA, Safe Areas, Gestures, Routing) so you can focus on business logic.
Por que usar WrapNative?Why use 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.
The market is full of "Zero Code" tools that deliver rigid apps, or enterprise frameworks that require a whole engineering team.
Web Puro
Pure Web
HTML / JS
Rápido, mas a UX sofre. Falta a sensação de "peso", transições nativas e integração com o hardware.
Fast, but the UX suffers. It lacks a sense of "weight," native transitions, and hardware integration.
Falta Polimento
Lack of polish
Utilitário Dev
Dev Utility
WrapNative
Entrega a UX nativa (Safe Areas, Haptics, Router) pronta. Você só injeta seu código. Ideal para Freelancers e MVPs.
Delivers a ready-to-use native UX (Safe Areas, Haptics, Router). You just inject your code. Ideal for freelancers and MVPs
Produtividade Máxima
Maximum Productivity
Big Frameworks
Grandes Frameworks
Ionic / React Native
Excelentes para grandes times, mas overkill para validar ideias ou projetos ágeis.
Excellent for large teams, but overkill for validating agile ideas or projects
Config Hell
Estrutura de Arquivos
File Structure
Ao exportar seu projeto do Builder, você receberá um arquivo .zip com a seguinte estrutura otimizada para produção:
When exporting from the Builder, you receive a .zip file with the following production-optimized structure:
/project-name
├── css/
│ └── wrapnative.css
├── js/
│ ├── app.js
│ └── wrapnative.js
├── index.html
├── manifest.json
└── sw.js
Roteamento DeclarativoDeclarative Routing
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.
Routing in WrapNative is based on HTML attributes. No complex JS route files needed. The Engine scans the DOM and manages visibility automatically.
1. Definindo Telas1. Defining Screens
<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 Links2. Creating Links
Use data-wn-link em qualquer elemento para navegar. Suporta View Transitions API automaticamente.
Use data-wn-link on any element to navigate. Supports View Transitions API automatically.
<a href="#explore" data-wn-link>Ir para Explorar</a>
Sub-rotas & Navegação ProfundaSub-routes & Deep Navigation
No WrapNative, uma Sub-rota é qualquer tela que não possui um link direto na barra de navegação principal (Tabbar).
In WrapNative, a Sub-route is any screen that does not have a direct link in the main navigation bar (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:
When the user clicks a link leading to a sub-route, the Engine treats it as deep navigation and automatically:
-
Adiciona a tela anterior à Pilha de Histórico.
Adds the previous screen to the History Stack.
-
Exibe o botão Voltar na Toolbar superior.
Displays the Back button in the top Toolbar.
-
Habilita o gesto físico de "Voltar" (Android Back Button).
Enables the physical "Back" gesture (Android Back Button).
Exemplo de EstruturaStructure Example
<div id="feed" data-wn-screen>
<a href="#post-detail" data-wn-link>Ver Post</a>
</div>
<div id="post-detail" data-wn-screen class="wn-hidden">
<h1>Detalhes do Post</h1>
<!-- Conteúdo -->
</div>
Eventos & EscopoEvents & Scope
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.
By default, app.js runs inside a DOMContentLoaded listener. This creates a local scope. Functions defined there are not visible to HTML onclick attributes.
Opção 1: Declarativa (Window)Option 1: Declarative (Window)
Exponha sua função ao objeto global. Rápido para prototipar.
Expose function to global window object. Fast for prototyping.
window.openCamera = async () => { ... };
<button onclick="openCamera()">Foto</button>
Opção 2: Estrita (Listener)Option 2: Strict (Listener)
Use addEventListener. Mais limpo e seguro para produção.
Use addEventListener. Cleaner and safer for production.
document.getElementById('btn').addEventListener('click', fn);
<button id="btn">Foto</button>
Reatividade & EstadoReactivity & State
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.
WrapNative follows the Zero Config philosophy. However, for more dynamism, we offer a lightweight abstraction over JS native Proxy.
Use WrapNative.state.reactive() para criar um objeto que atualiza automaticamente o HTML quando seus valores mudam.
Use WrapNative.state.reactive() to create an object that automatically updates HTML when values change.
const store = wrapnative.state.reactive({
count: 0,
user: 'Guest'
});
Async & Skeleton LoadingAsync & 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.
WrapNative does not use complex middlewares for async data. Use standard JavaScript try/catch/finally patterns along with reactive state to create fluid loading experiences.
O Padrão de CarregamentoThe Loading Pattern
- State: Create variables in the store (`isLoading`, `data`).
- Start: Set `isLoading = true` before the fetch.
- Await: Wait for the API/Database Promise.
- Finally: Set `isLoading = false` in the finally block to ensure the spinner disappears even with an error.
- Estado: Crie variáveis na store (`isLoading`, `data`).
- Início: Set `isLoading = true` antes do fetch.
- Await: Aguarde a Promise da API/Banco.
- Finally: Set `isLoading = false` no bloco finally para garantir que o spinner suma mesmo com erro.
Exemplo de Código (App.js)
const store = wrapnative.state.reactive({
isLoading: false,
hasData: false,
userName: ''
});
window.loadingProfile = async () => {
store.isLoading = true;
store.hasData = false;
try {
await new Promise(r => setTimeout(r, 2000));
store.userName = "Jane Doe";
store.hasData = true;
WN.bridge.haptic('light');
} catch (error) {
WN.bridge.toast('Error loading''Erro ao carregar');
} finally {
store.isLoading = false;
}
};
Exemplo de Código (HTML)Code Example (HTML)
Use as classes animate-pulse do Tailwind para criar o efeito de esqueleto.
Use Tailwind's animate-pulse classes to create the skeleton effect.
<!-- Botão Trigger -->
<button onclick="loadingProfile()">LoadCarregar</button>
<!-- 1. SKELETON (Appears if isLoading is true) --><!-- 1. SKELETON (Aparece se isLoading for 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) --><!-- 2. CONTEÚDO REAL (Aparece se hasData for 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)
Attribute Reference (Data Props)
Lista completa de atributos especiais que controlam o comportamento da Engine WrapNative.
Full list of special attributes that control the WrapNative Engine behavior.
data-wn-screen
Define um contêiner como uma "Tela" gerenciável pelo Router.
Defines a container as a "Screen" managed by the Router.
<div id="home" data-wn-screen>...</div>
data-wn-link
Link de navegação SPA. Use com `href="#id"`.
SPA navigation link. Use with `href="#id"`.
<a href="#detalhes" data-wn-link>Ir</a>
data-wn-title="..."
Define o título da Toolbar quando a tela está ativa.
Sets the Toolbar title when screen is active.
<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.
Conditional Rendering: Shows element only if store key is `true`. Removes `.wn-hidden` automatically.
<!-- 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.
Dynamic Text: Syncs text content (`innerText`) with 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.
Two-Way Binding: Binds input value to store and 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:
Add data-wn-ptr to the screen and listen for the event:
document.addEventListener('wrapnative-refresh', () => {
wrapnative.ui.completePTR();
});
Modais & SwipeModals & Swipe
O sistema de modais suporta o gesto de "Swipe-to-Dismiss" (arrastar para baixo para fechar), nativo em iOS.
The modal system supports "Swipe-to-Dismiss" gesture, native to iOS.
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
wrapnative.ui.openModal('meuModal');
wrapnative.ui.closeModal('meuModal');
Diálogos & AlertasDialogs & Alerts
Substitua o feio window.alert() por diálogos modernos, centralizados e responsivos com suporte a callbacks.
Replace ugly window.alert() with modern, centered, responsive dialogs with callbacks.
wrapnative.ui.alert({
title: 'Confirmar',
message: 'Deseja excluir este item?',
buttons: [
{
text: 'Cancelar',
role: 'cancel'
},
{
text: 'Sim',
handler: () => deleteItem()
}
]
});
Smart PWA
PWA Inteligente
A Engine detecta automaticamente o sistema operacional e apresenta o fluxo de instalação correto:
The Engine automatically detects the OS and presents the correct install flow:
- Android: Captura o evento
beforeinstallprompt e mostra um banner nativo.Android: Captures beforeinstallprompt and shows a native banner.
- iOS: Exibe um Modal Tela Cheia com guia visual de instalação (Share -> Add to Home).iOS: Displays a Full Screen Modal with visual install guide (Share -> Add to Home).