8.1 KiB
8.1 KiB
Otimizações Mobile - Angular IDT App
Este documento detalha todas as otimizações mobile implementadas no projeto Angular IDT App para melhorar a experiência do usuário em dispositivos móveis.
🎯 Visão Geral
Breakpoint Padrão
- Mobile: ≤ 768px
- Desktop: > 768px
- Detecção: Automática via
@HostListener('window:resize')
Filosofia de Design
- Mobile First: Priorizar a experiência mobile
- Edge-to-Edge: Aproveitamento máximo da tela
- Touch-Friendly: Controles adequados para toque
- Conteúdo Compacto: Informações essenciais apenas
📋 Tab System - Otimização de Títulos
Funcionalidade
Sistema automático de formatação de títulos das abas para dispositivos móveis.
Comportamento
Mobile (≤ 768px)
"Motorista: João Silva" → "João Silva"
"Veículo: Toyota Corolla" → "Toyota Corolla"
"Cliente: Empresa XYZ" → "Empresa XYZ"
"Novo Motorista" → "Novo Motorista" (inalterado)
"Nova Empresa" → "Nova Empresa" (inalterado)
Desktop (> 768px)
"Motorista: João Silva" → "Motorista: João Silva" (sempre completo)
Implementação Técnica
Arquivo: projects/idt_app/src/app/shared/components/tab-system/tab-system.component.ts
export class TabSystemComponent implements OnInit, OnDestroy {
isMobile: boolean = false;
@HostListener('window:resize', ['$event'])
onResize() {
this.checkIfMobile();
}
private checkIfMobile() {
this.isMobile = window.innerWidth <= 768;
}
getFormattedTabTitle(tab: TabItem): string {
if (!this.isMobile) {
return tab.title; // Desktop: título completo
}
// Mobile: remove domínio se não for "Novo"
if (tab.title.includes(':') && !tab.title.startsWith('Novo')) {
const parts = tab.title.split(':');
if (parts.length >= 2) {
return parts.slice(1).join(':').trim();
}
}
return tab.title; // Fallback
}
}
Template Usage:
<span class="tab-title">
{{ getFormattedTabTitle(tab) }}
</span>
Benefícios
- Espaço Otimizado: Mais espaço para o nome do item
- Legibilidade: Reduz confusão visual
- Responsivo: Adaptação automática
- Universal: Funciona para todos os domínios
📊 Data-Table - Otimização Completa
Header Reorganizado (Mobile)
Layout Atual
Desktop: [🔍 Busca] [Filtros] [Colunas] [Agrupar] [PageSize] [Export]
← Linha única cramped
Mobile: [🔍 Busca Global - 80%] [Filtros - 20%] ← Linha 1
[Req] [Col] [Grup] [5▼] [Exp] ← Linha 2
← Duas linhas organizadas
Implementação CSS
Arquivo: projects/idt_app/src/app/shared/components/data-table/data-table.component.scss
/* Desktop (padrão) */
.table-menu {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
/* Mobile: Reorganização em duas linhas */
@media (max-width: 768px) {
.table-menu {
flex-direction: column;
gap: 0.5rem;
}
.menu-top-row {
display: flex;
gap: 0.75rem;
margin-bottom: 0.5rem;
}
.menu-bottom-row {
display: flex;
gap: 0.5rem;
justify-content: space-between;
flex-wrap: wrap;
}
.global-filter-container {
flex: 1;
min-width: 0;
max-width: 80%;
}
.toggle-filters-btn {
flex: 0 0 auto;
max-width: 20%;
}
}
Funcionalidades Mobile
- Busca Global: 80% da largura
- Botões Compactos: Textos abreviados ("Col", "Grup", "Exp")
- Layout Edge-to-Edge: Sem bordas laterais
- Responsive Design: Adaptação automática
Paginação Otimizada
Layout Mobile
Antes: [Info sobre resultados]
[Controles de navegação]
← Duas linhas
Depois: [1-5 de 5] [◀][1][2][3][▶] ← Linha única
↑ esquerda ↑ direita
Implementação
/* Mobile: Paginação em linha única */
@media (max-width: 768px) {
.pagination {
padding: 0.375rem 0.5rem !important;
flex-direction: row !important;
justify-content: space-between !important;
align-items: center !important;
gap: 0.5rem !important;
min-height: 40px;
}
.pagination-info {
flex: 0 0 auto;
font-size: 0.8rem !important;
white-space: nowrap;
text-align: left;
margin-right: auto;
}
.pagination-controls {
flex: 0 0 auto;
margin-left: auto;
}
}
Melhorias Implementadas
- Texto Compacto: "1-5 de 5" vs "Exibindo 1 a 5 de 5 registros"
- Altura Reduzida: 40px vs 60px
- Alinhamento Inteligente: Info esquerda, controles direita
- Touch-Friendly: Botões maiores para toque
CSS Budget Management
Problema
- Limite: 20kB para CSS da data-table
- Atual: 23.44kB (3.44kB over)
- Status: ⚠️ Warning (ainda funcional)
Estratégias de Otimização
/* Ultra-compressão para mobile */
@media (max-width: 768px) {
.data-table-container,.table-menu{border-left:none!important;border-right:none!important;border-radius:0!important;margin:0!important}
.pagination{padding:.375rem .5rem!important;flex-direction:row!important;justify-content:space-between!important}
.pagination-info{font-size:.8rem!important;text-align:left!important;margin-right:auto!important}
/* ... mais regras comprimidas */
}
Técnicas aplicadas:
- Compressão Manual: Remoção de espaços
- Seletores Combinados: Agrupamento de regras
- Important Flags: Sobrescrita estratégica
- Propriedades Mínimas: Apenas essenciais
🎨 Componentes Afetados
Tab System Component
- Arquivo:
tab-system.component.ts - Funcionalidade: Formatação automática de títulos
- Benefício: Melhor aproveitamento do espaço horizontal
Data Table Component
- Arquivo:
data-table.component.scss - Funcionalidades: Header reorganizado + paginação compacta
- Benefício: Interface mobile nativa
Custom Tabs Component
- Arquivo:
custom-tabs.component.ts - Funcionalidade: Formatação de tabs internas (formulários)
- Benefício: Consistência com tab system principal
📱 Resultados e Benefícios
UX Mobile
- Interface Nativa: Aparência de app mobile
- Navegação Fluída: Transições suaves
- Conteúdo Visível: Máximo aproveitamento da tela
- Touch-Friendly: Controles adequados para toque
Performance
- Responsividade: Atualização automática no resize
- CSS Otimizado: Compressão máxima mantendo funcionalidades
- Bundle Size: Impacto mínimo no tamanho final
Desenvolvimento
- Automático: Sem necessidade de intervenção manual
- Universal: Funciona em todos os domínios
- Mantível: Código limpo e documentado
🛠️ Como Aplicar em Novos Componentes
Para Tab Titles
// 1. Adicionar detecção mobile
isMobile: boolean = false;
@HostListener('window:resize', ['$event'])
onResize() {
this.checkIfMobile();
}
private checkIfMobile() {
this.isMobile = window.innerWidth <= 768;
}
// 2. Implementar formatação
getFormattedTitle(title: string): string {
if (!this.isMobile) return title;
if (title.includes(':') && !title.startsWith('Novo')) {
const parts = title.split(':');
if (parts.length >= 2) {
return parts.slice(1).join(':').trim();
}
}
return title;
}
Para Layouts Mobile
/* Desktop first */
.component {
/* estilos desktop */
}
/* Mobile adaptations */
@media (max-width: 768px) {
.component {
/* layout mobile otimizado */
border-left: none !important;
border-right: none !important;
border-radius: 0 !important;
margin: 0 !important;
}
}
🎯 Próximos Passos
Possíveis Melhorias
- CSS Bundle Splitting: Separar CSS mobile/desktop
- Lazy Loading: Carregar CSS mobile sob demanda
- Tree Shaking: Remover CSS não utilizado
- Component Splitting: Dividir componentes grandes
Novos Componentes
- Mobile Menu: Menu hambúrguer nativo
- Swipe Gestures: Navegação por gestos
- Pull-to-Refresh: Atualização por arrastar
- Mobile Forms: Formulários otimizados
Este documento deve ser atualizado conforme novas otimizações mobile são implementadas.