Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui5-tabcontainer): show separators in overflow #4507

Merged
merged 60 commits into from
Jan 10, 2022
Merged
Changes from 1 commit
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
de1ab1c
ui5-tabcontainer: introduce overflow tabs
kskondov Nov 26, 2021
2a24d59
Fixing bugs
kskondov Nov 29, 2021
84e7532
Merge remote-tracking branch 'upstream/master' into ui5-tab-container…
TeodorTaushanov Nov 30, 2021
d35e584
filter visible tab strip items
TeodorTaushanov Dec 2, 2021
65dbfcf
Merge remote-tracking branch 'upstream/master' into ui5-tab-container…
TeodorTaushanov Dec 2, 2021
0daed63
filter overflow items
TeodorTaushanov Dec 2, 2021
72464a5
fix lint error and inline mode filtering
TeodorTaushanov Dec 2, 2021
f763831
implemented "start and end" overflow
TeodorTaushanov Dec 3, 2021
1d0c28c
Merge remote-tracking branch 'upstream/master' into ui5-tab-container…
TeodorTaushanov Dec 6, 2021
17bf805
fix start and end overflow items visibility
TeodorTaushanov Dec 6, 2021
f85caa7
fix filtering corner cases
TeodorTaushanov Dec 6, 2021
fe1340c
fix test page and the overflow buttons count text
TeodorTaushanov Dec 6, 2021
05287bb
fix lint errors
TeodorTaushanov Dec 7, 2021
09dc8a9
Merge remote-tracking branch 'upstream/master' into ui5-tab-container…
TeodorTaushanov Dec 7, 2021
a4af1be
Added documentation and samples
kskondov Dec 9, 2021
88d8892
Added tests
kskondov Dec 9, 2021
0c841bb
Address review comments
kskondov Dec 10, 2021
8dc7671
Addressed code review comments
kskondov Dec 10, 2021
fc1b49b
Address review findings
kskondov Dec 13, 2021
92361a1
feat(ui5-tabcontainer): Add keyboard navigation
kskondov Dec 13, 2021
e19b30e
Fix lint error
kskondov Dec 13, 2021
3e4b70f
Added tabs and overflow buttons keyboard navigation
kskondov Dec 13, 2021
c1efc03
Added warning for deprecated property
kskondov Dec 14, 2021
e055947
Fixed lint error
kskondov Dec 14, 2021
3049dce
Initial commit
kskondov Dec 14, 2021
28a131d
Merge branch 'ui5-tab-container-overflows' of github.com:SAP/ui5-webc…
kskondov Dec 14, 2021
e097e60
Set initial focus in overflow list
kskondov Dec 14, 2021
dfb48e3
Fixed lint
kskondov Dec 14, 2021
d0f23b5
Merge branch 'ui5-tabcontainer-keyboard-handling' of github.com:SAP/u…
kskondov Dec 14, 2021
b06e12e
Merge branch 'master' of github.com:SAP/ui5-webcomponents into ui5-ta…
kskondov Dec 14, 2021
12f6215
Set focus on selected item when there are no overflows
kskondov Dec 14, 2021
36c4fb1
Fix tests
kskondov Dec 14, 2021
688bf88
add arrow keys handling, truncate the tab if it can't fit in the tab …
georgimkv Dec 17, 2021
6c57478
lint
georgimkv Dec 17, 2021
257a36f
fix test
georgimkv Dec 20, 2021
7ec9b4b
feat(ui5-tabcontainer): show separators in overflow
georgimkv Dec 20, 2021
885a6b1
rename classes, refactor
georgimkv Dec 20, 2021
832d3d8
Merge branch 'master' into tc-separators-in-overflow
kskondov Dec 20, 2021
cf30bbe
Disable separators
kskondov Dec 20, 2021
9a88841
Merge branch 'master' of github.com:SAP/ui5-webcomponents into tc-sep…
kskondov Dec 20, 2021
d930408
Merge branch 'master' into ui5-tabcontainer-keyboardhandling
georgimkv Dec 21, 2021
a7154a2
Merge branch 'master' into ui5-tabcontainer-keyboardhandling
georgimkv Dec 21, 2021
95567c6
update base hash and lint
georgimkv Dec 21, 2021
dd0ad67
Lint and style
kskondov Dec 21, 2021
80a2830
Fix tests
kskondov Dec 21, 2021
74bc827
Merge branch 'ui5-tabcontainer-keyboardhandling' of github.com:SAP/ui…
kskondov Dec 21, 2021
63329c3
Remove unused unnecessary code and review for obsolete documentation
kskondov Dec 21, 2021
3d211c7
cancel item selection in overflow list
georgimkv Dec 22, 2021
d79d392
Merge branch 'ui5-tabcontainer-keyboardhandling' of github.com:SAP/ui…
kskondov Dec 22, 2021
4a6f384
css separators
kskondov Dec 22, 2021
1586879
Merge branch 'master' of github.com:SAP/ui5-webcomponents into tc-sep…
kskondov Dec 22, 2021
8f87ae6
Fix bug with multiple separators
kskondov Dec 23, 2021
84bae16
Merge branch 'master' of github.com:SAP/ui5-webcomponents into tc-sep…
kskondov Jan 6, 2022
57fc132
Address code review
kskondov Jan 7, 2022
7375956
Code review comments
kskondov Jan 7, 2022
2982bae
Updated separator metrics according to VD spec
kskondov Jan 10, 2022
a8a1e76
Merge branch 'master' of github.com:SAP/ui5-webcomponents into tc-sep…
kskondov Jan 10, 2022
ab8313d
Update separator parameters
kskondov Jan 10, 2022
146f106
Focus on first focusable element in overflow
kskondov Jan 10, 2022
3a704cc
Updated first focusable element selection
kskondov Jan 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
ui5-tabcontainer: introduce overflow tabs
Initial commit
kskondov committed Nov 26, 2021

Verified

This commit was signed with the committer’s verified signature. The key has expired.
mmarchini mary marchini
commit de1ab1c2bd3cc4f49d21d8d2a4544e6a934f1313
8 changes: 8 additions & 0 deletions packages/main/src/Tab.js
Original file line number Diff line number Diff line change
@@ -294,6 +294,10 @@ class Tab extends UI5Element {
classes.push(`ui5-tab-strip-item--${this.design.toLowerCase()}`);
}

if (this.hidden) {
classes.push("ui5-tab-strip-item--hidden");
}

return classes.join(" ");
}

@@ -318,6 +322,10 @@ class Tab extends UI5Element {
classes.push("ui5-tab-overflow-item--disabled");
}

if (!this.hidden) {
classes.push("ui5-tab-overflow-item--hidden");
}

return classes.join(" ");
}

20 changes: 2 additions & 18 deletions packages/main/src/TabContainer.hbs
Original file line number Diff line number Diff line change
@@ -8,14 +8,6 @@

<div class="{{classes.header}}" id="{{_id}}-header">
<div class="{{classes.headerInnerContainer}}">
<div class="{{classes.headerBackArrow}}">
<ui5-button @click="{{_onHeaderBackArrowClick}}"
icon="slim-arrow-left"
data-ui5-stable="tabs-left"
design="Transparent"
tabindex="-1"
title="{{previousIconACCName}}"></ui5-button>
</div>
<!-- tab items -->
<div class="{{classes.headerScrollContainer}}" id="{{_id}}-headerScrollContainer">
<ul
@@ -41,14 +33,6 @@
{{/each}}
</ul>
</div>
<div class="{{classes.headerForwardArrow}}">
<ui5-button @click="{{_onHeaderForwardArrowClick}}"
icon="slim-arrow-right"
data-ui5-stable="tabs-right"
design="Transparent"
tabindex="-1"
title="{{nextIconACCName}}"></ui5-button>
</div>
</div>
<!-- overflow button -->
{{#if shouldShowOverflow}}
@@ -62,10 +46,10 @@
<ui5-button
icon="{{overflowMenuIcon}}"
data-ui5-stable="tabs-overflow"
design="Transparent"
tabindex="-1"
title="{{overflowMenuTitle}}"
aria-haspopup="true"></ui5-button>
aria-haspopup="true"
icon-end>MORE</ui5-button>
{{/if}}
</div>
{{/if}}
133 changes: 71 additions & 62 deletions packages/main/src/TabContainer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
import ScrollEnablement from "@ui5/webcomponents-base/dist/delegate/ScrollEnablement.js";
import slideDown from "@ui5/webcomponents-base/dist/animations/slideDown.js";
import slideUp from "@ui5/webcomponents-base/dist/animations/slideUp.js";
import AnimationMode from "@ui5/webcomponents-base/dist/types/AnimationMode.js";
@@ -12,8 +11,6 @@ import MediaRange from "@ui5/webcomponents-base/dist/MediaRange.js";
import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
import "@ui5/webcomponents-icons/dist/slim-arrow-up.js";
import "@ui5/webcomponents-icons/dist/slim-arrow-down.js";
import "@ui5/webcomponents-icons/dist/slim-arrow-left.js";
import "@ui5/webcomponents-icons/dist/slim-arrow-right.js";
import { TABCONTAINER_PREVIOUS_ICON_ACC_NAME, TABCONTAINER_NEXT_ICON_ACC_NAME, TABCONTAINER_OVERFLOW_MENU_TITLE } from "./generated/i18n/i18n-defaults.js";
import Button from "./Button.js";
import Icon from "./Icon.js";
@@ -30,8 +27,6 @@ import tabContainerCss from "./generated/themes/TabContainer.css.js";
import ResponsivePopoverCommonCss from "./generated/themes/ResponsivePopoverCommon.css.js";
import TabLayout from "./types/TabLayout.js";

const SCROLL_STEP = 128;

const tabStyles = [];
const staticAreaTabStyles = [];

@@ -174,21 +169,6 @@ const metadata = {
type: Object,
},

_scrollable: {
type: Boolean,
noAttribute: true,
},

_scrollableBack: {
type: Boolean,
noAttribute: true,
},

_scrollableForward: {
type: Boolean,
noAttribute: true,
},

_animationRunning: {
type: Boolean,
noAttribute: true,
@@ -289,10 +269,6 @@ class TabContainer extends UI5Element {

this._handleResize = this._handleResize.bind(this);

// Init ScrollEnablement
this._scrollEnablement = new ScrollEnablement(this);
this._scrollEnablement.attachEvent("scroll", this._updateScrolling.bind(this));

// Init ItemNavigation
this._itemNavigation = new ItemNavigation(this, {
getItemsCallback: () => this._getTabs(),
@@ -319,8 +295,7 @@ class TabContainer extends UI5Element {
}

onAfterRendering() {
this._scrollEnablement.scrollContainer = this._getHeaderScrollContainer();
this._updateScrolling();
this.scrollContainer = this._getHeaderScrollContainer();

this.items.forEach(item => {
item._getTabInStripDomRef = this.getDomRef().querySelector(`*[data-ui5-stable="${item.stableDomRef}"]`);
@@ -338,21 +313,11 @@ class TabContainer extends UI5Element {
_onTablistFocusin(event) {
const target = event.target;

if (!this._scrollable || !target.classList.contains("ui5-tab-strip-item")) {
if (!target.classList.contains("ui5-tab-strip-item")) {
return;
}

const headerScrollContainer = this._getHeaderScrollContainer();
const leftArrowWidth = this.shadowRoot.querySelector(".ui5-tc__headerArrowLeft").offsetWidth;
const rightArrowWidth = this.shadowRoot.querySelector(".ui5-tc__headerArrowRight").offsetWidth;

if (this._scrollableBack && (target.offsetLeft - leftArrowWidth < headerScrollContainer.scrollLeft)) {
this._scrollEnablement.move(target.offsetLeft - leftArrowWidth - headerScrollContainer.scrollLeft, 0, true);
this._updateScrolling();
} else if (this._scrollableForward && (target.offsetLeft + target.offsetWidth > headerScrollContainer.scrollLeft + headerScrollContainer.offsetWidth - rightArrowWidth)) {
this._scrollEnablement.move(target.offsetLeft + target.offsetWidth - headerScrollContainer.scrollLeft - headerScrollContainer.offsetWidth + rightArrowWidth, 0, true);
this._updateScrolling();
}
this._showEndOverflow();
}

_onHeaderClick(event) {
@@ -398,9 +363,11 @@ class TabContainer extends UI5Element {
}

_onOverflowListItemSelect(event) {
const overflowItemIndex = event.detail.item.parentNode._itemNavigation._currentIndex;
this._onItemSelect(event.detail.item);
this.responsivePopover.close();
this.shadowRoot.querySelector(`#${event.detail.item.id}`).focus();
this._updateEndOverflow(overflowItemIndex);
}

_onItemSelect(target) {
@@ -482,6 +449,7 @@ class TabContainer extends UI5Element {
}

async _onOverflowButtonClick(event) {
this._updateEndOverflow();
const button = this.overflowButton[0] || this.getDomRef().querySelector(".ui-tc__overflowButton > [ui5-button]");

if (event.target !== button) {
@@ -496,18 +464,53 @@ class TabContainer extends UI5Element {
}
}

_onHeaderBackArrowClick() {
this._scrollEnablement.move(-SCROLL_STEP, 0).promise()
.then(_ => this._updateScrolling());
_updateEndOverflow(overflowItemIndex) {
const allItems = this.items;
const containerOffsetWidth = this._getHeaderScrollContainer().offsetWidth - this.getDomRef().querySelector(".ui-tc__overflowButton").offsetWidth;

this.itemsInEndOverflow = [];
this.lastVisibleTab = this._findLastVisibleItem(allItems, containerOffsetWidth);

for (let index = this.lastVisibleTab + 1; index < allItems.length; index++) {
allItems[index].hidden = true;
}

for (let index = 0; index < this.items.length; index++) {
this.itemsInEndOverflow.push({
text: this.items[index].text,
hidden: this.items[index].hidden,
icon: this.items[index].icon,
overflowPresentation: this.items[index].overflowPresentation,
});
}
if (overflowItemIndex) {
allItems[this.lastVisibleTab].hidden = true;
allItems[overflowItemIndex].hidden = false;
}
return this.itemsInEndOverflow;
}

_onHeaderForwardArrowClick() {
this._scrollEnablement.move(SCROLL_STEP, 0).promise()
.then(_ => this._updateScrolling());
_findLastVisibleItem(items, tabStripWidth) {
const startIndex = 0;
let lastVisibleTabIndex = -1,
index,
itemSize;

for (index = startIndex; index < items.length; index++) {
itemSize = items[index]._getRealDomRef().offsetWidth;

tabStripWidth -= itemSize;
if (tabStripWidth <= 0) {
lastVisibleTabIndex = index;
break;
}
}

return lastVisibleTabIndex;
}

_handleResize() {
this._updateScrolling();
this._showEndOverflow();
this._updateMediaRange();
}

@@ -516,14 +519,17 @@ class TabContainer extends UI5Element {
this.responsivePopover.close();
}

_updateScrolling() {
_showEndOverflow() {
const headerScrollContainer = this._getHeaderScrollContainer();
let allItemsWidth = 0;

this.items.forEach(item => {
allItemsWidth += item._getRealDomRef().offsetWidth;
});

this._scrollable = headerScrollContainer.offsetWidth < headerScrollContainer.scrollWidth;
this._scrollableBack = headerScrollContainer.scrollLeft > 0;
this._scrollableForward = Math.ceil(headerScrollContainer.scrollLeft) < headerScrollContainer.scrollWidth - headerScrollContainer.offsetWidth;
this.showOverflow = headerScrollContainer.offsetWidth < allItemsWidth;

if (!this._scrollable) {
if (!this.showOverflow) {
this._closeRespPopover();
}
}
@@ -544,13 +550,17 @@ class TabContainer extends UI5Element {
return this.shadowRoot.querySelector(`#${this._id}-headerScrollContainer`);
}

_getHeaderOverflowButton() {
return this.shadowRoot.querySelector(".ui5-tc__overflowButton");
}

async _respPopover() {
const staticAreaItem = await this.getStaticAreaItemDomRef();
return staticAreaItem.querySelector(`#${this._id}-overflowMenu`);
}

get shouldShowOverflow() {
return this.showOverflow && this._scrollable;
return this.showOverflow;
}

get classes() {
@@ -563,7 +573,6 @@ class TabContainer extends UI5Element {
},
header: {
"ui5-tc__header": true,
"ui5-tc__header--scrollable": this._scrollable,
},
headerInnerContainer: {
"ui5-tc__headerInnerContainer": true,
@@ -577,16 +586,16 @@ class TabContainer extends UI5Element {
separator: {
"ui5-tc__separator": true,
},
headerBackArrow: {
"ui5-tc__headerArrow": true,
"ui5-tc__headerArrowLeft": true,
"ui5-tc__headerArrow--visible": this._scrollableBack,
},
headerForwardArrow: {
"ui5-tc__headerArrow": true,
"ui5-tc__headerArrowRight": true,
"ui5-tc__headerArrow--visible": this._scrollableForward,
},
// headerBackArrow: {
// "ui5-tc__headerArrow": true,
// "ui5-tc__headerArrowLeft": true,
// "ui5-tc__headerArrow--visible": this._scrollableBack,
// },
// headerForwardArrow: {
// "ui5-tc__headerArrow": true,
// "ui5-tc__headerArrowRight": true,
// "ui5-tc__headerArrow--visible": this._scrollableForward,
// },
content: {
"ui5-tc__content": true,
"ui5-tc__content--collapsed": this._contentCollapsed,
2 changes: 1 addition & 1 deletion packages/main/src/TabContainerPopover.hbs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
_hide-header
class="ui5-tab-container-responsive-popover"
>
<ui5-list @ui5-item-press="{{_onOverflowListItemSelect}}">
<ui5-list separators="None" @ui5-item-press="{{_onOverflowListItemSelect}}">
{{#each items}}
{{#unless this.isSeparator}}
{{this.overflowPresentation}}
1 change: 0 additions & 1 deletion packages/main/src/TabInOverflow.hbs
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@
id="{{this._id}}"
class="{{this.overflowClasses}}"
type="{{this.overflowState}}"
?selected="{{this.effectiveSelected}}"
?disabled="{{this.effectiveDisabled}}"
aria-disabled="{{this.effectiveDisabled}}"
aria-selected="{{this.effectiveSelected}}"
5 changes: 5 additions & 0 deletions packages/main/src/themes/TabContainer.css
Original file line number Diff line number Diff line change
@@ -102,6 +102,11 @@
margin: 0 0.25rem;
}

.ui-tc__overflowButton>[ui5-button] {
margin-top: 0.25rem;
border-radius: 0.75rem;
height: 1.5rem;
}
.ui5-tc-root.ui5-tc--textOnly .ui5-tc__content {
height: calc(100% - var(--_ui5_tc_header_height_text_only)); /* the header height (text only tabs) */
}
4 changes: 4 additions & 0 deletions packages/main/src/themes/TabInOverflow.css
Original file line number Diff line number Diff line change
@@ -46,6 +46,10 @@
color: var(--_ui5_tc_overflowItem_current_color);
}

.ui5-tab-overflow-item--hidden {
display: none;
}

.ui5-tab-container-responsive-popover [ui5-li-custom][focused]:first-child::part(native-li)::after {
border-top-left-radius: var(--_ui5_tc_overflowItem_focus_border);
border-top-right-radius: var(--_ui5_tc_overflowItem_focus_border);
4 changes: 4 additions & 0 deletions packages/main/src/themes/TabInStrip.css
Original file line number Diff line number Diff line change
@@ -348,3 +348,7 @@
margin-right: 0;
margin-left: 0.5rem;
}

.ui5-tab-strip-item--hidden {
display: none;
}
2 changes: 1 addition & 1 deletion packages/main/src/themes/base/TabContainer-parameters.css
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@
--_ui5_tc_headerItemIcon_neutral_selected_background: var(--sapNeutralColor);
--_ui5_tc_headerItemIcon_semantic_selected_color: var(--sapGroup_ContentBackground);

--_ui5_tc_overflowItem_default_color: var(--sapHighlightColor);
--_ui5_tc_overflowItem_default_color: var(--sapNeutralTextColor);
--_ui5_tc_overflowItem_current_color: CurrentColor;
--_ui5_tc_content_border_bottom: 0.125rem solid var(--sapObjectHeader_BorderColor);

Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
/* Header Item */
--_ui5_tc_headerItemContent_border_bottom: 0.1875rem solid var(--sapSelectedColor);

--_ui5_tc_overflowItem_default_color: var(--sapHighlightColor);
--_ui5_tc_overflowItem_default_color: var(--sapNeutralTextColor);
--_ui5_tc_overflowItem_current_color: CurrentColor;
--_ui5_tc_content_border_bottom: 0.0625rem solid var(--sapObjectHeader_BorderColor);
}
Loading