npm package: @marcos_feitoza/personal-finance-frontend-core-ui
Description: Shared UI component library for Personal Finance frontend packages.
Latest version: 1.8.2

# Frontend Core UI (Flutter)

Shared UI component library for Personal Finance frontend packages.

## Purpose


O objetivo deste pacote é centralizar e padronizar a aparência e o comportamento dos elementos de UI em todo o aplicativo. Ele fornece uma biblioteca de componentes que podem ser utilizados por outros pacotes de feature, garantindo consistência visual e reduzindo a duplicação de código.

## Conteúdo Principal

- **`widgets/`**: Contém diversos widgets reutilizáveis, como `AppFormCard`, `AppDropdown`, `TradeForm`, `DividendLogForm`, `CryptoTradeForm`, `RrspContributionForm`, etc.
- **`utils/app_dialogs.dart`**: Funções utilitárias para exibir diálogos padronizados (ex: confirmação de exclusão).
- **`utils/app_logger.dart`**: Implementação de um logger condicional que exibe logs apenas em modo de depuração.
- **`utils/currency_input_formatter.dart`**: Formatter para campos de entrada de moeda.
- **`utils/theme_notifier.dart`**: Provedor para gerenciar o tema da aplicação (claro/escuro).

## Tema (Fase 1 — centralização)

Para evitar que cada tela/feature package defina seus próprios estilos (cores, espaçamentos, bordas), o **tema global** foi centralizado no core-ui.

Arquivos:

- `lib/theme/app_theme.dart`
  - Define `AppTheme.light` e `AppTheme.dark`.
  - **O que controla:**
    - `ColorScheme` (paleta de cores principal)
    - `AppBarTheme` (cor do topo e cor do texto/ícones)
    - `ElevatedButtonTheme` / `OutlinedButtonTheme` (tamanho e bordas padrão dos botões)
    - `InputDecorationTheme` (bordas/padding padrão de `TextFormField`)
- `lib/theme/app_colors.dart`
  - Tokens semânticos (ex.: `success`, `error`, `warning`) e `seed`.
  - **O que controla:**
    - cores usadas em feedback (SnackBars, highlights de sucesso/erro)
    - seed do tema (mudança global do “tom” do app)
- `lib/theme/app_spacing.dart`
  - Tokens de espaçamento (`xs/sm/md/lg/xl/...`).
  - **O que controla:**
    - valores de padding/margin padronizados

Uso no app shell (`personal-finance-frontend/lib/main.dart`):

```dart
import 'package:personal_finance_frontend_core_ui/theme/app_theme.dart';

MaterialApp(
  theme: AppTheme.light,
  darkTheme: AppTheme.dark,
)
```

Regras recomendadas:

- Em telas/features: preferir `Theme.of(context).colorScheme`.
- Para cores semânticas (ex.: erro/sucesso), usar `AppColors`.
- Para componentes, preferir `widgets/app_widgets.dart`.

## Design System (GenAI visual layer)

Além do tema base, o pacote recebeu uma camada visual padronizada para manter paridade entre módulos:

- `lib/theme/genai_tokens.dart`
  - tokens de cor (midnight/electric/neon/flame/coral), radius e sombras;
- `lib/widgets/genai_widgets.dart`
  - `GenaiButton`, `GenaiGlassCard`, `GenaiBackdrop`;
- `lib/theme/app_theme.dart`
  - ajustes de tipografia, bordas e estados para dark-glass consistente.

### Padronização de seleção (sem verde default)

`SegmentedButton` foi tematizado globalmente para usar o padrão do design system (electric) em vez da seleção verde default do Material.

Impacto direto:

- `Expense (Debit)` / `Refund (Credit)`;
- segmentações em charts/reports;
- demais formulários com `SegmentedButton`.

### Tabelas e filtros unificados

- `ReportTableCard` virou base visual de DataTable entre features;
- `ReportFilterActions` usa botões do DS;
- `FilterButton` recebeu estado ativo consistente e proteção de overflow (ellipsis).

## SnackBars padronizados (Fase 2)

Para evitar SnackBars com cores/textos inconsistentes, use os helpers:

- `showErrorSnackBar(context, message)`
- `showSuccessSnackBar(context, message)`
- `showInfoSnackBar(context, message)`

Arquivo:
- `lib/utils/app_snackbars.dart`

Exemplo:

```dart
import 'package:personal_finance_frontend_core_ui/utils/app_snackbars.dart';

showErrorSnackBar(context, 'Something went wrong');
```

---

## Loading / Empty / Error / Success (Fase 3)

Para evitar telas “silenciosas” e condicionais repetidos em cada screen (`if (isLoading) ... else if (error) ...`), use o widget centralizado:

- `lib/widgets/app_async_state_view.dart`

Ele padroniza os estados:

- **loading**: `CircularProgressIndicator`
- **error**: mensagem + botão “Try again” (opcional)
- **empty**: mensagem + ação (opcional)
- **success**: renderiza o `child`

Exemplo:

```dart
return AppAsyncStateView(
  isLoading: viewModel.isLoading,
  errorMessage: viewModel.errorMessage,
  isEmpty: viewModel.items.isEmpty,
  emptyMessage: 'No items found.',
  onRetry: viewModel.fetch,
  child: ListView(...),
);
```

---

## Como Usar (Instalação como Dependência)

Este pacote é uma dependência local para a aplicação principal (`personal-finance-frontend`) e outras features packages do frontend.

No `pubspec.yaml` do pacote consumidor, adicione a seguinte linha em `dependencies`:

```yaml
personal_finance_frontend_core_ui:
  path: ../personal-finance-frontend-core-ui
```

## Features

-   **Widgets Reutilizáveis**: Componentes de UI com design e comportamento padronizados.
-   **Diálogos Centralizados**: Funções para exibir diálogos consistentes em todo o aplicativo.
-   **Logging Condicional**: Um logger que ajuda a manter o console limpo em produção, exibindo mensagens apenas em desenvolvimento.
-   **Ferramentas de Formatação**: Utilitários para formatar entradas de usuário (ex: valores monetários).

---

## Dropdowns de Category/Subcategory (decisão de produto: "clean")

Para evitar poluição de dropdowns por itens gerados automaticamente (ex.: pagamentos de cartão criados na reconciliação), o app segue a regra:

- **Forms como `ExpenseForm` carregam apenas as categorias/subcategorias definidas pelo usuário**.
- Ou seja: a lista vem de `MetadataService.getUserCategories()`.

Isso garante que o autocomplete de Subcategory em **Add Expense** mostre somente o que o usuário:

- importou do demo
- criou manualmente em Categories Settings
- criou durante o Import Statement (CSV)