@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,117 @@
|
|
|
1
|
+
# RadioButton
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente de botão de opção (radio button) individual com integração nativa ao Angular Forms. Permite seleção única em grupos, utilizando o atributo `name` para garantir exclusividade. Pode ser usado isolado ou em conjunto com `RadioButtonGroupComponent`.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Seleção exclusiva entre duas ou mais opções mutuamente exclusivas
|
|
10
|
+
- Formulários onde o usuário deve escolher exatamente uma opção de um conjunto pequeno e visível
|
|
11
|
+
|
|
12
|
+
## Quando não usar
|
|
13
|
+
|
|
14
|
+
- Para seleção de múltiplas opções simultaneamente — use `Checkbox`
|
|
15
|
+
- Para conjuntos grandes de opções — use `Select` (dropdown)
|
|
16
|
+
- Para toggle simples entre dois estados — use `Switch`
|
|
17
|
+
|
|
18
|
+
## Instalação
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { RadioButtonComponent } from '@seniorsistemas/angular-components/radio-button';
|
|
22
|
+
|
|
23
|
+
@Component({
|
|
24
|
+
standalone: true,
|
|
25
|
+
imports: [RadioButtonComponent, FormsModule],
|
|
26
|
+
})
|
|
27
|
+
export class MeuComponent {}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Uso básico
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<s-radiobutton
|
|
34
|
+
value="opcaoA"
|
|
35
|
+
name="minhasOpcoes"
|
|
36
|
+
label="Opção A"
|
|
37
|
+
[(ngModel)]="selecionado"
|
|
38
|
+
></s-radiobutton>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## API
|
|
42
|
+
|
|
43
|
+
### Inputs
|
|
44
|
+
|
|
45
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
46
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
47
|
+
| `label` | `string` | — | Sim | Texto exibido ao lado do botão de opção |
|
|
48
|
+
| `name` | `string` | — | Sim | Nome do grupo. Deve ser igual para todos os botões do mesmo grupo |
|
|
49
|
+
| `value` | `unknown` | — | Sim | Valor associado ao botão. Emitido ao formulário quando selecionado |
|
|
50
|
+
| `buttonDisabled` | `boolean` | `false` | Não | Two-way binding para desabilitar o botão individualmente |
|
|
51
|
+
| `inputId` | `string` | `'RadioButton_X'` | Não | ID único do `<input>` interno, usado para acessibilidade |
|
|
52
|
+
|
|
53
|
+
### Outputs
|
|
54
|
+
|
|
55
|
+
| Evento | Tipo | Descrição |
|
|
56
|
+
|--------|------|-----------|
|
|
57
|
+
| `focusedInput` | `OutputEmitterRef<FocusEvent>` | Emitido quando o campo interno recebe foco |
|
|
58
|
+
| `inputFocusLost` | `OutputEmitterRef<FocusEvent>` | Emitido quando o campo interno perde o foco |
|
|
59
|
+
|
|
60
|
+
## Exemplos
|
|
61
|
+
|
|
62
|
+
### Grupo com ngModel
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<div style="display: flex; flex-direction: column; gap: 8px;">
|
|
66
|
+
<s-radiobutton value="BR" name="paises" label="Brasil" [(ngModel)]="selecionado"></s-radiobutton>
|
|
67
|
+
<s-radiobutton value="JP" name="paises" label="Japão" [(ngModel)]="selecionado"></s-radiobutton>
|
|
68
|
+
<s-radiobutton value="CA" name="paises" label="Canadá" [(ngModel)]="selecionado"></s-radiobutton>
|
|
69
|
+
</div>
|
|
70
|
+
<p>Selecionado: {{ selecionado }}</p>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Grupo com Reactive Forms
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<form [formGroup]="form">
|
|
77
|
+
<s-radiobutton value="BR" name="pais" label="Brasil" formControlName="pais"></s-radiobutton>
|
|
78
|
+
<s-radiobutton value="JP" name="pais" label="Japão" formControlName="pais"></s-radiobutton>
|
|
79
|
+
<s-radiobutton value="CA" name="pais" label="Canadá" formControlName="pais"></s-radiobutton>
|
|
80
|
+
</form>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Com item desabilitado
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<s-radiobutton value="BR" name="paises" label="Brasil" [(ngModel)]="selecionado"></s-radiobutton>
|
|
87
|
+
<s-radiobutton value="JP" name="paises" label="Japão (indisponível)" [(ngModel)]="selecionado" [buttonDisabled]="true"></s-radiobutton>
|
|
88
|
+
<s-radiobutton value="CA" name="paises" label="Canadá" [(ngModel)]="selecionado"></s-radiobutton>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Com ID customizado (para testes ou acessibilidade)
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
<s-radiobutton
|
|
95
|
+
value="opcaoA"
|
|
96
|
+
name="grupo"
|
|
97
|
+
label="Opção A"
|
|
98
|
+
inputId="radio-opcao-a"
|
|
99
|
+
[(ngModel)]="selecionado"
|
|
100
|
+
></s-radiobutton>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Acessibilidade
|
|
104
|
+
|
|
105
|
+
- Cada botão é um `<input type="radio">` nativo, totalmente acessível por teclado e leitores de tela
|
|
106
|
+
- Navegação por teclado:
|
|
107
|
+
- `Tab`: move o foco para o grupo de radio buttons
|
|
108
|
+
- `Setas ↑↓` ou `←→`: navegam entre as opções do mesmo grupo (`name`)
|
|
109
|
+
- `Space` ou `Enter`: seleciona o botão em foco
|
|
110
|
+
- O `label` é associado ao `<input>` via `inputId`, garantindo clicabilidade e semântica correta
|
|
111
|
+
- Itens desabilitados são sinalizados com `disabled` nativo
|
|
112
|
+
|
|
113
|
+
## Componentes relacionados
|
|
114
|
+
|
|
115
|
+
- [`RadioButtonGroup`](../radio-button-group/README.md) — agrupamento com layout e registro centralizado de radio buttons
|
|
116
|
+
- [`Checkbox`](../checkbox/README.md) — seleção múltipla
|
|
117
|
+
- [`Switch`](../switch/README.md) — alternador booleano simples
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# RatingScale
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente de escala de avaliação que permite ao usuário selecionar um nó de uma escala visual. Ideal para pesquisas de satisfação (NPS, CSAT) e questionários de feedback. Implementa `ControlValueAccessor` para integração com Reactive Forms e Template-Driven Forms.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Pesquisas de satisfação com representação visual emocional (ícones de humor)
|
|
10
|
+
- Net Promoter Score (NPS) com escala numérica de 0 a 10
|
|
11
|
+
- Avaliação de atendimento, suporte ou experiência do usuário
|
|
12
|
+
- Formulários de feedback com escalas qualitativas ou quantitativas
|
|
13
|
+
|
|
14
|
+
## Quando não usar
|
|
15
|
+
|
|
16
|
+
- Para avaliações com estrelas — use `StarRating`
|
|
17
|
+
- Para seleção de uma opção de um conjunto sem representação visual de escala — use `RadioButtonGroup`
|
|
18
|
+
- Quando a escala tem mais de 15 itens e o espaço horizontal é limitado
|
|
19
|
+
|
|
20
|
+
## Instalação
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { RatingScaleModule } from '@seniorsistemas/angular-components/rating-scale';
|
|
24
|
+
|
|
25
|
+
@NgModule({ imports: [RatingScaleModule] })
|
|
26
|
+
export class MeuModulo {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Uso básico
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<s-rating-scale
|
|
33
|
+
[nodes]="nosAvaliacao"
|
|
34
|
+
startLabel="Insatisfeito"
|
|
35
|
+
endLabel="Satisfeito"
|
|
36
|
+
[(ngModel)]="avaliacaoSelecionada"
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### Inputs
|
|
43
|
+
|
|
44
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
45
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
46
|
+
| `nodes` | `RatingScaleNode[]` | — | Sim | Lista de nós que compõem a escala. Cada nó é uma opção clicável |
|
|
47
|
+
| `startLabel` | `string` | `undefined` | Não | Rótulo exibido abaixo do primeiro nó (extremo negativo) |
|
|
48
|
+
| `endLabel` | `string` | `undefined` | Não | Rótulo exibido abaixo do último nó (extremo positivo) |
|
|
49
|
+
| `disabled` | `boolean` | `false` | Não | Desabilita o componente, impedindo seleção de qualquer nó |
|
|
50
|
+
|
|
51
|
+
### Tipos
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
interface RatingScaleNode {
|
|
55
|
+
id: string; // Identificador único do nó (obrigatório)
|
|
56
|
+
title?: string; // Texto exibido abaixo do ícone
|
|
57
|
+
icon?: string; // Classe do ícone Font Awesome (ex: 'fa-smile')
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
> O `FormControl` deve ser do tipo `RatingScaleNode`. O componente emite o objeto `RatingScaleNode` completo quando um nó é selecionado.
|
|
62
|
+
|
|
63
|
+
## Exemplos
|
|
64
|
+
|
|
65
|
+
### Escala de humor com ícones
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const nosHumor: RatingScaleNode[] = [
|
|
69
|
+
{ id: 'very-happy', title: 'Muito feliz', icon: 'fa-laugh-wink' },
|
|
70
|
+
{ id: 'happy', title: 'Feliz', icon: 'fa-smile' },
|
|
71
|
+
{ id: 'normal', title: 'Normal', icon: 'fa-meh' },
|
|
72
|
+
{ id: 'sad', title: 'Triste', icon: 'fa-sad-tear' },
|
|
73
|
+
{ id: 'very-sad', title: 'Muito triste', icon: 'fa-sad-cry' },
|
|
74
|
+
];
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<form [formGroup]="form">
|
|
79
|
+
<s-rating-scale
|
|
80
|
+
formControlName="avaliacao"
|
|
81
|
+
[nodes]="nosHumor"
|
|
82
|
+
startLabel="Triste"
|
|
83
|
+
endLabel="Feliz"
|
|
84
|
+
></s-rating-scale>
|
|
85
|
+
</form>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Escala numérica NPS (1 a 10)
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const nosNPS: RatingScaleNode[] = Array.from({ length: 10 }, (_, i) => ({
|
|
92
|
+
id: String(i + 1),
|
|
93
|
+
title: String(i + 1),
|
|
94
|
+
}));
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<s-rating-scale
|
|
99
|
+
formControlName="nps"
|
|
100
|
+
[nodes]="nosNPS"
|
|
101
|
+
startLabel="Muito insatisfeito"
|
|
102
|
+
endLabel="Muito satisfeito"
|
|
103
|
+
></s-rating-scale>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Com valor pré-selecionado
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
this.form = new FormGroup({
|
|
110
|
+
avaliacao: new FormControl(nosHumor[1]), // 'Feliz' pré-selecionado
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Desabilitado (somente leitura)
|
|
115
|
+
|
|
116
|
+
```html
|
|
117
|
+
<s-rating-scale
|
|
118
|
+
formControlName="avaliacao"
|
|
119
|
+
[nodes]="nosHumor"
|
|
120
|
+
[disabled]="true"
|
|
121
|
+
startLabel="Triste"
|
|
122
|
+
endLabel="Feliz"
|
|
123
|
+
></s-rating-scale>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Apenas ícones (sem títulos nos nós)
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<s-rating-scale
|
|
130
|
+
[nodes]="[
|
|
131
|
+
{ id: 'very-happy', icon: 'fa-laugh-wink' },
|
|
132
|
+
{ id: 'happy', icon: 'fa-smile' },
|
|
133
|
+
{ id: 'normal', icon: 'fa-meh' },
|
|
134
|
+
{ id: 'sad', icon: 'fa-sad-tear' },
|
|
135
|
+
{ id: 'very-sad', icon: 'fa-sad-cry' }
|
|
136
|
+
]"
|
|
137
|
+
startLabel="Triste"
|
|
138
|
+
endLabel="Feliz"
|
|
139
|
+
[(ngModel)]="avaliacao"
|
|
140
|
+
></s-rating-scale>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Acessibilidade
|
|
144
|
+
|
|
145
|
+
- Cada nó é um elemento `<button>` nativo, navegável por `Tab`, `Enter` e `Space`
|
|
146
|
+
- O nó selecionado recebe destaque visual
|
|
147
|
+
- Os ícones requerem Font Awesome disponível na aplicação
|
|
148
|
+
- `startLabel` e `endLabel` contextualizam os extremos da escala para todos os usuários
|
|
149
|
+
- Em modo `disabled`, nenhum nó aceita interação e o estilo visual indica o estado inativo
|
|
150
|
+
|
|
151
|
+
## Componentes relacionados
|
|
152
|
+
|
|
153
|
+
- [`StarRating`](../star-rating/README.md) — avaliação por estrelas com escala numérica fixa
|
|
154
|
+
- [`RadioButtonGroup`](../radio-button-group/README.md) — seleção única em lista de opções
|
package/select/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Select
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente de seleção dropdown genérico com suporte a seleção simples e múltipla, filtro, agrupamento, virtual scroll e acessibilidade ARIA completa. Implementa `ControlValueAccessor` para integração com Angular Forms.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Selecionar uma ou mais opções de uma lista fixa de itens
|
|
10
|
+
- Substituir `<select>` nativo com estilo customizado e recursos avançados
|
|
11
|
+
- Listas longas que precisam de busca textual (`filter`)
|
|
12
|
+
- Opções organizadas por categoria (`group`)
|
|
13
|
+
- Listas com muitos itens que exigem virtualização (`virtualScroll`)
|
|
14
|
+
|
|
15
|
+
## Quando não usar
|
|
16
|
+
|
|
17
|
+
- Listas com poucas opções sempre visíveis — prefira `SelectButton` ou `RadioButtonGroup`
|
|
18
|
+
- Busca com carregamento dinâmico de resultados — prefira `Autocomplete`
|
|
19
|
+
- Entrada de múltiplos valores livres — prefira `Chips`
|
|
20
|
+
|
|
21
|
+
## Instalação
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { SelectComponent } from '@seniorsistemas/angular-components/select';
|
|
25
|
+
|
|
26
|
+
@Component({ standalone: true, imports: [SelectComponent] })
|
|
27
|
+
export class MeuComponent {}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Uso básico
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<s-select
|
|
34
|
+
formControlName="pais"
|
|
35
|
+
[options]="paises"
|
|
36
|
+
optionLabel="nome"
|
|
37
|
+
optionValue="codigo"
|
|
38
|
+
placeholder="Selecione um país" />
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## API
|
|
42
|
+
|
|
43
|
+
### Inputs
|
|
44
|
+
|
|
45
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
46
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
47
|
+
| `options` | `T[]` | — | Sim | Lista de opções disponíveis para seleção |
|
|
48
|
+
| `placeholder` | `string` | `''` | Não | Texto exibido quando nenhuma opção está selecionada |
|
|
49
|
+
| `optionLabel` | `keyof T` | `undefined` | Não | Chave do objeto usada como texto de exibição. Obrigatório quando `options` são objetos |
|
|
50
|
+
| `optionValue` | `keyof T` | `undefined` | Não | Chave do objeto cujo valor será emitido ao formulário |
|
|
51
|
+
| `multiple` | `boolean` | `false` | Não | Habilita seleção de múltiplas opções com checkboxes |
|
|
52
|
+
| `filter` | `boolean` | `false` | Não | Exibe campo de busca textual no topo do dropdown |
|
|
53
|
+
| `filterBy` | `keyof T \| (keyof T)[]` | `undefined` | Não | Campo(s) usados para filtragem textual. Padrão: `optionLabel` |
|
|
54
|
+
| `showClear` | `boolean` | `false` | Não | Exibe botão X para limpar a seleção atual |
|
|
55
|
+
| `checkmark` | `boolean` | `false` | Não | Exibe ícone de checkmark ao lado da opção selecionada |
|
|
56
|
+
| `group` | `boolean` | `false` | Não | Habilita agrupamento. As opções devem ter estrutura `{ name, items[] }` |
|
|
57
|
+
| `virtualScroll` | `boolean` | `false` | Não | Virtualiza a lista para melhor performance com grandes volumes |
|
|
58
|
+
| `virtualScrollItemSize` | `number` | `37` | Não | Altura fixa de cada item em pixels para cálculo do virtual scroll |
|
|
59
|
+
| `emptyMessage` | `string \| null` | `null` | Não | Mensagem exibida quando nenhuma opção corresponde ao filtro |
|
|
60
|
+
| `disabled` | `boolean` (model) | `false` | Não | Controla o estado desabilitado via two-way binding |
|
|
61
|
+
| `showOptions` | `boolean` (model) | `false` | Não | Controla a visibilidade do painel via two-way binding |
|
|
62
|
+
| `ariaLabel` | `string` | `''` | Não | Label de acessibilidade do componente |
|
|
63
|
+
| `ariaLabelledBy` | `string` | `''` | Não | ID do elemento externo que descreve o componente |
|
|
64
|
+
|
|
65
|
+
### Tipos
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// Estrutura para opções agrupadas
|
|
69
|
+
interface GroupedOption {
|
|
70
|
+
name: string; // label do grupo
|
|
71
|
+
items: T[]; // opções filhas
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Exemplos
|
|
76
|
+
|
|
77
|
+
### Seleção simples
|
|
78
|
+
|
|
79
|
+
```html
|
|
80
|
+
<form [formGroup]="form">
|
|
81
|
+
<s-select
|
|
82
|
+
formControlName="pais"
|
|
83
|
+
[options]="paises"
|
|
84
|
+
optionLabel="nome"
|
|
85
|
+
optionValue="nome"
|
|
86
|
+
placeholder="Selecione um país"
|
|
87
|
+
[showClear]="true"
|
|
88
|
+
ariaLabel="Selecione um país"
|
|
89
|
+
></s-select>
|
|
90
|
+
</form>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Com filtro de busca
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<s-select
|
|
97
|
+
formControlName="pais"
|
|
98
|
+
[options]="paises"
|
|
99
|
+
optionLabel="nome"
|
|
100
|
+
optionValue="nome"
|
|
101
|
+
placeholder="Buscar país..."
|
|
102
|
+
[filter]="true"
|
|
103
|
+
[showClear]="true"
|
|
104
|
+
></s-select>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Seleção múltipla
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<s-select
|
|
111
|
+
formControlName="paises"
|
|
112
|
+
[options]="paises"
|
|
113
|
+
optionLabel="nome"
|
|
114
|
+
optionValue="nome"
|
|
115
|
+
placeholder="Selecione países..."
|
|
116
|
+
[multiple]="true"
|
|
117
|
+
[filter]="true"
|
|
118
|
+
[showClear]="true"
|
|
119
|
+
></s-select>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Opções agrupadas
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<s-select
|
|
126
|
+
formControlName="pais"
|
|
127
|
+
[options]="paisesPorContinente"
|
|
128
|
+
optionLabel="nome"
|
|
129
|
+
optionValue="nome"
|
|
130
|
+
placeholder="Selecione por continente..."
|
|
131
|
+
[group]="true"
|
|
132
|
+
ariaLabel="Selecione um país por continente"
|
|
133
|
+
></s-select>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Acessibilidade
|
|
137
|
+
|
|
138
|
+
- O componente implementa o padrão ARIA `combobox` com `role="combobox"`, `aria-expanded` e `aria-haspopup`
|
|
139
|
+
- Navegação pelo teclado: `ArrowDown`/`ArrowUp` para mover entre opções, `Enter`/`Espaço` para selecionar, `Escape` para fechar
|
|
140
|
+
- Com `filter` aberto: `ArrowDown` move o foco para a lista, `Escape` retorna foco ao campo de busca
|
|
141
|
+
- Os inputs `ariaLabel` e `ariaLabelledBy` permitem associar descrições externas para leitores de tela
|
|
142
|
+
- Ao fechar o dropdown, o foco retorna automaticamente ao elemento trigger
|
|
143
|
+
|
|
144
|
+
## Componentes relacionados
|
|
145
|
+
|
|
146
|
+
- [`SelectButton`](../select-button/README.md) — quando as opções devem estar sempre visíveis como botões
|
|
147
|
+
- [`Autocomplete`](../autocomplete/README.md) — quando a lista é carregada dinamicamente via busca
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# SelectButton
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente para seleção de uma ou múltiplas opções através de botões visuais agrupados. Alternativa visual ao `select` ou `radio button` quando as opções são poucas e devem estar sempre visíveis. Implementa `ControlValueAccessor` para integração com Angular Forms.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Filtros de período (hoje, semana, mês) em dashboards
|
|
10
|
+
- Alternância entre modos de visualização (lista, grade, mapa)
|
|
11
|
+
- Seleção de tipo ou categoria com opções mutuamente exclusivas e poucas alternativas (até 5)
|
|
12
|
+
- Filtros com múltiplos critérios aplicáveis simultaneamente (`multiple: true`)
|
|
13
|
+
|
|
14
|
+
## Quando não usar
|
|
15
|
+
|
|
16
|
+
- Listas com muitas opções — prefira `Select` com dropdown
|
|
17
|
+
- Seleção única com rótulos descritivos longos — prefira `RadioButtonGroup`
|
|
18
|
+
- Entrada de valores livres — prefira `Chips`
|
|
19
|
+
|
|
20
|
+
## Instalação
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { SelectButtonModule } from '@seniorsistemas/angular-components/select-button';
|
|
24
|
+
|
|
25
|
+
@NgModule({ imports: [SelectButtonModule] })
|
|
26
|
+
export class MeuModule {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Uso básico
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<s-select-button
|
|
33
|
+
formControlName="periodo"
|
|
34
|
+
[items]="periodos"
|
|
35
|
+
/>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API
|
|
39
|
+
|
|
40
|
+
### Inputs
|
|
41
|
+
|
|
42
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
43
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
44
|
+
| `items` | `SelectButtonItem[]` | — | Sim | Lista de itens exibidos como botões de seleção |
|
|
45
|
+
| `multiple` | `boolean` | `false` | Não | Permite selecionar múltiplos itens simultaneamente |
|
|
46
|
+
|
|
47
|
+
### Outputs
|
|
48
|
+
|
|
49
|
+
| Evento | Tipo | Descrição |
|
|
50
|
+
|--------|------|-----------|
|
|
51
|
+
| `itemSelected` | `EventEmitter<SelectButtonItem[]>` | Emitido após a seleção ser atualizada. Emite o array completo de itens ativos |
|
|
52
|
+
| `itemClicked` | `EventEmitter<SelectButtonItem>` | Emitido quando um item habilitado é clicado, antes da atualização da seleção |
|
|
53
|
+
|
|
54
|
+
### Tipos
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
interface SelectButtonItem {
|
|
58
|
+
label: string; // Texto exibido no botão. Obrigatório.
|
|
59
|
+
value: any; // Valor associado. Obrigatório.
|
|
60
|
+
disabled?: boolean; // Desabilita o item individualmente.
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Exemplos
|
|
65
|
+
|
|
66
|
+
### Seleção única — filtro de período
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<form [formGroup]="form">
|
|
70
|
+
<s-select-button
|
|
71
|
+
formControlName="periodo"
|
|
72
|
+
[items]="periodos"
|
|
73
|
+
[multiple]="false"
|
|
74
|
+
(itemSelected)="onPeriodoChange($event)"
|
|
75
|
+
></s-select-button>
|
|
76
|
+
</form>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
periodos: SelectButtonItem[] = [
|
|
81
|
+
{ label: 'Hoje', value: 'today' },
|
|
82
|
+
{ label: 'Esta semana', value: 'week' },
|
|
83
|
+
{ label: 'Este mês', value: 'month' },
|
|
84
|
+
{ label: 'Este ano', value: 'year' },
|
|
85
|
+
];
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Seleção múltipla
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<form [formGroup]="form">
|
|
92
|
+
<s-select-button
|
|
93
|
+
formControlName="frameworks"
|
|
94
|
+
[items]="frameworks"
|
|
95
|
+
[multiple]="true"
|
|
96
|
+
(itemSelected)="onSelecionados($event)"
|
|
97
|
+
(itemClicked)="onClicado($event)"
|
|
98
|
+
></s-select-button>
|
|
99
|
+
</form>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Com item desabilitado individualmente
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<s-select-button
|
|
106
|
+
formControlName="status"
|
|
107
|
+
[items]="statusItems"
|
|
108
|
+
></s-select-button>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
statusItems: SelectButtonItem[] = [
|
|
113
|
+
{ label: 'Ativo', value: 'active' },
|
|
114
|
+
{ label: 'Inativo', value: 'inactive' },
|
|
115
|
+
{ label: 'Bloqueado', value: 'blocked', disabled: true },
|
|
116
|
+
];
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Com valor pré-selecionado via FormControl
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
form = new FormGroup({
|
|
123
|
+
selection: new FormControl([{ label: 'Angular', value: 'angular' }])
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Acessibilidade
|
|
128
|
+
|
|
129
|
+
- Cada item do grupo é renderizado como um `<button>` com `role="button"`
|
|
130
|
+
- Itens desabilitados recebem o atributo `disabled` nativo e não respondem a foco ou clique
|
|
131
|
+
- O estado de seleção é indicado visualmente por classes CSS; recomenda-se associar `aria-pressed` via customização para leitores de tela
|
|
132
|
+
- O componente inteiro pode ser desabilitado via `FormControl.disable()` ou `setDisabledState`
|
|
133
|
+
|
|
134
|
+
## Componentes relacionados
|
|
135
|
+
|
|
136
|
+
- [`Select`](../select/README.md) — quando há muitas opções ou o espaço é limitado
|
|
137
|
+
- [`RadioButtonGroup`](../radio-button-group/README.md) — seleção única com layout vertical/horizontal
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Sidebar
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente de painel lateral deslizante que aparece sobre o conteúdo vindo do lado direito da tela. Suporta templates customizados para cabeçalho, corpo e rodapé via `sTemplate`, bloqueio automático de scroll e confirmação de fechamento.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Exibir detalhes de um item selecionado sem sair da página atual
|
|
10
|
+
- Formulários simples de edição rápida sem necessidade de uma nova rota
|
|
11
|
+
- Painéis de filtros avançados em listas e tabelas
|
|
12
|
+
- Configurações ou propriedades de um elemento da interface
|
|
13
|
+
- Fluxos complementares que não devem interromper o contexto principal
|
|
14
|
+
|
|
15
|
+
## Quando não usar
|
|
16
|
+
|
|
17
|
+
- Confirmações de ações destrutivas — prefira `ConfirmDialog`
|
|
18
|
+
- Conteúdo crítico que exige atenção exclusiva do usuário — prefira `Dialog` modal
|
|
19
|
+
- Navegação principal da aplicação — prefira um menu lateral (`nav`) fixo
|
|
20
|
+
|
|
21
|
+
## Instalação
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { SidebarModule } from '@seniorsistemas/angular-components/sidebar';
|
|
25
|
+
|
|
26
|
+
@NgModule({ imports: [SidebarModule] })
|
|
27
|
+
export class MeuModule {}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Uso básico
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<s-sidebar [(visible)]="sidebarAberta" header="Detalhes">
|
|
34
|
+
<p>Conteúdo do painel lateral.</p>
|
|
35
|
+
</s-sidebar>
|
|
36
|
+
|
|
37
|
+
<button (click)="sidebarAberta = true">Abrir Sidebar</button>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### Inputs
|
|
43
|
+
|
|
44
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
45
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
46
|
+
| `visible` | `ModelSignal<boolean>` | `false` | Não | Controla a visibilidade da sidebar. Suporta `[(visible)]` |
|
|
47
|
+
| `closable` | `boolean` | `true` | Não | Exibe o botão de fechar (X) no cabeçalho |
|
|
48
|
+
| `dismissible` | `boolean` | `true` | Não | Fechar ao clicar no backdrop (área escurecida fora do painel) |
|
|
49
|
+
| `closeOnEscape` | `boolean` | `true` | Não | Fechar ao pressionar a tecla Escape |
|
|
50
|
+
| `header` | `string` | `undefined` | Não | Texto exibido no cabeçalho padrão. Substituível via `sTemplate="header"` |
|
|
51
|
+
| `largeSized` | `boolean` | `false` | Não | Aumenta a largura da sidebar para acomodar mais conteúdo |
|
|
52
|
+
| `cache` | `boolean` | `false` | Não | Mantém o conteúdo no DOM quando fechada, preservando estado interno |
|
|
53
|
+
| `registerConfirmClose` | `() => boolean` | `() => true` | Não | Função chamada antes de fechar; retornar `false` bloqueia o fechamento |
|
|
54
|
+
|
|
55
|
+
## Exemplos
|
|
56
|
+
|
|
57
|
+
### Sidebar básica
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<s-sidebar [(visible)]="visible" header="Filtros Avançados" [closable]="true">
|
|
61
|
+
<p>Conteúdo do painel.</p>
|
|
62
|
+
</s-sidebar>
|
|
63
|
+
<s-button label="Abrir" (clicked)="visible = true"></s-button>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Sidebar grande
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<s-sidebar [(visible)]="visible" header="Edição de Registro" [largeSized]="true">
|
|
70
|
+
<!-- formulário complexo -->
|
|
71
|
+
</s-sidebar>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Com templates customizados
|
|
75
|
+
|
|
76
|
+
```html
|
|
77
|
+
<s-sidebar [(visible)]="visible">
|
|
78
|
+
<ng-template sTemplate="header">
|
|
79
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
80
|
+
<i class="fa fa-filter"></i>
|
|
81
|
+
<span>Filtros Avançados</span>
|
|
82
|
+
</div>
|
|
83
|
+
</ng-template>
|
|
84
|
+
<ng-template sTemplate="body">
|
|
85
|
+
<!-- conteúdo do painel -->
|
|
86
|
+
</ng-template>
|
|
87
|
+
<ng-template sTemplate="footer">
|
|
88
|
+
<s-button label="Aplicar" priority="primary" (clicked)="visible = false"></s-button>
|
|
89
|
+
</ng-template>
|
|
90
|
+
</s-sidebar>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Com confirmação de fechamento
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
confirmClose = (): boolean => {
|
|
97
|
+
return window.confirm('Deseja realmente fechar? As alterações serão perdidas.');
|
|
98
|
+
};
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<s-sidebar [(visible)]="visible" [registerConfirmClose]="confirmClose">
|
|
103
|
+
<!-- formulário com alterações não salvas -->
|
|
104
|
+
</s-sidebar>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Acessibilidade
|
|
108
|
+
|
|
109
|
+
- A sidebar utiliza `cdkTrapFocus` para aprisionar o foco dentro do painel enquanto aberta
|
|
110
|
+
- Pressionar `Escape` fecha a sidebar quando `closeOnEscape = true`
|
|
111
|
+
- O painel entra e sai com animação de deslizamento (300ms) vindo da direita
|
|
112
|
+
- Ao abrir, o scroll da página é bloqueado automaticamente e restaurado ao fechar
|
|
113
|
+
|
|
114
|
+
## Componentes relacionados
|
|
115
|
+
|
|
116
|
+
- [`Dialog`](../dialog/README.md) — modal centralizado para confirmações e conteúdo crítico
|
|
117
|
+
- [`SlideInBar`](../slide-in-bar/README.md) — painel que expande/colapsa embutido no layout
|