Skip to content

Commit 786f4e9

Browse files
authored
feat(ui5-suggestion-item): add new component (#1336)
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> ```
1 parent 56e39bc commit 786f4e9

File tree

8 files changed

+191
-27
lines changed

8 files changed

+191
-27
lines changed

packages/main/bundle.esm.js

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import Popover from "./dist/Popover.js";
4545
import Panel from "./dist/Panel.js";
4646
import RadioButton from "./dist/RadioButton.js";
4747
import ResponsivePopover from "./dist/ResponsivePopover.js";
48+
import SuggestionItem from "./dist/SuggestionItem.js";
4849
import SegmentedButton from "./dist/SegmentedButton.js";
4950
import Select from "./dist/Select.js";
5051
import Option from "./dist/Option.js";

packages/main/src/Input.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,23 @@ const metadata = {
5151
/**
5252
* Defines the <code>ui5-input</code> suggestion items.
5353
* <br><br>
54-
* Example: <br>
54+
* Example:
55+
* <br><br>
5556
* &lt;ui5-input show-suggestions><br>
56-
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;ui5-li>Item #1&lt;/ui5-li><br>
57-
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;ui5-li>Item #2&lt;/ui5-li><br>
57+
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;ui5-suggestion-item text="Item #1">&lt;/ui5-suggestion-item><br>
58+
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;ui5-suggestion-item text="Item #2">&lt;/ui5-suggestion-item><br>
5859
* &lt;/ui5-input>
59-
* <ui5-input show-suggestions><ui5-li>Item #1</ui5-li><ui5-li>Item #2</ui5-li></ui5-input>
60+
* <br>
61+
* <ui5-input show-suggestions>
62+
* <ui5-suggestion-item text="Item #1"></ui5-suggestion-item>
63+
* <ui5-suggestion-item text="Item #2"></ui5-suggestion-item>
64+
* </ui5-input>
6065
* <br><br>
6166
* <b>Note:</b> The suggestion would be displayed only if the <code>showSuggestions</code>
6267
* property is set to <code>true</code>.
6368
* <br><br>
64-
* <b>Note:</b> The &lt;ui5-li> and &lt;ui5-li-custom> are recommended to be used as suggestion items.
65-
* <br>
66-
* In order to use them, you need to import either <code>"@ui5/webcomponents/dist/StandardListItem"</code>, or <code>"@ui5/webcomponents/dist/CustomListItem"</code> module.
69+
* <b>Note:</b> The &lt;ui5-suggestion-item> is recommended to be used as a suggestion item.
70+
* and you need to import the <code>"@ui5/webcomponents/dist/SuggestionItem"</code> module.
6771
*
6872
* @type {HTMLElement[]}
6973
* @slot
@@ -321,6 +325,7 @@ const metadata = {
321325
* @alias sap.ui.webcomponents.main.Input
322326
* @extends sap.ui.webcomponents.base.UI5Element
323327
* @tagname ui5-input
328+
* @appenddocs SuggestionItem
324329
* @public
325330
*/
326331
class Input extends UI5Element {
@@ -547,7 +552,7 @@ class Input extends UI5Element {
547552
}
548553

549554
selectSuggestion(item, keyboardUsed) {
550-
const itemText = item.textContent;
555+
const itemText = item.text || item.textContent; // keep textContent for compatibility
551556
const fireInput = keyboardUsed
552557
? this.valueBeforeItemSelection !== itemText : this.value !== itemText;
553558

packages/main/src/InputPopover.hbs

+12-8
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,18 @@
3535

3636
<ui5-list separators="Inner">
3737
{{#each suggestionsTexts}}
38-
<ui5-li
39-
image="{{this.image}}"
40-
icon="{{this.icon}}"
41-
description="{{this.description}}"
42-
info="{{this.info}}"
43-
info-state="{{this.infoState}}"
44-
@ui5-_itemPress="{{ fnOnSuggestionItemPress }}"
45-
>{{ this.text }}</ui5-li>
38+
{{#if group}}
39+
<ui5-li-groupheader>{{ this.text }}</ui5-groupheader>
40+
{{else}}
41+
<ui5-li
42+
image="{{this.image}}"
43+
icon="{{this.icon}}"
44+
description="{{this.description}}"
45+
info="{{this.info}}"
46+
info-state="{{this.infoState}}"
47+
@ui5-_itemPress="{{ fnOnSuggestionItemPress }}"
48+
>{{ this.text }}</ui5-li>
49+
{{/if}}
4650
{{/each}}
4751
</ui5-list>
4852

packages/main/src/SuggestionItem.js

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
2+
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
3+
import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js";
4+
import StandardListItem from "./StandardListItem.js";
5+
import GroupHeaderListItem from "./GroupHeaderListItem.js";
6+
7+
/**
8+
* @public
9+
*/
10+
const metadata = {
11+
tag: "ui5-suggestion-item",
12+
properties: /** @lends sap.ui.webcomponents.main.SuggestionItem.prototype */ {
13+
/**
14+
* Defines the text of the <code>ui5-suggestion-item</code>.
15+
*
16+
* @type {string}
17+
* @defaultvalue ""
18+
* @public
19+
*/
20+
text: {
21+
type: String,
22+
},
23+
24+
/**
25+
* Defines the description displayed right under the item text, if such is present.
26+
* @type {string}
27+
* @defaultvalue: ""
28+
* @public
29+
*/
30+
description: {
31+
type: String,
32+
},
33+
34+
/**
35+
* Defines the <code>icon</code> source URI.
36+
* <br><br>
37+
* <b>Note:</b>
38+
* SAP-icons font provides numerous buil-in icons. To find all the available icons, see the
39+
* <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>.
40+
*
41+
* @type {string}
42+
* @public
43+
*/
44+
icon: {
45+
type: String,
46+
},
47+
48+
/**
49+
* Defines whether the <code>icon</code> should be displayed in the beginning of the item or in the end.
50+
* <br><br>
51+
* <b>Note:</b> If <code>image</code> is set, the <code>icon</code> would be displayed after the <code>image</code>.
52+
*
53+
* @type {boolean}
54+
* @defaultvalue false
55+
* @public
56+
*/
57+
iconEnd: {
58+
type: Boolean,
59+
},
60+
61+
/**
62+
* Defines the <code>image</code> source URI.
63+
* <br><br>
64+
* <b>Note:</b> The <code>image</code> would be displayed in the beginning of the item.
65+
*
66+
* @type {string}
67+
* @public
68+
*/
69+
image: {
70+
type: String,
71+
},
72+
73+
/**
74+
* Defines the <code>info</code>, displayed in the end of the item.
75+
* @type {string}
76+
* @public
77+
*/
78+
info: {
79+
type: String,
80+
},
81+
82+
/**
83+
* Defines the state of the <code>info</code>.
84+
* <br>
85+
* Available options are: <code>"None"</code> (by default), <code>"Success"</code>, <code>"Warning"</code> and <code>"Erorr"</code>.
86+
* @type {string}
87+
* @public
88+
*/
89+
infoState: {
90+
type: ValueState,
91+
defaultValue: ValueState.None,
92+
},
93+
94+
/**
95+
* Defines the item to be displayed as a group item. When set, the other properties,
96+
* such as <code>image</code>, <code>icon</code>, <code>description</code>, etc. will be omitted.
97+
* Only the <code>text</code> will be displayed.
98+
* @type {string}
99+
* @public
100+
*/
101+
group: {
102+
type: Boolean,
103+
},
104+
},
105+
slots: {
106+
},
107+
events: {
108+
},
109+
};
110+
111+
/**
112+
* @class
113+
* The <code>ui5-suggestion-item</code> represents the suggestion item of the <code>ui5-input</code>.
114+
*
115+
* @constructor
116+
* @author SAP SE
117+
* @alias sap.ui.webcomponents.main.SuggestionItem
118+
* @extends UI5Element
119+
* @public
120+
*/
121+
class SuggestionItem extends UI5Element {
122+
static get metadata() {
123+
return metadata;
124+
}
125+
126+
static get render() {
127+
return litRender;
128+
}
129+
130+
static async onDefine() {
131+
await Promise.all([
132+
StandardListItem.define(),
133+
GroupHeaderListItem.define(),
134+
]);
135+
}
136+
}
137+
138+
SuggestionItem.define();
139+
140+
export default SuggestionItem;

packages/main/src/features/InputSuggestions.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@ class Suggestions {
3737
const suggestions = [];
3838
inputSuggestionItems.map(suggestion => {
3939
return suggestions.push({
40-
text: suggestion.textContent,
40+
text: suggestion.text || suggestion.textContent, // keep textContent for compatibility
4141
description: suggestion.description || undefined,
4242
image: suggestion.image || undefined,
4343
icon: suggestion.icon || undefined,
4444
info: suggestion.info || undefined,
4545
infoState: suggestion.infoState,
46+
group: suggestion.group,
4647
});
4748
});
4849

@@ -290,7 +291,6 @@ Suggestions.SCROLL_STEP = 48;
290291
List.define();
291292
ResponsivePopover.define();
292293

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

packages/main/src/themes/GroupHeaderListItem.css

+1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@
1717
overflow: hidden;
1818
text-overflow: ellipsis;
1919
white-space: nowrap;
20+
font-weight: bold;
2021
}

packages/main/test/pages/Input.html

+18-5
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,19 @@ <h3>Input in Compact</h3>
3939
</ui5-input>
4040
</div>
4141

42-
<h3> Input with suggestions</h3>
42+
<h3> Input with suggestions: ui5-suggestion-item</h3>
43+
<ui5-input show-suggestions style="width: 100%">
44+
<ui5-suggestion-item text="Cozy"></ui5-suggestion-item>
45+
<ui5-suggestion-item text="Compact"></ui5-suggestion-item>
46+
<ui5-suggestion-item text="Condensed"></ui5-suggestion-item>
47+
<ui5-suggestion-item text="Cozy"></ui5-suggestion-item>
48+
<ui5-suggestion-item text="Compact"></ui5-suggestion-item>
49+
<ui5-suggestion-item text="Condensed"></ui5-suggestion-item>
50+
</ui5-input>
51+
<br/>
52+
<br/>
53+
<br/>
54+
<ui5-title>suggestion with ui5-li</ui5-title>
4355
<ui5-input id="myInput2" show-suggestions style="width: 100%">
4456
<ui5-li>Cozy</ui5-li>
4557
<ui5-li>Compact</ui5-li>
@@ -162,7 +174,7 @@ <h3> Input with multiple icons</h3>
162174
</ui5-input>
163175

164176
<script>
165-
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" }];
177+
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" }];
166178

167179
var input = document.getElementById('myInput');
168180
var myInput2 = document.getElementById('myInput2');
@@ -190,14 +202,15 @@ <h3> Input with multiple icons</h3>
190202
input.removeChild(input.firstChild);
191203
}
192204

193-
suggestionItems.forEach(function(item) {
194-
var li = document.createElement("ui5-li");
205+
suggestionItems.forEach(function(item, idx) {
206+
var li = document.createElement("ui5-suggestion-item");
195207
li.id = item.key;
196208
li.icon = "world";
197209
li.info = "explore";
210+
li.group = item.text.length === 1;
198211
li.infoState = "Success";
199212
li.description = "travel the world";
200-
li.textContent = item.text;
213+
li.text = item.text;
201214
input.appendChild(li);
202215
});
203216

packages/main/test/samples/Input.sample.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ <h3>Input With Suggestions (Note: the usage depends on the framework you are usi
6767
});
6868

6969
suggestionItems.forEach(function(item) {
70-
var li = document.createElement("ui5-li");
70+
var li = document.createElement("ui5-suggestion-item");
7171
li.icon = "world";
7272
li.id = item;
73-
li.textContent = item;
73+
li.text = item;
7474
oInput.appendChild(li);
7575
});
7676
});
@@ -103,10 +103,10 @@ <h3>Input With Suggestions (Note: the usage depends on the framework you are usi
103103
});
104104
// Add the new suggestions in the DOM
105105
suggestionItems.forEach(function(item) {
106-
var li = document.createElement("ui5-li");
106+
var li = document.createElement("ui5-suggestion-item");
107107
li.icon = "world";
108108
li.id = item;
109-
li.textContent = item;
109+
li.text = item;
110110
oInput.appendChild(li);
111111
});
112112
});

0 commit comments

Comments
 (0)