Skip to content

Commit 4d972c8

Browse files
authored
feat(ui5-tree-item): image slot added (#11106)
This feature enables semantic icons to be used with the ui5-tree-item Fixes: #7481
1 parent 1367714 commit 4d972c8

File tree

8 files changed

+107
-39
lines changed

8 files changed

+107
-39
lines changed

packages/main/cypress/specs/Tree.cy.tsx

+24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import Tree from "../../src/Tree.js";
22
import "../../src/TreeItem.js";
3+
import TreeItem from "../../src/TreeItem.js";
4+
import Icon from "../../src/Icon.js";
5+
import bell from "@ui5/webcomponents-icons/dist/bell.js";
36

47
describe("Tree Tests", () => {
58
it("tests accessibility properties forwarded to the list", () => {
@@ -27,6 +30,27 @@ describe("Tree Tests", () => {
2730
.and("have.attr", "accessible-description", "Description")
2831
.and("have.attr", "accessible-description-ref", "lblDesc2");
2932
});
33+
34+
it("Tests image slot", () => {
35+
cy.mount(
36+
<Tree>
37+
<TreeItem id="image-slot-tree-item">
38+
<Icon name={bell} slot="image" id="slotted-icon"></Icon>
39+
</TreeItem>
40+
</Tree>
41+
);
42+
43+
cy.get("#image-slot-tree-item")
44+
.shadow()
45+
.find("slot[name='image']")
46+
.should("exist")
47+
.then($slot => {
48+
const slotElement = $slot[0] as HTMLSlotElement;
49+
const assignedNodes = slotElement.assignedNodes();
50+
expect(assignedNodes.length).to.be.greaterThan(0);
51+
cy.wrap(assignedNodes[0]).should("have.attr", "id", "slotted-icon");
52+
});
53+
});
3054
});
3155

3256
describe("Tree Props", () => {

packages/main/src/TreeItemBase.ts

+23
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ class TreeItemBase extends ListItem {
195195
@property({ type: Boolean })
196196
_fixed = false;
197197

198+
/**
199+
* @private
200+
*/
201+
@property({ type: Boolean })
202+
_hasImage = false;
203+
198204
/**
199205
* Defines the items of the component.
200206
*
@@ -211,11 +217,24 @@ class TreeItemBase extends ListItem {
211217
})
212218
items!: Array<TreeItemBase>;
213219

220+
/**
221+
* **Note:** While the slot allows option for setting custom avatar, to match the
222+
* design guidelines, please use the `ui5-avatar` with size XS.
223+
*
224+
* **Note:** If bigger `ui5-avatar` needs to be used, then the size of the
225+
* `ui5-tree-item` should be customized in order to fit.
226+
* @since 2.10.0
227+
* @public
228+
*/
229+
@slot()
230+
image!: Array<HTMLElement>;
231+
214232
@i18n("@ui5/webcomponents")
215233
static i18nBundle: I18nBundle;
216234

217235
onBeforeRendering() {
218236
this.showToggleButton = this.requiresToggleButton;
237+
this._hasImage = this.hasImage;
219238
}
220239

221240
get classes(): ClassMap {
@@ -244,6 +263,10 @@ class TreeItemBase extends ListItem {
244263
return this.level > 1;
245264
}
246265

266+
get hasImage(): boolean {
267+
return !!this.image.length;
268+
}
269+
247270
get _toggleIconName() {
248271
return this.expanded ? "navigation-down-arrow" : "navigation-right-arrow";
249272
}

packages/main/src/TreeItemBaseTemplate.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ function listItemPostContent(this: TreeItemBase) {
5454
}
5555

5656
function listItemContent() { }
57-
function imageBegin() { }
57+
function imageBegin(this: TreeItemBase) {
58+
if (this.hasImage) {
59+
return <div class="ui5-tree-item-image">
60+
<slot name="image"></slot>
61+
</div>;
62+
}
63+
}
5864
function iconBegin(this: TreeItemBase) {
5965
return this.icon ? <Icon part="icon" name={this.icon} class="ui5-li-icon" /> : <></>;
6066
}

packages/main/src/themes/ListItem.css

+16-9
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@
6767
object-fit: contain
6868
}
6969

70+
::slotted([ui5-icon][slot="image"]){
71+
color: var(--sapContent_NonInteractiveIconColor);
72+
min-width: var(--_ui5_list_item_icon_size);
73+
min-height: var(--_ui5_list_item_icon_size);
74+
padding-inline-end: var(--_ui5_list_item_icon_padding-inline-end);
75+
}
76+
77+
::slotted([ui5-avatar][slot="image"]) {
78+
min-width: var(--_ui5_list_item_img_size);
79+
min-height: var(--_ui5_list_item_img_size);
80+
margin-top: var(--_ui5_list_item_img_top_margin);
81+
margin-bottom: var(--_ui5_list_item_img_bottom_margin);
82+
margin-inline-end: var(--_ui5_list_item_img_hn_margin);
83+
}
84+
7085
:host([description]) .ui5-li-root {
7186
padding: 1rem;
7287
}
@@ -119,14 +134,6 @@
119134
align-self: flex-end;
120135
}
121136

122-
.ui5-li-image {
123-
min-width: var(--_ui5_list_item_img_size);
124-
min-height: var(--_ui5_list_item_img_size);
125-
margin-top: var(--_ui5_list_item_img_top_margin);
126-
margin-bottom: var(--_ui5_list_item_img_bottom_margin);
127-
margin-inline-end: var(--_ui5_list_item_img_hn_margin);
128-
}
129-
130137
.ui5-li-icon {
131138
min-width: var(--_ui5_list_item_icon_size);
132139
min-height: var(--_ui5_list_item_icon_size);
@@ -197,4 +204,4 @@
197204

198205
:host([highlight="Information"]) .ui5-li-highlight {
199206
background: var(--sapInformativeTextColor);
200-
}
207+
}

packages/main/src/themes/TreeItem.css

+9
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@
4646
background-color: var(--sapList_Hover_SelectionBackground);
4747
}
4848

49+
:host([_has-image]) {
50+
height: unset;
51+
}
52+
53+
::slotted([ui5-avatar][slot="image"]) {
54+
min-width: var(--_ui5_avatar_fontsize_XS);
55+
min-height: var(--_ui5_avatar_fontsize_XS);
56+
}
57+
4958
.ui5-li-tree-toggle-box {
5059
min-width: var(--_ui5-tree-toggle-box-width);
5160
min-height: var(--_ui5-tree-toggle-box-height);

packages/main/test/pages/List.html

+8-28
Original file line numberDiff line numberDiff line change
@@ -184,45 +184,25 @@ <h2>ui5-list</h2>
184184
<br/><br/>
185185

186186
<ui5-list header-text="API: icon">
187-
<ui5-li icon="navigation-right-arrow">Option 1</ui5-li>
187+
<ui5-li icon="navigation-right-arrow">Option 1</ui5-li>
188188
</ui5-list>
189189

190190
<br/><br/>
191191
<hr />
192192
<br/><br/>
193193

194-
<ui5-list header-text="API: image">
195-
<ui5-li>Laptop HP
194+
<ui5-list header-text="API: image slot">
195+
<ui5-li>Avatar with src inside image slot
196196
<ui5-avatar slot="image">
197197
<img src="./img/HT-1000.jpg" alt="Woman image">
198198
</ui5-avatar>
199199
</ui5-li>
200-
<ui5-li>laptop Lenovo
201-
<ui5-avatar slot="image">
202-
<img src="./img/HT-1010.jpg" alt="Woman image">
203-
</ui5-avatar>
204-
</ui5-li>
205-
<ui5-li>IPhone 3
206-
<ui5-avatar slot="image">
207-
<img src="./img/HT-1022.jpg" alt="Woman image">
208-
</ui5-avatar>
200+
<ui5-li>Icon inside image slot
201+
<ui5-icon slot="image" name="bell"> </ui5-icon>
209202
</ui5-li>
210-
</ui5-list>
211-
212-
<br/><br/>
213-
214-
<ui5-list header-text="API: image">
215-
<ui5-li> Avatar inside image slot
216-
<div slot="image">
217-
<ui5-avatar shape="Square" initials="ABC" color-scheme="Accent2"></ui5-avatar>
218-
</div>
219-
</ui5-li>
220-
<ui5-li> Avatar inside image slot
221-
<div slot="image">
222-
<ui5-avatar >
223-
<img src="./img/woman_avatar_5.png" alt="Woman image">
224-
</ui5-avatar>
225-
</div>
203+
<ui5-li>Icon and Avatar with initials inside image slot
204+
<ui5-icon slot="image" name="bell"> </ui5-icon>
205+
<ui5-avatar slot="image" initials="AB"></ui5-avatar>
226206
</ui5-li>
227207
</ui5-list>
228208

packages/main/test/pages/Tree.html

+17
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,23 @@ <h2>With accessible description</h2>
225225
<ui5-tree-item text="Item 3"></ui5-tree-item>
226226
</ui5-tree>
227227

228+
<br><br>
229+
230+
<h2>API: image slot</h2>
231+
<ui5-label id="description">Tree items with image slot used</ui5-label>
232+
<ui5-tree accessible-description-ref="description">
233+
<ui5-tree-item text="Icon inside image slot">
234+
<ui5-icon slot="image" name="bell"> </ui5-icon>
235+
</ui5-tree-item>
236+
<ui5-tree-item text="Avatar inside image slot">
237+
<ui5-avatar slot="image" size="XS" initials="BL"> </ui5-avatar>
238+
</ui5-tree-item>
239+
<ui5-tree-item text="Avatar and Icon inside image slot">
240+
<ui5-avatar slot="image" size="XS" initials="BL"> </ui5-avatar>
241+
<ui5-icon slot="image" name="bell"> </ui5-icon>
242+
</ui5-tree-item>
243+
</ui5-tree>
244+
228245
<script>
229246
const mouseOverInput = document.getElementById("mouseover-counter");
230247
const mouseOutInput = document.getElementById("mouseout-counter");
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
import "@ui5/webcomponents/dist/Tree.js";
2-
import "@ui5/webcomponents/dist/TreeItem.js";
2+
import "@ui5/webcomponents/dist/TreeItem.js";
3+
import "@ui5/webcomponents-icons/dist/paste.js";
4+
import "@ui5/webcomponents-icons/dist/copy.js";

0 commit comments

Comments
 (0)