From 70dd6bf19cf34c01d102048a1adafe0d4f0bd1d8 Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Wed, 8 May 2024 14:06:03 +0300
Subject: [PATCH 01/11] feat(kit): added suppoer of SS.MSS and MM:SS.MSS
---
.../src/lib/masks/date-time/date-time-mask.ts | 1 +
.../min-max-date-time-postprocessor.ts | 2 +-
.../valid-date-time-preprocessor.ts | 3 ++
.../processors/max-validation-preprocessor.ts | 3 ++
.../tests/max-validation-preprocessor.spec.ts | 5 ++-
projects/kit/src/lib/masks/time/time-mask.ts | 2 +-
projects/kit/src/lib/types/time-mode.ts | 8 +++-
.../src/lib/utils/time/parse-time-string.ts | 43 ++++++++++++++++---
.../kit/src/lib/utils/time/to-time-string.ts | 7 +--
.../lib/utils/time/validate-time-string.ts | 4 +-
10 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/projects/kit/src/lib/masks/date-time/date-time-mask.ts b/projects/kit/src/lib/masks/date-time/date-time-mask.ts
index 2cad6759b..a30500f19 100644
--- a/projects/kit/src/lib/masks/date-time/date-time-mask.ts
+++ b/projects/kit/src/lib/masks/date-time/date-time-mask.ts
@@ -64,6 +64,7 @@ export function maskitoDateTimeOptionsGenerator({
dateModeTemplate,
dateSegmentsSeparator: dateSeparator,
dateTimeSeparator,
+ timeMode,
}),
],
postprocessors: [
diff --git a/projects/kit/src/lib/masks/date-time/postprocessors/min-max-date-time-postprocessor.ts b/projects/kit/src/lib/masks/date-time/postprocessors/min-max-date-time-postprocessor.ts
index 61a807fd5..d52fbc8d8 100644
--- a/projects/kit/src/lib/masks/date-time/postprocessors/min-max-date-time-postprocessor.ts
+++ b/projects/kit/src/lib/masks/date-time/postprocessors/min-max-date-time-postprocessor.ts
@@ -33,7 +33,7 @@ export function createMinMaxDateTimePostprocessor({
dateTimeSeparator,
});
const parsedDate = parseDateString(dateString, dateModeTemplate);
- const parsedTime = parseTimeString(timeString);
+ const parsedTime = parseTimeString(timeString, timeMode);
if (
!isDateTimeStringComplete(value, {
diff --git a/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts b/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
index e504bee13..834cdc95f 100644
--- a/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
+++ b/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
@@ -9,10 +9,12 @@ export function createValidDateTimePreprocessor({
dateModeTemplate,
dateSegmentsSeparator,
dateTimeSeparator,
+ timeMode,
}: {
dateModeTemplate: string;
dateSegmentsSeparator: string;
dateTimeSeparator: string;
+ timeMode: string;
}): MaskitoPreprocessor {
const invalidCharsRegExp = new RegExp(
`[^\\d${TIME_FIXED_CHARACTERS.map(escapeRegExp).join('')}${escapeRegExp(
@@ -69,6 +71,7 @@ export function createValidDateTimePreprocessor({
paddedMaxValues,
offset: validatedValue.length + dateTimeSeparator.length,
selection: [from, to],
+ timeMode,
});
if (timeString && !validatedTimeString) {
diff --git a/projects/kit/src/lib/masks/time/processors/max-validation-preprocessor.ts b/projects/kit/src/lib/masks/time/processors/max-validation-preprocessor.ts
index ffb010fbd..1f6353c94 100644
--- a/projects/kit/src/lib/masks/time/processors/max-validation-preprocessor.ts
+++ b/projects/kit/src/lib/masks/time/processors/max-validation-preprocessor.ts
@@ -7,6 +7,7 @@ import {padTimeSegments, validateTimeString} from '../../../utils/time';
export function createMaxValidationPreprocessor(
timeSegmentMaxValues: MaskitoTimeSegments,
+ timeMode: string,
): MaskitoPreprocessor {
const paddedMaxValues = padTimeSegments(timeSegmentMaxValues);
const invalidCharsRegExp = new RegExp(
@@ -26,6 +27,7 @@ export function createMaxValidationPreprocessor(
paddedMaxValues,
offset: 0,
selection,
+ timeMode,
});
return {
@@ -47,6 +49,7 @@ export function createMaxValidationPreprocessor(
paddedMaxValues,
offset: 0,
selection: [from, to],
+ timeMode,
});
if (newPossibleValue && !validatedTimeString) {
diff --git a/projects/kit/src/lib/masks/time/processors/tests/max-validation-preprocessor.spec.ts b/projects/kit/src/lib/masks/time/processors/tests/max-validation-preprocessor.spec.ts
index daa824454..a33bd2f8d 100644
--- a/projects/kit/src/lib/masks/time/processors/tests/max-validation-preprocessor.spec.ts
+++ b/projects/kit/src/lib/masks/time/processors/tests/max-validation-preprocessor.spec.ts
@@ -2,7 +2,10 @@ import {DEFAULT_TIME_SEGMENT_MAX_VALUES} from '../../../../constants';
import {createMaxValidationPreprocessor} from '../max-validation-preprocessor';
describe('createMaxValidationPreprocessor', () => {
- const processor = createMaxValidationPreprocessor(DEFAULT_TIME_SEGMENT_MAX_VALUES);
+ const processor = createMaxValidationPreprocessor(
+ DEFAULT_TIME_SEGMENT_MAX_VALUES,
+ 'HH:MM:SS',
+ );
describe('Paste from clipboard', () => {
const process = (data: string): string =>
diff --git a/projects/kit/src/lib/masks/time/time-mask.ts b/projects/kit/src/lib/masks/time/time-mask.ts
index 50608ad67..d017f19cf 100644
--- a/projects/kit/src/lib/masks/time/time-mask.ts
+++ b/projects/kit/src/lib/masks/time/time-mask.ts
@@ -31,7 +31,7 @@ export function maskitoTimeOptionsGenerator({
createFullWidthToHalfWidthPreprocessor(),
createColonConvertPreprocessor(),
createZeroPlaceholdersPreprocessor(),
- createMaxValidationPreprocessor(enrichedTimeSegmentMaxValues),
+ createMaxValidationPreprocessor(enrichedTimeSegmentMaxValues, mode),
],
overwriteMode: 'replace',
};
diff --git a/projects/kit/src/lib/types/time-mode.ts b/projects/kit/src/lib/types/time-mode.ts
index 20d0af8fb..364d77815 100644
--- a/projects/kit/src/lib/types/time-mode.ts
+++ b/projects/kit/src/lib/types/time-mode.ts
@@ -1 +1,7 @@
-export type MaskitoTimeMode = 'HH:MM:SS.MSS' | 'HH:MM:SS' | 'HH:MM' | 'HH';
+export type MaskitoTimeMode =
+ | 'HH:MM:SS.MSS'
+ | 'HH:MM:SS'
+ | 'HH:MM'
+ | 'HH'
+ | 'MM:SS.MSS'
+ | 'SS.MSS';
diff --git a/projects/kit/src/lib/utils/time/parse-time-string.ts b/projects/kit/src/lib/utils/time/parse-time-string.ts
index f9660ea19..95516a870 100644
--- a/projects/kit/src/lib/utils/time/parse-time-string.ts
+++ b/projects/kit/src/lib/utils/time/parse-time-string.ts
@@ -3,17 +3,50 @@ import type {MaskitoTimeSegments} from '../../types';
/**
* @param timeString can be with/without fixed characters
*/
-export function parseTimeString(timeString: string): Partial {
+export function parseTimeString(
+ timeString: string,
+ timeMode: string,
+): Partial {
const onlyDigits = timeString.replaceAll(/\D+/g, '');
+ const sliceIndexes = createSliceIndexes({
+ isStartsWithMilliseconds: timeMode.startsWith('MSS'),
+ isStartsWithMinutes: timeMode.startsWith('MM'),
+ isStartsWithSeconds: timeMode.startsWith('SS'),
+ });
+
const timeSegments = {
- hours: onlyDigits.slice(0, 2),
- minutes: onlyDigits.slice(2, 4),
- seconds: onlyDigits.slice(4, 6),
- milliseconds: onlyDigits.slice(6, 9),
+ hours: onlyDigits.slice(...sliceIndexes.hours),
+ minutes: onlyDigits.slice(...sliceIndexes.minutes),
+ seconds: onlyDigits.slice(...sliceIndexes.seconds),
+ milliseconds: onlyDigits.slice(...sliceIndexes.milliseconds),
};
return Object.fromEntries(
Object.entries(timeSegments).filter(([_, value]) => Boolean(value)),
);
}
+
+function createSliceIndexes({
+ isStartsWithMinutes,
+ isStartsWithSeconds,
+ isStartsWithMilliseconds,
+}: {
+ isStartsWithMinutes: boolean;
+ isStartsWithSeconds: boolean;
+ isStartsWithMilliseconds: boolean;
+}): MaskitoTimeSegments<[number, number]> {
+ const offset =
+ Number(isStartsWithMinutes) * 2 +
+ Number(isStartsWithSeconds) * 4 +
+ Number(isStartsWithMilliseconds) * 6;
+
+ const changeSelection = (index: number): number => Math.max(index - offset, 0);
+
+ return {
+ hours: [changeSelection(0), changeSelection(2)],
+ minutes: [changeSelection(2), changeSelection(4)],
+ seconds: [changeSelection(4), changeSelection(6)],
+ milliseconds: [changeSelection(6), changeSelection(9)],
+ };
+}
diff --git a/projects/kit/src/lib/utils/time/to-time-string.ts b/projects/kit/src/lib/utils/time/to-time-string.ts
index e7a6ad17c..4b5536086 100644
--- a/projects/kit/src/lib/utils/time/to-time-string.ts
+++ b/projects/kit/src/lib/utils/time/to-time-string.ts
@@ -6,9 +6,10 @@ export function toTimeString({
seconds = '',
milliseconds = '',
}: Partial): string {
- const mm = minutes && `:${minutes}`;
- const ss = seconds && `:${seconds}`;
- const ms = milliseconds && `.${milliseconds}`;
+ const mm = hours ? minutes && `:${minutes}` : minutes;
+ const ss = hours || minutes ? seconds && `:${seconds}` : seconds;
+ const ms =
+ hours || minutes || seconds ? milliseconds && `.${milliseconds}` : milliseconds;
return `${hours}${mm}${ss}${ms}`;
}
diff --git a/projects/kit/src/lib/utils/time/validate-time-string.ts b/projects/kit/src/lib/utils/time/validate-time-string.ts
index 1e76990f7..b6a34e5e7 100644
--- a/projects/kit/src/lib/utils/time/validate-time-string.ts
+++ b/projects/kit/src/lib/utils/time/validate-time-string.ts
@@ -14,13 +14,15 @@ export function validateTimeString({
paddedMaxValues,
offset,
selection: [from, to],
+ timeMode,
}: {
timeString: string;
paddedMaxValues: MaskitoTimeSegments;
offset: number;
selection: readonly [number, number];
+ timeMode: string;
}): {validatedTimeString: string; updatedTimeSelection: [number, number]} {
- const parsedTime = parseTimeString(timeString);
+ const parsedTime = parseTimeString(timeString, timeMode);
const possibleTimeSegments = Object.entries(parsedTime) as Array<
[keyof MaskitoTimeSegments, string]
From fbb43157dcbfcbeb45f434d1e757bce1fa1fc9f4 Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 11 May 2024 09:12:04 +0300
Subject: [PATCH 02/11] refactor(kit): parseTimeString
---
.../supported-input-types.template.html | 13 ++++++++---
.../src/lib/utils/time/parse-time-string.ts | 22 +++++--------------
2 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/projects/demo/src/pages/documentation/supported-input-types/supported-input-types.template.html b/projects/demo/src/pages/documentation/supported-input-types/supported-input-types.template.html
index 101adbc8b..b020b9a4d 100644
--- a/projects/demo/src/pages/documentation/supported-input-types/supported-input-types.template.html
+++ b/projects/demo/src/pages/documentation/supported-input-types/supported-input-types.template.html
@@ -13,15 +13,22 @@
- selectionStart
- selectionEnd
- setSelectionRange
+ -
+
selectionStart
+
+ -
+
selectionEnd
+
+ -
+
setSelectionRange
+
According to the
diff --git a/projects/kit/src/lib/utils/time/parse-time-string.ts b/projects/kit/src/lib/utils/time/parse-time-string.ts
index 95516a870..c361bfcb2 100644
--- a/projects/kit/src/lib/utils/time/parse-time-string.ts
+++ b/projects/kit/src/lib/utils/time/parse-time-string.ts
@@ -9,11 +9,7 @@ export function parseTimeString(
): Partial {
const onlyDigits = timeString.replaceAll(/\D+/g, '');
- const sliceIndexes = createSliceIndexes({
- isStartsWithMilliseconds: timeMode.startsWith('MSS'),
- isStartsWithMinutes: timeMode.startsWith('MM'),
- isStartsWithSeconds: timeMode.startsWith('SS'),
- });
+ const sliceIndexes = createSliceIndexes(timeMode);
const timeSegments = {
hours: onlyDigits.slice(...sliceIndexes.hours),
@@ -27,19 +23,11 @@ export function parseTimeString(
);
}
-function createSliceIndexes({
- isStartsWithMinutes,
- isStartsWithSeconds,
- isStartsWithMilliseconds,
-}: {
- isStartsWithMinutes: boolean;
- isStartsWithSeconds: boolean;
- isStartsWithMilliseconds: boolean;
-}): MaskitoTimeSegments<[number, number]> {
+function createSliceIndexes(timeMode: string): MaskitoTimeSegments<[number, number]> {
const offset =
- Number(isStartsWithMinutes) * 2 +
- Number(isStartsWithSeconds) * 4 +
- Number(isStartsWithMilliseconds) * 6;
+ Number(timeMode.startsWith('MM')) * 2 +
+ Number(timeMode.startsWith('SS')) * 4 +
+ Number(timeMode.startsWith('MSS')) * 6;
const changeSelection = (index: number): number => Math.max(index - offset, 0);
From 7a487d086f0484941a0ff3de5909cf2b96f66149 Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 11 May 2024 09:17:07 +0300
Subject: [PATCH 03/11] docs(demo): added new time modes to api
---
projects/demo/src/pages/kit/time/time-mask-doc.component.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/projects/demo/src/pages/kit/time/time-mask-doc.component.ts b/projects/demo/src/pages/kit/time/time-mask-doc.component.ts
index bde0aff1e..2b8067932 100644
--- a/projects/demo/src/pages/kit/time/time-mask-doc.component.ts
+++ b/projects/demo/src/pages/kit/time/time-mask-doc.component.ts
@@ -49,6 +49,8 @@ export class TimeMaskDocComponent implements GeneratorOptions {
'HH:MM:SS',
'HH:MM:SS.MSS',
'HH',
+ 'MM:SS.MSS',
+ 'SS.MSS',
];
protected readonly timeSegmentMaxValuesOptions: Array<
From b4eed66f8ef5c2c6382bb4d079f7a1cc9733cd2b Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 11 May 2024 10:24:56 +0300
Subject: [PATCH 04/11] test(demo-integrations): added tests for MM:SS.MSS and
SS.MSS
---
.../src/tests/kit/time/time-mode.cy.ts | 236 ++++++++++++++++++
1 file changed, 236 insertions(+)
diff --git a/projects/demo-integrations/src/tests/kit/time/time-mode.cy.ts b/projects/demo-integrations/src/tests/kit/time/time-mode.cy.ts
index 7b7c3aa94..f213625e2 100644
--- a/projects/demo-integrations/src/tests/kit/time/time-mode.cy.ts
+++ b/projects/demo-integrations/src/tests/kit/time/time-mode.cy.ts
@@ -412,5 +412,241 @@ describe('Time', () => {
});
});
});
+
+ describe('MM:SS.MSS', () => {
+ beforeEach(() => {
+ cy.visit(`/${DemoPath.Time}/API?mode=MM:SS.MSS`);
+ cy.get('#demo-content input')
+ .should('be.visible')
+ .first()
+ .focus()
+ .clear()
+ .as('input');
+ });
+
+ describe('Typing new character overwrite character after cursor', () => {
+ it('new character is different from the next one', () => {
+ cy.get('@input')
+ .type('5959999')
+ .type('{moveToStart}')
+ .type('0')
+ .should('have.value', '09:59.999')
+ .should('have.prop', 'selectionStart', '0'.length)
+ .should('have.prop', 'selectionEnd', '0'.length)
+ .type('000')
+ .should('have.value', '00:00.999')
+ .should('have.prop', 'selectionStart', '00:00.'.length)
+ .should('have.prop', 'selectionEnd', '00:00.'.length)
+ .type('00')
+ .should('have.value', '00:00.009')
+ .should('have.prop', 'selectionStart', '00:00.00'.length)
+ .should('have.prop', 'selectionEnd', '00:00.00'.length);
+ });
+
+ it('moves cursor behind next character if new character is the same with the next one', () => {
+ cy.get('@input')
+ .type('59:59.999')
+ .type('{moveToStart}')
+ .type('{rightArrow}'.repeat('59:59.'.length))
+ .type('9')
+ .should('have.value', '59:59.999')
+ .should('have.prop', 'selectionStart', '59:59.9'.length)
+ .should('have.prop', 'selectionEnd', '59:59.9'.length);
+ });
+ });
+
+ it('Pad typed value with zero if digit exceeds the first digit of time segment', () => {
+ cy.get('@input')
+ .type('6')
+ .should('have.value', '06')
+ .should('have.prop', 'selectionStart', '06'.length)
+ .should('have.prop', 'selectionEnd', '06'.length)
+ .type('6')
+ .should('have.value', '06:06')
+ .should('have.prop', 'selectionStart', '06:06'.length)
+ .should('have.prop', 'selectionEnd', '06:06'.length)
+ .type('999')
+ .should('have.value', '06:06.999')
+ .should('have.prop', 'selectionStart', '06:06.999'.length)
+ .should('have.prop', 'selectionEnd', '06:06:999'.length);
+ });
+
+ describe('Select range and press new digit', () => {
+ it(
+ '|59|:59.999 => Type 2 => 2|0:59.999',
+ BROWSER_SUPPORTS_REAL_EVENTS,
+ () => {
+ cy.get('@input')
+ .type('5959999')
+ .should('have.value', '59:59.999')
+ .realPress([
+ ...new Array(':59.999'.length).fill('ArrowLeft'),
+ 'Shift',
+ ...new Array('59'.length).fill('ArrowLeft'),
+ ]);
+
+ cy.get('@input')
+ .type('2')
+ .should('have.value', '20:59.999')
+ .should('have.prop', 'selectionStart', '2'.length)
+ .should('have.prop', 'selectionEnd', '2'.length);
+ },
+ );
+
+ it(
+ '|59|:59.999 => Type 6 => 06:|59.999',
+ BROWSER_SUPPORTS_REAL_EVENTS,
+ () => {
+ cy.get('@input')
+ .type('5959999')
+ .should('have.value', '59:59.999')
+ .realPress([
+ ...new Array(':59.999'.length).fill('ArrowLeft'),
+ 'Shift',
+ ...new Array('59'.length).fill('ArrowLeft'),
+ ]);
+
+ cy.get('@input')
+ .type('6')
+ .should('have.value', '06:59.999')
+ .should('have.prop', 'selectionStart', '06:'.length)
+ .should('have.prop', 'selectionEnd', '06:'.length);
+ },
+ );
+ });
+
+ describe('accepts time segment separators typed by user', () => {
+ it('59 => Type : => 59:', () => {
+ cy.get('@input')
+ .type('59')
+ .should('have.value', '59')
+ .type(':')
+ .should('have.value', '59:')
+ .should('have.prop', 'selectionStart', '59:'.length)
+ .should('have.prop', 'selectionEnd', '59:'.length);
+ });
+
+ it('59:59 => Type . => 59:59.', () => {
+ cy.get('@input')
+ .type('5959')
+ .should('have.value', '59:59')
+ .type('.')
+ .should('have.value', '59:59.')
+ .should('have.prop', 'selectionStart', '59:59.'.length)
+ .should('have.prop', 'selectionEnd', '59:59.'.length);
+ });
+ });
+
+ it('type 5959999 => 59:59.999', () => {
+ cy.get('@input').type('5959999').should('have.value', '59:59.999');
+ });
+ });
+
+ describe('SS.MSS', () => {
+ beforeEach(() => {
+ cy.visit(`/${DemoPath.Time}/API?mode=SS.MSS`);
+ cy.get('#demo-content input')
+ .should('be.visible')
+ .first()
+ .focus()
+ .clear()
+ .as('input');
+ });
+
+ describe('Typing new character overwrite character after cursor', () => {
+ it('new character is different from the next one', () => {
+ cy.get('@input')
+ .type('59999')
+ .type('{moveToStart}')
+ .type('0')
+ .should('have.value', '09.999')
+ .should('have.prop', 'selectionStart', '0'.length)
+ .should('have.prop', 'selectionEnd', '0'.length)
+ .type('0')
+ .should('have.value', '00.999')
+ .should('have.prop', 'selectionStart', '00.'.length)
+ .should('have.prop', 'selectionEnd', '00.'.length)
+ .type('00')
+ .should('have.value', '00.009')
+ .should('have.prop', 'selectionStart', '00.00'.length)
+ .should('have.prop', 'selectionEnd', '00.00'.length);
+ });
+
+ it('moves cursor behind next character if new character is the same with the next one', () => {
+ cy.get('@input')
+ .type('59.999')
+ .type('{moveToStart}')
+ .type('{rightArrow}'.repeat('59.'.length))
+ .type('9')
+ .should('have.value', '59.999')
+ .should('have.prop', 'selectionStart', '59.9'.length)
+ .should('have.prop', 'selectionEnd', '59.9'.length);
+ });
+ });
+
+ it('Pad typed value with zero if digit exceeds the first digit of time segment', () => {
+ cy.get('@input')
+ .type('6')
+ .should('have.value', '06')
+ .should('have.prop', 'selectionStart', '06'.length)
+ .should('have.prop', 'selectionEnd', '06'.length)
+ .type('999')
+ .should('have.value', '06.999')
+ .should('have.prop', 'selectionStart', '06.999'.length)
+ .should('have.prop', 'selectionEnd', '06:999'.length);
+ });
+
+ describe('Select range and press new digit', () => {
+ it('|59|.999 => Type 2 => 2|0.999', BROWSER_SUPPORTS_REAL_EVENTS, () => {
+ cy.get('@input')
+ .type('59999')
+ .should('have.value', '59.999')
+ .realPress([
+ ...new Array('.999'.length).fill('ArrowLeft'),
+ 'Shift',
+ ...new Array('59'.length).fill('ArrowLeft'),
+ ]);
+
+ cy.get('@input')
+ .type('2')
+ .should('have.value', '20.999')
+ .should('have.prop', 'selectionStart', '2'.length)
+ .should('have.prop', 'selectionEnd', '2'.length);
+ });
+
+ it('|59|.999 => Type 6 => 06.|999', BROWSER_SUPPORTS_REAL_EVENTS, () => {
+ cy.get('@input')
+ .type('59999')
+ .should('have.value', '59.999')
+ .realPress([
+ ...new Array('.999'.length).fill('ArrowLeft'),
+ 'Shift',
+ ...new Array('59'.length).fill('ArrowLeft'),
+ ]);
+
+ cy.get('@input')
+ .type('6')
+ .should('have.value', '06.999')
+ .should('have.prop', 'selectionStart', '06.'.length)
+ .should('have.prop', 'selectionEnd', '06.'.length);
+ });
+ });
+
+ describe('accepts time segment separators typed by user', () => {
+ it('59 => Type . => 59.', () => {
+ cy.get('@input')
+ .type('59')
+ .should('have.value', '59')
+ .type('.')
+ .should('have.value', '59.')
+ .should('have.prop', 'selectionStart', '59.'.length)
+ .should('have.prop', 'selectionEnd', '59.'.length);
+ });
+ });
+
+ it('type 59999 => 59.999', () => {
+ cy.get('@input').type('59999').should('have.value', '59.999');
+ });
+ });
});
});
From 39aedb0816f7549cce27f6361239f62967f4979e Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 11 May 2024 10:28:02 +0300
Subject: [PATCH 05/11] fix(kit): changed MM:SS.MSS to MM.SS.MSS
---
projects/demo/src/pages/kit/time/time-mask-doc.component.ts | 2 +-
projects/kit/src/lib/types/time-mode.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/demo/src/pages/kit/time/time-mask-doc.component.ts b/projects/demo/src/pages/kit/time/time-mask-doc.component.ts
index 2b8067932..994666a61 100644
--- a/projects/demo/src/pages/kit/time/time-mask-doc.component.ts
+++ b/projects/demo/src/pages/kit/time/time-mask-doc.component.ts
@@ -49,7 +49,7 @@ export class TimeMaskDocComponent implements GeneratorOptions {
'HH:MM:SS',
'HH:MM:SS.MSS',
'HH',
- 'MM:SS.MSS',
+ 'MM.SS.MSS',
'SS.MSS',
];
diff --git a/projects/kit/src/lib/types/time-mode.ts b/projects/kit/src/lib/types/time-mode.ts
index 364d77815..6c247a2e9 100644
--- a/projects/kit/src/lib/types/time-mode.ts
+++ b/projects/kit/src/lib/types/time-mode.ts
@@ -3,5 +3,5 @@ export type MaskitoTimeMode =
| 'HH:MM:SS'
| 'HH:MM'
| 'HH'
- | 'MM:SS.MSS'
+ | 'MM.SS.MSS'
| 'SS.MSS';
From a68386535093764c75878baea7aba95c2720b495 Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 11 May 2024 10:33:20 +0300
Subject: [PATCH 06/11] refactor(demo-integrations): changed MM:SS.MSS to
MM.SS.MSS
---
.../src/tests/kit/time/time-mode.cy.ts | 84 +++++++++----------
1 file changed, 42 insertions(+), 42 deletions(-)
diff --git a/projects/demo-integrations/src/tests/kit/time/time-mode.cy.ts b/projects/demo-integrations/src/tests/kit/time/time-mode.cy.ts
index f213625e2..d415d996a 100644
--- a/projects/demo-integrations/src/tests/kit/time/time-mode.cy.ts
+++ b/projects/demo-integrations/src/tests/kit/time/time-mode.cy.ts
@@ -413,9 +413,9 @@ describe('Time', () => {
});
});
- describe('MM:SS.MSS', () => {
+ describe('MM.SS.MSS', () => {
beforeEach(() => {
- cy.visit(`/${DemoPath.Time}/API?mode=MM:SS.MSS`);
+ cy.visit(`/${DemoPath.Time}/API?mode=MM.SS.MSS`);
cy.get('#demo-content input')
.should('be.visible')
.first()
@@ -430,28 +430,28 @@ describe('Time', () => {
.type('5959999')
.type('{moveToStart}')
.type('0')
- .should('have.value', '09:59.999')
+ .should('have.value', '09.59.999')
.should('have.prop', 'selectionStart', '0'.length)
.should('have.prop', 'selectionEnd', '0'.length)
.type('000')
- .should('have.value', '00:00.999')
- .should('have.prop', 'selectionStart', '00:00.'.length)
- .should('have.prop', 'selectionEnd', '00:00.'.length)
+ .should('have.value', '00.00.999')
+ .should('have.prop', 'selectionStart', '00.00.'.length)
+ .should('have.prop', 'selectionEnd', '00.00.'.length)
.type('00')
- .should('have.value', '00:00.009')
- .should('have.prop', 'selectionStart', '00:00.00'.length)
- .should('have.prop', 'selectionEnd', '00:00.00'.length);
+ .should('have.value', '00.00.009')
+ .should('have.prop', 'selectionStart', '00.00.00'.length)
+ .should('have.prop', 'selectionEnd', '00.00.00'.length);
});
it('moves cursor behind next character if new character is the same with the next one', () => {
cy.get('@input')
- .type('59:59.999')
+ .type('59.59.999')
.type('{moveToStart}')
- .type('{rightArrow}'.repeat('59:59.'.length))
+ .type('{rightArrow}'.repeat('59.59.'.length))
.type('9')
- .should('have.value', '59:59.999')
- .should('have.prop', 'selectionStart', '59:59.9'.length)
- .should('have.prop', 'selectionEnd', '59:59.9'.length);
+ .should('have.value', '59.59.999')
+ .should('have.prop', 'selectionStart', '59.59.9'.length)
+ .should('have.prop', 'selectionEnd', '59.59.9'.length);
});
});
@@ -462,83 +462,83 @@ describe('Time', () => {
.should('have.prop', 'selectionStart', '06'.length)
.should('have.prop', 'selectionEnd', '06'.length)
.type('6')
- .should('have.value', '06:06')
- .should('have.prop', 'selectionStart', '06:06'.length)
- .should('have.prop', 'selectionEnd', '06:06'.length)
+ .should('have.value', '06.06')
+ .should('have.prop', 'selectionStart', '06.06'.length)
+ .should('have.prop', 'selectionEnd', '06.06'.length)
.type('999')
- .should('have.value', '06:06.999')
- .should('have.prop', 'selectionStart', '06:06.999'.length)
- .should('have.prop', 'selectionEnd', '06:06:999'.length);
+ .should('have.value', '06.06.999')
+ .should('have.prop', 'selectionStart', '06.06.999'.length)
+ .should('have.prop', 'selectionEnd', '06.06.999'.length);
});
describe('Select range and press new digit', () => {
it(
- '|59|:59.999 => Type 2 => 2|0:59.999',
+ '|59|.59.999 => Type 2 => 2|0.59.999',
BROWSER_SUPPORTS_REAL_EVENTS,
() => {
cy.get('@input')
.type('5959999')
- .should('have.value', '59:59.999')
+ .should('have.value', '59.59.999')
.realPress([
- ...new Array(':59.999'.length).fill('ArrowLeft'),
+ ...new Array('.59.999'.length).fill('ArrowLeft'),
'Shift',
...new Array('59'.length).fill('ArrowLeft'),
]);
cy.get('@input')
.type('2')
- .should('have.value', '20:59.999')
+ .should('have.value', '20.59.999')
.should('have.prop', 'selectionStart', '2'.length)
.should('have.prop', 'selectionEnd', '2'.length);
},
);
it(
- '|59|:59.999 => Type 6 => 06:|59.999',
+ '|59|.59.999 => Type 6 => 06.|59.999',
BROWSER_SUPPORTS_REAL_EVENTS,
() => {
cy.get('@input')
.type('5959999')
- .should('have.value', '59:59.999')
+ .should('have.value', '59.59.999')
.realPress([
- ...new Array(':59.999'.length).fill('ArrowLeft'),
+ ...new Array('.59.999'.length).fill('ArrowLeft'),
'Shift',
...new Array('59'.length).fill('ArrowLeft'),
]);
cy.get('@input')
.type('6')
- .should('have.value', '06:59.999')
- .should('have.prop', 'selectionStart', '06:'.length)
- .should('have.prop', 'selectionEnd', '06:'.length);
+ .should('have.value', '06.59.999')
+ .should('have.prop', 'selectionStart', '06.'.length)
+ .should('have.prop', 'selectionEnd', '06.'.length);
},
);
});
describe('accepts time segment separators typed by user', () => {
- it('59 => Type : => 59:', () => {
+ it('59 => Type . => 59.', () => {
cy.get('@input')
.type('59')
.should('have.value', '59')
- .type(':')
- .should('have.value', '59:')
- .should('have.prop', 'selectionStart', '59:'.length)
- .should('have.prop', 'selectionEnd', '59:'.length);
+ .type('.')
+ .should('have.value', '59.')
+ .should('have.prop', 'selectionStart', '59.'.length)
+ .should('have.prop', 'selectionEnd', '59.'.length);
});
- it('59:59 => Type . => 59:59.', () => {
+ it('59.59 => Type . => 59:59.', () => {
cy.get('@input')
.type('5959')
- .should('have.value', '59:59')
+ .should('have.value', '59.59')
.type('.')
- .should('have.value', '59:59.')
- .should('have.prop', 'selectionStart', '59:59.'.length)
- .should('have.prop', 'selectionEnd', '59:59.'.length);
+ .should('have.value', '59.59.')
+ .should('have.prop', 'selectionStart', '59.59.'.length)
+ .should('have.prop', 'selectionEnd', '59.59.'.length);
});
});
- it('type 5959999 => 59:59.999', () => {
- cy.get('@input').type('5959999').should('have.value', '59:59.999');
+ it('type 5959999 => 59.59.999', () => {
+ cy.get('@input').type('5959999').should('have.value', '59.59.999');
});
});
From 0bf6b0c5937332bf04eaafd21f84adfe12c080d1 Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 18 May 2024 09:08:07 +0300
Subject: [PATCH 07/11] refactor(kit): timeMode is MaskitoTimeMode not a
string, added tests for parse time
---
.../valid-date-time-preprocessor.ts | 3 +-
.../processors/max-validation-preprocessor.ts | 4 +-
.../src/lib/utils/time/parse-time-string.ts | 4 +-
.../time/tests/parse-time-string.spec.ts | 50 +++++++++++++++++++
.../lib/utils/time/validate-time-string.ts | 4 +-
5 files changed, 58 insertions(+), 7 deletions(-)
create mode 100644 projects/kit/src/lib/utils/time/tests/parse-time-string.spec.ts
diff --git a/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts b/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
index 834cdc95f..23d76f77b 100644
--- a/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
+++ b/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
@@ -1,6 +1,7 @@
import type {MaskitoPreprocessor} from '@maskito/core';
import {DEFAULT_TIME_SEGMENT_MAX_VALUES, TIME_FIXED_CHARACTERS} from '../../../constants';
+import {MaskitoTimeMode} from '../../../types';
import {escapeRegExp, validateDateString} from '../../../utils';
import {padTimeSegments, validateTimeString} from '../../../utils/time';
import {parseDateTimeString} from '../utils';
@@ -14,7 +15,7 @@ export function createValidDateTimePreprocessor({
dateModeTemplate: string;
dateSegmentsSeparator: string;
dateTimeSeparator: string;
- timeMode: string;
+ timeMode: MaskitoTimeMode;
}): MaskitoPreprocessor {
const invalidCharsRegExp = new RegExp(
`[^\\d${TIME_FIXED_CHARACTERS.map(escapeRegExp).join('')}${escapeRegExp(
diff --git a/projects/kit/src/lib/masks/time/processors/max-validation-preprocessor.ts b/projects/kit/src/lib/masks/time/processors/max-validation-preprocessor.ts
index 1f6353c94..35fa2a8dd 100644
--- a/projects/kit/src/lib/masks/time/processors/max-validation-preprocessor.ts
+++ b/projects/kit/src/lib/masks/time/processors/max-validation-preprocessor.ts
@@ -1,13 +1,13 @@
import type {MaskitoPreprocessor} from '@maskito/core';
import {TIME_FIXED_CHARACTERS} from '../../../constants';
-import type {MaskitoTimeSegments} from '../../../types';
+import type {MaskitoTimeMode, MaskitoTimeSegments} from '../../../types';
import {escapeRegExp} from '../../../utils';
import {padTimeSegments, validateTimeString} from '../../../utils/time';
export function createMaxValidationPreprocessor(
timeSegmentMaxValues: MaskitoTimeSegments,
- timeMode: string,
+ timeMode: MaskitoTimeMode,
): MaskitoPreprocessor {
const paddedMaxValues = padTimeSegments(timeSegmentMaxValues);
const invalidCharsRegExp = new RegExp(
diff --git a/projects/kit/src/lib/utils/time/parse-time-string.ts b/projects/kit/src/lib/utils/time/parse-time-string.ts
index c361bfcb2..5b1a42843 100644
--- a/projects/kit/src/lib/utils/time/parse-time-string.ts
+++ b/projects/kit/src/lib/utils/time/parse-time-string.ts
@@ -1,11 +1,11 @@
-import type {MaskitoTimeSegments} from '../../types';
+import type {MaskitoTimeMode, MaskitoTimeSegments} from '../../types';
/**
* @param timeString can be with/without fixed characters
*/
export function parseTimeString(
timeString: string,
- timeMode: string,
+ timeMode: MaskitoTimeMode,
): Partial {
const onlyDigits = timeString.replaceAll(/\D+/g, '');
diff --git a/projects/kit/src/lib/utils/time/tests/parse-time-string.spec.ts b/projects/kit/src/lib/utils/time/tests/parse-time-string.spec.ts
new file mode 100644
index 000000000..80b9c99b7
--- /dev/null
+++ b/projects/kit/src/lib/utils/time/tests/parse-time-string.spec.ts
@@ -0,0 +1,50 @@
+import {describe, expect, it} from '@jest/globals';
+
+import {parseTimeString} from '../parse-time-string';
+
+describe('parseTimeString', () => {
+ it('HH', () => {
+ expect(parseTimeString('19', 'HH')).toEqual({
+ hours: '19',
+ });
+ });
+
+ it('HH:MM', () => {
+ expect(parseTimeString('23:59', 'HH:MM')).toEqual({
+ hours: '23',
+ minutes: '59',
+ });
+ });
+
+ it('HH:MM:SS', () => {
+ expect(parseTimeString('12:24:55', 'HH:MM:SS')).toEqual({
+ hours: '12',
+ minutes: '24',
+ seconds: '55',
+ });
+ });
+
+ it('HH:MM:SS.MSS', () => {
+ expect(parseTimeString('10:05:42.783', 'HH:MM:SS.MSS')).toEqual({
+ hours: '10',
+ minutes: '05',
+ seconds: '42',
+ milliseconds: '783',
+ });
+ });
+
+ it('MM.SS.MSS', () => {
+ expect(parseTimeString('12.30.001', 'MM.SS.MSS')).toEqual({
+ minutes: '12',
+ seconds: '30',
+ milliseconds: '001',
+ });
+ });
+
+ it('SS.MSS', () => {
+ expect(parseTimeString('59.999', 'SS.MSS')).toEqual({
+ seconds: '59',
+ milliseconds: '999',
+ });
+ });
+});
diff --git a/projects/kit/src/lib/utils/time/validate-time-string.ts b/projects/kit/src/lib/utils/time/validate-time-string.ts
index b6a34e5e7..b1d2de973 100644
--- a/projects/kit/src/lib/utils/time/validate-time-string.ts
+++ b/projects/kit/src/lib/utils/time/validate-time-string.ts
@@ -1,5 +1,5 @@
import {TIME_FIXED_CHARACTERS, TIME_SEGMENT_VALUE_LENGTHS} from '../../constants';
-import type {MaskitoTimeSegments} from '../../types';
+import type {MaskitoTimeMode, MaskitoTimeSegments} from '../../types';
import {escapeRegExp} from '../escape-reg-exp';
import {padWithZeroesUntilValid} from '../pad-with-zeroes-until-valid';
import {parseTimeString} from './parse-time-string';
@@ -20,7 +20,7 @@ export function validateTimeString({
paddedMaxValues: MaskitoTimeSegments;
offset: number;
selection: readonly [number, number];
- timeMode: string;
+ timeMode: MaskitoTimeMode;
}): {validatedTimeString: string; updatedTimeSelection: [number, number]} {
const parsedTime = parseTimeString(timeString, timeMode);
From f3914afacffa9a54cf340e3e2f04ff241b9ec71f Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 18 May 2024 09:11:14 +0300
Subject: [PATCH 08/11] refactor(kit): parseTimeString
---
.../src/lib/utils/time/parse-time-string.ts | 38 +++++++------------
1 file changed, 14 insertions(+), 24 deletions(-)
diff --git a/projects/kit/src/lib/utils/time/parse-time-string.ts b/projects/kit/src/lib/utils/time/parse-time-string.ts
index 5b1a42843..310c47be8 100644
--- a/projects/kit/src/lib/utils/time/parse-time-string.ts
+++ b/projects/kit/src/lib/utils/time/parse-time-string.ts
@@ -1,5 +1,12 @@
import type {MaskitoTimeMode, MaskitoTimeSegments} from '../../types';
+const SEGMENT_FULL_NAME: Record = {
+ HH: 'hours',
+ MM: 'minutes',
+ SS: 'seconds',
+ MSS: 'milliseconds',
+};
+
/**
* @param timeString can be with/without fixed characters
*/
@@ -9,32 +16,15 @@ export function parseTimeString(
): Partial {
const onlyDigits = timeString.replaceAll(/\D+/g, '');
- const sliceIndexes = createSliceIndexes(timeMode);
-
- const timeSegments = {
- hours: onlyDigits.slice(...sliceIndexes.hours),
- minutes: onlyDigits.slice(...sliceIndexes.minutes),
- seconds: onlyDigits.slice(...sliceIndexes.seconds),
- milliseconds: onlyDigits.slice(...sliceIndexes.milliseconds),
- };
+ let offset = 0;
return Object.fromEntries(
- Object.entries(timeSegments).filter(([_, value]) => Boolean(value)),
- );
-}
-
-function createSliceIndexes(timeMode: string): MaskitoTimeSegments<[number, number]> {
- const offset =
- Number(timeMode.startsWith('MM')) * 2 +
- Number(timeMode.startsWith('SS')) * 4 +
- Number(timeMode.startsWith('MSS')) * 6;
+ timeMode.split(/\W/).map(segmentAbbr => {
+ const segmentValue = onlyDigits.slice(offset, offset + segmentAbbr.length);
- const changeSelection = (index: number): number => Math.max(index - offset, 0);
+ offset += segmentAbbr.length;
- return {
- hours: [changeSelection(0), changeSelection(2)],
- minutes: [changeSelection(2), changeSelection(4)],
- seconds: [changeSelection(4), changeSelection(6)],
- milliseconds: [changeSelection(6), changeSelection(9)],
- };
+ return [SEGMENT_FULL_NAME[segmentAbbr], segmentValue];
+ }),
+ );
}
From e83b7399fe82b04356df696615fdf70568b19c2e Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 18 May 2024 09:17:44 +0300
Subject: [PATCH 09/11] refactor(kit): toTimeString
---
projects/kit/src/lib/utils/time/to-time-string.ts | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/projects/kit/src/lib/utils/time/to-time-string.ts b/projects/kit/src/lib/utils/time/to-time-string.ts
index 4b5536086..c41eae849 100644
--- a/projects/kit/src/lib/utils/time/to-time-string.ts
+++ b/projects/kit/src/lib/utils/time/to-time-string.ts
@@ -1,15 +1,15 @@
import type {MaskitoTimeSegments} from '../../types';
+const LEADING_NON_DIGITS = /^\D*/;
+const TRAILING_NON_DIGITS = /\D*$/;
+
export function toTimeString({
hours = '',
minutes = '',
seconds = '',
milliseconds = '',
}: Partial): string {
- const mm = hours ? minutes && `:${minutes}` : minutes;
- const ss = hours || minutes ? seconds && `:${seconds}` : seconds;
- const ms =
- hours || minutes || seconds ? milliseconds && `.${milliseconds}` : milliseconds;
-
- return `${hours}${mm}${ss}${ms}`;
+ return `${hours}:${minutes}:${seconds}.${milliseconds}`
+ .replace(LEADING_NON_DIGITS, '')
+ .replace(TRAILING_NON_DIGITS, '');
}
From 84b28187c50b9219284386d4499997d4f4062cf1 Mon Sep 17 00:00:00 2001
From: Stanslav Zaytsev
Date: Sat, 18 May 2024 09:41:40 +0300
Subject: [PATCH 10/11] test(kit): toTimeString
---
.../utils/time/tests/to-time-string.spec.ts | 133 ++++++++++++++++++
1 file changed, 133 insertions(+)
create mode 100644 projects/kit/src/lib/utils/time/tests/to-time-string.spec.ts
diff --git a/projects/kit/src/lib/utils/time/tests/to-time-string.spec.ts b/projects/kit/src/lib/utils/time/tests/to-time-string.spec.ts
new file mode 100644
index 000000000..61156eaa7
--- /dev/null
+++ b/projects/kit/src/lib/utils/time/tests/to-time-string.spec.ts
@@ -0,0 +1,133 @@
+import {toTimeString} from '../to-time-string';
+
+describe('toTimeString', () => {
+ describe('HH', () => {
+ it('21', () => {
+ expect(toTimeString({hours: '21'})).toBe('21');
+ });
+
+ it('1', () => {
+ expect(toTimeString({hours: '1'})).toBe('1');
+ });
+ });
+
+ describe('HH:MM', () => {
+ it('21:59', () => {
+ expect(toTimeString({hours: '21', minutes: '59'})).toBe('21:59');
+ });
+
+ it('12:4', () => {
+ expect(toTimeString({hours: '12', minutes: '4'})).toBe('12:4');
+ });
+ });
+
+ describe('HH:MM:SS', () => {
+ it('21:59:23', () => {
+ expect(toTimeString({hours: '21', minutes: '59', seconds: '23'})).toBe(
+ '21:59:23',
+ );
+ });
+
+ it('01:23:5', () => {
+ expect(toTimeString({hours: '01', minutes: '23', seconds: '5'})).toBe(
+ '01:23:5',
+ );
+ });
+ });
+
+ describe('HH:MM:SS.MSS', () => {
+ it('21:59:23.111', () => {
+ expect(
+ toTimeString({
+ hours: '21',
+ minutes: '59',
+ seconds: '23',
+ milliseconds: '111',
+ }),
+ ).toBe('21:59:23.111');
+ });
+
+ it('01:23:52.1', () => {
+ expect(
+ toTimeString({
+ hours: '01',
+ minutes: '23',
+ seconds: '52',
+ milliseconds: '1',
+ }),
+ ).toBe('01:23:52.1');
+ });
+
+ it('13:13:13.15', () => {
+ expect(
+ toTimeString({
+ hours: '13',
+ minutes: '13',
+ seconds: '13',
+ milliseconds: '15',
+ }),
+ ).toBe('13:13:13.15');
+ });
+ });
+
+ describe('MM:SS.MSS', () => {
+ it('12:12.111', () => {
+ expect(
+ toTimeString({
+ minutes: '12',
+ seconds: '12',
+ milliseconds: '111',
+ }),
+ ).toBe('12:12.111');
+ });
+
+ it('23:01.9', () => {
+ expect(
+ toTimeString({
+ minutes: '23',
+ seconds: '01',
+ milliseconds: '9',
+ }),
+ ).toBe('23:01.9');
+ });
+
+ it('00:02.91', () => {
+ expect(
+ toTimeString({
+ minutes: '00',
+ seconds: '02',
+ milliseconds: '91',
+ }),
+ ).toBe('00:02.91');
+ });
+ });
+
+ describe('SS.MSS', () => {
+ it('12.111', () => {
+ expect(
+ toTimeString({
+ seconds: '12',
+ milliseconds: '111',
+ }),
+ ).toBe('12.111');
+ });
+
+ it('01.9', () => {
+ expect(
+ toTimeString({
+ seconds: '01',
+ milliseconds: '9',
+ }),
+ ).toBe('01.9');
+ });
+
+ it('02.91', () => {
+ expect(
+ toTimeString({
+ seconds: '02',
+ milliseconds: '91',
+ }),
+ ).toBe('02.91');
+ });
+ });
+});
From 5aade8c2fdd81005b80cc30daa61ae457fe881a5 Mon Sep 17 00:00:00 2001
From: taiga-family-bot
Date: Sat, 18 May 2024 06:45:12 +0000
Subject: [PATCH 11/11] chore: apply changes after linting [bot]
---
.../date-time/preprocessors/valid-date-time-preprocessor.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts b/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
index 23d76f77b..f48750bf2 100644
--- a/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
+++ b/projects/kit/src/lib/masks/date-time/preprocessors/valid-date-time-preprocessor.ts
@@ -1,7 +1,7 @@
import type {MaskitoPreprocessor} from '@maskito/core';
import {DEFAULT_TIME_SEGMENT_MAX_VALUES, TIME_FIXED_CHARACTERS} from '../../../constants';
-import {MaskitoTimeMode} from '../../../types';
+import type {MaskitoTimeMode} from '../../../types';
import {escapeRegExp, validateDateString} from '../../../utils';
import {padTimeSegments, validateTimeString} from '../../../utils/time';
import {parseDateTimeString} from '../utils';