@progress/kendo-dateinputs-common 0.2.0-dev.202301101148 → 0.2.0-dev.202301131210

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.
@@ -147,16 +147,18 @@ export class DateObject {
147
147
  partiallyInvalidText += text[i];
148
148
  }
149
149
  else if (this.getInvalidDatePartValue(symbol)) {
150
+ const partsForSegment = this.getPartsForSegment(mask, i);
150
151
  if (symbol === "M") {
151
- if (mask.partMap[i].pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD) {
152
+ const datePartText = (parseToInt(this.getInvalidDatePartValue(symbol)) + JS_MONTH_OFFSET).toString();
153
+ if (partsForSegment.length > MONTH_PART_WITH_WORDS_THRESHOLD) {
152
154
  partiallyInvalidText += formattedDates[symbol][i];
153
155
  }
154
156
  else {
155
157
  if (this.getInvalidDatePartValue(symbol)) {
156
- const month = parseToInt(this.getInvalidDatePartValue(symbol) + JS_MONTH_OFFSET).toString();
157
- const formattedMonth = padZero(Math.abs(mask.partMap[i].pattern.length - month.length)) + month;
158
- partiallyInvalidText += formattedMonth;
159
- i += Math.max(0, formattedMonth.length - 1);
158
+ const formattedDatePart = padZero(partsForSegment.length - datePartText.length) + datePartText;
159
+ partiallyInvalidText += formattedDatePart;
160
+ // add -1 as the first character in the segment is at index i
161
+ i += partsForSegment.length - 1;
160
162
  }
161
163
  else {
162
164
  partiallyInvalidText += formattedDates[symbol][i];
@@ -165,8 +167,11 @@ export class DateObject {
165
167
  }
166
168
  else {
167
169
  if (this.getInvalidDatePartValue(symbol)) {
168
- partiallyInvalidText += this.getInvalidDatePartValue(symbol);
169
- i += Math.max(0, this.getInvalidDatePartValue(symbol).toString().length - 1);
170
+ const datePartText = this.getInvalidDatePartValue(symbol).toString();
171
+ const formattedDatePart = padZero(partsForSegment.length - datePartText.length) + datePartText;
172
+ partiallyInvalidText += formattedDatePart;
173
+ // add -1 as the first character in the segment is at index i
174
+ i += partsForSegment.length - 1;
170
175
  }
171
176
  else {
172
177
  partiallyInvalidText += formattedDates[symbol][i];
@@ -275,16 +280,18 @@ export class DateObject {
275
280
  }
276
281
  }
277
282
  modifyPart(symbol, offset) {
283
+ if (!isPresent(symbol) || !isPresent(offset) || offset === 0) {
284
+ return;
285
+ }
278
286
  let newValue = cloneDate(this.value);
279
- let originalValue = cloneDate(this.value);
280
287
  let timeModified = false;
281
288
  let invalidDateFound;
282
- let currentInvalidDatePartValue = 0;
283
- if (!this.autoCorrectParts) {
284
- const isMonth = symbol === "M";
285
- const isDay = symbol === "d" || symbol === "E";
289
+ const isMonth = symbol === "M";
290
+ const isDay = symbol === "d" || symbol === "E";
291
+ const symbolExists = this.getExisting(symbol);
292
+ if (!this.autoCorrectParts && (isDay || isMonth)) {
286
293
  const invalidDateParts = this._partiallyInvalidDate.invalidDateParts || {};
287
- const invalidDatePart = invalidDateParts[symbol];
294
+ const invalidDatePartValue = this.getInvalidDatePartValue(symbol);
288
295
  let year = invalidDateParts.y.value || newValue.getFullYear();
289
296
  let month = invalidDateParts.M.value || newValue.getMonth();
290
297
  let day = invalidDateParts.d.value || invalidDateParts.E.value || newValue.getDate();
@@ -303,33 +310,61 @@ export class DateObject {
303
310
  case 'E':
304
311
  day += offset;
305
312
  break;
306
- case 'h':
307
- case 'H':
308
- hour += offset;
309
- break;
310
- case 'm':
311
- minutes += offset;
312
- break;
313
- case 's':
314
- seconds += offset;
315
- break;
316
- case 'S':
317
- milliseconds += offset;
318
- break;
319
- // case 'a': newValue.setHours(newValue.getHours() + (12 * offset)); timeModified = true; break;
313
+ // case 'h':
314
+ // case 'H': hour += offset; break;
315
+ // case 'm': minutes += offset; break;
316
+ // case 's': seconds += offset; break;
317
+ // case 'S': milliseconds += offset; break;
320
318
  default: break;
321
319
  }
322
320
  if (symbol === "M") {
323
- if ((month < 0 || month > 11) && this.getExisting(symbol)) {
324
- // do not cycle months
325
- this.setExisting(symbol, false);
326
- return;
321
+ if ((month < 0 || month > 11)) {
322
+ if (symbolExists) {
323
+ this.setExisting(symbol, false);
324
+ this.resetInvalidDateSymbol(symbol);
325
+ return;
326
+ }
327
+ }
328
+ if (!symbolExists) {
329
+ if (month < 0) {
330
+ month = clamp(11 + ((month % 11) + 1), 0, 11);
331
+ }
332
+ else {
333
+ const monthValue = isPresent(invalidDatePartValue) ?
334
+ month :
335
+ ((offset - JS_MONTH_OFFSET) % 12);
336
+ month = clamp(monthValue, 0, 11);
337
+ }
338
+ month = clamp(month, 0, 11);
339
+ }
340
+ month = clamp(month, 0, 11);
341
+ }
342
+ else if (symbol === "d") {
343
+ if (symbolExists) {
344
+ if (day <= 0 || day > 31) {
345
+ this.setExisting(symbol, false);
346
+ this.resetInvalidDateSymbol(symbol);
347
+ return;
348
+ }
349
+ }
350
+ else if (!symbolExists) {
351
+ if (isPresent(invalidDatePartValue)) {
352
+ if (day <= 0 || day > 31) {
353
+ this.setExisting(symbol, false);
354
+ this.resetInvalidDateSymbol(symbol);
355
+ return;
356
+ }
357
+ }
358
+ if (offset < 0) {
359
+ const dayValue = isPresent(invalidDatePartValue) ? day : 1 + (31 - Math.abs(offset % 31));
360
+ day = clamp(dayValue, 1, 31);
361
+ }
362
+ else {
363
+ const dayValue = isPresent(invalidDatePartValue) ? day : offset % 31;
364
+ day = clamp(dayValue, 1, 31);
365
+ }
366
+ day = clamp(day, 1, 31);
327
367
  }
328
- // const mask = this.dateFormatString(this.value, this.format);
329
- // const monthPart = mask.partMap.filter(x => x.type === "month");
330
- // if (monthPart && monthPart[0] && monthPart[0].pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD) {
331
- month = (12 + month) % 12;
332
- // }
333
368
  }
334
369
  const dateCandidate = createDate(year, month, day, hour, minutes, seconds, milliseconds);
335
370
  const newValueCandidate = isMonth || isDay ?
@@ -426,92 +461,6 @@ export class DateObject {
426
461
  this.setExisting(symbol, false);
427
462
  }
428
463
  }
429
- else {
430
- // this.modifyDateSymbol()
431
- switch (symbol) {
432
- case 'y':
433
- newValue.setFullYear(newValue.getFullYear() + offset);
434
- break;
435
- case 'M':
436
- newValue = addMonths(this.value, offset);
437
- break;
438
- case 'd':
439
- case 'E':
440
- newValue.setDate(newValue.getDate() + offset);
441
- break;
442
- case 'h':
443
- case 'H':
444
- newValue.setHours(newValue.getHours() + offset);
445
- timeModified = true;
446
- break;
447
- case 'm':
448
- newValue.setMinutes(newValue.getMinutes() + offset);
449
- timeModified = true;
450
- break;
451
- case 's':
452
- newValue.setSeconds(newValue.getSeconds() + offset);
453
- timeModified = true;
454
- break;
455
- case "S":
456
- newValue.setMilliseconds(newValue.getMilliseconds() + offset);
457
- break;
458
- case 'a':
459
- newValue.setHours(newValue.getHours() + (12 * offset));
460
- timeModified = true;
461
- break;
462
- default: break;
463
- }
464
- invalidDateFound = true;
465
- if (invalidDatePart && invalidDatePart.value) {
466
- currentInvalidDatePartValue = parseToInt(invalidDatePart.value);
467
- }
468
- else {
469
- if (!isPresent(invalidDatePart.value)) {
470
- newValue = cloneDate(originalValue);
471
- // this.modifyDateSymbol()
472
- switch (symbol) {
473
- case 'y':
474
- currentInvalidDatePartValue = originalValue.getFullYear();
475
- break;
476
- case 'M':
477
- currentInvalidDatePartValue = originalValue.getMonth();
478
- break;
479
- case 'd':
480
- case 'E':
481
- currentInvalidDatePartValue = originalValue.getDate();
482
- break;
483
- case 'h':
484
- case 'H':
485
- currentInvalidDatePartValue = originalValue.getHours();
486
- break;
487
- case 'm':
488
- currentInvalidDatePartValue = originalValue.getMinutes();
489
- break;
490
- case 's':
491
- currentInvalidDatePartValue = originalValue.getSeconds();
492
- break;
493
- case 'S':
494
- currentInvalidDatePartValue = originalValue.getMilliseconds();
495
- break;
496
- // case 'a': newValue.setHours(newValue.getHours() + (12 * offset)); timeModified = true; break;
497
- default: break;
498
- }
499
- }
500
- else {
501
- }
502
- }
503
- let invalidDatePartValue = Math.max(0, currentInvalidDatePartValue + offset);
504
- if (symbol !== "y") {
505
- invalidDatePartValue = clamp(currentInvalidDatePartValue + offset, 0, 99);
506
- }
507
- this.setInvalidDatePart(symbol, {
508
- value: invalidDatePartValue,
509
- date: cloneDate(newValue),
510
- startDateOffset: (this.getInvalidDatePart(symbol).startDateOffset || 0) + offset,
511
- startDate: cloneDate(this.value)
512
- });
513
- this.setExisting(symbol, false);
514
- }
515
464
  }
516
465
  else {
517
466
  switch (symbol) {
@@ -667,6 +616,13 @@ export class DateObject {
667
616
  if (originalFormat.length < rawInputValue.length) {
668
617
  datePartText += currentChar;
669
618
  }
619
+ else if (!isDeleting && originalFormat.length > rawInputValue.length) {
620
+ const lengthDiff = originalFormat.length - rawInputValue.length;
621
+ const trimmedDatePartText = datePartText.substring(0, datePartText.length - lengthDiff);
622
+ if (trimmedDatePartText && trimmedDatePartText.length > 0) {
623
+ datePartText = trimmedDatePartText;
624
+ }
625
+ }
670
626
  if (datePartText.length > segmentLength) {
671
627
  return extend(parseResult, { value: null, switchToNext: false });
672
628
  }
@@ -704,6 +660,13 @@ export class DateObject {
704
660
  if (originalFormat.length < rawInputValue.length) {
705
661
  datePartText += currentChar;
706
662
  }
663
+ else if (!isDeleting && originalFormat.length > rawInputValue.length) {
664
+ const lengthDiff = originalFormat.length - rawInputValue.length;
665
+ const trimmedDatePartText = datePartText.substring(0, datePartText.length - lengthDiff);
666
+ if (trimmedDatePartText && trimmedDatePartText.length > 0) {
667
+ datePartText = trimmedDatePartText;
668
+ }
669
+ }
707
670
  }
708
671
  }
709
672
  else {
@@ -749,14 +712,19 @@ export class DateObject {
749
712
  if (!tryParse) {
750
713
  break;
751
714
  }
752
- if (!this.autoCorrectParts) {
753
- tryParse = false;
754
- }
755
715
  let middle = resetSegmentValue ?
756
716
  currentChar :
757
717
  isInCaretMode ?
758
718
  datePartText :
759
719
  (current.substring(i) + currentChar);
720
+ if (!this.autoCorrectParts) {
721
+ tryParse = false;
722
+ if (!isInCaretMode) {
723
+ // try to make an exact match as there will be only 1 attempt
724
+ middle = unpadZero(middle);
725
+ middle = padZero(segmentLength - middle.length) + middle;
726
+ }
727
+ }
760
728
  if (isInCaretMode) {
761
729
  // try to make an exact match as there will be only 1 attempt
762
730
  tryParse = false;
@@ -774,6 +742,7 @@ export class DateObject {
774
742
  // to "Thursday, February 1, 2022 3:04:05 AM"
775
743
  // as "EEEE, February..." is not parsable
776
744
  parsedDate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
745
+ datePartText = middle;
777
746
  }
778
747
  const isCurrentCharParsable = !isNaN(parseInt(currentChar, 10)) || (isInCaretMode && isDeleting && currentChar === "");
779
748
  if (!parsedDate && !isNaN(middleNumber) && isCurrentCharParsable) {
@@ -803,7 +772,7 @@ export class DateObject {
803
772
  const patternLength = this.patternLength(patternValue) || patternValue.length;
804
773
  const leadingZeroOffset = (this.leadingZero || {})[symbol] || 0;
805
774
  const patternSatisfied = (leadingZeroOffset + (unpadZero(middle) || currentChar).length) >= patternLength;
806
- const switchToNext = peekDate === null ||
775
+ let switchToNext = peekDate === null ||
807
776
  (leadingZero[symbol] && patternValue.length <= middle.length) ||
808
777
  patternSatisfied;
809
778
  if (this.shouldNormalizeCentury()) {
@@ -811,6 +780,26 @@ export class DateObject {
811
780
  }
812
781
  this._value = parsedDate;
813
782
  this.setExisting(symbol, true);
783
+ if (isInCaretMode && switchToNext) {
784
+ if (symbol === "M") {
785
+ if (segmentLength <= MONTH_PART_WITH_WORDS_THRESHOLD) {
786
+ const datePartValue = parseToInt(datePartText);
787
+ if (datePartValue >= 2) {
788
+ switchToNext = true;
789
+ }
790
+ else {
791
+ switchToNext = false;
792
+ }
793
+ }
794
+ }
795
+ else {
796
+ switchToNext = switchToNext ?
797
+ hasFixedFormat ?
798
+ datePartText.length === segmentLength :
799
+ datePartText.length > segmentLength :
800
+ switchToNext;
801
+ }
802
+ }
814
803
  return extend(parseResult, { value: this.value, switchToNext: switchToNext });
815
804
  }
816
805
  }
@@ -838,9 +827,6 @@ export class DateObject {
838
827
  }
839
828
  if (!this.autoCorrectParts) {
840
829
  this.setExisting(symbol, false);
841
- // todo check if string is better
842
- // const padPrefix = padZero(Math.abs(current.length - datePartText.length));
843
- // const paddedDatePartText = padPrefix + datePartText;
844
830
  let datePartValue;
845
831
  const textToParse = isInCaretMode ? datePartText : current;
846
832
  const parsedValue = parseToInt(textToParse);
@@ -1020,27 +1006,68 @@ export class DateObject {
1020
1006
  let resultText = '';
1021
1007
  let resultFormat = '';
1022
1008
  let format = mask.symbols;
1009
+ let processTextSymbolsEnded = false;
1010
+ let ignoreFormatSymbolsCount = 0;
1011
+ const formattedDates = this.getFormattedInvalidDates(format);
1023
1012
  for (let formatSymbolIndex = format.length - 1; formatSymbolIndex >= 0; formatSymbolIndex--) {
1013
+ const partsForSegment = this.getPartsForSegment(mask, formatSymbolIndex);
1024
1014
  if (this.knownParts.indexOf(format[formatSymbolIndex]) === -1 || this.getExisting(format[formatSymbolIndex])) {
1025
- resultText = text[formatSymbolIndex] + resultText;
1015
+ if (this.autoCorrectParts) {
1016
+ resultText = text[formatSymbolIndex] + resultText;
1017
+ }
1018
+ else {
1019
+ if (text.length !== format.length) {
1020
+ if (processTextSymbolsEnded) {
1021
+ resultText = text[formatSymbolIndex] + resultText;
1022
+ }
1023
+ else if (ignoreFormatSymbolsCount > 0) {
1024
+ resultText = text[formatSymbolIndex] + resultText;
1025
+ ignoreFormatSymbolsCount--;
1026
+ if (ignoreFormatSymbolsCount <= 0) {
1027
+ processTextSymbolsEnded = true;
1028
+ }
1029
+ }
1030
+ else {
1031
+ resultText = (text[formatSymbolIndex + text.length - format.length] || "") + resultText;
1032
+ }
1033
+ }
1034
+ else {
1035
+ resultText = text[formatSymbolIndex] + resultText;
1036
+ }
1037
+ }
1026
1038
  resultFormat = format[formatSymbolIndex] + resultFormat;
1027
1039
  }
1028
1040
  else {
1029
1041
  const symbol = format[formatSymbolIndex];
1030
- while (formatSymbolIndex >= 0 && symbol === format[formatSymbolIndex]) {
1031
- formatSymbolIndex--;
1042
+ let formatSymbolIndexModifier = 0;
1043
+ if (this.autoCorrectParts || (!this.autoCorrectParts && !this.getInvalidDatePartValue(symbol))) {
1044
+ while (formatSymbolIndex >= 0 && symbol === format[formatSymbolIndex]) {
1045
+ formatSymbolIndex--;
1046
+ }
1047
+ formatSymbolIndex++;
1032
1048
  }
1033
- formatSymbolIndex++;
1034
1049
  if (this.leadingZero && this.leadingZero[symbol]) {
1035
1050
  resultText = '0' + resultText;
1036
1051
  }
1037
1052
  else {
1038
1053
  if (!this.autoCorrectParts && this.getInvalidDatePartValue(symbol)) {
1039
- // use mask.symbols instead of mask.partMap
1040
- const part = mask.partMap[formatSymbolIndex];
1041
- const pattern = mask.partMap.filter(x => x.type === part.type && x.pattern === part.pattern);
1042
- const segmentText = text.substr(formatSymbolIndex, pattern.length);
1043
- resultText = segmentText + resultText;
1054
+ let datePartText = this.getInvalidDatePartValue(symbol).toString();
1055
+ if (symbol === "M") {
1056
+ datePartText = (parseToInt(this.getInvalidDatePartValue(symbol)) + JS_MONTH_OFFSET).toString();
1057
+ if (partsForSegment.length > MONTH_PART_WITH_WORDS_THRESHOLD) {
1058
+ resultText = formattedDates[symbol][formatSymbolIndex] + resultText;
1059
+ }
1060
+ else {
1061
+ datePartText = (parseToInt(this.getInvalidDatePartValue(symbol)) + JS_MONTH_OFFSET).toString();
1062
+ resultText = datePartText + resultText;
1063
+ ignoreFormatSymbolsCount = datePartText.length - partsForSegment.length;
1064
+ }
1065
+ }
1066
+ else {
1067
+ resultText = datePartText + resultText;
1068
+ formatSymbolIndexModifier = datePartText.length - 1;
1069
+ ignoreFormatSymbolsCount = datePartText.length - partsForSegment.length;
1070
+ }
1044
1071
  }
1045
1072
  else {
1046
1073
  resultText = this.dateFieldName(mask.partMap[formatSymbolIndex]) + resultText;
@@ -1049,6 +1076,9 @@ export class DateObject {
1049
1076
  while (resultFormat.length < resultText.length) {
1050
1077
  resultFormat = format[formatSymbolIndex] + resultFormat;
1051
1078
  }
1079
+ if (formatSymbolIndexModifier !== 0) {
1080
+ formatSymbolIndex = (formatSymbolIndex - formatSymbolIndexModifier) + (text.length - format.length);
1081
+ }
1052
1082
  }
1053
1083
  }
1054
1084
  return { text: resultText, format: resultFormat };
@@ -1213,4 +1243,30 @@ export class DateObject {
1213
1243
  markDatePartsAsExisting() {
1214
1244
  this.modifyExisting(true);
1215
1245
  }
1246
+ /**
1247
+ * @hidden
1248
+ */
1249
+ getPartsForSegment(mask, partIndex) {
1250
+ const segmentPart = mask.partMap[partIndex];
1251
+ const partsForSegment = [];
1252
+ for (let maskPartIndex = partIndex; maskPartIndex < mask.partMap.length; maskPartIndex++) {
1253
+ const part = mask.partMap[maskPartIndex];
1254
+ if (segmentPart.type === part.type && segmentPart.pattern === part.pattern) {
1255
+ partsForSegment.push(part);
1256
+ }
1257
+ else {
1258
+ break;
1259
+ }
1260
+ }
1261
+ for (let maskPartIndex = partIndex - 1; maskPartIndex >= 0; maskPartIndex--) {
1262
+ const part = mask.partMap[maskPartIndex];
1263
+ if (segmentPart.type === part.type && segmentPart.pattern === part.pattern) {
1264
+ partsForSegment.unshift(part);
1265
+ }
1266
+ else {
1267
+ break;
1268
+ }
1269
+ }
1270
+ return partsForSegment;
1271
+ }
1216
1272
  }
@@ -83,7 +83,7 @@ export class DateInput extends Observable {
83
83
  dateValue = null;
84
84
  }
85
85
  this.element = element;
86
- this.element._kendoWidget = this;
86
+ // this.element._kendoWidget = this;
87
87
  this.options = extend({}, defaultDateInputOptions, options);
88
88
  this.intl = this.options.intlService;
89
89
  this.formatPlaceholder = this.options.formatPlaceholder ? this.options.formatPlaceholder : 'formatPattern';
@@ -92,6 +92,7 @@ export class DateInput extends Observable {
92
92
  this.setTextAndFormat();
93
93
  this.bindEvents();
94
94
  this.resetSegmentValue = true;
95
+ this.interactionMode = DateInputInteractionMode.None;
95
96
  this.forceUpdate();
96
97
  }
97
98
  destroy() {
@@ -146,8 +147,8 @@ export class DateInput extends Observable {
146
147
  setOptions(options, refresh = false) {
147
148
  this.options = extend(this.options, options);
148
149
  if (refresh) {
149
- this.destroy();
150
- this.init(this.element, options);
150
+ this.unbindEvents();
151
+ this.init(this.element, this.options);
151
152
  }
152
153
  }
153
154
  /**
@@ -359,24 +360,13 @@ export class DateInput extends Observable {
359
360
  }
360
361
  }
361
362
  else if (hasCaret) {
362
- if (this.options.format.length !== this.currentFormat.length) {
363
- if (hasDateValueChanged && isPresent(this.dateObject.value)) {
364
- const elementValueLength = this.elementValue.length;
365
- this.forceUpdate();
366
- const selectionOffset = this.elementValue.length - elementValueLength;
367
- this.setSelection({
368
- start: currentSelection.start + selectionOffset,
369
- end: currentSelection.start + selectionOffset
370
- });
363
+ if (hasDateValueChanged && isPresent(this.dateObject.getValue())) {
364
+ if (switchPart) {
365
+ this.switchDateSegment(1);
371
366
  }
372
367
  }
373
368
  else {
374
- if (hasDateValueChanged) {
375
- if (lastParseResultHasNoValue) {
376
- this.restorePreviousInputEventState();
377
- }
378
- }
379
- else {
369
+ if (lastParseResultHasNoValue) {
380
370
  this.restorePreviousInputEventState();
381
371
  }
382
372
  }
@@ -656,6 +646,14 @@ export class DateInput extends Observable {
656
646
  if (start < 0) {
657
647
  start = 0;
658
648
  }
649
+ if (!this.options.autoCorrectParts && this.currentFormat.length !== this.currentText.length) {
650
+ if (this.currentFormat.length < this.currentText.length) {
651
+ end += this.currentText.length - this.currentFormat.length;
652
+ }
653
+ else {
654
+ end = Math.max(0, end - (this.currentFormat.length - this.currentText.length));
655
+ }
656
+ }
659
657
  return { start, end };
660
658
  }
661
659
  /**
@@ -679,24 +677,37 @@ export class DateInput extends Observable {
679
677
  const selection = this.selection;
680
678
  if (this.isInCaretMode()) {
681
679
  let start = selection.start;
682
- let closestNonSeparatorSymbol = this.currentFormat[start];
683
- for (let i = start; i >= 0; i--) {
684
- closestNonSeparatorSymbol = this.currentFormat[i];
685
- if (closestNonSeparatorSymbol !== Constants.formatSeparator) {
686
- start = i;
687
- break;
680
+ const currentSymbol = this.currentFormat[start - (this.elementValue.length - this.currentFormat.length)] ||
681
+ this.currentFormat[start];
682
+ let symbol = "";
683
+ let symbolCandidate = "";
684
+ if (offset < 0) {
685
+ for (let i = start + offset; i >= 0; i--) {
686
+ symbolCandidate = this.currentFormat[i];
687
+ if (symbolCandidate !== Constants.formatSeparator &&
688
+ symbolCandidate !== currentSymbol) {
689
+ start = i;
690
+ symbol = symbolCandidate;
691
+ break;
692
+ }
688
693
  }
689
694
  }
690
- let symbol;
691
- for (let i = start; i < this.currentFormat.length; i++) {
692
- symbol = this.currentFormat[i];
693
- if (symbol !== Constants.formatSeparator) {
694
- break;
695
+ else {
696
+ for (let i = start + offset; i < this.currentFormat.length; i++) {
697
+ symbolCandidate = this.currentFormat[i];
698
+ if (symbolCandidate !== Constants.formatSeparator &&
699
+ symbolCandidate !== currentSymbol) {
700
+ start = i;
701
+ symbol = symbolCandidate;
702
+ break;
703
+ }
695
704
  }
696
705
  }
697
706
  if (symbol) {
698
707
  this.forceUpdate();
699
708
  this.setSelection(this.selectionBySymbol(symbol));
709
+ this.interactionMode = DateInputInteractionMode.Selection;
710
+ return;
700
711
  }
701
712
  }
702
713
  let { start: selectionStart, end: selectionEnd } = this.selection;
@@ -170,4 +170,8 @@ export declare class DateObject {
170
170
  */
171
171
  modifyDateSymbolWithValue(date: any, symbol: any, value: any): Date;
172
172
  markDatePartsAsExisting(): void;
173
+ /**
174
+ * @hidden
175
+ */
176
+ getPartsForSegment(mask: any, partIndex: any): any[];
173
177
  }