@ptsecurity/mosaic 15.9.3 → 15.9.5
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/datepicker/calendar-header.component.d.ts +13 -13
- package/datepicker/datepicker-input.directive.d.ts +10 -0
- package/esm2020/core/version.mjs +2 -2
- package/esm2020/datepicker/calendar-header.component.mjs +42 -13
- package/esm2020/datepicker/datepicker-input.directive.mjs +103 -23
- package/esm2020/input/input-number.mjs +196 -41
- package/fesm2015/ptsecurity-mosaic-core.mjs +1 -1
- package/fesm2015/ptsecurity-mosaic-core.mjs.map +1 -1
- package/fesm2015/ptsecurity-mosaic-datepicker.mjs +143 -34
- package/fesm2015/ptsecurity-mosaic-datepicker.mjs.map +1 -1
- package/fesm2015/ptsecurity-mosaic-input.mjs +198 -41
- package/fesm2015/ptsecurity-mosaic-input.mjs.map +1 -1
- package/fesm2020/ptsecurity-mosaic-core.mjs +1 -1
- package/fesm2020/ptsecurity-mosaic-core.mjs.map +1 -1
- package/fesm2020/ptsecurity-mosaic-datepicker.mjs +143 -34
- package/fesm2020/ptsecurity-mosaic-datepicker.mjs.map +1 -1
- package/fesm2020/ptsecurity-mosaic-input.mjs +195 -40
- package/fesm2020/ptsecurity-mosaic-input.mjs.map +1 -1
- package/input/input-number.d.ts +50 -10
- package/package.json +4 -4
@@ -2,17 +2,17 @@ import * as i3$1 from '@angular/cdk/a11y';
|
|
2
2
|
import { A11yModule } from '@angular/cdk/a11y';
|
3
3
|
import { CommonModule } from '@angular/common';
|
4
4
|
import * as i0 from '@angular/core';
|
5
|
-
import { InjectionToken,
|
5
|
+
import { InjectionToken, forwardRef, EventEmitter, Directive, Attribute, Input, Optional, Self, Inject, Component, ChangeDetectionStrategy, ViewEncapsulation, NgModule } from '@angular/core';
|
6
6
|
import * as i1 from '@angular/forms';
|
7
|
-
import { NG_VALIDATORS, Validators, FormsModule } from '@angular/forms';
|
7
|
+
import { NG_VALUE_ACCESSOR, NG_VALIDATORS, Validators, FormsModule } from '@angular/forms';
|
8
8
|
import * as i3 from '@ptsecurity/mosaic/core';
|
9
9
|
import { mixinErrorState, PopUpTriggers, McCommonModule } from '@ptsecurity/mosaic/core';
|
10
10
|
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
|
11
11
|
import { getSupportedInputTypes } from '@angular/cdk/platform';
|
12
12
|
import * as i4 from '@ptsecurity/mosaic/form-field';
|
13
13
|
import { McFormFieldControl } from '@ptsecurity/mosaic/form-field';
|
14
|
-
import { Subject } from 'rxjs';
|
15
|
-
import { A, C, V, X, Z,
|
14
|
+
import { Subject, Subscription } from 'rxjs';
|
15
|
+
import { A, C, V, X, Z, NUMPAD_MINUS, DASH, FF_MINUS, DELETE, BACKSPACE, TAB, ESCAPE, ENTER, LEFT_ARROW, RIGHT_ARROW, HOME, END, isFunctionKey, isNumberKey, isNumpadKey, UP_ARROW, DOWN_ARROW } from '@ptsecurity/cdk/keycodes';
|
16
16
|
import { McTooltipTrigger, MC_TOOLTIP_SCROLL_STRATEGY } from '@ptsecurity/mosaic/tooltip';
|
17
17
|
import * as i1$1 from '@angular/cdk/overlay';
|
18
18
|
import * as i2 from '@angular/cdk/bidi';
|
@@ -25,6 +25,7 @@ const MC_INPUT_VALUE_ACCESSOR = new InjectionToken('MC_INPUT_VALUE_ACCESSOR');
|
|
25
25
|
|
26
26
|
const BIG_STEP = 10;
|
27
27
|
const SMALL_STEP = 1;
|
28
|
+
// TODO: подставлять локализованный сплиттер
|
28
29
|
function normalizeSplitter(value) {
|
29
30
|
return value ? value.replace(/,/g, '.') : value;
|
30
31
|
}
|
@@ -48,16 +49,33 @@ function add(value1, value2) {
|
|
48
49
|
const precision = Math.max(getPrecision(value1), getPrecision(value2));
|
49
50
|
return (value1 * precision + value2 * precision) / precision;
|
50
51
|
}
|
52
|
+
const MC_NUMBER_INPUT_VALUE_ACCESSOR = {
|
53
|
+
provide: NG_VALUE_ACCESSOR,
|
54
|
+
useExisting: forwardRef(() => McNumberInput),
|
55
|
+
multi: true
|
56
|
+
};
|
51
57
|
class McNumberInput {
|
52
|
-
constructor(elementRef,
|
58
|
+
constructor(elementRef, renderer, step, bigStep, min, max) {
|
53
59
|
this.elementRef = elementRef;
|
54
|
-
this.
|
55
|
-
|
60
|
+
this.renderer = renderer;
|
61
|
+
/** Emits when the value changes (either due to user input or programmatic change). */
|
62
|
+
this.valueChange = new EventEmitter();
|
63
|
+
/** Emits when the disabled state has changed */
|
64
|
+
this.disabledChange = new EventEmitter();
|
56
65
|
this.stateChanges = new Subject();
|
66
|
+
this.controlType = 'input-number';
|
67
|
+
this._disabled = false;
|
68
|
+
this.focused = false;
|
69
|
+
this.localeSubscription = Subscription.EMPTY;
|
70
|
+
// tslint:disable-next-line:no-empty
|
71
|
+
this.onTouched = () => { };
|
72
|
+
// tslint:disable-next-line:no-empty
|
73
|
+
this.cvaOnChange = () => { };
|
57
74
|
this.step = isDigit(step) ? parseFloat(step) : SMALL_STEP;
|
58
75
|
this.bigStep = isDigit(bigStep) ? parseFloat(bigStep) : BIG_STEP;
|
59
76
|
this.min = isDigit(min) ? parseFloat(min) : -Infinity;
|
60
77
|
this.max = isDigit(max) ? parseFloat(max) : Infinity;
|
78
|
+
setTimeout(() => this.nativeElement.type = 'text', 0);
|
61
79
|
if ('valueAsNumber' in this.nativeElement) {
|
62
80
|
Object.defineProperty(Object.getPrototypeOf(this.nativeElement), 'valueAsNumber', {
|
63
81
|
// tslint:disable-next-line:no-reserved-keywords
|
@@ -68,9 +86,71 @@ class McNumberInput {
|
|
68
86
|
});
|
69
87
|
}
|
70
88
|
}
|
89
|
+
get value() {
|
90
|
+
return this._value;
|
91
|
+
}
|
92
|
+
set value(value) {
|
93
|
+
const oldValue = this.value;
|
94
|
+
this._value = value;
|
95
|
+
if (oldValue !== value) {
|
96
|
+
this.setViewValue(this.formatNumber(value));
|
97
|
+
this.valueChange.emit(value);
|
98
|
+
}
|
99
|
+
}
|
100
|
+
get disabled() {
|
101
|
+
return this._disabled;
|
102
|
+
}
|
103
|
+
set disabled(value) {
|
104
|
+
const newValue = coerceBooleanProperty(value);
|
105
|
+
const element = this.nativeElement;
|
106
|
+
if (this._disabled !== newValue) {
|
107
|
+
this._disabled = newValue;
|
108
|
+
this.disabledChange.emit(newValue);
|
109
|
+
}
|
110
|
+
// We need to null check the `blur` method, because it's undefined during SSR.
|
111
|
+
if (newValue && element.blur) {
|
112
|
+
// Normally, native input elements automatically blur if they turn disabled. This behavior
|
113
|
+
// is problematic, because it would mean that it triggers another change detection cycle,
|
114
|
+
// which then causes a changed after checked error if the input element was focused before.
|
115
|
+
element.blur();
|
116
|
+
}
|
117
|
+
}
|
71
118
|
get nativeElement() {
|
72
119
|
return this.elementRef.nativeElement;
|
73
120
|
}
|
121
|
+
get viewValue() {
|
122
|
+
return this.nativeElement.value;
|
123
|
+
}
|
124
|
+
get ngControl() {
|
125
|
+
return this.control;
|
126
|
+
}
|
127
|
+
ngOnDestroy() {
|
128
|
+
this.localeSubscription.unsubscribe();
|
129
|
+
this.valueChange.complete();
|
130
|
+
this.disabledChange.complete();
|
131
|
+
}
|
132
|
+
onContainerClick() {
|
133
|
+
this.focus();
|
134
|
+
}
|
135
|
+
focus() {
|
136
|
+
this.nativeElement.focus();
|
137
|
+
}
|
138
|
+
// Implemented as part of ControlValueAccessor.
|
139
|
+
writeValue(value) {
|
140
|
+
this.value = value;
|
141
|
+
}
|
142
|
+
// Implemented as part of ControlValueAccessor.
|
143
|
+
registerOnChange(fn) {
|
144
|
+
this.cvaOnChange = fn;
|
145
|
+
}
|
146
|
+
// Implemented as part of ControlValueAccessor.
|
147
|
+
registerOnTouched(fn) {
|
148
|
+
this.onTouched = fn;
|
149
|
+
}
|
150
|
+
// Implemented as part of ControlValueAccessor.
|
151
|
+
setDisabledState(isDisabled) {
|
152
|
+
this.disabled = isDisabled;
|
153
|
+
}
|
74
154
|
focusChanged(isFocused) {
|
75
155
|
if (isFocused !== this.focused) {
|
76
156
|
this.focused = isFocused;
|
@@ -78,7 +158,6 @@ class McNumberInput {
|
|
78
158
|
}
|
79
159
|
}
|
80
160
|
onKeyDown(event) {
|
81
|
-
var _a;
|
82
161
|
// tslint:disable-next-line:deprecation
|
83
162
|
const keyCode = event.keyCode;
|
84
163
|
const isCtrlA = (e) => e.keyCode === A && (e.ctrlKey || e.metaKey);
|
@@ -86,32 +165,31 @@ class McNumberInput {
|
|
86
165
|
const isCtrlV = (e) => e.keyCode === V && (e.ctrlKey || e.metaKey);
|
87
166
|
const isCtrlX = (e) => e.keyCode === X && (e.ctrlKey || e.metaKey);
|
88
167
|
const isCtrlZ = (e) => e.keyCode === Z && (e.ctrlKey || e.metaKey);
|
89
|
-
const isFKey = (e) => e.keyCode >= F1 && e.keyCode <= F12;
|
90
|
-
const isNumber = (e) => (e.keyCode >= ZERO && e.keyCode <= NINE) ||
|
91
|
-
(e.keyCode >= NUMPAD_ZERO && e.keyCode <= NUMPAD_NINE);
|
92
168
|
const isPeriod = (e) => e.key === '.' || e.key === ',';
|
93
169
|
const minuses = [NUMPAD_MINUS, DASH, FF_MINUS];
|
94
170
|
const serviceKeys = [DELETE, BACKSPACE, TAB, ESCAPE, ENTER];
|
95
171
|
const arrows = [LEFT_ARROW, RIGHT_ARROW];
|
96
172
|
const allowedKeys = [HOME, END].concat(arrows).concat(serviceKeys).concat(minuses);
|
97
173
|
if (minuses.includes(keyCode) &&
|
98
|
-
(this.
|
174
|
+
(this.viewValue.includes(event.key) || this.min >= 0)) {
|
99
175
|
event.preventDefault();
|
100
176
|
return;
|
101
177
|
}
|
102
178
|
if (allowedKeys.indexOf(keyCode) !== -1 ||
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
179
|
+
[
|
180
|
+
isCtrlA,
|
181
|
+
isCtrlC,
|
182
|
+
isCtrlV,
|
183
|
+
isCtrlX,
|
184
|
+
isCtrlZ,
|
185
|
+
isFunctionKey,
|
186
|
+
isPeriod
|
187
|
+
].some((fn) => fn(event))) {
|
110
188
|
// let it happen, don't do anything
|
111
189
|
return;
|
112
190
|
}
|
113
191
|
// Ensure that it is not a number and stop the keypress
|
114
|
-
if (event.shiftKey || !
|
192
|
+
if (event.shiftKey || !isNumberKey(event) && !isNumpadKey(event)) {
|
115
193
|
event.preventDefault();
|
116
194
|
// process steps
|
117
195
|
const step = event.shiftKey ? this.bigStep : this.step;
|
@@ -123,49 +201,124 @@ class McNumberInput {
|
|
123
201
|
}
|
124
202
|
}
|
125
203
|
}
|
204
|
+
onInput(event) {
|
205
|
+
var _a;
|
206
|
+
const currentValueLength = ((_a = this.formatNumber(this.value)) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
207
|
+
setTimeout(() => {
|
208
|
+
const fromPaste = event.inputType === 'insertFromPaste';
|
209
|
+
let formattedValue;
|
210
|
+
if (fromPaste) {
|
211
|
+
formattedValue = this.formatNumber(this.valueFromPaste);
|
212
|
+
}
|
213
|
+
else {
|
214
|
+
/*this.viewValue is raw and should be reformatted to localized number */
|
215
|
+
formattedValue = this.formatViewValue();
|
216
|
+
const offsetWhenSeparatorAdded = 2;
|
217
|
+
Promise.resolve().then(() => {
|
218
|
+
if (Math.abs(this.viewValue.length - currentValueLength) === offsetWhenSeparatorAdded) {
|
219
|
+
const cursorPosition = Math.max(0, (this.nativeElement.selectionStart || 0) + Math.sign(this.viewValue.length - currentValueLength));
|
220
|
+
this.renderer.setProperty(this.nativeElement, 'selectionStart', cursorPosition);
|
221
|
+
this.renderer.setProperty(this.nativeElement, 'selectionEnd', cursorPosition);
|
222
|
+
}
|
223
|
+
});
|
224
|
+
}
|
225
|
+
this.setViewValue(formattedValue, !fromPaste);
|
226
|
+
this.viewToModelUpdate(formattedValue);
|
227
|
+
});
|
228
|
+
}
|
126
229
|
onPaste(event) {
|
127
|
-
|
230
|
+
var _a;
|
231
|
+
this.valueFromPaste = this.checkAndNormalizeLocalizedNumber((_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text'));
|
232
|
+
if (this.valueFromPaste === null) {
|
128
233
|
event.preventDefault();
|
129
234
|
}
|
130
235
|
}
|
131
236
|
stepUp(step) {
|
132
|
-
this.
|
133
|
-
const res = Math.max(Math.min(add(this.
|
134
|
-
this.
|
135
|
-
this.
|
237
|
+
this.nativeElement.focus();
|
238
|
+
const res = Math.max(Math.min(add(this.value || 0, step), this.max), this.min);
|
239
|
+
this.setViewValue(this.formatNumber(res));
|
240
|
+
this._value = res;
|
241
|
+
this.cvaOnChange(res);
|
242
|
+
this.valueChange.emit(res);
|
136
243
|
}
|
137
244
|
stepDown(step) {
|
138
|
-
this.
|
139
|
-
const res = Math.min(Math.max(add(this.
|
140
|
-
this.
|
141
|
-
this.
|
245
|
+
this.nativeElement.focus();
|
246
|
+
const res = Math.min(Math.max(add(this.value || 0, -step), this.min), this.max);
|
247
|
+
this.setViewValue(this.formatNumber(res));
|
248
|
+
this._value = res;
|
249
|
+
this.cvaOnChange(res);
|
250
|
+
this.valueChange.emit(res);
|
251
|
+
}
|
252
|
+
setViewValue(value, savePosition = false) {
|
253
|
+
const cursorPosition = this.nativeElement.selectionStart;
|
254
|
+
this.renderer.setProperty(this.nativeElement, 'value', value);
|
255
|
+
if (savePosition) {
|
256
|
+
this.renderer.setProperty(this.nativeElement, 'selectionStart', cursorPosition);
|
257
|
+
this.renderer.setProperty(this.nativeElement, 'selectionEnd', cursorPosition);
|
258
|
+
}
|
142
259
|
}
|
143
|
-
viewToModelUpdate(
|
144
|
-
|
145
|
-
|
260
|
+
viewToModelUpdate(newValue) {
|
261
|
+
var _a;
|
262
|
+
const normalizedValue = newValue === null ? null : +this.normalizeNumber(newValue);
|
263
|
+
if (normalizedValue !== this.value) {
|
264
|
+
this._value = normalizedValue;
|
265
|
+
this.cvaOnChange(normalizedValue);
|
266
|
+
this.valueChange.emit(normalizedValue);
|
267
|
+
}
|
268
|
+
(_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.updateValueAndValidity({ emitEvent: false });
|
269
|
+
}
|
270
|
+
formatViewValue() {
|
271
|
+
if (this.viewValue === null || this.viewValue === '' || Number.isNaN(+this.normalizeNumber(this.viewValue))) {
|
272
|
+
return null;
|
273
|
+
}
|
274
|
+
return this.viewValue;
|
275
|
+
}
|
276
|
+
formatNumber(value) {
|
277
|
+
if (value === null || value === undefined) {
|
278
|
+
return null;
|
146
279
|
}
|
280
|
+
return value.toString();
|
281
|
+
}
|
282
|
+
/**
|
283
|
+
* Method that returns a string representation of a number without localized separators
|
284
|
+
*/
|
285
|
+
normalizeNumber(value, _) {
|
286
|
+
if (value === null || value === undefined) {
|
287
|
+
return '';
|
288
|
+
}
|
289
|
+
return value.toString();
|
290
|
+
}
|
291
|
+
checkAndNormalizeLocalizedNumber(num) {
|
292
|
+
if (num === null || num === undefined) {
|
293
|
+
return null;
|
294
|
+
}
|
295
|
+
/* if some locale input config satisfies pasted number, try to normalise with selected locale config */
|
296
|
+
let numberOutput = null;
|
297
|
+
const normalized = +this.normalizeNumber(num);
|
298
|
+
if (!Number.isNaN(normalized)) {
|
299
|
+
numberOutput = normalized;
|
300
|
+
}
|
301
|
+
return numberOutput;
|
147
302
|
}
|
148
303
|
}
|
149
|
-
/** @nocollapse */ McNumberInput.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: McNumberInput, deps: [{ token: i0.ElementRef }, { token:
|
150
|
-
/** @nocollapse */ McNumberInput.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: McNumberInput, selector: "input[mcInput][type=\"number\"]", inputs: { bigStep: "bigStep", step: "step", min: "min", max: "max" }, host: { listeners: { "blur": "focusChanged(false)", "focus": "focusChanged(true)", "paste": "onPaste($event)", "keydown": "onKeyDown($event)" } }, exportAs: ["mcNumericalInput"], ngImport: i0 });
|
304
|
+
/** @nocollapse */ McNumberInput.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: McNumberInput, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: 'step', attribute: true }, { token: 'big-step', attribute: true }, { token: 'min', attribute: true }, { token: 'max', attribute: true }], target: i0.ɵɵFactoryTarget.Directive });
|
305
|
+
/** @nocollapse */ McNumberInput.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: McNumberInput, selector: "input[mcInput][type=\"number\"]", inputs: { bigStep: "bigStep", step: "step", min: "min", max: "max", value: "value", disabled: "disabled" }, host: { listeners: { "blur": "focusChanged(false)", "focus": "focusChanged(true)", "paste": "onPaste($event)", "keydown": "onKeyDown($event)", "input": "onInput($event)" } }, providers: [MC_NUMBER_INPUT_VALUE_ACCESSOR], exportAs: ["mcNumericalInput"], ngImport: i0 });
|
151
306
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: McNumberInput, decorators: [{
|
152
307
|
type: Directive,
|
153
308
|
args: [{
|
154
309
|
selector: `input[mcInput][type="number"]`,
|
155
310
|
exportAs: 'mcNumericalInput',
|
311
|
+
providers: [MC_NUMBER_INPUT_VALUE_ACCESSOR],
|
156
312
|
host: {
|
157
313
|
'(blur)': 'focusChanged(false)',
|
158
314
|
'(focus)': 'focusChanged(true)',
|
159
315
|
'(paste)': 'onPaste($event)',
|
160
|
-
'(keydown)': 'onKeyDown($event)'
|
316
|
+
'(keydown)': 'onKeyDown($event)',
|
317
|
+
'(input)': 'onInput($event)'
|
161
318
|
}
|
162
319
|
}]
|
163
320
|
}], ctorParameters: function () {
|
164
|
-
return [{ type: i0.ElementRef }, { type:
|
165
|
-
type: Optional
|
166
|
-
}, {
|
167
|
-
type: Self
|
168
|
-
}] }, { type: undefined, decorators: [{
|
321
|
+
return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: undefined, decorators: [{
|
169
322
|
type: Attribute,
|
170
323
|
args: ['step']
|
171
324
|
}] }, { type: undefined, decorators: [{
|
@@ -186,6 +339,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
186
339
|
type: Input
|
187
340
|
}], max: [{
|
188
341
|
type: Input
|
342
|
+
}], value: [{
|
343
|
+
type: Input
|
344
|
+
}], disabled: [{
|
345
|
+
type: Input
|
189
346
|
}] } });
|
190
347
|
|
191
348
|
const MC_INPUT_INVALID_TYPES = [
|
@@ -947,5 +1104,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
947
1104
|
* Generated bundle index. Do not edit.
|
948
1105
|
*/
|
949
1106
|
|
950
|
-
export { BIG_STEP, MAX_VALIDATOR, MC_INPUT_VALUE_ACCESSOR, MIN_VALIDATOR, MaxValidator, McInput, McInputBase, McInputMixinBase, McInputModule, McInputMono, McInputPassword, McNumberInput, McPasswordToggle, MinValidator, SMALL_STEP, add, getPrecision, isDigit, isFloat, isInt, normalizeSplitter };
|
1107
|
+
export { BIG_STEP, MAX_VALIDATOR, MC_INPUT_VALUE_ACCESSOR, MC_NUMBER_INPUT_VALUE_ACCESSOR, MIN_VALIDATOR, MaxValidator, McInput, McInputBase, McInputMixinBase, McInputModule, McInputMono, McInputPassword, McNumberInput, McPasswordToggle, MinValidator, SMALL_STEP, add, getPrecision, isDigit, isFloat, isInt, normalizeSplitter };
|
951
1108
|
//# sourceMappingURL=ptsecurity-mosaic-input.mjs.map
|