@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,157 @@
|
|
|
1
|
+
# MouseEvents
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Módulo com duas diretivas para eventos de mouse avançados: `sLongPress` (pressão longa) e `sDoubleClick` (duplo clique). Permitem detectar gestos específicos que o DOM nativo não suporta nativamente de forma consistente.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Ações de contexto em dispositivos touch via `sLongPress` (equivalente ao clique direito)
|
|
10
|
+
- Edição inline acionada por duplo clique via `sDoubleClick`
|
|
11
|
+
- Seleção múltipla ao pressionar e arrastar (combinado com long press)
|
|
12
|
+
- Evitar acionamentos acidentais exigindo gestos deliberados
|
|
13
|
+
|
|
14
|
+
## Quando não usar
|
|
15
|
+
|
|
16
|
+
- Quando o clique simples é suficiente — use `(click)` nativo
|
|
17
|
+
- Quando a acessibilidade via teclado é necessária — combine com [`InteractiveContent`](../interactive-content/README.md)
|
|
18
|
+
|
|
19
|
+
## Instalação
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { MouseEventsModule } from '@seniorsistemas/angular-components/mouse-events';
|
|
23
|
+
|
|
24
|
+
@NgModule({
|
|
25
|
+
imports: [MouseEventsModule],
|
|
26
|
+
})
|
|
27
|
+
export class MeuModule {}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Uso básico
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<!-- Long Press -->
|
|
34
|
+
<div [sLongPressDelay]="500" (sLongPress)="onLongPress($event)">
|
|
35
|
+
Pressione e segure
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<!-- Double Click -->
|
|
39
|
+
<div sDoubleClick (doubleClicked)="onDoubleClick($event)">
|
|
40
|
+
Clique duas vezes
|
|
41
|
+
</div>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
### Diretiva `sLongPress`
|
|
47
|
+
|
|
48
|
+
#### Inputs
|
|
49
|
+
|
|
50
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
51
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
52
|
+
| `sLongPressDelay` | `number` | `500` | Não | Tempo em milissegundos para disparar o long press após pressionar o elemento. |
|
|
53
|
+
|
|
54
|
+
#### Outputs
|
|
55
|
+
|
|
56
|
+
| Evento | Tipo | Descrição |
|
|
57
|
+
|--------|------|-----------|
|
|
58
|
+
| `sLongPress` | `EventEmitter<MouseEvent>` | Emitido quando o elemento é pressionado por mais de `sLongPressDelay` ms sem soltar. |
|
|
59
|
+
|
|
60
|
+
### Diretiva `sDoubleClick`
|
|
61
|
+
|
|
62
|
+
#### Outputs
|
|
63
|
+
|
|
64
|
+
| Evento | Tipo | Descrição |
|
|
65
|
+
|--------|------|-----------|
|
|
66
|
+
| `doubleClicked` | `EventEmitter<PointerEvent>` | Emitido quando dois cliques ocorrem dentro de 500ms. |
|
|
67
|
+
|
|
68
|
+
## Exemplos
|
|
69
|
+
|
|
70
|
+
### Long Press para menu de contexto
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<div
|
|
74
|
+
[sLongPressDelay]="800"
|
|
75
|
+
(sLongPress)="abrirMenuContexto($event)"
|
|
76
|
+
style="padding: 16px; cursor: pointer; user-select: none;"
|
|
77
|
+
>
|
|
78
|
+
Pressione e segure para opções
|
|
79
|
+
</div>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Long Press com delay customizado
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<div
|
|
86
|
+
sLongPress
|
|
87
|
+
[sLongPressDelay]="1000"
|
|
88
|
+
(sLongPress)="onLongPress()"
|
|
89
|
+
style="width: 200px; height: 100px; background: #6366f1; color: white; display: flex; align-items: center; justify-content: center; border-radius: 8px; cursor: pointer; user-select: none;"
|
|
90
|
+
>
|
|
91
|
+
Segure por 1 segundo
|
|
92
|
+
</div>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Double Click para edição inline
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<div
|
|
99
|
+
sDoubleClick
|
|
100
|
+
(doubleClicked)="ativarEdicao(item)"
|
|
101
|
+
style="padding: 8px; cursor: text;"
|
|
102
|
+
>
|
|
103
|
+
@if (!editando) {
|
|
104
|
+
<span>{{ item.valor }}</span>
|
|
105
|
+
} @else {
|
|
106
|
+
<input [(ngModel)]="item.valor" (blur)="salvar(item)" />
|
|
107
|
+
}
|
|
108
|
+
</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Uso combinado (long press + double click)
|
|
112
|
+
|
|
113
|
+
```html
|
|
114
|
+
<div
|
|
115
|
+
sDoubleClick
|
|
116
|
+
(doubleClicked)="onDoubleClick(item)"
|
|
117
|
+
[sLongPressDelay]="600"
|
|
118
|
+
(sLongPress)="onLongPress(item)"
|
|
119
|
+
style="padding: 16px; border: 1px solid #e5e7eb; border-radius: 8px; cursor: pointer; user-select: none;"
|
|
120
|
+
>
|
|
121
|
+
{{ item.titulo }}
|
|
122
|
+
</div>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Visão geral lado a lado
|
|
126
|
+
|
|
127
|
+
```html
|
|
128
|
+
<div style="display: flex; gap: 24px;">
|
|
129
|
+
<div
|
|
130
|
+
sLongPress
|
|
131
|
+
[sLongPressDelay]="500"
|
|
132
|
+
(sLongPress)="longPressCount = longPressCount + 1"
|
|
133
|
+
style="padding: 16px; background: #7892a1; color: white; border-radius: 8px; cursor: pointer; user-select: none;"
|
|
134
|
+
>
|
|
135
|
+
Pressione e segure ({{ longPressCount }})
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div
|
|
139
|
+
sDoubleClick
|
|
140
|
+
(doubleClicked)="doubleClickCount = doubleClickCount + 1"
|
|
141
|
+
style="padding: 16px; background: #059669; color: white; border-radius: 8px; cursor: pointer; user-select: none;"
|
|
142
|
+
>
|
|
143
|
+
Clique duas vezes ({{ doubleClickCount }})
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Acessibilidade
|
|
149
|
+
|
|
150
|
+
- `sLongPress` detecta eventos `mousedown`/`mouseup` e `touchstart`/`touchend` — funciona em dispositivos touch
|
|
151
|
+
- `sDoubleClick` usa intervalo de 500ms entre cliques — não conflita com o evento `dblclick` nativo
|
|
152
|
+
- Para garantir acessibilidade via teclado em elementos com essas diretivas, combine com [`InteractiveContent`](../interactive-content/README.md)
|
|
153
|
+
|
|
154
|
+
## Componentes relacionados
|
|
155
|
+
|
|
156
|
+
- [`InteractiveContent`](../interactive-content/README.md) — acessibilidade via teclado para elementos customizados
|
|
157
|
+
- [`Button`](../button/README.md) — botão nativo com acessibilidade integrada; prefira quando a semântica de botão é adequada
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# NavigationButton
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Componente de navegação por etapas que exibe o passo atual com botões de avançar e retroceder. Ao clicar no label central, abre um dropdown (TieredMenu) para seleção direta de qualquer etapa. Implementa `ControlValueAccessor` para integração com Angular Forms.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Navegação entre períodos (meses, trimestres, anos) em relatórios e dashboards
|
|
10
|
+
- Paginação de etapas onde o usuário pode avançar, retroceder ou pular diretamente
|
|
11
|
+
- Fluxos de wizard com etapas sequenciais nomeadas
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Quando o usuário precisa ver o progresso visual de todas as etapas simultaneamente — prefira [`Stepper`](../stepper/README.md) ou [`Steps`](../steps/README.md)
|
|
16
|
+
- Navegação por páginas numeradas — prefira paginação convencional
|
|
17
|
+
|
|
18
|
+
## Instalação
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { NavigationButtonModule } from '@seniorsistemas/angular-components/navigation-button';
|
|
22
|
+
|
|
23
|
+
@NgModule({
|
|
24
|
+
imports: [NavigationButtonModule],
|
|
25
|
+
})
|
|
26
|
+
export class MeuModule {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Uso básico
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<s-navigation-button
|
|
33
|
+
[steps]="etapas"
|
|
34
|
+
(stepChanged)="onEtapaMudou($event)"
|
|
35
|
+
></s-navigation-button>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API
|
|
39
|
+
|
|
40
|
+
### Inputs
|
|
41
|
+
|
|
42
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
43
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
44
|
+
| `steps` | `NavigationButtonItem[]` | — | Sim | Lista de etapas de navegação. |
|
|
45
|
+
| `defaultValue` | `unknown` | `undefined` | Não | Valor padrão a ser selecionado na inicialização. |
|
|
46
|
+
| `tooltip` | `string` | `undefined` | Não | Tooltip global exibido no label central (sobrescrito pelo tooltip individual do item). |
|
|
47
|
+
| `changeOnInit` | `boolean` | `false` | Não | Quando `true`, emite `stepChanged` na inicialização com a etapa inicial. |
|
|
48
|
+
|
|
49
|
+
### Outputs
|
|
50
|
+
|
|
51
|
+
| Evento | Tipo | Descrição |
|
|
52
|
+
|--------|------|-----------|
|
|
53
|
+
| `stepChanged` | `EventEmitter<NavigationButtonStepChangedInfo>` | Emitido quando o usuário navega para uma nova etapa, com informações da etapa anterior e atual. |
|
|
54
|
+
|
|
55
|
+
### Tipos
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
interface NavigationButtonItem {
|
|
59
|
+
label: string; // Texto exibido no botão e no dropdown
|
|
60
|
+
value: unknown; // Valor associado à etapa
|
|
61
|
+
tooltip?: string; // Tooltip exibido ao passar o mouse no label (sobrescreve o global)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface NavigationButtonStepChangedInfo {
|
|
65
|
+
previous: NavigationButtonItem | null; // Etapa anterior (null na inicialização)
|
|
66
|
+
current: NavigationButtonItem; // Etapa atual
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Exemplos
|
|
71
|
+
|
|
72
|
+
### Navegação entre períodos mensais
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
etapas: NavigationButtonItem[] = [
|
|
76
|
+
{ label: 'Janeiro', value: 'jan' },
|
|
77
|
+
{ label: 'Fevereiro', value: 'feb' },
|
|
78
|
+
{ label: 'Março', value: 'mar' },
|
|
79
|
+
{ label: 'Abril', value: 'apr' },
|
|
80
|
+
];
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<s-navigation-button
|
|
85
|
+
[steps]="etapas"
|
|
86
|
+
(stepChanged)="onPeriodoMudou($event)"
|
|
87
|
+
></s-navigation-button>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Com tooltip e valor padrão
|
|
91
|
+
|
|
92
|
+
```html
|
|
93
|
+
<s-navigation-button
|
|
94
|
+
[steps]="etapas"
|
|
95
|
+
[defaultValue]="'apr'"
|
|
96
|
+
tooltip="Clique para selecionar um período"
|
|
97
|
+
(stepChanged)="onPeriodoMudou($event)"
|
|
98
|
+
></s-navigation-button>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Com tooltips individuais por etapa
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
etapasComTooltip: NavigationButtonItem[] = [
|
|
105
|
+
{ label: 'Etapa 1', value: 'step1', tooltip: 'Dados pessoais' },
|
|
106
|
+
{ label: 'Etapa 2', value: 'step2', tooltip: 'Endereço' },
|
|
107
|
+
{ label: 'Etapa 3', value: 'step3', tooltip: 'Contato' },
|
|
108
|
+
{ label: 'Etapa 4', value: 'step4', tooltip: 'Revisão' },
|
|
109
|
+
];
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```html
|
|
113
|
+
<s-navigation-button
|
|
114
|
+
[steps]="etapasComTooltip"
|
|
115
|
+
(stepChanged)="onEtapaMudou($event)"
|
|
116
|
+
></s-navigation-button>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Integração com Reactive Forms
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
form = new FormGroup({
|
|
123
|
+
periodo: new FormControl('feb'),
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```html
|
|
128
|
+
<form [formGroup]="form">
|
|
129
|
+
<s-navigation-button
|
|
130
|
+
formControlName="periodo"
|
|
131
|
+
[steps]="etapas"
|
|
132
|
+
tooltip="Selecione um período"
|
|
133
|
+
(stepChanged)="onPeriodoMudou($event)"
|
|
134
|
+
></s-navigation-button>
|
|
135
|
+
</form>
|
|
136
|
+
<div>Valor selecionado: {{ form.get('periodo')?.value }}</div>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Emitindo evento na inicialização
|
|
140
|
+
|
|
141
|
+
```html
|
|
142
|
+
<s-navigation-button
|
|
143
|
+
[steps]="etapas"
|
|
144
|
+
[changeOnInit]="true"
|
|
145
|
+
(stepChanged)="onEtapaMudou($event)"
|
|
146
|
+
></s-navigation-button>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Acessibilidade
|
|
150
|
+
|
|
151
|
+
- O botão ← retrocede para a etapa anterior e é desabilitado automaticamente na primeira etapa
|
|
152
|
+
- O botão → avança para a próxima etapa e é desabilitado automaticamente na última
|
|
153
|
+
- Clicar no label central abre um dropdown (TieredMenu) com todas as etapas para seleção direta
|
|
154
|
+
- Implementa `ControlValueAccessor` — compatível com `formControlName` e `ngModel`
|
|
155
|
+
|
|
156
|
+
## Componentes relacionados
|
|
157
|
+
|
|
158
|
+
- [`Stepper`](../stepper/README.md) — indicador de progresso em etapas com clique em cada passo visível
|
|
159
|
+
- [`Steps`](../steps/README.md) — navegação visual entre etapas com todos os passos exibidos
|
|
160
|
+
- [`GridMenu`](../grid-menu/README.md) — seleção de módulo ou contexto em formato de grade
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Numeric
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Pipe e serviço Angular para formatação de valores numéricos de acordo com o locale ativo. O `NumericPipe` retorna um `Observable<string>` e deve ser usado sempre com o pipe `async`. O `NumericService` oferece o método `instant()` para formatação síncrona em TypeScript.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Exibir valores numéricos formatados conforme o locale do usuário (separadores de milhar e decimal)
|
|
10
|
+
- Formatar valores monetários, percentuais ou números com precisão configurável em templates ou em código TypeScript
|
|
11
|
+
- Quando a formatação precisa reagir automaticamente a mudanças de locale
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Para entrada de dados numéricos pelo usuário — use `sNumericMask` do pacote `numeric-mask`, que cuida de formatação no campo de input
|
|
16
|
+
- Para manipulação aritmética de grandes números — use a biblioteca `BigNumber.js` diretamente
|
|
17
|
+
|
|
18
|
+
## Instalação
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { NumericModule } from '@seniorsistemas/angular-components/numeric';
|
|
22
|
+
|
|
23
|
+
@NgModule({
|
|
24
|
+
imports: [NumericModule, AsyncPipe],
|
|
25
|
+
})
|
|
26
|
+
export class MeuModulo {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
O `NumericModule` requer `LocaleModule.forRoot()` configurado no módulo raiz da aplicação.
|
|
30
|
+
|
|
31
|
+
## Uso básico
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<!-- Valor inteiro com locale do usuário -->
|
|
35
|
+
{{ 1234567 | numeric | async }}
|
|
36
|
+
|
|
37
|
+
<!-- Com opções de formatação -->
|
|
38
|
+
{{ 1234567.89 | numeric:{ numberFormatOptions: { minimumFractionDigits: 2 } } | async }}
|
|
39
|
+
|
|
40
|
+
<!-- Com locale fixo -->
|
|
41
|
+
{{ 1234567.89 | numeric:{ locale: 'en-US', numberFormatOptions: { minimumFractionDigits: 2 } } | async }}
|
|
42
|
+
|
|
43
|
+
<!-- Moeda -->
|
|
44
|
+
{{ 1234.56 | numeric:{ numberFormatOptions: { style: 'currency', currency: 'BRL' } } | async }}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
### NumericPipe
|
|
50
|
+
|
|
51
|
+
#### Assinatura
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
transform(
|
|
55
|
+
value: number | string | BigNumber,
|
|
56
|
+
options?: {
|
|
57
|
+
locale?: string;
|
|
58
|
+
numberFormatOptions?: Intl.NumberFormatOptions;
|
|
59
|
+
}
|
|
60
|
+
): Observable<string>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
| Parâmetro | Tipo | Padrão | Obrigatório | Descrição |
|
|
64
|
+
|-----------|------|--------|:-----------:|-----------|
|
|
65
|
+
| `value` | `number \| string \| BigNumber` | — | Sim | Valor a ser formatado |
|
|
66
|
+
| `options.locale` | `string` | Locale do `LocaleService` | Não | Sobrescreve o locale para formatação |
|
|
67
|
+
| `options.numberFormatOptions` | `Intl.NumberFormatOptions` | `{}` | Não | Opções de formatação da API `Intl.NumberFormat` |
|
|
68
|
+
|
|
69
|
+
### NumericService
|
|
70
|
+
|
|
71
|
+
#### Método `instant()`
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
instant(
|
|
75
|
+
value: number | string | BigNumber,
|
|
76
|
+
options?: {
|
|
77
|
+
locale?: string;
|
|
78
|
+
numberFormatOptions?: Intl.NumberFormatOptions;
|
|
79
|
+
}
|
|
80
|
+
): string | null
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Retorna o valor formatado de forma síncrona. Deve ser chamado somente após o `LocaleService` ter sido inicializado.
|
|
84
|
+
|
|
85
|
+
### Tipos
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Aceita qualquer opção da API nativa
|
|
89
|
+
type NumericOptions = {
|
|
90
|
+
locale?: string;
|
|
91
|
+
numberFormatOptions?: Intl.NumberFormatOptions;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Tipos de entrada aceitos
|
|
95
|
+
type NumericValue = number | string | BigNumber;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Exemplos
|
|
99
|
+
|
|
100
|
+
### Formatação por locale
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<!-- pt-BR: 1.234.567,89 -->
|
|
104
|
+
{{ 1234567.89 | numeric:{ locale: 'pt-BR', numberFormatOptions: { minimumFractionDigits: 2 } } | async }}
|
|
105
|
+
|
|
106
|
+
<!-- en-US: 1,234,567.89 -->
|
|
107
|
+
{{ 1234567.89 | numeric:{ locale: 'en-US', numberFormatOptions: { minimumFractionDigits: 2 } } | async }}
|
|
108
|
+
|
|
109
|
+
<!-- de-DE: 1.234.567,89 -->
|
|
110
|
+
{{ 1234567.89 | numeric:{ locale: 'de-DE', numberFormatOptions: { minimumFractionDigits: 2 } } | async }}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Formatação de moedas
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<!-- BRL: R$ 1.234,56 -->
|
|
117
|
+
{{ 1234.56 | numeric:{ locale: 'pt-BR', numberFormatOptions: { style: 'currency', currency: 'BRL' } } | async }}
|
|
118
|
+
|
|
119
|
+
<!-- USD: $1,234.56 -->
|
|
120
|
+
{{ 1234.56 | numeric:{ locale: 'en-US', numberFormatOptions: { style: 'currency', currency: 'USD' } } | async }}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Uso do NumericService em TypeScript
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { inject } from '@angular/core';
|
|
127
|
+
import { NumericService } from '@seniorsistemas/angular-components/numeric';
|
|
128
|
+
|
|
129
|
+
const numericService = inject(NumericService);
|
|
130
|
+
|
|
131
|
+
// Formatação com locale e opções
|
|
132
|
+
const valor = numericService.instant(1234567.89, {
|
|
133
|
+
locale: 'pt-BR',
|
|
134
|
+
numberFormatOptions: { minimumFractionDigits: 2, maximumFractionDigits: 2 },
|
|
135
|
+
});
|
|
136
|
+
// Resultado: "1.234.567,89"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Acessibilidade
|
|
140
|
+
|
|
141
|
+
- Os valores formatados são texto puro, lidos por leitores de tela conforme o locale configurado
|
|
142
|
+
- Não há componente visual; a acessibilidade depende do elemento host que exibe o valor
|
|
143
|
+
|
|
144
|
+
## Componentes relacionados
|
|
145
|
+
|
|
146
|
+
- [`sNumericMask`](../numeric-mask/README.md) — máscara de entrada para campos numéricos
|
|
147
|
+
- [`Locale`](../locale/) — serviço e pipes de localização usados internamente
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# NumericMask
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Diretiva Angular para formatação de valores numéricos em campos de input com suporte a internacionalização. Aplica separadores de milhar e decimal conforme o locale configurado, com controle de casas decimais, suporte a valores negativos e notação científica.
|
|
6
|
+
|
|
7
|
+
## Quando usar
|
|
8
|
+
|
|
9
|
+
- Campos de entrada de valores numéricos que precisam de formatação automática conforme o locale do usuário
|
|
10
|
+
- Campos monetários, de quantidade ou de medidas que exijam separadores de milhar e decimal corretos
|
|
11
|
+
- Formulários com validação de valor mínimo e máximo em campos numéricos
|
|
12
|
+
|
|
13
|
+
## Quando não usar
|
|
14
|
+
|
|
15
|
+
- Para exibição de valores formatados somente leitura — use o `NumericPipe` do pacote `numeric` com `| async`
|
|
16
|
+
- Para inputs do tipo `number` do HTML — a diretiva opera sobre `<input type="text">`
|
|
17
|
+
- Quando a entrada é livre (texto, datas, etc.) — use as diretivas de máscara específicas para cada tipo
|
|
18
|
+
|
|
19
|
+
## Instalação
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { NumericMaskDirective } from '@seniorsistemas/angular-components/numeric-mask';
|
|
23
|
+
|
|
24
|
+
@Component({
|
|
25
|
+
standalone: true,
|
|
26
|
+
imports: [NumericMaskDirective, FormsModule],
|
|
27
|
+
})
|
|
28
|
+
export class MeuComponent {
|
|
29
|
+
valor: string | null = null;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Uso básico
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<input
|
|
37
|
+
type="text"
|
|
38
|
+
sNumericMask
|
|
39
|
+
[locale]="'pt-BR'"
|
|
40
|
+
[minDecimalPlaces]="2"
|
|
41
|
+
[maxDecimalPlaces]="2"
|
|
42
|
+
[(ngModel)]="valor"
|
|
43
|
+
/>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## API
|
|
47
|
+
|
|
48
|
+
### Inputs
|
|
49
|
+
|
|
50
|
+
| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|
|
51
|
+
|-------------|------|--------|:-----------:|-----------|
|
|
52
|
+
| `locale` | `string \| undefined` | Locale do `LocaleService` | Não | Locale para formatação (ex: `'pt-BR'`, `'en-US'`). Se omitido, usa o locale do `LocaleService` |
|
|
53
|
+
| `minDecimalPlaces` | `number` | `0` | Não | Número mínimo de casas decimais a exibir |
|
|
54
|
+
| `maxDecimalPlaces` | `number` | `10` | Não | Número máximo de casas decimais permitidas |
|
|
55
|
+
| `allowNegative` | `boolean` | `false` | Não | Permite valores negativos. Use as teclas `+` ou `-` para alternar o sinal |
|
|
56
|
+
| `allowScientificNotation` | `boolean` | `true` | Não | Habilita suporte a notação científica (ex: `1.5e10`) |
|
|
57
|
+
| `min` | `number \| undefined` | `undefined` | Não | Valor mínimo permitido (validação de formulário) |
|
|
58
|
+
| `max` | `number \| undefined` | `undefined` | Não | Valor máximo permitido (validação de formulário) |
|
|
59
|
+
|
|
60
|
+
### Tipos
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
// O valor do modelo (ngModel / FormControl) é sempre string no formato decimal internacional
|
|
64
|
+
// Exemplo: "1234567.89" para o valor 1.234.567,89 em pt-BR
|
|
65
|
+
type NumericMaskModelValue = string | null;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Erros de validação emitidos
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Valor negativo quando allowNegative = false
|
|
72
|
+
{ negativeNotAllowed: true }
|
|
73
|
+
|
|
74
|
+
// Valor abaixo do mínimo
|
|
75
|
+
{ min: { min: number; actual: number } }
|
|
76
|
+
|
|
77
|
+
// Valor acima do máximo
|
|
78
|
+
{ max: { max: number; actual: number } }
|
|
79
|
+
|
|
80
|
+
// Casas decimais acima do máximo
|
|
81
|
+
{ excessiveDecimalPlaces: { max: number; actual: number } }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Exemplos
|
|
85
|
+
|
|
86
|
+
### Campo monetário com 2 casas decimais fixas
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<input
|
|
90
|
+
type="text"
|
|
91
|
+
sNumericMask
|
|
92
|
+
locale="pt-BR"
|
|
93
|
+
[minDecimalPlaces]="2"
|
|
94
|
+
[maxDecimalPlaces]="2"
|
|
95
|
+
placeholder="0,00"
|
|
96
|
+
[(ngModel)]="valorMonetario"
|
|
97
|
+
/>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Campo com valores negativos
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<input
|
|
104
|
+
type="text"
|
|
105
|
+
sNumericMask
|
|
106
|
+
locale="pt-BR"
|
|
107
|
+
[minDecimalPlaces]="2"
|
|
108
|
+
[maxDecimalPlaces]="2"
|
|
109
|
+
[allowNegative]="true"
|
|
110
|
+
placeholder="-0,00"
|
|
111
|
+
[(ngModel)]="variacao"
|
|
112
|
+
/>
|
|
113
|
+
<!-- Pressione + ou - para alternar entre positivo e negativo -->
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Campo com validação de intervalo (porcentagem)
|
|
117
|
+
|
|
118
|
+
```html
|
|
119
|
+
<input
|
|
120
|
+
type="text"
|
|
121
|
+
sNumericMask
|
|
122
|
+
locale="pt-BR"
|
|
123
|
+
[minDecimalPlaces]="2"
|
|
124
|
+
[maxDecimalPlaces]="2"
|
|
125
|
+
[min]="0"
|
|
126
|
+
[max]="100"
|
|
127
|
+
placeholder="0,00"
|
|
128
|
+
[(ngModel)]="percentual"
|
|
129
|
+
/>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Campo com locale en-US
|
|
133
|
+
|
|
134
|
+
```html
|
|
135
|
+
<input
|
|
136
|
+
type="text"
|
|
137
|
+
sNumericMask
|
|
138
|
+
locale="en-US"
|
|
139
|
+
[minDecimalPlaces]="2"
|
|
140
|
+
[maxDecimalPlaces]="2"
|
|
141
|
+
placeholder="0.00"
|
|
142
|
+
[(ngModel)]="valor"
|
|
143
|
+
/>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Campo com casas decimais variáveis
|
|
147
|
+
|
|
148
|
+
```html
|
|
149
|
+
<input
|
|
150
|
+
type="text"
|
|
151
|
+
sNumericMask
|
|
152
|
+
locale="pt-BR"
|
|
153
|
+
[minDecimalPlaces]="0"
|
|
154
|
+
[maxDecimalPlaces]="4"
|
|
155
|
+
placeholder="0"
|
|
156
|
+
[(ngModel)]="quantidade"
|
|
157
|
+
/>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Acessibilidade
|
|
161
|
+
|
|
162
|
+
- Define automaticamente `inputmode="decimal"` no elemento host para exibir teclado numérico em dispositivos móveis
|
|
163
|
+
- Define `autocomplete="off"` para evitar sugestões incorretas do navegador
|
|
164
|
+
- Suporte a `Backspace`, `Tab`, `Enter`, `Escape`, `ArrowLeft`, `ArrowRight`, `Delete`, `Home` e `End`
|
|
165
|
+
- As teclas `+` e `-` alternam o sinal quando `allowNegative` está ativo
|
|
166
|
+
|
|
167
|
+
## Componentes relacionados
|
|
168
|
+
|
|
169
|
+
- [`NumericPipe`](../numeric/README.md) — formatação de valores numéricos para exibição somente leitura
|
|
170
|
+
- [`NumberInput`](../number-input/src/lib/number-input/README.md) — diretiva descontinuada, use `sNumericMask` em seu lugar
|