From 9f5c8a4f3145a8f56abec178188e53b387a627b6 Mon Sep 17 00:00:00 2001 From: Nikoleta Ivanova <31706628+nikoletavnv@users.noreply.github.com> Date: Wed, 8 May 2024 15:38:06 +0300 Subject: [PATCH] refactor(ui5-input): events changes (#8769) * refactor(ui5-input): events changes BREAKING CHANGE: Remove suggestion-item-select event. Rename and modify suggestion-item-preview event. Remove openPicker method and replace it with public property "open". * refactor(ui5-input): events changes * refactor(ui5-input): property open tests * refactor(ui5-input): events change * refactor(ui5-input): events change * refactor(ui5-input): events changes * refactor(ui5-input): events changes * refactor(ui5-input): events changes --- packages/fiori/src/themes/ShellBar.css | 1 - packages/fiori/test/pages/ShellBar.html | 2 +- packages/main/src/Input.ts | 178 ++++++--------- packages/main/src/MultiInput.ts | 9 +- .../main/src/features/InputSuggestions.ts | 12 +- packages/main/test/pages/Input.html | 83 ++++--- packages/main/test/pages/Input_quickview.html | 15 +- packages/main/test/pages/MultiInput.html | 15 +- .../test/pages/MultiInput_Suggestions.html | 2 +- packages/main/test/specs/Input.mobile.spec.js | 11 +- packages/main/test/specs/Input.spec.js | 202 ++++++++---------- packages/main/test/specs/MultiInput.spec.js | 40 ---- 12 files changed, 222 insertions(+), 348 deletions(-) diff --git a/packages/fiori/src/themes/ShellBar.css b/packages/fiori/src/themes/ShellBar.css index cdea64312c4a..e19dd8ded01c 100644 --- a/packages/fiori/src/themes/ShellBar.css +++ b/packages/fiori/src/themes/ShellBar.css @@ -454,7 +454,6 @@ slot[name="profile"] { box-shadow: var(--_ui5_shellbar_search_field_box_shadow_hover); } -/* Todo: modify this selector after ui5-input is updated */ ::slotted([ui5-input][focused]) { outline: var(--_ui5_shellbar_search_field_outline_focused); } diff --git a/packages/fiori/test/pages/ShellBar.html b/packages/fiori/test/pages/ShellBar.html index 5eff69e15ab0..16a77695e1c4 100644 --- a/packages/fiori/test/pages/ShellBar.html +++ b/packages/fiori/test/pages/ShellBar.html @@ -240,7 +240,7 @@

ShellBar in Compact

diff --git a/packages/main/test/pages/Input_quickview.html b/packages/main/test/pages/Input_quickview.html index ae90ee3b8c42..7bd144669f1b 100644 --- a/packages/main/test/pages/Input_quickview.html +++ b/packages/main/test/pages/Input_quickview.html @@ -73,8 +73,8 @@

Test Quick View sample



-
Test suggestion-item-preview
- +
Test selection-change
+

Test mouseover on item
@@ -105,9 +105,9 @@

Test Quick View sample

var focusQuickView = false; /* - * Open quickviewCard on suggestion-item-preview + * Open quickviewCard on selection-change */ - inputPreview.addEventListener("ui5-suggestion-item-preview", function (event) { + inputPreview.addEventListener("ui5-selection-change", function (event) { const targetRef = event.detail.targetRef; quickViewCard.close(); @@ -159,17 +159,16 @@

Test Quick View sample

*/ var focusQuickView2 = false; - inputPreview2.addEventListener("ui5-suggestion-item-preview", function (event) { + inputPreview2.addEventListener("ui5-selection-change", function (event) { var item = event.detail.targetRef; quickViewCard2.close(); quickViewCard2.showAt(item, true /* preventInitialFocus */); // log info - suggestionItemPreviewRes.value = item.textContent; + selectionChangeRes.value = item.textContent; }); inputPreview2.addEventListener("keyup", async function (event) { - const item = event.target.previewItem; const combination = event.key === "1"; if (combination) { @@ -179,7 +178,7 @@

Test Quick View sample

} // log info - keyupResult.value = event.key + " on item: " + (item && item.text); + keyupResult.value = event.key + " on suggestion item"; }); [].slice.call(document.querySelectorAll("#inputPreview2 .suggestionItem")).forEach(function(el) { diff --git a/packages/main/test/pages/MultiInput.html b/packages/main/test/pages/MultiInput.html index 83fe18c07cab..5b09821ffad4 100644 --- a/packages/main/test/pages/MultiInput.html +++ b/packages/main/test/pages/MultiInput.html @@ -315,7 +315,7 @@

Suggestions + showing wrapping

Create tokens on change and on paste

- +
Token is already in the list
@@ -424,19 +424,6 @@

Eventing

document.getElementById("dialog").show(); }); - document.getElementById("suggestion-token").addEventListener("ui5-suggestion-item-select", function (event) { - var item = event.detail.item; - var mi = event.target - var token = document.createElement("ui5-token"); - - token.setAttribute("text", item.text); - token.setAttribute("slot", "tokens"); - event.target.appendChild(token); - - // discuss ?! - event.target.value = ""; - }); - document.getElementById("basic-overflow-and-icon").addEventListener("ui5-value-help-trigger", function (event) { document.getElementById("basic-event-listener").innerHTML = "value help icon press"; }); diff --git a/packages/main/test/pages/MultiInput_Suggestions.html b/packages/main/test/pages/MultiInput_Suggestions.html index bfed2e3aa5bb..0c9bc686233c 100644 --- a/packages/main/test/pages/MultiInput_Suggestions.html +++ b/packages/main/test/pages/MultiInput_Suggestions.html @@ -97,7 +97,7 @@

Token Creation onChange (unique)

document.getElementById("dialog").show(); }); - document.getElementById("suggestion-token").addEventListener("ui5-suggestion-item-select", function (event) { + document.getElementById("suggestion-token").addEventListener("ui5-selection-change", function (event) { var item = event.detail.item; var mi = event.target var token = document.createElement("ui5-token"); diff --git a/packages/main/test/specs/Input.mobile.spec.js b/packages/main/test/specs/Input.mobile.spec.js index 0af2f27959e7..aa5a2d0567ac 100644 --- a/packages/main/test/specs/Input.mobile.spec.js +++ b/packages/main/test/specs/Input.mobile.spec.js @@ -76,25 +76,26 @@ describe("Eventing", () => { const input = await browser.$("#myInput"); const sExpectedSelectedKey = "Bg"; const sChangeText = "Bulgaria"; + const sTypedText = "b"; await input.scrollIntoView(); await input.click(); const dialogInput = await input.shadow$("ui5-responsive-popover").$(".ui5-input-inner-phone"); - await dialogInput.keys("b"); + await dialogInput.keys(sTypedText); const suggestionItem = await input.shadow$("ui5-responsive-popover").$$("ui5-li-suggestion-item")[2]; await suggestionItem.click(); - const selectedKey = await browser.$("#myLabel").getText(); - assert.strictEqual(selectedKey.split(" :: ")[1], sExpectedSelectedKey, "Selected key event property was correct"); + const selectedKey = await browser.$("#myLabelSelectionChange").getText(); + assert.strictEqual(selectedKey.split(" :: ")[1], sExpectedSelectedKey, "Selection change event property was correct"); const change = await browser.$("#myLabelChange").getText(); assert.strictEqual(change.split(" :: ")[1], sChangeText, "Change event property was correct"); - const liveChange = await browser.$("#myLabelLiveChange").getText(); - assert.strictEqual(liveChange.split(" :: ")[1], sChangeText, "liveChange event property was correct"); + const inputChange = await browser.$("#myLabelInputChange").getText(); + assert.strictEqual(inputChange.split(" :: ")[1], sTypedText, "Input event property was correct"); }); }); diff --git a/packages/main/test/specs/Input.spec.js b/packages/main/test/specs/Input.spec.js index 2defdcd64ee8..68f367a89a4d 100644 --- a/packages/main/test/specs/Input.spec.js +++ b/packages/main/test/specs/Input.spec.js @@ -378,14 +378,12 @@ describe("Input general interaction", () => { // assert.ok(!await popover.getProperty("open"), "suggestions are closed"); // assert.strictEqual(await suggestionsInput.getValue(), "Portugal", "First item has been selected"); - // assert.strictEqual(await inputResult.getValue(), "1", "suggestionItemSelected event called once"); // await suggestionsInput.keys("\b"); // item = await browser.$("#myInput").$$("ui5-li")[0]; // await item.click(); // assert.strictEqual(await suggestionsInput.getValue(), "Portugal", "First item has been selected again"); - // assert.strictEqual(await inputResult.getValue(), "2", "suggestionItemSelected event called for second time"); }); it("handles suggestions selection cancel with ESC", async () => { @@ -462,27 +460,11 @@ describe("Input general interaction", () => { assert.strictEqual(await suggestionsInput.getValue(), "abc", "The value is restored to the last confirmed by 'ENTER' press one."); }); - it("handles group suggestion item via keyboard", async () => { - - const suggestionsInput = await browser.$("#myInputGrouping").shadow$("input"); - const inputResult = await browser.$("#inputResultGrouping").shadow$("input"); - - await suggestionsInput.click(); - await suggestionsInput.keys("C"); - await suggestionsInput.keys("ArrowDown"); - await suggestionsInput.keys("Enter"); - await browser.pause(300); - - assert.strictEqual(await suggestionsInput.getValue(), "C", "Group item is not selected"); - assert.strictEqual(await inputResult.getValue(), "", "suggestionItemSelected event is not called"); - }); - it("should select typeaheaded item on mouse click and remove value text selection", async () => { await browser.url(`test/pages/Input.html`); const suggestionsInput = await browser.$("#myInput").shadow$("input"); const changeEventResult = await browser.$("#inputResult").shadow$("input"); - const suggestionSelectEventResult = await browser.$("#input-selection-event-test").shadow$("input"); const input = await browser.$("#myInput"); const respPopover = await input.shadow$("ui5-responsive-popover"); @@ -500,7 +482,6 @@ describe("Input general interaction", () => { }); assert.strictEqual(await changeEventResult.getValue(), "1", "Change is fired once"); - assert.strictEqual(await suggestionSelectEventResult.getValue(), "1", "suggestion-item-select is fired once"); assert.strictEqual(await valueNotSelected, true, "Value is no longer type aheaded (autocompleted)"); }); @@ -509,7 +490,6 @@ describe("Input general interaction", () => { const suggestionsInput = await browser.$("#myInput").shadow$("input"); const changeEventResult = await browser.$("#inputResult").shadow$("input"); - const suggestionSelectEventResult = await browser.$("#input-selection-event-test").shadow$("input"); const input = await browser.$("#myInput"); const respPopover = await input.shadow$("ui5-responsive-popover"); @@ -530,7 +510,6 @@ describe("Input general interaction", () => { assert.strictEqual(await suggestionsInput.getValue(), "Cuba", "Item is selected"); assert.strictEqual(await changeEventResult.getValue(), "1", "Change is fired once"); - assert.strictEqual(await suggestionSelectEventResult.getValue(), "1", "suggestion-item-select is fired once"); assert.strictEqual(await valueNotSelected, true, "Value is no longer type aheaded (autocompleted)"); }); @@ -731,11 +710,11 @@ describe("Input general interaction", () => { assert.strictEqual(parseFloat(await input.getProperty("value")).toPrecision(3), "1.22", "Value is not lost"); }); - it("fires suggestion-item-preview", async () => { + it("fires selection-change", async () => { await browser.url(`test/pages/Input_quickview.html`); const inputItemPreview = await browser.$("#inputPreview2").shadow$("input"); - const suggestionItemPreviewRes = await browser.$("#suggestionItemPreviewRes"); + const selectionChangeRes = await browser.$("#selectionChangeRes"); const EXPECTED_PREVIEW_ITEM_TEXT = "Laptop Lenovo"; // act @@ -749,7 +728,7 @@ describe("Input general interaction", () => { const inputPopover = await inputElement.shadow$("ui5-responsive-popover"); const helpPopover = await browser.$("#quickViewCard2"); - assert.strictEqual(await suggestionItemPreviewRes.getValue(), EXPECTED_PREVIEW_ITEM_TEXT, "First item has been previewed"); + assert.strictEqual(await selectionChangeRes.getValue(), EXPECTED_PREVIEW_ITEM_TEXT, "First item has been previewed"); assert.ok(await helpPopover.isDisplayedInViewport(), "The help popover is open."); assert.ok(await inputPopover.isDisplayedInViewport(), "The input popover is open."); @@ -1072,8 +1051,8 @@ describe("Input general interaction", () => { await input.scrollIntoView(); - await browser.executeAsync((done) =>{ - return done(document.getElementById("change-event-value").openPicker()); + await browser.execute(() =>{ + document.getElementById("change-event-value").openPicker(); }); const listItem = await input.shadow$("ui5-responsive-popover").$("ui5-li-suggestion-item"); @@ -1087,36 +1066,6 @@ describe("Input general interaction", () => { describe("Input arrow navigation", () => { - it("handles suggestions via keyboard, should not fire suggestionItemSelect on inactive item", async () => { - await browser.url(`test/pages/Input.html`); - - const suggestionsInput = await browser.$("#myInput2").shadow$("input"); - const inputResult = await browser.$("#inputResult").shadow$("input"); - - await suggestionsInput.click(); - await suggestionsInput.keys("c"); - await suggestionsInput.keys("ArrowDown"); - await suggestionsInput.keys("Enter"); - - assert.strictEqual(await suggestionsInput.getValue(), "Cozy", "First item has been selected"); - assert.strictEqual(await inputResult.getValue(), "1", "suggestionItemSelected event called once"); - - await suggestionsInput.keys("Backspace"); // to open the suggestions pop up once again - await suggestionsInput.keys("ArrowUp"); - - assert.strictEqual(await suggestionsInput.getValue(), "Coz", - "The input is still focused"); - - await suggestionsInput.keys("ArrowDown"); - await suggestionsInput.keys("ArrowDown"); - await suggestionsInput.keys("ArrowDown"); - await suggestionsInput.keys("ArrowDown"); - await suggestionsInput.keys("Enter"); - - assert.strictEqual(await suggestionsInput.getValue(), "Coz", "Inactive item text is not applied as input's value"); - assert.strictEqual(await inputResult.getValue(), "1", "suggestionItemSelect is not fired as item is 'Inactive'"); - }); - it("Should navigate up and down through the suggestions popover with arrow keys", async () => { await browser.url(`test/pages/Input.html`); @@ -1472,59 +1421,6 @@ describe("XSS tests for suggestions", () => { }); }); -describe("Prevent suggestion-item-select event", () => { - let input; - let SUGGESTION_TEXT; - const INPUT_ID_SELECTOR = "#input-prevent-suggestion-select"; - - beforeEach(async () => { - await browser.url(`test/pages/Input.html`); - - input = await browser.$(INPUT_ID_SELECTOR); - }); - - it("User can prevent suggested-item-select on desired item", async () => { - SUGGESTION_TEXT = "Cozy"; - - await input.click(); - await input.keys(SUGGESTION_TEXT.at(0)); - - const respPopover = await input.shadow$("ui5-responsive-popover"); - - // Select first suggestion item that has event prevent - const firstSuggestion = await respPopover - .$("ui5-list") - .$("ui5-li-suggestion-item"); - await firstSuggestion.click(); - - assert.strictEqual( - await input.getProperty("value"), - "test test", - "Prevent suggestion-item-select event does not work" - ); - }); - - it("Suggestion selection works as usual for items that do not match event prevent criterias defined by user", async () => { - SUGGESTION_TEXT = "Compact"; - - await input.click(); - await input.keys(SUGGESTION_TEXT.at(0)); - - const respPopover = await input.shadow$("ui5-responsive-popover"); - - const secondSuggestion = await respPopover - .$("ui5-list") - .$$("ui5-li-suggestion-item")[1]; - await secondSuggestion.click(); - - assert.strictEqual( - await input.getProperty("value"), - SUGGESTION_TEXT, - "Event suggestion-item-select works as expected for items without event prevention" - ); - }); -}); - describe("Lazy loading", () => { beforeEach(async () => { await browser.url(`test/pages/InputsLazyLoading.html`); @@ -1580,4 +1476,92 @@ describe("Lazy loading", () => { assert.strictEqual(await respPopover.getProperty("open"), true, "Picker should not be open"); }); +}); + +describe("Selection-change event", () => { + it("Selection-change event fires when interacting with Arrow UP and Arrow DOWN keys", async () => { + await browser.url(`test/pages/Input.html`); + + const input = await $("#input-selection-change"); + const inner = await input.shadow$("input"); + + await inner.click(); + await inner.keys("C"); + await input.keys("ArrowDown"); + await input.keys("ArrowDown"); + await input.keys("ArrowUp"); + + const selectionChangeCount = await $("#input-selection-change-count"); + assert.strictEqual(await selectionChangeCount.getText(), "3", "Selection-change event was fired 3 times"); + }); + + it("Selection-change event fires when suggestion item is selected by clicking on it without previously selected", async () => { + await browser.url(`test/pages/Input.html`); + + const input = await $("#input-selection-change"); + const inner = await input.shadow$("input"); + const selectionChangeCount = await $("#input-selection-change-count"); + + await inner.click(); + await inner.keys("C"); + + // select first item + await input.keys("ArrowDown"); + assert.strictEqual(await selectionChangeCount.getText(), "1", "Selection-change event was fired 1 time"); + + const respPopover = await input.shadow$("ui5-responsive-popover"); + + // click on second item + const suggestionItems = await respPopover.$("ui5-list").$$("ui5-li-suggestion-item"); + await suggestionItems[2].click(); + + assert.strictEqual(await selectionChangeCount.getText(), "2", "Selection-change event was fired 2 times"); + }); + + it("Selection-change event does not fire when item is clicked but focus is already on it", async () => { + await browser.url(`test/pages/Input.html`); + + const input = await $("#input-selection-change"); + const inner = await input.shadow$("input"); + const selectionChangeCount = await $("#input-selection-change-count"); + + await inner.click(); + await inner.keys("C"); + + // select first item + await input.keys("ArrowDown"); + assert.strictEqual(await selectionChangeCount.getText(), "1", "Selection-change event was fired once"); + + const respPopover = await input.shadow$("ui5-responsive-popover"); + + // click on first item + const firstSuggestion = await respPopover.$("ui5-list").$("ui5-li-suggestion-item"); + await firstSuggestion.click(); + + assert.strictEqual(await selectionChangeCount.getText(), "1", "Selection-change event was fired once"); + }); + + it("Selection-change event fires with null arguments when suggestion was selected but user alters input value to something else", async () => { + await browser.url(`test/pages/Input.html`); + + const input = await $("#input-selection-change"); + const inner = await input.shadow$("input"); + const selectionChangeCount = await $("#input-selection-change-count"); + const selectionChangeValue = await $("#input-selection-change-value"); + + await inner.click(); + await inner.keys("C"); + + // select first item + await input.keys("ArrowDown"); + assert.strictEqual(await selectionChangeCount.getText(), "1", "Selection-change event was fired once"); + assert.strictEqual(await selectionChangeValue.getText(), "Cozy", "Selection-change event was fired with arguments"); + + await inner.click(); + await inner.keys("N"); // this value is not in the suggestions + await inner.keys("Enter"); + + assert.strictEqual(await selectionChangeCount.getText(), "2", "Selection-change event was fired twice"); + assert.strictEqual(await selectionChangeValue.getText(), "", "Selection-change event was fired with null arguments"); + }); }); \ No newline at end of file diff --git a/packages/main/test/specs/MultiInput.spec.js b/packages/main/test/specs/MultiInput.spec.js index 37c94351a3af..2c55e76b9a30 100644 --- a/packages/main/test/specs/MultiInput.spec.js +++ b/packages/main/test/specs/MultiInput.spec.js @@ -122,25 +122,6 @@ describe("MultiInput general interaction", () => { assert.ok(await allTokens[5].getProperty("overflows"), `Token 5 should not overflow`); }); - it ("adds a token after selection change", async () => { - const mi = await browser.$("#suggestion-token"); - const input = await mi.shadow$("input"); - const popover = await mi.shadow$("ui5-responsive-popover"); - - await input.click(); - await input.keys("c"); - - assert.ok(await popover.getProperty("open"), "Suggestion Popovoer is open"); - let allTokens = await mi.$$("ui5-token"); - assert.strictEqual(allTokens.length, 0, "0 tokens"); - - await popover.$("ui5-li-suggestion-item").click(); - - allTokens = await mi.$$("ui5-token"); - assert.notOk(await popover.getProperty("open"), "Suggestion Popovoer is closed"); - assert.strictEqual(allTokens.length, 1, "a token is added after selection"); - }); - it ("Placeholder", async () => { const mi1 = await browser.$("#empty-mi").shadow$(".ui5-input-inner"); const mi2 = await browser.$("#mi-with-tokens-customicon").shadow$(".ui5-input-inner"); @@ -616,27 +597,6 @@ describe("Keyboard handling", () => { assert.notEqual(newScrollLeft, scrollLeftForthToken, "tokenizer is scrolled again when navigating through the tokens"); }) - it("should change input's value when set in selection change event", async () => { - const input = $("#suggestion-token"); - const innerInput = input.shadow$("input"); - - await input.scrollIntoView(); - await innerInput.click(); - await innerInput.keys('a'); - await innerInput.keys("Enter"); - - assert.strictEqual(await input.getProperty("value"), "", "value should be cleared in event handler"); - assert.strictEqual(await innerInput.getProperty("value"), "", "inner value should be cleared in event handler"); - - await innerInput.keys("ArrowLeft"); - - assert.isNotOk(await input.getProperty("focused"), "focused property has been removed from input"); - - await innerInput.keys("ArrowRight"); - - assert.isOk(await input.getProperty("focused"), "focused property has been set to the input"); - }); - it("should text field always when focus in" , async () => { const mi = $("#one-token"); const inner = mi.shadow$("input");