@seniorsistemas/angular-components 19.3.3 → 19.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/accordion/README.md +166 -0
  2. package/alert/README.md +92 -0
  3. package/autocomplete/README.md +162 -0
  4. package/badge/README.md +126 -0
  5. package/bignumber-input/README.md +122 -0
  6. package/breadcrumb/README.md +144 -0
  7. package/button/README.md +159 -0
  8. package/calendar-mask/README.md +89 -0
  9. package/card/README.md +133 -0
  10. package/chat/README.md +130 -0
  11. package/checkbox/README.md +108 -0
  12. package/checkbox-list/README.md +149 -0
  13. package/chips/README.md +152 -0
  14. package/code-editor/README.md +149 -0
  15. package/collapse-link/README.md +128 -0
  16. package/confirm-dialog/README.md +105 -0
  17. package/content-generator/README.md +111 -0
  18. package/control-errors/README.md +92 -0
  19. package/country-phone-picker/README.md +121 -0
  20. package/currency/README.md +90 -0
  21. package/custom-fields/README.md +142 -0
  22. package/dialog/README.md +152 -0
  23. package/dynamic-form/README.md +176 -0
  24. package/editable-overlay/README.md +98 -0
  25. package/empty-state/README.md +134 -0
  26. package/esm2022/loading-state/lib/loading-state/loading-state.component.mjs +4 -4
  27. package/fesm2022/seniorsistemas-angular-components-loading-state.mjs +3 -3
  28. package/fesm2022/seniorsistemas-angular-components-loading-state.mjs.map +1 -1
  29. package/fieldset/README.md +135 -0
  30. package/file-picker/README.md +162 -0
  31. package/file-upload/README.md +23 -7
  32. package/gantt/README.md +173 -0
  33. package/global-search/README.md +151 -0
  34. package/grid-menu/README.md +123 -0
  35. package/help-popover/README.md +134 -0
  36. package/ia-insight/README.md +24 -6
  37. package/image-cropper/README.md +140 -0
  38. package/infinite-scroll/README.md +130 -0
  39. package/info-sign/README.md +111 -0
  40. package/inline-edit/README.md +139 -0
  41. package/insights/README.md +159 -0
  42. package/interactive-content/README.md +120 -0
  43. package/kanban/README.md +184 -0
  44. package/label-value/README.md +154 -0
  45. package/loading-state/README.md +141 -0
  46. package/localized-number-input/README.md +128 -0
  47. package/mouse-events/README.md +157 -0
  48. package/navigation-button/README.md +160 -0
  49. package/numeric/README.md +147 -0
  50. package/numeric-mask/README.md +170 -0
  51. package/object-card/README.md +158 -0
  52. package/package.json +1 -1
  53. package/paginator/README.md +121 -0
  54. package/panel/README.md +147 -0
  55. package/password-strength/README.md +144 -0
  56. package/picklist/README.md +170 -0
  57. package/pin-code-field/README.md +137 -0
  58. package/product-header/README.md +33 -6
  59. package/profile-picture-picker/README.md +159 -0
  60. package/progressbar/README.md +136 -0
  61. package/radio-button/README.md +117 -0
  62. package/rating-scale/README.md +154 -0
  63. package/select/README.md +147 -0
  64. package/select-button/README.md +137 -0
  65. package/sidebar/README.md +117 -0
  66. package/slide-in-bar/README.md +122 -0
  67. package/slider/README.md +127 -0
  68. package/speech-recognition/README.md +104 -0
  69. package/split-button/README.md +126 -0
  70. package/spotlight/README.md +200 -0
  71. package/star-rating/README.md +127 -0
  72. package/stats-card/README.md +135 -0
  73. package/stepper/README.md +164 -0
  74. package/switch/README.md +125 -0
  75. package/table/README.md +185 -0
  76. package/text-area-ia/README.md +17 -6
@@ -0,0 +1,105 @@
1
+ # ConfirmDialog
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Serviço para exibir diálogos de confirmação modais de forma programática. Utilizado via `ConfirmDialogService.confirm()` — não é instanciado diretamente no template.
6
+
7
+ ## Quando usar
8
+
9
+ - Confirmar ações destrutivas como exclusão ou arquivamento de registros
10
+ - Solicitar confirmação explícita antes de operações irreversíveis
11
+ - Exibir alertas que requerem reconhecimento do usuário (sem botão de cancelar)
12
+
13
+ ## Quando não usar
14
+
15
+ - Mensagens de feedback simples sem necessidade de confirmação — use [`Alert`](../alert/README.md) ou notificações inline
16
+ - Fluxos com formulários complexos — use [`Dialog`](../dialog/README.md) com `DialogService`
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { ConfirmDialogService } from '@seniorsistemas/angular-components/confirm-dialog';
22
+ import { DialogService } from '@seniorsistemas/angular-components/dialog';
23
+
24
+ @Component({
25
+ standalone: true,
26
+ providers: [ConfirmDialogService, DialogService],
27
+ })
28
+ export class MeuComponent {}
29
+ ```
30
+
31
+ ## Uso básico
32
+
33
+ ```typescript
34
+ // No componente — injete o serviço e chame confirm()
35
+ constructor(private confirmDialogService: ConfirmDialogService) {}
36
+
37
+ openConfirm() {
38
+ this.confirmDialogService.confirm({
39
+ header: 'Remover item?',
40
+ message: 'Esta ação não pode ser desfeita.',
41
+ acceptLabel: 'Remover',
42
+ rejectLabel: 'Cancelar',
43
+ accept: () => this.delete(),
44
+ reject: () => console.log('cancelado'),
45
+ });
46
+ }
47
+ ```
48
+
49
+ ## API
50
+
51
+ ### Tipos
52
+
53
+ ```typescript
54
+ type ConfirmDialog = {
55
+ header: string; // Título do diálogo (obrigatório)
56
+ message: string; // Mensagem exibida no corpo (obrigatório)
57
+ acceptLabel: string; // Label do botão de confirmar (obrigatório)
58
+ accept: VoidFunction; // Callback ao confirmar (obrigatório)
59
+ rejectLabel?: string; // Label do botão de cancelar (opcional)
60
+ reject?: VoidFunction; // Callback ao cancelar ou fechar (opcional)
61
+ }
62
+ ```
63
+
64
+ ### ConfirmDialogService
65
+
66
+ | Método | Parâmetros | Descrição |
67
+ |--------|-----------|-----------|
68
+ | `confirm` | `confirmDialog: ConfirmDialog` | Abre o diálogo de confirmação modal |
69
+
70
+ ## Exemplos
71
+
72
+ ### Confirmação de exclusão
73
+
74
+ ```typescript
75
+ this.confirmDialogService.confirm({
76
+ header: 'Remover este item?',
77
+ message: 'Uma vez removido, o item não poderá ser restaurado.',
78
+ acceptLabel: 'Remover',
79
+ rejectLabel: 'Cancelar',
80
+ accept: () => { this.lastAction = 'Confirmado: item removido'; },
81
+ reject: () => { this.lastAction = 'Cancelado'; },
82
+ });
83
+ ```
84
+
85
+ ### Alerta sem botão de cancelar
86
+
87
+ ```typescript
88
+ this.confirmDialogService.confirm({
89
+ header: 'Atividade concluída',
90
+ message: 'Salvamos esta atividade em seu repositório.',
91
+ acceptLabel: 'Entendi',
92
+ accept: () => { this.lastAction = 'Usuário confirmou'; },
93
+ });
94
+ ```
95
+
96
+ ## Acessibilidade
97
+
98
+ - O diálogo é aberto em uma janela modal com backdrop que bloqueia interação com o conteúdo de fundo
99
+ - O foco é capturado dentro do diálogo enquanto estiver aberto
100
+ - Fechar via Escape chama o callback `reject` quando definido
101
+
102
+ ## Componentes relacionados
103
+
104
+ - [`Dialog`](../dialog/README.md) — quando precisar de formulários ou conteúdo customizado na modal
105
+ - [`Alert`](../alert/README.md) — para mensagens de feedback inline sem confirmação
@@ -0,0 +1,111 @@
1
+ # ContentGenerator
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente de área de texto com geração de conteúdo por inteligência artificial integrada. Permite ao usuário digitar livremente ou solicitar geração de texto via IA através de um diálogo de contexto, com suporte opcional a reconhecimento de voz.
6
+
7
+ ## Quando usar
8
+
9
+ - Campos de texto longos onde a IA pode auxiliar na redação (descrições, observações, resumos)
10
+ - Formulários com campos de conteúdo aberto onde a geração assistida melhora a produtividade
11
+ - Campos com contexto específico onde um `prompt` customizado direciona a IA
12
+
13
+ ## Quando não usar
14
+
15
+ - Campos de texto simples sem necessidade de IA — use [`TextArea`](../text-area/README.md)
16
+ - Campos de entrada curtos (nome, código) — use um input simples
17
+ - O seletor `s-text-area-ia` está descontinuado (remoção na v20.0.0) — use `s-content-generator`
18
+
19
+ ## Instalação
20
+
21
+ ```typescript
22
+ import { ContentGeneratorModule } from '@seniorsistemas/angular-components/content-generator';
23
+
24
+ @Component({ standalone: true, imports: [ContentGeneratorModule] })
25
+ export class MeuComponent {}
26
+ ```
27
+
28
+ ## Uso básico
29
+
30
+ ```html
31
+ <s-content-generator
32
+ formControlName="descricao"
33
+ label="Descrição"
34
+ [rows]="6"
35
+ />
36
+ ```
37
+
38
+ ## API
39
+
40
+ ### Inputs
41
+
42
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
43
+ |-------------|------|--------|:-----------:|-----------|
44
+ | `label` | `string` | — | — | Label exibido acima da área de texto |
45
+ | `placeholder` | `string` | `''` | — | Texto de placeholder quando a área está vazia |
46
+ | `prompt` | `string` | — | — | Instrução enviada à IA para direcionar o conteúdo gerado |
47
+ | `rows` | `number` | `10` | — | Número de linhas visíveis da área de texto |
48
+ | `cols` | `number` | `10` | — | Número de colunas da área de texto |
49
+ | `readonly` | `boolean` | `false` | — | Torna a área de texto somente leitura |
50
+ | `speechRecognition` | `boolean` | `false` | — | Habilita o botão de reconhecimento de voz |
51
+ | `keepContext` | `boolean` | `false` | — | Mantém o contexto do diálogo de IA entre aberturas |
52
+ | `speechRecognitionPlaceholder` | `string` | `''` | — | Placeholder exibido durante o reconhecimento de voz |
53
+ | `maxLength` | `number \| null` | `null` | — | Limite máximo de caracteres (`null` = sem limite) |
54
+ | `id` | `string` | `ContentGenerator_{n}` | — | Identificador único do componente no DOM |
55
+ | `textAreaStyle` | `Partial<CSSStyleDeclaration>` | `{}` | — | Estilos CSS inline aplicados à área de texto interna |
56
+
57
+ ## Exemplos
58
+
59
+ ### Com prompt customizado
60
+
61
+ ```html
62
+ <form [formGroup]="form">
63
+ <s-content-generator
64
+ formControlName="descricao"
65
+ label="Descrição do produto"
66
+ placeholder="Descreva o produto ou use a IA para gerar..."
67
+ [rows]="6"
68
+ prompt="Gere uma descrição focada em benefícios para o cliente, em tom profissional."
69
+ ></s-content-generator>
70
+ </form>
71
+ ```
72
+
73
+ ### Com reconhecimento de voz
74
+
75
+ ```html
76
+ <form [formGroup]="form">
77
+ <s-content-generator
78
+ formControlName="observacoes"
79
+ label="Observações"
80
+ placeholder="Digite ou dite suas observações..."
81
+ [rows]="5"
82
+ [speechRecognition]="true"
83
+ speechRecognitionPlaceholder="Ouvindo... fale agora"
84
+ ></s-content-generator>
85
+ </form>
86
+ ```
87
+
88
+ ### Com limite de caracteres
89
+
90
+ ```html
91
+ <form [formGroup]="form">
92
+ <s-content-generator
93
+ formControlName="resumo"
94
+ label="Resumo executivo"
95
+ placeholder="Máximo de 500 caracteres..."
96
+ [maxLength]="500"
97
+ [rows]="5"
98
+ ></s-content-generator>
99
+ </form>
100
+ ```
101
+
102
+ ## Acessibilidade
103
+
104
+ - Implementa `ControlValueAccessor` — compatível com `formControlName`, `formControl` e `ngModel`
105
+ - O botão de IA e o botão de voz possuem labels acessíveis
106
+ - O diálogo de contexto da IA é navegável por teclado
107
+
108
+ ## Componentes relacionados
109
+
110
+ - [`TextArea`](../text-area/README.md) — área de texto simples sem IA
111
+ - [`SpeechRecognition`](../speech-recognition/README.md) — reconhecimento de voz standalone
@@ -0,0 +1,92 @@
1
+ # ControlErrors
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente que exibe as mensagens de erro de validação associadas a um controle de formulário. Observa as mudanças de estado do controle e renderiza as mensagens mapeadas quando o campo está `dirty` e inválido.
6
+
7
+ ## Quando usar
8
+
9
+ - Exibir mensagens de erro de validação abaixo de campos de formulário de forma padronizada
10
+ - Substituir lógica manual de `*ngIf` para erros por um padrão consistente
11
+ - Campos com múltiplas regras de validação simultâneas
12
+
13
+ ## Quando não usar
14
+
15
+ - Mensagens de erro globais de formulário — use um componente de alerta
16
+ - Validações assíncronas que retornam mensagens da API — adapte usando o mapa `errorMessages`
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { ControlErrorsModule } from '@seniorsistemas/angular-components/control-errors';
22
+
23
+ @Component({ standalone: true, imports: [ControlErrorsModule] })
24
+ export class MeuComponent {}
25
+ ```
26
+
27
+ ## Uso básico
28
+
29
+ ```html
30
+ <input type="email" formControlName="email" />
31
+ <s-control-errors
32
+ [control]="form.get('email')"
33
+ [errorMessages]="{ required: 'E-mail obrigatório', email: 'E-mail inválido' }"
34
+ />
35
+ ```
36
+
37
+ ## API
38
+
39
+ ### Inputs
40
+
41
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
42
+ |-------------|------|--------|:-----------:|-----------|
43
+ | `control` | `AbstractControl \| NgModel` | — | Sim | Controle do formulário cujos erros serão exibidos |
44
+ | `errorMessages` | `Record<string, string>` | `{}` | — | Mapa de chave de erro para mensagem de texto |
45
+ | `id` | `string` | `s-control-errors-{n}` | — | Identificador único do componente |
46
+ | `form` | `any` | — | — | Referência ao formulário pai para validações customizadas |
47
+
48
+ ## Exemplos
49
+
50
+ ### Campo de e-mail com validação
51
+
52
+ ```html
53
+ <form [formGroup]="form">
54
+ <label>E-mail *</label>
55
+ <input type="email" formControlName="email" (blur)="form.get('email')?.markAsDirty()" />
56
+ <s-control-errors
57
+ [control]="form.get('email')"
58
+ [errorMessages]="{ required: 'E-mail é obrigatório.', email: 'Informe um e-mail válido.' }"
59
+ ></s-control-errors>
60
+ </form>
61
+ ```
62
+
63
+ ### Campo de senha com múltiplas regras
64
+
65
+ ```html
66
+ <s-control-errors
67
+ [control]="form.get('password')"
68
+ [errorMessages]="{
69
+ required: 'Senha é obrigatória.',
70
+ minlength: 'A senha deve ter no mínimo 8 caracteres.',
71
+ pattern: 'A senha deve conter ao menos uma letra maiúscula e um número.'
72
+ }"
73
+ ></s-control-errors>
74
+ ```
75
+
76
+ ### Formulário com submissão e marcação de campos
77
+
78
+ ```typescript
79
+ onSubmit() {
80
+ Object.values(this.form.controls).forEach(c => c.markAsDirty());
81
+ this.form.updateValueAndValidity();
82
+ }
83
+ ```
84
+
85
+ ## Acessibilidade
86
+
87
+ - As mensagens de erro são renderizadas no DOM com IDs únicos para possível associação via `aria-describedby`
88
+ - As mensagens só aparecem após interação do usuário (`dirty`), evitando erros prematuros ao carregar a página
89
+
90
+ ## Componentes relacionados
91
+
92
+ - [`Alert`](../alert/README.md) — mensagens de feedback inline não vinculadas a um controle
@@ -0,0 +1,121 @@
1
+ # CountryPhonePicker
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente de seleção de país com DDI e campo de telefone com máscara dinâmica. Exibe uma lista de países com bandeiras, aplica automaticamente a máscara de formatação conforme o país selecionado e emite os dados via Angular Forms.
6
+
7
+ ## Quando usar
8
+
9
+ - Formulários internacionais que aceitam números de telefone de diferentes países
10
+ - Cadastros onde o DDI precisa ser capturado junto ao número
11
+ - Formulários regionalizados onde apenas um subconjunto de países é relevante
12
+
13
+ ## Quando não usar
14
+
15
+ - Formulários exclusivamente nacionais sem necessidade de seleção de país — use um campo de texto com máscara
16
+ - Quando o DDI é fixo e não precisa ser selecionado pelo usuário
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { CountryPhonePickerModule } from '@seniorsistemas/angular-components/country-phone-picker';
22
+
23
+ @Component({ standalone: true, imports: [CountryPhonePickerModule] })
24
+ export class MeuComponent {}
25
+ ```
26
+
27
+ > **Atenção:** É necessário adicionar os estilos de bandeiras no `angular.json`:
28
+ > ```json
29
+ > "styles": ["node_modules/flag-icons/css/flag-icons.min.css"]
30
+ > ```
31
+
32
+ ## Uso básico
33
+
34
+ ```html
35
+ <s-country-phone-picker formControlName="telefone" />
36
+ ```
37
+
38
+ ## API
39
+
40
+ ### Inputs
41
+
42
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
43
+ |-------------|------|--------|:-----------:|-----------|
44
+ | `countries` | `string[]` | `[]` | — | Lista de códigos ISO 3166-1 alpha-2 exibidos no dropdown. Vazio = todos os países |
45
+ | `ordination` | `Ordination` | `Ordination.NO` | — | Critério de ordenação da lista de países |
46
+
47
+ ### Outputs
48
+
49
+ | Evento | Tipo | Descrição |
50
+ |--------|------|-----------|
51
+ | `selected` | `EventEmitter<CountryPhoneData>` | Emitido ao selecionar um país no dropdown |
52
+ | `focusLost` | `EventEmitter<PhoneSelectionData \| null>` | Emitido quando o campo de telefone perde o foco |
53
+
54
+ ### Tipos
55
+
56
+ ```typescript
57
+ enum Ordination {
58
+ NO = 'no', // Sem ordenação (ordem padrão)
59
+ AZ = 'az', // Ordem alfabética A-Z
60
+ ZA = 'za', // Ordem alfabética Z-A
61
+ }
62
+
63
+ interface CountryPhoneData {
64
+ id: string; // Código ISO do país (ex: 'br')
65
+ ddi: string; // Código DDI (ex: '+55')
66
+ mask: string | string[]; // Máscara(s) de formatação
67
+ }
68
+
69
+ interface PhoneSelectionData {
70
+ id: string; // Código ISO do país selecionado
71
+ ddi: string; // Código DDI
72
+ value: string; // Número formatado com máscara
73
+ rawValue: string; // Número sem formatação
74
+ }
75
+ ```
76
+
77
+ ## Exemplos
78
+
79
+ ### Lista filtrada para países específicos
80
+
81
+ ```html
82
+ <s-country-phone-picker
83
+ formControlName="telefone"
84
+ [countries]="['br', 'us', 'ar', 'co', 'py', 'uy', 'cl', 'pe']"
85
+ (selected)="onPaisSelecionado($event)"
86
+ (focusLost)="onFocusLost($event)"
87
+ ></s-country-phone-picker>
88
+ ```
89
+
90
+ ### Lista ordenada alfabeticamente
91
+
92
+ ```html
93
+ <s-country-phone-picker
94
+ formControlName="telefone"
95
+ [ordination]="'az'"
96
+ ></s-country-phone-picker>
97
+ ```
98
+
99
+ ### Reagindo à seleção de país
100
+
101
+ ```typescript
102
+ onPaisSelecionado(country: CountryPhoneData) {
103
+ console.log('País selecionado:', country.id, 'DDI:', country.ddi);
104
+ }
105
+
106
+ onFocusLost(data: PhoneSelectionData | null) {
107
+ if (data) {
108
+ console.log('Número formatado:', data.value);
109
+ }
110
+ }
111
+ ```
112
+
113
+ ## Acessibilidade
114
+
115
+ - Navegação por teclado no dropdown: `Enter`/`Espaço` abre/confirma, `Escape` fecha, `ArrowUp`/`ArrowDown` navega entre países
116
+ - O dropdown fecha ao clicar fora do componente
117
+ - Implementa `ControlValueAccessor` — compatível com `formControlName`, `formControl` e `ngModel`
118
+
119
+ ## Componentes relacionados
120
+
121
+ - [`Mask`](../mask/README.md) — diretiva de máscara aplicada internamente ao campo de telefone
@@ -0,0 +1,90 @@
1
+ # Currency
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Serviço para obter o símbolo de uma moeda formatado de acordo com o locale ativo da aplicação, utilizando a API nativa `Intl.NumberFormat` do browser.
6
+
7
+ ## Quando usar
8
+
9
+ - Exibir o símbolo da moeda dinamicamente ao lado de valores monetários
10
+ - Construir campos de entrada com prefixo de moeda que se adapta ao locale do usuário
11
+ - Obter o símbolo compacto (ex: `R$`, `$`, `€`) para exibição em interfaces
12
+
13
+ ## Quando não usar
14
+
15
+ - Formatação completa de valores monetários — use o `CurrencyPipe` do Angular ou o pipe `Numeric` da biblioteca
16
+ - Validação de entradas monetárias — use validators de formulário
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { CurrencyService } from '@seniorsistemas/angular-components/currency';
22
+
23
+ @Component({ standalone: true })
24
+ export class MeuComponent {
25
+ private readonly currencyService = inject(CurrencyService);
26
+ }
27
+ ```
28
+
29
+ O serviço é `providedIn: 'root'` e não requer módulo adicional. Requer que `LocaleModule.forRoot()` esteja configurado na aplicação.
30
+
31
+ ## Uso básico
32
+
33
+ ```typescript
34
+ const symbol = this.currencyService.getCurrencySymbol({ currency: 'BRL' }); // 'R$'
35
+ const symbol = this.currencyService.getCurrencySymbol({ currency: 'USD' }); // 'US$' ou '$'
36
+ const symbol = this.currencyService.getCurrencySymbol({ currency: 'EUR' }); // '€'
37
+ ```
38
+
39
+ ## API
40
+
41
+ ### CurrencyService
42
+
43
+ | Método | Parâmetros | Retorno | Descrição |
44
+ |--------|-----------|---------|-----------|
45
+ | `getCurrencySymbol` | `{ currency: Currency }` | `string` | Retorna o símbolo da moeda formatado para o locale ativo |
46
+
47
+ ### Tipos
48
+
49
+ ```typescript
50
+ // Currency é um union type de todos os códigos ISO 4217 suportados
51
+ type Currency = 'BRL' | 'USD' | 'EUR' | 'GBP' | 'JPY' | 'ARS' | 'CLP' | 'MXN' | /* ... */;
52
+ ```
53
+
54
+ ## Exemplos
55
+
56
+ ### Exibindo símbolo em um campo de entrada
57
+
58
+ ```typescript
59
+ @Component({
60
+ template: `
61
+ <div class="input-group">
62
+ <span class="prefix">{{ currencySymbol }}</span>
63
+ <input type="number" formControlName="valor" />
64
+ </div>
65
+ `
66
+ })
67
+ export class ValorComponent {
68
+ private readonly currencyService = inject(CurrencyService);
69
+ readonly currencySymbol = this.currencyService.getCurrencySymbol({ currency: 'BRL' });
70
+ }
71
+ ```
72
+
73
+ ### Múltiplas moedas
74
+
75
+ ```typescript
76
+ const moedas: Currency[] = ['BRL', 'USD', 'EUR', 'GBP', 'JPY'];
77
+ const simbolos = moedas.map(code => ({
78
+ code,
79
+ symbol: this.currencyService.getCurrencySymbol({ currency: code }),
80
+ }));
81
+ // [{ code: 'BRL', symbol: 'R$' }, { code: 'USD', symbol: 'US$' }, ...]
82
+ ```
83
+
84
+ ## Acessibilidade
85
+
86
+ - O símbolo retornado é uma string de texto simples, compatível com leitores de tela quando usado em elementos HTML com contexto adequado
87
+
88
+ ## Componentes relacionados
89
+
90
+ - [`Locale`](../locale/README.md) — serviço de localização que define o locale usado na formatação
@@ -0,0 +1,142 @@
1
+ # CustomFields
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente que carrega e renderiza campos customizados dinamicamente a partir da API de customização de campos da plataforma Senior. Realiza chamadas HTTP para obter a configuração dos campos, gera o formulário reativamente e implementa `ControlValueAccessor` e `Validator` para integração completa com formulários Angular.
6
+
7
+ ## Quando usar
8
+
9
+ - Telas que precisam exibir campos customizados configurados pelo cliente na plataforma Senior
10
+ - Formulários de entidades que suportam extensão via campo customizável
11
+ - Quando os campos são definidos dinamicamente em runtime via API
12
+
13
+ ## Quando não usar
14
+
15
+ - Formulários com campos fixos conhecidos em tempo de compilação — use [`DynamicForm`](../dynamic-form/README.md) diretamente
16
+ - Ambientes sem conexão com a API da plataforma Senior — o componente depende de autenticação e endpoints externos
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { CustomFieldsModule } from '@seniorsistemas/angular-components/custom-fields';
22
+
23
+ @Component({ standalone: true, imports: [CustomFieldsModule] })
24
+ export class MeuComponent {}
25
+ ```
26
+
27
+ Requer `LocaleModule.forRoot()` e `TranslateModule.forRoot()` configurados na aplicação.
28
+
29
+ ## Uso básico
30
+
31
+ ```html
32
+ <form [formGroup]="form">
33
+ <s-custom-fields
34
+ formControlName="camposCustomizados"
35
+ domain="plataforma"
36
+ service="servico"
37
+ entity="entidade"
38
+ />
39
+ </form>
40
+ ```
41
+
42
+ ```typescript
43
+ this.form = new FormGroup({
44
+ camposCustomizados: new FormControl(null),
45
+ });
46
+ ```
47
+
48
+ ## API
49
+
50
+ ### Inputs
51
+
52
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
53
+ |-------------|------|--------|:-----------:|-----------|
54
+ | `domain` | `string` | — | Sim | Domínio para buscar os campos na API |
55
+ | `service` | `string` | — | Sim | Nome do serviço para identificar os campos |
56
+ | `entity` | `string` | — | Sim | Nome da entidade para a qual os campos são carregados |
57
+ | `entityObject` | `CustomFieldsResponse` | — | — | Dados pré-carregados para evitar chamada extra à API |
58
+ | `invalidErrorLabel` | `string` | `''` | — | Mensagem de erro para campos com valor inválido |
59
+ | `customFieldsEndpoint` | `string` | `'platform/field_customization/queries/getEntity'` | — | Endpoint para buscar a configuração dos campos |
60
+ | `fileLocationEndpoint` | `string` | `'platform/field_customization/actions/requestUpload'` | — | Endpoint para upload de arquivos em campos blob |
61
+ | `requestAccessEndpoint` | `string` | `'platform/field_customization/actions/requestAccess'` | — | Endpoint para acesso a arquivos já enviados |
62
+ | `requiredErrorMessage` | `string` | `''` | — | Mensagem de erro para campos obrigatórios não preenchidos |
63
+ | `displayTimeInfoSign` | `number` | `0` | — | Tempo em ms após o qual o info-sign de campos data é exibido |
64
+ | `showFileUploadDate` | `boolean` | `false` | — | Exibe data de upload nos campos do tipo arquivo |
65
+ | `ready$` | `BehaviorSubject<boolean> \| null` | `null` | — | Observable que sinaliza quando iniciar o carregamento dos campos |
66
+ | `disableFields` | `boolean` | — | — | Quando `true`, todos os campos são desabilitados |
67
+
68
+ ### Tipos
69
+
70
+ ```typescript
71
+ enum CustomFieldType {
72
+ String = 'String',
73
+ Boolean = 'Boolean',
74
+ Integer = 'Integer',
75
+ Double = 'Double',
76
+ Date = 'Date',
77
+ DateTime = 'DateTime',
78
+ LocalDateTime = 'LocalDateTime',
79
+ Time = 'Time',
80
+ Money = 'Money',
81
+ Blob = 'Blob',
82
+ Binary = 'Binary',
83
+ Any = 'Any',
84
+ Enum = 'Enum',
85
+ }
86
+
87
+ interface CustomFieldsResponse {
88
+ entity_: {
89
+ active: boolean;
90
+ fields: FieldFromAPI[];
91
+ };
92
+ }
93
+ ```
94
+
95
+ ## Exemplos
96
+
97
+ ### Uso básico com formulário reativo
98
+
99
+ ```html
100
+ <form [formGroup]="form">
101
+ <s-custom-fields
102
+ formControlName="camposCustomizados"
103
+ domain="plataforma"
104
+ service="servico"
105
+ entity="entidade"
106
+ requiredErrorMessage="Campo obrigatório"
107
+ />
108
+ </form>
109
+ ```
110
+
111
+ ### Com dados pré-carregados
112
+
113
+ ```html
114
+ <s-custom-fields
115
+ formControlName="camposCustomizados"
116
+ domain="plataforma"
117
+ service="servico"
118
+ entity="entidade"
119
+ [entityObject]="dadosPreCarregados"
120
+ />
121
+ ```
122
+
123
+ ### Desabilitando campos
124
+
125
+ ```html
126
+ <s-custom-fields
127
+ formControlName="camposCustomizados"
128
+ domain="plataforma"
129
+ service="servico"
130
+ entity="entidade"
131
+ [disableFields]="modoSomenteLeitura"
132
+ />
133
+ ```
134
+
135
+ ## Acessibilidade
136
+
137
+ - Os campos renderizados são os mesmos do `DynamicForm`, que segue as práticas de acessibilidade dos componentes internos
138
+ - Labels e tooltips dos campos são configurados via API de customização da plataforma
139
+
140
+ ## Componentes relacionados
141
+
142
+ - [`DynamicForm`](../dynamic-form/README.md) — formulário dinâmico base usado internamente