@dev-tcloud/tcloud-ui 6.14.3 → 6.17.0
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/docs/tcloud-ui-accordion.md +345 -0
- package/docs/tcloud-ui-actions.md +88 -0
- package/docs/tcloud-ui-alert-banner.md +104 -0
- package/docs/tcloud-ui-array-to-text.md +361 -0
- package/docs/tcloud-ui-breadcrumb.md +103 -0
- package/docs/tcloud-ui-bytes.md +109 -0
- package/docs/tcloud-ui-calendar.md +387 -0
- package/docs/tcloud-ui-card-accordion.md +266 -0
- package/docs/tcloud-ui-card-title.md +47 -0
- package/docs/tcloud-ui-card.md +40 -0
- package/docs/tcloud-ui-choice-issues.md +59 -0
- package/docs/tcloud-ui-cnpj.md +102 -0
- package/docs/tcloud-ui-container.md +171 -0
- package/docs/tcloud-ui-cpf.md +102 -0
- package/docs/tcloud-ui-currency.md +271 -0
- package/docs/tcloud-ui-data-list.md +91 -0
- package/docs/tcloud-ui-datebr.md +139 -0
- package/docs/tcloud-ui-datepicker-time.md +191 -0
- package/docs/tcloud-ui-datepicker.md +186 -0
- package/docs/tcloud-ui-dropdown-multi.md +444 -0
- package/docs/tcloud-ui-dropdown.md +369 -0
- package/docs/tcloud-ui-el-copy.md +113 -0
- package/docs/tcloud-ui-empty-content.md +412 -0
- package/docs/tcloud-ui-faq.md +496 -0
- package/docs/tcloud-ui-filter-bar.md +86 -0
- package/docs/tcloud-ui-filters.md +337 -0
- package/docs/tcloud-ui-hover-parent.md +467 -0
- package/docs/tcloud-ui-icon-button.md +104 -0
- package/docs/tcloud-ui-input-container.md +520 -0
- package/docs/tcloud-ui-input-password.md +258 -0
- package/docs/tcloud-ui-input-search.md +314 -0
- package/docs/tcloud-ui-label-token.md +286 -0
- package/docs/tcloud-ui-legend.md +72 -0
- package/docs/tcloud-ui-line-step-circle.md +98 -0
- package/docs/tcloud-ui-line-step-title.md +194 -0
- package/docs/tcloud-ui-linha-logo.md +550 -0
- package/docs/tcloud-ui-loading.md +88 -0
- package/docs/tcloud-ui-message.md +539 -0
- package/docs/tcloud-ui-modal.md +196 -0
- package/docs/tcloud-ui-monthname.md +123 -0
- package/docs/tcloud-ui-multi-input.md +290 -0
- package/docs/tcloud-ui-multi-select.md +311 -0
- package/docs/tcloud-ui-multiples-values.md +157 -0
- package/docs/tcloud-ui-not-found.md +88 -0
- package/docs/tcloud-ui-number-step.md +134 -0
- package/docs/tcloud-ui-pagination.md +579 -0
- package/docs/tcloud-ui-progress-bar.md +65 -0
- package/docs/tcloud-ui-radio.md +83 -0
- package/docs/tcloud-ui-reorder-items.md +418 -0
- package/docs/tcloud-ui-respective.md +167 -0
- package/docs/tcloud-ui-scroll-box.md +109 -0
- package/docs/tcloud-ui-search-bar.md +88 -0
- package/docs/tcloud-ui-search-in-object.md +143 -0
- package/docs/tcloud-ui-search-input.md +74 -0
- package/docs/tcloud-ui-skeleton-loading.md +394 -0
- package/docs/tcloud-ui-slide-toggle.md +210 -0
- package/docs/tcloud-ui-statusinfo.md +138 -0
- package/docs/tcloud-ui-tab-group.md +376 -0
- package/docs/tcloud-ui-tab-menu.md +109 -0
- package/docs/tcloud-ui-table.md +96 -0
- package/docs/tcloud-ui-tag.md +379 -0
- package/docs/tcloud-ui-tc-badge.md +168 -0
- package/docs/tcloud-ui-tc-btn.md +189 -0
- package/docs/tcloud-ui-tc-colors.md +204 -0
- package/docs/tcloud-ui-tc-form-control.md +200 -0
- package/docs/tcloud-ui-tc-text.md +139 -0
- package/docs/tcloud-ui-tc-title.md +118 -0
- package/docs/tcloud-ui-tcloud-form.md +55 -0
- package/docs/tcloud-ui-toast.md +83 -0
- package/docs/tcloud-ui-tooltip.md +88 -0
- package/docs/tcloud-ui-topology.md +232 -0
- package/docs/tcloud-ui-upload-area.md +195 -0
- package/docs/tcloud-ui-welcome.md +112 -0
- package/docs/tcloud-ui-wizard-steps.md +103 -0
- package/js/tcloud-ui-app.js +11 -0
- package/package.json +1 -1
- package/scss/tcloud-ui/styles/_claus-badge.scss +117 -0
- package/scss/tcloud-ui/styles/_claus-btn.scss +207 -0
- package/scss/tcloud-ui/styles/_claus-card.scss +12 -0
- package/scss/tcloud-ui/styles/_claus-colors.scss +192 -0
- package/scss/tcloud-ui/styles/_claus-form.scss +88 -0
- package/scss/tcloud-ui/styles/_claus-sizes.scss +28 -0
- package/scss/tcloud-ui/styles/_claus-spacers.scss +49 -0
- package/scss/tcloud-ui/styles/_claus-themes.scss +36 -0
- package/scss/tcloud-ui/styles/_claus-title.scss +24 -0
- package/scss/tcloud-ui/styles/_claus-typography.scss +70 -0
- package/scss/tcloud-ui/styles/_claus-variables.scss +131 -0
- package/scss/tcloud-ui/styles/_colors.scss +123 -0
- package/scss/tcloud-ui/styles/_tc-btn.scss +210 -0
- package/scss/tcloud-ui/styles/_tc-card.scss +7 -0
- package/scss/tcloud-ui/styles/_tc-title.scss +49 -0
- package/scss/tcloud-ui/styles.scss +35 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Modal
|
|
2
|
+
|
|
3
|
+
## Características
|
|
4
|
+
|
|
5
|
+
- Modal standalone com animação de entrada/saída configurável por posição, e bloqueio de scroll do `body` enquanto aberto.
|
|
6
|
+
- Suporte a posições de âncora (`top`, `right`, `left`, `bottom`) e tamanhos predefinidos via `window` ou controle fino via `maxWidth`.
|
|
7
|
+
- Modo confirmação opcional: exige que o usuário digite um texto específico antes de habilitar a ação — com suporte à desabilitação do campo de texto (`confirmInput: false`).
|
|
8
|
+
- Estado de carregamento controlável via `loading`, que desabilita as ações do footer enquanto uma operação assíncrona está em curso.
|
|
9
|
+
- Estrutura modular baseada em três sub-componentes de composição: `tcloud-ui-modal-header`, `tcloud-ui-modal-body` e `tcloud-ui-modal-footer`.
|
|
10
|
+
- Suporte a two-way binding via `[(open)]` para controle declarativo da visibilidade.
|
|
11
|
+
|
|
12
|
+
## Instalação
|
|
13
|
+
|
|
14
|
+
Importe os componentes necessários no componente standalone consumidor:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import {
|
|
18
|
+
TCloudUiModalComponent,
|
|
19
|
+
TCloudUiModalHeaderComponent,
|
|
20
|
+
TCloudUiModalBodyComponent,
|
|
21
|
+
TCloudUiModalFooterComponent
|
|
22
|
+
} from 'tcloud-ui';
|
|
23
|
+
|
|
24
|
+
@Component({
|
|
25
|
+
selector: 'app-example',
|
|
26
|
+
standalone: true,
|
|
27
|
+
imports: [
|
|
28
|
+
TCloudUiModalComponent,
|
|
29
|
+
TCloudUiModalHeaderComponent,
|
|
30
|
+
TCloudUiModalBodyComponent,
|
|
31
|
+
TCloudUiModalFooterComponent
|
|
32
|
+
],
|
|
33
|
+
template: `...`
|
|
34
|
+
})
|
|
35
|
+
export class ExampleComponent {}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Propriedades (API)
|
|
39
|
+
|
|
40
|
+
### `tcloud-ui-modal` — Inputs
|
|
41
|
+
|
|
42
|
+
| Nome | Tipo | Descrição | Valor Default |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| `open` | `boolean` | Controla a visibilidade do modal. Suporta two-way binding via `[(open)]`. | `false` |
|
|
45
|
+
| `loading` | `boolean` | Coloca o modal em estado de carregamento, desabilitando as ações do footer. | `false` |
|
|
46
|
+
| `autoClose` | `boolean` | Fecha o modal automaticamente após uma ação confirmada ou cancelada. | `true` |
|
|
47
|
+
| `confirm` | `boolean` | Ativa o modo confirmação no footer, exibindo campo de digitação e botões de confirmar/cancelar. | `false` |
|
|
48
|
+
| `confirmText` | `string` | Texto que o usuário deve digitar para habilitar a confirmação (utilizado quando `confirm: true`). | `'Confirmo'` |
|
|
49
|
+
| `confirmInput` | `boolean` | Quando `false`, omite o campo de texto no modo confirmação e permite confirmar diretamente. | `true` |
|
|
50
|
+
| `maxWidth` | `number` | Largura máxima do modal em pixels. Ignorado se `window` for utilizado. | `500` |
|
|
51
|
+
| `window` | `'small' \| 'medium' \| 'large' \| 'big' \| 'full'` | Define a largura por tamanho semântico: 300 / 500 / 900 / 1100 / 1400 px. Tem precedência sobre `maxWidth`. | — |
|
|
52
|
+
| `position` | `'top' \| 'right' \| 'left' \| 'bottom'` | Define a âncora de entrada/saída da animação e o layout do modal. | `'top'` |
|
|
53
|
+
| `sticky` | `boolean` | Mantém o modal em modo fixo (útil para side panels com scroll interno). | `false` |
|
|
54
|
+
| `title` | `any` | Título exibido no topo do modal (alternativa a usar `tcloud-ui-modal-header`). | — |
|
|
55
|
+
|
|
56
|
+
### `tcloud-ui-modal` — Outputs
|
|
57
|
+
|
|
58
|
+
| Nome | Tipo de Evento | Descrição |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `openChange` | `EventEmitter<boolean>` | Emite o novo estado ao fechar, viabilizando two-way binding com `[(open)]`. |
|
|
61
|
+
| `toConfirm` | `EventEmitter<boolean>` | Emite `true` quando o usuário confirma a ação no modo confirmação. |
|
|
62
|
+
| `toCancel` | `EventEmitter<boolean>` | Emite `false` quando o usuário cancela no modo confirmação. |
|
|
63
|
+
| `toAction` | `EventEmitter<'confirmed' \| 'cancel' \| 'close'>` | Emite a ação resultante após qualquer interação de fechamento do modal. |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### `tcloud-ui-modal-header` — Inputs
|
|
68
|
+
|
|
69
|
+
| Nome | Tipo | Descrição | Valor Default |
|
|
70
|
+
|---|---|---|---|
|
|
71
|
+
| `title` | `any` | Texto do cabeçalho do modal. | — |
|
|
72
|
+
| `mode` | `'colorless' \| 'info' \| 'success' \| 'danger' \| 'warning'` | Define a variação visual do cabeçalho e propaga o modo ao footer via serviço interno. | `'info'` |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### `tcloud-ui-modal-footer` — Inputs
|
|
77
|
+
|
|
78
|
+
| Nome | Tipo | Descrição | Valor Default |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| `actions` | `boolean` | Controla a exibição dos botões de ação no footer. | `true` |
|
|
81
|
+
| `btnCloseText` | `string` | Texto do botão de fechar (exibido quando não está em modo confirmação). | `'Fechar'` |
|
|
82
|
+
| `btnCancelText` | `string` | Texto do botão de cancelar (exibido no modo confirmação). | `'Cancelar'` |
|
|
83
|
+
| `btnConfirmText` | `string` | Texto do botão de confirmar (exibido no modo confirmação). | `'Confirmar'` |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Exemplos de Uso
|
|
88
|
+
|
|
89
|
+
### Uso Básico
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<!-- app.component.html -->
|
|
93
|
+
<tcloud-ui-modal [(open)]="isOpen" [window]="'big'">
|
|
94
|
+
<tcloud-ui-modal-header title="Título do Modal" mode="colorless"></tcloud-ui-modal-header>
|
|
95
|
+
<tcloud-ui-modal-body>
|
|
96
|
+
<p>Conteúdo do modal aqui.</p>
|
|
97
|
+
</tcloud-ui-modal-body>
|
|
98
|
+
<tcloud-ui-modal-footer></tcloud-ui-modal-footer>
|
|
99
|
+
</tcloud-ui-modal>
|
|
100
|
+
|
|
101
|
+
<button type="button" (click)="isOpen = !isOpen">Abrir Modal</button>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
// app.component.ts
|
|
106
|
+
export class AppComponent {
|
|
107
|
+
isOpen = false;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### Uso Avançado
|
|
114
|
+
|
|
115
|
+
#### Side panel lateral com scroll e modo sticky
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<tcloud-ui-modal [(open)]="openRight" [window]="'small'" [position]="'right'" [sticky]="true">
|
|
119
|
+
<tcloud-ui-modal-header title="Painel Lateral" mode="colorless"></tcloud-ui-modal-header>
|
|
120
|
+
<tcloud-ui-modal-body>
|
|
121
|
+
<table>
|
|
122
|
+
<tr *ngFor="let item of items">
|
|
123
|
+
<td>{{ item.name }}</td>
|
|
124
|
+
</tr>
|
|
125
|
+
</table>
|
|
126
|
+
</tcloud-ui-modal-body>
|
|
127
|
+
<tcloud-ui-modal-footer></tcloud-ui-modal-footer>
|
|
128
|
+
</tcloud-ui-modal>
|
|
129
|
+
|
|
130
|
+
<button type="button" (click)="openRight = !openRight">Abrir lateral direita</button>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### Modal de confirmação com digitação obrigatória
|
|
134
|
+
|
|
135
|
+
```html
|
|
136
|
+
<tcloud-ui-modal
|
|
137
|
+
[(open)]="openConfirm"
|
|
138
|
+
[confirm]="true"
|
|
139
|
+
confirmText="EXCLUIR"
|
|
140
|
+
(toAction)="onAction($event)">
|
|
141
|
+
<tcloud-ui-modal-header title="Atenção" mode="warning"></tcloud-ui-modal-header>
|
|
142
|
+
<tcloud-ui-modal-body>
|
|
143
|
+
Digite <strong>EXCLUIR</strong> para confirmar a exclusão permanente do registro.
|
|
144
|
+
</tcloud-ui-modal-body>
|
|
145
|
+
<tcloud-ui-modal-footer></tcloud-ui-modal-footer>
|
|
146
|
+
</tcloud-ui-modal>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
onAction(action: 'confirmed' | 'cancel' | 'close') {
|
|
151
|
+
if (action === 'confirmed') {
|
|
152
|
+
// executar exclusão
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Modal de confirmação sem campo de texto
|
|
158
|
+
|
|
159
|
+
```html
|
|
160
|
+
<tcloud-ui-modal
|
|
161
|
+
[(open)]="openConfirmSimple"
|
|
162
|
+
[confirm]="true"
|
|
163
|
+
[confirmInput]="false"
|
|
164
|
+
(toAction)="onAction($event)">
|
|
165
|
+
<tcloud-ui-modal-header title="Confirmar ação" mode="danger"></tcloud-ui-modal-header>
|
|
166
|
+
<tcloud-ui-modal-body>Deseja realmente executar esta ação?</tcloud-ui-modal-body>
|
|
167
|
+
<tcloud-ui-modal-footer></tcloud-ui-modal-footer>
|
|
168
|
+
</tcloud-ui-modal>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### Modal com estado de carregamento
|
|
172
|
+
|
|
173
|
+
```html
|
|
174
|
+
<tcloud-ui-modal [(open)]="isOpen" [loading]="isSaving">
|
|
175
|
+
<tcloud-ui-modal-header title="Salvar" mode="info"></tcloud-ui-modal-header>
|
|
176
|
+
<tcloud-ui-modal-body>
|
|
177
|
+
Processando sua solicitação...
|
|
178
|
+
</tcloud-ui-modal-body>
|
|
179
|
+
<tcloud-ui-modal-footer></tcloud-ui-modal-footer>
|
|
180
|
+
</tcloud-ui-modal>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
export class AppComponent {
|
|
185
|
+
isOpen = false;
|
|
186
|
+
isSaving = false;
|
|
187
|
+
|
|
188
|
+
save() {
|
|
189
|
+
this.isSaving = true;
|
|
190
|
+
this.myService.save().subscribe(() => {
|
|
191
|
+
this.isSaving = false;
|
|
192
|
+
this.isOpen = false;
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# MonthNamePipe
|
|
2
|
+
|
|
3
|
+
O pipe `monthname` converte uma string no formato `yyyy-MM` para o nome do mês correspondente em português brasileiro. Utiliza um array interno com os 12 meses do ano para realizar a tradução do número do mês para seu nome por extenso.
|
|
4
|
+
|
|
5
|
+
## Características
|
|
6
|
+
|
|
7
|
+
- Conversão de formato `yyyy-MM` para nome do mês em português (Janeiro a Dezembro)
|
|
8
|
+
- Parsing da string pelo separador `-` para extrair o mês
|
|
9
|
+
- Retorna string vazia para valores vazios ou formatos inválidos
|
|
10
|
+
- Validação: exige exatamente duas partes separadas por `-`
|
|
11
|
+
- Pipe standalone
|
|
12
|
+
|
|
13
|
+
## Instalação
|
|
14
|
+
|
|
15
|
+
Importe o pipe diretamente no módulo ou componente standalone:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { MonthNamePipe } from 'tcloud-ui';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## API
|
|
22
|
+
|
|
23
|
+
### Sintaxe do Pipe
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
{{ valor | monthname }}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Parâmetros
|
|
30
|
+
|
|
31
|
+
Este pipe não recebe parâmetros adicionais.
|
|
32
|
+
|
|
33
|
+
### Entrada e Saída
|
|
34
|
+
|
|
35
|
+
| Entrada | Saída |
|
|
36
|
+
|--------------|--------------|
|
|
37
|
+
| `'2026-01'` | `'Janeiro'` |
|
|
38
|
+
| `'2026-03'` | `'Março'` |
|
|
39
|
+
| `'2026-06'` | `'Junho'` |
|
|
40
|
+
| `'2026-12'` | `'Dezembro'` |
|
|
41
|
+
| `''` | `''` |
|
|
42
|
+
|
|
43
|
+
### Meses Disponíveis
|
|
44
|
+
|
|
45
|
+
| Número | Nome |
|
|
46
|
+
|--------|------------|
|
|
47
|
+
| 01 | Janeiro |
|
|
48
|
+
| 02 | Fevereiro |
|
|
49
|
+
| 03 | Março |
|
|
50
|
+
| 04 | Abril |
|
|
51
|
+
| 05 | Maio |
|
|
52
|
+
| 06 | Junho |
|
|
53
|
+
| 07 | Julho |
|
|
54
|
+
| 08 | Agosto |
|
|
55
|
+
| 09 | Setembro |
|
|
56
|
+
| 10 | Outubro |
|
|
57
|
+
| 11 | Novembro |
|
|
58
|
+
| 12 | Dezembro |
|
|
59
|
+
|
|
60
|
+
## Exemplos de Uso
|
|
61
|
+
|
|
62
|
+
### Básico — Exibição do nome do mês
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<p>{{ '2026-03' | monthname }}</p>
|
|
66
|
+
<!-- Resultado: Março -->
|
|
67
|
+
|
|
68
|
+
<p>{{ '2026-12' | monthname }}</p>
|
|
69
|
+
<!-- Resultado: Dezembro -->
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { MonthNamePipe } from 'tcloud-ui';
|
|
74
|
+
|
|
75
|
+
@Component({
|
|
76
|
+
standalone: true,
|
|
77
|
+
imports: [MonthNamePipe],
|
|
78
|
+
template: `
|
|
79
|
+
<p>{{ competencia | monthname }}</p>
|
|
80
|
+
`
|
|
81
|
+
})
|
|
82
|
+
export class ExemploBasicoComponent {
|
|
83
|
+
competencia = '2026-03';
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Avançado — Listagem de competências
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<table class="table">
|
|
91
|
+
<thead>
|
|
92
|
+
<tr>
|
|
93
|
+
<th>Competência</th>
|
|
94
|
+
<th>Mês</th>
|
|
95
|
+
<th>Valor</th>
|
|
96
|
+
</tr>
|
|
97
|
+
</thead>
|
|
98
|
+
<tbody>
|
|
99
|
+
<tr *ngFor="let item of competencias">
|
|
100
|
+
<td>{{ item.periodo }}</td>
|
|
101
|
+
<td>{{ item.periodo | monthname }}</td>
|
|
102
|
+
<td>{{ item.valor | currency:'BRL' }}</td>
|
|
103
|
+
</tr>
|
|
104
|
+
</tbody>
|
|
105
|
+
</table>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { MonthNamePipe } from 'tcloud-ui';
|
|
110
|
+
|
|
111
|
+
@Component({
|
|
112
|
+
standalone: true,
|
|
113
|
+
imports: [CommonModule, MonthNamePipe],
|
|
114
|
+
template: `...`
|
|
115
|
+
})
|
|
116
|
+
export class ExemploAvancadoComponent {
|
|
117
|
+
competencias = [
|
|
118
|
+
{ periodo: '2026-01', valor: 1500.00 },
|
|
119
|
+
{ periodo: '2026-02', valor: 2300.50 },
|
|
120
|
+
{ periodo: '2026-03', valor: 1800.75 }
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
```
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Multi Input
|
|
2
|
+
|
|
3
|
+
## Características
|
|
4
|
+
- Componente standalone para entrada de múltiplos valores em formato de tags/labels.
|
|
5
|
+
- Input com botão de adicionar (+) para inserir novos itens à lista.
|
|
6
|
+
- Cada item exibido com botão de remoção (x).
|
|
7
|
+
- Suporte a ngModel (two-way binding) via ControlValueAccessor.
|
|
8
|
+
- Validação com `required` via NG_VALIDATORS: exige ao menos um item na lista.
|
|
9
|
+
- Suporte a estados: `disabled` e `loading`.
|
|
10
|
+
- Largura máxima configurável para labels.
|
|
11
|
+
- Modo `showInput`: oculta o input de entrada, exibindo apenas os itens.
|
|
12
|
+
- Emite alterações via evento `tcChange`.
|
|
13
|
+
|
|
14
|
+
## Instalação
|
|
15
|
+
```ts
|
|
16
|
+
import { TCloudUiMultiInputComponent } from 'projects/tcloud-ui/src/public-api';
|
|
17
|
+
|
|
18
|
+
@Component({
|
|
19
|
+
selector: 'app-example',
|
|
20
|
+
standalone: true,
|
|
21
|
+
imports: [TCloudUiMultiInputComponent],
|
|
22
|
+
template: `
|
|
23
|
+
<tcloud-ui-multi-input
|
|
24
|
+
[tcList]="items"
|
|
25
|
+
(tcChange)="onItemsChanged($event)">
|
|
26
|
+
</tcloud-ui-multi-input>
|
|
27
|
+
`
|
|
28
|
+
})
|
|
29
|
+
export class ExampleComponent {
|
|
30
|
+
items = [{ value: 'Item 1' }, { value: 'Item 2' }];
|
|
31
|
+
|
|
32
|
+
onItemsChanged(event: any[]) {
|
|
33
|
+
console.log('Itens atualizados:', event);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Propriedades (API)
|
|
39
|
+
### Inputs
|
|
40
|
+
| Nome | Tipo | Descrição | Valor Default |
|
|
41
|
+
| --- | --- | --- | --- |
|
|
42
|
+
| tcList | { value: any }[] | Array de objetos com propriedade `value` representando os itens. | undefined |
|
|
43
|
+
| placeholder | string | Texto exibido no input quando vazio. | '' |
|
|
44
|
+
| disabled | boolean | Se true, desabilita input e botões. | false |
|
|
45
|
+
| loading | boolean | Se true, desabilita input e botões (estado de carregamento). | false |
|
|
46
|
+
| required | string | Se definido, habilita validação de pelo menos um item na lista. | undefined |
|
|
47
|
+
| maxWidthLabel | string | Largura máxima de cada label (ex: '95px', '120px'). | undefined |
|
|
48
|
+
| showInput | boolean | Se true, oculta o input de entrada e exibe apenas os itens existentes. | false |
|
|
49
|
+
| ngModel | { value: any }[] | Array de itens para two-way binding. | undefined |
|
|
50
|
+
|
|
51
|
+
### Outputs
|
|
52
|
+
| Nome | Tipo de Evento | Descrição |
|
|
53
|
+
| --- | --- | --- |
|
|
54
|
+
| tcChange | EventEmitter<any[]> | Emite o array de itens atualizado ao adicionar ou remover. |
|
|
55
|
+
| onChange | EventEmitter<any> | Emite alterações internas. |
|
|
56
|
+
|
|
57
|
+
## Exemplos de Uso
|
|
58
|
+
### Uso Básico - Modo Simples
|
|
59
|
+
```ts
|
|
60
|
+
export class ExampleComponent {
|
|
61
|
+
items = [
|
|
62
|
+
{ value: 'Texto 1' },
|
|
63
|
+
{ value: 'Texto 2' },
|
|
64
|
+
{ value: 'Texto 3' }
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
onItemsChanged(event: any[]) {
|
|
68
|
+
console.log('Itens:', event);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<tcloud-ui-multi-input
|
|
75
|
+
[tcList]="items"
|
|
76
|
+
(tcChange)="onItemsChanged($event)"
|
|
77
|
+
[placeholder]="'Digite um valor'">
|
|
78
|
+
</tcloud-ui-multi-input>
|
|
79
|
+
|
|
80
|
+
<pre>{{ items | json }}</pre>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Com Largura Máxima de Label
|
|
84
|
+
```html
|
|
85
|
+
<tcloud-ui-multi-input
|
|
86
|
+
[tcList]="items"
|
|
87
|
+
(tcChange)="onItemsChanged($event)"
|
|
88
|
+
[maxWidthLabel]="'95px'"
|
|
89
|
+
[placeholder]="'Selecione um item'">
|
|
90
|
+
</tcloud-ui-multi-input>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Com Validação Required (ngModel)
|
|
94
|
+
```html
|
|
95
|
+
<form #formulario="ngForm">
|
|
96
|
+
<tcloud-ui-multi-input
|
|
97
|
+
name="tags"
|
|
98
|
+
[(ngModel)]="selectedItems"
|
|
99
|
+
required>
|
|
100
|
+
</tcloud-ui-multi-input>
|
|
101
|
+
|
|
102
|
+
<p *ngIf="formulario.invalid">
|
|
103
|
+
É necessário ao menos um item.
|
|
104
|
+
</p>
|
|
105
|
+
|
|
106
|
+
<button [disabled]="formulario.invalid">Salvar</button>
|
|
107
|
+
</form>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Componente:
|
|
111
|
+
```ts
|
|
112
|
+
export class FormComponent {
|
|
113
|
+
selectedItems: { value: any }[] | undefined;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Modo Somente Leitura (showInput)
|
|
118
|
+
```html
|
|
119
|
+
<!-- Exibe apenas os itens, sem input para adicionar novos -->
|
|
120
|
+
<tcloud-ui-multi-input
|
|
121
|
+
[tcList]="items"
|
|
122
|
+
[showInput]="true"
|
|
123
|
+
(tcChange)="onItemsChanged($event)"
|
|
124
|
+
[maxWidthLabel]="'95px'">
|
|
125
|
+
</tcloud-ui-multi-input>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Desabilitado
|
|
129
|
+
```html
|
|
130
|
+
<tcloud-ui-multi-input
|
|
131
|
+
[tcList]="items"
|
|
132
|
+
[disabled]="true"
|
|
133
|
+
[placeholder]="'Input desabilitado'">
|
|
134
|
+
</tcloud-ui-multi-input>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Uso Avançado
|
|
138
|
+
### Com ngModel e Formulário Reativo
|
|
139
|
+
```ts
|
|
140
|
+
export class FormComponent {
|
|
141
|
+
tags: { value: string }[] = [];
|
|
142
|
+
|
|
143
|
+
addTag(tag: string) {
|
|
144
|
+
this.tags.push({ value: tag });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
removeAllTags() {
|
|
148
|
+
this.tags = [];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```html
|
|
154
|
+
<form #form="ngForm">
|
|
155
|
+
<div>
|
|
156
|
+
<label>Tags do Produto:</label>
|
|
157
|
+
<tcloud-ui-multi-input
|
|
158
|
+
name="productTags"
|
|
159
|
+
[(ngModel)]="tags"
|
|
160
|
+
required
|
|
161
|
+
[placeholder]="'Adicionar tag...'">
|
|
162
|
+
</tcloud-ui-multi-input>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
<p *ngIf="tags && tags.length > 0">
|
|
166
|
+
Total de tags: {{ tags.length }}
|
|
167
|
+
</p>
|
|
168
|
+
|
|
169
|
+
<button type="button" (click)="removeAllTags()">Limpar</button>
|
|
170
|
+
<button type="submit" [disabled]="form.invalid">Salvar</button>
|
|
171
|
+
</form>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Lista de Emails
|
|
175
|
+
```ts
|
|
176
|
+
export class EmailListComponent {
|
|
177
|
+
emails: { value: string }[] = [
|
|
178
|
+
{ value: 'admin@example.com' },
|
|
179
|
+
{ value: 'user@example.com' }
|
|
180
|
+
];
|
|
181
|
+
|
|
182
|
+
onEmailsChanged(updatedEmails: any[]) {
|
|
183
|
+
console.log('Emails atualizados:', updatedEmails);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```html
|
|
189
|
+
<div>
|
|
190
|
+
<label>Destinatários:</label>
|
|
191
|
+
<tcloud-ui-multi-input
|
|
192
|
+
[tcList]="emails"
|
|
193
|
+
(tcChange)="onEmailsChanged($event)"
|
|
194
|
+
[placeholder]="'Digite um email...'"
|
|
195
|
+
[maxWidthLabel]="'200px'">
|
|
196
|
+
</tcloud-ui-multi-input>
|
|
197
|
+
</div>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Com Estado de Loading
|
|
201
|
+
```ts
|
|
202
|
+
export class LoadingComponent {
|
|
203
|
+
items: { value: string }[] = [];
|
|
204
|
+
isLoading: boolean = false;
|
|
205
|
+
|
|
206
|
+
loadItems() {
|
|
207
|
+
this.isLoading = true;
|
|
208
|
+
// Simular carregamento
|
|
209
|
+
setTimeout(() => {
|
|
210
|
+
this.items = [
|
|
211
|
+
{ value: 'Item carregado 1' },
|
|
212
|
+
{ value: 'Item carregado 2' }
|
|
213
|
+
];
|
|
214
|
+
this.isLoading = false;
|
|
215
|
+
}, 2000);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
```html
|
|
221
|
+
<tcloud-ui-multi-input
|
|
222
|
+
[tcList]="items"
|
|
223
|
+
[loading]="isLoading"
|
|
224
|
+
[placeholder]="'Carregando...'">
|
|
225
|
+
</tcloud-ui-multi-input>
|
|
226
|
+
|
|
227
|
+
<button (click)="loadItems()" [disabled]="isLoading">Carregar Itens</button>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Controle Dinâmico com Dados Externos
|
|
231
|
+
```ts
|
|
232
|
+
export class DynamicComponent {
|
|
233
|
+
tags: { value: string }[] = [];
|
|
234
|
+
suggestions = ['Angular', 'React', 'Vue', 'Svelte', 'Next.js'];
|
|
235
|
+
|
|
236
|
+
addSuggestion(suggestion: string) {
|
|
237
|
+
if (!this.tags.find(t => t.value === suggestion)) {
|
|
238
|
+
this.tags.push({ value: suggestion });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
onTagsChanged(event: any[]) {
|
|
243
|
+
this.tags = event;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
```html
|
|
249
|
+
<div>
|
|
250
|
+
<label>Tecnologias:</label>
|
|
251
|
+
<tcloud-ui-multi-input
|
|
252
|
+
[tcList]="tags"
|
|
253
|
+
(tcChange)="onTagsChanged($event)"
|
|
254
|
+
[placeholder]="'Adicionar tecnologia...'"
|
|
255
|
+
[maxWidthLabel]="'120px'">
|
|
256
|
+
</tcloud-ui-multi-input>
|
|
257
|
+
|
|
258
|
+
<div class="suggestions">
|
|
259
|
+
<p>Sugestões:</p>
|
|
260
|
+
<button
|
|
261
|
+
*ngFor="let s of suggestions"
|
|
262
|
+
(click)="addSuggestion(s)"
|
|
263
|
+
type="button">
|
|
264
|
+
{{ s }}
|
|
265
|
+
</button>
|
|
266
|
+
</div>
|
|
267
|
+
</div>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Estrutura de Dados
|
|
271
|
+
Os itens devem seguir o formato:
|
|
272
|
+
```ts
|
|
273
|
+
interface IMultiInputItem {
|
|
274
|
+
value: any; // Valor exibido e armazenado
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Exemplo:
|
|
279
|
+
```ts
|
|
280
|
+
const items = [
|
|
281
|
+
{ value: 'Tag 1' },
|
|
282
|
+
{ value: 'Tag 2' },
|
|
283
|
+
{ value: 'Tag 3' }
|
|
284
|
+
];
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Validação
|
|
288
|
+
- Quando `required` é definido, o componente valida se há ao menos um item na lista.
|
|
289
|
+
- A validação é integrada com Angular Forms via `NG_VALIDATORS`.
|
|
290
|
+
- O controle é marcado como inválido quando a lista está vazia e `required` está ativo.
|