From 3a0e8fe0846cc69e36c9372271774761c6775ef8 Mon Sep 17 00:00:00 2001 From: hinzzx Date: Thu, 18 Jan 2024 09:24:59 +0200 Subject: [PATCH 1/8] feat(ui5-date-picker): introduce value-state-change event --- packages/main/src/DatePicker.ts | 35 ++++++++++++++++--- packages/main/test/pages/DatePicker.html | 11 ++++++ .../main/test/pages/DatePicker_test_page.html | 8 +++++ packages/main/test/specs/DatePicker.spec.js | 14 ++++++++ 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index 74ccda9cc561..2c0e72c66ea9 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -59,6 +59,10 @@ type DatePickerChangeEventDetail = { valid: boolean, } +type ValueStateChangeEventDetail = { + isValid: boolean, +} + type DatePickerInputEventDetail = { value: string, valid: boolean, @@ -217,6 +221,26 @@ type DatePickerInputEventDetail = { }, }, }) +/** + * Fired before the value state of the component is updated. + * The event is preventable, meaning that if it's default action is + * prevented, the component will not update the value state. + * + * @allowPreventDefault + * @public + * @param {boolean} isValid Indicates whether the current value of the component is considered valid. + */ +@event("value-state-change", { + detail: { + /** + * @public + */ + isValid: { + type: Boolean, + }, + }, +}) + class DatePicker extends DateComponentBase implements IFormElement { /** * Defines a formatted date value. @@ -543,11 +567,14 @@ class DatePicker extends DateComponentBase implements IFormElement { _updateValueState() { const isValid = this._checkValueValidity(this.value); + const eventPrevented = !this.fireEvent("value-state-change", { isValid }, true); - if (isValid && this.valueState === ValueState.Error) { // If not valid - always set Error regardless of the current value state - this.valueState = ValueState.None; - } else if (!isValid) { // However if valid, change only Error (but not the others) to None - this.valueState = ValueState.Error; + if (!eventPrevented) { + if (isValid && this.valueState === ValueState.Error) { // If not valid - always set Error regardless of the current value state + this.valueState = ValueState.None; + } else if (!isValid) { // However if valid, change only Error (but not the others) to None + this.valueState = ValueState.Error; + } } } diff --git a/packages/main/test/pages/DatePicker.html b/packages/main/test/pages/DatePicker.html index 1f1e9f387fa2..6526b25d3425 100644 --- a/packages/main/test/pages/DatePicker.html +++ b/packages/main/test/pages/DatePicker.html @@ -29,6 +29,10 @@
+ +

DatePicker with value-state-change event prevented

+ +

DatePicker with no format pattern & min-max dates in ISO format

@@ -199,6 +203,13 @@

DatePicker with format `yyyy` should open picker on years

dp11.setAttribute("value", dp11.formatValue(new Date(2018, 11, 11))); }); + const datePickerValueStateChangePrevented = document.getElementById("dpVsChangePrevented"); + + datePickerValueStateChangePrevented.addEventListener("value-state-change", function(e) { + e.preventDefault(); + console.log("Value state change prevented!", datePickerValueStateChangePrevented); + }); + diff --git a/packages/main/test/pages/DatePicker_test_page.html b/packages/main/test/pages/DatePicker_test_page.html index dc5e344a7c20..5017d0dc09c0 100644 --- a/packages/main/test/pages/DatePicker_test_page.html +++ b/packages/main/test/pages/DatePicker_test_page.html @@ -36,6 +36,8 @@ +

DatePicker value-state-change event prevented

+ Set date @@ -102,6 +104,12 @@

Test accessibleName and accessibleNameRef

document.getElementById('b1').addEventListener("click", function(e) { dp16.setAttribute("value", dp16.formatValue(new Date(2018, 11, 11))); }); + + const datePickerValueStateChangePrevented = document.getElementById("dpVsChangePrevented"); + + datePickerValueStateChangePrevented.addEventListener("value-state-change", function(e) { + e.preventDefault(); + }); diff --git a/packages/main/test/specs/DatePicker.spec.js b/packages/main/test/specs/DatePicker.spec.js index 7dff59f6ee78..3e03b83293a2 100644 --- a/packages/main/test/specs/DatePicker.spec.js +++ b/packages/main/test/specs/DatePicker.spec.js @@ -1330,4 +1330,18 @@ describe("Date Picker Tests", () => { let displayedYear = await datepicker.getDisplayedYear(11); assert.notOk(await displayedYear.hasClass("ui5-yp-item--disabled"), "Year 2025 is not disabled"); }); + + it("Value state is not changed, when value-state-change is prevented", async () => { + datepicker.id = "#dpVsChangePrevented"; + + const input = await datepicker.getInput(); + + const valueState = await input.getProperty("valueState"); + await input.click(); + await browser.keys("Jan 29, 2019"); + + await browser.$("#dpVsChangePrevented").shadow$("ui5-input").shadow$("input").click(); // click elsewhere to focusout + + assert.strictEqual(await input.getProperty("valueState"), valueState, "value state is not changed"); + }); }); From fe5b2fc323098db6cecb4a94b30e1af4d726f152 Mon Sep 17 00:00:00 2001 From: hinzzx Date: Fri, 19 Jan 2024 11:19:33 +0200 Subject: [PATCH 2/8] feat(ui5-date-picker): address code review comments, add generic type to event --- packages/main/src/DatePicker.ts | 16 ++++++---------- packages/main/test/pages/DatePicker.html | 1 - 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index 2c0e72c66ea9..8a87a92afd3f 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -222,7 +222,7 @@ type DatePickerInputEventDetail = { }, }) /** - * Fired before the value state of the component is updated. + * Fired before the value state of the component is updated internally. * The event is preventable, meaning that if it's default action is * prevented, the component will not update the value state. * @@ -230,7 +230,7 @@ type DatePickerInputEventDetail = { * @public * @param {boolean} isValid Indicates whether the current value of the component is considered valid. */ -@event("value-state-change", { +@event("value-state-change", { detail: { /** * @public @@ -240,7 +240,6 @@ type DatePickerInputEventDetail = { }, }, }) - class DatePicker extends DateComponentBase implements IFormElement { /** * Defines a formatted date value. @@ -567,14 +566,11 @@ class DatePicker extends DateComponentBase implements IFormElement { _updateValueState() { const isValid = this._checkValueValidity(this.value); - const eventPrevented = !this.fireEvent("value-state-change", { isValid }, true); + const newValueState = isValid ? ValueState.None : ValueState.Error; - if (!eventPrevented) { - if (isValid && this.valueState === ValueState.Error) { // If not valid - always set Error regardless of the current value state - this.valueState = ValueState.None; - } else if (!isValid) { // However if valid, change only Error (but not the others) to None - this.valueState = ValueState.Error; - } + if (this.valueState !== newValueState) { + const eventPrevented = !this.fireEvent("value-state-change", { isValid }, true); + this.valueState = eventPrevented ? this.valueState : newValueState; } } diff --git a/packages/main/test/pages/DatePicker.html b/packages/main/test/pages/DatePicker.html index 6526b25d3425..70e825dd00df 100644 --- a/packages/main/test/pages/DatePicker.html +++ b/packages/main/test/pages/DatePicker.html @@ -207,7 +207,6 @@

DatePicker with format `yyyy` should open picker on years

datePickerValueStateChangePrevented.addEventListener("value-state-change", function(e) { e.preventDefault(); - console.log("Value state change prevented!", datePickerValueStateChangePrevented); }); From 6cf0f5d546911c322a926a7a09fc54411b120d15 Mon Sep 17 00:00:00 2001 From: hinzzx Date: Fri, 19 Jan 2024 15:00:20 +0200 Subject: [PATCH 3/8] feat(ui5-data-picker): change event detail --- packages/main/src/DatePicker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index 8a87a92afd3f..98100638e949 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -60,7 +60,7 @@ type DatePickerChangeEventDetail = { } type ValueStateChangeEventDetail = { - isValid: boolean, + newValueState: `${ValueState}`, } type DatePickerInputEventDetail = { @@ -228,15 +228,15 @@ type DatePickerInputEventDetail = { * * @allowPreventDefault * @public - * @param {boolean} isValid Indicates whether the current value of the component is considered valid. + * @param {string} newValueState The new valueState that will be set. */ @event("value-state-change", { detail: { /** * @public */ - isValid: { - type: Boolean, + newValueState: { + type: String, }, }, }) @@ -569,7 +569,7 @@ class DatePicker extends DateComponentBase implements IFormElement { const newValueState = isValid ? ValueState.None : ValueState.Error; if (this.valueState !== newValueState) { - const eventPrevented = !this.fireEvent("value-state-change", { isValid }, true); + const eventPrevented = !this.fireEvent("value-state-change", { newValueState }, true); this.valueState = eventPrevented ? this.valueState : newValueState; } } From ae658ba6abf73a5ecb460e79d80639c0ada411ff Mon Sep 17 00:00:00 2001 From: hinzzx Date: Fri, 19 Jan 2024 15:26:29 +0200 Subject: [PATCH 4/8] feat(ui5-date-picker): add the valid event detail --- packages/main/src/DatePicker.ts | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index 98100638e949..3c65a07bec04 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -60,7 +60,8 @@ type DatePickerChangeEventDetail = { } type ValueStateChangeEventDetail = { - newValueState: `${ValueState}`, + valueState: `${ValueState}`, + valid: boolean, } type DatePickerInputEventDetail = { @@ -228,16 +229,22 @@ type DatePickerInputEventDetail = { * * @allowPreventDefault * @public - * @param {string} newValueState The new valueState that will be set. + * @param {string} valueState The new valueState that will be set. */ @event("value-state-change", { detail: { /** * @public */ - newValueState: { + valueState: { type: String, }, + /** + * @public + */ + valid: { + type: Boolean, + }, }, }) class DatePicker extends DateComponentBase implements IFormElement { @@ -565,12 +572,12 @@ class DatePicker extends DateComponentBase implements IFormElement { } _updateValueState() { - const isValid = this._checkValueValidity(this.value); - const newValueState = isValid ? ValueState.None : ValueState.Error; + const valid = this._checkValueValidity(this.value); + const valueState = valid ? ValueState.None : ValueState.Error; - if (this.valueState !== newValueState) { - const eventPrevented = !this.fireEvent("value-state-change", { newValueState }, true); - this.valueState = eventPrevented ? this.valueState : newValueState; + if (this.valueState !== valueState) { + const eventPrevented = !this.fireEvent("value-state-change", { valueState, valid }, true); + this.valueState = eventPrevented ? this.valueState : valueState; } } From 8ee0ba84c4c2e5c6665f2c8ce969797e8ce4b40a Mon Sep 17 00:00:00 2001 From: hinzzx Date: Mon, 22 Jan 2024 16:49:54 +0200 Subject: [PATCH 5/8] feat(ui5-date-picker): address code review comments --- packages/main/src/DatePicker.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index 3c65a07bec04..db47424032ea 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -573,11 +573,14 @@ class DatePicker extends DateComponentBase implements IFormElement { _updateValueState() { const valid = this._checkValueValidity(this.value); - const valueState = valid ? ValueState.None : ValueState.Error; + const previousValueState = this.valueState; - if (this.valueState !== valueState) { - const eventPrevented = !this.fireEvent("value-state-change", { valueState, valid }, true); - this.valueState = eventPrevented ? this.valueState : valueState; + this.valueState = valid ? ValueState.None : ValueState.Error; + + const eventPrevented = !this.fireEvent("value-state-change", { valueState: this.valueState, valid }, true); + + if (eventPrevented) { + this.valueState = previousValueState; } } From b6e3d2d707b59c0ccec606f8ce9ad628c055a363 Mon Sep 17 00:00:00 2001 From: hinzzx Date: Tue, 23 Jan 2024 14:12:48 +0200 Subject: [PATCH 6/8] fix(ui5-date-picker): change event detail name and export it --- packages/main/src/DatePicker.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index db47424032ea..da3c950ec077 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -59,7 +59,7 @@ type DatePickerChangeEventDetail = { valid: boolean, } -type ValueStateChangeEventDetail = { +type DatePickerValueStateChangeEventDetail = { valueState: `${ValueState}`, valid: boolean, } @@ -231,7 +231,7 @@ type DatePickerInputEventDetail = { * @public * @param {string} valueState The new valueState that will be set. */ -@event("value-state-change", { +@event("value-state-change", { detail: { /** * @public @@ -577,7 +577,7 @@ class DatePicker extends DateComponentBase implements IFormElement { this.valueState = valid ? ValueState.None : ValueState.Error; - const eventPrevented = !this.fireEvent("value-state-change", { valueState: this.valueState, valid }, true); + const eventPrevented = !this.fireEvent("value-state-change", { valueState: this.valueState, valid }, true); if (eventPrevented) { this.valueState = previousValueState; @@ -893,4 +893,5 @@ export default DatePicker; export type { DatePickerChangeEventDetail, DatePickerInputEventDetail, + DatePickerValueStateChangeEventDetail, }; From d4734201ee19a2e0a41a6bd0ac1cf69826d6ddf0 Mon Sep 17 00:00:00 2001 From: hinzzx Date: Thu, 25 Jan 2024 08:44:22 +0200 Subject: [PATCH 7/8] feat(ui5-date-picker): address code review comments --- packages/main/src/DatePicker.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index 430e6075b25a..a54df09cc393 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -182,7 +182,7 @@ type DatePickerInputEventDetail = { * @param {string} value The submitted value. * @param {boolean} valid Indicator if the value is in correct format pattern and in valid range. */ -@event("change", { +@event("change", { detail: { /** * @public @@ -206,7 +206,7 @@ type DatePickerInputEventDetail = { * @param {string} value The submitted value. * @param {boolean} valid Indicator if the value is in correct format pattern and in valid range. */ -@event("input", { +@event("input", { detail: { /** * @public @@ -230,6 +230,7 @@ type DatePickerInputEventDetail = { * @allowPreventDefault * @public * @param {string} valueState The new valueState that will be set. + * @param {boolean} valid Indicator if the value is in correct format pattern and in valid range. */ @event("value-state-change", { detail: { From 5a300aa85e14c5171f1e8a4d274c3c08bbc562c2 Mon Sep 17 00:00:00 2001 From: hinzzx Date: Thu, 25 Jan 2024 08:48:40 +0200 Subject: [PATCH 8/8] feat(ui5-date-picker): add missing event details --- packages/main/src/DatePicker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index a54df09cc393..2320aa9df5bd 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -182,7 +182,7 @@ type DatePickerInputEventDetail = { * @param {string} value The submitted value. * @param {boolean} valid Indicator if the value is in correct format pattern and in valid range. */ -@event("change", { +@event("change", { detail: { /** * @public @@ -206,7 +206,7 @@ type DatePickerInputEventDetail = { * @param {string} value The submitted value. * @param {boolean} valid Indicator if the value is in correct format pattern and in valid range. */ -@event("input", { +@event("input", { detail: { /** * @public