-
Notifications
You must be signed in to change notification settings - Fork 1
DesignSystem pt BR
🌐 Esta página em: English · Português
O design system por trás dos componentes write-once: uma especificação
completa de tokens/componentes (preservada no repositório em
docs/design/Photon-Design-System.dc.html, a fonte da verdade) implementada como tokens C#
tipados em eQuantic.UI.Primitives e consumida por todos os alvos de realização.
-
Cores: toda cor é um
ColorTokenpar claro/escuro; componentes nunca guardam cores cruas. Variantes interativas resolvem cinco sub-tokens (Base,OnBase,Pressed, que é um token real e não uma sobreposição,Subtle,OnSubtle). Desabilitado não é uma cor: é um grupo com 38% de opacidade. -
Escala tipográfica: dirigida por papéis (
Display…BodyM,Caption,Label) com clamps de Dynamic Type por papel, mais a ponta densa onde todo chrome de desktop vive:TitleSmall(15/700, o degrau entreLabel13 eTitle20),LabelSmall(11, para trilhos de status, leituras de inspetor, legendas de espécime) eOverline(10/800, com tracking, a sobrancelha em maiúsculas acima de um grupo). Uma escala que para em 12dp é uma escala de toque; uma sidebar, uma toolbar e uma barra de status vivem todas abaixo dela, e sem esses degraus cada uma sai um quinto grande demais. Um estilo também carrega sua face:TypeStyle.Monoseleciona a monoespaçada (a do próprio sistema, SF Mono num Mac), eTypeStyle.Italico corte inclinado (desde a 0.2.0-preview.28 é um EIXO, então negrito itálico e código itálico existem os dois), que o medidor, o rasterizador e o cache de raster honram porque já chaveiam pelo estilo. -
Caixas de linha seguem o tamanho:
TypeStyle.WithSize(size)escala a altura de linha na mesma proporção (oline-heightsem unidade do CSS), eTypeStyle.OfSize(size, weight)deriva uma no 1.25× tipográfico. Remendar só o tamanho deixa um glifo maior na caixa antiga, e é assim que uma descendente termina fora da linha dela. -
Espaçamento (
Space.S1–S16, base 4dp, pertencente ao gap, margem não existe), raio (Radius.Xs–Full, clampado pelo engine), tamanhos de ícone (whitelist §07 16/20/24/32; tamanhos arbitrários lançam), toque (contrato de alvo ≥48dp), elevação (uma sombra analítica por nó), movimento (durações + curvas + mola).
Density (Comfortable | Compact) é uma propriedade do alvo, nunca do local da chamada: um
app nunca pede um botão menor no Mac; o Mac é que pede um app mais denso. É a densidade do Material
e o control size da Apple, e é o que mantém UMA árvore honesta num telefone e num desktop.
Sizing.Height, PaddingX, LabelSize e HitTarget resolvem por ela (Small 32→26, Medium 40→32,
Large 48→40, XLarge 56→48), e a escada de seleção também (SwitchWidth/SwitchHeight/
SwitchThumb/SwitchTravel, SelectionBox, RadioDot). Sob um ponteiro o alvo de toque para
de inflar: o mínimo do §08 é um contrato de dedo, e numa toolbar de botões de 26dp aquelas
margens invisíveis se sobreporiam umas às outras.
Ela chega aos componentes por ComponentContext.Density, a mesma porta pela qual o tema chega,
então nenhuma assinatura de Build mudou. Quem decide é o alvo: o shell do macOS diz Compact; o
boot do web lê (pointer: fine).
A escada vive na camada de tokens, sempre. Um componente nunca guarda uma cópia privada da própria tabela de tamanhos, porque uma cópia não consegue seguir a densidade que o alvo pede.
Sizing.Avatar(size)e os degraus de seleção existem para que quem chama leia o mesmo número que o componente desenha.
- Valores de token são pinados; o contraste WCAG é recalculado nos testes para cada par afirmado.
- Métricas de componente vêm das tabelas da spec (ex.: a tabela de tamanhos do Button: alturas 32/40/48/56) e são afirmadas em todos os eixos: pins do realizer web em C#, imagens golden nativas (claro + escuro), execução de fixture transpilada no vitest.
- As regras do resolvedor de estilo (variantes derivadas Outline/Ghost/Link, pressed como troca de
token, anel duplo de foco) vivem em C# neutro de alvo (
ButtonStyles).
Artefatos client-side que carregam valores do design system são gerados da fonte única em C# e pinados byte a byte na CI (um desvio falha o build; fluxos por variável de ambiente regeneram):
| Artefato | Gerador | Regenerar com |
|---|---|---|
Stylesheet normativo (custom properties, .eq-type-*, .eq-elevation-*, vars de motion) |
PhotonCssGenerator |
(função pura, testada por valor) |
design-system.generated.ts (tokens, objeto de tema, tabela de tamanhos do Button) |
DesignSystemTsGenerator |
EQ_UPDATE_DESIGN_TS=1 |
icons.generated.ts (dados de path dos glifos) |
IconTsGenerator |
EQ_UPDATE_ICONS_TS=1 |
| Módulos de componente transpilados embarcados | saída viva do eqc | EQ_UPDATE_TRANSPILED=1 |
A mesma regra sustenta a hidratação: o SSR (realizer C#) e o lowering do cliente (TS) são mantidos byte-idênticos por literais cross-pinadas nas duas suítes de teste.
Um enum Icons curado (23 glifos e crescendo: Menu, o gatilho de navegação do shell compacto,
chegou na 0.2.0-preview.26) com os dados de path vivendo uma vez no IconRegistry em C#
(máscaras alpha de path única 24×24): o web emite <svg fill="currentColor"> inline (o tom monta
no token de cor exatamente como o texto faz), o lado TS consome o módulo gerado, e o futuro atlas
de glifos nativo rasteriza do mesmo registro. Outline ↔ preenchido são glifos distintos; ícones
ignoram Dynamic Type.
A autoria é 100% C# tipado (BoxStyle, StyleDiff, tokens), e não existe um plano CSS. Três leis
governam a realização web:
- Uma semântica: o mesmo vocabulário de estilo dirige valores dp no Photon e CSS no web.
-
Sem teto de expressividade: Wrap, Grid, AspectRatio, AlignSelf, Opacity de grupo,
Transform2D estático, diffs de estado Hover/Focus, adaptatividade por classe de tamanho de
janela (
AdaptiveNode), Sticky, ZIndex, scroll nos dois eixos. -
Sem reescrita por construção: toda declaração regular desce para UMA classe atômica
deduplicada (
eq-+ hash FNV-1a deprop:valor); cores de tema referenciamvar(--eq-color-*); o SSR junta as regras da página num único<style id="eq-atomic">que o cliente adota por identidade (hidratação = igualdade de classe, garantida de ponta a ponta pelo teste e2e de identidade). ~118 regras / 4,8 KB cobriram o showroom inteiro.
Pseudo-estados descem para regras atômicas de pseudo-variante (:hover/:focus-visible, zero JS);
classes de tamanho para classes fixas com media gate. O StyleAtomizer em C# e o
style-atomizer.ts em TS são gêmeos byte-idênticos (fixture cross-pinada).
Uma interface (cores como pares ColorToken claro/escuro, papéis de tipo, escala de forma, specs
de elevação, opacidade de desabilitado), selecionada via AddUI(...).UseTheme(...) e transportada
do SSR para o cliente.
Trocar claro/escuro em tempo de execução é um SERVIÇO: IThemeController (Mode + Apply) é
tomado por construtor como qualquer capacidade, e o componente nunca aprende qual alvo respondeu. O
runner nativo repinta a janela contra a outra paleta; o browser vira uma declaração color-scheme
(a paleta web inteira é autorada como pares light-dark(), então a troca não custa re-render).
ITextClipboard é oferecido do mesmo jeito para o botão de copiar de uma página. Duas
implementações acompanham: PhotonTheme (o padrão) e MaterialTheme (Material 3 de verdade:
baseline MaterialTheme.Instance ou cor dinâmica FromSeed(cor) via um port CAM16/HCT validado
contra os valores do Google). A forma é dirigida pelo tema; a mesma árvore de componentes se
rebrandiza com uma linha.
🌐 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