Vigiante Front
Documentação Técnica Completa
Versão: 0.0.0
Repositório: github.com/eupedroveloso/vigiante-front
Organização: Fiocruz / Fiotec
Sumário
- Visão Geral
- Stack Tecnológica
- Estrutura do Projeto
- Configuração e Ambiente
- Como Executar
- Roteamento
- Design System
- Biblioteca de Componentes UI (Helm)
- Componentes Compartilhados
- Serviços Core
- Ícones e Assets
- Styleguide Interativo
- Testes
- Build e Deploy
- Convenções de Código
- Apêndice
1. Visão Geral
O Vigiante Front é o frontend Angular do sistema ViconSaga (Vigilância Comunitária com Saúde e Geoprocessamento Ativo), desenvolvido para a Fiocruz/Fiotec. Trata-se de uma aplicação de mapeamento e coleta de dados georreferenciados com foco em vigilância comunitária em saúde.
O repositório está atualmente em fase de construção do design system e componentes base, com um styleguide interativo que documenta e exibe todos os tokens de design, tipografia, ícones e componentes de UI. Os componentes seguem fielmente as especificações do Figma ViconSaga e serão a base para as funcionalidades de mapeamento e coleta de dados.
Principais características
- Aplicação Angular 21 com Standalone Components (sem NgModules)
- Design system com tokens CSS customizados via Tailwind CSS v4
- Biblioteca de componentes Spartan UI (Helm) estilizados e mantidos localmente
- Styleguide interativo com exemplos ao vivo de cada componente
- Suporte completo a Dark Mode
- Componentização orientada a composição para a interface de mapeamento
- Biblioteca de mais de 70 ícones SVG customizados
2. Stack Tecnológica
| Tecnologia | Versão | Finalidade |
|---|---|---|
| Angular | 21.1.0 | Framework principal (Standalone Components) |
| TypeScript | ~5.9.2 | Linguagem de programação |
| Tailwind CSS | ^4.1.18 | Estilização utilitária e tokens de design |
| Spartan UI (Brain) | ^0.0.1-alpha.614 | Primitivos de componentes headless |
| @ng-icons/core + lucide | >=32.0.0 <34.0.0 | Ícones via ng-icons |
| RxJS | ~7.8.0 | Programação reativa |
| PostCSS | ^8.5.6 | Processamento de CSS |
| Vitest | ^4.0.8 | Runner de testes unitários |
| Angular CDK | ^21.1.3 | Kit de desenvolvimento de componentes |
| class-variance-authority | ^0.7.1 | Variantes de classes tipadas |
| clsx + tailwind-merge | ^2.1.1 / ^3.3.1 | Composição segura de classes CSS |
Configuração TypeScript
O projeto usa configurações rígidas para segurança de tipos:
strict: true— habilita todas as verificações estritasnoImplicitOverride: true— exigeoverrideexplicitamentenoPropertyAccessFromIndexSignature: true— previne acesso implícito por índicenoImplicitReturns: true— todos os caminhos devem retornar valornoFallthroughCasesInSwitch: true— previne fallthrough em switchtarget: ES2022— saída modernastrictTemplates: true— verificação de tipos nos templates Angular
3. Estrutura do Projeto
vigiante-front-main/
├── angular.json # Configuração do Angular CLI
├── package.json # Dependências e scripts
├── tsconfig.json # TypeScript com path aliases
├── tsconfig.app.json
├── tsconfig.spec.json
├── components.json # Configuração do Spartan CLI
├── DESIGN_SYSTEM.md # Documentação do design system
├── README.md
├── public/
│ └── favicon.ico
└── src/
├── main.ts # Bootstrap da aplicação
├── index.html
├── styles.scss # Estilos globais + tokens CSS
├── assets/
│ └── icons/ # Biblioteca de ícones SVG
│ ├── *.svg # Ícones gerais (~70 arquivos)
│ └── custom/ # Ícones/imagens personalizadas
│ ├── vigiante-logo.svg
│ ├── street-view.svg
│ ├── heatmap.svg
│ ├── gps.png
│ ├── satellite.png
│ └── terreno.png
├── lib/
│ └── ui/ # Componentes Helm (Spartan UI locais)
│ ├── breadcrumb/
│ ├── button/
│ ├── collapsible/
│ ├── icon/
│ ├── input/
│ ├── separator/
│ ├── sheet/
│ ├── sidebar/
│ ├── skeleton/
│ ├── tooltip/
│ └── utils/
└── app/
├── app.ts # Componente raiz (RouterOutlet)
├── app.config.ts # Providers da aplicação
├── app.routes.ts # Rotas principais
├── core/
│ └── services/
│ ├── asset.service.ts # URLs absolutas para assets
│ └── icon.service.ts # Catálogo de ícones
├── shared/
│ └── components/
│ ├── index.ts # Barrel de exportação
│ ├── breadcrumb/
│ ├── input/
│ ├── map-control/
│ ├── mode-tool/
│ ├── principal-bar/
│ ├── project-tabs/
│ └── tools-bar-map/
└── styleguide/
├── styleguide.component.* # Layout (sidebar + outlet)
├── navigation.config.ts # Navegação do styleguide
└── pages/
├── styleguide/ # Página inicial
├── tokens/ # Design tokens
├── typography/ # Tipografia
├── icons/ # Ícones ng-icons/lucide
├── icons-custom/ # Ícones SVG do projeto
├── component-detail/ # Detalhe genérico
└── components/ # Showcases de componentes
├── breadcrumb/
├── input/
├── map-control/
├── mode-tool/
├── principal-bar/
├── project-tabs/
└── tools-bar-map/
4. Configuração e Ambiente
Pré-requisitos
| Requisito | Versão |
|---|---|
| Node.js | 18+ (LTS recomendado) |
| npm | 10.9.3 (definido como packageManager obrigatório) |
| Angular CLI | ^21.1.3 |
Path Aliases (TypeScript)
O tsconfig.json configura aliases para importar os componentes Helm locais como se fossem pacotes npm, seguindo o padrão "copy-and-own" similar ao shadcn/ui:
// Importação via alias (resolve para src/lib/ui/*/src/index.ts)
import { HlmBreadcrumb } from '@spartan-ng/helm/breadcrumb';
import { HlmButton } from '@spartan-ng/helm/button';
import { HlmInput } from '@spartan-ng/helm/input';
import { HlmSidebar } from '@spartan-ng/helm/sidebar';
// ... e mais 7 aliases
Aliases disponíveis: breadcrumb, utils, icon, input, sidebar, button, separator, sheet, skeleton, tooltip, collapsible.
Configuração de Assets (angular.json)
Os assets são servidos em dois grupos:
public/**→ raiz do servidor (/)src/assets/**→/assets/
5. Como Executar
# Instalar dependências
npm install
# Iniciar servidor de desenvolvimento (http://localhost:4200)
npm start
# Build para produção
npm run build
# Build em modo watch (desenvolvimento contínuo)
npm run watch
# Executar testes
npm test
# Adicionar componentes Spartan UI via CLI
npx ng g @spartan-ng/cli:ui
Após iniciar, a aplicação redireciona automaticamente para /styleguide.
6. Roteamento
A aplicação usa lazy loading para todos os componentes de rota, otimizando o bundle inicial. Todas as rotas carregam o componente apenas quando acessadas.
/ → redireciona para /styleguide
/styleguide → StyleguideComponent (layout com sidebar)
/styleguide/ → StyleguidePageComponent (visão geral)
/styleguide/tokens → TokensComponent
/styleguide/typography → TypographyComponent
/styleguide/icons → IconsComponent (ng-icons/lucide)
/styleguide/icons-custom → IconsCustomComponent (SVGs do projeto)
/styleguide/components/breadcrumb → BreadcrumbShowcaseComponent
/styleguide/components/input → InputShowcaseComponent
/styleguide/components/tools-bar-map → ToolsBarMapShowcaseComponent
/styleguide/components/principal-bar → PrincipalBarShowcaseComponent
/styleguide/components/project-tabs → ProjectTabsShowcaseComponent
/styleguide/components/mode-tool → ModeToolShowcaseComponent
/styleguide/components/map-control → MapControlShowcaseComponent
/styleguide/components/:name → ComponentDetailComponent (genérico)
O componente raiz AppComponent é minimalista — apenas <router-outlet />.
7. Design System
O design system é implementado via CSS Custom Properties em src/styles.scss, integrado ao Tailwind CSS v4 via camadas (@layer theme, base, components, utilities).
7.1 Paleta de Cores
Cor Primária
| Propriedade | Valor |
|---|---|
| Cor | Laranja-avermelhado vibrante |
| OKLCH | oklch(68% 0.23 38.5) |
| Hex aproximado | #FF5B04 (tom 400 da escala) |
| CSS Variable | --primary |
| Uso | Elementos interativos, CTAs, destaques, anel de foco |
Cores Semânticas
| Token | OKLCH | Hex Aproximado | Uso |
|---|---|---|---|
--success |
oklch(72% 0.22 142) |
#7ccf00 |
Confirmações positivas |
--warning |
oklch(72% 0.19 70) |
#efb100 |
Alertas de atenção |
--destructive |
oklch(59% 0.25 12) |
#fb2c36 |
Erros, ações destrutivas |
--info |
oklch(64% 0.20 242) |
#2b7fff |
Mensagens informativas |
Tokens de Interface — Light Mode
| Token | Valor OKLCH | Descrição |
|---|---|---|
--background |
oklch(100% 0 0) |
Fundo principal (branco puro) |
--foreground |
oklch(0.145 0 0) |
Texto principal (#212121) |
--card |
oklch(100% 0 0) |
Fundo de cards |
--card-foreground |
oklch(0.145 0 0) |
Texto em cards |
--secondary |
oklch(0.97 0 0) |
Fundo secundário (#F5F5F5) |
--muted |
oklch(0.97 0 0) |
Fundo de elementos muted |
--muted-foreground |
oklch(0.556 0 0) |
Texto secundário (#757575) |
--border |
oklch(90% 0 0) |
Bordas (#E5E5E5) |
--input |
oklch(90% 0 0) |
Borda de inputs |
--ring |
oklch(68% 0.23 38.5) |
Anel de foco (laranja primário) |
--radius |
0.625rem (10px) |
Border radius padrão |
Tokens — Dark Mode
Ativado pela classe .dark no elemento raiz:
| Token | Light | Dark |
|---|---|---|
--background |
branco puro | oklch(20% 0 0) |
--foreground |
quase preto | oklch(95% 0 0) |
--card |
branco | oklch(25% 0 0) |
--secondary |
cinza claro | oklch(30% 0 0) |
--border |
cinza claro | oklch(35% 0 0) |
--primary |
laranja | laranja (sem alteração) |
Tokens de Sidebar
O design system inclui tokens dedicados para a sidebar: --sidebar, --sidebar-foreground, --sidebar-primary, --sidebar-primary-foreground, --sidebar-accent, --sidebar-accent-foreground, --sidebar-border, --sidebar-ring.
Tokens de Gráficos
--chart-1 (primary/laranja), --chart-2 (info/azul), --chart-3 (success/verde), --chart-4 (warning/amarelo), --chart-5 (destructive/vermelho).
7.2 Tipografia
| Propriedade | Valor |
|---|---|
| Família principal | Geist Sans |
| Fallbacks | -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue |
| Pesos | 400 (Regular), 500 (Medium), 600 (Semibold), 700 (Bold) |
| Feature settings | rlig 1, calt 1 (ligaduras e alternativas contextuais) |
| CSS Variable | --font-sans |
7.3 Border Radius
| Variação | Valor | Aplicação |
|---|---|---|
Padrão (--radius) |
0.625rem (10px) |
Componentes gerais |
| Small | 0.25rem (4px) |
Elementos compactos |
| Medium | 0.5rem (8px) |
Médio |
| Large | 1rem (16px) |
Cards, painéis |
| XLarge | 1.5rem (24px) |
Modais, drawers |
| Full | 9999px |
Elementos pill/badge |
7.4 Espacamento e Sombras
- Espaçamento: Sistema base do Tailwind (4px/8px), ritmo relaxado com bom uso de espaço em branco
- Sombras: Sutis, para indicar elevação em cards, dropdowns e controles do mapa
8. Biblioteca de Componentes UI (Helm)
O projeto mantém uma versão local dos componentes Spartan UI em src/lib/ui/, seguindo o padrão "copy-and-own" — os arquivos são copiados para o projeto e podem ser customizados livremente sem depender de versões npm.
Cada componente Helm é uma diretiva ou componente Angular standalone que aplica classes Tailwind sobre os primitivos headless do @spartan-ng/brain.
Componentes Helm disponíveis
| Componente | Alias | Sub-componentes | Descrição |
|---|---|---|---|
| Breadcrumb | @spartan-ng/helm/breadcrumb |
7 | HlmBreadcrumb, List, Item, Link, Page, Separator, Ellipsis |
| Button | @spartan-ng/helm/button |
2 | HlmButton, token de configuração |
| Collapsible | @spartan-ng/helm/collapsible |
3 | HlmCollapsible, Content, Trigger |
| Icon | @spartan-ng/helm/icon |
2 | HlmIcon, token de configuração |
| Input | @spartan-ng/helm/input |
1 | HlmInput (diretiva de estilo) |
| Separator | @spartan-ng/helm/separator |
1 | HlmSeparator |
| Sheet | @spartan-ng/helm/sheet |
10 | HlmSheet, Close, Content, Description, Footer, Header, Overlay, Title, Trigger |
| Sidebar | @spartan-ng/helm/sidebar |
17 | HlmSidebar + 16 sub-componentes completos |
| Skeleton | @spartan-ng/helm/skeleton |
1 | HlmSkeleton |
| Tooltip | @spartan-ng/helm/tooltip |
2 | HlmTooltip, Trigger |
| Utils | @spartan-ng/helm/utils |
1 | Função hlm() para composição de classes |
Uso dos componentes Helm
import { HlmBreadcrumb, HlmBreadcrumbList, HlmBreadcrumbItem } from '@spartan-ng/helm/breadcrumb';
import { HlmButton } from '@spartan-ng/helm/button';
import { HlmInput } from '@spartan-ng/helm/input';
import { HlmSidebar, HlmSidebarContent } from '@spartan-ng/helm/sidebar';
9. Componentes Compartilhados
Localizados em src/app/shared/components/, todos são Standalone Components exportados via barrel em index.ts.
9.1 BreadcrumbComponent
Seletor: app-breadcrumb
Componente declarativo que recebe uma lista de itens e renderiza o breadcrumb automaticamente, inferindo o tipo de cada nó (link navegável, página atual, ou reticências).
Interfaces
interface BreadcrumbItem {
label?: string;
routerLink?: string | string[]; // Ausente = página atual (último item)
showDropdown?: boolean; // Exibe chevron dropdown ao lado
ellipsis?: boolean; // Renderiza "..." no lugar do item
}
// Tipo interno derivado automaticamente:
type BreadcrumbNode =
| { type: 'link'; label: string; routerLink: string | string[]; showDropdown?: boolean }
| { type: 'page'; label: string }
| { type: 'ellipsis' };
Inputs
| Input | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
items |
BreadcrumbItem[] |
✅ | — | Lista de itens |
ariaLabel |
string |
Não | 'breadcrumb' |
Texto acessível do <nav> |
Exemplo
<app-breadcrumb
[items]="[
{ label: 'Início', routerLink: '/' },
{ ellipsis: true },
{ label: 'Projetos', routerLink: '/projetos' },
{ label: 'Projeto Alpha' }
]"
ariaLabel="Navegação principal"
/>
9.2 InputComponent
Seletor: app-input
Campo de entrada completo (Label + Input + Description) com estados, ícone opcional e acessibilidade automática via IDs gerados incrementalmente.
Inputs
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
label |
string |
'Label' |
Rótulo acima do campo |
placeholder |
string |
'Placeholder' |
Placeholder do input |
description |
string |
'This is an input description.' |
Texto auxiliar abaixo do campo |
disabled |
boolean |
false |
Desabilita e aplica tom muted |
error |
boolean \| 'auto' |
false |
Estado de erro (borda vermelha) |
type |
string |
'text' |
Tipo HTML do input |
value |
string |
'' |
Valor atual |
inputId |
string \| undefined |
undefined |
ID customizado (auto-gerado se omitido) |
iconLeft |
string \| undefined |
undefined |
Nome do SVG em assets/icons (ex: 'magnifying-glass.svg') |
Outputs
| Output | Tipo | Descrição |
|---|---|---|
valueChange |
string |
Emitido a cada keystroke — novo valor |
Exemplos
<!-- Campo de busca com ícone -->
<app-input
label="Buscar"
placeholder="Pesquisar projetos..."
iconLeft="magnifying-glass.svg"
[value]="searchTerm"
(valueChange)="onSearch($event)"
/>
<!-- Campo com estado de erro -->
<app-input label="Email" [error]="true" description="Email inválido." />
<!-- Campo desabilitado -->
<app-input label="ID" [value]="project.id" [disabled]="true" description="" />
9.3 MapControlComponent
Seletor: app-map-control
Referência Figma: node 616-7299
Painel vertical de controles de mapa com botões de tela cheia, zoom, Street View e miniatura do mapa base. Todos os botões são opcionais via inputs.
Inputs
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
showFullscreen |
boolean |
true |
Botão de tela cheia |
showZoom |
boolean |
true |
Botões zoom in/out |
showStreetView |
boolean |
true |
Botão Street View (Pegman) |
showBaseMapThumbnail |
boolean |
true |
Área de miniatura do mapa base |
baseMapThumbnailUrl |
string \| undefined |
undefined |
URL da imagem da miniatura |
Outputs
| Output | Tipo | Descrição |
|---|---|---|
fullscreenClick |
void |
Tela cheia |
zoomInClick |
void |
Zoom + |
zoomOutClick |
void |
Zoom - |
streetViewClick |
void |
Street View |
baseMapThumbnailClick |
void |
Clique na miniatura |
Exemplo
<app-map-control
[baseMapThumbnailUrl]="currentMapPreview"
(fullscreenClick)="toggleFullscreen()"
(zoomInClick)="map.zoomIn()"
(zoomOutClick)="map.zoomOut()"
(baseMapThumbnailClick)="openLayerPicker()"
/>
9.4 ModeToolComponent
Seletor: app-mode-tool
Seletor de modo com botões de ícone para alternar entre diferentes visualizações (ex: mapa vs lista). Usa model() do Angular para two-way binding nativo.
Interface
interface ModeToolOption {
id: string; // Identificador único
icon: string; // URL ou caminho do ícone SVG
label?: string; // Rótulo acessível
}
Inputs
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
options |
ModeToolOption[] |
[] |
Opções disponíveis |
value |
string (model) |
'' |
ID selecionado (two-way) |
disabled |
boolean |
false |
Desabilita o componente |
Outputs
| Output | Tipo | Descrição |
|---|---|---|
valueChange |
string |
ID da opção selecionada |
Exemplo
modeOptions: ModeToolOption[] = [
{ id: 'map', icon: '/assets/icons/map.svg', label: 'Mapa' },
{ id: 'list', icon: '/assets/icons/list.svg', label: 'Lista' }
];
<app-mode-tool
[options]="modeOptions"
[(value)]="selectedMode"
(valueChange)="onModeChange($event)"
/>
9.5 ProjectTabsComponent
Seletor: app-project-tabs
Referência Figma: node 309-1542
Barra de abas para projetos abertos, com home, fechamento individual e adição de nova aba.
Interface
interface ProjectTab {
id: string;
label: string;
icon?: string;
closable?: boolean; // Exibe botão X
}
Inputs
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
showHome |
boolean |
true |
Botão home à esquerda |
tabs |
ProjectTab[] |
[] |
Lista de abas |
activeIndex |
number |
0 |
Índice da aba ativa (0-based) |
variant |
'dark' \| 'light' |
'dark' |
Estilo visual da barra |
showAddButton |
boolean |
false |
Botão (+) para nova aba |
Outputs
| Output | Tipo | Descrição |
|---|---|---|
tabSelect |
string |
ID da aba clicada |
tabClose |
string |
ID da aba fechada |
homeClick |
void |
Clique no home |
tabAdd |
void |
Clique no (+) |
9.6 ToolsBarMapComponent
Seletor: app-tools-bar-map
Barra de ferramentas do mapa com menu, seletor de modo e botões de geometria. Pode operar de forma standalone ou embutida na PrincipalBarComponent via [embedded]="true".
Ferramentas
| ID | Ícone SVG | Comportamento |
|---|---|---|
location-plus |
location-plus.svg |
Sempre ativo em cor primary (laranja + ícone branco) |
border-inner |
border-inner.svg |
Ativo/inativo com activeToolId |
draw-polygon |
draw-polygon.svg |
Ativo/inativo com activeToolId |
draw-circle |
draw-circle.svg |
Ativo/inativo com activeToolId |
layer-group |
layer-group.svg |
Ativo/inativo com activeToolId |
Inputs
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
modeToolValue |
string |
'' |
Opção ativa no seletor de modo |
modeToolOptions |
ModeToolOption[] |
[] |
Opções do seletor |
embedded |
boolean |
false |
Remove borda externa (uso interno) |
activeToolId |
string \| undefined |
undefined |
ID da ferramenta ativa |
Outputs
| Output | Tipo | Descrição |
|---|---|---|
menuClick |
void |
Clique no hamburger |
toolClick |
string |
ID do botão de ferramenta clicado |
modeChange |
string |
ID do modo selecionado |
9.7 PrincipalBarComponent
Seletor: app-principal-bar
Referência Figma: node 309-1542
Componente de orquestração que compõe três camadas de interface em sequência vertical:
Camada 1 — Barra escura (Project Tabs): Navegação entre projetos abertos com botão home à esquerda.
Camada 2 — Barra branca (Ferramentas): Menu hamburger (ou ToolsBarMap completa) + seletor de modo + botões de ação + campo de busca com crosshairs + notificações.
Camada 3 — Barra de Breadcrumb: Navegação contextual à esquerda + botões de ação contextuais à direita.
Interfaces
interface PrincipalBarAction {
id: string;
icon: string; // URL do ícone SVG
label?: string;
active?: boolean; // Destaque com cor primary
disabled?: boolean;
}
interface PrincipalBarBreadcrumbAction {
id: string;
icon: string;
label?: string;
}
Inputs — Barra Principal
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
showMenuToggle |
boolean |
true |
Botão hamburger |
actions |
PrincipalBarAction[] |
[] |
Botões de ação customizados |
searchPlaceholder |
string |
'Buscar local' |
Placeholder da busca |
showSearch |
boolean |
true |
Campo de busca + crosshairs |
showNotifications |
boolean |
true |
Sino de notificações |
showToolsBarMap |
boolean |
false |
Usa ToolsBarMap em vez de menu+actions |
activeToolsBarMapToolId |
string \| undefined |
undefined |
Ferramenta ativa no ToolsBarMap |
Inputs — Project Tabs
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
showProjectTabs |
boolean |
true |
Exibe a camada de abas |
projectTabs |
ProjectTab[] |
[] |
Abas abertas |
activeProjectTabIndex |
number |
0 |
Índice da aba ativa |
showProjectTabsAddButton |
boolean |
false |
Botão (+) nas abas |
Inputs — Mode Tool
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
showModeTool |
boolean |
true |
Exibe o seletor de modo |
modeToolOptions |
ModeToolOption[] |
[] |
Opções |
modeToolValue |
string |
'' |
Opção selecionada |
Inputs — Breadcrumb
| Input | Tipo | Padrão | Descrição |
|---|---|---|---|
showBreadcrumb |
boolean |
true |
Exibe a camada de breadcrumb |
breadcrumbItems |
BreadcrumbItem[] |
[] |
Itens do breadcrumb |
breadcrumbRightActions |
PrincipalBarBreadcrumbAction[] |
[] |
Botões à direita do breadcrumb |
Outputs
| Output | Tipo | Descrição |
|---|---|---|
menuToggleClick |
void |
Clique no menu |
actionClick |
string |
ID da action ou ferramenta clicada |
searchChange |
string |
Valor da busca |
locationCrosshairsClick |
void |
Clique no botão de localização |
notificationClick |
void |
Clique no sino |
projectTabSelect |
string |
ID da aba selecionada |
projectTabClose |
string |
ID da aba fechada |
projectTabAdd |
void |
Adicionar aba |
modeToolChange |
string |
ID do modo selecionado |
breadcrumbActionClick |
string |
ID da ação do breadcrumb |
Exemplo completo
<app-principal-bar
[showToolsBarMap]="true"
[activeToolsBarMapToolId]="activeTool"
[projectTabs]="openProjects"
[activeProjectTabIndex]="currentTabIndex"
[showProjectTabsAddButton]="true"
[modeToolOptions]="modeOptions"
[modeToolValue]="currentMode"
[breadcrumbItems]="breadcrumbs"
[breadcrumbRightActions]="contextActions"
(actionClick)="onToolSelected($event)"
(projectTabSelect)="selectProject($event)"
(projectTabClose)="closeProject($event)"
(searchChange)="onSearch($event)"
(locationCrosshairsClick)="centerOnUser()"
(breadcrumbActionClick)="onContextAction($event)"
/>
10. Serviços Core
10.1 AssetService
Arquivo: core/services/asset.service.ts | Providido em: root
Resolve URLs absolutas para assets, compatível com qualquer base href.
@Injectable({ providedIn: 'root' })
export class AssetService {
icon(name: string): string
// 'bars.svg' → '/assets/icons/bars.svg'
// 'custom/vigiante-logo.svg' → '/assets/icons/custom/vigiante-logo.svg'
// 'assets/icons/map.svg' → '/assets/icons/map.svg' (caminho completo respeitado)
}
Uso nos componentes:
private readonly asset = inject(AssetService);
protected icon(name: string): string {
return this.asset.icon(name);
}
<img [src]="icon('bars.svg')" alt="Menu" class="w-5 h-5" />
10.2 IconService
Arquivo: core/services/icon.service.ts | Providido em: root
Catálogo centralizado dos ícones SVG do projeto com suporte a categorização e busca textual.
interface Icon {
name: string;
path: string;
category: 'shapes' | 'arrows' | 'ui' | 'actions' | 'other';
tags?: string[];
}
// Métodos disponíveis:
getAllIcons(): Icon[]
getIconsByCategory(category: string): Icon[] // 'all' retorna todos
searchIcons(query: string): Icon[] // busca por name e tags
addIcon(icon: Icon): void
Categorias e quantidades:
| Categoria | Exemplos |
|---|---|
shapes (6) |
circle, draw-circle, draw-polygon, draw-square, hexagon-check, bullseye |
arrows (7) |
arrow-down-to-bracket, arrow-up-from-bracket, chevron-down/up/left/right |
ui (16) |
bars, border-inner, expand, filter, list, sliders, grip-dots, ellipsis |
actions (16) |
check, copy, eye, file-import, gear, magnifying-glass, plus, trash, xmark |
other (30+) |
bell, calendar, car-side, clock, location-dot, map, user, users, sensor-on |
11. Ícones e Assets
Ícones SVG Customizados
Localizados em src/assets/icons/, o projeto conta com mais de 70 ícones SVG referenciados por nome de arquivo via AssetService.
Geográficos/Mapa: circle.svg, draw-circle.svg, draw-polygon.svg, draw-square.svg, location-crosshairs.svg, location-dot.svg, location-plus.svg, map.svg, map-pin.svg, focus.svg, pin-viewfinder.svg, crosshairs-simple.svg, ruler.svg, bullseye.svg
UI/Navegação: bars.svg, chevron-down.svg, chevron-left.svg, chevron-right.svg, chevron-up.svg, ellipsis.svg, ellipsis-vertical.svg, expand.svg, filter.svg, grip-dots.svg, grip-dots-vertical.svg, grip-lines.svg, list.svg, sliders.svg, border-inner.svg
Ações: check.svg, copy.svg, eye.svg, eye-slash.svg, file-import.svg, floppy-disk.svg, gear.svg, magnifying-glass.svg, magnifying-glass-location.svg, minus.svg, pen-line.svg, plus.svg, rotate-right.svg, share-nodes.svg, trash.svg, xmark.svg
Conteúdo: bell.svg, calendar.svg, calendar-lines.svg, calendar-week.svg, car-side.svg, circle-info.svg, clipboard-user.svg, clock.svg, file.svg, file-circle-exclamation.svg, file-circle-info.svg, folder-open.svg, folder-tree.svg, house.svg, input-numeric.svg, layer-group.svg, layer-minus.svg, layer-plus.svg, lock-keyhole.svg, map-pin.svg, palette.svg, play.svg, screen-users.svg, sensor-on.svg, user.svg, users.svg, users-rectangle.svg
Customizados (assets/icons/custom/):
| Arquivo | Descrição |
|---|---|
vigiante-logo.svg |
Logo principal do Vigiante |
street-view.svg |
Ícone de Street View (Pegman) |
heatmap.svg |
Camada de mapa de calor |
gps.png |
Indicador de GPS |
satellite.png |
Miniatura do mapa satélite |
terreno.png |
Miniatura do mapa de terreno |
12. Styleguide Interativo
Acessível em /styleguide, é uma aplicação Angular completa dentro do projeto que serve como documentação viva.
Estrutura de Navegação
Styleguide
└── Visão geral
Foundation
├── Design Tokens (/styleguide/tokens)
├── Tipografia (/styleguide/typography)
├── Icons (/styleguide/icons) ← ng-icons/lucide
└── Ícones customizados (/styleguide/icons-custom) ← SVGs do projeto
Components
├── Breadcrumb (/styleguide/components/breadcrumb)
├── Input (/styleguide/components/input)
├── Tools Bar Map (/styleguide/components/tools-bar-map)
├── Principal Bar (/styleguide/components/principal-bar)
├── Project Tabs (/styleguide/components/project-tabs)
├── Mode Tool (/styleguide/components/mode-tool)
└── Map Control (/styleguide/components/map-control)
Layout
StyleguideComponent renderiza:
- Sidebar esquerda — logo Vigiante + navegação por seções (configurada em navigation.config.ts)
- Área central — <router-outlet /> com os showcases de cada página
Cada página de showcase (pages/components/*/) exibe o componente em diferentes estados e variações com exemplos ao vivo.
13. Testes
O projeto usa Vitest como runner de testes, integrado ao Angular CLI via builder @angular/build:unit-test.
npm test
# ou: ng test
Arquivos de teste seguem a convenção .spec.ts.
14. Build e Deploy
Configurações de Build
O Angular CLI usa @angular/build:application (esbuild nativo):
Produção (padrão)
npm run build
| Parâmetro | Valor |
|---|---|
| Output hashing | all (cache busting automático) |
| Otimização | Habilitada |
| Source maps | Desabilitados |
| Budget inicial | Warning: 500kB / Error: 1MB |
| Budget por componente (CSS) | Warning: 4kB / Error: 8kB |
| Diretório de saída | dist/vigiante-front/ |
Desenvolvimento
npm run watch # build contínuo com source maps
npm start # dev-server em localhost:4200
15. Convenções de Código
Standalone Components
Todos os componentes seguem o padrão Angular 17+:
@Component({
selector: 'app-nome',
standalone: true,
imports: [ /* dependências diretas */ ],
templateUrl: './nome.component.html',
styleUrl: './nome.component.scss'
})
export class NomeComponent { }
Signals API
O projeto adota os novos primitivos de reatividade do Angular:
| API | Uso |
|---|---|
input<T>() |
Props de leitura com valor padrão |
input.required<T>() |
Props obrigatórias (erro em tempo de compilação) |
model<T>() |
Two-way binding (substitui o par @Input + @Output com mesmo nome) |
output<T>() |
Eventos de saída |
computed<T>() |
Valores derivados reativos |
signal<T>() |
Estado local mutável |
inject() |
Injeção de dependência (sem construtor) |
Nomenclatura
| Elemento | Convenção | Exemplo |
|---|---|---|
| Componentes | PascalCase + sufixo Component | BreadcrumbComponent |
| Seletores | app- + kebab-case |
app-breadcrumb |
| Arquivos | kebab-case + tipo | breadcrumb.component.ts |
| Serviços | PascalCase + Service | AssetService |
| Interfaces | PascalCase | BreadcrumbItem, ProjectTab |
| Outputs de evento | verbo + ação (camelCase) | tabSelect, menuToggleClick |
| Inputs booleanos de visibilidade | show + Elemento |
showHome, showSearch |
| ID de ferramentas | kebab-case | 'draw-polygon', 'border-inner' |
Template Style
- Usa
@if,@for,@switch(nova sintaxe de fluxo de controle Angular 17+) - Classes CSS aplicadas diretamente com Tailwind utilitário
[ngClass]apenas para bindings condicionais dinâmicosaria-labelobrigatório em botões sem texto visível
Prettier
{
"printWidth": 100,
"singleQuote": true,
"overrides": [{ "files": "*.html", "options": { "parser": "angular" } }]
}
16. Apêndice
Links Úteis
| Recurso | URL |
|---|---|
| Styleguide (dev) | http://localhost:4200/styleguide |
| Angular 21 | https://angular.dev |
| Tailwind CSS v4 | https://tailwindcss.com/docs |
| Spartan UI | https://www.spartan.ng |
| ng-icons | https://ng-icons.github.io/ng-icons |
| Vitest | https://vitest.dev |
| Design System (local) | DESIGN_SYSTEM.md na raiz do projeto |
Comandos de Referência
# Desenvolvimento
npm start # Inicia em http://localhost:4200
npm run watch # Build watch com source maps
# Produção
npm run build # Build otimizado em dist/
# Testes
npm test # Executa testes com Vitest
# Componentes
npx ng g @spartan-ng/cli:ui # Adicionar componente Spartan UI
ng generate component path/nome # Gerar novo componente
# Angular CLI
ng generate --help # Ver todos os schematics disponíveis