From bc290affdcdc1cd6e088a32a60dc5e74fd00a1d8 Mon Sep 17 00:00:00 2001 From: Andrei Belokopytov Date: Mon, 3 Feb 2025 12:34:19 +0300 Subject: [PATCH] feat(kit): `Date` supports `dd/mm` and `mm/dd` modes (#1939) Co-authored-by: Andrey Belokopytov Co-authored-by: Nikita Barsukov --- .../src/tests/kit/date/date-mode.cy.ts | 102 ++++++++++++++++++ .../pages/kit/date/date-mask-doc.component.ts | 2 + .../processors/min-max-date-postprocessor.ts | 5 +- projects/kit/src/lib/types/date-mode.ts | 2 + 4 files changed, 110 insertions(+), 1 deletion(-) diff --git a/projects/demo-integrations/src/tests/kit/date/date-mode.cy.ts b/projects/demo-integrations/src/tests/kit/date/date-mode.cy.ts index 25f5e473e..40ba54802 100644 --- a/projects/demo-integrations/src/tests/kit/date/date-mode.cy.ts +++ b/projects/demo-integrations/src/tests/kit/date/date-mode.cy.ts @@ -203,5 +203,107 @@ describe('Date', () => { .should('have.prop', 'selectionEnd', '2025'.length); }); }); + + describe('dd/mm', () => { + beforeEach(() => { + cy.visit(`/${DemoPath.Date}/API?mode=dd%2Fmm`); + cy.get('#demo-content input') + .should('be.visible') + .first() + .focus() + .as('input'); + }); + + it('"dd/mm" => 14.07', () => { + cy.get('@input') + .type('1407') + .should('have.value', '14.07') + .should('have.prop', 'selectionStart', '14.07'.length) + .should('have.prop', 'selectionEnd', '14.07'.length); + }); + + it('"dd/mm" => 01.01', () => { + cy.get('@input') + .type('0101') + .should('have.value', '01.01') + .should('have.prop', 'selectionStart', '01.11'.length) + .should('have.prop', 'selectionEnd', '01.11'.length); + }); + + it('"dd/mm" => 05.11', () => { + cy.get('@input') + .type('511') + .should('have.value', '05.11') + .should('have.prop', 'selectionStart', '05.11'.length) + .should('have.prop', 'selectionEnd', '05.11'.length); + }); + + it('"dd/mm" => 05.05', () => { + cy.get('@input') + .type('55') + .should('have.value', '05.05') + .should('have.prop', 'selectionStart', '05.05'.length) + .should('have.prop', 'selectionEnd', '05.05'.length); + }); + + it('dd/mm" => 01.05', () => { + cy.get('@input') + .type('3104') + .should('have.value', '01.05') + .should('have.prop', 'selectionStart', '01.05'.length) + .should('have.prop', 'selectionEnd', '01.05'.length); + }); + }); + + describe('mm/dd', () => { + beforeEach(() => { + cy.visit(`/${DemoPath.Date}/API?mode=mm%2Fdd`); + cy.get('#demo-content input') + .should('be.visible') + .first() + .focus() + .as('input'); + }); + + it('"mm/dd" => 02.29', () => { + cy.get('@input') + .type('0229') + .should('have.value', '02.29') + .should('have.prop', 'selectionStart', '02.29'.length) + .should('have.prop', 'selectionEnd', '02.29'.length); + }); + + it('"mm/dd" => 01.01', () => { + cy.get('@input') + .type('0101') + .should('have.value', '01.01') + .should('have.prop', 'selectionStart', '01.01'.length) + .should('have.prop', 'selectionEnd', '01.01'.length); + }); + + it('"mm/dd" => 09.12', () => { + cy.get('@input') + .type('912') + .should('have.value', '09.12') + .should('have.prop', 'selectionStart', '09.12'.length) + .should('have.prop', 'selectionEnd', '09.12'.length); + }); + + it('"mm/dd" => 09.09', () => { + cy.get('@input') + .type('99') + .should('have.value', '09.09') + .should('have.prop', 'selectionStart', '09.09'.length) + .should('have.prop', 'selectionEnd', '09.09'.length); + }); + + it('dd/mm" => 05.01', () => { + cy.get('@input') + .type('431') + .should('have.value', '05.01') + .should('have.prop', 'selectionStart', '05.01'.length) + .should('have.prop', 'selectionEnd', '05.01'.length); + }); + }); }); }); diff --git a/projects/demo/src/pages/kit/date/date-mask-doc.component.ts b/projects/demo/src/pages/kit/date/date-mask-doc.component.ts index 9b1510c7c..4ffaba503 100644 --- a/projects/demo/src/pages/kit/date/date-mask-doc.component.ts +++ b/projects/demo/src/pages/kit/date/date-mask-doc.component.ts @@ -49,6 +49,8 @@ export default class DateMaskDocComponent implements GeneratorOptions { 'dd/mm/yyyy', 'mm/dd/yyyy', 'yyyy/mm/dd', + 'dd/mm', + 'mm/dd', 'mm/yy', 'mm/yyyy', 'yyyy/mm', diff --git a/projects/kit/src/lib/processors/min-max-date-postprocessor.ts b/projects/kit/src/lib/processors/min-max-date-postprocessor.ts index 55bb7fece..9eb541e13 100644 --- a/projects/kit/src/lib/processors/min-max-date-postprocessor.ts +++ b/projects/kit/src/lib/processors/min-max-date-postprocessor.ts @@ -12,6 +12,8 @@ import { } from '../utils'; import {raiseSegmentValueToMin} from '../utils/date/raise-segment-value-to-min'; +const LEAP_YEAR = '1972'; + export function createMinMaxDatePostprocessor({ dateModeTemplate, min = DEFAULT_MIN_DATE, @@ -48,7 +50,8 @@ export function createMinMaxDatePostprocessor({ continue; } - const date = segmentsToDate(parsedDate); + const date = segmentsToDate({year: LEAP_YEAR, ...parsedDate}); + const clampedDate = clamp(date, min, max); validatedValue += toDateString(dateToSegments(clampedDate), { diff --git a/projects/kit/src/lib/types/date-mode.ts b/projects/kit/src/lib/types/date-mode.ts index ce6e7662d..5611cc732 100644 --- a/projects/kit/src/lib/types/date-mode.ts +++ b/projects/kit/src/lib/types/date-mode.ts @@ -1,5 +1,7 @@ export type MaskitoDateMode = + | 'dd/mm' | 'dd/mm/yyyy' + | 'mm/dd' | 'mm/dd/yyyy' | 'mm/yy' | 'mm/yyyy'