Skip to content

Commit

Permalink
feat(ui5-suggestion-item): enable mouseover|out events (#1784)
Browse files Browse the repository at this point in the history
The user can now bind for mouseover and mouseout events on the ui5-suggestion-item elements and perform some other action. For example: opening another popover, pointing to particular suggestion, when hovered.

FIXES: #1768
  • Loading branch information
ilhan007 committed Jun 15, 2020
1 parent 511cb40 commit 4359b9a
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 15 deletions.
32 changes: 32 additions & 0 deletions packages/main/src/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,21 @@ class Input extends UI5Element {
this.valueBeforeItemSelection = this.value;
this.value = item.group ? "" : item.textContent;
this._announceSelectedItem();
this._previewItem = item;
}

/**
* The suggestion item on preview.
* @type { ui5-suggestion-item }
* @readonly
* @public
*/
get previewItem() {
if (!this._previewItem) {
return null;
}

return this.getSuggestionByListItem(this._previewItem);
}

async fireEventByAction(action) {
Expand Down Expand Up @@ -795,13 +810,30 @@ class Input extends UI5Element {
return this.getInputId();
}

getSuggestionByListItem(item) {
const key = parseInt(item.getAttribute("data-ui5-key"));
return this.suggestionItems[key];
}

getInputId() {
return `${this._id}-inner`;
}

/* Suggestions interface */
onItemFocused() {}

onItemMouseOver(event) {
const item = event.target;
const suggestion = this.getSuggestionByListItem(item);
suggestion.fireEvent("mouseover", { targetRef: item });
}

onItemMouseOut(event) {
const item = event.target;
const suggestion = this.getSuggestionByListItem(item);
suggestion.fireEvent("mouseout", { targetRef: item });
}

onItemSelected(item, keyboardUsed) {
this.selectSuggestion(item, keyboardUsed);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/main/src/InputPopover.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
{{/if}}
{{/unless}}


<ui5-list separators="Inner">
{{#each suggestionsTexts}}
{{#if group}}
Expand All @@ -61,6 +60,7 @@
info="{{this.info}}"
info-state="{{this.infoState}}"
@ui5-_item-press="{{ fnOnSuggestionItemPress }}"
data-ui5-key="{{key}}"
>{{ this.text }}</ui5-li>
{{/if}}
{{/each}}
Expand Down
8 changes: 6 additions & 2 deletions packages/main/src/Popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,10 @@ class Popover extends Popup {
/**
* Opens the popover.
* @param {HTMLElement} opener the element that the popover is opened by
* @param {boolean} preventInitialFocus prevents applying the focus inside the popover
* @public
*/
openBy(opener) {
openBy(opener, preventInitialFocus = false) {
if (!opener || this.opened) {
return;
}
Expand All @@ -266,7 +267,10 @@ class Popover extends Popup {

this.fireEvent("before-open", {});
this.reposition();
this.applyInitialFocus();

if (!preventInitialFocus) {
this.applyInitialFocus();
}

addOpenedPopover(this);

Expand Down
17 changes: 16 additions & 1 deletion packages/main/src/features/InputSuggestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Suggestions {
// Press and Focus handlers
this.fnOnSuggestionItemPress = this.onItemPress.bind(this);
this.fnOnSuggestionItemFocus = this.onItemFocused.bind(this);
this.fnOnSuggestionItemMouseOver = this.onItemMouseOver.bind(this);
this.fnOnSuggestionItemMouseOut = this.onItemMouseOut.bind(this);

// An integer value to store the currently selected item position,
// that changes due to user interaction.
Expand All @@ -45,7 +47,7 @@ class Suggestions {
const inputSuggestionItems = this._getComponent().suggestionItems;

const suggestions = [];
inputSuggestionItems.map(suggestion => {
inputSuggestionItems.map((suggestion, idx) => {
return suggestions.push({
text: suggestion.text || suggestion.textContent, // keep textContent for compatibility
description: suggestion.description || undefined,
Expand All @@ -54,6 +56,7 @@ class Suggestions {
info: suggestion.info || undefined,
infoState: suggestion.infoState,
group: suggestion.group,
key: idx,
});
});

Expand Down Expand Up @@ -119,6 +122,14 @@ class Suggestions {
this._getComponent().onItemFocused();
}

onItemMouseOver(event) {
this._getComponent().onItemMouseOver(event);
}

onItemMouseOut(event) {
this._getComponent().onItemMouseOut(event);
}

onItemSelected(selectedItem, keyboardUsed) {
const item = selectedItem || this._getItems()[this.selectedItemIndex];

Expand Down Expand Up @@ -155,6 +166,10 @@ class Suggestions {
list.addEventListener("ui5-item-press", this.fnOnSuggestionItemPress);
list.removeEventListener("ui5-item-focused", this.fnOnSuggestionItemFocus);
list.addEventListener("ui5-item-focused", this.fnOnSuggestionItemFocus);
list.removeEventListener("mouseover", this.fnOnSuggestionItemMouseOver);
list.addEventListener("mouseover", this.fnOnSuggestionItemMouseOver);
list.removeEventListener("mouseout", this.fnOnSuggestionItemMouseOut);
list.addEventListener("mouseout", this.fnOnSuggestionItemMouseOut);
}

_attachPopupListeners() {
Expand Down
63 changes: 53 additions & 10 deletions packages/main/test/pages/Input.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,32 @@ <h3>Input in Compact</h3>
</div>

<h3> Input suggestions with ui5-suggestion-item</h3>
<ui5-input id="inputItemPreviewRes" placeholder="preview item test"></ui5-input>
<ui5-input id="inputItemPreview" show-suggestions style="width: 100%">
<ui5-suggestion-item text="Cozy"></ui5-suggestion-item>
<ui5-suggestion-item text="Compact"></ui5-suggestion-item>
<ui5-suggestion-item text="Condensed"></ui5-suggestion-item>
<ui5-suggestion-item text="Cozy"></ui5-suggestion-item>
<ui5-suggestion-item text="Compact"></ui5-suggestion-item>
<ui5-suggestion-item text="Condensed"></ui5-suggestion-item>

<div style="width: 200px">Input keyp</div>
<ui5-input id="keyupResult" style="width: 100%"></ui5-input> <br>

<div style="width: 200px">Input suggestion-item-preview</div>
<ui5-input id="inputItemPreviewRes" style="width:100%"></ui5-input><br><br>

<div style="width: 200px">mouseover on item</div>
<ui5-input id="mouseoverResult" style="width: 100%"></ui5-input> <br>

<div style="width: 200px">mouseout on item</div>
<ui5-input id="mouseoutResult" style="width:100%"></ui5-input><br>

<ui5-input id="inputPreview" show-suggestions style="width: 200px">
<ui5-suggestion-item class="suggestionItem" text="Cozy"></ui5-suggestion-item>
<ui5-suggestion-item class="suggestionItem" text="Compact"></ui5-suggestion-item>
<ui5-suggestion-item class="suggestionItem" text="Condensed"></ui5-suggestion-item>
<ui5-suggestion-item class="suggestionItem" text="Cozy"></ui5-suggestion-item>
<ui5-suggestion-item class="suggestionItem" text="Compact"></ui5-suggestion-item>
<ui5-suggestion-item class="suggestionItem" text="Condensed"></ui5-suggestion-item>
</ui5-input>

<ui5-popover id="quickViewCard" header-text="My Heading" id="pop" placement-type="Right">
<ui5-button>Click me</ui5-button>
</ui5-popover>

<br/>
<br/>
<h3>Input suggestions with ui5-li</h3>
Expand Down Expand Up @@ -314,8 +331,34 @@ <h3> Input with multiple icons</h3>
inputChangeResult.value = ++inputChangeResultCounter;
});

inputItemPreview.addEventListener("ui5-suggestion-item-preview", function (event) {
inputItemPreviewRes.value = event.detail.item.textContent;
// Preview suggestion item events
inputPreview.addEventListener("ui5-suggestion-item-preview", function (event) {
var item = event.detail.item;
inputItemPreviewRes.value = item.textContent;

quickViewCard.close(false, true, true);
quickViewCard.openBy(item, true);
});

inputPreview.addEventListener("keyup", function (event) {
const item = event.target.previewItem;
keyupResult.value = "[key]: " + event.key + " , [preview item]:" + (item && item.text);
});

[].slice.call(document.querySelectorAll(".suggestionItem")).forEach(function(el) {
el.addEventListener("mouseover", function (event) {
const targetRef = event.detail.targetRef;

mouseoverResult.value = targetRef.textContent;
quickViewCard.openBy(targetRef, true);
});

el.addEventListener("mouseout", function (event) {
const targetRef = event.detail.targetRef;

mouseoutResult.value = targetRef.textContent;
quickViewCard.close(false, true, true);
});
});
</script>
</body>
Expand Down
2 changes: 1 addition & 1 deletion packages/main/test/specs/Input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe("Input general interaction", () => {
});

it("fires suggestion-item-preview", () => {
const inputItemPreview = $("#inputItemPreview").shadow$("input");
const inputItemPreview = $("#inputPreview").shadow$("input");
const inputItemPreviewRes = $("#inputItemPreviewRes");

inputItemPreview.click();
Expand Down

0 comments on commit 4359b9a

Please sign in to comment.