# DynamicForm

![Status](https://img.shields.io/badge/status-stable-brightgreen)

Componente de formulário dinâmico que renderiza campos configuráveis a partir de uma estrutura de dados (`DynamicStructure[]`). Integra-se a um `FormGroup` Angular existente e suporta uma grande variedade de tipos de campo, layout em grid e organização em seções e fieldsets.

## Quando usar

- Formulários gerados a partir de metadados ou configuração da API
- Campos que precisam de layout em grid responsivo configurável
- Formulários com estrutura variável em runtime

## Quando não usar

- Formulários simples com poucos campos fixos — crie o template diretamente
- Quando a flexibilidade de layout do DynamicForm é desnecessária e adiciona complexidade sem ganho

## Instalação

```typescript
import { DynamicFormModule } from '@seniorsistemas/angular-components/dynamic-form';
// ou standalone:
import { DynamicFormComponent } from '@seniorsistemas/angular-components/dynamic-form';

@Component({ standalone: true, imports: [DynamicFormComponent] })
export class MeuComponent {}
```

## Uso básico

```html
<s-dynamic-form [form]="meuFormGroup" [configs]="estrutura" />
```

```typescript
this.form = new FormGroup({
  nome: new FormControl(''),
  email: new FormControl(''),
});

this.configs: DynamicStructure[] = [{
  type: 'row',
  fields: [
    { name: 'nome', type: 'string', label: 'Nome', size: { md: 6 } },
    { name: 'email', type: 'string', label: 'E-mail', size: { md: 6 } },
  ]
}];
```

## API

### Inputs

| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|-------------|------|--------|:-----------:|-----------|
| `form` | `FormGroup` | — | Sim | `FormGroup` Angular ao qual os campos serão vinculados |
| `configs` | `DynamicStructure[]` | `[]` | — | Lista de estruturas de campos dinâmicos a renderizar |
| `fields` | `DynamicType[]` | — | — | **Depreciado.** Use `configs` no lugar |
| `id` | `string` | — | — | Identificador único do formulário no DOM |
| `errorMessages` | `any` | `{}` | — | Mapa de mensagens de erro globais por nome de validador |

### Tipos de campo disponíveis

| Tipo | Descrição |
|------|-----------|
| `string` | Campo de texto simples |
| `password` | Campo de senha com toggle de visibilidade |
| `textArea` | Área de texto multilinha |
| `number` | Campo numérico com máscara |
| `integer` | Campo de número inteiro |
| `money` | Campo monetário |
| `slider` | Controle deslizante |
| `date` | Seletor de data |
| `dateTime` | Seletor de data e hora |
| `time` | Seletor de hora |
| `boolean` | Radio button sim/não/vazio |
| `booleanSwitch` | Toggle switch |
| `enum` | Dropdown de opções |
| `radioButton` | Grupo de radio buttons |
| `autocomplete` | Campo com sugestões |
| `chips` | Campo de tags |
| `checkbox` | Checkbox hierárquico |
| `lookup` | Campo de busca avançada (modal) |
| `starRating` | Avaliação por estrelas |
| `contentGenerator` | Gerador de conteúdo com IA |
| `profilePicture` | Upload de foto de perfil |
| `countryPhonePicker` | Seletor de telefone por país |
| `blob` | Upload de arquivo |

### Estruturas de layout

```typescript
type DynamicStructure =
  | { type: 'row'; fields: DynamicType[] }
  | { type: 'section'; title?: string; configs: DynamicStructure[] }
  | { type: 'fieldset'; legend?: string; configs: DynamicStructure[] };
```

## Exemplos

### Formulário básico com grid

```html
<form [formGroup]="form" style="max-width: 800px;">
  <s-dynamic-form [form]="form" [configs]="configs" />
</form>
```

```typescript
this.form = new FormGroup({
  nome: new FormControl(''),
  email: new FormControl(''),
  tipo: new FormControl(null),
  ativo: new FormControl(false),
});

this.configs = [{
  type: 'row',
  fields: [
    { name: 'nome', type: 'string', label: 'Nome', size: { md: 6 } },
    { name: 'email', type: 'string', label: 'E-mail', size: { md: 6 } },
    {
      name: 'tipo',
      type: 'enum',
      label: 'Tipo',
      size: { md: 6 },
      options: [
        { label: 'Pessoa Física', value: 'pf' },
        { label: 'Pessoa Jurídica', value: 'pj' },
      ],
    },
    { name: 'ativo', type: 'booleanSwitch', label: 'Ativo', size: { md: 6 },
      optionsLabel: { true: 'Sim', false: 'Não' } },
  ],
}];
```

### Formulário com data e número

```typescript
this.configs = [{
  type: 'row',
  fields: [
    { name: 'valor', type: 'number', label: 'Valor', size: { md: 4 }, allowNegative: false },
    { name: 'data', type: 'date', label: 'Data', size: { md: 4 }, appendTo: 'body' },
    { name: 'descricao', type: 'string', label: 'Descrição', size: { md: 4 } },
  ],
}];
```

### Formulário com seções

```typescript
this.configs = [{
  type: 'section',
  title: 'Dados Pessoais',
  configs: [{
    type: 'row',
    fields: [
      { name: 'nome', type: 'string', label: 'Nome', size: { md: 6 } },
      { name: 'cpf', type: 'string', label: 'CPF', size: { md: 6 } },
    ]
  }]
}];
```

## Acessibilidade

- Os campos internos utilizam `label` vinculado via `for`/`id`
- Campos obrigatórios são marcados com `aria-required`
- Mensagens de erro são associadas aos campos correspondentes

## Componentes relacionados

- [`CustomFields`](../custom-fields/README.md) — campos customizados via API da plataforma Senior, baseado no DynamicForm
- [`Fieldset`](../fieldset/README.md) — agrupador de campos com suporte a toggle
