@progress/kendo-angular-dateinputs 14.0.0-develop.8 → 14.0.0-develop.9

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.
@@ -8,18 +8,19 @@ import { maxValidator } from '../validators/max.validator';
8
8
  import { incompleteDateValidator } from '../validators/incomplete-date.validator';
9
9
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS, NgControl } from '@angular/forms';
10
10
  import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
11
- import { IntlService } from '@progress/kendo-angular-intl';
11
+ import { IntlService, localeData } from '@progress/kendo-angular-intl';
12
12
  import { validatePackage } from '@progress/kendo-licensing';
13
13
  import { packageMetadata } from '../package-metadata';
14
- import { addMonths, cloneDate, createDate, getDate, isEqual, lastDayOfMonth } from '@progress/kendo-date-math';
15
- import { isDocumentAvailable, hasObservers, KendoInput, Keys } from '@progress/kendo-angular-common';
14
+ import { cloneDate, isEqual } from '@progress/kendo-date-math';
15
+ import { hasObservers, KendoInput } from '@progress/kendo-angular-common';
16
16
  import { Arrow } from './arrow.enum';
17
- import { approximateStringMatching, noop, isInRange, dateInRange, isValidRange, setTime, cropTwoDigitYear, setYears, msPaddingFromFormat, millisecondDigitsInFormat, millisecondStepFor, getSizeClass, getRoundedClass, getFillModeClass, DEFAULT_FILL_MODE, DEFAULT_ROUNDED, DEFAULT_SIZE } from '../util';
17
+ import { noop, isValidRange, getSizeClass, getRoundedClass, getFillModeClass, DEFAULT_FILL_MODE, DEFAULT_ROUNDED, DEFAULT_SIZE } from '../util';
18
18
  import { PickerService } from '../common/picker.service';
19
19
  import { closest } from '../common/dom-queries';
20
20
  import { requiresZoneOnBlur, isPresent, attributeNames } from '../common/utils';
21
21
  import { Subscription } from 'rxjs';
22
22
  import { caretAltDownIcon, caretAltUpIcon } from '@progress/kendo-svg-icons';
23
+ import { DateInput } from '@progress/kendo-dateinputs-common';
23
24
  import * as i0 from "@angular/core";
24
25
  import * as i1 from "@progress/kendo-angular-intl";
25
26
  import * as i2 from "@progress/kendo-angular-l10n";
@@ -32,424 +33,37 @@ let nextId = 0;
32
33
  const MIN_DOC_LINK = 'http://www.telerik.com/kendo-angular-ui/components/dateinputs/api/DateInputComponent/#toc-min';
33
34
  const MAX_DOC_LINK = 'http://www.telerik.com/kendo-angular-ui/components/dateinputs/api/DateInputComponent/#toc-max';
34
35
  const VALUE_DOC_LINK = 'http://www.telerik.com/kendo-angular-ui/components/dateinputs/dateinput/#toc-using-with-json';
35
- const DATE_PART_REGEXP = /year|month|<day>/;
36
- const TIME_PART_REGEXP = /hour|minute|second|millisecond/;
37
- const SHORT_PATTERN_LENGTH_REGEXP = /d|M|H|h|m|s/;
38
36
  const TWO_DIGIT_YEAR_MAX = 68;
39
- const PREVIOUS_CENTURY_BASE = 1900;
40
- const CURRENT_CENTURY_BASE = 2000;
41
37
  const DEFAULT_FORMAT = 'd';
42
- const padZero = (length) => new Array(Math.max(length, 0)).fill('0').join('');
43
- const unpadZero = (value) => value.replace(/^0*/, '');
44
- class Mask {
45
- constructor() {
46
- this.symbols = "";
47
- }
48
- }
49
- class KendoDate {
50
- constructor(intl, formatPlaceholder, format, value, twoDigitYearMax = TWO_DIGIT_YEAR_MAX) {
51
- this.intl = intl;
52
- this.formatPlaceholder = formatPlaceholder;
53
- this.format = format;
54
- this.twoDigitYearMax = twoDigitYearMax;
55
- this.year = true;
56
- this.month = true;
57
- this.date = true;
58
- this.hours = true;
59
- this.minutes = true;
60
- this.seconds = true;
61
- this.milliseconds = true;
62
- this.leadingZero = null;
63
- this.monthNames = null;
64
- this.typedMonthPart = "";
65
- this.value = getDate(new Date());
66
- this.knownParts = "adHhmMsSEy";
67
- this.symbols = {
68
- "E": "E",
69
- "H": "H",
70
- "M": "M",
71
- "a": "a",
72
- "d": "d",
73
- "h": "h",
74
- "m": "m",
75
- "s": "s",
76
- "S": "S",
77
- "y": "y"
78
- };
79
- validatePackage(packageMetadata);
80
- this.monthNames = this.allFormatedMonths();
81
- this.dayPeriods = this.allDayPeriods();
82
- if (!value) {
83
- this.value = getDate(new Date());
84
- const sampleFormat = this.dateFormatString(this.value, this.format).symbols;
85
- for (let i = 0; i < sampleFormat.length; i++) {
86
- this.setExisting(sampleFormat[i], false);
87
- }
88
- }
89
- else {
90
- this.value = cloneDate(value);
91
- }
92
- }
93
- hasValue() {
94
- const pred = (a, p) => a || p.type !== 'literal' && p.type !== 'dayperiod' && this.getExisting(p.pattern[0]);
95
- return this.intl.splitDateFormat(this.format).reduce(pred, false);
96
- }
97
- shouldNormalizeCentury() {
98
- return this.intl.splitDateFormat(this.format).some(part => part.pattern === 'yy');
99
- }
100
- getDateObject() {
101
- for (let i = 0; i < this.knownParts.length; i++) {
102
- if (!this.getExisting(this.knownParts[i])) {
103
- return null;
104
- }
105
- }
106
- return cloneDate(this.value);
107
- }
108
- getTextAndFormat(format) {
109
- return this.merge(this.intl.formatDate(this.value, format), this.dateFormatString(this.value, format));
110
- }
111
- getExisting(symbol) {
112
- switch (symbol) {
113
- case "y": return this.year;
114
- case "M":
115
- case "L": return this.month;
116
- case "d": return this.date;
117
- case "E": return this.date && this.month && this.year;
118
- case "h":
119
- case "H": return this.hours;
120
- case "m": return this.minutes;
121
- case "s": return this.seconds;
122
- case "S": return this.milliseconds;
123
- default: return true;
124
- }
125
- }
126
- setExisting(symbol, value) {
127
- switch (symbol) {
128
- case "y":
129
- this.year = value;
130
- if (value === false) {
131
- this.value.setFullYear(2000);
132
- }
133
- break; //allow 2/29 dates
134
- case "M":
135
- this.month = value;
136
- if (value === false) {
137
- this.value.setMonth(0);
138
- }
139
- break; //make sure you can type 31 at day part
140
- case "d":
141
- this.date = value;
142
- break;
143
- case "h":
144
- case "H":
145
- this.hours = value;
146
- break;
147
- case "m":
148
- this.minutes = value;
149
- break;
150
- case "s":
151
- this.seconds = value;
152
- break;
153
- case "S":
154
- this.milliseconds = value;
155
- break;
156
- default: return;
157
- }
158
- }
159
- modifyPart(symbol, offset) {
160
- let newValue = cloneDate(this.value);
161
- switch (symbol) {
162
- case "y":
163
- newValue.setFullYear(newValue.getFullYear() + offset);
164
- break;
165
- case "M":
166
- newValue = addMonths(this.value, offset);
167
- break;
168
- case "d":
169
- case "E":
170
- newValue.setDate(newValue.getDate() + offset);
171
- break;
172
- case "h":
173
- case "H":
174
- newValue.setHours(newValue.getHours() + offset);
175
- break;
176
- case "m":
177
- newValue.setMinutes(newValue.getMinutes() + offset);
178
- break;
179
- case "s":
180
- newValue.setSeconds(newValue.getSeconds() + offset);
181
- break;
182
- case "S":
183
- newValue.setMilliseconds(newValue.getMilliseconds() + offset);
184
- break;
185
- case "a":
186
- newValue.setHours(newValue.getHours() + (12 * offset));
187
- break;
188
- default: break;
189
- }
190
- if (this.shouldNormalizeCentury()) {
191
- newValue = this.normalizeCentury(newValue);
192
- }
193
- if (newValue.getFullYear() > 0) {
194
- this.setExisting(symbol, true);
195
- this.value = newValue;
196
- }
197
- }
198
- parsePart(symbol, currentChar, resetSegmentValue) {
199
- if (!currentChar) {
200
- this.resetLeadingZero();
201
- this.setExisting(symbol, false);
202
- return { value: null, switchToNext: false };
203
- }
204
- const baseDate = this.intl.formatDate(this.value, this.format);
205
- const dateParts = this.dateFormatString(this.value, this.format);
206
- const baseFormat = dateParts.symbols;
207
- let replaced = false;
208
- let prefix = "";
209
- let current = "";
210
- let suffix = "";
211
- for (let i = 0; i < baseDate.length; i++) {
212
- if (baseFormat[i] === symbol) {
213
- current += this.getExisting(symbol) ? baseDate[i] : "0";
214
- replaced = true;
215
- }
216
- else if (!replaced) {
217
- prefix += baseDate[i];
218
- }
219
- else {
220
- suffix += baseDate[i];
221
- }
222
- }
223
- const currentMaxLength = current.length - 3;
224
- let parsedDate = null;
225
- const month = this.matchMonth(currentChar);
226
- const dayPeriod = this.matchDayPeriod(currentChar, symbol);
227
- const isZeroCurrentChar = currentChar === '0';
228
- const leadingZero = (this.leadingZero || {})[symbol] || 0;
229
- if (isZeroCurrentChar) {
230
- const valueNumber = parseInt(resetSegmentValue ? currentChar : current + currentChar, 10);
231
- if (valueNumber === 0 && !this.isAbbrMonth(dateParts.partMap, symbol)) {
232
- this.incrementLeadingZero(symbol);
233
- }
234
- }
235
- else {
236
- this.resetLeadingZero();
237
- }
238
- for (let i = Math.max(0, currentMaxLength); i <= current.length; i++) {
239
- let middle = resetSegmentValue ? currentChar : (current.substring(i) + currentChar);
240
- if (symbol === "S" && resetSegmentValue) {
241
- // The "S" parser in intl parses "1" as 100ms in order to handle ISOString dates correctly, so to get 1ms, we need to pass "001"
242
- const padding = msPaddingFromFormat(baseFormat);
243
- middle = padding + middle;
244
- }
245
- const middleNumber = parseInt(middle, 10);
246
- parsedDate = this.intl.parseDate(prefix + middle + suffix, this.format);
247
- if (!parsedDate && !isNaN(middleNumber) && !isNaN(parseInt(currentChar, 10))) {
248
- if (symbol === 'M' && !month) {
249
- const monthNumber = middleNumber - 1;
250
- if (monthNumber > -1 && monthNumber < 12) {
251
- parsedDate = cloneDate(this.value);
252
- parsedDate.setMonth(monthNumber);
253
- if (parsedDate.getMonth() !== monthNumber) {
254
- parsedDate = lastDayOfMonth(addMonths(parsedDate, -1));
255
- }
256
- }
257
- }
258
- if (symbol === 'y') {
259
- parsedDate = createDate(parseInt(middle, 10), this.month ? this.value.getMonth() : 0, this.date ? this.value.getDate() : 1, this.hours ? this.value.getHours() : 0, this.minutes ? this.value.getMinutes() : 0, this.seconds ? this.value.getSeconds() : 0, this.milliseconds ? this.value.getMilliseconds() : 0);
260
- if (this.date && parsedDate.getDate() !== this.value.getDate()) {
261
- parsedDate = lastDayOfMonth(addMonths(parsedDate, -1));
262
- }
263
- }
264
- }
265
- if (parsedDate) {
266
- //move to next segment if the part will overflow with next char
267
- //when start from empty date (01, then 010), padded zeros should be trimmed
268
- const patternValue = this.partPattern(dateParts.partMap, symbol).pattern;
269
- const peekDate = this.intl.parseDate(`${prefix}${this.peek(middle, patternValue)}${suffix}`, this.format);
270
- const patternLength = this.patternLength(patternValue) || patternValue.length;
271
- const patternSatisfied = (leadingZero + (unpadZero(middle) || currentChar).length) >= patternLength;
272
- const switchToNext = peekDate === null || patternSatisfied;
273
- if (this.shouldNormalizeCentury()) {
274
- parsedDate = this.normalizeCentury(parsedDate);
275
- }
276
- this.value = parsedDate;
277
- this.setExisting(symbol, true);
278
- return { value: this.value, switchToNext: switchToNext };
279
- }
280
- }
281
- if (month) {
282
- parsedDate = this.intl.parseDate(prefix + month + suffix, this.format);
283
- if (parsedDate) {
284
- this.value = parsedDate;
285
- this.setExisting(symbol, true);
286
- return { value: this.value, switchToNext: false };
287
- }
288
- }
289
- if (dayPeriod) {
290
- parsedDate = this.intl.parseDate(prefix + dayPeriod + suffix, this.format);
291
- if (parsedDate) {
292
- this.value = parsedDate;
293
- return { value: this.value, switchToNext: true };
294
- }
295
- }
296
- if (isZeroCurrentChar) {
297
- this.setExisting(symbol, false);
298
- }
299
- return { value: null, switchToNext: false };
300
- }
301
- resetLeadingZero() {
302
- const hasLeadingZero = this.leadingZero !== null;
303
- this.setLeadingZero(null);
304
- return hasLeadingZero;
305
- }
306
- setLeadingZero(leadingZero) {
307
- this.leadingZero = leadingZero;
308
- }
309
- normalizeCentury(date) {
310
- if (!isPresent(date)) {
311
- return date;
312
- }
313
- const twoDigitYear = cropTwoDigitYear(date);
314
- const centuryBase = this.getNormalizedCenturyBase(twoDigitYear);
315
- const normalizedDate = setYears(date, centuryBase + twoDigitYear);
316
- return normalizedDate;
317
- }
318
- incrementLeadingZero(symbol) {
319
- const leadingZero = this.leadingZero || {};
320
- leadingZero[symbol] = (leadingZero[symbol] || 0) + 1;
321
- this.leadingZero = leadingZero;
322
- }
323
- isAbbrMonth(parts, symbol) {
324
- const pattern = this.partPattern(parts, symbol);
325
- return pattern.type === 'month' && pattern.names;
326
- }
327
- partPattern(parts, symbol) {
328
- return parts.filter((part) => part.pattern.indexOf(symbol) !== -1)[0];
329
- }
330
- peek(value, pattern) {
331
- const peekValue = unpadZero(value) + '0';
332
- return padZero(pattern.length - peekValue.length) + peekValue;
333
- }
334
- matchMonth(typedChar) {
335
- this.typedMonthPart += typedChar.toLowerCase();
336
- if (!this.monthNames) {
337
- return "";
338
- }
339
- while (this.typedMonthPart.length > 0) {
340
- for (let i = 0; i < this.monthNames.length; i++) {
341
- if (this.monthNames[i].toLowerCase().indexOf(this.typedMonthPart) === 0) {
342
- return this.monthNames[i];
343
- }
344
- }
345
- const monthAsNum = parseInt(this.typedMonthPart, 10);
346
- if (monthAsNum >= 1 && monthAsNum <= 12 && monthAsNum.toString() === this.typedMonthPart /*ensure they exact match*/) {
347
- return this.monthNames[monthAsNum - 1];
348
- }
349
- this.typedMonthPart = this.typedMonthPart.substring(1, this.typedMonthPart.length);
350
- }
351
- return "";
352
- }
353
- matchDayPeriod(typedChar, symbol) {
354
- const lowerChart = String(typedChar).toLowerCase();
355
- if (symbol === 'a' && this.dayPeriods) {
356
- if (this.dayPeriods.am.toLowerCase().startsWith(lowerChart)) {
357
- return this.dayPeriods.am;
358
- }
359
- else if (this.dayPeriods.pm.toLowerCase().startsWith(lowerChart)) {
360
- return this.dayPeriods.pm;
361
- }
362
- }
363
- return '';
364
- }
365
- allFormatedMonths() {
366
- const dateFormatParts = this.intl.splitDateFormat(this.format);
367
- for (let i = 0; i < dateFormatParts.length; i++) {
368
- if (dateFormatParts[i].type === "month" && dateFormatParts[i].names) {
369
- return this.intl.dateFormatNames(dateFormatParts[i].names);
370
- }
371
- }
372
- return null;
373
- }
374
- allDayPeriods() {
375
- const dateFormatParts = this.intl.splitDateFormat(this.format);
376
- for (let i = 0; i < dateFormatParts.length; i++) {
377
- if (dateFormatParts[i].type === "dayperiod" && dateFormatParts[i].names) {
378
- return this.intl.dateFormatNames(dateFormatParts[i].names);
379
- }
380
- }
381
- return null;
382
- }
383
- patternLength(pattern) {
384
- if (pattern[0] === 'y') {
385
- return 4;
386
- }
387
- if (SHORT_PATTERN_LENGTH_REGEXP.test(pattern)) {
388
- return 2;
389
- }
390
- return 0;
391
- }
392
- //TODO: REMOVE!
393
- dateFormatString(date, format) {
394
- const dateFormatParts = this.intl.splitDateFormat(format);
395
- const parts = [];
396
- const partMap = [];
397
- for (let i = 0; i < dateFormatParts.length; i++) {
398
- let partLength = this.intl.formatDate(date, { pattern: dateFormatParts[i].pattern }).length;
399
- while (partLength > 0) {
400
- parts.push(this.symbols[dateFormatParts[i].pattern[0]] || "_");
401
- partMap.push(dateFormatParts[i]);
402
- partLength--;
403
- }
404
- }
405
- const returnValue = new Mask();
406
- returnValue.symbols = parts.join("");
407
- returnValue.partMap = partMap;
408
- return returnValue;
409
- }
410
- merge(text, mask) {
411
- // Important: right to left.
412
- let resultText = "";
413
- let resultFormat = "";
414
- const format = mask.symbols;
415
- for (let r = format.length - 1; r >= 0; r--) {
416
- if (this.knownParts.indexOf(format[r]) === -1 || this.getExisting(format[r])) {
417
- resultText = text[r] + resultText;
418
- resultFormat = format[r] + resultFormat;
419
- }
420
- else {
421
- const currentSymbol = format[r];
422
- while (r >= 0 && currentSymbol === format[r]) {
423
- r--;
424
- }
425
- r++;
426
- if (this.leadingZero && this.leadingZero[currentSymbol]) {
427
- resultText = '0' + resultText;
428
- }
429
- else {
430
- resultText = this.dateFieldName(mask.partMap[r]) + resultText;
431
- }
432
- while (resultFormat.length < resultText.length) {
433
- resultFormat = format[r] + resultFormat;
434
- }
435
- }
436
- }
437
- return [resultText, resultFormat];
438
- }
439
- dateFieldName(part) {
440
- const formatPlaceholder = this.formatPlaceholder || 'wide';
441
- if (formatPlaceholder[part.type]) {
442
- return formatPlaceholder[part.type];
443
- }
444
- if (formatPlaceholder === 'formatPattern') {
445
- return part.pattern;
446
- }
447
- return this.intl.dateFieldName(Object.assign(part, { nameType: formatPlaceholder }));
448
- }
449
- getNormalizedCenturyBase(twoDigitYear) {
450
- return twoDigitYear > this.twoDigitYearMax ?
451
- PREVIOUS_CENTURY_BASE :
452
- CURRENT_CENTURY_BASE;
38
+ const DEFAULT_FORMAT_PLACEHOLDER = 'wide';
39
+ const DATE_PART_REGEXP = /year|month|<day>/;
40
+ const TIME_PART_REGEXP = /hour|minute|second|millisecond/;
41
+ /**
42
+ * @hidden
43
+ * Need to overrite `dateFormatNames` parameters order and provide `cldr` object
44
+ * required by the kendo-dateinputs-common package
45
+ */
46
+ export class DateInputIntl {
47
+ constructor(service) {
48
+ this.service = service;
49
+ this.cldr = {};
50
+ this.localeId = service['localeId'];
51
+ this.format = service.format;
52
+ this.toString = service.toString;
53
+ this.formatDate = service.formatDate;
54
+ this.parseDate = service.parseDate;
55
+ this.parseNumber = service.parseNumber;
56
+ this.formatNumber = service.formatNumber;
57
+ this.splitDateFormat = service.splitDateFormat;
58
+ this.numberSymbols = service.numberSymbols;
59
+ this.firstDay = service.firstDay;
60
+ this.weekendRange = service.weekendRange;
61
+ this.dateFieldName = service.dateFieldName;
62
+ this.dateFormatNames = (localeId, options) => this.service.dateFormatNames(options, localeId || this.localeId);
63
+ const _localeData = localeData(this.localeId);
64
+ // Setting the `cldr` object from here could be avoided if the logic in the common package is revisited to
65
+ // directly relies on the `localeId` being set as part of the options => TBD and validated for all suites
66
+ this.cldr[_localeData.name] = _localeData;
453
67
  }
454
68
  }
455
69
  /**
@@ -545,16 +159,50 @@ export class DateInputComponent {
545
159
  * }
546
160
  * ```
547
161
  */
548
- this.steps = {};
162
+ this.steps = {
163
+ // Default values are needed until fix in common package: https://github.com/telerik/kendo-dateinputs-common/issues/26
164
+ second: 1,
165
+ minute: 1,
166
+ hour: 1,
167
+ day: 1,
168
+ month: 1,
169
+ year: 1
170
+ };
549
171
  /**
550
172
  * Determines whether the built-in min or max validators are to be enforced when a form is being validated.
551
173
  */
552
174
  this.rangeValidation = true;
553
175
  /**
554
176
  * @hidden
555
- * Based on the min and max values, specifies whether the value will be auto-corrected while typing.
177
+ *
178
+ * Determines whether to auto correct invalid segments automatically.
179
+ * TODO: To be fixed in common package before enabling: https://github.com/telerik/kendo-dateinputs-common/issues/24
180
+ *
181
+ * @default true
182
+ */
183
+ this.autoCorrectParts = true;
184
+ /**
185
+ * Determines whether to automatically move to the next segment after the user completes the current one.
186
+ *
187
+ * @default true
188
+ */
189
+ this.autoSwitchParts = true;
190
+ /**
191
+ * A string array representing custom keys, which will move the focus to the next date format segment.
192
+ */
193
+ this.autoSwitchKeys = [];
194
+ /**
195
+ * Determines if the users should see a blinking caret inside the Date Input when possible.
196
+ *
197
+ * @default false
198
+ */
199
+ this.allowCaretMode = false;
200
+ /**
201
+ * When enabled, the DateInput will autofill the rest of the date to the current date when the component loses focus.
202
+ *
203
+ * @default false
556
204
  */
557
- this.autoCorrect = false;
205
+ this.autoFill = false;
558
206
  /**
559
207
  * Determines whether the built-in validation for incomplete dates is to be enforced when a form is being validated.
560
208
  */
@@ -567,6 +215,12 @@ export class DateInputComponent {
567
215
  * will be assumed to be 20xx, while 69 and larger will be assumed to be 19xx.
568
216
  */
569
217
  this.twoDigitYearMax = TWO_DIGIT_YEAR_MAX;
218
+ /**
219
+ * Indicates whether the mouse scroll can be used to increase/decrease the time segments values.
220
+ *
221
+ * @default true
222
+ */
223
+ this.enableMouseWheel = true;
570
224
  /**
571
225
  * Specifies whether the **Up** and **Down** spin buttons will be rendered.
572
226
  * For more information, refer to the article on
@@ -643,18 +297,16 @@ export class DateInputComponent {
643
297
  * @hidden
644
298
  */
645
299
  this.isDateIncomplete = false;
646
- this.currentValue = "";
647
300
  this.currentFormat = "";
648
- this.backspace = false;
649
- this.resetSegmentValue = true;
650
301
  this.minValidator = noop;
651
302
  this.maxValidator = noop;
652
303
  this.incompleteValidator = noop;
653
304
  this._value = null;
654
305
  this._active = false;
655
306
  this._focusableId = `dateinput-${nextId++}`;
307
+ this._formatPlaceholder = DEFAULT_FORMAT_PLACEHOLDER;
656
308
  this.kendoDate = null;
657
- this.paste = false;
309
+ this.kendoDateObject = null;
658
310
  this.domEvents = [];
659
311
  this.onControlChange = noop;
660
312
  this.onControlTouched = noop;
@@ -663,8 +315,7 @@ export class DateInputComponent {
663
315
  this._rounded = DEFAULT_ROUNDED;
664
316
  this._fillMode = DEFAULT_FILL_MODE;
665
317
  this.subs = new Subscription();
666
- this.symbolsMap = this.dateSymbolMap();
667
- this.updateFormatSections();
318
+ validatePackage(packageMetadata);
668
319
  if (this.pickerService) {
669
320
  this.pickerService.input = this;
670
321
  }
@@ -701,6 +352,58 @@ export class DateInputComponent {
701
352
  get tabIndex() {
702
353
  return this.tabindex;
703
354
  }
355
+ /**
356
+ * Defines the descriptions of the format sections in the input field.
357
+ * For more information, refer to the article on
358
+ * [placeholders]({% slug placeholders_dateinput %}).
359
+ *
360
+ * @example
361
+ * ```ts
362
+ * _@Component({
363
+ * selector: 'my-app',
364
+ * template: `
365
+ * <div class="row example-wrapper" [style.min-height.px]="450">
366
+ * <div class="col-xs-12 col-md-6 example-col">
367
+ * <p>Full-length format description:</p>
368
+ * <kendo-dateinput formatPlaceholder="wide"></kendo-dateinput>
369
+ * </div>
370
+ *
371
+ * <div class="col-xs-12 col-md-6 example-col">
372
+ * <p>Narrow-length format description:</p>
373
+ * <kendo-dateinput formatPlaceholder="narrow"></kendo-dateinput>
374
+ * </div>
375
+ *
376
+ * <div class="col-xs-12 col-md-6 example-col">
377
+ * <p>Short-length format description:</p>
378
+ * <kendo-dateinput formatPlaceholder="short"></kendo-dateinput>
379
+ * </div>
380
+ *
381
+ * <div class="col-xs-12 col-md-6 example-col">
382
+ * <p>Display defined format:</p>
383
+ * <kendo-dateinput format="MM/dd/yyyy" formatPlaceholder="formatPattern"></kendo-dateinput>
384
+ * </div>
385
+ *
386
+ * <div class="col-xs-12 col-md-6 example-col">
387
+ * <p>Custom defined format descriptions</p>
388
+ * <kendo-dateinput format="G"
389
+ * [formatPlaceholder]="{
390
+ * year: 'y', month: 'M', day: 'd',
391
+ * hour: 'h', minute: 'm', second: 's'
392
+ * }"
393
+ * ></kendo-dateinput>
394
+ * </div>
395
+ * </div>
396
+ * `
397
+ * })
398
+ * export class AppComponent { }
399
+ * ```
400
+ */
401
+ set formatPlaceholder(format) {
402
+ this._formatPlaceholder = format ? format : DEFAULT_FORMAT_PLACEHOLDER;
403
+ }
404
+ get formatPlaceholder() {
405
+ return this._formatPlaceholder;
406
+ }
704
407
  /**
705
408
  * Specifies the value of the DateInput component.
706
409
  *
@@ -708,9 +411,6 @@ export class DateInputComponent {
708
411
  */
709
412
  set value(value) {
710
413
  this.verifyValue(value);
711
- if (this.autoCorrect && !isInRange(value, this.min, this.max)) {
712
- return;
713
- }
714
414
  this._value = cloneDate(value);
715
415
  this.valueUpdate.emit(cloneDate(value));
716
416
  }
@@ -822,34 +522,39 @@ export class DateInputComponent {
822
522
  const ngControl = this.injector.get(NgControl, null);
823
523
  return ngControl?.control || null;
824
524
  }
825
- get inputFormat() {
826
- if (!this.format) {
827
- return DEFAULT_FORMAT;
828
- }
829
- if (typeof this.format === 'string') {
830
- return this.format;
831
- }
832
- else {
833
- return this.format.inputFormat;
834
- }
835
- }
836
- get displayFormat() {
837
- if (!this.format) {
838
- return DEFAULT_FORMAT;
839
- }
840
- if (typeof this.format === 'string') {
841
- return this.format;
842
- }
843
- else {
844
- return this.format.displayFormat;
845
- }
525
+ get options() {
526
+ return {
527
+ format: this.format,
528
+ steps: this.steps,
529
+ readonly: this.readonly,
530
+ formatPlaceholder: this.formatPlaceholder,
531
+ placeholder: this.placeholder,
532
+ autoCorrectParts: this.autoCorrectParts,
533
+ autoSwitchParts: this.autoSwitchParts,
534
+ selectPreviousSegmentOnBackspace: true,
535
+ autoSwitchKeys: this.autoSwitchKeys,
536
+ twoDigitYearMax: this.twoDigitYearMax,
537
+ enableMouseWheel: this.enableMouseWheel,
538
+ selectNearestSegmentOnFocus: false,
539
+ allowCaretMode: this.allowCaretMode,
540
+ autoFill: this.autoFill,
541
+ value: this.value,
542
+ intlService: new DateInputIntl(this.intl)
543
+ };
846
544
  }
847
545
  /**
848
546
  * @hidden
849
547
  * Used by the TextBoxContainer to determine if the component is empty
850
548
  */
851
549
  isEmpty() {
852
- return !this.currentValue || !String(this.currentValue).trim();
550
+ const currentValue = this.dateInput.nativeElement.value;
551
+ return !currentValue || !String(currentValue).trim();
552
+ }
553
+ /**
554
+ * @hidden
555
+ */
556
+ handleDragAndDrop(args) {
557
+ args.preventDefault();
853
558
  }
854
559
  /**
855
560
  * @hidden
@@ -861,15 +566,16 @@ export class DateInputComponent {
861
566
  * @hidden
862
567
  */
863
568
  ngOnInit() {
864
- this.kendoDate = this.getKendoDate(this.value);
865
- this.updateElementValue();
569
+ if (this.kendoDate) {
570
+ this.kendoDate.destroy();
571
+ }
572
+ this.kendoDate = this.initKendoDate();
573
+ this.kendoDateObject = this.kendoDate.dateObject;
574
+ this.updateFormatSections();
866
575
  this.subs.add(this.intl.changes.subscribe(this.intlChange.bind(this)));
867
576
  this.ngControl = this.injector.get(NgControl, null);
868
577
  if (this.wrapper) {
869
578
  this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
870
- this.ngZone.runOutsideAngular(() => {
871
- this.bindEvents();
872
- });
873
579
  }
874
580
  }
875
581
  /**
@@ -883,14 +589,37 @@ export class DateInputComponent {
883
589
  this.incompleteValidator = this.incompleteDateValidation ? incompleteDateValidator() : noop;
884
590
  this.onValidatorChange();
885
591
  }
886
- if (changes['format']) {
887
- this.symbolsMap = this.dateSymbolMap();
592
+ const isEqualToKendoDate = this.kendoDate && isEqual(this.value, this.kendoDate.value);
593
+ if (changes['format'] || !isEqualToKendoDate || changes['placeholder']) {
594
+ if (!this.kendoDate) {
595
+ return;
596
+ }
597
+ ;
598
+ this.kendoDate?.setOptions(this.options, true);
888
599
  this.updateFormatSections();
889
600
  }
890
- const isEqualToKendoDate = this.kendoDate && isEqual(this.value, this.kendoDate.getDateObject());
891
- if (changes['format'] || !isEqualToKendoDate || changes['placeholder']) {
892
- this.kendoDate = this.getKendoDate(this.value);
893
- this.updateElementValue(this.isActive);
601
+ }
602
+ updateFormatSections() {
603
+ this.formatSections = this.intl.splitDateFormat(this.kendoDate.inputFormat)
604
+ .reduce(({ date, time }, p) => {
605
+ return {
606
+ date: date || DATE_PART_REGEXP.test(p.type),
607
+ time: time || TIME_PART_REGEXP.test(p.type)
608
+ };
609
+ }, { date: false, time: false });
610
+ }
611
+ updateIncompleteValidationStatus() {
612
+ const previousValue = this.isDateIncomplete;
613
+ this.isDateIncomplete = this.kendoDateObject.hasValue() && this.value === null;
614
+ if (previousValue === this.isDateIncomplete || !this.incompleteDateValidation) {
615
+ return;
616
+ }
617
+ if (isPresent(this.ngControl) && !isPresent(this.pickerService)) {
618
+ this.cdr.markForCheck();
619
+ this.ngZone.run(() => this.onValidatorChange());
620
+ }
621
+ else if (isPresent(this.pickerService)) {
622
+ this.pickerService.dateCompletenessChange.emit();
894
623
  }
895
624
  }
896
625
  ngAfterViewInit() {
@@ -946,15 +675,16 @@ export class DateInputComponent {
946
675
  */
947
676
  writeValue(value) {
948
677
  this.verifyValue(value);
949
- this.kendoDate = this.getKendoDate(value);
950
678
  this.value = cloneDate(value);
951
- this.updateElementValue(this.isActive);
679
+ this.kendoDate?.setOptions(this.options, true);
680
+ this.kendoDateObject?.setValue(this.value);
681
+ this.kendoDate?.refreshElementValue();
952
682
  }
953
683
  /**
954
684
  * @hidden
955
685
  */
956
686
  triggerChange() {
957
- const value = this.kendoDate.getDateObject();
687
+ const value = this.kendoDate.value;
958
688
  if (+value !== +this.value) {
959
689
  this.value = cloneDate(value);
960
690
  this.notify();
@@ -997,11 +727,7 @@ export class DateInputComponent {
997
727
  * ```
998
728
  */
999
729
  focus() {
1000
- const input = this.inputElement;
1001
- if (input) {
1002
- input.focus();
1003
- this.selectDateSegment(this.currentFormat[0]);
1004
- }
730
+ this.kendoDate && this.kendoDate.focus();
1005
731
  }
1006
732
  /**
1007
733
  * Blurs the DateInput component.
@@ -1017,220 +743,53 @@ export class DateInputComponent {
1017
743
  */
1018
744
  handleButtonClick(offset) {
1019
745
  this.arrowDirection = Arrow.None;
1020
- this.modifyDateSegmentValue(offset);
1021
- }
1022
- /**
1023
- * @hidden
1024
- */
1025
- modifyDateSegmentValue(offset) {
1026
- const caret = this.caret();
1027
- const symbol = this.currentFormat[caret[0]];
1028
- let step = (this.steps || {})[this.symbolsMap[symbol]] || 1;
1029
- if (symbol === "S" && !this.steps.millisecond) {
1030
- const msDigits = millisecondDigitsInFormat(this.inputFormat);
1031
- step = millisecondStepFor(msDigits);
1032
- }
1033
- this.kendoDate.modifyPart(symbol, offset * step);
1034
- this.putDateInRange();
1035
- this.updateElementValue(this.isActive);
1036
- this.triggerChange();
1037
- this.selectDateSegment(symbol);
1038
- this.updateIncompleteValidationStatus();
1039
- }
1040
- /**
1041
- * @hidden
1042
- */
1043
- switchDateSegment(offset) {
1044
- const caret = this.caret();
1045
- if (this.kendoDate.resetLeadingZero()) {
1046
- this.updateElementValue(this.isActive);
1047
- }
1048
- if (caret[0] < caret[1] && this.currentFormat[caret[0]] !== this.currentFormat[caret[1] - 1]) {
1049
- this.selectNearestSegment(offset > 0 ? caret[0] : caret[1] - 1);
1050
- this.resetSegmentValue = true;
1051
- return true;
1052
- }
1053
- const previousFormatSymbol = this.currentFormat[caret[0]];
1054
- let a = caret[0] + offset;
1055
- while (a > 0 && a < this.currentFormat.length) {
1056
- if (this.currentFormat[a] !== previousFormatSymbol &&
1057
- this.currentFormat[a] !== "_") {
1058
- break;
1059
- }
1060
- a += offset;
1061
- }
1062
- if (this.currentFormat[a] === "_") {
1063
- //there is not known symbol found
1064
- return false;
1065
- }
1066
- let b = a;
1067
- while (b >= 0 && b < this.currentFormat.length) {
1068
- if (this.currentFormat[b] !== this.currentFormat[a]) {
1069
- break;
1070
- }
1071
- b += offset;
1072
- }
1073
- if (a > b && (b + 1 !== caret[0] || a + 1 !== caret[1])) {
1074
- this.caret(b + 1, a + 1);
1075
- this.resetSegmentValue = true;
1076
- return true;
1077
- }
1078
- else if (a < b && (a !== caret[0] || b !== caret[1])) {
1079
- this.caret(a, b);
1080
- this.resetSegmentValue = true;
1081
- return true;
1082
- }
1083
- return false;
1084
- }
1085
- /**
1086
- * @hidden
1087
- */
1088
- selectDateSegment(symbol) {
1089
- let begin = -1;
1090
- let end = 0;
1091
- for (let i = 0; i < this.currentFormat.length; i++) {
1092
- if (this.currentFormat[i] === symbol) {
1093
- end = i + 1;
1094
- if (begin === -1) {
1095
- begin = i;
1096
- }
746
+ this.kendoDate.focus();
747
+ this.kendoDate.modifyDateSegmentValue(offset);
748
+ }
749
+ initKendoDate() {
750
+ const kendoDate = new DateInput(this.dateInput.nativeElement, {
751
+ ...this.options,
752
+ events: {
753
+ valueChange: this.onWidgetValueChange.bind(this),
754
+ inputEnd: this.onWidgetInputEnd.bind(this),
755
+ focusEnd: this.onWidgetFocus.bind(this),
756
+ blurEnd: this.onWidgetBlur.bind(this),
757
+ keydown: this.onWidgetKeyDown.bind(this),
1097
758
  }
1098
- }
1099
- if (begin < 0) {
1100
- begin = 0;
1101
- }
1102
- this.caret(0, 0);
1103
- this.caret(begin, end);
759
+ });
760
+ return kendoDate;
1104
761
  }
1105
- /**
1106
- * @hidden
1107
- */
1108
- handleClick() {
1109
- this.hasMousedown = false;
1110
- if (this.isActive) {
1111
- const selectionPresent = this.inputElement.selectionStart !== this.inputElement.selectionEnd;
1112
- const placeholderToggled = isPresent(this.placeholder) && !this.kendoDate.hasValue() && !this.focusedPriorToMousedown;
1113
- // focus first segment if the user hasn't selected something during mousedown and if the placeholder was just toggled
1114
- const selectFirstSegment = !selectionPresent && placeholderToggled;
1115
- const index = selectFirstSegment ? 0 : this.caret()[0];
1116
- this.selectNearestSegment(index);
1117
- }
762
+ onWidgetValueChange() {
763
+ this.triggerChange();
1118
764
  }
1119
- /**
1120
- * @hidden
1121
- */
1122
- handleDragAndDrop(args) {
1123
- args.preventDefault();
765
+ onWidgetKeyDown() {
766
+ this.kendoDateObject = this.kendoDate.dateObject;
1124
767
  }
1125
- /**
1126
- * @hidden
1127
- */
1128
- handleMousedown() {
1129
- this.hasMousedown = true;
1130
- this.focusedPriorToMousedown = this.isActive;
768
+ onWidgetInputEnd() {
769
+ this.updateIncompleteValidationStatus();
1131
770
  }
1132
- /**
1133
- * @hidden
1134
- */
1135
- handleFocus(args) {
1136
- this.renderer.removeAttribute(this.inputElement, attributeNames.ariaActiveDescendant);
771
+ onWidgetFocus({ event: FocuseEvent }) {
1137
772
  this.isActive = true;
1138
- this.updateElementValue();
1139
- if (!this.hasMousedown) {
1140
- this.caret(0, this.inputValue.length);
1141
- }
1142
- this.hasMousedown = false;
1143
773
  if (hasObservers(this.onFocus)) {
1144
774
  this.ngZone.run(() => {
1145
- this.emitFocus(args);
775
+ this.emitFocus(event);
1146
776
  });
1147
777
  }
1148
778
  else {
1149
- this.emitFocus(args);
779
+ this.emitFocus(event);
1150
780
  }
1151
781
  }
1152
- /**
1153
- * @hidden
1154
- */
1155
- handleBlur(args) {
782
+ onWidgetBlur({ event: FocuseEvent }) {
1156
783
  this.isActive = false;
1157
- this.resetSegmentValue = true;
1158
- this.kendoDate.resetLeadingZero();
1159
- this.updateElementValue();
1160
784
  if (hasObservers(this.onBlur) || requiresZoneOnBlur(this.ngControl)) {
1161
785
  this.ngZone.run(() => {
1162
786
  this.onControlTouched();
1163
- this.emitBlur(args);
787
+ this.emitBlur(event);
1164
788
  this.cdr.markForCheck();
1165
789
  });
1166
790
  }
1167
791
  else {
1168
- this.emitBlur(args);
1169
- }
1170
- }
1171
- getKendoDate(value) {
1172
- const { leadingZero } = (this.kendoDate || {}) || null;
1173
- const kendoDate = new KendoDate(this.intl, this.formatPlaceholder, this.inputFormat, value, this.twoDigitYearMax);
1174
- kendoDate.setLeadingZero(this.isActive ? leadingZero : null);
1175
- return kendoDate;
1176
- }
1177
- dateSymbolMap() {
1178
- const reducer = (map, part) => {
1179
- map[part.pattern[0]] = part.type;
1180
- return map;
1181
- };
1182
- return this.intl.splitDateFormat(this.inputFormat).reduce(reducer, {});
1183
- }
1184
- updateElementValue(isActive) {
1185
- const start = this.caret()[0]; //XXX: get caret position before input is updated
1186
- const format = this.isActive ? this.inputFormat : this.displayFormat;
1187
- const texts = this.kendoDate.getTextAndFormat(format);
1188
- const showPlaceholder = !this.isActive && isPresent(this.placeholder) && !this.kendoDate.hasValue();
1189
- const input = this.inputElement;
1190
- this.currentFormat = texts[1];
1191
- this.currentValue = !showPlaceholder ? texts[0] : '';
1192
- this.renderer.setProperty(input, "value", this.currentValue);
1193
- if (input.placeholder !== this.placeholder) {
1194
- this.renderer.setProperty(input, "placeholder", this.placeholder);
1195
- }
1196
- if (isActive) {
1197
- this.selectNearestSegment(start);
1198
- }
1199
- }
1200
- caret(start, end = start) {
1201
- const isPosition = start !== undefined;
1202
- let returnValue = [start, start];
1203
- const element = this.inputElement;
1204
- if (isPosition && (this.disabled || this.readonly)) {
1205
- return undefined;
1206
- }
1207
- try {
1208
- if (element.selectionStart !== undefined) {
1209
- if (isPosition) {
1210
- if (isDocumentAvailable() && document.activeElement !== element) {
1211
- element.focus();
1212
- }
1213
- element.setSelectionRange(start, end);
1214
- }
1215
- returnValue = [element.selectionStart, element.selectionEnd];
1216
- }
1217
- }
1218
- catch (e) {
1219
- returnValue = [];
1220
- }
1221
- return returnValue;
1222
- }
1223
- selectNearestSegment(index) {
1224
- // Finds the nearest (in both directions) known part.
1225
- for (let i = index, j = index - 1; i < this.currentFormat.length || j >= 0; i++, j--) {
1226
- if (i < this.currentFormat.length && this.currentFormat[i] !== "_") {
1227
- this.selectDateSegment(this.currentFormat[i]);
1228
- return;
1229
- }
1230
- if (j >= 0 && this.currentFormat[j] !== "_") {
1231
- this.selectDateSegment(this.currentFormat[j]);
1232
- return;
1233
- }
792
+ this.emitBlur(event);
1234
793
  }
1235
794
  }
1236
795
  verifyRange() {
@@ -1249,135 +808,9 @@ export class DateInputComponent {
1249
808
  throw new Error(`The 'value' should be a valid JavaScript Date instance. Check ${VALUE_DOC_LINK} for possible resolution.`);
1250
809
  }
1251
810
  }
1252
- putDateInRange() {
1253
- const currentDate = this.kendoDate.getDateObject();
1254
- const candidate = dateInRange(currentDate, this.min, this.max);
1255
- if (this.autoCorrect && !isEqual(currentDate, candidate)) {
1256
- this.kendoDate = this.getKendoDate(candidate);
1257
- }
1258
- }
1259
- updateFormatSections() {
1260
- this.formatSections = this.intl.splitDateFormat(this.inputFormat)
1261
- .reduce(({ date, time }, p) => {
1262
- return {
1263
- date: date || DATE_PART_REGEXP.test(p.type),
1264
- time: time || TIME_PART_REGEXP.test(p.type)
1265
- };
1266
- }, { date: false, time: false });
1267
- }
1268
811
  intlChange() {
812
+ this.kendoDate.setOptions(this.options, true);
1269
813
  this.updateFormatSections();
1270
- this.kendoDate = this.getKendoDate(this.value);
1271
- this.updateElementValue(this.isActive);
1272
- }
1273
- updateOnPaste() {
1274
- let value = this.intl.parseDate(this.inputValue, this.inputFormat) || this.value;
1275
- if (isPresent(value) && this.kendoDate.shouldNormalizeCentury()) {
1276
- value = this.kendoDate.normalizeCentury(value);
1277
- }
1278
- const notify = +value !== +this.value;
1279
- this.writeValue(value);
1280
- if (notify) {
1281
- this.notify();
1282
- }
1283
- }
1284
- bindEvents() {
1285
- const element = this.wrapper.nativeElement;
1286
- const mousewheelHandler = this.handleMouseWheel.bind(this);
1287
- this.domEvents.push(this.renderer.listen(element, 'DOMMouseScroll', mousewheelHandler), this.renderer.listen(element, 'mousewheel', mousewheelHandler), this.renderer.listen(element, 'keydown', this.handleKeydown.bind(this)), this.renderer.listen(element, 'paste', this.handlePaste.bind(this)), this.renderer.listen(element, 'input', this.handleInput.bind(this)));
1288
- }
1289
- handleMouseWheel(event) {
1290
- if (this.disabled || this.readonly || !this.isActive) {
1291
- return;
1292
- }
1293
- event = window.event || event;
1294
- if (event.shiftKey) {
1295
- this.switchDateSegment((event.wheelDelta || -event.detail) > 0 ? -1 : 1);
1296
- }
1297
- else {
1298
- this.modifyDateSegmentValue((event.wheelDelta || -event.detail) > 0 ? 1 : -1);
1299
- }
1300
- event.returnValue = false;
1301
- if (event.preventDefault) {
1302
- event.preventDefault();
1303
- }
1304
- if (event.stopPropagation) {
1305
- event.stopPropagation();
1306
- }
1307
- }
1308
- handlePaste() {
1309
- this.paste = true;
1310
- }
1311
- handleKeydown(event) {
1312
- if (this.disabled || this.readonly || event.altKey || event.ctrlKey || event.metaKey) {
1313
- return;
1314
- }
1315
- if (event.keyCode === Keys.Backspace) {
1316
- this.backspace = true;
1317
- return;
1318
- }
1319
- switch (event.keyCode) {
1320
- case Keys.ArrowDown:
1321
- this.modifyDateSegmentValue(-1);
1322
- break;
1323
- case Keys.ArrowUp:
1324
- this.modifyDateSegmentValue(1);
1325
- break;
1326
- case Keys.ArrowRight:
1327
- this.switchDateSegment(1);
1328
- break;
1329
- case Keys.ArrowLeft:
1330
- this.switchDateSegment(-1);
1331
- break;
1332
- case Keys.Home:
1333
- this.selectNearestSegment(0);
1334
- break;
1335
- case Keys.End:
1336
- this.selectNearestSegment(this.inputValue.length);
1337
- break;
1338
- default:
1339
- return; //skip the preventDefault if we didn't handled the keyCode
1340
- }
1341
- event.preventDefault();
1342
- }
1343
- handleInput() {
1344
- if (this.disabled || this.readonly) {
1345
- return;
1346
- }
1347
- if (this.paste) {
1348
- this.updateOnPaste();
1349
- this.paste = false;
1350
- return;
1351
- }
1352
- const diff = approximateStringMatching(this.currentValue, this.currentFormat, this.inputValue, this.caret()[0]);
1353
- const navigationOnly = (diff.length === 1 && diff[0][1] === "_");
1354
- let switchPart = false;
1355
- if (!navigationOnly) {
1356
- let parsedPart;
1357
- for (let i = 0; i < diff.length; i++) {
1358
- parsedPart = this.kendoDate.parsePart(diff[i][0], diff[i][1], this.resetSegmentValue);
1359
- switchPart = parsedPart.switchToNext;
1360
- }
1361
- const candidate = this.kendoDate.getDateObject();
1362
- if (this.value && candidate && !this.formatSections['date']) {
1363
- this.kendoDate = this.getKendoDate(setTime(this.value, candidate));
1364
- }
1365
- }
1366
- this.resetSegmentValue = false;
1367
- this.putDateInRange();
1368
- this.updateElementValue(this.isActive);
1369
- this.triggerChange();
1370
- this.updateIncompleteValidationStatus();
1371
- if (diff.length && diff[0][0] !== "_") {
1372
- this.selectDateSegment(diff[0][0]);
1373
- }
1374
- if (switchPart || navigationOnly) {
1375
- this.switchDateSegment(1);
1376
- }
1377
- if (this.backspace) {
1378
- this.switchDateSegment(-1);
1379
- }
1380
- this.backspace = false;
1381
814
  }
1382
815
  emitFocus(args) {
1383
816
  this.onFocus.emit();
@@ -1391,20 +824,6 @@ export class DateInputComponent {
1391
824
  this.pickerService.onBlur.emit(args);
1392
825
  }
1393
826
  }
1394
- updateIncompleteValidationStatus() {
1395
- const previousValue = this.isDateIncomplete;
1396
- this.isDateIncomplete = this.kendoDate.hasValue() && this.value === null;
1397
- if (previousValue === this.isDateIncomplete || !this.incompleteDateValidation) {
1398
- return;
1399
- }
1400
- if (isPresent(this.ngControl) && !isPresent(this.pickerService)) {
1401
- this.cdr.markForCheck();
1402
- this.ngZone.run(() => this.onValidatorChange());
1403
- }
1404
- else if (isPresent(this.pickerService)) {
1405
- this.pickerService.dateCompletenessChange.emit();
1406
- }
1407
- }
1408
827
  setSpinnerFill(spinner, fill, oldFill) {
1409
828
  if (oldFill !== 'none') {
1410
829
  this.renderer.removeClass(spinner, `k-button-${oldFill}`);
@@ -1430,7 +849,7 @@ export class DateInputComponent {
1430
849
  }
1431
850
  }
1432
851
  DateInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: DateInputComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.IntlService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Injector }, { token: i2.LocalizationService }, { token: i3.PickerService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1433
- DateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: DateInputComponent, selector: "kendo-dateinput", inputs: { focusableId: "focusableId", pickerType: "pickerType", disabled: "disabled", readonly: "readonly", title: "title", tabindex: "tabindex", role: "role", ariaReadOnly: "ariaReadOnly", tabIndex: "tabIndex", format: "format", formatPlaceholder: "formatPlaceholder", placeholder: "placeholder", steps: "steps", max: "max", min: "min", rangeValidation: "rangeValidation", autoCorrect: "autoCorrect", incompleteDateValidation: "incompleteDateValidation", twoDigitYearMax: "twoDigitYearMax", value: "value", spinners: "spinners", isPopupOpen: "isPopupOpen", hasPopup: "hasPopup", size: "size", rounded: "rounded", fillMode: "fillMode" }, outputs: { valueChange: "valueChange", valueUpdate: "valueUpdate", onFocus: "focus", onBlur: "blur" }, host: { properties: { "class.k-input": "this.wrapperClass", "class.k-dateinput": "this.wrapperClass", "class.k-disabled": "this.disabledClass" } }, providers: [
852
+ DateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: DateInputComponent, selector: "kendo-dateinput", inputs: { focusableId: "focusableId", pickerType: "pickerType", disabled: "disabled", readonly: "readonly", title: "title", tabindex: "tabindex", role: "role", ariaReadOnly: "ariaReadOnly", tabIndex: "tabIndex", format: "format", formatPlaceholder: "formatPlaceholder", placeholder: "placeholder", steps: "steps", max: "max", min: "min", rangeValidation: "rangeValidation", autoCorrectParts: "autoCorrectParts", autoSwitchParts: "autoSwitchParts", autoSwitchKeys: "autoSwitchKeys", allowCaretMode: "allowCaretMode", autoFill: "autoFill", incompleteDateValidation: "incompleteDateValidation", twoDigitYearMax: "twoDigitYearMax", enableMouseWheel: "enableMouseWheel", value: "value", spinners: "spinners", isPopupOpen: "isPopupOpen", hasPopup: "hasPopup", size: "size", rounded: "rounded", fillMode: "fillMode" }, outputs: { valueChange: "valueChange", valueUpdate: "valueUpdate", onFocus: "focus", onBlur: "blur" }, host: { properties: { "class.k-input": "this.wrapperClass", "class.k-dateinput": "this.wrapperClass", "class.k-disabled": "this.disabledClass" } }, providers: [
1434
853
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateInputComponent), multi: true },
1435
854
  { provide: NG_VALIDATORS, useExisting: forwardRef(() => DateInputComponent), multi: true },
1436
855
  { provide: L10N_PREFIX, useValue: 'kendo.dateinput' },
@@ -1463,13 +882,8 @@ DateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", ver
1463
882
  [attr.aria-expanded]="isPopupOpen"
1464
883
  [attr.aria-haspopup]="hasPopup"
1465
884
  [kendoEventsOutsideAngular]="{
1466
- click: handleClick,
1467
- focus: handleFocus,
1468
- mousedown: handleMousedown,
1469
- touchstart: handleMousedown,
1470
885
  dragstart: handleDragAndDrop,
1471
- drop: handleDragAndDrop,
1472
- blur: handleBlur
886
+ drop: handleDragAndDrop
1473
887
  }"
1474
888
  [scope]="this"
1475
889
  />
@@ -1552,13 +966,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
1552
966
  [attr.aria-expanded]="isPopupOpen"
1553
967
  [attr.aria-haspopup]="hasPopup"
1554
968
  [kendoEventsOutsideAngular]="{
1555
- click: handleClick,
1556
- focus: handleFocus,
1557
- mousedown: handleMousedown,
1558
- touchstart: handleMousedown,
1559
969
  dragstart: handleDragAndDrop,
1560
- drop: handleDragAndDrop,
1561
- blur: handleBlur
970
+ drop: handleDragAndDrop
1562
971
  }"
1563
972
  [scope]="this"
1564
973
  />
@@ -1636,12 +1045,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
1636
1045
  type: Input
1637
1046
  }], rangeValidation: [{
1638
1047
  type: Input
1639
- }], autoCorrect: [{
1048
+ }], autoCorrectParts: [{
1049
+ type: Input
1050
+ }], autoSwitchParts: [{
1051
+ type: Input
1052
+ }], autoSwitchKeys: [{
1053
+ type: Input
1054
+ }], allowCaretMode: [{
1055
+ type: Input
1056
+ }], autoFill: [{
1640
1057
  type: Input
1641
1058
  }], incompleteDateValidation: [{
1642
1059
  type: Input
1643
1060
  }], twoDigitYearMax: [{
1644
1061
  type: Input
1062
+ }], enableMouseWheel: [{
1063
+ type: Input
1645
1064
  }], value: [{
1646
1065
  type: Input
1647
1066
  }], spinners: [{