From 106a3ddfd9550a52c63b40cebf59c225f5a31732 Mon Sep 17 00:00:00 2001 From: Stoyan Date: Fri, 3 Apr 2026 17:14:29 +0300 Subject: [PATCH 1/5] fix(ui5-date-range-picker): remove relative date handling --- .../main/cypress/specs/DateRangePicker.cy.tsx | 67 +++++++++++++++++++ packages/main/src/DateRangePicker.ts | 34 ++++++++++ 2 files changed, 101 insertions(+) diff --git a/packages/main/cypress/specs/DateRangePicker.cy.tsx b/packages/main/cypress/specs/DateRangePicker.cy.tsx index 2269b1337c75..8d44d1f46dd4 100644 --- a/packages/main/cypress/specs/DateRangePicker.cy.tsx +++ b/packages/main/cypress/specs/DateRangePicker.cy.tsx @@ -968,4 +968,71 @@ describe("Validation inside a form", () => { cy.get("#dateRangePicker:invalid") .should("not.exist"); }); +}); + +describe("DateRangePicker relative dates rejection", () => { + it("typing 'today' sets error state", () => { + cy.mount(); + + cy.get("[ui5-daterange-picker]") + .as("dateRangePicker") + .shadow() + .find("[ui5-datetime-input]") + .realClick() + .should("be.focused"); + + cy.realType("today"); + cy.realPress("Enter"); + + cy.get("@dateRangePicker") + .should("have.value", "today"); + + cy.get("@dateRangePicker") + .should("have.attr", "value-state", "Negative"); + }); + + it("typing 'tomorrow' sets error state", () => { + cy.mount(); + + cy.get("[ui5-daterange-picker]") + .as("dateRangePicker") + .shadow() + .find("[ui5-datetime-input]") + .realClick() + .should("be.focused"); + + cy.realType("tomorrow"); + cy.realPress("Enter"); + + cy.get("@dateRangePicker") + .should("have.value", "tomorrow"); + + cy.get("@dateRangePicker") + .should("have.attr", "value-state", "Negative"); + }); + + it("setting value='today' as attribute sets error state", () => { + cy.mount(); + + cy.get("[ui5-daterange-picker]") + .as("dateRangePicker") + .should("have.attr", "value-state", "Negative"); + }); + + it("valid concrete date range does not set error state", () => { + cy.mount(); + + cy.get("[ui5-daterange-picker]") + .as("dateRangePicker") + .shadow() + .find("[ui5-datetime-input]") + .realClick() + .should("be.focused"); + + cy.realType("09/09/2020 - 10/10/2020"); + cy.realPress("Enter"); + + cy.get("@dateRangePicker") + .should("have.attr", "value-state", "None"); + }); }); \ No newline at end of file diff --git a/packages/main/src/DateRangePicker.ts b/packages/main/src/DateRangePicker.ts index 2c6f5412e3ed..cfcb8e1e4b44 100644 --- a/packages/main/src/DateRangePicker.ts +++ b/packages/main/src/DateRangePicker.ts @@ -6,6 +6,7 @@ import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDat import UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js"; import modifyDateBy from "@ui5/webcomponents-localization/dist/dates/modifyDateBy.js"; import getTodayUTCTimestamp from "@ui5/webcomponents-localization/dist/dates/getTodayUTCTimestamp.js"; +import type DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; import { DATERANGE_DESCRIPTION, DATERANGEPICKER_POPOVER_ACCESSIBLE_NAME, @@ -136,6 +137,27 @@ class DateRangePicker extends DatePicker implements IFormInputElement { this._prevDelimiter = null; } + /** + * Checks if a date string is a relative date (e.g. "today", "tomorrow") + * that would be resolved by DateFormat.parseRelative(). + * Relative dates are not supported in DateRangePicker. + * @private + */ + _isRelativeValue(dateString: string, format: DateFormat): boolean { + const trimmed = dateString.trim(); + if (!trimmed) { + return false; + } + + const parsed = format.parse(trimmed); + if (!parsed) { + return false; + } + + const formatted = format.format(parsed); + return formatted !== trimmed; + } + /** * **Note:** The getter method is inherited and not supported. If called it will return an empty value. * @public @@ -272,6 +294,10 @@ class DateRangePicker extends DatePicker implements IFormInputElement { isValid(value: string): boolean { const parts = this._splitValueByDelimiter(value).filter(str => str.trim() !== ""); + if (parts.some(dateString => this._isRelativeValue(dateString, this.getFormat()))) { + return false; + } + return parts.length <= 2 && parts.every(dateString => super.isValid(dateString)); // must be at most 2 dates and each must be valid } @@ -283,6 +309,10 @@ class DateRangePicker extends DatePicker implements IFormInputElement { isValidValue(value: string): boolean { const parts = this._splitValueByDelimiter(value).filter(str => str.trim() !== ""); + if (parts.some(dateString => this._isRelativeValue(dateString, this.getValueFormat()))) { + return false; + } + return parts.length <= 2 && parts.every(dateString => super.isValidValue(dateString)); // must be at most 2 dates and each must be valid } @@ -294,6 +324,10 @@ class DateRangePicker extends DatePicker implements IFormInputElement { isValidDisplayValue(value: string): boolean { const parts = this._splitValueByDelimiter(value).filter(str => str.trim() !== ""); + if (parts.some(dateString => this._isRelativeValue(dateString, this.getDisplayFormat()))) { + return false; + } + return parts.length <= 2 && parts.every(dateString => super.isValidDisplayValue(dateString)); // must be at most 2 dates and each must be valid } From 207be89bb52ecdb5330ef7e62aed0310234abc66 Mon Sep 17 00:00:00 2001 From: Stoyan Date: Mon, 6 Apr 2026 09:42:44 +0300 Subject: [PATCH 2/5] correct test --- .../main/cypress/specs/DateRangePicker.cy.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/main/cypress/specs/DateRangePicker.cy.tsx b/packages/main/cypress/specs/DateRangePicker.cy.tsx index 8d44d1f46dd4..127a7d7cd031 100644 --- a/packages/main/cypress/specs/DateRangePicker.cy.tsx +++ b/packages/main/cypress/specs/DateRangePicker.cy.tsx @@ -1011,11 +1011,23 @@ describe("DateRangePicker relative dates rejection", () => { .should("have.attr", "value-state", "Negative"); }); - it("setting value='today' as attribute sets error state", () => { - cy.mount(); + it("typing 'yesterday' sets error state", () => { + cy.mount(); cy.get("[ui5-daterange-picker]") .as("dateRangePicker") + .shadow() + .find("[ui5-datetime-input]") + .realClick() + .should("be.focused"); + + cy.realType("yesterday"); + cy.realPress("Enter"); + + cy.get("@dateRangePicker") + .should("have.value", "yesterday"); + + cy.get("@dateRangePicker") .should("have.attr", "value-state", "Negative"); }); From 96fb18c9fe5bb44d3db689c0699e5ae0c43c31b1 Mon Sep 17 00:00:00 2001 From: Stoyan Date: Tue, 7 Apr 2026 10:59:30 +0300 Subject: [PATCH 3/5] address comments --- .../main/cypress/specs/DateRangePicker.cy.tsx | 70 +++++-------------- packages/main/src/DateRangePicker.ts | 3 + 2 files changed, 19 insertions(+), 54 deletions(-) diff --git a/packages/main/cypress/specs/DateRangePicker.cy.tsx b/packages/main/cypress/specs/DateRangePicker.cy.tsx index 127a7d7cd031..8dbc60f02afc 100644 --- a/packages/main/cypress/specs/DateRangePicker.cy.tsx +++ b/packages/main/cypress/specs/DateRangePicker.cy.tsx @@ -971,64 +971,26 @@ describe("Validation inside a form", () => { }); describe("DateRangePicker relative dates rejection", () => { - it("typing 'today' sets error state", () => { - cy.mount(); + const relativeKeywords = ["today", "tomorrow", "yesterday"]; - cy.get("[ui5-daterange-picker]") - .as("dateRangePicker") - .shadow() - .find("[ui5-datetime-input]") - .realClick() - .should("be.focused"); - - cy.realType("today"); - cy.realPress("Enter"); - - cy.get("@dateRangePicker") - .should("have.value", "today"); - - cy.get("@dateRangePicker") - .should("have.attr", "value-state", "Negative"); - }); + relativeKeywords.forEach(keyword => { + it(`typing '${keyword}' sets error state`, () => { + cy.mount(); - it("typing 'tomorrow' sets error state", () => { - cy.mount(); + cy.get("[ui5-daterange-picker]") + .as("dateRangePicker") + .shadow() + .find("[ui5-datetime-input]") + .realClick() + .should("be.focused"); - cy.get("[ui5-daterange-picker]") - .as("dateRangePicker") - .shadow() - .find("[ui5-datetime-input]") - .realClick() - .should("be.focused"); - - cy.realType("tomorrow"); - cy.realPress("Enter"); + cy.realType(keyword); + cy.realPress("Enter"); - cy.get("@dateRangePicker") - .should("have.value", "tomorrow"); - - cy.get("@dateRangePicker") - .should("have.attr", "value-state", "Negative"); - }); - - it("typing 'yesterday' sets error state", () => { - cy.mount(); - - cy.get("[ui5-daterange-picker]") - .as("dateRangePicker") - .shadow() - .find("[ui5-datetime-input]") - .realClick() - .should("be.focused"); - - cy.realType("yesterday"); - cy.realPress("Enter"); - - cy.get("@dateRangePicker") - .should("have.value", "yesterday"); - - cy.get("@dateRangePicker") - .should("have.attr", "value-state", "Negative"); + cy.get("@dateRangePicker") + .should("have.value", keyword) + .should("have.attr", "value-state", "Negative"); + }); }); it("valid concrete date range does not set error state", () => { diff --git a/packages/main/src/DateRangePicker.ts b/packages/main/src/DateRangePicker.ts index cfcb8e1e4b44..20cc3f229d57 100644 --- a/packages/main/src/DateRangePicker.ts +++ b/packages/main/src/DateRangePicker.ts @@ -41,6 +41,9 @@ const DEFAULT_DELIMITER = "-"; * The user can enter a date by: * Using the calendar that opens in a popup or typing it in directly in the input field (not available for mobile devices). * For the `ui5-daterange-picker` + * + * **Note:** Relative date values such as "today", "yesterday", or "tomorrow" are not supported. + * Entering a relative date sets the component to an error state. * ### ES6 Module Import * * `import "@ui5/webcomponents/dist/DateRangePicker.js";` From 2c7541d52a9ae963a54fc3574097333131b720ac Mon Sep 17 00:00:00 2001 From: Stoyan <88034608+hinzzx@users.noreply.github.com> Date: Wed, 8 Apr 2026 09:04:47 +0300 Subject: [PATCH 4/5] Update packages/main/cypress/specs/DateRangePicker.cy.tsx Co-authored-by: Dimitar Stoev --- packages/main/cypress/specs/DateRangePicker.cy.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/main/cypress/specs/DateRangePicker.cy.tsx b/packages/main/cypress/specs/DateRangePicker.cy.tsx index 8dbc60f02afc..a515e6a395e0 100644 --- a/packages/main/cypress/specs/DateRangePicker.cy.tsx +++ b/packages/main/cypress/specs/DateRangePicker.cy.tsx @@ -970,7 +970,7 @@ describe("Validation inside a form", () => { }); }); -describe("DateRangePicker relative dates rejection", () => { +describe("DateRangePicker rejects relative dates", () => { const relativeKeywords = ["today", "tomorrow", "yesterday"]; relativeKeywords.forEach(keyword => { From f40412f5119d9146c86a8387ad35011dc7776a88 Mon Sep 17 00:00:00 2001 From: Stoyan <88034608+hinzzx@users.noreply.github.com> Date: Wed, 8 Apr 2026 09:04:55 +0300 Subject: [PATCH 5/5] Update packages/main/src/DateRangePicker.ts Co-authored-by: Dimitar Stoev --- packages/main/src/DateRangePicker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/main/src/DateRangePicker.ts b/packages/main/src/DateRangePicker.ts index 20cc3f229d57..559cb30e0612 100644 --- a/packages/main/src/DateRangePicker.ts +++ b/packages/main/src/DateRangePicker.ts @@ -40,7 +40,7 @@ const DEFAULT_DELIMITER = "-"; * ### Usage * The user can enter a date by: * Using the calendar that opens in a popup or typing it in directly in the input field (not available for mobile devices). - * For the `ui5-daterange-picker` + * For the `ui5-daterange-picker`: * * **Note:** Relative date values such as "today", "yesterday", or "tomorrow" are not supported. * Entering a relative date sets the component to an error state.