@seniorsistemas/angular-components 19.9.0 → 19.9.2
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/bignumber-input/lib/bignumber-input/bignumber-input.directive.d.ts +7 -1
- package/control-errors/lib/control-errors/control-errors.component.d.ts +11 -2
- package/esm2022/bignumber-input/lib/bignumber-input/bignumber-input.directive.mjs +8 -2
- package/esm2022/control-errors/lib/control-errors/control-errors.component.mjs +21 -1
- package/esm2022/drawer/lib/drawer/drawer.component.mjs +3 -3
- package/esm2022/dynamic-form/dynamic-form/form-field/fields/bignumber/bignumber-field.component.mjs +2 -2
- package/esm2022/inline-edit/lib/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.mjs +1 -1
- package/esm2022/numeric-mask/lib/numeric-mask/numeric-mask.directive.mjs +62 -6
- package/esm2022/sidebar/public-api.mjs +12 -1
- package/esm2022/spotlight/lib/spotlight/spotlight-overlay/rect-stability.mjs +61 -0
- package/esm2022/spotlight/lib/spotlight/spotlight-overlay/spotlight-overlay.component.mjs +91 -21
- package/fesm2022/seniorsistemas-angular-components-bignumber-input.mjs +7 -1
- package/fesm2022/seniorsistemas-angular-components-bignumber-input.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-control-errors.mjs +20 -0
- package/fesm2022/seniorsistemas-angular-components-control-errors.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-drawer.mjs +2 -2
- package/fesm2022/seniorsistemas-angular-components-drawer.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +1 -1
- package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs +1 -1
- package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-numeric-mask.mjs +61 -5
- package/fesm2022/seniorsistemas-angular-components-numeric-mask.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-sidebar.mjs +12 -1
- package/fesm2022/seniorsistemas-angular-components-sidebar.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-spotlight.mjs +150 -20
- package/fesm2022/seniorsistemas-angular-components-spotlight.mjs.map +1 -1
- package/numeric-mask/README.md +164 -60
- package/numeric-mask/lib/numeric-mask/numeric-mask.directive.d.ts +29 -2
- package/package.json +13 -13
- package/sidebar/README.md +3 -3
- package/sidebar/public-api.d.ts +10 -0
- package/spotlight/README.md +28 -0
- package/spotlight/lib/spotlight/spotlight-overlay/rect-stability.d.ts +32 -0
- package/spotlight/lib/spotlight/spotlight-overlay/spotlight-overlay.component.d.ts +33 -0
package/numeric-mask/README.md
CHANGED
|
@@ -22,11 +22,11 @@ Diretiva Angular para formatação de valores numéricos em campos de input com
|
|
|
22
22
|
import { NumericMaskDirective } from '@seniorsistemas/angular-components/numeric-mask';
|
|
23
23
|
|
|
24
24
|
@Component({
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
standalone: true,
|
|
26
|
+
imports: [NumericMaskDirective, FormsModule],
|
|
27
27
|
})
|
|
28
28
|
export class MeuComponent {
|
|
29
|
-
|
|
29
|
+
valor: string | null = null;
|
|
30
30
|
}
|
|
31
31
|
```
|
|
32
32
|
|
|
@@ -34,12 +34,12 @@ export class MeuComponent {
|
|
|
34
34
|
|
|
35
35
|
```html
|
|
36
36
|
<input
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
type="text"
|
|
38
|
+
sNumericMask
|
|
39
|
+
[locale]="'pt-BR'"
|
|
40
|
+
[minDecimalPlaces]="2"
|
|
41
|
+
[maxDecimalPlaces]="2"
|
|
42
|
+
[(ngModel)]="valor"
|
|
43
43
|
/>
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -47,15 +47,17 @@ export class MeuComponent {
|
|
|
47
47
|
|
|
48
48
|
### Inputs
|
|
49
49
|
|
|
50
|
-
| Propriedade
|
|
51
|
-
|
|
52
|
-
| `locale`
|
|
53
|
-
| `minDecimalPlaces`
|
|
54
|
-
| `maxDecimalPlaces`
|
|
55
|
-
| `allowNegative`
|
|
56
|
-
| `allowScientificNotation` | `boolean`
|
|
57
|
-
| `min`
|
|
58
|
-
| `max`
|
|
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
|
+
| `blockDecimalOverflow` | `boolean` | `true` | Não | Bloqueia a digitação e a colagem de casas decimais além de `maxDecimalPlaces`. Quando `maxDecimalPlaces` é `0`, o próprio separador decimal não pode ser digitado |
|
|
60
|
+
| `decimalRoundingMode` | `'preserve' \| 'truncate' \| 'roundUp' \| 'roundDown'` | `'preserve'` | Não | Estratégia aplicada no `blur` quando `blockDecimalOverflow` é `false`. Sem efeito enquanto `blockDecimalOverflow` for `true` |
|
|
59
61
|
|
|
60
62
|
### Tipos
|
|
61
63
|
|
|
@@ -69,16 +71,96 @@ type NumericMaskModelValue = string | null;
|
|
|
69
71
|
|
|
70
72
|
```typescript
|
|
71
73
|
// Valor negativo quando allowNegative = false
|
|
72
|
-
{
|
|
74
|
+
{
|
|
75
|
+
negativeNotAllowed: true;
|
|
76
|
+
}
|
|
73
77
|
|
|
74
78
|
// Valor abaixo do mínimo
|
|
75
|
-
{
|
|
79
|
+
{
|
|
80
|
+
min: {
|
|
81
|
+
min: number;
|
|
82
|
+
actual: number;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
76
85
|
|
|
77
86
|
// Valor acima do máximo
|
|
78
|
-
{
|
|
87
|
+
{
|
|
88
|
+
max: {
|
|
89
|
+
max: number;
|
|
90
|
+
actual: number;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
79
93
|
|
|
80
94
|
// Casas decimais acima do máximo
|
|
81
|
-
{
|
|
95
|
+
{
|
|
96
|
+
excessiveDecimalPlaces: {
|
|
97
|
+
max: number;
|
|
98
|
+
actual: number;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Comportamento de excesso de casas decimais
|
|
104
|
+
|
|
105
|
+
Por padrão (`blockDecimalOverflow = true`), a digitação e a colagem de valores com mais casas decimais que `maxDecimalPlaces` são bloqueadas no momento da entrada: dígitos excedentes são ignorados imediatamente (sem esperar o `blur`) e, quando `maxDecimalPlaces` é `0`, o próprio separador decimal não pode ser digitado.
|
|
106
|
+
|
|
107
|
+
Desligando o bloqueio (`[blockDecimalOverflow]="false"`), a digitação volta a ser livre e o input `decimalRoundingMode` passa a controlar o que acontece ao perder o foco (`blur`):
|
|
108
|
+
|
|
109
|
+
| `decimalRoundingMode` | Comportamento no `blur` |
|
|
110
|
+
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
111
|
+
| `'preserve'` (padrão) | Comportamento legado: a exibição é truncada, mas o modelo mantém a precisão total do que foi digitado |
|
|
112
|
+
| `'truncate'` | Corta as casas excedentes tanto na exibição quanto no modelo, sem arredondar (sempre em direção a zero) |
|
|
113
|
+
| `'roundUp'` | Arredonda sempre para o próximo valor representável **acima** (ceiling), mesmo que o excedente seja mínimo — não é arredondamento para o valor mais próximo |
|
|
114
|
+
| `'roundDown'` | Arredonda sempre para o próximo valor representável **abaixo** (floor), pelo mesmo motivo |
|
|
115
|
+
|
|
116
|
+
```html
|
|
117
|
+
<!-- Padrão: bloqueia a digitação acima de 2 casas decimais -->
|
|
118
|
+
<input
|
|
119
|
+
type="text"
|
|
120
|
+
sNumericMask
|
|
121
|
+
[maxDecimalPlaces]="2"
|
|
122
|
+
[(ngModel)]="valor"
|
|
123
|
+
/>
|
|
124
|
+
|
|
125
|
+
<!-- Comportamento legado explícito (digitação livre, modelo com precisão total) -->
|
|
126
|
+
<input
|
|
127
|
+
type="text"
|
|
128
|
+
sNumericMask
|
|
129
|
+
[maxDecimalPlaces]="2"
|
|
130
|
+
[blockDecimalOverflow]="false"
|
|
131
|
+
decimalRoundingMode="preserve"
|
|
132
|
+
[(ngModel)]="valor"
|
|
133
|
+
/>
|
|
134
|
+
|
|
135
|
+
<!-- Trunca no blur (corta sem arredondar) -->
|
|
136
|
+
<input
|
|
137
|
+
type="text"
|
|
138
|
+
sNumericMask
|
|
139
|
+
[maxDecimalPlaces]="2"
|
|
140
|
+
[blockDecimalOverflow]="false"
|
|
141
|
+
decimalRoundingMode="truncate"
|
|
142
|
+
[(ngModel)]="valor"
|
|
143
|
+
/>
|
|
144
|
+
|
|
145
|
+
<!-- Arredonda sempre para cima no blur -->
|
|
146
|
+
<input
|
|
147
|
+
type="text"
|
|
148
|
+
sNumericMask
|
|
149
|
+
[maxDecimalPlaces]="2"
|
|
150
|
+
[blockDecimalOverflow]="false"
|
|
151
|
+
decimalRoundingMode="roundUp"
|
|
152
|
+
[(ngModel)]="valor"
|
|
153
|
+
/>
|
|
154
|
+
|
|
155
|
+
<!-- Arredonda sempre para baixo no blur -->
|
|
156
|
+
<input
|
|
157
|
+
type="text"
|
|
158
|
+
sNumericMask
|
|
159
|
+
[maxDecimalPlaces]="2"
|
|
160
|
+
[blockDecimalOverflow]="false"
|
|
161
|
+
decimalRoundingMode="roundDown"
|
|
162
|
+
[(ngModel)]="valor"
|
|
163
|
+
/>
|
|
82
164
|
```
|
|
83
165
|
|
|
84
166
|
## Exemplos
|
|
@@ -87,13 +169,13 @@ type NumericMaskModelValue = string | null;
|
|
|
87
169
|
|
|
88
170
|
```html
|
|
89
171
|
<input
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
172
|
+
type="text"
|
|
173
|
+
sNumericMask
|
|
174
|
+
locale="pt-BR"
|
|
175
|
+
[minDecimalPlaces]="2"
|
|
176
|
+
[maxDecimalPlaces]="2"
|
|
177
|
+
placeholder="0,00"
|
|
178
|
+
[(ngModel)]="valorMonetario"
|
|
97
179
|
/>
|
|
98
180
|
```
|
|
99
181
|
|
|
@@ -101,14 +183,14 @@ type NumericMaskModelValue = string | null;
|
|
|
101
183
|
|
|
102
184
|
```html
|
|
103
185
|
<input
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
186
|
+
type="text"
|
|
187
|
+
sNumericMask
|
|
188
|
+
locale="pt-BR"
|
|
189
|
+
[minDecimalPlaces]="2"
|
|
190
|
+
[maxDecimalPlaces]="2"
|
|
191
|
+
[allowNegative]="true"
|
|
192
|
+
placeholder="-0,00"
|
|
193
|
+
[(ngModel)]="variacao"
|
|
112
194
|
/>
|
|
113
195
|
<!-- Pressione + ou - para alternar entre positivo e negativo -->
|
|
114
196
|
```
|
|
@@ -117,15 +199,15 @@ type NumericMaskModelValue = string | null;
|
|
|
117
199
|
|
|
118
200
|
```html
|
|
119
201
|
<input
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
202
|
+
type="text"
|
|
203
|
+
sNumericMask
|
|
204
|
+
locale="pt-BR"
|
|
205
|
+
[minDecimalPlaces]="2"
|
|
206
|
+
[maxDecimalPlaces]="2"
|
|
207
|
+
[min]="0"
|
|
208
|
+
[max]="100"
|
|
209
|
+
placeholder="0,00"
|
|
210
|
+
[(ngModel)]="percentual"
|
|
129
211
|
/>
|
|
130
212
|
```
|
|
131
213
|
|
|
@@ -133,13 +215,13 @@ type NumericMaskModelValue = string | null;
|
|
|
133
215
|
|
|
134
216
|
```html
|
|
135
217
|
<input
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
218
|
+
type="text"
|
|
219
|
+
sNumericMask
|
|
220
|
+
locale="en-US"
|
|
221
|
+
[minDecimalPlaces]="2"
|
|
222
|
+
[maxDecimalPlaces]="2"
|
|
223
|
+
placeholder="0.00"
|
|
224
|
+
[(ngModel)]="valor"
|
|
143
225
|
/>
|
|
144
226
|
```
|
|
145
227
|
|
|
@@ -147,13 +229,13 @@ type NumericMaskModelValue = string | null;
|
|
|
147
229
|
|
|
148
230
|
```html
|
|
149
231
|
<input
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
232
|
+
type="text"
|
|
233
|
+
sNumericMask
|
|
234
|
+
locale="pt-BR"
|
|
235
|
+
[minDecimalPlaces]="0"
|
|
236
|
+
[maxDecimalPlaces]="4"
|
|
237
|
+
placeholder="0"
|
|
238
|
+
[(ngModel)]="quantidade"
|
|
157
239
|
/>
|
|
158
240
|
```
|
|
159
241
|
|
|
@@ -168,3 +250,25 @@ type NumericMaskModelValue = string | null;
|
|
|
168
250
|
|
|
169
251
|
- [`NumericPipe`](../numeric/README.md) — formatação de valores numéricos para exibição somente leitura
|
|
170
252
|
- [`NumberInput`](../number-input/src/lib/number-input/README.md) — diretiva descontinuada, use `sNumericMask` em seu lugar
|
|
253
|
+
|
|
254
|
+
## Migração
|
|
255
|
+
|
|
256
|
+
### Mudança de comportamento padrão
|
|
257
|
+
|
|
258
|
+
A partir desta versão, `blockDecimalOverflow` passa a ser `true` por padrão: a digitação e a colagem de valores com mais casas decimais que `maxDecimalPlaces` passam a ser bloqueadas no momento da entrada, em vez de aceitas livremente e truncadas apenas na exibição ao perder o foco.
|
|
259
|
+
|
|
260
|
+
Para restaurar o comportamento anterior (digitação livre, modelo com precisão total, exibição truncada no `blur`):
|
|
261
|
+
|
|
262
|
+
```html
|
|
263
|
+
<input
|
|
264
|
+
type="text"
|
|
265
|
+
sNumericMask
|
|
266
|
+
[maxDecimalPlaces]="2"
|
|
267
|
+
[blockDecimalOverflow]="false"
|
|
268
|
+
decimalRoundingMode="preserve"
|
|
269
|
+
[(ngModel)]="valor"
|
|
270
|
+
/>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
`decimalRoundingMode="preserve"` já é o padrão — pode ser omitido, mas deixá-lo explícito reforça a intenção do comportamento legado.
|
|
274
|
+
|
|
@@ -56,6 +56,22 @@ export declare class NumericMaskDirective implements OnInit, OnChanges, ControlV
|
|
|
56
56
|
* Maximum value allowed
|
|
57
57
|
*/
|
|
58
58
|
max: import("@angular/core").InputSignal<number | undefined>;
|
|
59
|
+
/**
|
|
60
|
+
* Blocks typing/pasting decimal digits beyond maxDecimalPlaces.
|
|
61
|
+
* When maxDecimalPlaces is 0, the decimal separator itself cannot be entered.
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
blockDecimalOverflow: import("@angular/core").InputSignal<boolean>;
|
|
65
|
+
/**
|
|
66
|
+
* Strategy applied on blur when blockDecimalOverflow is false.
|
|
67
|
+
* 'preserve' keeps the model at full precision; only the display is truncated (legacy behavior).
|
|
68
|
+
* 'truncate' cuts the excess decimals without rounding (towards zero), updating the model too.
|
|
69
|
+
* 'roundUp' always rounds to the next representable value above (ceiling), updating the model too.
|
|
70
|
+
* 'roundDown' always rounds to the next representable value below (floor), updating the model too.
|
|
71
|
+
* Has no effect while blockDecimalOverflow is true.
|
|
72
|
+
* @default 'preserve'
|
|
73
|
+
*/
|
|
74
|
+
decimalRoundingMode: import("@angular/core").InputSignal<"preserve" | "truncate" | "roundUp" | "roundDown">;
|
|
59
75
|
private readonly elementRef;
|
|
60
76
|
private readonly renderer;
|
|
61
77
|
private readonly localeService;
|
|
@@ -127,10 +143,21 @@ export declare class NumericMaskDirective implements OnInit, OnChanges, ControlV
|
|
|
127
143
|
*/
|
|
128
144
|
private escapeRegex;
|
|
129
145
|
/**
|
|
130
|
-
* Truncates a number to the specified decimal places
|
|
146
|
+
* Truncates (or rounds, depending on roundingMode) a number to the specified decimal places
|
|
131
147
|
* @private
|
|
132
148
|
*/
|
|
133
149
|
private truncateToDecimalPlaces;
|
|
150
|
+
/**
|
|
151
|
+
* Maps decimalRoundingMode to the corresponding BigNumber rounding mode
|
|
152
|
+
* @private
|
|
153
|
+
*/
|
|
154
|
+
private resolveRoundingMode;
|
|
155
|
+
/**
|
|
156
|
+
* Limits the decimal part of a value being typed/pasted to maxDecimalPlaces,
|
|
157
|
+
* preserving any scientific notation exponent untouched
|
|
158
|
+
* @private
|
|
159
|
+
*/
|
|
160
|
+
private applyBlockLimit;
|
|
134
161
|
/**
|
|
135
162
|
* Parses a string value to its numeric representation, handling separators and sign
|
|
136
163
|
* Returns BigNumber to preserve full precision and optional number conversion
|
|
@@ -172,5 +199,5 @@ export declare class NumericMaskDirective implements OnInit, OnChanges, ControlV
|
|
|
172
199
|
setDisabledState(isDisabled: boolean): void;
|
|
173
200
|
validate(control: AbstractControl): ValidationErrors | null;
|
|
174
201
|
static ɵfac: i0.ɵɵFactoryDeclaration<NumericMaskDirective, never>;
|
|
175
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<NumericMaskDirective, "[sNumericMask]", never, { "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "minDecimalPlaces": { "alias": "minDecimalPlaces"; "required": false; "isSignal": true; }; "maxDecimalPlaces": { "alias": "maxDecimalPlaces"; "required": false; "isSignal": true; }; "allowNegative": { "alias": "allowNegative"; "required": false; "isSignal": true; }; "allowScientificNotation": { "alias": "allowScientificNotation"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "decimalSeparator": { "alias": "decimalSeparator"; "required": false; "isSignal": true; }; "thousandSeparator": { "alias": "thousandSeparator"; "required": false; "isSignal": true; }; }, { "decimalSeparator": "decimalSeparatorChange"; "thousandSeparator": "thousandSeparatorChange"; }, never, never, true, never>;
|
|
202
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NumericMaskDirective, "[sNumericMask]", never, { "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "minDecimalPlaces": { "alias": "minDecimalPlaces"; "required": false; "isSignal": true; }; "maxDecimalPlaces": { "alias": "maxDecimalPlaces"; "required": false; "isSignal": true; }; "allowNegative": { "alias": "allowNegative"; "required": false; "isSignal": true; }; "allowScientificNotation": { "alias": "allowScientificNotation"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "blockDecimalOverflow": { "alias": "blockDecimalOverflow"; "required": false; "isSignal": true; }; "decimalRoundingMode": { "alias": "decimalRoundingMode"; "required": false; "isSignal": true; }; "decimalSeparator": { "alias": "decimalSeparator"; "required": false; "isSignal": true; }; "thousandSeparator": { "alias": "thousandSeparator"; "required": false; "isSignal": true; }; }, { "decimalSeparator": "decimalSeparatorChange"; "thousandSeparator": "thousandSeparatorChange"; }, never, never, true, never>;
|
|
176
203
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seniorsistemas/angular-components",
|
|
3
|
-
"version": "19.9.
|
|
3
|
+
"version": "19.9.2",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/cdk": "^18.2.14",
|
|
6
6
|
"@angular/common": "^18.2.0",
|
|
@@ -97,36 +97,36 @@
|
|
|
97
97
|
"esm": "./esm2022/accordion/seniorsistemas-angular-components-accordion.mjs",
|
|
98
98
|
"default": "./fesm2022/seniorsistemas-angular-components-accordion.mjs"
|
|
99
99
|
},
|
|
100
|
-
"./autocomplete": {
|
|
101
|
-
"types": "./autocomplete/index.d.ts",
|
|
102
|
-
"esm2022": "./esm2022/autocomplete/seniorsistemas-angular-components-autocomplete.mjs",
|
|
103
|
-
"esm": "./esm2022/autocomplete/seniorsistemas-angular-components-autocomplete.mjs",
|
|
104
|
-
"default": "./fesm2022/seniorsistemas-angular-components-autocomplete.mjs"
|
|
105
|
-
},
|
|
106
100
|
"./alert": {
|
|
107
101
|
"types": "./alert/index.d.ts",
|
|
108
102
|
"esm2022": "./esm2022/alert/seniorsistemas-angular-components-alert.mjs",
|
|
109
103
|
"esm": "./esm2022/alert/seniorsistemas-angular-components-alert.mjs",
|
|
110
104
|
"default": "./fesm2022/seniorsistemas-angular-components-alert.mjs"
|
|
111
105
|
},
|
|
106
|
+
"./autocomplete": {
|
|
107
|
+
"types": "./autocomplete/index.d.ts",
|
|
108
|
+
"esm2022": "./esm2022/autocomplete/seniorsistemas-angular-components-autocomplete.mjs",
|
|
109
|
+
"esm": "./esm2022/autocomplete/seniorsistemas-angular-components-autocomplete.mjs",
|
|
110
|
+
"default": "./fesm2022/seniorsistemas-angular-components-autocomplete.mjs"
|
|
111
|
+
},
|
|
112
112
|
"./badge": {
|
|
113
113
|
"types": "./badge/index.d.ts",
|
|
114
114
|
"esm2022": "./esm2022/badge/seniorsistemas-angular-components-badge.mjs",
|
|
115
115
|
"esm": "./esm2022/badge/seniorsistemas-angular-components-badge.mjs",
|
|
116
116
|
"default": "./fesm2022/seniorsistemas-angular-components-badge.mjs"
|
|
117
117
|
},
|
|
118
|
-
"./bignumber-input": {
|
|
119
|
-
"types": "./bignumber-input/index.d.ts",
|
|
120
|
-
"esm2022": "./esm2022/bignumber-input/seniorsistemas-angular-components-bignumber-input.mjs",
|
|
121
|
-
"esm": "./esm2022/bignumber-input/seniorsistemas-angular-components-bignumber-input.mjs",
|
|
122
|
-
"default": "./fesm2022/seniorsistemas-angular-components-bignumber-input.mjs"
|
|
123
|
-
},
|
|
124
118
|
"./breadcrumb": {
|
|
125
119
|
"types": "./breadcrumb/index.d.ts",
|
|
126
120
|
"esm2022": "./esm2022/breadcrumb/seniorsistemas-angular-components-breadcrumb.mjs",
|
|
127
121
|
"esm": "./esm2022/breadcrumb/seniorsistemas-angular-components-breadcrumb.mjs",
|
|
128
122
|
"default": "./fesm2022/seniorsistemas-angular-components-breadcrumb.mjs"
|
|
129
123
|
},
|
|
124
|
+
"./bignumber-input": {
|
|
125
|
+
"types": "./bignumber-input/index.d.ts",
|
|
126
|
+
"esm2022": "./esm2022/bignumber-input/seniorsistemas-angular-components-bignumber-input.mjs",
|
|
127
|
+
"esm": "./esm2022/bignumber-input/seniorsistemas-angular-components-bignumber-input.mjs",
|
|
128
|
+
"default": "./fesm2022/seniorsistemas-angular-components-bignumber-input.mjs"
|
|
129
|
+
},
|
|
130
130
|
"./button": {
|
|
131
131
|
"types": "./button/index.d.ts",
|
|
132
132
|
"esm2022": "./esm2022/button/seniorsistemas-angular-components-button.mjs",
|
package/sidebar/README.md
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
> **Descontinuado** — Este pacote é um alias de compatibilidade para o componente `Drawer` e será removido na versão 20.0.0.
|
|
6
6
|
|
|
7
|
-
O pacote `sidebar` re-exporta `DrawerComponent` e `DrawerModule` do pacote `@seniorsistemas/angular-components/drawer
|
|
7
|
+
O pacote `sidebar` re-exporta `DrawerComponent` e `DrawerModule` do pacote `@seniorsistemas/angular-components/drawer` — tanto sob os nomes novos (`DrawerComponent`/`DrawerModule`) quanto sob os nomes antigos (`SidebarComponent`/`SidebarModule`), para manter compatibilidade com quem já importava por qualquer um dos dois nomes a partir deste pacote.
|
|
8
8
|
|
|
9
9
|
## Quando usar
|
|
10
10
|
|
|
11
|
-
- Apenas para manutenção de código legado que já usa `
|
|
11
|
+
- Apenas para manutenção de código legado que já usa `SidebarComponent`/`SidebarModule` (ou `DrawerComponent`/`DrawerModule`) a partir deste pacote
|
|
12
12
|
|
|
13
13
|
## Quando não usar
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ O pacote `sidebar` re-exporta `DrawerComponent` e `DrawerModule` do pacote `@sen
|
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
20
|
// Antes (descontinuado)
|
|
21
|
-
import {
|
|
21
|
+
import { SidebarModule } from '@seniorsistemas/angular-components/sidebar';
|
|
22
22
|
|
|
23
23
|
// Depois (recomendado)
|
|
24
24
|
import { DrawerModule } from '@seniorsistemas/angular-components/drawer';
|
package/sidebar/public-api.d.ts
CHANGED
|
@@ -9,3 +9,13 @@ export declare const DrawerComponent: typeof DrawerComponentOriginal;
|
|
|
9
9
|
* O pacote sidebar será removido na versão 20.0.0.
|
|
10
10
|
*/
|
|
11
11
|
export declare const DrawerModule: typeof DrawerModuleOriginal;
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated Use DrawerComponent from '@seniorsistemas/angular-components/drawer'.
|
|
14
|
+
* O pacote sidebar será removido na versão 20.0.0.
|
|
15
|
+
*/
|
|
16
|
+
export declare const SidebarComponent: typeof DrawerComponentOriginal;
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use DrawerModule from '@seniorsistemas/angular-components/drawer'.
|
|
19
|
+
* O pacote sidebar será removido na versão 20.0.0.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SidebarModule: typeof DrawerModuleOriginal;
|
package/spotlight/README.md
CHANGED
|
@@ -88,6 +88,32 @@ this.tourService.start([
|
|
|
88
88
|
| `previous` | `OutputEmitterRef<void>` | Emitido ao clicar em "Voltar" |
|
|
89
89
|
| `understand` | `OutputEmitterRef<void>` | Emitido ao clicar em "Entendido" (modo simples) |
|
|
90
90
|
|
|
91
|
+
### Hooks `beforeNext` / `beforePrevious`
|
|
92
|
+
|
|
93
|
+
Cada passo pode definir `beforeNext?: () => void | Promise<void>` e `beforePrevious?: () => void | Promise<void>`, executados antes de avançar/retroceder. Se retornarem uma `Promise`, o Spotlight aguarda sua resolução antes de trocar de passo.
|
|
94
|
+
|
|
95
|
+
Isso é útil quando o próximo passo aponta para um elemento que só existe (ou só chega à posição final) depois de uma ação disparada pelo `beforeNext` — por exemplo, abrir um menu ou uma aba:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
this.tourService.start([
|
|
99
|
+
{
|
|
100
|
+
stepId: 'abrir-menu',
|
|
101
|
+
title: 'Abra o menu',
|
|
102
|
+
message: 'Clique aqui para abrir as opções.',
|
|
103
|
+
beforeNext: () => this.menuService.open(), // abre um menu com animação CSS
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
stepId: 'item-do-menu', // elemento dentro do menu recém-aberto
|
|
107
|
+
title: 'Selecione aqui',
|
|
108
|
+
message: 'Este item concentra as opções mais usadas.',
|
|
109
|
+
},
|
|
110
|
+
]);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Não é necessário esperar manualmente a animação terminar.** O Spotlight aguarda internamente até que a posição do elemento-alvo do próximo passo se estabilize, tolerando transições CSS típicas de abertura de menus, abas e painéis. Não adicione `setTimeout`/delays artificiais dentro de `beforeNext` — eles são redundantes e, no melhor caso, apenas adicionam espera desnecessária.
|
|
114
|
+
|
|
115
|
+
Se o elemento do próximo passo ainda não existir no DOM no momento da troca (por exemplo, criado dinamicamente pelo `beforeNext` via `@if`/troca de aba), o Spotlight aguarda brevemente pelo registro automático via `[sSpotlightStep]` antes de recorrer a um popover centralizado sem destaque. Em ambos os casos de espera esgotada, um aviso é emitido no console citando o `stepId` — útil para diagnosticar um `stepId` incorreto ou uma animação anormalmente longa.
|
|
116
|
+
|
|
91
117
|
### Tipos
|
|
92
118
|
|
|
93
119
|
```typescript
|
|
@@ -105,6 +131,8 @@ interface SpotlightStep {
|
|
|
105
131
|
showDoNotShowAgain?: boolean;
|
|
106
132
|
dismissible?: boolean;
|
|
107
133
|
actions?: SpotlightStepAction[];
|
|
134
|
+
beforeNext?: () => void | Promise<void>;
|
|
135
|
+
beforePrevious?: () => void | Promise<void>;
|
|
108
136
|
}
|
|
109
137
|
|
|
110
138
|
interface SpotlightStepAction {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilitário puro (sem dependência de Angular/NgZone) para aguardar até que a posição
|
|
3
|
+
* e o tamanho de um elemento parem de mudar — usado para medir corretamente elementos
|
|
4
|
+
* que podem estar em transição/animação (ex: um menu abrindo) no momento em que o
|
|
5
|
+
* Spotlight precisa apontar para eles.
|
|
6
|
+
*/
|
|
7
|
+
export interface RectStabilityOptions {
|
|
8
|
+
/** Quantas amostras consecutivas dentro da tolerância definem "estável". */
|
|
9
|
+
requiredStableSamples: number;
|
|
10
|
+
/** Diferença máxima (px) entre duas amostras para serem consideradas iguais. */
|
|
11
|
+
tolerancePx: number;
|
|
12
|
+
/** Teto de segurança (ms) — nunca esperar além disso. */
|
|
13
|
+
maxWaitMs: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const DEFAULT_RECT_STABILITY_OPTIONS: RectStabilityOptions;
|
|
16
|
+
export interface StableRectResult {
|
|
17
|
+
rect: DOMRect;
|
|
18
|
+
timedOut: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface StabilizeHandle {
|
|
21
|
+
readonly promise: Promise<StableRectResult>;
|
|
22
|
+
cancel(): void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Faz polling de `el.getBoundingClientRect()` em frames sucessivos até que
|
|
26
|
+
* `requiredStableSamples` amostras consecutivas sejam iguais (dentro de `tolerancePx`),
|
|
27
|
+
* ou até que `maxWaitMs` seja atingido — o que ocorrer primeiro.
|
|
28
|
+
*
|
|
29
|
+
* `scheduleFrame`/`cancelFrame`/`now` são injetáveis para permitir testes determinísticos;
|
|
30
|
+
* por padrão usam as APIs nativas do navegador.
|
|
31
|
+
*/
|
|
32
|
+
export declare function waitForStableRect(el: HTMLElement, options?: RectStabilityOptions, scheduleFrame?: (cb: FrameRequestCallback) => number, cancelFrame?: (handle: number) => void, now?: () => number): StabilizeHandle;
|
|
@@ -20,6 +20,13 @@ export declare class SpotlightOverlayComponent implements OnInit, OnDestroy {
|
|
|
20
20
|
readonly totalSteps: import("@angular/core").Signal<number>;
|
|
21
21
|
/** @internal*/
|
|
22
22
|
readonly targetRect: import("@angular/core").WritableSignal<DOMRect | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Controla se a máscara deve animar a transição entre retângulos (reposicionamento
|
|
25
|
+
* em vivo, ex: scroll/resize) ou saltar instantaneamente (chegada/saída de um passo).
|
|
26
|
+
* Ver `setTargetRectImmediate`.
|
|
27
|
+
*/
|
|
28
|
+
private readonly maskTransitionEnabled;
|
|
29
|
+
private readonly maskTransitionStyle;
|
|
23
30
|
/** @internal */
|
|
24
31
|
readonly topMaskStyle: import("@angular/core").Signal<Record<string, string>>;
|
|
25
32
|
/** @internal */
|
|
@@ -36,7 +43,25 @@ export declare class SpotlightOverlayComponent implements OnInit, OnDestroy {
|
|
|
36
43
|
private popoverSubs;
|
|
37
44
|
private focusTrap;
|
|
38
45
|
private previouslyFocusedElement;
|
|
46
|
+
private pendingArrival;
|
|
47
|
+
private elementWaitTimerId;
|
|
48
|
+
private stabilizeGeneration;
|
|
39
49
|
constructor();
|
|
50
|
+
/**
|
|
51
|
+
* Aguarda o layout do elemento-alvo estabilizar (ex: animação de abertura de um menu
|
|
52
|
+
* disparada pelo `beforeNext` do passo anterior) antes de medir sua posição definitiva
|
|
53
|
+
* e posicionar a máscara/popover. Substitui a antiga espera de um único frame, que
|
|
54
|
+
* capturava o retângulo no meio de animações de terceiros na tela.
|
|
55
|
+
*/
|
|
56
|
+
private beginArrivalSequence;
|
|
57
|
+
/**
|
|
58
|
+
* Aguarda até `ELEMENT_WAIT_TIMEOUT_MS` pelo registro do elemento-alvo via
|
|
59
|
+
* `[sSpotlightStep]` (útil quando o `beforeNext` do passo anterior cria o elemento
|
|
60
|
+
* dinamicamente, ex: abrindo uma aba) antes de recorrer ao popover centralizado.
|
|
61
|
+
* Mantém o último quadro renderizado durante a espera para evitar um flash.
|
|
62
|
+
*/
|
|
63
|
+
private awaitElementRegistration;
|
|
64
|
+
private cancelPendingArrival;
|
|
40
65
|
ngOnInit(): void;
|
|
41
66
|
ngOnDestroy(): void;
|
|
42
67
|
/** @internal */
|
|
@@ -62,6 +87,14 @@ export declare class SpotlightOverlayComponent implements OnInit, OnDestroy {
|
|
|
62
87
|
private syncDirectionAndArrow;
|
|
63
88
|
private destroyPopoverOverlay;
|
|
64
89
|
private updateTargetRect;
|
|
90
|
+
/**
|
|
91
|
+
* Aplica um novo `targetRect` sem animação de transição na máscara — usado ao
|
|
92
|
+
* chegar/saltar para um alvo novo, onde animar a partir da posição do passo
|
|
93
|
+
* anterior criaria a falsa impressão de "apontou errado e corrigiu depois".
|
|
94
|
+
* A transição é reabilitada no frame seguinte para reposicionamentos legítimos
|
|
95
|
+
* (scroll/resize de um alvo já visível).
|
|
96
|
+
*/
|
|
97
|
+
private setTargetRectImmediate;
|
|
65
98
|
private refreshRect;
|
|
66
99
|
private observeElement;
|
|
67
100
|
private disconnectResizeObserver;
|