@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
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Picklist
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente para transferência de itens entre duas listas — disponíveis e selecionados. Suporta arrastar e soltar, filtro por texto, seleção múltipla com checkboxes e templates customizáveis para renderização dos itens.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Seleção de múltiplos itens de uma lista para outra (ex: permissões, usuários, produtos)
|
|
10
|
+
- Configuração de associações ou vínculos onde a ordem dos itens selecionados importa
|
|
11
|
+
- Qualquer cenário de transferência bidirecional entre dois conjuntos de dados
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Para seleção simples de um único item — use `Select` ou `RadioButton`
|
|
16
|
+
- Para seleção múltipla sem necessidade de duas listas — use `Checkbox` ou `MultiSelect`
|
|
17
|
+
- Quando a lista é muito grande e precisa de paginação — considere uma abordagem diferente
|
|
18
|
+
|
|
19
|
+
## Instalação
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { PicklistModule } from '@seniorsistemas/angular-components/picklist';
|
|
23
|
+
import { TemplateModule } from '@seniorsistemas/angular-components/template';
|
|
24
|
+
|
|
25
|
+
@NgModule({ imports: [PicklistModule, TemplateModule] })
|
|
26
|
+
export class MeuModulo {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Uso básico
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<s-picklist
|
|
33
|
+
[itensToSelect]="itensDisponiveis"
|
|
34
|
+
[selectedItens]="itensSelecionados"
|
|
35
|
+
(selectedItensChange)="onSelecaoMudou($event)"
|
|
36
|
+
(itensToSelectChange)="onDisponiveisAtualizado($event)"
|
|
37
|
+
>
|
|
38
|
+
<ng-template sTemplate="item-to-select" let-item="item">
|
|
39
|
+
<span>{{ item.nome }}</span>
|
|
40
|
+
</ng-template>
|
|
41
|
+
<ng-template sTemplate="selected-item" let-item="item">
|
|
42
|
+
<span>{{ item.nome }}</span>
|
|
43
|
+
</ng-template>
|
|
44
|
+
</s-picklist>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> Os dois templates (`item-to-select` e `selected-item`) são **obrigatórios**.
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
### Inputs
|
|
52
|
+
|
|
53
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
54
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
55
|
+
| `itensToSelect` | `PickListItem<any>[]` | `[]` | Sim | Lista de itens disponíveis para seleção (coluna esquerda) |
|
|
56
|
+
| `selectedItens` | `PickListItem<any>[]` | `[]` | Sim | Lista de itens já selecionados (coluna direita) |
|
|
57
|
+
| `availableItensLabel` | `string` | Tradução padrão | Não | Rótulo do cabeçalho da lista de disponíveis |
|
|
58
|
+
| `availableItensPlaceholder` | `string` | `undefined` | Não | Placeholder do campo de busca da lista de disponíveis |
|
|
59
|
+
| `addSelectedItensLabel` | `string` | `undefined` | Não | Rótulo do botão que move itens selecionados para a direita |
|
|
60
|
+
| `addAllItensLabel` | `string` | `undefined` | Não | Rótulo do botão que move todos os disponíveis para a direita |
|
|
61
|
+
| `selectedItensLabel` | `string` | Tradução padrão | Não | Rótulo do cabeçalho da lista de selecionados |
|
|
62
|
+
| `selectedItensPlaceholder` | `string` | `undefined` | Não | Placeholder do campo de busca da lista de selecionados |
|
|
63
|
+
| `removeSelectedItemsLabel` | `string` | `undefined` | Não | Rótulo do botão que remove itens selecionados |
|
|
64
|
+
| `removeAllItemsLabel` | `string` | `undefined` | Não | Rótulo do botão que remove todos os selecionados |
|
|
65
|
+
| `showCheckbox` | `boolean` | `false` | Não | Exibe checkboxes nos itens e "selecionar todos" no cabeçalho |
|
|
66
|
+
| `filterBy` | `string` | `''` | Não | Propriedade do objeto `data` usada para filtrar os itens. Quando definido, exibe campos de busca |
|
|
67
|
+
|
|
68
|
+
### Outputs
|
|
69
|
+
|
|
70
|
+
| Evento | Tipo | Descrição |
|
|
71
|
+
|--------|------|-----------|
|
|
72
|
+
| `selectedItensChange` | `EventEmitter<any[]>` | Emitido quando a lista de selecionados muda. Emite os dados brutos (sem o wrapper `PickListItem`) |
|
|
73
|
+
| `itensToSelectChange` | `EventEmitter<any[]>` | Emitido quando a lista de disponíveis muda. Emite os dados brutos (sem o wrapper `PickListItem`) |
|
|
74
|
+
|
|
75
|
+
### Tipos
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
interface PickListItem<T> {
|
|
79
|
+
data: T; // Dados brutos do item — expostos no template como `let-item="item"`
|
|
80
|
+
disabled?: boolean; // Impede seleção, movimentação e drag do item
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Exemplos
|
|
85
|
+
|
|
86
|
+
### Picklist básico
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<s-picklist
|
|
90
|
+
[itensToSelect]="parseItensPickList(paises)"
|
|
91
|
+
[selectedItens]="parseItensPickList(paisesSelecionados)"
|
|
92
|
+
(selectedItensChange)="onSelecaoMudou($event)"
|
|
93
|
+
>
|
|
94
|
+
<ng-template sTemplate="item-to-select" let-item="item">
|
|
95
|
+
<span>{{ item.nome }}</span>
|
|
96
|
+
</ng-template>
|
|
97
|
+
<ng-template sTemplate="selected-item" let-item="item">
|
|
98
|
+
<span>{{ item.nome }}</span>
|
|
99
|
+
</ng-template>
|
|
100
|
+
</s-picklist>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Com filtro e checkbox
|
|
104
|
+
|
|
105
|
+
```html
|
|
106
|
+
<s-picklist
|
|
107
|
+
[itensToSelect]="itensDisponiveis"
|
|
108
|
+
[selectedItens]="itensSelecionados"
|
|
109
|
+
[showCheckbox]="true"
|
|
110
|
+
filterBy="nome"
|
|
111
|
+
availableItensPlaceholder="Buscar..."
|
|
112
|
+
selectedItensPlaceholder="Buscar..."
|
|
113
|
+
>
|
|
114
|
+
<ng-template sTemplate="item-to-select" let-item="item">
|
|
115
|
+
<span>{{ item.nome }}</span>
|
|
116
|
+
</ng-template>
|
|
117
|
+
<ng-template sTemplate="selected-item" let-item="item">
|
|
118
|
+
<span>{{ item.nome }}</span>
|
|
119
|
+
</ng-template>
|
|
120
|
+
</s-picklist>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Com itens desabilitados
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { parseItensPickList } from '@seniorsistemas/angular-components/picklist';
|
|
127
|
+
|
|
128
|
+
this.itensDisponiveis = parseItensPickList(produtos, (item) => !item.emEstoque);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Com labels customizados
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<s-picklist
|
|
135
|
+
[itensToSelect]="itensDisponiveis"
|
|
136
|
+
[selectedItens]="itensSelecionados"
|
|
137
|
+
availableItensLabel="Países disponíveis"
|
|
138
|
+
selectedItensLabel="Países selecionados"
|
|
139
|
+
addSelectedItensLabel="Incluir →"
|
|
140
|
+
addAllItensLabel="Incluir todos"
|
|
141
|
+
removeSelectedItemsLabel="← Excluir"
|
|
142
|
+
removeAllItemsLabel="Excluir todos"
|
|
143
|
+
>
|
|
144
|
+
...
|
|
145
|
+
</s-picklist>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Utilitário parseItensPickList
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { parseItensPickList } from '@seniorsistemas/angular-components/picklist';
|
|
152
|
+
|
|
153
|
+
// Sem itens desabilitados
|
|
154
|
+
this.itensToSelect = parseItensPickList(meusObjetos);
|
|
155
|
+
|
|
156
|
+
// Com função de desabilitação
|
|
157
|
+
this.itensToSelect = parseItensPickList(meusObjetos, (item) => item.bloqueado);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Acessibilidade
|
|
161
|
+
|
|
162
|
+
- Os botões de adicionar/remover são elementos `<button>` nativos, navegáveis por teclado
|
|
163
|
+
- O drag & drop usa o CDK do Angular, acessível com mouse
|
|
164
|
+
- Itens desabilitados não podem ser selecionados, movidos ou arrastados
|
|
165
|
+
- Os campos de filtro têm `placeholder` configurável para orientar o usuário
|
|
166
|
+
|
|
167
|
+
## Componentes relacionados
|
|
168
|
+
|
|
169
|
+
- [`TokenList`](../token-list/README.md) — exibição de tokens selecionados em modo somente leitura
|
|
170
|
+
- [`Chips`](../chips/README.md) — entrada de múltiplos valores em formato de tags
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# PinCodeField
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente para entrada de códigos PIN ou códigos de verificação (OTP) com campos individuais para cada dígito. Implementa `ControlValueAccessor` para integração nativa com Reactive Forms e Template-Driven Forms do Angular.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Códigos de verificação OTP enviados por SMS ou e-mail
|
|
10
|
+
- Autenticação de dois fatores (2FA)
|
|
11
|
+
- PINs numéricos de acesso (ex: cartão de crédito)
|
|
12
|
+
- Códigos de ativação de produto (alfanumérico)
|
|
13
|
+
|
|
14
|
+
## Quando não usar
|
|
15
|
+
|
|
16
|
+
- Para senhas textuais sem comprimento fixo — use `<input type="password">` com `sPasswordStrength`
|
|
17
|
+
- Para campos de texto curto com comprimento variável — use `InputText`
|
|
18
|
+
|
|
19
|
+
## Instalação
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { PinCodeFieldComponent } from '@seniorsistemas/angular-components/pin-code-field';
|
|
23
|
+
|
|
24
|
+
@Component({
|
|
25
|
+
standalone: true,
|
|
26
|
+
imports: [PinCodeFieldComponent, ReactiveFormsModule],
|
|
27
|
+
})
|
|
28
|
+
export class MeuComponent {}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Uso básico
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<form [formGroup]="form">
|
|
35
|
+
<s-pin-code-field
|
|
36
|
+
formControlName="codigo"
|
|
37
|
+
[length]="6"
|
|
38
|
+
helpText="Digite o código de 6 dígitos recebido"
|
|
39
|
+
(codeFilled)="onCodigoConcluido($event)"
|
|
40
|
+
></s-pin-code-field>
|
|
41
|
+
</form>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
### Inputs
|
|
47
|
+
|
|
48
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
49
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
50
|
+
| `length` | `number` | `6` | Não | Número de campos de entrada (comprimento do código PIN). Mínimo: 1 |
|
|
51
|
+
| `alphanumeric` | `boolean` | `false` | Não | Permite entrada alfanumérica. Quando `false`, aceita apenas dígitos (0–9) |
|
|
52
|
+
| `helpText` | `string` | `''` | Não | Texto de ajuda exibido abaixo dos campos |
|
|
53
|
+
| `invalid` | `boolean` | `false` | Não | Exibe borda vermelha nos campos. Tipicamente vinculado ao estado `invalid && dirty` do `FormControl` |
|
|
54
|
+
| `disabled` | `boolean` | `false` | Não | Two-way binding para o estado desabilitado. Desabilita todos os campos |
|
|
55
|
+
|
|
56
|
+
### Outputs
|
|
57
|
+
|
|
58
|
+
| Evento | Tipo | Descrição |
|
|
59
|
+
|--------|------|-----------|
|
|
60
|
+
| `codeFilled` | `OutputEmitterRef<string>` | Emitido quando todos os campos estão preenchidos. Emite o código completo como string |
|
|
61
|
+
|
|
62
|
+
## Exemplos
|
|
63
|
+
|
|
64
|
+
### Código OTP de 6 dígitos com Reactive Forms
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<form [formGroup]="form">
|
|
68
|
+
<s-pin-code-field
|
|
69
|
+
formControlName="codigo"
|
|
70
|
+
[length]="6"
|
|
71
|
+
[alphanumeric]="false"
|
|
72
|
+
[invalid]="(form.get('codigo')?.invalid && form.get('codigo')?.dirty) || false"
|
|
73
|
+
helpText="Digite o código de 6 dígitos recebido"
|
|
74
|
+
(codeFilled)="onCodigoConcluido($event)"
|
|
75
|
+
></s-pin-code-field>
|
|
76
|
+
</form>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### PIN de 4 dígitos
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<s-pin-code-field
|
|
83
|
+
formControlName="pin"
|
|
84
|
+
[length]="4"
|
|
85
|
+
helpText="Digite seu PIN de 4 dígitos"
|
|
86
|
+
></s-pin-code-field>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Código alfanumérico
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<s-pin-code-field
|
|
93
|
+
formControlName="chave"
|
|
94
|
+
[length]="6"
|
|
95
|
+
[alphanumeric]="true"
|
|
96
|
+
helpText="Digite o código alfanumérico (letras e números)"
|
|
97
|
+
></s-pin-code-field>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Estado de erro
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<s-pin-code-field
|
|
104
|
+
formControlName="codigo"
|
|
105
|
+
[length]="6"
|
|
106
|
+
[invalid]="true"
|
|
107
|
+
helpText="Digite o código de 6 dígitos"
|
|
108
|
+
></s-pin-code-field>
|
|
109
|
+
<p style="color: red;">Código inválido. Tente novamente.</p>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Desabilitado com valor pré-preenchido
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
this.form = new FormGroup({
|
|
116
|
+
codigo: new FormControl('123456'),
|
|
117
|
+
});
|
|
118
|
+
this.form.disable();
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```html
|
|
122
|
+
<s-pin-code-field formControlName="codigo" [length]="6"></s-pin-code-field>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Acessibilidade
|
|
126
|
+
|
|
127
|
+
- Cada campo de entrada possui ARIA label e role semântico correto
|
|
128
|
+
- Navegação completa por teclado:
|
|
129
|
+
- `ArrowRight` / `ArrowLeft`: move o foco entre os campos
|
|
130
|
+
- `Backspace`: limpa o campo atual ou retorna ao anterior
|
|
131
|
+
- Auto-avança para o próximo campo ao preencher cada dígito
|
|
132
|
+
- Suporte a colar (Ctrl+V / Cmd+V): distribui automaticamente os caracteres válidos entre os campos
|
|
133
|
+
- O componente é marcado como `touched` quando o último campo perde o foco
|
|
134
|
+
|
|
135
|
+
## Componentes relacionados
|
|
136
|
+
|
|
137
|
+
- [`PasswordStrength`](../password-strength/README.md) — indicador visual de força de senha
|
package/product-header/README.md
CHANGED
|
@@ -1,17 +1,44 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ProductHeader
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
Este pacote é um alias de compatibilidade para o componente `Topbar
|
|
5
|
+
> **Descontinuado** — Este pacote é um alias de compatibilidade para o componente `Topbar` e será removido na versão 20.0.0.
|
|
6
|
+
|
|
7
|
+
O pacote `product-header` re-exporta `TopbarComponent` e `TopbarModule` do pacote `@seniorsistemas/angular-components/topbar` com os nomes antigos `ProductHeaderComponent` e `ProductHeaderModule`.
|
|
8
|
+
|
|
9
|
+
## Quando usar
|
|
10
|
+
|
|
11
|
+
- Apenas para manutenção de código legado que já usa `ProductHeaderComponent` ou `ProductHeaderModule`
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Em todo código novo — use `TopbarComponent` ou `TopbarModule` do pacote `@seniorsistemas/angular-components/topbar`
|
|
6
16
|
|
|
7
17
|
## Migração
|
|
8
18
|
|
|
9
|
-
|
|
19
|
+
```typescript
|
|
20
|
+
// Antes (descontinuado)
|
|
21
|
+
import { ProductHeaderModule } from '@seniorsistemas/angular-components/product-header';
|
|
10
22
|
|
|
11
|
-
|
|
23
|
+
// Depois (recomendado)
|
|
24
|
+
import { TopbarModule } from '@seniorsistemas/angular-components/topbar';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<!-- Antes (descontinuado) -->
|
|
29
|
+
<s-product-header></s-product-header>
|
|
30
|
+
|
|
31
|
+
<!-- Depois (recomendado) -->
|
|
32
|
+
<s-topbar></s-topbar>
|
|
33
|
+
```
|
|
12
34
|
|
|
13
35
|
## Documentação
|
|
14
36
|
|
|
15
|
-
Consulte a documentação completa do componente
|
|
37
|
+
Consulte a documentação completa do componente no Topbar:
|
|
38
|
+
|
|
16
39
|
- **Storybook**: `Components/Structure/Topbar`
|
|
17
40
|
- **Pacote**: `@seniorsistemas/angular-components/topbar`
|
|
41
|
+
|
|
42
|
+
## Componentes relacionados
|
|
43
|
+
|
|
44
|
+
- [`Topbar`](../topbar/README.md) — componente substituto recomendado
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# ProfilePicturePicker
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente para seleção, recorte e gerenciamento de foto de perfil. Permite selecionar uma imagem via clique ou arrastar e soltar, recortá-la em um cropper integrado e exibi-la como thumbnail. Implementa `ControlValueAccessor` para integração com Angular Forms.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Cadastro ou edição de perfil de usuário com foto
|
|
10
|
+
- Formulários que precisam de upload de imagem com recorte antes de salvar
|
|
11
|
+
- Campos de avatar em sistemas de gestão de pessoas
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Para upload de arquivos genéricos (documentos, PDFs, etc.) — use `FilePicker`
|
|
16
|
+
- Para seleção de imagem sem recorte — use um input de arquivo simples
|
|
17
|
+
- Quando o aspecto ratio varia dinamicamente por item — configure `aspectRatio` conforme o caso
|
|
18
|
+
|
|
19
|
+
## Instalação
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { ProfilePicturePickerModule } from '@seniorsistemas/angular-components/profile-picture-picker';
|
|
23
|
+
|
|
24
|
+
@NgModule({ imports: [ProfilePicturePickerModule] })
|
|
25
|
+
export class MeuModulo {}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Uso básico
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<s-profile-picture-picker
|
|
32
|
+
formControlName="avatar"
|
|
33
|
+
subtitle="Formato: JPG, PNG (máximo de 1 MB)"
|
|
34
|
+
simpleTitle="Arraste sua foto ou"
|
|
35
|
+
actionTitle="selecione um arquivo"
|
|
36
|
+
accept=".png, .jpg"
|
|
37
|
+
[supportedExtensions]="['png', 'jpg']"
|
|
38
|
+
[maxFileSize]="1048576"
|
|
39
|
+
(imageChange)="onImageChange($event)"
|
|
40
|
+
(removedImage)="onImageRemoved()"
|
|
41
|
+
(invalidFile)="onArquivoInvalido($event)"
|
|
42
|
+
/>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
### Inputs
|
|
48
|
+
|
|
49
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
50
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
51
|
+
| `subtitle` | `string` | — | Sim | Legenda exibida abaixo do título com orientações de formato e tamanho |
|
|
52
|
+
| `simpleTitle` | `string` | `undefined` | Não | Parte estática do título (antes da ação clicável) |
|
|
53
|
+
| `actionTitle` | `string` | `undefined` | Não | Parte clicável do título — ao clicar, abre o seletor de arquivo |
|
|
54
|
+
| `image` | `string \| ProfilePicturePickerData \| null` | `null` | Não | Imagem atual. Aceita string base64 ou objeto com dados do arquivo |
|
|
55
|
+
| `aspectRatio` | `number` | `1` | Não | Proporção de aspecto do recorte (`1` = quadrado, `16/9` = widescreen) |
|
|
56
|
+
| `accept` | `string` | `undefined` | Não | Atributo `accept` do input de arquivo (ex: `".png, .jpg"`) |
|
|
57
|
+
| `supportedExtensions` | `string[]` | `[]` | Não | Extensões aceitas para validação (ex: `['png', 'jpg']`) |
|
|
58
|
+
| `maxFileSize` | `number` | `undefined` | Não | Tamanho máximo em bytes. Exemplo: `1048576` = 1 MB |
|
|
59
|
+
| `removeButtonLabel` | `string` | Tradução padrão | Não | Texto do botão de remover a foto |
|
|
60
|
+
| `changeButtonLabel` | `string` | Tradução padrão | Não | Texto do botão de alterar a foto |
|
|
61
|
+
| `confirmationTexts` | `ConfirmationTexts` | `undefined` | Não | Textos do diálogo de confirmação de remoção |
|
|
62
|
+
| `cropperLabelsConfig` | `CropperLabelsConfig` | `undefined` | Não | Textos customizados do Image Cropper integrado |
|
|
63
|
+
|
|
64
|
+
### Outputs
|
|
65
|
+
|
|
66
|
+
| Evento | Tipo | Descrição |
|
|
67
|
+
|--------|------|-----------|
|
|
68
|
+
| `imageChange` | `EventEmitter<string \| ProfilePicturePickerData>` | Emitido quando uma imagem é selecionada e recortada |
|
|
69
|
+
| `removedImage` | `EventEmitter<void>` | Emitido quando o usuário confirma a remoção da imagem |
|
|
70
|
+
| `invalidFile` | `EventEmitter<FileValidationErrors>` | Emitido quando a validação do arquivo falha |
|
|
71
|
+
| ~~`changedImage`~~ | `EventEmitter<string>` | **Descontinuado** — use `imageChange` |
|
|
72
|
+
|
|
73
|
+
### Tipos
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
interface ProfilePicturePickerData {
|
|
77
|
+
source: File; // Arquivo original selecionado
|
|
78
|
+
base64: string; // Imagem recortada em base64
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface FileValidationErrors {
|
|
82
|
+
file: File | null;
|
|
83
|
+
validation: 'maxFileSize' | 'maxFileLimit' | 'typeInvalid' | 'unsupportedExtension';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface ConfirmationTexts {
|
|
87
|
+
removalHeader: string; // Título do diálogo de confirmação
|
|
88
|
+
removalMessage: string; // Mensagem do diálogo
|
|
89
|
+
removalAcceptLabel: string; // Label do botão confirmar
|
|
90
|
+
removalRejectLabel: string; // Label do botão cancelar
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface CropperLabelsConfig {
|
|
94
|
+
header?: string;
|
|
95
|
+
cropLabel?: string;
|
|
96
|
+
removeLabel?: string;
|
|
97
|
+
cancelLabel?: string;
|
|
98
|
+
selectAnotherLabel?: string;
|
|
99
|
+
emptyStateTitle?: string;
|
|
100
|
+
emptyStateActionLabel?: string;
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Exemplos
|
|
105
|
+
|
|
106
|
+
### Cadastro de novo usuário
|
|
107
|
+
|
|
108
|
+
```html
|
|
109
|
+
<form [formGroup]="form">
|
|
110
|
+
<s-profile-picture-picker
|
|
111
|
+
formControlName="foto"
|
|
112
|
+
subtitle="Formato: JPG, PNG (máximo de 1 MB)"
|
|
113
|
+
simpleTitle="Arraste sua foto ou"
|
|
114
|
+
actionTitle="selecione um arquivo"
|
|
115
|
+
accept=".png, .jpg"
|
|
116
|
+
[supportedExtensions]="['png', 'jpg']"
|
|
117
|
+
[maxFileSize]="1048576"
|
|
118
|
+
(invalidFile)="onArquivoInvalido($event)"
|
|
119
|
+
></s-profile-picture-picker>
|
|
120
|
+
</form>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Edição com imagem pré-carregada
|
|
124
|
+
|
|
125
|
+
```html
|
|
126
|
+
<form [formGroup]="form">
|
|
127
|
+
<!-- O formControl recebe a string base64 da imagem atual -->
|
|
128
|
+
<s-profile-picture-picker
|
|
129
|
+
formControlName="foto"
|
|
130
|
+
subtitle="Formato: JPG, PNG"
|
|
131
|
+
[changeButtonLabel]="'Trocar foto'"
|
|
132
|
+
[removeButtonLabel]="'Excluir foto'"
|
|
133
|
+
[confirmationTexts]="confirmacaoTextos"
|
|
134
|
+
></s-profile-picture-picker>
|
|
135
|
+
</form>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Com aspect ratio widescreen (banner)
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<s-profile-picture-picker
|
|
142
|
+
formControlName="capa"
|
|
143
|
+
subtitle="Formato: JPG, PNG — proporção 16:9"
|
|
144
|
+
[aspectRatio]="16 / 9"
|
|
145
|
+
></s-profile-picture-picker>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Acessibilidade
|
|
149
|
+
|
|
150
|
+
- A área de upload aceita foco via teclado e interação por clique
|
|
151
|
+
- O drag & drop é complementar — sempre há o botão clicável como alternativa
|
|
152
|
+
- O diálogo de confirmação de remoção usa PrimeNG `ConfirmDialog`, que é acessível por teclado
|
|
153
|
+
- O thumbnail é decorativo e não carece de texto alternativo quando a imagem é de perfil do usuário logado
|
|
154
|
+
|
|
155
|
+
## Componentes relacionados
|
|
156
|
+
|
|
157
|
+
- [`ImageCropper`](../image-cropper/README.md) — cropper de imagem usado internamente
|
|
158
|
+
- [`Thumbnail`](../thumbnail/README.md) — exibição de imagem em miniatura
|
|
159
|
+
- [`FilePicker`](../file-picker/README.md) — seleção de arquivos genérica
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Progressbar
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente de barra de progresso para representar visualmente o avanço de uma operação. Suporta modo determinado (valor percentual 0–100) e modo indeterminado (animação contínua quando a duração é desconhecida), além de um marcador de valor-alvo para comparação.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Processos com percentual de conclusão calculável — uploads, downloads, etapas de um fluxo, metas
|
|
10
|
+
- Operações de duração desconhecida — chamadas de API, processamentos em background (modo indeterminado)
|
|
11
|
+
- Dashboards de desempenho ou KPIs com comparação entre valor atual e meta
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Para indicar carregamento simples de página ou componente — use `Spinner` ou `Skeleton`
|
|
16
|
+
- Para representar sequências de etapas com navegação — use `Steps`
|
|
17
|
+
- Quando não há valor numérico mensurável e a duração é desconhecida sem necessidade de label — use `Spinner`
|
|
18
|
+
|
|
19
|
+
## Instalação
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { ProgressBarModule } from '@seniorsistemas/angular-components/progressbar';
|
|
23
|
+
|
|
24
|
+
@NgModule({ imports: [ProgressBarModule] })
|
|
25
|
+
export class MeuModulo {}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Uso básico
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<s-progressbar
|
|
32
|
+
[value]="75"
|
|
33
|
+
activeColor="blue"
|
|
34
|
+
[showValue]="true"
|
|
35
|
+
/>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API
|
|
39
|
+
|
|
40
|
+
### Inputs
|
|
41
|
+
|
|
42
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
43
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
44
|
+
| `activeColor` | `ProgressBarColors` | — | Sim | Cor da barra de progresso ativa |
|
|
45
|
+
| `value` | `number` | — | Não* | Valor atual (0–100). Obrigatório no modo `'determinate'`. Não usar em `'indeterminate'` |
|
|
46
|
+
| `mode` | `ProgressBarMode` | `'determinate'` | Não | Modo de operação da barra |
|
|
47
|
+
| `showValue` | `boolean` | `true` | Não | Exibe o valor percentual dentro da barra (apenas no modo determinado) |
|
|
48
|
+
| `targetValue` | `number` | `undefined` | Não | Valor-alvo (0–100) exibido como marcador de referência (modo determinado) |
|
|
49
|
+
| `label` | `string` | `undefined` | Não | Rótulo exibido abaixo da barra no modo indeterminado |
|
|
50
|
+
| `targetLabel` | `string` | `undefined` | Não | Rótulo do marcador de valor-alvo |
|
|
51
|
+
| `numberFormatOptions` | `Intl.NumberFormatOptions` | `{ style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 2, roundingMode: 'trunc' }` | Não | Opções de formatação do valor percentual exibido |
|
|
52
|
+
|
|
53
|
+
### Tipos
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
type ProgressBarColors = 'blue' | 'green' | 'red' | 'yellow';
|
|
57
|
+
|
|
58
|
+
type ProgressBarMode = 'determinate' | 'indeterminate';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Guia de cores
|
|
62
|
+
|
|
63
|
+
| Cor | Uso sugerido |
|
|
64
|
+
|-----|-------------|
|
|
65
|
+
| `'blue'` | Progresso neutro ou informativo |
|
|
66
|
+
| `'green'` | Progresso positivo ou concluído com sucesso |
|
|
67
|
+
| `'red'` | Alertas críticos ou progresso negativo |
|
|
68
|
+
| `'yellow'` | Alertas ou progresso intermediário |
|
|
69
|
+
|
|
70
|
+
## Exemplos
|
|
71
|
+
|
|
72
|
+
### Modo determinado básico
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<s-progressbar
|
|
76
|
+
[value]="65"
|
|
77
|
+
activeColor="blue"
|
|
78
|
+
[showValue]="true"
|
|
79
|
+
mode="determinate"
|
|
80
|
+
></s-progressbar>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Com marcador de meta
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<s-progressbar
|
|
87
|
+
[value]="45"
|
|
88
|
+
activeColor="green"
|
|
89
|
+
[showValue]="true"
|
|
90
|
+
mode="determinate"
|
|
91
|
+
[targetValue]="70"
|
|
92
|
+
targetLabel="Meta 70%"
|
|
93
|
+
></s-progressbar>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Múltiplas cores
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<s-progressbar [value]="60" activeColor="blue" [showValue]="true" mode="determinate"></s-progressbar>
|
|
100
|
+
<s-progressbar [value]="80" activeColor="green" [showValue]="true" mode="determinate"></s-progressbar>
|
|
101
|
+
<s-progressbar [value]="35" activeColor="red" [showValue]="true" mode="determinate"></s-progressbar>
|
|
102
|
+
<s-progressbar [value]="55" activeColor="yellow" [showValue]="true" mode="determinate"></s-progressbar>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Sem valor exibido
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<s-progressbar
|
|
109
|
+
[value]="40"
|
|
110
|
+
activeColor="blue"
|
|
111
|
+
[showValue]="false"
|
|
112
|
+
mode="determinate"
|
|
113
|
+
></s-progressbar>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Modo indeterminado
|
|
117
|
+
|
|
118
|
+
```html
|
|
119
|
+
<s-progressbar
|
|
120
|
+
activeColor="blue"
|
|
121
|
+
mode="indeterminate"
|
|
122
|
+
label="Processando dados..."
|
|
123
|
+
></s-progressbar>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Acessibilidade
|
|
127
|
+
|
|
128
|
+
- O componente usa elementos semânticos de barra de progresso com valores calculados pelo CSS
|
|
129
|
+
- No modo determinado, o valor percentual é exibido visualmente dentro da barra
|
|
130
|
+
- No modo indeterminado, o `label` fornece contexto textual para leitores de tela sobre o que está sendo processado
|
|
131
|
+
- Erros são lançados em tempo de desenvolvimento se `value` estiver fora do intervalo 0–100 ou se `value`/`targetValue` forem usados em modo `'indeterminate'`
|
|
132
|
+
|
|
133
|
+
## Componentes relacionados
|
|
134
|
+
|
|
135
|
+
- [`Spinner`](../spinner/README.md) — indicador de carregamento circular
|
|
136
|
+
- [`Steps`](../steps/README.md) — sequência de etapas com navegação
|