Pular para o conteúdo

Material 3 → Verge

Guia prático e opinativo pra mover uma interface do Material 3 do Google pro Verge, a linguagem visual canônica do Koder Design System. Rename de tokens, swap de componentes e as poucas diferenças filosóficas que valem ser conhecidas. Verge v0 é Adwaita-based, não Material-based — a maioria dos tokens M3 tem counterpart no Verge mas a linguagem visual difere.

Por que migrar

  • Self-hosted — Koder Design serve da sua infra — sem CDN do Google, sem fetch terceirizado, sem version pinning no release cycle de outra empresa.
  • Controle total do tema — Light e dark são baseline; 35 presets shipam out-of-the-box, e você sobrescreve cada token em três níveis de customização (L0 só brand → L4 token-level).
  • 35 presets — Famílias Era, Brand, Mood, Cultural, Domain — escolha ou componha. Material You é uma estratégia de personalização; Koder trata como uma variante entre muitas.
  • Spec aberta — Cada página deste site é gerada de uma spec em `meta/docs/stack/specs/`. Fork da spec, regenere o design system — zero black box.
  • Sem tracking — O site de docs do Koder Design não usa analytics, nenhum beacon per-page. O widget de feedback no rodapé é opt-in e anônimo.

Mapeamento de tokens

A maioria dos tokens de cor, forma, movimento e tipografia do Material 3 tem contraparte 1:1 em Koder. Onde a filosofia diverge, a tabela explica.

Token Material 3Token Koder DesignNotas
md.sys.color.primary--kdr-accentRename 1:1
md.sys.color.on-primary--kdr-accent-onRename 1:1
md.sys.color.primary-container--kdr-surface-2Koder colapsa a hierarquia de containers do Material em duas camadas (`surface` / `surface-2`)
md.sys.color.primary-fixed--kdr-accentKoder não modela variantes fixed-tone — use o role base
md.sys.color.surface--kdr-surfaceRename 1:1
md.sys.color.surface-container--kdr-surface-2Koder colapsa a hierarquia de containers do Material em duas camadas (`surface` / `surface-2`)
md.sys.color.on-surface--kdr-textRename 1:1
md.sys.color.on-surface-variant--kdr-text-mutedRename 1:1
md.sys.color.outline--kdr-borderRename 1:1
md.sys.color.error--kdr-errorRename 1:1
md.sys.elevation.level0..5--kdr-shadow-0..5Receita tonal diverge; veja `specs/themes/elevation.kmd`
md.sys.shape.corner.small--kdr-radius-smKoder ship sm/md/lg só; escala 5-tier do Material colapsa
md.sys.shape.corner.medium--kdr-radius-mdKoder ship sm/md/lg só; escala 5-tier do Material colapsa
md.sys.shape.corner.large--kdr-radius-lgKoder ship sm/md/lg só; escala 5-tier do Material colapsa
md.sys.typescale.display-largevar(--kds-font-display)Koder usa 4 famílias role-based (sans/mono/display/serif); escala per-class do Material mapeia via role
md.sys.typescale.body-largevar(--kds-font-sans)Koder usa 4 famílias role-based (sans/mono/display/serif); escala per-class do Material mapeia via role
md.sys.motion.easing.standardcubic-bezier(0.2, 0.8, 0.2, 1)Koder ship curvas canônicas inline (sem `--kdr-motion-*` vars ainda — tracked v2)
md.sys.motion.duration.medium2240msKoder ship curvas canônicas inline (sem `--kdr-motion-*` vars ainda — tracked v2)
md.sys.state.hover.opacityn/aKoder usa background-color shifts (surface-2, accent-mix) em vez das stateful overlay opacities do Material

Mapeamento de componentes

Cada componente Koder é uma spec que consolida as variantes do Material sob uma API só (Material agrupa = nós agrupamos).

Componente Material 3Componente Koder DesignSpec
MaterialButtonKoderButtoncomponents/buttons
FilledButton / TonalButton / OutlinedButton / TextButton / FABKoderButton via prop `variant=`components/buttons
Card (3 variants)KoderCardcomponents/cards
CheckboxKoderCheckboxcomponents/checkbox
Chip (4 variants)KoderChipcomponents/chips
Dialog / AlertDialogKoderDialogcomponents/dialogs
Menu / DropdownMenuKoderMenucomponents/menus
NavigationBar / NavigationRail / NavigationDrawerKoderNav via prop `variant=`components/navigation
SnackbarKoderSnackbarcomponents/snackbars
SwitchKoderSwitchcomponents/switch
Tabs (primary / secondary)KoderTabscomponents/tabs
TextField (filled / outlined)KoderTextFieldcomponents/text-fields
Tooltip (plain / rich)KoderTooltipcomponents/tooltips
DatePicker / TimePickerKoderDatePicker / KoderTimePickercomponents/pickers
BottomSheet / SideSheetKoderSheetcomponents/sheets

Diferenças que quebram

  1. Paleta 13-tom → taxonomia de 18 roles. Material deriva 13 tons por cor-chave e expõe como roles. Koder pula o passo intermediário de tom — seus 18 roles semânticos mapeiam direto pra cores-semente derivadas via HCT. Efeito prático: quando precisar de cor, peça o role (`accent-on`, `surface-2`), não o tom.
  2. Material You → presets + seed-color. Material You redeira o sistema do wallpaper do usuário no Android. Koder trata isso como uma de 35+ estratégias de preset e oferece um nível explícito de customização por seed-color (L2). Paridade cross-platform importa mais que extração de wallpaper.
  3. Elevação tonal só no escuro. Material 3 usa elevação tonal nos dois schemes. Koder usa shadow elevation em light e overlay tonal em dark — combinados onde o contraste demanda. Ver `specs/themes/elevation.kmd`.
  4. Overlay de estado → swap de background. Material aplica overlay translúcido (`hover.opacity = 0.08`, etc.) sobre a cor base. Koder swap pro outro surface token no mesmo role. Cascade mais limpa, theming mais simples, menos pilha translúcida pra debugar.
  5. Sans default único, serif opt-in. Material 3 ship Roboto Flex como variable font default. Koder ship Inter (sans) + JetBrains Mono (mono) — WOFF2 self-hosted. Serif é opt-in pra surfaces content-heavy (reading mode); display fonts são commission per preset.

Upgrade passo a passo

  1. Audite sua surface atual de tokens.

    Rode `grep -r 'md.sys' src/` pra enumerar cada token Material que você referencia. Mapeie cada um pro equivalente Koder usando a tabela acima. Deixe o resto no default na primeira passada — migrations opinativas se enrolam quando tentam traduzir tudo de uma vez.

  2. Substitua o theme provider.

    Substitua seu wrapper `MaterialApp` / `MaterialTheme` pelo `KoderApp` (Flutter) ou `<koder-design>` (Web) do Koder Design. Ambos aceitam prop `preset=` (default: `koder-base`) e `seedColor` opcional pra customização L2.

  3. Renomeie imports de componentes.

    Use a tabela de componentes acima. A maioria dos renames é mecânica (`MaterialButton` → `KoderButton`); alguns colapsam múltiplos widgets Material num só Koder via prop `variant=` (estilos de botão, surfaces de nav, tipos de dialog).

  4. Calibre a seed-color L2.

    Abra `/playground/` e cole sua seed de brand. A paleta de 18 roles deriva automaticamente. Se precisar de controle mais fino (L3 / L4), edite seu arquivo de override de token direto — o playground emite o JSON pra você.

  5. Verifique no checador de contraste.

    Abre /tools/contrast/ pra spot-check cada par de token contra WCAG 2.2 AA / AAA. Atenção especial ao par `text-muted` × `surface-2` — a escala tonal do Material era permissiva aqui; os defaults do Koder são mais apertados mas valem verificar quando você traz uma cor de brand.

Gaps conhecidos

Estas são features do Material que Koder Design ainda não bate. Tracked publicamente:

  • Cor dinâmica derivada de wallpaper (Material You no Android). Koder oferece customização por seed-color mas não extração wallpaper-level do OS. Tracked: `themes/color-dynamic.kmd` v2.
  • Variable-axis font com grade + optical-size axes (Material Symbols, Roboto Flex). Koder ship Inter + JetBrains Mono — single weight axis. Koder Display custom commission tracked em `projects/koder-stack#128`.
  • Paridade Figma kit + plugin. Spec existe (`specs/tools/design-kit-export.kmd`); implementação é a mais lenta das 5 tracks de tool.
  • Code samples per-platform em cada página de componente (Flutter / Web / Android Compose / iOS SwiftUI). Spec em `specs/develop/code-samples-toggle.kmd`.

Acompanhe o progresso no blog de releases do Koder Design →