Skip to content

Commit

Permalink
feat(ui5-suggestion-item): add new component (#1336)
Browse files Browse the repository at this point in the history
An abstract item to serve as a suggestion item within the Input. Based on the suggestion item properties, the Input will display either a StandardListItem, or a GroupHeaderListItem within the suggestion popover.

FIXES: #1313

The usage becomes:

```html
<ui5-input id="myInput2" show-suggestions >
        <ui5-suggestion-item group text="group 1"></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>
</ui5-input>
```

Although this is still compatible:

```html
<ui5-input  show-suggestions >
	<ui5-li>Cozy</ui5-li>
	<ui5-li>Compact</ui5-li>
	<ui5-li>Condensed</ui5-li>
</ui5-input>
```
  • Loading branch information
ilhan007 authored Mar 24, 2020
1 parent 56e39bc commit 786f4e9
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 27 deletions.
1 change: 1 addition & 0 deletions packages/main/bundle.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import Popover from "./dist/Popover.js";
import Panel from "./dist/Panel.js";
import RadioButton from "./dist/RadioButton.js";
import ResponsivePopover from "./dist/ResponsivePopover.js";
import SuggestionItem from "./dist/SuggestionItem.js";
import SegmentedButton from "./dist/SegmentedButton.js";
import Select from "./dist/Select.js";
import Option from "./dist/Option.js";
Expand Down
21 changes: 13 additions & 8 deletions packages/main/src/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,23 @@ const metadata = {
/**
* Defines the <code>ui5-input</code> suggestion items.
* <br><br>
* Example: <br>
* Example:
* <br><br>
* &lt;ui5-input show-suggestions><br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;ui5-li>Item #1&lt;/ui5-li><br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;ui5-li>Item #2&lt;/ui5-li><br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;ui5-suggestion-item text="Item #1">&lt;/ui5-suggestion-item><br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;ui5-suggestion-item text="Item #2">&lt;/ui5-suggestion-item><br>
* &lt;/ui5-input>
* <ui5-input show-suggestions><ui5-li>Item #1</ui5-li><ui5-li>Item #2</ui5-li></ui5-input>
* <br>
* <ui5-input show-suggestions>
* <ui5-suggestion-item text="Item #1"></ui5-suggestion-item>
* <ui5-suggestion-item text="Item #2"></ui5-suggestion-item>
* </ui5-input>
* <br><br>
* <b>Note:</b> The suggestion would be displayed only if the <code>showSuggestions</code>
* property is set to <code>true</code>.
* <br><br>
* <b>Note:</b> The &lt;ui5-li> and &lt;ui5-li-custom> are recommended to be used as suggestion items.
* <br>
* In order to use them, you need to import either <code>"@ui5/webcomponents/dist/StandardListItem"</code>, or <code>"@ui5/webcomponents/dist/CustomListItem"</code> module.
* <b>Note:</b> The &lt;ui5-suggestion-item> is recommended to be used as a suggestion item.
* and you need to import the <code>"@ui5/webcomponents/dist/SuggestionItem"</code> module.
*
* @type {HTMLElement[]}
* @slot
Expand Down Expand Up @@ -321,6 +325,7 @@ const metadata = {
* @alias sap.ui.webcomponents.main.Input
* @extends sap.ui.webcomponents.base.UI5Element
* @tagname ui5-input
* @appenddocs SuggestionItem
* @public
*/
class Input extends UI5Element {
Expand Down Expand Up @@ -547,7 +552,7 @@ class Input extends UI5Element {
}

selectSuggestion(item, keyboardUsed) {
const itemText = item.textContent;
const itemText = item.text || item.textContent; // keep textContent for compatibility
const fireInput = keyboardUsed
? this.valueBeforeItemSelection !== itemText : this.value !== itemText;

Expand Down
20 changes: 12 additions & 8 deletions packages/main/src/InputPopover.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,18 @@

<ui5-list separators="Inner">
{{#each suggestionsTexts}}
<ui5-li
image="{{this.image}}"
icon="{{this.icon}}"
description="{{this.description}}"
info="{{this.info}}"
info-state="{{this.infoState}}"
@ui5-_itemPress="{{ fnOnSuggestionItemPress }}"
>{{ this.text }}</ui5-li>
{{#if group}}
<ui5-li-groupheader>{{ this.text }}</ui5-groupheader>
{{else}}
<ui5-li
image="{{this.image}}"
icon="{{this.icon}}"
description="{{this.description}}"
info="{{this.info}}"
info-state="{{this.infoState}}"
@ui5-_itemPress="{{ fnOnSuggestionItemPress }}"
>{{ this.text }}</ui5-li>
{{/if}}
{{/each}}
</ui5-list>

Expand Down
140 changes: 140 additions & 0 deletions packages/main/src/SuggestionItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js";
import StandardListItem from "./StandardListItem.js";
import GroupHeaderListItem from "./GroupHeaderListItem.js";

/**
* @public
*/
const metadata = {
tag: "ui5-suggestion-item",
properties: /** @lends sap.ui.webcomponents.main.SuggestionItem.prototype */ {
/**
* Defines the text of the <code>ui5-suggestion-item</code>.
*
* @type {string}
* @defaultvalue ""
* @public
*/
text: {
type: String,
},

/**
* Defines the description displayed right under the item text, if such is present.
* @type {string}
* @defaultvalue: ""
* @public
*/
description: {
type: String,
},

/**
* Defines the <code>icon</code> source URI.
* <br><br>
* <b>Note:</b>
* SAP-icons font provides numerous buil-in icons. To find all the available icons, see the
* <ui5-link target="_blank" href="https://openui5.hana.ondemand.com/test-resources/sap/m/demokit/iconExplorer/webapp/index.html" class="api-table-content-cell-link">Icon Explorer</ui5-link>.
*
* @type {string}
* @public
*/
icon: {
type: String,
},

/**
* Defines whether the <code>icon</code> should be displayed in the beginning of the item or in the end.
* <br><br>
* <b>Note:</b> If <code>image</code> is set, the <code>icon</code> would be displayed after the <code>image</code>.
*
* @type {boolean}
* @defaultvalue false
* @public
*/
iconEnd: {
type: Boolean,
},

/**
* Defines the <code>image</code> source URI.
* <br><br>
* <b>Note:</b> The <code>image</code> would be displayed in the beginning of the item.
*
* @type {string}
* @public
*/
image: {
type: String,
},

/**
* Defines the <code>info</code>, displayed in the end of the item.
* @type {string}
* @public
*/
info: {
type: String,
},

/**
* Defines the state of the <code>info</code>.
* <br>
* Available options are: <code>"None"</code> (by default), <code>"Success"</code>, <code>"Warning"</code> and <code>"Erorr"</code>.
* @type {string}
* @public
*/
infoState: {
type: ValueState,
defaultValue: ValueState.None,
},

/**
* Defines the item to be displayed as a group item. When set, the other properties,
* such as <code>image</code>, <code>icon</code>, <code>description</code>, etc. will be omitted.
* Only the <code>text</code> will be displayed.
* @type {string}
* @public
*/
group: {
type: Boolean,
},
},
slots: {
},
events: {
},
};

/**
* @class
* The <code>ui5-suggestion-item</code> represents the suggestion item of the <code>ui5-input</code>.
*
* @constructor
* @author SAP SE
* @alias sap.ui.webcomponents.main.SuggestionItem
* @extends UI5Element
* @public
*/
class SuggestionItem extends UI5Element {
static get metadata() {
return metadata;
}

static get render() {
return litRender;
}

static async onDefine() {
await Promise.all([
StandardListItem.define(),
GroupHeaderListItem.define(),
]);
}
}

SuggestionItem.define();

export default SuggestionItem;
4 changes: 2 additions & 2 deletions packages/main/src/features/InputSuggestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ class Suggestions {
const suggestions = [];
inputSuggestionItems.map(suggestion => {
return suggestions.push({
text: suggestion.textContent,
text: suggestion.text || suggestion.textContent, // keep textContent for compatibility
description: suggestion.description || undefined,
image: suggestion.image || undefined,
icon: suggestion.icon || undefined,
info: suggestion.info || undefined,
infoState: suggestion.infoState,
group: suggestion.group,
});
});

Expand Down Expand Up @@ -290,7 +291,6 @@ Suggestions.SCROLL_STEP = 48;
List.define();
ResponsivePopover.define();


// Add suggestions support to the global features registry so that Input.js can use it
registerFeature("InputSuggestions", Suggestions);

Expand Down
1 change: 1 addition & 0 deletions packages/main/src/themes/GroupHeaderListItem.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: bold;
}
23 changes: 18 additions & 5 deletions packages/main/test/pages/Input.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,19 @@ <h3>Input in Compact</h3>
</ui5-input>
</div>

<h3> Input with suggestions</h3>
<h3> Input with suggestions: ui5-suggestion-item</h3>
<ui5-input 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>
</ui5-input>
<br/>
<br/>
<br/>
<ui5-title>suggestion with ui5-li</ui5-title>
<ui5-input id="myInput2" show-suggestions style="width: 100%">
<ui5-li>Cozy</ui5-li>
<ui5-li>Compact</ui5-li>
Expand Down Expand Up @@ -162,7 +174,7 @@ <h3> Input with multiple icons</h3>
</ui5-input>

<script>
var sap_database_entries = [{ key: "Afg", text: "Afghanistan" }, { key: "Arg", text: "Argentina" }, { key: "Alb", text: "Albania" }, { key: "Arm", text: "Armenia" }, { key: "Alg", text: "Algeria" }, { key: "And", text: "Andorra" }, { key: "Ang", text: "Angola" }, { key: "Ast", text: "Austria" }, { key: "Aus", text: "Australia" }, { key: "Aze", text: "Azerbaijan" }, { key: "Aruba", text: "Aruba" }, { key: "Antigua", text: "Antigua and Barbuda" }, { key: "Bel", text: "Belarus" }, { key: "Bel", text: "Belgium" }, { key: "Bg", text: "Bulgaria" }, { key: "Bra", text: "Brazil" }, { key: "Ch", text: "China" }, { key: "Cub", text: "Cuba" }, { key: "Chil", text: "Chili" }, { key: "Lat", text: "Latvia" }, { key: "Lit", text: "Litva" }, { key: "Prt", text: "Portugal" }, { key: "Sen", text: "Senegal" }, { key: "Ser", text: "Serbia" }, { key: "Afg", text: "Seychelles" }, { key: "Sierra", text: "Sierra Leone" }, { key: "Sgp", text: "Singapore" }, { key: "Sint", text: "Sint Maarten" }, { key: "Slv", text: "Slovakia" }, { key: "Slo", text: "Slovenia" }];
var sap_database_entries = [{ key: "A", text: "A" }, { key: "Afg", text: "Afghanistan" }, { key: "Arg", text: "Argentina" }, { key: "Alb", text: "Albania" }, { key: "Arm", text: "Armenia" }, { key: "Alg", text: "Algeria" }, { key: "And", text: "Andorra" }, { key: "Ang", text: "Angola" }, { key: "Ast", text: "Austria" }, { key: "Aus", text: "Australia" }, { key: "Aze", text: "Azerbaijan" }, { key: "Aruba", text: "Aruba" }, { key: "Antigua", text: "Antigua and Barbuda" }, { key: "B", text: "B" }, { key: "Bel", text: "Belarus" }, { key: "Bel", text: "Belgium" }, { key: "Bg", text: "Bulgaria" }, { key: "Bra", text: "Brazil" }, { key: "C", text: "C" }, { key: "Ch", text: "China" }, { key: "Cub", text: "Cuba" }, { key: "Chil", text: "Chili" }, { key: "L", text: "L" }, { key: "Lat", text: "Latvia" }, { key: "Lit", text: "Litva" }, { key: "P", text: "P" }, { key: "Prt", text: "Portugal" }, { key: "S", text: "S" }, { key: "Sen", text: "Senegal" }, { key: "Ser", text: "Serbia" }, { key: "Sey", text: "Seychelles" }, { key: "Sierra", text: "Sierra Leone" }, { key: "Sgp", text: "Singapore" }, { key: "Sint", text: "Sint Maarten" }, { key: "Slv", text: "Slovakia" }, { key: "Slo", text: "Slovenia" }];

var input = document.getElementById('myInput');
var myInput2 = document.getElementById('myInput2');
Expand Down Expand Up @@ -190,14 +202,15 @@ <h3> Input with multiple icons</h3>
input.removeChild(input.firstChild);
}

suggestionItems.forEach(function(item) {
var li = document.createElement("ui5-li");
suggestionItems.forEach(function(item, idx) {
var li = document.createElement("ui5-suggestion-item");
li.id = item.key;
li.icon = "world";
li.info = "explore";
li.group = item.text.length === 1;
li.infoState = "Success";
li.description = "travel the world";
li.textContent = item.text;
li.text = item.text;
input.appendChild(li);
});

Expand Down
8 changes: 4 additions & 4 deletions packages/main/test/samples/Input.sample.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ <h3>Input With Suggestions (Note: the usage depends on the framework you are usi
});

suggestionItems.forEach(function(item) {
var li = document.createElement("ui5-li");
var li = document.createElement("ui5-suggestion-item");
li.icon = "world";
li.id = item;
li.textContent = item;
li.text = item;
oInput.appendChild(li);
});
});
Expand Down Expand Up @@ -103,10 +103,10 @@ <h3>Input With Suggestions (Note: the usage depends on the framework you are usi
});
// Add the new suggestions in the DOM
suggestionItems.forEach(function(item) {
var li = document.createElement("ui5-li");
var li = document.createElement("ui5-suggestion-item");
li.icon = "world";
li.id = item;
li.textContent = item;
li.text = item;
oInput.appendChild(li);
});
});
Expand Down

0 comments on commit 786f4e9

Please sign in to comment.