npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

po-ui-json-forms

v20.0.3

Published

Biblioteca Angular para criação de formulários dinâmicos integrando PO-UI com NGX Formly através de configuração JSON. Permite criar formulários complexos de forma declarativa usando todos os componentes de formulário do PO-UI com validação reativa integr

Readme

PO-UI JSON Forms

Uma biblioteca Angular que integra o PO-UI com NGX Formly para criação de formulários dinâmicos através de configuração JSON. Esta biblioteca permite criar formulários complexos usando componentes do PO-UI de forma declarativa e dinâmica.

🚀 Características

  • ✅ Integração completa entre PO-UI e NGX Formly
  • ✅ Suporte a todos os principais componentes de formulário do PO-UI
  • ✅ Formulários dinâmicos via configuração JSON
  • ✅ Validação reativa integrada
  • ✅ Templates pré-definidos
  • ✅ Compatível com Angular 19+
  • ✅ Componentes standalone

📦 Instalação

npm install po-ui-json-forms @po-ui/ng-components @ngx-formly/core

Dependências Peer

Esta biblioteca requer as seguintes dependências:

{
  "@angular/common": "^19.0.0",
  "@angular/core": "^19.0.0",
  "@angular/forms": "^19.0.0",
  "@ngx-formly/core": "^7.0.0",
  "@po-ui/ng-components": "~19.0.0",
  "rxjs": "~7.8.0"
}

⚙️ Configuração

Angular 19 (Standalone Bootstrap)

Configure no seu app.config.ts:

import { ApplicationConfig, provideZoneChangeDetection, importProvidersFrom } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { FormlyModule } from '@ngx-formly/core';
import { 
  PoUiJsonFormsModule, 
  PO_UI_FORMLY_TYPES,
  FormlyFieldPoInput,
  FormlyFieldPoNumber,
  FormlyFieldPoEmail,
  FormlyFieldPoPassword,
  FormlyFieldPoTextarea,
  FormlyFieldPoSelect,
  FormlyFieldPoDatepicker,
  FormlyFieldPoDatepickerRange,
  FormlyFieldPoCheckboxGroup,
  FormlyFieldPoRadioGroup,
  FormlyFieldPoCombo,
  FormlyFieldPoCheckbox,
  FormlyFieldPoLookup,
  FormlyFieldPoMultiselect,
  FormlyFieldPoSwitch
} from 'po-ui-json-forms';

import { routes } from './app.routes';

const FORMLY_TYPES_CONFIG = [
  { name: 'po-input', component: FormlyFieldPoInput },
  { name: 'po-number', component: FormlyFieldPoNumber },
  { name: 'po-email', component: FormlyFieldPoEmail },
  { name: 'po-password', component: FormlyFieldPoPassword },
  { name: 'po-textarea', component: FormlyFieldPoTextarea },
  { name: 'po-select', component: FormlyFieldPoSelect },
  { name: 'po-datepicker', component: FormlyFieldPoDatepicker },
  { name: 'po-datepicker-range', component: FormlyFieldPoDatepickerRange },
  { name: 'po-checkbox-group', component: FormlyFieldPoCheckboxGroup },
  { name: 'po-radio-group', component: FormlyFieldPoRadioGroup },
  { name: 'po-combo', component: FormlyFieldPoCombo },
  { name: 'po-checkbox', component: FormlyFieldPoCheckbox },
  { name: 'po-lookup', component: FormlyFieldPoLookup },
  { name: 'po-multiselect', component: FormlyFieldPoMultiselect },
  { name: 'po-switch', component: FormlyFieldPoSwitch }
];

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }), 
    provideRouter(routes),
    provideHttpClient(),
    importProvidersFrom(
      PoUiJsonFormsModule.forRoot(),
      FormlyModule.forRoot({
        types: FORMLY_TYPES_CONFIG
      })
    )
  ]
};

🔧 Uso Básico

Exemplo Completo de Formulário

Aqui está um exemplo completo demonstrando todos os tipos de campos disponíveis:

import { Component } from '@angular/core';
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
import { FormlyFormOptions, FormlyFieldConfig, FormlyModule } from '@ngx-formly/core';
import { PoModule } from '@po-ui/ng-components';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [ReactiveFormsModule, FormlyModule, PoModule, CommonModule],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'JSON PO-UI Form Generator';
  
  form = new FormGroup({});
  model: any = {};
  options: FormlyFormOptions = {};

  // Configuração usando diferentes tipos do PO-UI
  fields: FormlyFieldConfig[] = [
    {
      key: 'nome',
      type: 'po-input',
      mask: '@@@-999-9999', // Exemplo de máscara
      maskFormatModel: false
      props: {
        label: 'Nome Completo',
        placeholder: 'Digite seu nome completo',
        required: true,
        description: 'Informe seu nome completo'
      }
    },
    {
      key: 'sobrenome',
      type: 'po-input',
      props: {
        label: 'Sobrenome',
        placeholder: 'Digite seu sobrenome',
        required: false
      }
    },
    {
      key: 'email',
      type: 'po-email',
      props: {
        label: 'E-mail',
        placeholder: 'Digite seu e-mail',
        required: true,
        description: 'Informe um e-mail válido'
      }
    },
    {
      key: 'senha',
      type: 'po-password',
      props: {
        label: 'Senha',
        placeholder: 'Digite sua senha',
        required: true,
        minLength: 8,
        description: 'A senha deve ter pelo menos 8 caracteres'
      }
    },
    {
      key: 'idade',
      type: 'po-number',
      props: {
        label: 'Idade',
        placeholder: 'Digite sua idade',
        required: true,
        min: 18,
        max: 120,
        description: 'Informe sua idade (mínimo 18 anos)'
      }
    },
    {
      key: 'dataNascimento',
      type: 'po-datepicker',
      props: {
        label: 'Data de Nascimento',
        required: true,
        description: 'Selecione sua data de nascimento'
      }
    },
    {
      key: 'estado',
      type: 'po-select',
      props: {
        label: 'Estado',
        placeholder: 'Selecione seu estado',
        required: true,
        options: [
          { label: 'São Paulo', value: 'SP' },
          { label: 'Rio de Janeiro', value: 'RJ' },
          { label: 'Minas Gerais', value: 'MG' },
          { label: 'Bahia', value: 'BA' },
          { label: 'Paraná', value: 'PR' },
          { label: 'Rio Grande do Sul', value: 'RS' },
          { label: 'Pernambuco', value: 'PE' },
          { label: 'Ceará', value: 'CE' },
          { label: 'Pará', value: 'PA' },
          { label: 'Santa Catarina', value: 'SC' }
        ],
        description: 'Selecione o estado onde reside'
      }
    },
    {
      key: 'profissao',
      type: 'po-combo',
      props: {
        label: 'Profissão',
        placeholder: 'Digite ou selecione sua profissão',
        required: true,
        options: [
          { label: 'Desenvolvedor', value: 'dev' },
          { label: 'Designer', value: 'design' },
          { label: 'Analista', value: 'analista' },
          { label: 'Gerente', value: 'gerente' },
          { label: 'Consultor', value: 'consultor' },
          { label: 'Arquiteto de Software', value: 'arquiteto' },
          { label: 'Product Owner', value: 'po' },
          { label: 'Scrum Master', value: 'sm' }
        ],
        fieldValue: 'value',
        fieldLabel: 'label',
        description: 'Digite ou selecione sua profissão'
      }
    },
    {
      key: 'genero',
      type: 'po-radio-group',
      props: {
        label: 'Gênero',
        required: true,
        options: [
          { label: 'Masculino', value: 'M' },
          { label: 'Feminino', value: 'F' },
          { label: 'Outro', value: 'O' },
          { label: 'Prefiro não informar', value: 'N' }
        ],
        description: 'Selecione seu gênero'
      }
    },
    {
      key: 'hobbies',
      type: 'po-checkbox-group',
      props: {
        label: 'Hobbies',
        options: [
          { label: 'Leitura', value: 'leitura' },
          { label: 'Esportes', value: 'esportes' },
          { label: 'Música', value: 'musica' },
          { label: 'Cinema', value: 'cinema' },
          { label: 'Culinária', value: 'culinaria' },
          { label: 'Viagens', value: 'viagens' },
          { label: 'Tecnologia', value: 'tecnologia' },
          { label: 'Arte', value: 'arte' }
        ],
        description: 'Selecione seus hobbies (múltipla escolha)'
      }
    },
    {
      key: 'biografia',
      type: 'po-textarea',
      props: {
        label: 'Biografia',
        placeholder: 'Conte um pouco sobre você...',
        rows: 4,
        maxLength: 500,
        description: 'Escreva uma breve biografia (máximo 500 caracteres)'
      }
    },
    {
      key: 'newsletter',
      type: 'po-checkbox',
      props: {
        label: 'Aceito receber newsletter',
        description: 'Marque para receber nossas novidades por e-mail'
      }
    },
    {
      key: 'termos',
      type: 'po-checkbox',
      props: {
        label: 'Aceito os termos de uso',
        required: true,
        description: 'É obrigatório aceitar os termos para continuar'
      }
    },
    {
      key: 'periodoFerias',
      type: 'po-datepicker-range',
      props: {
        label: 'Período de Férias',
        required: false,
        description: 'Selecione o período desejado para suas férias'
      }
    },
    {
      key: 'tecnologias',
      type: 'po-multiselect',
      props: {
        label: 'Tecnologias',
        placeholder: 'Selecione as tecnologias que conhece',
        options: [
          { label: 'Angular', value: 'angular' },
          { label: 'React', value: 'react' },
          { label: 'Vue.js', value: 'vue' },
          { label: 'Node.js', value: 'node' },
          { label: 'Python', value: 'python' },
          { label: 'Java', value: 'java' },
          { label: 'C#', value: 'csharp' },
          { label: 'JavaScript', value: 'javascript' },
          { label: 'TypeScript', value: 'typescript' },
          { label: 'PHP', value: 'php' }
        ],
        description: 'Selecione múltiplas tecnologias que você conhece'
      }
    },
    {
      key: 'notificacoes',
      type: 'po-switch',
      props: {
        label: 'Ativar Notificações',
        description: 'Ative para receber notificações push'
      }
    }
  ];

  onSubmit() {
    if (this.form.valid) {
      console.log('Dados:', this.model);
    }
  }
}

Template HTML

<po-page-default p-title="{{ title }}">
  <form [formGroup]="form" (ngSubmit)="onSubmit()">
    <formly-form 
      [form]="form" 
      [fields]="fields" 
      [model]="model" 
      [options]="options">
    </formly-form>
    
    <div class="po-row">
      <po-button
        class="po-md-3"
        p-label="Submeter"
        p-type="primary"
        type="submit"
        [p-disabled]="!form.valid">
      </po-button>
      
      <po-button
        class="po-md-3 po-ml-1"
        p-label="Limpar"
        p-type="default"
        (p-click)="form.reset(); model = {}">
      </po-button>
    </div>
  </form>
</po-page-default>

🚀 Teste Online

Experimente a biblioteca em funcionamento no StackBlitz:

Open in StackBlitz

Link direto: https://stackblitz.com/~/github.com/yuriduartetotvs/po-ui-json-forms?file=src/app/app.component.html

📋 Tipos de Campos Suportados

| Tipo | Componente PO-UI | Descrição | |------|------------------|-----------| | po-input | PoInputComponent | Campo de texto simples | | po-email | PoEmailComponent | Campo de e-mail com validação | | po-password | PoPasswordComponent | Campo de senha | | po-number | PoNumberComponent | Campo numérico | | po-textarea | PoTextareaComponent | Área de texto multilinha | | po-select | PoSelectComponent | Lista suspensa de seleção única | | po-combo | PoComboComponent | Campo de busca com autocomplete | | po-multiselect | PoMultiselectComponent | Seleção múltipla | | po-radio-group | PoRadioGroupComponent | Grupo de radio buttons | | po-checkbox-group | PoCheckboxGroupComponent | Grupo de checkboxes | | po-checkbox | PoCheckboxComponent | Checkbox individual | | po-datepicker | PoDatepickerComponent | Seletor de data | | po-datepicker-range | PoDatepickerRangeComponent | Seletor de período | | po-switch | PoSwitchComponent | Botão liga/desliga | | po-lookup | PoLookupComponent | Campo de busca avançada |

🎯 Exemplos de Configuração

Campo de Input Simples

{
  key: 'nome',
  type: 'po-input',
  props: {
    label: 'Nome',
    placeholder: 'Digite seu nome',
    required: true,
    maxLength: 100
  }
}

Campo Select com Opções

{
  key: 'categoria',
  type: 'po-select',
  props: {
    label: 'Categoria',
    required: true,
    options: [
      { label: 'Tecnologia', value: 'tech' },
      { label: 'Saúde', value: 'health' },
      { label: 'Educação', value: 'education' }
    ]
  }
}

Campo com Validação Customizada

{
  key: 'cpf',
  type: 'po-input',
  props: {
    label: 'CPF',
    mask: '999.999.999-99',
    required: true
  },
  validators: {
    validation: ['cpf']
  }
}

Tipos Disponíveis

A biblioteca fornece os seguintes tipos de campo do PO-UI:

  • po-input - Campo de entrada de texto
  • po-number - Campo numérico
  • po-email - Campo de e-mail
  • po-password - Campo de senha
  • po-textarea - Área de texto
  • po-select - Seleção única
  • po-multiselect - Seleção múltipla
  • po-combo - Combo box com busca
  • po-datepicker - Seletor de data
  • po-datepicker-range - Seletor de intervalo de datas
  • po-checkbox - Checkbox individual
  • po-checkbox-group - Grupo de checkboxes
  • po-radio-group - Grupo de radio buttons
  • po-switch - Switch (liga/desliga)
  • po-lookup - Campo de busca avançada

🤝 Contribuição

  1. Fork o repositório
  2. Crie uma branch para sua feature (git checkout -b feature/nova-feature)
  3. Commit suas mudanças (git commit -m 'Adiciona nova feature')
  4. Push para a branch (git push origin feature/nova-feature)
  5. Abra um Pull Request

📄 Licença

MIT License

🐛 Reportar Problemas

Se encontrou algum problema ou tem sugestões, por favor:

  1. Verifique se já não existe uma issue similar
  2. Crie uma nova issue com:
    • Descrição detalhada do problema
    • Passos para reproduzir
    • Versão do Angular e das dependências
    • Código de exemplo (se aplicável)

📚 Recursos Adicionais


Desenvolvido para ajudar na produtividade de criação de formulario com JSON para PO-UI