Skip to content

Commit def538f

Browse files
committed
feat(ui5-card): add 'action' slot (#1915)
Provides a new slot, called "action", displayed in the right most part of the header to enable users add a action, in most cases single button. When the action slot is used, the status text would not be displayed (if present). FIXES: #1913
1 parent 38edef6 commit def538f

File tree

5 files changed

+91
-12
lines changed

5 files changed

+91
-12
lines changed

packages/main/src/Card.hbs

+6-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@
2929
<div id="{{_id}}-subheading" class="ui5-card-subheading" part="subheading">{{subheading}}</div>
3030
{{/if}}
3131
</div>
32-
<span id="{{_id}}-status" part="status" class="ui5-card-status">{{status}}</span>
32+
33+
{{#if hasAction}}
34+
<slot name="action"></slot>
35+
{{else}}
36+
<span id="{{_id}}-status" part="status" class="ui5-card-status">{{status}}</span>
37+
{{/if}}
3338
</div>
3439
{{/if}}
3540

packages/main/src/Card.js

+24-5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ const metadata = {
4949
avatar: {
5050
type: HTMLElement,
5151
},
52+
53+
/**
54+
* Defines an action, displayed in the right most part of the header.
55+
* <br><br>
56+
* <b>Note:</b> If set, the <code>status</code> text will not be displayed,
57+
* you can either have <code>action</code>, or <code>status</code>.
58+
* @type {HTMLElement[]}
59+
* @slot
60+
* @public
61+
* @since 1.0.0-rc.8
62+
*/
63+
action: {
64+
type: HTMLElement,
65+
},
5266
},
5367
properties: /** @lends sap.ui.webcomponents.main.Card.prototype */ {
5468

@@ -74,6 +88,9 @@ const metadata = {
7488

7589
/**
7690
* Defines the status displayed in the <code>ui5-card</code> header.
91+
* <br><br>
92+
* <b>Note:</b> If the <code>action</code> slot is set, the <code>status</code> will not be displayed,
93+
* you can either have <code>action</code>, or <code>status</code>.
7794
* @type {string}
7895
* @defaultvalue ""
7996
* @public
@@ -120,10 +137,8 @@ const metadata = {
120137
* The <code>ui5-card</code> is a component that represents information in the form of a
121138
* tile with separate header and content areas.
122139
* The content area of a <code>ui5-card</code> can be arbitrary HTML content.
123-
* The header can be used through several properties, such as:
124-
* <code>heading</code>, <code>subheading</code>, <code>status</code>
125-
* and a slot:
126-
* <code>avatar</code>.
140+
* The header can be used through several properties, such as: <code>heading</code>, <code>subheading</code>, <code>status</code>
141+
* and two slots: <code>avatar</code> and <code>action</code>.
127142
*
128143
* <h3>Keyboard handling</h3>
129144
* In case you enable <code>headerInteractive</code> property, you can press the <code>ui5-card</code> header by Space and Enter keys.
@@ -193,7 +208,7 @@ class Card extends UI5Element {
193208
}
194209

195210
get hasHeader() {
196-
return !!(this.heading || this.subheading || this.status || this.avatar);
211+
return !!(this.heading || this.subheading || this.status || this.hasAction || this.avatar);
197212
}
198213

199214
get ariaCardRoleDescription() {
@@ -216,6 +231,10 @@ class Card extends UI5Element {
216231
return !!this.avatar.length;
217232
}
218233

234+
get hasAction() {
235+
return !!this.action.length;
236+
}
237+
219238
static async onDefine() {
220239
await Promise.all([
221240
Icon.define(),

packages/main/src/themes/Card.css

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@
2222
.ui5-card-header {
2323
position: relative;
2424
display: flex;
25-
align-items: flex-start;
25+
align-items: center;
2626
background: var(--sapTile_Background);
2727
border-bottom: 1px solid var(--_ui5_card_header_border_color);
2828
padding: var(--_ui5_card_content_padding);
2929
}
3030

31+
:host([subheading]) .ui5-card-header {
32+
align-items: flex-start;
33+
}
34+
3135
/* Card with no content */
3236
.ui5-card-root.ui5-card--nocontent {
3337
height: auto;

packages/main/test/pages/Card.html

+46
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,52 @@
5656
</ui5-list>
5757
</ui5-card>
5858

59+
60+
<ui5-card heading="Linked activities (5)" class="myCard" status="4 of 10" id="actionCard">
61+
<ui5-list id="myList3" separators="Inner">
62+
<ui5-li icon="horizontal-bullet-chart">
63+
Increase customer satisfaction by 10% using marketing methods
64+
</ui5-li>
65+
<ui5-li icon="opportunity">
66+
Get 1000 survey responses to annual employee survey
67+
</ui5-li>
68+
</ui5-list>
69+
70+
<ui5-button icon="add" slot="action" design="Transparent">
71+
Add activity
72+
</ui5-button>
73+
</ui5-card>
74+
75+
<ui5-card heading="Linked activities (5)" class="myCard" subheading="quick links">
76+
<ui5-list id="myList3" separators="Inner">
77+
<ui5-li icon="horizontal-bullet-chart">
78+
Increase customer satisfaction by 10% using marketing methods
79+
</ui5-li>
80+
<ui5-li icon="opportunity">
81+
Get 1000 survey responses to annual employee survey
82+
</ui5-li>
83+
</ui5-list>
84+
85+
<ui5-button icon="add" slot="action" design="Transparent">
86+
Add activity
87+
</ui5-button>
88+
</ui5-card>
89+
90+
<ui5-card heading="Linked activities (5)">
91+
<ui5-list id="myList3" separators="Inner">
92+
<ui5-li icon="horizontal-bullet-chart">
93+
Increase customer satisfaction by 10% using marketing methods
94+
</ui5-li>
95+
<ui5-li icon="opportunity">
96+
Get 1000 survey responses to annual employee survey
97+
</ui5-li>
98+
</ui5-list>
99+
100+
<ui5-icon name="group" slot="avatar"></ui5-icon>
101+
102+
<ui5-button icon="overflow" slot="action" design="Transparent"></ui5-button>
103+
</ui5-card>
104+
59105
<script>
60106
card.addEventListener("ui5-headerClick", function (event) {
61107
console.log(event);

packages/main/test/specs/Card.spec.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ describe("Card general interaction", () => {
66
it("tests initial rendering", () => {
77
const card = browser.$("#card");
88

9-
assert.ok(card, "Has shadow root");
9+
assert.ok(card.isExisting(), "The component has shadow root.");
1010
});
1111

12-
it("fires headerPress upon click, Enter and Space", () => {
12+
it("tests status not rendered, when action is set", () => {
13+
const status = browser.$("#actionCard").shadow$(".ui5-card-status");
14+
15+
assert.notOk(status.isExisting(), "The status DOM is not rendered.");
16+
});
17+
18+
it("tests headerPress upon click, Enter and Space", () => {
1319
const cardHeader = browser.$("#card").shadow$(".ui5-card-header");
1420
const cardHeader2 = browser.$("#card2").shadow$(".ui5-card-header");
1521
const field = browser.$("#field");
@@ -18,13 +24,12 @@ describe("Card general interaction", () => {
1824
cardHeader.keys("Space");
1925
cardHeader.keys("Enter");
2026

21-
assert.strictEqual(field.getProperty("value"), "3", "headerPress should be called 3 times");
22-
27+
assert.strictEqual(field.getProperty("value"), "3", "The headerPress event should be called 3 times.");
2328

2429
cardHeader2.click();
2530
cardHeader2.keys("Space");
2631
cardHeader2.keys("Enter");
2732

28-
assert.strictEqual(field.getProperty("value"), "3", "events count should remain 3 as the header is not interactive.");
33+
assert.strictEqual(field.getProperty("value"), "3", "The events count should remain 3 as the header is not interactive.");
2934
});
3035
});

0 commit comments

Comments
 (0)