Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Theme
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Create API Key
Add Docs
PO UI Angular
https://github.com/po-ui/po-angular
Admin
PO UI Angular is a library of UI components for Angular, providing a set of pre-built components to
...
Tokens:
48,671
Snippets:
380
Trust Score:
8.8
Update:
1 month ago
Context
Skills
Chat
Benchmark
67.2
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# PO UI - Biblioteca de Componentes Angular O **PO UI** (PO Angular) é uma biblioteca de componentes de interface de usuário para Angular, desenvolvida pela TOTVS. A biblioteca oferece uma ampla coleção de componentes reutilizáveis, templates pré-configurados, serviços para sincronização offline e armazenamento local, permitindo o desenvolvimento rápido de aplicações empresariais modernas e acessíveis. A biblioteca segue os padrões de acessibilidade WCAG e oferece suporte a internacionalização (i18n) em português, inglês, espanhol e russo. O PO UI está organizado em múltiplos pacotes: `@po-ui/ng-components` para componentes UI básicos, `@po-ui/ng-templates` para templates de páginas dinâmicas, `@po-ui/ng-sync` para sincronização offline, e `@po-ui/ng-storage` para armazenamento local. Todos os componentes são altamente customizáveis através de CSS tokens e seguem um design system consistente. --- ## Componentes de Formulário ### po-input - Campo de Entrada de Texto O componente `po-input` é um campo de entrada de texto com suporte a máscara, validação, ícones e estados de carregamento. Ele implementa `ControlValueAccessor` para integração completa com Angular Reactive Forms. ```typescript import { Component } from '@angular/core'; import { PoInputModule } from '@po-ui/ng-components'; @Component({ selector: 'app-form-example', template: ` <po-input p-label="Nome Completo" p-placeholder="Digite seu nome" p-help="Informe seu nome conforme documento" p-icon="an an-user" p-required p-maxlength="100" p-clean [(ngModel)]="nome" (p-change)="onNomeChange($event)" (p-blur)="onBlur()"> </po-input> <po-input p-label="CPF" p-mask="999.999.999-99" p-error-pattern="CPF inválido" p-required [(ngModel)]="cpf"> </po-input> <po-input p-label="Telefone" p-mask="(99) 99999-9999" p-mask-format-model p-loading p-size="medium" [(ngModel)]="telefone"> </po-input> ` }) export class FormExampleComponent { nome: string = ''; cpf: string = ''; telefone: string = ''; onNomeChange(value: string): void { console.log('Nome alterado:', value); } onBlur(): void { console.log('Campo perdeu foco'); } } ``` --- ### po-combo - Campo de Seleção com Filtro O `po-combo` exibe uma lista de opções com fácil seleção e filtragem, suportando dados locais ou requisições a APIs remotas com paginação e scroll infinito. ```typescript import { Component, OnInit } from '@angular/core'; import { PoComboModule, PoComboOption, PoComboFilterMode, PoComboLiterals } from '@po-ui/ng-components'; @Component({ selector: 'app-combo-example', template: ` <!-- Combo com opções locais --> <po-combo p-label="Estado" p-placeholder="Selecione um estado" p-required p-clean p-sort p-filter-mode="contains" [p-options]="estados" [(ngModel)]="estadoSelecionado" (p-change)="onEstadoChange($event)"> </po-combo> <!-- Combo com serviço remoto --> <po-combo p-label="Cidade" p-placeholder="Digite para pesquisar" p-filter-service="https://api.exemplo.com/cidades" p-field-label="nome" p-field-value="id" p-filter-minlength="3" p-debounce-time="500" p-infinite-scroll [p-filter-params]="{ estado: estadoSelecionado }" [(ngModel)]="cidadeSelecionada" (p-change)="onCidadeChange($event)"> </po-combo> <!-- Combo com agrupamento --> <po-combo p-label="Produto" [p-options]="produtosAgrupados" [p-literals]="literalsPersonalizadas" [(ngModel)]="produtoSelecionado"> </po-combo> ` }) export class ComboExampleComponent implements OnInit { estadoSelecionado: string; cidadeSelecionada: number; produtoSelecionado: string; estados: Array<PoComboOption> = [ { value: 'SP', label: 'São Paulo' }, { value: 'RJ', label: 'Rio de Janeiro' }, { value: 'MG', label: 'Minas Gerais' }, { value: 'PR', label: 'Paraná' } ]; produtosAgrupados = [ { label: 'Eletrônicos', options: [ { value: 'tv', label: 'Televisão' }, { value: 'notebook', label: 'Notebook' } ]}, { label: 'Móveis', options: [ { value: 'sofa', label: 'Sofá' }, { value: 'mesa', label: 'Mesa' } ]} ]; literalsPersonalizadas: PoComboLiterals = { noData: 'Nenhum item encontrado', chooseOption: 'Escolha uma opção' }; onEstadoChange(estado: string): void { console.log('Estado selecionado:', estado); } onCidadeChange(cidade: number): void { console.log('Cidade selecionada:', cidade); } } ``` --- ## Componentes de Interface ### po-button - Botão de Ação O `po-button` permite que o usuário execute ações predefinidas, com suporte a diferentes estilos visuais (primary, secondary, tertiary) e estados (loading, disabled, danger). ```typescript import { Component } from '@angular/core'; import { PoButtonModule, PoButtonKind, PoButtonType } from '@po-ui/ng-components'; @Component({ selector: 'app-button-example', template: ` <!-- Botão primário --> <po-button p-label="Salvar" p-kind="primary" p-icon="an an-floppy-disk" (p-click)="salvar()"> </po-button> <!-- Botão secundário com loading --> <po-button p-label="Processar" p-kind="secondary" p-icon="an an-gear" [p-loading]="processando" (p-click)="processar()"> </po-button> <!-- Botão de perigo para ações destrutivas --> <po-button p-label="Excluir" p-kind="secondary" p-danger p-icon="an an-trash" (p-click)="excluir()"> </po-button> <!-- Botão terciário (link-style) --> <po-button p-label="Cancelar" p-kind="tertiary" (p-click)="cancelar()"> </po-button> <!-- Botão de submit em formulário --> <po-button p-label="Enviar" p-type="submit" p-kind="primary" [p-disabled]="!formularioValido" p-size="large"> </po-button> ` }) export class ButtonExampleComponent { processando = false; formularioValido = true; salvar(): void { console.log('Dados salvos'); } processar(): void { this.processando = true; setTimeout(() => { this.processando = false; console.log('Processamento concluído'); }, 2000); } excluir(): void { console.log('Item excluído'); } cancelar(): void { console.log('Operação cancelada'); } } ``` --- ### po-table - Tabela de Dados O `po-table` é um componente para exibição de dados tabulares com suporte a ordenação, seleção, ações em linha, detalhes expansíveis, paginação via API e virtual scroll para grandes volumes de dados. ```typescript import { Component, OnInit, ViewChild } from '@angular/core'; import { PoTableModule, PoTableColumn, PoTableAction, PoTableComponent, PoTableColumnSort, PoTableLiterals } from '@po-ui/ng-components'; @Component({ selector: 'app-table-example', template: ` <po-table #tabela p-sort p-striped p-selectable p-height="400" p-container="shadow" p-service-api="https://api.exemplo.com/usuarios" [p-columns]="colunas" [p-items]="usuarios" [p-actions]="acoes" [p-literals]="literals" (p-selected)="onSelecionado($event)" (p-sort-by)="onOrdenar($event)" (p-show-more)="carregarMais($event)"> </po-table> ` }) export class TableExampleComponent implements OnInit { @ViewChild('tabela') tabela: PoTableComponent; usuarios = []; hasNext = true; colunas: Array<PoTableColumn> = [ { property: 'id', label: 'Código', width: '80px' }, { property: 'nome', label: 'Nome' }, { property: 'email', label: 'E-mail' }, { property: 'status', label: 'Status', type: 'label', labels: [ { value: 'ativo', color: 'color-10', label: 'Ativo' }, { value: 'inativo', color: 'color-07', label: 'Inativo' } ]}, { property: 'dataCadastro', label: 'Data Cadastro', type: 'date', format: 'dd/MM/yyyy' }, { property: 'salario', label: 'Salário', type: 'currency', format: 'BRL' } ]; acoes: Array<PoTableAction> = [ { action: this.editar.bind(this), icon: 'an an-pencil', label: 'Editar' }, { action: this.visualizar.bind(this), icon: 'an an-eye', label: 'Visualizar' }, { action: this.excluir.bind(this), icon: 'an an-trash', label: 'Excluir', type: 'danger', separator: true } ]; literals: PoTableLiterals = { noData: 'Nenhum usuário encontrado', loadingData: 'Carregando...', loadMoreData: 'Carregar mais' }; ngOnInit(): void { this.carregarUsuarios(); } carregarUsuarios(): void { // Simula carregamento de dados this.usuarios = [ { id: 1, nome: 'João Silva', email: 'joao@email.com', status: 'ativo', dataCadastro: '2024-01-15', salario: 5000 }, { id: 2, nome: 'Maria Santos', email: 'maria@email.com', status: 'ativo', dataCadastro: '2024-02-20', salario: 6500 }, { id: 3, nome: 'Pedro Costa', email: 'pedro@email.com', status: 'inativo', dataCadastro: '2023-11-10', salario: 4200 } ]; } editar(usuario: any): void { console.log('Editando usuário:', usuario); } visualizar(usuario: any): void { console.log('Visualizando usuário:', usuario); } excluir(usuario: any): void { console.log('Excluindo usuário:', usuario); } onSelecionado(usuario: any): void { console.log('Usuário selecionado:', usuario); } onOrdenar(sort: PoTableColumnSort): void { console.log('Ordenando por:', sort.column.property, sort.type); } carregarMais(sort?: PoTableColumnSort): void { console.log('Carregando mais dados...'); } } ``` --- ### po-modal - Janela Modal O `po-modal` é utilizado para exibir conteúdos em uma janela sobreposta, com suporte a diferentes tamanhos e ações customizáveis no rodapé. ```typescript import { Component, ViewChild } from '@angular/core'; import { PoModalModule, PoModalComponent, PoModalAction } from '@po-ui/ng-components'; @Component({ selector: 'app-modal-example', template: ` <po-button p-label="Abrir Modal" (p-click)="abrirModal()"></po-button> <po-modal #modal p-title="Cadastro de Cliente" p-size="lg" p-icon="an an-user-plus" [p-primary-action]="acaoPrimaria" [p-secondary-action]="acaoSecundaria" (p-close)="onFechar()"> <po-input p-label="Nome" [(ngModel)]="cliente.nome"></po-input> <po-input p-label="E-mail" [(ngModel)]="cliente.email"></po-input> <po-input p-label="Telefone" p-mask="(99) 99999-9999" [(ngModel)]="cliente.telefone"></po-input> </po-modal> <!-- Modal de confirmação --> <po-modal #modalConfirmacao p-title="Confirmar Exclusão" p-size="sm" p-hide-close [p-primary-action]="confirmarExclusao" [p-secondary-action]="cancelarExclusao"> <p>Tem certeza que deseja excluir este registro? Esta ação não pode ser desfeita.</p> </po-modal> ` }) export class ModalExampleComponent { @ViewChild('modal') modal: PoModalComponent; @ViewChild('modalConfirmacao') modalConfirmacao: PoModalComponent; cliente = { nome: '', email: '', telefone: '' }; acaoPrimaria: PoModalAction = { label: 'Salvar', action: () => this.salvarCliente() }; acaoSecundaria: PoModalAction = { label: 'Cancelar', action: () => this.modal.close() }; confirmarExclusao: PoModalAction = { label: 'Excluir', action: () => this.executarExclusao(), danger: true }; cancelarExclusao: PoModalAction = { label: 'Cancelar', action: () => this.modalConfirmacao.close() }; abrirModal(): void { this.modal.open(); } salvarCliente(): void { console.log('Cliente salvo:', this.cliente); this.modal.close(); } executarExclusao(): void { console.log('Registro excluído'); this.modalConfirmacao.close(); } onFechar(): void { console.log('Modal fechado'); } } ``` --- ## Serviços ### PoNotificationService - Notificações Toast O `PoNotificationService` é responsável por emitir notificações temporárias na interface, suportando tipos success, warning, error e information. ```typescript import { Component } from '@angular/core'; import { PoNotificationService, PoToasterOrientation } from '@po-ui/ng-components'; @Component({ selector: 'app-notification-example', template: ` <po-button p-label="Sucesso" (p-click)="mostrarSucesso()"></po-button> <po-button p-label="Erro" (p-click)="mostrarErro()"></po-button> <po-button p-label="Aviso" (p-click)="mostrarAviso()"></po-button> <po-button p-label="Info" (p-click)="mostrarInfo()"></po-button> <po-button p-label="Com Ação" (p-click)="mostrarComAcao()"></po-button> ` }) export class NotificationExampleComponent { constructor(private notificacao: PoNotificationService) { // Define duração padrão das notificações (em milissegundos) this.notificacao.setDefaultDuration(5000); } mostrarSucesso(): void { // Notificação simples com string this.notificacao.success('Operação realizada com sucesso!'); } mostrarErro(): void { // Notificações de erro permanecem até serem fechadas manualmente this.notificacao.error({ message: 'Erro ao processar a requisição', supportMessage: 'Código: ERR_500', orientation: PoToasterOrientation.Top }); } mostrarAviso(): void { this.notificacao.warning({ message: 'Atenção! Esta ação não pode ser desfeita.', duration: 10000 }); } mostrarInfo(): void { this.notificacao.information({ message: 'Nova versão disponível para download.' }); } mostrarComAcao(): void { this.notificacao.success({ message: 'E-mail enviado com sucesso!', actionLabel: 'Desfazer', action: () => { console.log('Ação de desfazer executada'); this.notificacao.information('Envio cancelado'); } }); } } ``` --- ### PoDialogService - Diálogos de Confirmação e Alerta O `PoDialogService` exibe caixas de diálogo para alertas e confirmações, permitindo customização completa das ações. ```typescript import { Component } from '@angular/core'; import { PoDialogService, PoDialogConfirmOptions, PoDialogAlertOptions } from '@po-ui/ng-components'; @Component({ selector: 'app-dialog-example', template: ` <po-button p-label="Mostrar Alerta" (p-click)="mostrarAlerta()"></po-button> <po-button p-label="Confirmar Exclusão" p-danger (p-click)="confirmarExclusao()"></po-button> ` }) export class DialogExampleComponent { constructor(private dialog: PoDialogService) {} mostrarAlerta(): void { const alertOptions: PoDialogAlertOptions = { title: 'Informação Importante', message: 'O sistema passará por manutenção programada no próximo final de semana.', ok: () => console.log('Usuário confirmou leitura do alerta') }; this.dialog.alert(alertOptions); } confirmarExclusao(): void { const confirmOptions: PoDialogConfirmOptions = { title: 'Confirmar Exclusão', message: 'Deseja realmente excluir os 5 itens selecionados? Esta ação não pode ser desfeita.', confirm: () => { console.log('Itens excluídos'); // Executa lógica de exclusão }, cancel: () => { console.log('Exclusão cancelada'); }, literals: { confirm: 'Sim, excluir', cancel: 'Não, manter' } }; this.dialog.confirm(confirmOptions); } } ``` --- ## Templates Dinâmicos ### po-page-dynamic-table - Página de Listagem Dinâmica O `po-page-dynamic-table` é um template que exibe uma lista de registros em tabela baseado em metadados, com suporte a CRUD completo, filtros avançados e ações customizáveis. ```typescript import { Component } from '@angular/core'; import { PoPageDynamicTableModule, PoPageDynamicTableActions, PoPageDynamicTableCustomAction, PoPageDynamicTableCustomTableAction, PoDynamicFormField } from '@po-ui/ng-templates'; @Component({ selector: 'app-dynamic-table-example', template: ` <po-page-dynamic-table p-title="Gerenciamento de Usuários" p-service-api="https://api.exemplo.com/usuarios" p-quick-search-param="search" p-height="500" p-keep-filters p-infinite-scroll [p-fields]="campos" [p-actions]="acoes" [p-page-custom-actions]="acoesPaginaCustom" [p-table-custom-actions]="acoesTabela"> </po-page-dynamic-table> ` }) export class DynamicTableExampleComponent { campos: Array<PoDynamicFormField> = [ { property: 'id', key: true, visible: false }, { property: 'nome', label: 'Nome', filter: true, gridColumns: 6 }, { property: 'email', label: 'E-mail', filter: true, gridColumns: 6 }, { property: 'departamento', label: 'Departamento', filter: true, options: [ { value: 'TI', label: 'Tecnologia' }, { value: 'RH', label: 'Recursos Humanos' }, { value: 'FIN', label: 'Financeiro' } ] }, { property: 'status', label: 'Status', type: 'label', labels: [ { value: 'ativo', label: 'Ativo', color: 'color-10' }, { value: 'inativo', label: 'Inativo', color: 'color-07' } ]}, { property: 'dataAdmissao', label: 'Data Admissão', type: 'date' } ]; acoes: PoPageDynamicTableActions = { new: '/usuarios/novo', edit: '/usuarios/editar/:id', detail: '/usuarios/detalhe/:id', remove: true, removeAll: true, beforeRemove: '/api/usuarios/before-remove', beforeEdit: this.antesDeEditar.bind(this) }; acoesPaginaCustom: Array<PoPageDynamicTableCustomAction> = [ { label: 'Exportar', action: this.exportar.bind(this), icon: 'an an-download' }, { label: 'Imprimir', action: this.imprimir.bind(this), icon: 'an an-printer' }, { label: 'Excluir Selecionados', action: this.excluirSelecionados.bind(this), selectable: true } ]; acoesTabela: Array<PoPageDynamicTableCustomTableAction> = [ { label: 'Enviar E-mail', action: this.enviarEmail.bind(this), icon: 'an an-envelope' }, { label: 'Resetar Senha', action: this.resetarSenha.bind(this), icon: 'an an-key' } ]; antesDeEditar(id: string, resource: any): any { console.log('Antes de editar:', id); return { allowAction: resource.status !== 'inativo' }; } exportar(): void { console.log('Exportando dados...'); } imprimir(): void { console.log('Imprimindo relatório...'); } excluirSelecionados(selectedItems: Array<any>): void { console.log('Excluindo itens:', selectedItems); } enviarEmail(usuario: any): void { console.log('Enviando e-mail para:', usuario.email); } resetarSenha(usuario: any): void { console.log('Resetando senha de:', usuario.nome); } } ``` --- ## Sincronização Offline ### PoSyncService - Sincronização de Dados Offline O `PoSyncService` permite sincronização automática de dados entre aplicação e servidor, com suporte a operações offline, fila de eventos e múltiplos schemas. ```typescript import { Component, OnInit } from '@angular/core'; import { PoSyncService, PoSyncSchema, PoSyncConfig, PoNetworkType, PoEntity } from '@po-ui/ng-sync'; @Component({ selector: 'app-sync-example', template: ` <po-button p-label="Sincronizar" (p-click)="sincronizar()"></po-button> <po-button p-label="Carregar Dados" (p-click)="carregarDados()"></po-button> ` }) export class SyncExampleComponent implements OnInit { private clienteModel: PoEntity; schemas: Array<PoSyncSchema> = [ { name: 'clientes', idField: 'id', getUrlApi: 'https://api.exemplo.com/clientes', diffUrlApi: 'https://api.exemplo.com/clientes/diff', pageSize: 50, fields: ['id', 'nome', 'email', 'telefone', 'endereco'] }, { name: 'produtos', idField: 'codigo', getUrlApi: 'https://api.exemplo.com/produtos', diffUrlApi: 'https://api.exemplo.com/produtos/diff', pageSize: 100, fields: ['codigo', 'descricao', 'preco', 'estoque'] } ]; config: PoSyncConfig = { type: [PoNetworkType.wifi, PoNetworkType.ethernet], period: 60 // Sincronização automática a cada 60 segundos }; constructor(private poSync: PoSyncService) {} async ngOnInit(): Promise<void> { // Prepara a aplicação para sincronização await this.poSync.prepare(this.schemas, this.config); // Obtém referência ao model de clientes this.clienteModel = this.poSync.getModel('clientes'); // Escuta respostas da sincronização this.poSync.getResponses().subscribe(response => { console.log('Resposta da sincronização:', response); }); // Notificação quando sincronização é concluída this.poSync.onSync().subscribe(() => { console.log('Sincronização concluída'); }); } async carregarDados(): Promise<void> { // Carga inicial dos dados this.poSync.loadData().subscribe(data => { console.log('Dados carregados:', data); }); } async sincronizar(): Promise<void> { // Dispara sincronização manual await this.poSync.sync(); } async buscarClientes(): Promise<Array<any>> { // Busca todos os clientes locais return await this.clienteModel.find().exec(); } async buscarClientePorId(id: number): Promise<any> { // Busca cliente específico return await this.clienteModel.findById(id).exec(); } async salvarCliente(cliente: any): Promise<void> { // Salva cliente (será sincronizado posteriormente) await this.clienteModel.save(cliente); } async removerCliente(id: number): Promise<void> { // Remove cliente (remoção será sincronizada) await this.clienteModel.remove(id); } async inserirRequisicaoHttp(): Promise<void> { // Insere requisição HTTP customizada na fila de eventos await this.poSync.insertHttpCommand({ url: 'https://api.exemplo.com/relatorio', method: 'POST', body: { tipo: 'vendas', periodo: '2024-01' } }); } } ``` --- ## Armazenamento Local ### PoStorageService - Armazenamento de Dados Local O `PoStorageService` fornece armazenamento de dados no dispositivo local com suporte a múltiplos drivers (WebSQL, IndexedDB, LocalStorage, LokiJS). ```typescript import { Component, OnInit } from '@angular/core'; import { PoStorageService } from '@po-ui/ng-storage'; @Component({ selector: 'app-storage-example', template: ` <po-button p-label="Salvar" (p-click)="salvarDados()"></po-button> <po-button p-label="Carregar" (p-click)="carregarDados()"></po-button> <po-button p-label="Limpar" p-danger (p-click)="limparDados()"></po-button> ` }) export class StorageExampleComponent implements OnInit { constructor(private storage: PoStorageService) {} async ngOnInit(): Promise<void> { // Aguarda storage estar pronto await this.storage.ready(); console.log('Driver utilizado:', this.storage.getDriver()); } async salvarDados(): Promise<void> { // Salvar valor simples await this.storage.set('usuario', { nome: 'João', idade: 30 }); // Salvar lista const clientes = [ { id: 1, nome: 'Cliente A' }, { id: 2, nome: 'Cliente B' } ]; await this.storage.set('clientes', clientes); // Adicionar item à lista existente await this.storage.appendItemToArray('clientes', { id: 3, nome: 'Cliente C' }); // Concatenar listas const novosClientes = [{ id: 4, nome: 'Cliente D' }]; await this.storage.appendArrayToArray('clientes', novosClientes); } async carregarDados(): Promise<void> { // Buscar valor const usuario = await this.storage.get('usuario'); console.log('Usuário:', usuario); // Verificar existência const existe = await this.storage.exists('usuario'); console.log('Usuário existe:', existe); // Buscar primeiro item de lista const primeiroCliente = await this.storage.getFirstItem('clientes'); console.log('Primeiro cliente:', primeiroCliente); // Buscar por campo específico const cliente = await this.storage.getItemByField('clientes', 'id', 2); console.log('Cliente encontrado:', cliente); // Listar todas as chaves const chaves = await this.storage.keys(); console.log('Chaves armazenadas:', chaves); // Quantidade de chaves const quantidade = await this.storage.length(); console.log('Total de chaves:', quantidade); } async atualizarDados(): Promise<void> { // Atualizar propriedade de objeto await this.storage.setIndexToObject('usuario', 'idade', 31); // Remover propriedade de objeto await this.storage.removeIndexFromObject('usuario', 'campoTemporario'); // Remover item de lista por campo await this.storage.removeItemFromArray('clientes', 'id', 1); } async limparDados(): Promise<void> { // Remover chave específica await this.storage.remove('usuario'); // Limpar toda base de dados await this.storage.clear(); } async operacoesComLock(): Promise<void> { // Operações com lock para evitar acesso paralelo await this.storage.limitedCallWrap(async () => { const dados = await this.storage.get('dadosCriticos', true); dados.contador++; await this.storage.set('dadosCriticos', dados, true); }); } } ``` --- ## Resumo de Casos de Uso e Padrões de Integração O PO UI é ideal para desenvolvimento de aplicações empresariais Angular que necessitam de uma biblioteca completa de componentes consistentes e acessíveis. Os principais casos de uso incluem: sistemas de gestão (ERP, CRM), portais administrativos, dashboards corporativos, aplicações com suporte offline (através do PoSync) e aplicações mobile-first com PWA. A biblioteca se integra nativamente com Angular Reactive Forms, suporta lazy loading dos módulos, e oferece customização completa via CSS tokens para adequação à identidade visual corporativa. Para integração, recomenda-se importar os módulos específicos necessários (`PoButtonModule`, `PoTableModule`, etc.) ao invés do módulo completo, visando otimizar o bundle size. Os templates dinâmicos (`po-page-dynamic-table`, `po-page-dynamic-edit`) são especialmente úteis para criar CRUDs rapidamente baseados em metadados de API, seguindo o padrão REST definido pelo PO UI. Para aplicações offline, o `PoSyncService` combinado com `PoStorageService` oferece uma solução completa de sincronização e persistência local, permitindo que usuários trabalhem sem conexão e sincronizem dados quando online.