@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.
- package/accordion/README.md +166 -0
- package/alert/README.md +92 -0
- package/autocomplete/README.md +162 -0
- package/badge/README.md +126 -0
- package/bignumber-input/README.md +122 -0
- package/breadcrumb/README.md +144 -0
- package/button/README.md +159 -0
- package/calendar-mask/README.md +89 -0
- package/card/README.md +133 -0
- package/chat/README.md +130 -0
- package/checkbox/README.md +108 -0
- package/checkbox-list/README.md +149 -0
- package/chips/README.md +152 -0
- package/code-editor/README.md +149 -0
- package/collapse-link/README.md +128 -0
- package/confirm-dialog/README.md +105 -0
- package/content-generator/README.md +111 -0
- package/control-errors/README.md +92 -0
- package/country-phone-picker/README.md +121 -0
- package/currency/README.md +90 -0
- package/custom-fields/README.md +142 -0
- package/dialog/README.md +152 -0
- package/dynamic-form/README.md +176 -0
- package/editable-overlay/README.md +98 -0
- package/empty-state/README.md +134 -0
- package/esm2022/loading-state/lib/loading-state/loading-state.component.mjs +4 -4
- package/fesm2022/seniorsistemas-angular-components-loading-state.mjs +3 -3
- package/fesm2022/seniorsistemas-angular-components-loading-state.mjs.map +1 -1
- package/fieldset/README.md +135 -0
- package/file-picker/README.md +162 -0
- package/file-upload/README.md +23 -7
- package/gantt/README.md +173 -0
- package/global-search/README.md +151 -0
- package/grid-menu/README.md +123 -0
- package/help-popover/README.md +134 -0
- package/ia-insight/README.md +24 -6
- package/image-cropper/README.md +140 -0
- package/infinite-scroll/README.md +130 -0
- package/info-sign/README.md +111 -0
- package/inline-edit/README.md +139 -0
- package/insights/README.md +159 -0
- package/interactive-content/README.md +120 -0
- package/kanban/README.md +184 -0
- package/label-value/README.md +154 -0
- package/loading-state/README.md +141 -0
- package/localized-number-input/README.md +128 -0
- package/mouse-events/README.md +157 -0
- package/navigation-button/README.md +160 -0
- package/numeric/README.md +147 -0
- package/numeric-mask/README.md +170 -0
- package/object-card/README.md +158 -0
- package/package.json +1 -1
- package/paginator/README.md +121 -0
- package/panel/README.md +147 -0
- package/password-strength/README.md +144 -0
- package/picklist/README.md +170 -0
- package/pin-code-field/README.md +137 -0
- package/product-header/README.md +33 -6
- package/profile-picture-picker/README.md +159 -0
- package/progressbar/README.md +136 -0
- package/radio-button/README.md +117 -0
- package/rating-scale/README.md +154 -0
- package/select/README.md +147 -0
- package/select-button/README.md +137 -0
- package/sidebar/README.md +117 -0
- package/slide-in-bar/README.md +122 -0
- package/slider/README.md +127 -0
- package/speech-recognition/README.md +104 -0
- package/split-button/README.md +126 -0
- package/spotlight/README.md +200 -0
- package/star-rating/README.md +127 -0
- package/stats-card/README.md +135 -0
- package/stepper/README.md +164 -0
- package/switch/README.md +125 -0
- package/table/README.md +185 -0
- package/text-area-ia/README.md +17 -6
package/kanban/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Kanban
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente de quadro Kanban com suporte a arrastar e soltar colunas e itens. Permite seleção via checkboxes, templates customizáveis para cabeçalho, corpo e rodapé dos cards, e emite eventos de movimentação e seleção.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Gerenciamento de tarefas e projetos com workflows visuais (Scrum, Kanban)
|
|
10
|
+
- Visualização e organização de itens distribuídos em estágios ou categorias
|
|
11
|
+
- Interfaces onde o usuário precisa mover itens entre colunas por arrastar e soltar
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Listas simples sem necessidade de colunas múltiplas — use uma lista ou tabela
|
|
16
|
+
- Quando os itens não podem ser movidos entre categorias — use abas ou filtros
|
|
17
|
+
|
|
18
|
+
## Instalação
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { KanbanModule } from '@seniorsistemas/angular-components/kanban';
|
|
22
|
+
|
|
23
|
+
@NgModule({
|
|
24
|
+
imports: [KanbanModule],
|
|
25
|
+
})
|
|
26
|
+
export class MeuModule {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Uso básico
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<s-kanban [data]="dadosKanban" (itemsMoved)="onItemMovido($event)"></s-kanban>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
### Inputs
|
|
38
|
+
|
|
39
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
40
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
41
|
+
| `data` | `KanbanData` | — | Sim | Dados do quadro Kanban com colunas e itens. |
|
|
42
|
+
| `showItemCheckboxes` | `boolean` | `true` | Não | Exibe checkboxes de seleção em cada item Kanban. |
|
|
43
|
+
| `showColumnCheckboxes` | `boolean` | `true` | Não | Exibe checkboxes de seleção no cabeçalho de cada coluna. |
|
|
44
|
+
|
|
45
|
+
### Outputs
|
|
46
|
+
|
|
47
|
+
| Evento | Tipo | Descrição |
|
|
48
|
+
|--------|------|-----------|
|
|
49
|
+
| `itemsMoved` | `EventEmitter<KanbanItemMovedData>` | Emitido quando o usuário move um item entre colunas ou posições. |
|
|
50
|
+
| `dataUpdated` | `EventEmitter<KanbanData>` | Emitido quando os dados do quadro são atualizados após movimentação. |
|
|
51
|
+
| `itemsSelected` | `EventEmitter<KanbanItem[]>` | Emitido quando a seleção de itens muda, com a lista de itens selecionados. |
|
|
52
|
+
|
|
53
|
+
### Tipos
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
interface KanbanData {
|
|
57
|
+
columns: KanbanColumn[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface KanbanColumn {
|
|
61
|
+
id?: string;
|
|
62
|
+
title: string;
|
|
63
|
+
items: KanbanItem[];
|
|
64
|
+
options?: KanbanColumnOption[]; // Menu de opções no cabeçalho da coluna
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface KanbanItem {
|
|
68
|
+
data: any; // Dados do item (livre)
|
|
69
|
+
options?: KanbanItemOption[]; // Menu de opções no card
|
|
70
|
+
disabled?: boolean; // Bloqueia movimentação e seleção
|
|
71
|
+
frozen?: boolean; // Bloqueia movimentação mas permite seleção
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface KanbanItemMovedData {
|
|
75
|
+
items: KanbanItem[]; // Itens movidos (inclui selecionados)
|
|
76
|
+
previousColumn: KanbanColumn; // Coluna de origem
|
|
77
|
+
targetColumn: KanbanColumn; // Coluna de destino
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface KanbanColumnOption {
|
|
81
|
+
label: string;
|
|
82
|
+
iconClass?: string;
|
|
83
|
+
command: (column: KanbanColumn) => void;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface KanbanItemOption {
|
|
87
|
+
label: string;
|
|
88
|
+
iconClass?: string;
|
|
89
|
+
command: (item: KanbanItem) => void;
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Exemplos
|
|
94
|
+
|
|
95
|
+
### Kanban básico com templates
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
dadosKanban: KanbanData = {
|
|
99
|
+
columns: [
|
|
100
|
+
{
|
|
101
|
+
id: 'todo',
|
|
102
|
+
title: 'A Fazer',
|
|
103
|
+
items: [
|
|
104
|
+
{ data: { id: 1, title: 'Implementar login', assignee: 'João' } },
|
|
105
|
+
{ data: { id: 2, title: 'Configurar banco de dados', assignee: 'Maria' } },
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{ id: 'doing', title: 'Em Progresso', items: [] },
|
|
109
|
+
{ id: 'done', title: 'Concluído', items: [] },
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<s-kanban [data]="dadosKanban" (itemsMoved)="onItemMovido($event)">
|
|
116
|
+
<ng-template sTemplate="item-header" let-item>
|
|
117
|
+
<h4>{{ item.data.title }}</h4>
|
|
118
|
+
</ng-template>
|
|
119
|
+
<ng-template sTemplate="item-body" let-item>
|
|
120
|
+
<p>{{ item.data.assignee }}</p>
|
|
121
|
+
</ng-template>
|
|
122
|
+
<ng-template sTemplate="item-footer" let-item>
|
|
123
|
+
<span>#{{ item.data.id }}</span>
|
|
124
|
+
</ng-template>
|
|
125
|
+
</s-kanban>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Com itens desabilitados e congelados
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
dadosKanban: KanbanData = {
|
|
132
|
+
columns: [{
|
|
133
|
+
id: 'col1',
|
|
134
|
+
title: 'Coluna',
|
|
135
|
+
items: [
|
|
136
|
+
{ data: { title: 'Normal' } },
|
|
137
|
+
{ data: { title: 'Bloqueado' }, disabled: true },
|
|
138
|
+
{ data: { title: 'Congelado' }, frozen: true },
|
|
139
|
+
],
|
|
140
|
+
}],
|
|
141
|
+
};
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Com menus de opções
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
dadosKanban: KanbanData = {
|
|
148
|
+
columns: [{
|
|
149
|
+
id: 'backlog',
|
|
150
|
+
title: 'Backlog',
|
|
151
|
+
items: [{
|
|
152
|
+
data: { id: 1, title: 'Feature A' },
|
|
153
|
+
options: [
|
|
154
|
+
{ label: 'Editar', iconClass: 'far fa-edit', command: (item) => this.editar(item) },
|
|
155
|
+
{ label: 'Excluir', iconClass: 'far fa-trash', command: (item) => this.excluir(item) },
|
|
156
|
+
],
|
|
157
|
+
}],
|
|
158
|
+
options: [
|
|
159
|
+
{ label: 'Adicionar Tarefa', iconClass: 'far fa-plus', command: (col) => this.adicionar(col) },
|
|
160
|
+
],
|
|
161
|
+
}],
|
|
162
|
+
};
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Templates customizáveis
|
|
166
|
+
|
|
167
|
+
| Valor do `sTemplate` | Descrição |
|
|
168
|
+
|----------------------|-----------|
|
|
169
|
+
| `item-header` | Cabeçalho do card |
|
|
170
|
+
| `item-body` | Corpo do card |
|
|
171
|
+
| `item-footer` | Rodapé do card |
|
|
172
|
+
| `column-header` | Cabeçalho da coluna |
|
|
173
|
+
| `column-empty-message` | Mensagem exibida quando a coluna está vazia |
|
|
174
|
+
|
|
175
|
+
## Acessibilidade
|
|
176
|
+
|
|
177
|
+
- Use Ctrl+Clique para selecionar múltiplos itens antes de arrastar
|
|
178
|
+
- Itens com `disabled: true` não podem ser movidos ou selecionados
|
|
179
|
+
- Itens com `frozen: true` não podem ser movidos mas podem ser selecionados
|
|
180
|
+
- Os checkboxes de seleção de coluna selecionam todos os itens habilitados da coluna
|
|
181
|
+
|
|
182
|
+
## Componentes relacionados
|
|
183
|
+
|
|
184
|
+
- [`GridMenu`](../grid-menu/README.md) — menu em grade para navegação e seleção simples
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# LabelValue
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente para exibição de pares label/valor em modo somente leitura. Suporta cinco tipos de valor: texto simples, badge, moeda, número e data — cada um com formatação automática adequada ao locale da aplicação.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Painéis de visualização de detalhes de entidades (funcionário, produto, pedido)
|
|
10
|
+
- Resumos de formulários antes da submissão
|
|
11
|
+
- Seções de informações em cards ou modais onde os dados não são editáveis
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Campos editáveis — use um formulário convencional ou [`InlineEdit`](../inline-edit/README.md)
|
|
16
|
+
- Métricas numéricas com ícone e destaque visual — prefira o componente StatsCard
|
|
17
|
+
|
|
18
|
+
## Instalação
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { LabelValueModule } from '@seniorsistemas/angular-components/label-value';
|
|
22
|
+
|
|
23
|
+
@NgModule({
|
|
24
|
+
imports: [LabelValueModule],
|
|
25
|
+
})
|
|
26
|
+
export class MeuModule {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Uso básico
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<s-label-value [configuration]="{ type: 'Text', title: 'Nome', value: 'João Silva' }"></s-label-value>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
### Inputs
|
|
38
|
+
|
|
39
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
40
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
41
|
+
| `configuration` | `LabelValueConfiguration` | — | Sim | Configuração do par label/valor. O campo `type` determina como o valor é renderizado. |
|
|
42
|
+
|
|
43
|
+
### Tipos
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
type LabelValueConfiguration =
|
|
47
|
+
| TextConfiguration
|
|
48
|
+
| BadgeConfiguration
|
|
49
|
+
| CurrencyConfiguration
|
|
50
|
+
| NumberConfiguration
|
|
51
|
+
| DateConfiguration;
|
|
52
|
+
|
|
53
|
+
// Texto simples
|
|
54
|
+
type TextConfiguration = {
|
|
55
|
+
type: 'Text';
|
|
56
|
+
title: string;
|
|
57
|
+
value: string;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Badge(s)
|
|
61
|
+
type BadgeConfiguration = {
|
|
62
|
+
type: 'Badge';
|
|
63
|
+
title: string;
|
|
64
|
+
value: Partial<Pick<BadgeComponent, 'type' | 'color' | 'text' | 'iconClass' | 'iconPosition'>>[];
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Valor monetário formatado pelo locale
|
|
68
|
+
type CurrencyConfiguration = {
|
|
69
|
+
type: 'Currency';
|
|
70
|
+
title: string;
|
|
71
|
+
value: string | number;
|
|
72
|
+
currency: string; // Ex: 'BRL', 'USD', 'EUR'
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Valor numérico formatado pelo locale
|
|
76
|
+
type NumberConfiguration = {
|
|
77
|
+
type: 'Number';
|
|
78
|
+
title: string;
|
|
79
|
+
value: string | number;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Data formatada com moment.js
|
|
83
|
+
type DateConfiguration = {
|
|
84
|
+
type: 'Date';
|
|
85
|
+
title: string;
|
|
86
|
+
value: string | Date;
|
|
87
|
+
format?: string; // Formato moment.js, padrão: 'L'
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Exemplos
|
|
92
|
+
|
|
93
|
+
### Tipo Text
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<s-label-value [configuration]="{ type: 'Text', title: 'Nome completo', value: 'João Silva' }">
|
|
97
|
+
</s-label-value>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Tipo Badge com múltiplos badges
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<s-label-value [configuration]="{
|
|
104
|
+
type: 'Badge',
|
|
105
|
+
title: 'Permissões',
|
|
106
|
+
value: [
|
|
107
|
+
{ text: 'Leitura', color: 'blue', iconClass: 'fa fa-eye' },
|
|
108
|
+
{ text: 'Escrita', color: 'green', iconClass: 'fa fa-edit' },
|
|
109
|
+
{ text: 'Admin', color: 'red', iconClass: 'fa fa-shield-alt' }
|
|
110
|
+
]
|
|
111
|
+
}"></s-label-value>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Tipo Currency
|
|
115
|
+
|
|
116
|
+
```html
|
|
117
|
+
<s-label-value [configuration]="{ type: 'Currency', title: 'Salário', currency: 'BRL', value: 5750.99 }">
|
|
118
|
+
</s-label-value>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Tipo Date com formato customizado
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<s-label-value [configuration]="{
|
|
125
|
+
type: 'Date',
|
|
126
|
+
title: 'Última atualização',
|
|
127
|
+
value: '2024-11-01T18:21:16Z',
|
|
128
|
+
format: 'L HH:mm:ss'
|
|
129
|
+
}"></s-label-value>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Painel de detalhes com múltiplos campos
|
|
133
|
+
|
|
134
|
+
```html
|
|
135
|
+
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;">
|
|
136
|
+
<s-label-value [configuration]="{ type: 'Text', title: 'Nome', value: 'João Silva' }"></s-label-value>
|
|
137
|
+
<s-label-value [configuration]="{ type: 'Text', title: 'CPF', value: '123.456.789-00' }"></s-label-value>
|
|
138
|
+
<s-label-value [configuration]="{ type: 'Date', title: 'Admissão', value: '2020-03-01' }"></s-label-value>
|
|
139
|
+
<s-label-value [configuration]="{ type: 'Currency', title: 'Salário', currency: 'BRL', value: 5750 }"></s-label-value>
|
|
140
|
+
<s-label-value [configuration]="{ type: 'Badge', title: 'Status', value: [{ text: 'Ativo', color: 'green' }] }"></s-label-value>
|
|
141
|
+
<s-label-value [configuration]="{ type: 'Number', title: 'Dias trabalhados', value: 1250 }"></s-label-value>
|
|
142
|
+
</div>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Acessibilidade
|
|
146
|
+
|
|
147
|
+
- Quando `value` é nulo ou string vazia, exibe a mensagem "Não informado" (internacionalizada via `TranslateModule`)
|
|
148
|
+
- O `title` é sempre exibido em negrito como rótulo do campo
|
|
149
|
+
- Requer `LocaleModule.forRoot()` e `TranslateModule.forRoot()` no módulo raiz para formatação de moeda, número e data
|
|
150
|
+
|
|
151
|
+
## Componentes relacionados
|
|
152
|
+
|
|
153
|
+
- [`Badge`](../badge/README.md) — componente de badge usado internamente no tipo Badge
|
|
154
|
+
- [`InlineEdit`](../inline-edit/README.md) — quando os campos precisam ser editáveis inline
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# LoadingState
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente para exibir indicadores de carregamento sobre conteúdo enquanto operações assíncronas estão em andamento. Permite bloquear componentes específicos ou a página inteira, com dois tipos de indicador visual. Também disponível como diretiva estrutural `*sLoadingState`.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Carregamento de dados em listas, tabelas ou painéis
|
|
10
|
+
- Processamento de formulários após submissão
|
|
11
|
+
- Operações assíncronas em containers específicos da tela
|
|
12
|
+
- Carregamento inicial da aplicação (com `blockWindow: true` e indicador Logo)
|
|
13
|
+
|
|
14
|
+
## Quando não usar
|
|
15
|
+
|
|
16
|
+
- Operações muito rápidas (< 300ms) onde o flash do indicador seria indesejado — o componente já tem delay de 300ms embutido
|
|
17
|
+
- Progresso mensurável — prefira [`Progressbar`](../progressbar/README.md) quando há percentual de conclusão
|
|
18
|
+
|
|
19
|
+
## Instalação
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { LoadingStateModule } from '@seniorsistemas/angular-components/loading-state';
|
|
23
|
+
|
|
24
|
+
@NgModule({
|
|
25
|
+
imports: [LoadingStateModule],
|
|
26
|
+
})
|
|
27
|
+
export class MeuModule {}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Uso básico
|
|
31
|
+
|
|
32
|
+
### Como componente
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<s-loading-state [loading]="carregando">
|
|
36
|
+
<div>Conteúdo que será bloqueado durante o carregamento</div>
|
|
37
|
+
</s-loading-state>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Como diretiva estrutural
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<div *sLoadingState="carregando">
|
|
44
|
+
Conteúdo que será bloqueado
|
|
45
|
+
</div>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## API
|
|
49
|
+
|
|
50
|
+
### Inputs
|
|
51
|
+
|
|
52
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
53
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
54
|
+
| `loading` | `boolean` | — | Sim | Controla o estado de carregamento. Quando `true`, exibe o indicador após 300ms. Quando `false`, remove após 200ms. |
|
|
55
|
+
| `indicator` | `LoadingStateIndicators` | `LoadingStateIndicators.Dots` | Não | Tipo de indicador visual: `dots` (pontos animados) ou `logo` (logotipo animado). |
|
|
56
|
+
| `blockWindow` | `boolean` | `false` | Não | Quando `true`, bloqueia a janela inteira com overlay em vez de apenas o container. |
|
|
57
|
+
| `id` | `string` | `s-loading-state-{auto}` | Não | Identificador único do componente no DOM. |
|
|
58
|
+
|
|
59
|
+
### Tipos
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
enum LoadingStateIndicators {
|
|
63
|
+
Dots = 'dots', // Indicador de pontos animados (padrão)
|
|
64
|
+
Logo = 'logo', // Indicador com logotipo animado
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Diretiva `*sLoadingState`
|
|
69
|
+
|
|
70
|
+
A diretiva aceita `boolean` ou objeto de configuração:
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<!-- Forma simples -->
|
|
74
|
+
<div *sLoadingState="carregando">Conteúdo</div>
|
|
75
|
+
|
|
76
|
+
<!-- Forma com configuração -->
|
|
77
|
+
<div *sLoadingState="{ loading: carregando, indicator: 'logo' }">Conteúdo</div>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Exemplos
|
|
81
|
+
|
|
82
|
+
### Carregamento de uma seção específica
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<s-loading-state [loading]="carregandoDados" [indicator]="'dots'">
|
|
86
|
+
<div class="painel">
|
|
87
|
+
<h3>Dados do Funcionário</h3>
|
|
88
|
+
<div>{{ dados | json }}</div>
|
|
89
|
+
</div>
|
|
90
|
+
</s-loading-state>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Bloqueio da página inteira
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<s-loading-state [loading]="processando" [blockWindow]="true" [indicator]="'logo'">
|
|
97
|
+
<div class="pagina">
|
|
98
|
+
<!-- conteúdo da página -->
|
|
99
|
+
</div>
|
|
100
|
+
</s-loading-state>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Múltiplos loading states independentes
|
|
104
|
+
|
|
105
|
+
```html
|
|
106
|
+
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;">
|
|
107
|
+
<div *sLoadingState="carregandoSecao1">
|
|
108
|
+
<h4>Seção 1</h4>
|
|
109
|
+
<p>Conteúdo independente</p>
|
|
110
|
+
</div>
|
|
111
|
+
<div *sLoadingState="carregandoSecao2">
|
|
112
|
+
<h4>Seção 2</h4>
|
|
113
|
+
<p>Conteúdo independente</p>
|
|
114
|
+
</div>
|
|
115
|
+
<div *sLoadingState="carregandoSecao3">
|
|
116
|
+
<h4>Seção 3</h4>
|
|
117
|
+
<p>Conteúdo independente</p>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Com indicador Logo e configuração via diretiva
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<div *sLoadingState="{ loading: carregando, indicator: 'logo' }">
|
|
126
|
+
Conteúdo com indicador de logo customizado
|
|
127
|
+
</div>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Acessibilidade
|
|
131
|
+
|
|
132
|
+
- O indicador tem delay de bloqueio de 300ms para evitar flash em operações rápidas
|
|
133
|
+
- O delay de desbloqueio é de 200ms para transição suave ao remover o overlay
|
|
134
|
+
- Use `blockWindow: true` com moderação — bloqueia toda interação do usuário com a página
|
|
135
|
+
- O `id` gerado automaticamente é único por instância do componente
|
|
136
|
+
|
|
137
|
+
## Componentes relacionados
|
|
138
|
+
|
|
139
|
+
- [`EmptyState`](../empty-state/README.md) — exibir mensagem quando não há conteúdo após o carregamento
|
|
140
|
+
- [`Progressbar`](../progressbar/README.md) — indicar progresso mensurável de operações com percentual
|
|
141
|
+
- [`InfiniteScroll`](../infinite-scroll/README.md) — carregamento progressivo de listas com scroll
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# LocalizedNumberInput
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Diretiva de validação para campos `<input>` que verifica se o valor digitado é um número localizado válido, considerando os separadores decimal e de milhar do locale ativo. Integra-se ao sistema de formulários Angular via `NG_VALIDATORS`, adicionando o erro `invalidNumber` quando o valor não é válido.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Campos de entrada numérica em formulários que precisam validar o formato localizado (ex: `1.234,56` em pt-BR)
|
|
10
|
+
- Quando o usuário digita livremente e você precisa garantir que o valor é um número no formato correto antes de processar
|
|
11
|
+
- Aplicações multi-locale onde os separadores podem variar
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Quando você precisa de formatação visual automática enquanto o usuário digita — prefira uma máscara numérica
|
|
16
|
+
- Para campos de valores inteiros sem casas decimais — use validação nativa do Angular Forms (`Validators.pattern`)
|
|
17
|
+
|
|
18
|
+
## Instalação
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { LocalizedNumberInputModule } from '@seniorsistemas/angular-components/localized-number-input';
|
|
22
|
+
|
|
23
|
+
@NgModule({
|
|
24
|
+
imports: [LocalizedNumberInputModule],
|
|
25
|
+
})
|
|
26
|
+
export class MeuModule {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Dependência:** Requer `LocaleModule.forRoot()` configurado no módulo raiz da aplicação.
|
|
30
|
+
|
|
31
|
+
## Uso básico
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<input sLocalizedNumberInput [precision]="2" formControlName="valor" />
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
### Inputs
|
|
40
|
+
|
|
41
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
42
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
43
|
+
| `precision` | `number` | `2` | Não | Número máximo de casas decimais aceitas na validação. |
|
|
44
|
+
| `decimalSeparator` | `string` | Locale ativo | Não | Separador decimal personalizado. Usa o do locale ativo se não informado. |
|
|
45
|
+
| `thousandsSeparator` | `string` | Locale ativo | Não | Separador de milhar personalizado. Usa o do locale ativo se não informado. |
|
|
46
|
+
|
|
47
|
+
### Erros de validação
|
|
48
|
+
|
|
49
|
+
| Chave | Valor | Condição |
|
|
50
|
+
|-------|-------|----------|
|
|
51
|
+
| `invalidNumber` | `true` | O valor digitado não corresponde ao formato de número localizado esperado. |
|
|
52
|
+
|
|
53
|
+
## Exemplos
|
|
54
|
+
|
|
55
|
+
### Validação com locale pt-BR (padrão)
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<form [formGroup]="form">
|
|
59
|
+
<input
|
|
60
|
+
sLocalizedNumberInput
|
|
61
|
+
[precision]="2"
|
|
62
|
+
formControlName="valor"
|
|
63
|
+
placeholder="Ex: 1.234,56"
|
|
64
|
+
/>
|
|
65
|
+
@if (form.get('valor')?.errors?.['invalidNumber'] && form.get('valor')?.dirty) {
|
|
66
|
+
<small style="color: red;">Número inválido para o locale atual (pt-BR)</small>
|
|
67
|
+
}
|
|
68
|
+
</form>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Validação com separadores customizados (en-US)
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<input
|
|
75
|
+
sLocalizedNumberInput
|
|
76
|
+
[precision]="2"
|
|
77
|
+
decimalSeparator="."
|
|
78
|
+
thousandsSeparator=","
|
|
79
|
+
formControlName="valorUsd"
|
|
80
|
+
placeholder="Ex: 1,234.56"
|
|
81
|
+
/>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Alta precisão decimal (4 casas)
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<input
|
|
88
|
+
sLocalizedNumberInput
|
|
89
|
+
[precision]="4"
|
|
90
|
+
formControlName="cotacao"
|
|
91
|
+
placeholder="Ex: 1.234,5678"
|
|
92
|
+
/>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Exibindo erro de validação
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
@Component({ ... })
|
|
99
|
+
export class MeuComponent {
|
|
100
|
+
form = new FormGroup({
|
|
101
|
+
valor: new FormControl(''),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
get valorInvalido(): boolean {
|
|
105
|
+
const control = this.form.get('valor');
|
|
106
|
+
return !!(control?.errors?.['invalidNumber'] && control.dirty);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```html
|
|
112
|
+
<input sLocalizedNumberInput [precision]="2" formControlName="valor" />
|
|
113
|
+
@if (valorInvalido) {
|
|
114
|
+
<small>Informe um número válido. Exemplo: 1.234,56</small>
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Acessibilidade
|
|
119
|
+
|
|
120
|
+
- A diretiva integra-se ao sistema de validação nativo do Angular Forms via `NG_VALIDATORS`
|
|
121
|
+
- O erro `invalidNumber` é adicionado ao `FormControl` para uso com mensagens de validação padrão
|
|
122
|
+
- Use `formControlName` ou `ngModel` para que a validação seja aplicada corretamente
|
|
123
|
+
- Os separadores são obtidos automaticamente do `LocaleService` — não é necessário configurar manualmente para o locale padrão
|
|
124
|
+
|
|
125
|
+
## Componentes relacionados
|
|
126
|
+
|
|
127
|
+
- [`NumericMask`](../numeric-mask/README.md) — máscara de entrada com formatação visual automática enquanto o usuário digita
|
|
128
|
+
- [`BigNumberInput`](../bignumber-input/README.md) — máscara para números de grande precisão
|