PO UI é uma biblioteca de componentes para aplicações Angular, estruturada como monorepo com múltiplos pacotes publicáveis (@po-ui/ng-components, @po-ui/ng-templates, @po-ui/ng-sync, @po-ui/ng-storage, @po-ui/ng-code-editor). Cada biblioteca está em projects/ e inclui schematics para integração com Angular CLI.
Arquitetura Principal:
- Padrão de Componentes: Componentes divididos em
-base.component.ts(propriedades/Getters/Setters) e.component.ts(lógica/renderização). A classe base gerencia inputs/outputs/validação, a classe filha gerencia interação com a view. - Documentação: Auto-gerada via Dgeni a partir de comentários JSDoc no código fonte. O projeto portal (
projects/portal/) constrói o site de documentação. - Sistema de Build: Usa Angular CLI + ng-packagr para build das bibliotecas, Gulp para compilação de schematics e substituição de versões.
A documentação oficial do projeto é escrita em português.
Essa decisão reflete o fato de que o PO UI é uma biblioteca brasileira, com foco principal em entregas para desenvolvedores brasileiros. O objetivo é garantir clareza, acessibilidade e alinhamento com o público-alvo predominante da biblioteca.
Todo conteúdo de documentação — incluindo descrições em JSDoc, guias, exemplos e instruções — deve ser redigido em português formal, técnico e impessoal.
Embora a documentação seja escrita em português, todo o código fonte deve ser escrito em inglês.
Essa prática segue os padrões internacionais de desenvolvimento de software e garante:
- Consistência com o ecossistema Angular e TypeScript
- Melhor legibilidade para colaboradores internacionais
- Aderência às boas práticas da comunidade open source
- Padronização de nomes de variáveis, métodos, classes e interfaces
Portanto:
- Nomes de variáveis, funções, classes, enums e interfaces devem estar em inglês.
- Comentários técnicos internos que expliquem lógica específica podem seguir o padrão já adotado no projeto, mas identificadores de código devem permanecer em inglês.
Os textos descritivos dos testes unitários (descrições de describe() e it()) devem ser escritos em inglês.
Essa diretriz garante:
- Padronização com ferramentas e relatórios de testes
- Clareza semântica ao ler mensagens de falha
- Consistência com o código fonte
- Aderência às convenções amplamente utilizadas na comunidade Angular/Jasmine
Exemplo:
describe('PoButtonComponent', () => {
it('should disable the button when disabled property is true', () => {
// ...
});
});# Iniciar servidor de desenvolvimento
npm start
# Executar testes para biblioteca específica
npm run test:ui # Componentes UI (ChromeHeadless)
npm run test:ui:browse # Componentes UI (Chrome, interativo)
npm run test:schematics # Testes de todos os schematics
# Linting
npm run lint:ui # Lint da biblioteca UI
npm run format:check # Verificar formatação Prettier
npm run format:all # Auto-formatar todos os arquivos
# Build
npm run build:ui:lite # Build apenas da lib UI (sem schematics/pack)
npm run build:ui # Build completo com schematics + npm pack
npm run build # Build de todas as bibliotecas- Requisito de Coverage: 99% em statements, branches, functions e lines (ver
projects/ui/karma.conf.js) - Estrutura de Testes: Use
describe()para agrupamento de componentes/métodos,describe()aninhados para teste de propriedades - Utilitários: Importe
expectPropertiesValuesde../../util-test/util-expect.specpara validação de valores booleanos - Arquivo de Setup:
projects/ui/src/lib/util-test/util-setup.spec.tsexecuta antes de todos os testes (configurado em karma.conf.js)
npm run build:ui # Build e pack
npm run publish:ui:local # Publicar em localhost:4873
npm run publish:local # Publicar todos os pacotes// 1. Private properties for getters/setters (use underscore prefix)
private _prop: string = 'default';
// 2. Public readonly properties
public readonly items: Array<Item> = [];
// 3. Private class variables (no underscore needed)
private internalState: boolean;
// 4. Decorators in order:
@ViewChild('template') template: TemplateRef<any>;
@Input('p-label') label: string;
@Output('p-click') click = new EventEmitter();
// 5. Getters/Setters (set before get)
@Input('p-disabled') set disabled(value: boolean) {
this._disabled = convertToBoolean(value);
}
get disabled(): boolean {
return this._disabled;
}- Inputs booleanos: Use
@Input({ alias: 'p-prop', transform: convertToBoolean })ou decorator legado@InputBoolean() - Propriedades opcionais: Marque com operador
?OU use tag JSDoc@optional(deve vir antes de@description) - Aliases: Sempre prefixe com
p-(ex:@Input('p-label')) - Valores padrão: Documente com tag JSDoc
@defaultusando backticks:@default \md``
/**
* @optional
*
* @description
*
* Define o tamanho do elemento. Valores aceitos: `sm`, `md`, `lg`.
*
* @default `md`
*/
@Input('p-size') size: string = 'md';Regras:
- Use
/** */para documentação (linhas únicas//são ignoradas pelo Dgeni) - Escreva descrições impessoais e formais (evite "você deve/você pode")
- Use backticks para valores/nomes de propriedades, triple backticks para blocos de código
- Arrays tipados como
Array<T>nãoT[] - Linke para outros componentes/APIs com links markdown
Todos os pacotes exportam padrão barrel module:
PoModule(ui) → agregaPoComponentsModule,PoServicesModule,PoDirectivesModule, etc.- Cada componente tem seu próprio
.module.tsque declara/exporta o componente - API pública definida em
src/public-api.ts(entry point em ng-package.json)
<COMPONENT>/<ISSUE> # po-button/DTHFUI-222 ou po-button/235
<COMPONENT>/<DEV> # po-button/fulano (se não houver issue)
<type>(scope): <descrição curta>
<body>
<footer>
Types: feat, fix, docs, refactor, perf, test, build
Scope: Nome do componente sem o prefixo po- (ex: feat(button), NÃO feat(po-button))
Use rebase/squash antes do PR para garantir um único commit por feature
- Incluir nome do componente + número da issue no título
- Descrever comportamento atual vs novo comportamento
- Fornecer código de reprodução/demo quando aplicável
- Todos os checks de lint/format/test devem passar (lint, format:check, test)
Cada biblioteca tem schematics em projects/<lib>/schematics/:
ng-add/: Schematic de instalaçãong-generate/: Geradores de componentes/featuresng-update/: Scripts de migração
Build: gulp build:schematics --lib ui compila TS para JS em dist/ng-components/schematics/
Test: npm run test:ui:schematics executa specs Jasmine nos schematics compilados
- Versões gerenciadas via
standard-version(conventional changelog) scripts/version-replace.jsatualiza placeholders de versão (0.0.0-PLACEHOLDER) em arquivos package.json durante o build- Execute
npm run releasepara gerar CHANGELOG.md (pula commit/tag conforme config)
O site portal auto-gera documentação dos componentes a partir do código fonte:
- Processadores Dgeni parsam tags JSDoc de
projects/ui/src/lib/ - Tasks Gulp em
projects/portal/gulpfile.jstransformam markdown → HTML - Páginas de componentes/guias geradas em
src/app/documentation/esrc/app/guide/ - Build com
npm run build:portal:docs(requernpm run build:uiprimeiro)
PO UI usa @po-ui/style para theming com CSS custom properties (tokens). Componentes são estilizados usando variáveis CSS que podem ser customizadas por componente ou globalmente.
Localizado em projects/ui/src/lib/services/po-theme/:
- Propósito: Gerenciar cores de tema, modo claro/escuro, níveis de acessibilidade (AA/AAA) e modos de densidade
- Métodos Principais:
setTheme(config, type, a11yLevel, persistPreference)- Aplicar tema customizadocleanThemeActive()- Resetar para tema padrão
- Persistência: Salva automaticamente preferências do usuário no localStorage
Todo componente documenta tokens CSS customizáveis em seu -base.component.ts:
/**
* #### Tokens customizáveis
*
* É possível alterar o estilo do componente usando os seguintes tokens (CSS):
*
* > Para maiores informações, acesse o guia [Personalizando o Tema Padrão com Tokens CSS](https://po-ui.io/guides/theme-customization).
*
* | Propriedade | Descrição | Valor Padrão |
* |------------------------------|------------------------------|-----------------------------------|
* | `--font-family` | Família tipográfica usada | `var(--font-family-theme)` |
* | `--color` | Cor principal do botão | `var(--color-action-default)` |
* | `--border-radius` | Raio dos cantos | `var(--border-radius-md)` |
* | **Hover** | | |
* | `--color-hover` | Cor no estado hover | `var(--color-action-hover)` |
*/Convenções de Nomenclatura de Tokens:
- Baseado em estados:
--{property}-{state}(ex:--color-hover,--background-pressed,--text-color-disabled) - Baseado em variantes:
--{property}-{variant}(ex:--color-button-danger,--border-color-danger-hover) - Referencie tokens globais usando
var(--global-token-name)
- Tipografia:
--font-family,--font-size,--font-weight,--line-height - Cores:
--color-*,--text-color-*,--background-*,--border-color-* - Espaçamento:
--padding,--margin - Forma:
--border-radius,--border-width - Efeitos:
--shadow,--outline-color-focused
- Tema base:
@po-ui/style/css/po-theme-default.min.css(configurado emangular.json) - Constantes de tema:
projects/ui/src/lib/services/po-theme/helpers/po-theme-poui.constant.ts- Tema PO padrãopo-theme-default-aa.constant.ts/po-theme-default-aaa.constant.ts- Variantes de acessibilidadepo-theme-light-defaults.constant.ts/po-theme-dark-defaults.constant.ts- Modos claro/escuro
- Documente tokens em comentário JSDoc acima da classe do componente (no
-base.component.ts) - Agrupe tokens logicamente (Padrão → Hover → Focused → Pressed → Disabled → Danger/variantes)
- Use formato de tabela markdown com colunas Propriedade, Descrição, Valor Padrão
- Referencie guia de customização de tema no cabeçalho da documentação
- Teste com níveis de acessibilidade AA e AAA para garantir que valores de tokens funcionem corretamente
O PO UI segue as definições visuais do Animalia DS, o Design System que serve como base para os tokens de design, especificações de componentes e diretrizes de acessibilidade.
Relação com o PO UI:
- Os componentes PO UI implementam progressivamente as definições visuais do Animalia DS
- A biblioteca de ícones padrão é o Animalia Icons (
@animaliads/animalia-icon), com prefixoan an-* - O dicionário de ícones está em
projects/ui/src/lib/components/po-icon/po-icon-dictionary.ts - A documentação de acessibilidade dos componentes referencia as especificações do Animalia DS
- Variáveis CSS legacy (prefixo
--color-primary-*,--color-secondary-*) estão sendo substituídas por tokens do Animalia DS
Ao implementar ou modificar componentes:
- Consulte a documentação do componente no Animalia DS para verificar as especificações visuais
- Siga os estados definidos pelo DS: Enable, Disable, Static, Hover, Focus, Active, Loading
- Use os tokens CSS do Animalia DS como referência para valores padrão
- Documente a conformidade com o Animalia DS no CHANGELOG usando o padrão:
implementa definições do AnimaliaDS
Referências:
- Documentação Animalia DS: https://doc.animaliads.io/
- Live demos de componentes: https://doc.animaliads.io/docs/components/
- Portal PO UI: https://po-ui.io/
Para conectar agentes de IA às especificações de design do Animalia DS no Figma, configure o MCP do Figma no seu ambiente de desenvolvimento.
Figma MCP permite que agentes de IA:
- Consultem especificações de componentes diretamente do Figma
- Verifiquem espaçamentos, cores e tipografia definidos no design
- Comparem a implementação com o design original
- Extraiam informações de estados (hover, focus, disabled, etc.)
Configuração sugerida para mcp.json:
{
"mcpServers": {
"figma": {
"command": "npx",
"args": ["-y", "figma-developer-mcp", "--stdio"],
"env": {
"FIGMA_API_KEY": "<sua-chave-api-figma>"
}
}
}
}Nota: A chave da API do Figma deve ser configurada como variável de ambiente, nunca embutida no código.
- NgModules: NÃO crie arquivos
.module.ts. Todo componente DEVE usarstandalone: true. - CommonModule: NÃO importe
CommonModule. Importe componentes/diretivas individuais diretamente no arrayimportsdo decorator@Component. - Structural Directives: NÃO use
*ngIf,*ngFor,*ngSwitch. Use Control Flow Syntax:@if (condition) { ... } @else { ... }@for (item of items; track item.id) { ... } @empty { ... }@switch (value) { @case ('a') { ... } @default { ... } }
- Tipo
any: NÃO use o tipoany. Defina interfaces ou types explícitos para todo dado. - Decorator-based Inputs/Outputs: NÃO use
@Input()/@Output()em novos componentes. Use APIs function-based:label = input<string>('', { alias: 'p-label' })em vez de@Input('p-label') label: stringclicked = output<void>({ alias: 'p-click' })em vez de@Output('p-click') click = new EventEmitter()- Inputs booleanos:
disabled = input<boolean, unknown>(false, { alias: 'p-disabled', transform: convertToBoolean })
- Standalone Components: Todo novo componente DEVE ter
standalone: trueno decorator@Component. - Signals: Use
signal()para estado local mutável,computed()para valores derivados eeffect()para side effects reativos. - Control Flow: Use
@if,@for,@switchem todos os templates. - Typed Reactive Forms: Use
FormControl<string>, nuncaFormControlsem tipo genérico. - ControlValueAccessor: Todo componente de campo (input, select, textarea, datepicker, combo, lookup) DEVE implementar
ControlValueAccessorpara integração comngModeleFormControl.
Nota sobre código existente (legacy): Componentes existentes ainda usam
@Input(),@Output(),NgModulese*ngIf/*ngFor. Ao modificar componentes existentes, mantenha o padrão vigente no arquivo. As regras acima aplicam-se a novos componentes e refatorações explícitas.
Componentes seguem padrões WCAG:
- Indicadores de foco: espessura mínima de 2px (WCAG 2.4.12)
- Navegação por teclado: Espaço/Enter ativam botões (WAI-ARIA 3.5)
- Tamanhos padrão: Verifique utilitário
getDefaultSizeFn()para conformidade AA/AAA - Níveis de acessibilidade: AAA (padrão - maior contraste, áreas clicáveis maiores) vs AA (proporções balanceadas)
- Modos de densidade: Controle espaçamento entre/dentro de componentes via enum
PoDensityMode - Documente recursos de acessibilidade na seção
@descriptiondo componente
Todo componente interativo DEVE incluir:
roleapropriado quando o elemento HTML semântico não for suficiente (ex:role="dialog",role="listbox")aria-labelouaria-labelledbypara elementos sem texto visívelaria-describedbyquando houver texto auxiliar (mensagem de erro, helper text)aria-expandedpara elementos que controlam painéis expansíveis (dropdowns, accordions)aria-live="polite"para regiões com conteúdo dinâmico (toasters, contadores, mensagens de validação)aria-disabled="true"em conjunto com[disabled]quando relevantearia-checkedpara checkboxes e toggles (incluindo estadomixedpara indeterminado)aria-selectedpara itens selecionáveis em listas, tabs e menusaria-hidden="true"para elementos decorativos que não devem ser anunciados por leitores de tela
Modais, drawers, popovers e qualquer overlay DEVEM:
- Capturar o foco ao abrir (primeiro elemento focável recebe foco)
- Impedir que Tab/Shift+Tab saiam do overlay enquanto estiver aberto
- Retornar o foco ao elemento que abriu o overlay ao fechar
- Fechar com tecla Esc
| Tecla | Comportamento esperado |
|---|---|
Tab |
Move foco para o próximo elemento focável |
Shift+Tab |
Move foco para o elemento focável anterior |
Enter / Space |
Ativa botões, links e controles interativos |
Esc |
Fecha overlay, modal, dropdown ou popover aberto |
Arrow Up/Down |
Navega itens em listas, menus, selects e combos |
Arrow Left/Right |
Navega tabs, segmented controls e radio groups |
Home / End |
Vai para primeiro/último item em listas e menus |
- Texto normal: ratio mínimo de 4.5:1 (WCAG AA) ou 7:1 (WCAG AAA)
- Texto grande (≥18px bold ou ≥24px): ratio mínimo de 3:1 (AA) ou 4.5:1 (AAA)
- Elementos gráficos e componentes de interface: ratio mínimo de 3:1
- Código fonte de componentes:
projects/ui/src/lib/components/po-<name>/ - Serviços:
projects/ui/src/lib/services/ - Utilitários:
projects/ui/src/lib/utils/util.ts(convertToBoolean, validateSizeFn, etc.) - Decorators:
projects/ui/src/lib/decorators/(@InputBoolean, @InputRequired) - Helpers de teste:
projects/ui/src/lib/util-test/ - Config de build:
angular.json(definições de projeto),tsconfig*.json(opções do compilador)