From ff652128699dfb7d36e83b2206015f2a1e500cf1 Mon Sep 17 00:00:00 2001 From: Georgi Damyanov Date: Fri, 3 Oct 2025 11:19:31 +0300 Subject: [PATCH 1/2] feat: normalize display value only on change --- packages/main/cypress/specs/DatePicker.cy.tsx | 22 +++++++++++++++++++ packages/main/cypress/support/commands.ts | 1 + .../support/commands/DatePicker.commands.ts | 14 ++++++++++++ packages/main/src/DatePicker.ts | 13 +++++++++-- packages/main/src/DateRangePicker.ts | 12 ++++++++-- 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/packages/main/cypress/specs/DatePicker.cy.tsx b/packages/main/cypress/specs/DatePicker.cy.tsx index 07865db24ebb..159b1018aaea 100644 --- a/packages/main/cypress/specs/DatePicker.cy.tsx +++ b/packages/main/cypress/specs/DatePicker.cy.tsx @@ -1549,6 +1549,28 @@ describe("Date Picker Tests", () => { .find("ui5-yearpicker") .should("be.visible"); }); + + it("Should not auto-format incomplete date while typing", () => { + cy.mount(); + cy.get("[ui5-date-picker]") + .ui5DatePickerGetInnerInput() + .realClick() + .realType("2023-0", { delay: 100 }); + + cy.get("ui5-date-picker") + .ui5DatePickerGetInnerInput() + .should("have.value", "2023-0"); + }); + + it("Should normalize value on change", () => { + cy.mount(); + cy.get("[ui5-date-picker]") + .ui5DatePickerTypeDate("202-12-1"); + + cy.get("[ui5-date-picker]") + .ui5DatePickerGetInnerInput() + .should("have.value", "0202-12-01"); + }); }); describe("Legacy date customization and Islamic calendar type", () => { diff --git a/packages/main/cypress/support/commands.ts b/packages/main/cypress/support/commands.ts index 016ee3e4f724..71ef25b616a4 100644 --- a/packages/main/cypress/support/commands.ts +++ b/packages/main/cypress/support/commands.ts @@ -89,6 +89,7 @@ declare global { ui5DatePickerGetMonthButton(): Chainable> ui5DatePickerGetYearButton(): Chainable> ui5DatePickerValueHelpIconPress(): Chainable + ui5DatePickerTypeDate(value: string, delay?: number): Chainable ui5SegmentedButtonItemToggleSelect(deselect?: boolean): Chainable ui5SegmentedButtonFocusFirstItem(): Chainable ui5SwitchCheckAttributeInShadowDomRoot(attrName: string, attrValue: string): Chainable diff --git a/packages/main/cypress/support/commands/DatePicker.commands.ts b/packages/main/cypress/support/commands/DatePicker.commands.ts index 8616c65f5431..d28b660b8708 100644 --- a/packages/main/cypress/support/commands/DatePicker.commands.ts +++ b/packages/main/cypress/support/commands/DatePicker.commands.ts @@ -266,3 +266,17 @@ Cypress.Commands.add("ui5DatePickerValueHelpIconPress", { prevSubject: true }, s .find("ui5-icon") .realClick(); }); + +Cypress.Commands.add("ui5DatePickerTypeDate", { prevSubject: true }, (subject: string, date: string, delay: number = 0) => { + cy.wrap(subject) + .as("datePicker"); + + cy.get("@datePicker") + .ui5DatePickerGetInnerInput() + .realClick() + .clear() + .should("be.focused"); + + cy.realType(date, { delay }); + cy.realPress("Enter"); +}); diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index e0a9df7b1a0a..342a0914cd95 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -369,6 +369,8 @@ class DatePicker extends DateComponentBase implements IFormInputElement { liveValue?: string; + isLiveUpdate?: boolean; + /** * Defines the value state message that will be displayed as pop up under the component. * @@ -441,7 +443,9 @@ class DatePicker extends DateComponentBase implements IFormInputElement { } }); - this.value = this.normalizeFormattedValue(this.value) || this.value; + if (!this.isLiveUpdate) { + this.value = this.normalizeFormattedValue(this.value) || this.value; + } this.liveValue = this.value; } @@ -544,8 +548,9 @@ class DatePicker extends DateComponentBase implements IFormInputElement { _updateValueAndFireEvents(value: string, normalizeValue: boolean, events: Array<"change" | "value-changed" | "input">, updateValue = true) { const valid = this._checkValueValidity(value); + this.isLiveUpdate = !updateValue; - if (valid && normalizeValue) { + if ((valid && normalizeValue) || !this.isLiveUpdate) { value = this.getDisplayValueFromValue(value); value = this.normalizeDisplayValue(value); // transform valid values (in any format) to the correct format } @@ -813,6 +818,10 @@ class DatePicker extends DateComponentBase implements IFormInputElement { return ""; } + if (this.isLiveUpdate) { + return this.liveValue!; + } + return this.getDisplayFormat().format(this.getValueFormat().parse(this.value, true), true); } diff --git a/packages/main/src/DateRangePicker.ts b/packages/main/src/DateRangePicker.ts index 0a90fdfc41c5..04d57cf050a7 100644 --- a/packages/main/src/DateRangePicker.ts +++ b/packages/main/src/DateRangePicker.ts @@ -311,6 +311,10 @@ class DateRangePicker extends DatePicker implements IFormInputElement { const firstDateTimestamp = this._exctractDisplayTimestamp(values[0]); const lastDateTimestamp = this._exctractDisplayTimestamp(values[1]); + if (!firstDateTimestamp || !lastDateTimestamp) { + return value; + } + if (firstDateTimestamp && lastDateTimestamp && firstDateTimestamp > lastDateTimestamp) { // if both are timestamps (not undefined), flip if necessary return this._buildDisplayValue(lastDateTimestamp, firstDateTimestamp); } @@ -329,7 +333,7 @@ class DateRangePicker extends DatePicker implements IFormInputElement { firstDateString = this._getValueStringFromTimestamp((this._exctractDisplayTimestamp(values[0]) as number) * 1000); lastDateString = this._getValueStringFromTimestamp((this._exctractDisplayTimestamp(values[1]) as number) * 1000); - if (!firstDateString && !lastDateString) { + if (!firstDateString || !lastDateString) { return value; } @@ -518,13 +522,17 @@ class DateRangePicker extends DatePicker implements IFormInputElement { } getDisplayValueFromValue(value: string): string { + if (this.isLiveUpdate) { + return value; + } + let firstDateString = ""; let lastDateString = ""; firstDateString = this._getDisplayStringFromTimestamp((this._extractFirstTimestamp(value) as number) * 1000); lastDateString = this._getDisplayStringFromTimestamp((this._extractLastTimestamp(value) as number) * 1000); - if (!firstDateString && !lastDateString) { + if (!firstDateString || !lastDateString) { return value; } From 835090f9d40492cbb42fa834b5c9cb9b65ab7aa6 Mon Sep 17 00:00:00 2001 From: Georgi Damyanov Date: Tue, 7 Oct 2025 16:53:07 +0300 Subject: [PATCH 2/2] fix: revert --- 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 04d57cf050a7..e13634f312f2 100644 --- a/packages/main/src/DateRangePicker.ts +++ b/packages/main/src/DateRangePicker.ts @@ -532,7 +532,7 @@ class DateRangePicker extends DatePicker implements IFormInputElement { firstDateString = this._getDisplayStringFromTimestamp((this._extractFirstTimestamp(value) as number) * 1000); lastDateString = this._getDisplayStringFromTimestamp((this._extractLastTimestamp(value) as number) * 1000); - if (!firstDateString || !lastDateString) { + if (!firstDateString && !lastDateString) { return value; }