- Introduced a new theme for the application based on dark navy aesthetics. - Created design tokens for colors, spacings, and border radii. - Developed a theme module in Rust to manage styles for various UI components. - Updated multiple screens and components to align with the new design, including cards, buttons, badges, and progress bars. - Enhanced user experience with improved layouts and visual elements across the application.
9.5 KiB
UI Redesign — Comparador de Notas
Data: 04/03/2026
Branch: change-ui
Base: iced 0.13.1 (Elm architecture)
Referência visual: ui-ideia/mockup.html + ui-ideia/design_tokens.json
1. Objetivo
Aplicar o visual do mockup (tema dark navy, cards, badges coloridos, progress bars) a todas as telas da aplicação, mantendo a lógica de negócio e a arquitetura Elm intocadas.
2. Design Tokens (mapeados para Rust)
Paleta de cores
| Token | Hex | Uso |
|---|---|---|
BG |
#0F172A |
Fundo geral da janela |
SURFACE |
#1E293B |
Cards / containers primários |
SURFACE_2 |
#334155 |
Cards secundários, cabeçalho de tabela |
BORDER |
#334155 |
Bordas de inputs e cards |
TEXT |
#F1F5F9 |
Texto principal |
TEXT_SECONDARY |
#94A3B8 |
Labels, placeholders, texto muted |
TEXT_MUTED |
#64748B |
Texto desabilitado |
PRIMARY |
#3B82F6 |
Botões primários, links, step ativo |
PRIMARY_HOVER |
#2563EB |
Hover em botões primários |
SUCCESS |
#22C55E |
Badge OK, progress bar ≥ 90% |
WARNING |
#F59E0B |
Badge Faltante, progress bar 60–89% |
ERROR |
#EF4444 |
Badge Duplicada, progress bar < 60% |
OVERLAY |
rgba(0,0,0,0.6) | Fundo do modal |
Espaçamentos
| Token | px |
|---|---|
XS |
4 |
SM |
8 |
MD |
12 |
LG |
16 |
XL |
24 |
XXL |
32 |
Border radius
| Token | px |
|---|---|
SM |
4 |
MD |
6 |
LG |
8 |
3. Arquivo de tema: src/ui/theme.rs
Módulo responsável por expor:
PALETA: constantesColorpara todas as cores acima- Funções de estilo para
container::Style,button::Style,text_input::Style,progress_bar::Style - Nenhuma lógica de negócio — apenas aparência
Estratégia de tema iced
// main.rs — encadear .theme()
iced::application(...)
.theme(|_app, _| tema_dark())
.run_with(App::new)
// theme.rs
pub fn tema_dark() -> iced::Theme {
iced::Theme::custom("dark".to_string(), iced::theme::Palette {
background: hex("#0F172A"),
text: hex("#F1F5F9"),
primary: hex("#3B82F6"),
success: hex("#22C55E"),
danger: hex("#EF4444"),
})
}
Widgets que precisam de aparência customizada além da paleta (cards, badges) recebem closure .style(|theme| ...) inline ou via função helper em theme.rs.
4. Componentes visuais novos / modificados
4.1 Card container
Container com background SURFACE, borda BORDER 1px, radius LG (8px), padding LG (16px).
// theme.rs
pub fn card(theme: &iced::Theme) -> container::Style { ... }
pub fn card_secondary(theme: &iced::Theme) -> container::Style { ... }
4.2 Botão primary
Background PRIMARY, texto TEXT, radius MD (6px), sem borda.
Hover: background PRIMARY_HOVER.
4.3 Botão secondary / ghost
Background SURFACE_2, texto TEXT, radius MD.
4.4 Botão danger
Background semi-transparente ERROR (20% alpha), texto ERROR, radius MD.
4.5 Badge de status (inline)
Container com padding [2, 8], radius SM (4px), background 20% alpha da cor semântica.
Implementado como container(text(...).size(12)) com style closure.
| Status | Cor texto | Background alpha |
|---|---|---|
| OK | SUCCESS |
20% |
| Faltante | WARNING |
20% |
| Duplicada | ERROR |
20% |
4.6 Progress bar por série
Componente progress_bar nativo do iced com style closure que escolhe cor baseada no percentual:
- ≥ 90% →
SUCCESS - 60–89% →
WARNING - < 60% →
ERROR
Background da trilha: #111827 (mais escuro que SURFACE).
4.7 Stat cards (tela de resultado)
Row de 3 cards com número grande colorido + label. Componente reutilizável stat_card(valor, label, cor).
4.8 Breadcrumb
Row no topo da janela (exceto Layouts e Analisando). Steps separados por ›. Background SURFACE, padding [8, 16], borda inferior 1px BORDER.
| Estado do step | Cor | Tamanho |
|---|---|---|
| Ativo | PRIMARY |
14px |
| Concluído | TEXT_SECONDARY |
13px |
| Futuro | TEXT_MUTED |
13px |
5. Telas — mudanças por arquivo
5.1 screens/import.rs
Atual: Coluna plana com título, row de arquivo e row de layout.
Novo:
- Card central (max-width 600px) centrado na tela
- Área de drop zone estilizada com borda tracejada
BORDER, radiusLG, paddingXL - Ícone
📂grande + texto instrucional - Nome do arquivo selecionado com truncamento
- Seção de layout com separador visual
- Botão primary "▶ Configurar Colunas" ocupando largura do card
5.2 screens/selecionar_aba.rs
Atual: Lista de botões idênticos (bug de highlight).
Novo:
- Card com lista de abas scrollável
- Aba selecionada: background
PRIMARY(20% alpha), textoPRIMARY, bordaPRIMARY - Aba não selecionada: background
SURFACE_2, textoTEXT - Preview abaixo da lista em card separado
5.3 screens/configuracao_colunas.rs
Atual: Coluna plana de inputs.
Novo:
- Seção de configuração em card
SURFACE - Labels com
TEXT_SECONDARY, inputs com fundoBG, bordaBORDER - Campos opcionais: checkbox com estilo consistente + input inline
- Erros em card com borda
ERROR(20% alpha) - Botões na barra inferior fixada: "Voltar" (ghost), "Analisar" (primary), "Reanalisar" (secondary), "Salvar" (ghost)
5.4 screens/resultado.rs
Atual: Coluna de texto puro.
Novo (alinhado ao mockup):
- Header row: título + botões de ação à direita
- Stat cards row: 3 cards — "Notas Faltantes" (azul), "Duplicadas" (vermelho), "Total R$" (texto branco)
- Card de completude por série: para cada série, label + progress bar colorida por threshold
- Controle de itens/página: botões com highlight no ativo
- Seções faltantes/duplicatas: cabeçalho de série em row com badge de contagem + botão Copiar; itens em lista
5.5 screens/layouts.rs
Atual: Coluna plana.
Novo:
- Seções CSV e XLSX em cards separados
- Cada layout numa row com hover highlight
- Botões de ação menores (ícone + texto compacto)
- Linha de importar JSON no rodapé do card
5.6 components/modal.rs
Atual: Box com estilo do tema padrão.
Novo:
- Background
SURFACE, bordaBORDER, radiusLG - Título
TEXT18px, mensagemTEXT_SECONDARY14px - Separador entre conteúdo e botões
- Botão "Fechar" ghost, "Confirmar" primary
- Tipos Erro/Aviso com ícone + cor no título
5.7 components/tabela_preview.rs
Atual: Monospace puro.
Novo:
- Cabeçalho com background
SURFACE_2, textoTEXT_SECONDARY - Células com background
SURFACE, textoTEXT, fonte monospace - Borda inferior
BORDERnas células
5.8 components/paginacao.rs
Atual: Row simples de botões.
Novo:
- Botões ◀/▶ com estilo ghost
- "Página X / Y" em
TEXT_SECONDARY
6. Arquivos a criar/modificar
| Arquivo | Ação |
|---|---|
src/main.rs |
Adicionar .theme(...) |
src/ui/mod.rs |
Adicionar pub mod theme; |
src/ui/theme.rs |
Criar — paleta + helpers de estilo |
src/ui/app.rs |
Breadcrumb novo estilo + tela Analisando centralizada |
src/ui/screens/import.rs |
Reescrever |
src/ui/screens/selecionar_aba.rs |
Reescrever (corrigir bug highlight) |
src/ui/screens/configuracao_colunas.rs |
Reescrever |
src/ui/screens/resultado.rs |
Reescrever |
src/ui/screens/layouts.rs |
Reescrever |
src/ui/components/modal.rs |
Reescrever |
src/ui/components/tabela_preview.rs |
Reescrever |
src/ui/components/paginacao.rs |
Reescrever |
7. Limitações do iced 0.13 e workarounds
| Limitação CSS | Workaround iced |
|---|---|
box-shadow |
Cor de borda ou sem sombra (aceitar diferença) |
rgba(r,g,b,0.2) |
Color { r, g, b, a: 0.2 } com valores 0.0–1.0 |
| Font Inter | Usa fonte do sistema (system-ui) — sem mudança necessária |
display: flex; gap |
row![...].spacing(N) |
border-bottom nas células |
container com border bottom via border.width fracional não suportado — usar separador visual alternativo |
8. Ordem de implementação
theme.rs— paleta e helpers (base para tudo)main.rs— ativar temamodal.rs— usado por todas as telasresultado.rs— tela principal do mockupimport.rsselecionar_aba.rsconfiguracao_colunas.rslayouts.rsapp.rs— breadcrumb + Analisandotabela_preview.rs+paginacao.rs- Compilar e corrigir
9. Notas de compatibilidade iced 0.13
button::Styleincluibackground,text_color,border: Border { color, width, radius },shadowcontainer::Styleincluibackground,text_color,border,shadowprogress_bar::Styleincluibackgroundebartext_input::Styleincluibackground,border,icon,placeholder,value,selection- Closures de estilo recebem
&Themee retornam oStyleconcreto do widget iced::Borderaceitaradius: iced::border::Radius— usarN.into()para uniform radius