-
Notifications
You must be signed in to change notification settings - Fork 1
EmailRealizer pt BR
🌐 Esta página em: English · Português
Estado: planejado, não construído. Nada abaixo existe hoje. Esta página é o desenho e as fatias; a entrada do roadmap aponta para cá.
Escrever o email em C# com os mesmos componentes com que se escreve uma página, e receber de volta um HTML que um cliente de email realmente renderiza.
Um componente aqui é uma árvore de VisualNode que não sabe nada sobre seu alvo. O realizador web a
transforma em DOM e CSS; o Photon a transforma em pintura na GPU. Email é um terceiro realizador
— um alvo cujo motor de render é muito restritivo, o que é arquiteturalmente a mesma forma de um
alvo sem DOM nenhum.
Nada na camada de autoria muda. Os mesmos Column, Text, Image e tokens de tema, o mesmo
Build(context).
Duas peças estão na árvore hoje, verificadas lendo o código:
-
WebRealizer.Lower(node, theme, typeScale, styles: null)— sem o sink de estilos, os estilos ficam inline no elemento em vez de virarem classes atômicas deduplicadas. Estilo inline é a restrição mais dura do email, e esse caminho já o produz. -
HtmlRenderer.RenderNode(...)transforma a árvore rebaixada numa string de HTML.
Ou seja, "componente C# → HTML com estilos inline" são duas chamadas que já existem. O que falta é tudo o que diz respeito ao meio.
| Exigência | Por quê | Onde o realizador web difere |
|---|---|---|
Layout em <table> aninhada |
O Outlook no Windows renderiza com o motor do Word: sem flexbox, sem grid |
Row/Column descem para FlexDirection
|
Só style="" inline |
Blocos <style> e CSS externo são removidos ou ignorados por vários clientes |
Classes atômicas + folha de estilo (o caminho do sink) |
| Cores literais | Custom properties do CSS não são resolvidas | Tokens emitem var(--eq-color-…, fallback)
|
| URL absoluta de imagem ou CID | URIs data: são descartadas pelo Gmail |
Assets assumem uma origem servida |
| Largura restrita | ~600px é a convenção que todo cliente tolera | Páginas são fluidas |
| Nenhuma interação | Sem JS, sem hover na maioria dos clientes, sem contêiner rolável |
Pressable, ScrollView e estados de hover existem |
Um pacote novo, eQuantic.UI.Email, dependendo apenas de Primitives e Core — nunca de
eQuantic.UI.Web, para que os dois realizadores não possam derivar um para dentro do outro.
// Escrito exatamente como uma página.
public sealed class WelcomeEmail(string name) : StatelessComponent
{
public override VisualNode Build(ComponentContext context) =>
Column(gap: Space.S4, children: [
Image(Assets.Logo, width: 132),
Text($"Bem-vindo, {name}", TypeRole.Heading),
Button("Confirme seu endereço", href: "https://…"),
]);
}
// Renderizado onde é enviado.
EmailMessage message = EmailRenderer.Render(new WelcomeEmail("Edgar"), theme);
// message.Html — rebaixado para tabelas, totalmente inline
// message.PlainText — gerado da MESMA árvore, não escrito duas vezesEmailMessage carrega as duas partes porque uma mensagem multipart precisa das duas, e gerar a
alternativa em texto a partir da árvore é o único jeito de ela ficar em dia com o HTML.
M0 — Medir antes de construir. Pegar um componente que já existe, renderizar pelas duas chamadas acima, e abrir o resultado no Gmail (web, iOS, Android), no Outlook (desktop Windows, web) e no Apple Mail. Produzir uma tabela do que sobrevive intacto. Isso decide o tamanho da M1, e é meio dia. Nenhum código novo.
M1 — Rebaixar para tabelas. Box, Row, Column e Gap viram <table>/<tr>/<td>
aninhados, com padding de célula e linhas espaçadoras. Alinhamento mapeia para align/valign. É o
grosso do track.
M2 — Estilos inline e tema literal. Reusar o caminho sem sink; resolver todo token para uma cor e um comprimento literais, para nada depender de custom properties. Densidade e escala de tipo resolvem uma vez, na renderização.
M3 — Casca do documento. EmailDocument: doctype, o conjunto de <meta>, o contêiner de 600px,
a linha invisível de preheader, e o meta de modo escuro que os clientes honram.
M4 — Cerca do vocabulário. Diagnósticos nomeando o que um email não faz — ScrollView,
Pressable, Draggable, estilo de hover e foco, position: absolute. Um Link vira <a>; um
Button vira um <a> à prova de balas estilizado como botão. Uma Image sem URL absoluta é um
erro, não uma figura quebrada na caixa de entrada de alguém.
M5 — Alternativa em texto puro. Percorrer a mesma árvore para a parte text/plain.
-
Nunca um bloco
<style>, mesmo onde um cliente o suporte. Uma regra vence uma matriz de exceções. - Sem interatividade. Um email é uma página impressa que por acaso tem links.
- Sem gambiarra por cliente dentro dos componentes. O que o Outlook precisa mora no realizador, nunca em algo que um autor escreve.
- Anexos e envio não são nossos. A saída é HTML mais texto; enviar é trabalho da app (MailKit, SES, o que ela já usa).
As mesmas duas redes que o resto do framework usa:
- Pins de HTML, regenerados de propósito como as fixtures transpiladas, para que uma mudança de layout apareça como diff e não como surpresa.
- Uma matriz de clientes como conformidade, rodada contra clientes reais e registrada — a regra do "o browser é o árbitro" vale aqui ainda mais forte, porque clientes de email estão mais longe de uma especificação do que browsers estão.
🌐 English · Português
🏁 Comece aqui
📱 Write-once
- Componentes write-once
- Superfície declarativa
- Motor Photon
- Design System
- Capacidades
- Armazenamento
- Formulários
- Editor de código
- Markdown
- Mermaid
- Renderização de Email
🏗️ Arquitetura
⚙️ Compilação
- Compilador
- Avaliação em tempo de compilação
- Recursos C# suportados
- Resolução de tipos externos
- Fluxo de build
- Diagnósticos
⚡ Runtime
🔌 Servidor
🎨 Ecossistema
🚀 Desenvolvimento