Skip to content

Commit fb38b2c

Browse files
authored
feat(ui5-tabcontainer): content can be displayed above the tab strip (#1516)
1 parent c55bcdc commit fb38b2c

File tree

5 files changed

+148
-16
lines changed

5 files changed

+148
-16
lines changed

packages/main/src/TabContainer.hbs

+14-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
class="{{classes.root}}"
33
dir="{{rtl}}"
44
>
5+
{{#if tabsAtTheBottom}}
6+
{{> contentArea}}
7+
{{/if}}
8+
59
<div class="{{classes.header}}" id="{{_id}}-header">
610
<ui5-icon @click="{{_onHeaderBackArrowClick}}" class="{{classes.headerBackArrow}}" name="slim-arrow-left" tabindex="-1" accessible-name="{{previousIconACCName}}" show-tooltip></ui5-icon>
711

@@ -46,15 +50,21 @@
4650
<ui5-button
4751
@click="{{_onOverflowButtonClick}}"
4852
class="{{classes.overflowButton}}"
49-
icon="slim-arrow-down"
53+
icon="{{overflowMenuIcon}}"
5054
type="Transparent"
5155
title="{{overflowMenuTitle}}"
5256
design="Transparent"
5357
></ui5-button>
5458
{{/if}}
5559
</div>
5660

57-
<!-- content area -->
61+
{{#unless tabsAtTheBottom}}
62+
{{> contentArea}}
63+
{{/unless}}
64+
65+
</div>
66+
67+
{{#*inline "contentArea"}}
5868
<div class="{{classes.content}}">
5969
{{#each renderItems}}
6070
{{#unless this.isSeparator}}
@@ -64,7 +74,7 @@
6474
{{/unless}}
6575
{{/each}}
6676
</div>
67-
</div>
77+
{{/inline}}
6878

6979
{{#*inline "standardTab"}}
7080
{{#if this.item.icon}}
@@ -106,4 +116,4 @@
106116
<span class="{{this.headerItemAdditionalTextClasses}}" id="{{this.item._id}}-additionalText">{{this.item.additionalText}}</span>
107117
{{/if}}
108118
</div>
109-
{{/inline}}
119+
{{/inline}}

packages/main/src/TabContainer.js

+27
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation
66
import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js";
77
import { getRTL } from "@ui5/webcomponents-base/dist/config/RTL.js";
88
import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
9+
import "@ui5/webcomponents-icons/dist/icons/slim-arrow-up.js";
910
import "@ui5/webcomponents-icons/dist/icons/slim-arrow-down.js";
1011
import "@ui5/webcomponents-icons/dist/icons/slim-arrow-left.js";
1112
import "@ui5/webcomponents-icons/dist/icons/slim-arrow-right.js";
@@ -16,6 +17,7 @@ import Icon from "./Icon.js";
1617
import List from "./List.js";
1718
import ResponsivePopover from "./ResponsivePopover.js";
1819
import SemanticColor from "./types/SemanticColor.js";
20+
import TabContainerTabsPlacement from "./types/TabContainerTabsPlacement.js";
1921

2022
// Templates
2123
import TabContainerTemplate from "./generated/templates/TabContainerTemplate.lit.js";
@@ -76,6 +78,23 @@ const metadata = {
7678
type: Boolean,
7779
},
7880

81+
/**
82+
* Defines the placement of the tab strip (tab buttons area) relative to the actual tabs' content.
83+
* <br><br>
84+
* <b>Note:</b> By default the tab strip is displayed above the tabs' content area and this is the recommended
85+
* layout for most scenarios. Set to <code>Bottom</code> only when the <code>ui5-tabcontainer</code> is at the
86+
* bottom of the page and you want the tab strip to act as a menu.
87+
*
88+
* @type {TabContainerTabsPlacement}
89+
* @defaultvalue "Top"
90+
* @since 1.0.0-rc.7
91+
* @public
92+
*/
93+
tabsPlacement: {
94+
type: TabContainerTabsPlacement,
95+
defaultValue: TabContainerTabsPlacement.Top,
96+
},
97+
7998
/**
8099
* Defines whether the overflow select list is displayed.
81100
* <br><br>
@@ -462,6 +481,14 @@ class TabContainer extends UI5Element {
462481
return this.i18nBundle.getText(TABCONTAINER_OVERFLOW_MENU_TITLE);
463482
}
464483

484+
get tabsAtTheBottom() {
485+
return this.tabsPlacement === TabContainerTabsPlacement.Bottom;
486+
}
487+
488+
get overflowMenuIcon() {
489+
return this.tabsAtTheBottom ? "slim-arrow-up" : "slim-arrow-down";
490+
}
491+
465492
get rtl() {
466493
return getRTL() ? "rtl" : undefined;
467494
}

packages/main/src/themes/TabContainer.css

+9-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
box-sizing: border-box;
2626
}
2727

28+
:host([tabs-placement="Bottom"]) .ui5-tc__header {
29+
border-top: var(--_ui5_tc_header_border_bottom);
30+
}
31+
2832
.ui5-tc-root.ui5-tc--textOnly .ui5-tc__header {
2933
height: var(--_ui5_tc_header_height_text_only);
3034
}
@@ -241,6 +245,10 @@
241245
box-sizing: border-box;
242246
}
243247

248+
:host([tabs-placement="Bottom"]) .ui5-tc__content {
249+
border-top: var(--_ui5_tc_content_border_bottom);
250+
}
251+
244252
.ui5-tc__content--collapsed {
245253
display: none;
246254
}
@@ -378,4 +386,4 @@
378386
[dir=rtl] .ui-tc__overflowButton {
379387
margin-right: auto;
380388
margin-left: 0.25rem;
381-
}
389+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import DataType from "@ui5/webcomponents-base/dist/types/DataType.js";
2+
3+
/**
4+
* @lends sap.ui.webcomponents.main.types.TabContainerTabsPlacement.prototype
5+
* @public
6+
*/
7+
const TabContainerTabsPlacements = {
8+
/**
9+
* The tab strip is displayed above the tab content (Default)
10+
* @public
11+
* @type {Top}
12+
*/
13+
Top: "Top",
14+
15+
/**
16+
* The tab strip is displayed below the tab content
17+
* @public
18+
* @type {Bottom}
19+
*/
20+
Bottom: "Bottom",
21+
};
22+
23+
/**
24+
* @class
25+
* Different options for the position of the tab strip relative to the tab content area.
26+
* @constructor
27+
* @author SAP SE
28+
* @alias sap.ui.webcomponents.main.types.TabContainerTabsPlacement
29+
* @public
30+
* @enum {string}
31+
*/
32+
class TabContainerTabsPlacement extends DataType {
33+
static isValid(value) {
34+
return !!TabContainerTabsPlacements[value];
35+
}
36+
}
37+
38+
TabContainerTabsPlacement.generataTypeAcessors(TabContainerTabsPlacements);
39+
40+
export default TabContainerTabsPlacement;

packages/main/test/pages/TabContainer.html

+58-11
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ <h1 class="header-title">ui5-tabcontainer</h1>
5454

5555
<section>
5656
<h2>Tab Container</h2>
57-
<ui5-tabcontainer id="tabContainer1" fixed collapsed show-overflow="true">
57+
<ui5-tabcontainer id="tabContainer1" fixed collapsed show-overflow>
5858
<ui5-tab text="Products" additional-text="125">
5959
</ui5-tab>
6060
<ui5-tab-separator></ui5-tab-separator>
@@ -64,7 +64,7 @@ <h2>Tab Container</h2>
6464
</ui5-tab>
6565
<ui5-tab icon="sap-icon://menu2" text="Keyboards" semantic-color="Negative" additional-text="15">
6666
</ui5-tab>
67-
<ui5-tab icon="sap-icon://menu2" disabled="true" text="Disabled" semantic-color="Negative" additional-text="40">
67+
<ui5-tab icon="sap-icon://menu2" disabled text="Disabled" semantic-color="Negative" additional-text="40">
6868
</ui5-tab>
6969
<ui5-tab icon="sap-icon://menu2" text="Neutral" semantic-color="Neutral" additional-text="40">
7070
</ui5-tab>
@@ -75,7 +75,7 @@ <h2>Tab Container</h2>
7575

7676
<section>
7777
<h2>Icon only</h2>
78-
<ui5-tabcontainer show-overflow="true" id="tabContainerIconOnly">
78+
<ui5-tabcontainer show-overflow id="tabContainerIconOnly">
7979
<ui5-tab icon="sap-icon://card" selected>
8080
<ui5-button>Button 11</ui5-button>
8181
<ui5-button>Button 12</ui5-button>
@@ -121,7 +121,7 @@ <h2>Icon only</h2>
121121

122122
<section>
123123
<h2>Text only</h2>
124-
<ui5-tabcontainer show-overflow="true" id="tabContainerTextOnly">
124+
<ui5-tabcontainer show-overflow id="tabContainerTextOnly">
125125
<ui5-tab text="Products ID" selected>
126126
<ui5-button>Button 11</ui5-button>
127127
<ui5-button>Button 12</ui5-button>
@@ -225,7 +225,7 @@ <h2>Text only</h2>
225225
<section>
226226
<h2>Icon and Text</h2>
227227

228-
<ui5-tabcontainer show-overflow="true">
228+
<ui5-tabcontainer show-overflow>
229229
<ui5-tab icon="sap-icon://card" text="Tab 1" additional-text="123">
230230
<div style="height: 300px">
231231
<h4>Content with set height: 300px</h4>
@@ -245,7 +245,7 @@ <h4>Content with set height: 300px</h4>
245245
<section>
246246
<h2>Icon and Text with tabLayout="Inline"</h2>
247247

248-
<ui5-tabcontainer show-overflow="true" tab-layout="Inline">
248+
<ui5-tabcontainer show-overflow tab-layout="Inline">
249249
<ui5-tab icon="sap-icon://card" text="Tab 1" additional-text="123">
250250
<div style="height: 300px">
251251
<h4>Content with set height: 300px</h4>
@@ -265,7 +265,7 @@ <h4>Content with set height: 300px</h4>
265265
<section>
266266
<h2>Text and additional text</h2>
267267

268-
<ui5-tabcontainer show-overflow="true">
268+
<ui5-tabcontainer show-overflow>
269269
<ui5-tab text="Tab 1" additional-text="additional">
270270
<ui5-button>Button 11</ui5-button>
271271
<ui5-button>Button 12</ui5-button>
@@ -282,7 +282,7 @@ <h2>Text and additional text</h2>
282282
<section>
283283
<h2>Text and additional text with tabLayout="Inline"</h2>
284284

285-
<ui5-tabcontainer show-overflow="true" tab-layout="Inline">
285+
<ui5-tabcontainer show-overflow tab-layout="Inline">
286286
<ui5-tab text="Monitors" additional-text="10">
287287
<ui5-button>Button 11</ui5-button>
288288
<ui5-button>Button 12</ui5-button>
@@ -299,7 +299,7 @@ <h2>Text and additional text with tabLayout="Inline"</h2>
299299
<section>
300300
<h2>Tabs with input elements</h2>
301301

302-
<ui5-tabcontainer show-overflow="true">
302+
<ui5-tabcontainer show-overflow>
303303
<ui5-tab text="Tab 1" selected>
304304
<p>ui5-input</p>
305305
<ui5-input></ui5-input>
@@ -320,7 +320,7 @@ <h2>Result</h2>
320320
<section class="ui5-content-density-compact">
321321
<h3>TabContainer in Compact</h3>
322322
<div>
323-
<ui5-tabcontainer show-overflow="true">
323+
<ui5-tabcontainer show-overflow>
324324
<ui5-tab text="Products ID">
325325
<ui5-button>Button 11</ui5-button>
326326
<ui5-button>Button 12</ui5-button>
@@ -362,11 +362,58 @@ <h3>TabContainer in Compact</h3>
362362
</div>
363363
</section>
364364

365+
366+
<section>
367+
<h2>tabs-placement=Bottom</h2>
368+
<ui5-tabcontainer show-overflow tabs-placement="Bottom">
369+
<ui5-tab icon="sap-icon://card" selected>
370+
<ui5-button>Button 11</ui5-button>
371+
<ui5-button>Button 12</ui5-button>
372+
</ui5-tab>
373+
<ui5-tab icon="sap-icon://employee">
374+
<ui5-button>Button 3</ui5-button>
375+
</ui5-tab>
376+
<ui5-tab icon="sap-icon://employee">
377+
<ui5-button>Button 3</ui5-button>
378+
</ui5-tab>
379+
<ui5-tab icon="sap-icon://menu2">
380+
<ui5-button>Button 2</ui5-button>
381+
</ui5-tab>
382+
<ui5-tab icon="sap-icon://menu2">
383+
<ui5-button>Button 2</ui5-button>
384+
</ui5-tab>
385+
<ui5-tab icon="sap-icon://employee">
386+
<ui5-button>Button 3</ui5-button>
387+
</ui5-tab>
388+
<ui5-tab icon="sap-icon://employee">
389+
<ui5-button>Button 3</ui5-button>
390+
</ui5-tab>
391+
<ui5-tab icon="sap-icon://employee">
392+
<ui5-button>Button 3</ui5-button>
393+
</ui5-tab>
394+
<ui5-tab icon="sap-icon://employee">
395+
<ui5-button>Button 3</ui5-button>
396+
</ui5-tab>
397+
<ui5-tab icon="sap-icon://employee">
398+
<ui5-button>Button 3</ui5-button>
399+
</ui5-tab>
400+
<ui5-tab icon="sap-icon://employee">
401+
<ui5-button>Button 3</ui5-button>
402+
</ui5-tab>
403+
<ui5-tab icon="sap-icon://menu2">
404+
<ui5-button>Button 2</ui5-button>
405+
</ui5-tab>
406+
<ui5-tab icon="sap-icon://employee">
407+
<ui5-button>Button 3</ui5-button>
408+
</ui5-tab>
409+
</ui5-tabcontainer>
410+
</section>
411+
365412
<script>
366413
document.getElementById("tabContainer1").addEventListener("ui5-tabSelect", function (event) {
367414
result.innerHTML = event.detail.tab.text;
368415
resultIdx.innerHTML = event.detail.tabIndex;
369416
});
370417
</script>
371418
</body>
372-
</html>
419+
</html>

0 commit comments

Comments
 (0)