@progress/kendo-dateinputs-common 0.2.0-dev.202301161405 → 0.2.0-dev.202301231327

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.
@@ -530,6 +530,14 @@ export class DateObject {
530
530
  literal: ""
531
531
  };
532
532
  });
533
+ const flatDateParts = dateParts.partMap
534
+ .map((x) => {
535
+ return {
536
+ type: x.type,
537
+ pattern: x.pattern,
538
+ text: ""
539
+ };
540
+ });
533
541
  for (let i = 0; i < datePartsLiterals.length; i++) {
534
542
  const datePart = datePartsLiterals[i];
535
543
  for (let j = 0; j < datePart.pattern.length; j++) {
@@ -539,13 +547,23 @@ export class DateObject {
539
547
  }
540
548
  i += datePart.pattern.length - 1;
541
549
  }
550
+ for (let i = 0; i < flatDateParts.length; i++) {
551
+ const datePart = flatDateParts[i];
552
+ for (let j = 0; j < datePart.pattern.length; j++) {
553
+ if (flatDateParts[i + j]) {
554
+ flatDateParts[i + j].text = datePart.pattern[j];
555
+ }
556
+ }
557
+ i += datePart.pattern.length - 1;
558
+ }
542
559
  let shouldResetPart = isInCaretMode && symbol === "M" && dateParts.partMap
543
560
  .filter(x => x.type === "month")
544
561
  .some(x => x.pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD);
545
562
  let parseResult = {
546
563
  value: null,
547
564
  switchPart: false,
548
- resetPart: shouldResetPart
565
+ resetPart: shouldResetPart,
566
+ hasInvalidDatePart: false
549
567
  };
550
568
  if (!currentChar) {
551
569
  if (isInCaretMode) {
@@ -579,13 +597,19 @@ export class DateObject {
579
597
  let basePrefix = '';
580
598
  let baseSuffix = '';
581
599
  let suffix = '';
582
- const datePartStartIndex = originalFormat.indexOf(symbol);
583
- const datePartEndIndex = originalFormat.lastIndexOf(symbol);
584
- const segmentLength = datePartEndIndex - datePartStartIndex + 1;
600
+ let convertedBaseFormat = "";
601
+ for (let i = 0; i < flatDateParts.length; i++) {
602
+ convertedBaseFormat += flatDateParts[i].text;
603
+ }
585
604
  const hasFixedFormat = (this.format === baseFormat) ||
605
+ (this.format === convertedBaseFormat) ||
586
606
  (this.format === originalFormat) ||
587
607
  (this.format.length === originalFormat.length);
608
+ const datePartStartIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).indexOf(symbol);
609
+ const datePartEndIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).lastIndexOf(symbol);
610
+ const segmentLength = datePartEndIndex - datePartStartIndex + 1;
588
611
  let processedSegmentCharsCount = 0;
612
+ let formatToTextLengthDiff = originalFormat.length - rawInputValue.length;
589
613
  if (isInCaretMode || (!isInCaretMode && !this.autoCorrectParts)) {
590
614
  for (let i = 0; i < baseDate.length; i++) {
591
615
  if (baseFormat[i] === symbol) {
@@ -598,6 +622,11 @@ export class DateObject {
598
622
  }
599
623
  processedSegmentCharsCount++;
600
624
  }
625
+ else if (formatToTextLengthDiff > 0) {
626
+ if (datePartText.length + formatToTextLengthDiff < segmentLength) {
627
+ datePartText += rawInputValue[i] || "";
628
+ }
629
+ }
601
630
  else {
602
631
  datePartText += rawInputValue[i] || "";
603
632
  }
@@ -612,13 +641,13 @@ export class DateObject {
612
641
  baseSuffix += baseDate[i];
613
642
  }
614
643
  }
615
- if (hasFixedFormat && this.autoCorrectParts) {
616
- if (originalFormat.length < rawInputValue.length) {
644
+ if (hasFixedFormat) {
645
+ if (convertedBaseFormat.length < rawInputValue.length) {
617
646
  datePartText += currentChar;
618
647
  }
619
648
  else if (!isDeleting && originalFormat.length > rawInputValue.length) {
620
649
  const lengthDiff = originalFormat.length - rawInputValue.length;
621
- const trimmedDatePartText = datePartText.substring(0, datePartText.length - lengthDiff);
650
+ const trimmedDatePartText = datePartText.substr(0, datePartText.length - lengthDiff);
622
651
  if (trimmedDatePartText && trimmedDatePartText.length > 0) {
623
652
  datePartText = trimmedDatePartText;
624
653
  }
@@ -627,7 +656,7 @@ export class DateObject {
627
656
  return extend(parseResult, { value: null, switchToNext: false });
628
657
  }
629
658
  }
630
- else {
659
+ if (!hasFixedFormat || (hasFixedFormat && !this.autoCorrectParts)) {
631
660
  processedSegmentCharsCount = 0;
632
661
  current = "";
633
662
  datePartText = "";
@@ -645,6 +674,11 @@ export class DateObject {
645
674
  }
646
675
  processedSegmentCharsCount++;
647
676
  }
677
+ else if (formatToTextLengthDiff > 0) {
678
+ if (datePartText.length + formatToTextLengthDiff < segmentLength) {
679
+ datePartText += rawInputValue[i] || "";
680
+ }
681
+ }
648
682
  else {
649
683
  datePartText += rawInputValue[i] || "";
650
684
  }
@@ -654,24 +688,12 @@ export class DateObject {
654
688
  prefix += rawInputValue[i] || "";
655
689
  }
656
690
  else {
657
- suffix += rawInputValue[i] || "";
691
+ suffix += rawInputValue[i - formatToTextLengthDiff] || "";
658
692
  }
659
693
  }
660
694
  if (originalFormat.length < rawInputValue.length) {
661
695
  datePartText += currentChar;
662
696
  }
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
- const originalDatePartText = datePartText;
668
- datePartText = trimmedDatePartText;
669
- if (prefix + datePartText + suffix !== rawInputValue) {
670
- // move trimmed characters to the suffix
671
- suffix = originalDatePartText.substring(datePartText.length) + suffix;
672
- }
673
- }
674
- }
675
697
  }
676
698
  }
677
699
  if (!isInCaretMode) {
@@ -701,12 +723,17 @@ export class DateObject {
701
723
  }
702
724
  }
703
725
  let parsedDate = null;
704
- const month = this.matchMonth(currentChar);
726
+ let month = this.matchMonth(currentChar);
705
727
  const dayPeriod = this.matchDayPeriod(currentChar, symbol);
706
728
  const isZeroCurrentChar = currentChar === '0';
707
729
  const leadingZero = this.leadingZero || {};
708
- if (isZeroCurrentChar && !isInCaretMode) {
709
- let valueNumber = parseInt(resetSegmentValue ? currentChar : current + currentChar, 10);
730
+ if (isZeroCurrentChar) {
731
+ if (datePartText === "0") {
732
+ datePartText = current;
733
+ }
734
+ let valueNumber = parseToInt(resetSegmentValue ?
735
+ currentChar :
736
+ (isInCaretMode ? datePartText : current) + currentChar);
710
737
  if (valueNumber === 0 && !this.isAbbrMonth(dateParts.partMap, symbol)) {
711
738
  this.incrementLeadingZero(symbol);
712
739
  }
@@ -734,23 +761,15 @@ export class DateObject {
734
761
  isInCaretMode ?
735
762
  datePartText :
736
763
  (current.substring(i) + currentChar);
737
- if (!this.autoCorrectParts) {
738
- tryParse = false;
739
- if (!isInCaretMode) {
740
- // try to make an exact match as there will be only 1 attempt
741
- middle = unpadZero(middle);
742
- middle = padZero(segmentLength - middle.length) + middle;
743
- }
744
- }
745
- if (isInCaretMode) {
746
- // try to make an exact match as there will be only 1 attempt
764
+ if (isInCaretMode || !this.autoCorrectParts) {
747
765
  tryParse = false;
748
766
  middle = unpadZero(middle);
767
+ middle = padZero(segmentLength - middle.length) + middle;
749
768
  }
750
769
  let middleNumber = parseInt(middle, 10);
751
770
  const candidateDateString = prefix + middle + suffix;
752
771
  parsedDate = this.intl.parseDate(candidateDateString, this.format, this.localeId);
753
- if (isInCaretMode && !hasFixedFormat && !isValidDate(parsedDate)) {
772
+ if (isInCaretMode && !isValidDate(parsedDate)) {
754
773
  // if part of the date is not available, e.g. "d"
755
774
  // but an expanded format like "F" is used
756
775
  // the element value can be "EEEE, February 1, 2022 3:04:05 AM"
@@ -760,7 +779,6 @@ export class DateObject {
760
779
  // as "EEEE, February..." is not parsable
761
780
  if (this.autoCorrectParts) {
762
781
  parsedDate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
763
- datePartText = middle;
764
782
  }
765
783
  }
766
784
  const isCurrentCharParsable = !isNaN(parseInt(currentChar, 10)) || (isInCaretMode && isDeleting && currentChar === "");
@@ -787,13 +805,10 @@ export class DateObject {
787
805
  if ((isInCaretMode && isValidDate(parsedDate)) || (!isInCaretMode && parsedDate)) {
788
806
  // move to next segment if the part will overflow with next char
789
807
  // when start from empty date (01, then 010), padded zeros should be trimmed
790
- const peekDate = this.intl.parseDate(`${prefix}${this.peek(middle, patternValue)}${suffix}`, this.format, this.localeId);
791
- const patternLength = this.patternLength(patternValue) || patternValue.length;
792
- const leadingZeroOffset = (this.leadingZero || {})[symbol] || 0;
793
- const patternSatisfied = (leadingZeroOffset + (unpadZero(middle) || currentChar).length) >= patternLength;
794
- let switchToNext = peekDate === null ||
795
- (leadingZero[symbol] && patternValue.length <= middle.length) ||
796
- patternSatisfied;
808
+ const peekValue = this.peek(middle, patternValue);
809
+ const peekDateString = `${prefix}${peekValue}${suffix}`;
810
+ const peekDate = this.intl.parseDate(peekDateString, this.format, this.localeId);
811
+ let switchToNext = peekDate === null || (leadingZero[symbol] && patternValue.length <= middle.length) || false;
797
812
  if (this.shouldNormalizeCentury()) {
798
813
  parsedDate = this.normalizeCentury(parsedDate);
799
814
  }
@@ -821,14 +836,12 @@ export class DateObject {
821
836
  }
822
837
  if (isInCaretMode && switchToNext) {
823
838
  if (symbol === "M") {
824
- if (segmentLength <= MONTH_PART_WITH_WORDS_THRESHOLD) {
825
- const datePartValue = parseToInt(datePartText);
826
- if (datePartValue >= 2) {
827
- switchToNext = true;
828
- }
829
- else {
830
- switchToNext = false;
831
- }
839
+ const datePartValue = parseToInt(datePartText);
840
+ if (datePartValue >= 2 || datePartText.length >= 2) {
841
+ switchToNext = true;
842
+ }
843
+ else {
844
+ switchToNext = false;
832
845
  }
833
846
  }
834
847
  else {
@@ -861,9 +874,6 @@ export class DateObject {
861
874
  this.leadingZero = !this.isAbbrMonth(dateParts.partMap, symbol) ? { [symbol]: true } : null;
862
875
  this.setExisting(symbol, false);
863
876
  }
864
- if (isInCaretMode && datePartText.length > segmentLength) {
865
- return extend(parseResult, { value: null, switchToNext: false });
866
- }
867
877
  if (!this.autoCorrectParts) {
868
878
  let datePartValue;
869
879
  const textToParse = isInCaretMode ? datePartText : middle;
@@ -874,20 +884,146 @@ export class DateObject {
874
884
  return extend(parseResult, { value: null, switchToNext: false });
875
885
  }
876
886
  datePartValue = symbol === "M" ?
877
- clamp(parsedValue - JS_MONTH_OFFSET, 0, 12 - JS_MONTH_OFFSET) :
887
+ parsedValue - JS_MONTH_OFFSET :
878
888
  parsedValue;
879
- // if (!isEqual(newDate, this.value)) {
880
- this.setExisting(symbol, false);
881
- this.setInvalidDatePart(symbol, {
882
- value: datePartValue,
883
- date: cloneDate(this.value),
884
- startDate: this._partiallyInvalidDate.startDate || cloneDate(this.value)
885
- });
886
- // }
889
+ const isMonth = symbol === "M";
890
+ const isDay = symbol === "d";
891
+ let newValue = cloneDate(this._value);
892
+ const invalidDateParts = this._partiallyInvalidDate.invalidDateParts || {};
893
+ let year = invalidDateParts.y.value || newValue.getFullYear();
894
+ /* tslint:disable:no-shadowed-variable */
895
+ let month = isMonth ? datePartValue : invalidDateParts.M.value || newValue.getMonth();
896
+ /* tslint:enable:no-shadowed-variable */
897
+ let day = isDay ? datePartValue : invalidDateParts.d.value || invalidDateParts.E.value || newValue.getDate();
898
+ let hour = invalidDateParts.h.value || invalidDateParts.H.value || newValue.getHours();
899
+ let minutes = invalidDateParts.m.value || newValue.getMinutes();
900
+ let seconds = invalidDateParts.s.value || newValue.getSeconds();
901
+ let milliseconds = invalidDateParts.S.value || newValue.getMilliseconds();
902
+ const dateCandidate = createDate(year, month, day, hour, minutes, seconds, milliseconds);
903
+ const dateCandidateExists = areDatePartsEqualTo(dateCandidate, year, month, day, hour, minutes, seconds, milliseconds);
904
+ const newValueCandidate = isMonth || isDay ?
905
+ this.modifyDateSymbolWithValue(newValue, symbol, isMonth ? month : day) :
906
+ null;
907
+ let invalidDateFound = false;
908
+ if (isMonth && newValueCandidate) {
909
+ if (newValueCandidate.getMonth() === month) {
910
+ if (this.getExisting("d")) {
911
+ if (dateCandidateExists) {
912
+ newValue = cloneDate(dateCandidate);
913
+ this.resetInvalidDateSymbol(symbol);
914
+ }
915
+ else {
916
+ invalidDateFound = true;
917
+ this.setInvalidDatePart(symbol, {
918
+ value: month,
919
+ date: cloneDate(newValueCandidate),
920
+ // startDateOffset: offset,
921
+ startDate: cloneDate(this.value)
922
+ });
923
+ this.setExisting(symbol, false);
924
+ }
925
+ }
926
+ else if (dateCandidateExists) {
927
+ this.resetInvalidDateSymbol(symbol);
928
+ newValue = cloneDate(dateCandidate);
929
+ if (this.getExisting("M") && this.getExisting("y")) {
930
+ // changing from 28/Feb to 29/Feb to 29/March
931
+ this.setExisting("d", true);
932
+ this.resetInvalidDateSymbol("d");
933
+ }
934
+ }
935
+ else {
936
+ this.resetInvalidDateSymbol(symbol);
937
+ newValue = cloneDate(newValueCandidate);
938
+ }
939
+ }
940
+ else {
941
+ invalidDateFound = true;
942
+ this.setInvalidDatePart(symbol, {
943
+ value: month,
944
+ date: cloneDate(newValueCandidate),
945
+ // startDateOffset: offset,
946
+ startDate: cloneDate(this.value)
947
+ });
948
+ this.setExisting(symbol, false);
949
+ }
950
+ }
951
+ else if (isDay && newValueCandidate) {
952
+ if (newValueCandidate.getDate() === day) {
953
+ if (this.getExisting("M")) {
954
+ if (dateCandidateExists) {
955
+ newValue = cloneDate(dateCandidate);
956
+ this.resetInvalidDateSymbol(symbol);
957
+ }
958
+ else {
959
+ invalidDateFound = true;
960
+ this.setInvalidDatePart(symbol, {
961
+ value: day,
962
+ date: cloneDate(newValueCandidate),
963
+ // startDateOffset: offset,
964
+ startDate: cloneDate(this.value)
965
+ });
966
+ this.setExisting(symbol, false);
967
+ }
968
+ }
969
+ else if (dateCandidateExists) {
970
+ newValue = cloneDate(dateCandidate);
971
+ this.resetInvalidDateSymbol(symbol);
972
+ if (this.getExisting("d") && this.getExisting("y")) {
973
+ // changing from 31/Jan to 31/Feb to 28/Feb
974
+ this.setExisting("M", true);
975
+ this.resetInvalidDateSymbol("M");
976
+ }
977
+ }
978
+ else {
979
+ this.resetInvalidDateSymbol(symbol);
980
+ newValue = cloneDate(newValueCandidate);
981
+ }
982
+ }
983
+ else {
984
+ invalidDateFound = true;
985
+ this.setInvalidDatePart(symbol, {
986
+ value: day,
987
+ date: cloneDate(this.value),
988
+ // startDateOffset: offset,
989
+ startDate: cloneDate(this.value)
990
+ });
991
+ this.setExisting(symbol, false);
992
+ }
993
+ }
994
+ if (!invalidDateFound) {
995
+ this.setExisting(symbol, true);
996
+ if (isInCaretMode && !isValidDate(parsedDate)) {
997
+ const valueCandidate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
998
+ if (isValidDate(valueCandidate)) {
999
+ this._value = valueCandidate;
1000
+ }
1001
+ }
1002
+ else {
1003
+ this._value = newValue;
1004
+ }
1005
+ if (this.getValue()) {
1006
+ this.resetInvalidDate();
1007
+ }
1008
+ }
1009
+ let switchToNext = false;
1010
+ if (symbol === "M") {
1011
+ if (parsedValue >= 2 || textToParse.length >= 2) {
1012
+ switchToNext = true;
1013
+ }
1014
+ else {
1015
+ switchToNext = false;
1016
+ }
1017
+ }
1018
+ else {
1019
+ switchToNext = hasFixedFormat ?
1020
+ textToParse.length === segmentLength :
1021
+ textToParse.length > segmentLength;
1022
+ }
887
1023
  return extend(parseResult, {
888
1024
  value: null,
889
- switchToNext: false,
890
- hasInvalidDatePart: true
1025
+ switchToNext: switchToNext,
1026
+ hasInvalidDatePart: invalidDateFound
891
1027
  });
892
1028
  }
893
1029
  }
@@ -910,6 +1046,12 @@ export class DateObject {
910
1046
  setLeadingZero(leadingZero) {
911
1047
  this.leadingZero = leadingZero;
912
1048
  }
1049
+ /**
1050
+ * @hidden
1051
+ */
1052
+ getLeadingZero() {
1053
+ return this.leadingZero || {};
1054
+ }
913
1055
  /**
914
1056
  * @hidden
915
1057
  */
@@ -992,7 +1134,6 @@ export class DateObject {
992
1134
  const dateFormatParts = this.intl.splitDateFormat(this.format, this.localeId);
993
1135
  for (let i = 0; i < dateFormatParts.length; i++) {
994
1136
  if (dateFormatParts[i].type === 'month' && dateFormatParts[i].names) {
995
- // return this.intl.dateFormatNames(dateFormatParts[i].names);
996
1137
  return this.intl.dateFormatNames(locale, dateFormatParts[i].names);
997
1138
  }
998
1139
  }
@@ -1200,15 +1341,8 @@ export class DateObject {
1200
1341
  return (invalidDatePart || {}).value;
1201
1342
  }
1202
1343
  setInvalidDatePart(symbol, { value = null, date = null, startDateOffset = 0, startDate = null }) {
1203
- let clampedValue = value;
1204
- if (symbol === "d") {
1205
- clampedValue = clamp(isPresent(value) ? value : 1, 1, 31);
1206
- }
1207
- else if (symbol === "M") {
1208
- clampedValue = clamp(isPresent(value) ? value : 0, 0, 11);
1209
- }
1210
1344
  if (this._partiallyInvalidDate.invalidDateParts[symbol]) {
1211
- this._partiallyInvalidDate.invalidDateParts[symbol].value = clampedValue;
1345
+ this._partiallyInvalidDate.invalidDateParts[symbol].value = value;
1212
1346
  this._partiallyInvalidDate.invalidDateParts[symbol].date = date;
1213
1347
  this._partiallyInvalidDate.invalidDateParts[symbol].startDateOffset = startDateOffset;
1214
1348
  this._partiallyInvalidDate.startDate = startDate;
@@ -29,6 +29,7 @@ const CHANGE = "change";
29
29
  const defaultDateInputOptions = {
30
30
  format: "d",
31
31
  allowNulls: false,
32
+ hasPlaceholder: false,
32
33
  placeholder: null,
33
34
  cycleTime: true,
34
35
  locale: null,
@@ -286,7 +287,7 @@ export class DateInput extends Observable {
286
287
  text = currentText;
287
288
  }
288
289
  const newText = this.elementValue;
289
- const diff = approximateStringMatching({
290
+ let diff = approximateStringMatching({
290
291
  oldText: text,
291
292
  newText: newText,
292
293
  formatPattern: this.currentFormat,
@@ -294,6 +295,24 @@ export class DateInput extends Observable {
294
295
  isInCaretMode: hasCaret,
295
296
  keyEvent: this.keyDownEvent
296
297
  });
298
+ const currentFormatChar = this.formatStateOnKeyDown.format[this.formatStateOnKeyDown.selectionStart] || "";
299
+ if (this.options.allowCaretMode && hasCaret && this.currentFormat.length !== this.elementValue.length) {
300
+ if (currentFormatChar &&
301
+ currentFormatChar.length > 0 &&
302
+ currentFormatChar !== Constants.formatSeparator) {
303
+ if (!diff || diff.length === 0) {
304
+ diff = [];
305
+ diff[0][0] = currentFormatChar;
306
+ diff[0][1] = e.data || "";
307
+ }
308
+ else if (diff[0] && diff[0][0] !== Constants.formatSeparator) {
309
+ if (diff[0][0] !== currentFormatChar) {
310
+ diff[0][0] = currentFormatChar;
311
+ diff[0][1] = e.data || "";
312
+ }
313
+ }
314
+ }
315
+ }
297
316
  if (hasCaret && (!diff || diff.length === 0)) {
298
317
  this.restorePreviousInputEventState();
299
318
  return;
@@ -366,10 +385,30 @@ export class DateInput extends Observable {
366
385
  if (switchPart) {
367
386
  this.switchDateSegment(1);
368
387
  }
388
+ else {
389
+ if (this.options.format.length !== this.currentFormat.length &&
390
+ currentFormatChar && currentFormatChar !== "y") {
391
+ const elementValueLength = this.elementValue.length;
392
+ this.forceUpdate();
393
+ const selectionOffset = this.elementValue.length - elementValueLength;
394
+ this.setSelection({
395
+ start: currentSelection.start + selectionOffset,
396
+ end: currentSelection.start + selectionOffset
397
+ });
398
+ }
399
+ }
369
400
  }
370
401
  else {
371
- if (lastParseResultHasNoValue && !hasInvalidDatePart) {
372
- this.restorePreviousInputEventState();
402
+ if (lastParseResultHasNoValue) {
403
+ let hasLeadingZero = this.dateObject.getLeadingZero()[currentFormatChar];
404
+ if (switchPart) {
405
+ this.switchDateSegment(1);
406
+ }
407
+ else if (e.data === "0" && hasLeadingZero) {
408
+ }
409
+ else {
410
+ this.restorePreviousInputEventState();
411
+ }
373
412
  }
374
413
  }
375
414
  }
@@ -394,7 +433,10 @@ export class DateInput extends Observable {
394
433
  }
395
434
  }
396
435
  else {
397
- if (!hasInvalidDatePart) {
436
+ let hasLeadingZero = this.dateObject.getLeadingZero()[currentFormatChar];
437
+ if (e.data === "0" && hasLeadingZero) {
438
+ }
439
+ else if (!hasInvalidDatePart) {
398
440
  this.restorePreviousInputEventState();
399
441
  }
400
442
  }
@@ -458,9 +500,14 @@ export class DateInput extends Observable {
458
500
  if (this.triggerKeyDown({ event: e })) {
459
501
  return;
460
502
  }
503
+ const { start, end } = this.selection;
461
504
  this.keyDownEvent = e;
462
505
  this.previousElementValue = this.element.value;
463
- const { start, end } = this.selection;
506
+ this.formatStateOnKeyDown = {
507
+ format: this.currentFormat,
508
+ selectionStart: start,
509
+ selectionEnd: end
510
+ };
464
511
  this.previousElementSelection = { start, end };
465
512
  const autoSwitchKeys = (this.options.autoSwitchKeys || [])
466
513
  .map(x => x.toString().toLowerCase().trim());
@@ -714,11 +761,13 @@ export class DateInput extends Observable {
714
761
  return;
715
762
  }
716
763
  }
764
+ this.interactionMode = DateInputInteractionMode.None;
717
765
  let { start: selectionStart, end: selectionEnd } = this.selection;
718
766
  if (selectionStart < selectionEnd &&
719
767
  this.currentFormat[selectionStart] !== this.currentFormat[selectionEnd - 1]) {
720
768
  this.setSelection(this.selectionByIndex(offset > 0 ? selectionStart : selectionEnd - 1));
721
769
  this.resetSegmentValue = true;
770
+ this.interactionMode = DateInputInteractionMode.None;
722
771
  return;
723
772
  }
724
773
  const previousFormatSymbol = this.currentFormat[selectionStart];
@@ -749,6 +798,7 @@ export class DateInput extends Observable {
749
798
  this.setSelection({ start: a, end: b });
750
799
  this.resetSegmentValue = true;
751
800
  }
801
+ this.interactionMode = DateInputInteractionMode.None;
752
802
  }
753
803
  modifyDateSegmentValue(offset, symbol = "", event = {}) {
754
804
  if (!this.dateObject) {
@@ -937,13 +987,14 @@ export class DateInput extends Observable {
937
987
  const { text: currentText, format: currentFormat } = this.dateObject.getTextAndFormat(format);
938
988
  this.currentFormat = currentFormat;
939
989
  this.currentText = currentText;
990
+ const hasPlaceholder = this.options.hasPlaceholder || isPresent(this.options.placeholder);
940
991
  const showPlaceholder = !this.isActive &&
941
- isPresent(this.options.placeholder) &&
992
+ hasPlaceholder &&
942
993
  !this.dateObject.hasValue();
943
- if (isPresent(this.options.placeholder)) {
994
+ if (hasPlaceholder && isPresent(this.options.placeholder)) {
944
995
  element.placeholder = this.options.placeholder;
945
996
  }
946
- const newElementValue = !showPlaceholder ? currentText : "";
997
+ const newElementValue = showPlaceholder ? "" : currentText;
947
998
  this.previousElementValue = this.elementValue;
948
999
  this.setElementValue(newElementValue);
949
1000
  if (this.isActive && !this.options.allowCaretMode && this.options.selectNearestSegmentOnFocus) {
@@ -81,6 +81,10 @@ export declare class DateObject {
81
81
  */
82
82
  resetLeadingZero(): boolean;
83
83
  setLeadingZero(leadingZero: any): void;
84
+ /**
85
+ * @hidden
86
+ */
87
+ getLeadingZero(): any;
84
88
  /**
85
89
  * @hidden
86
90
  */