Skip to content

Commit

Permalink
fix(ui5-tabcontainer): avoid multiple selected tabs when there is no …
Browse files Browse the repository at this point in the history
…explicit selection (#8808)

Fixes: #8323
  • Loading branch information
dimovpetar committed Apr 23, 2024
1 parent a60c5ee commit ae8d969
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 17 deletions.
5 changes: 1 addition & 4 deletions packages/main/src/Tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ class Tab extends UI5Element implements ITabbable, ITab {
@property({ type: Boolean })
movable!: boolean;

@property({ type: Boolean })
forcedSelected!: boolean;

@property({ type: Boolean })
_isTopLevelTab!: boolean;

Expand Down Expand Up @@ -320,7 +317,7 @@ class Tab extends UI5Element implements ITabbable, ITab {

get effectiveSelected() {
const subItemSelected = this.tabs.some(elem => elem.effectiveSelected);
return this.selected || this.forcedSelected || subItemSelected;
return this.selected || this._selectedTabReference === this || subItemSelected;
}

get effectiveHidden() {
Expand Down
18 changes: 6 additions & 12 deletions packages/main/src/TabContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,13 +397,12 @@ class TabContainer extends UI5Element {
}

// update selected tab
const selectedTabs = this._itemsFlat.filter((tab): tab is Tab => !tab.isSeparator && (tab as Tab).selected);
if (selectedTabs.length) {
this._selectedTab.forcedSelected = false;
this._selectedTab = selectedTabs[0];
const selectedTab = this._itemsFlat.find((tab): tab is Tab => !tab.isSeparator && (tab as Tab).selected);

if (selectedTab) {
this._selectedTab = selectedTab;
} else {
this._selectedTab = this._itemsFlat[0] as Tab;
this._selectedTab.forcedSelected = true;
}

walk(this.items, item => {
Expand Down Expand Up @@ -825,14 +824,9 @@ class TabContainer extends UI5Element {
}

// update selected property on all items
this._itemsFlat!.forEach((item, index) => {
this._itemsFlat!.forEach(item => {
if (!item.isSeparator) {
const selected = selectedTabIndex === index;
(item as Tab).selected = selected;

if ((item as Tab).forcedSelected) {
(item as Tab).forcedSelected = false;
}
(item as Tab).selected = item === selectedTab;
}
});
}
Expand Down
17 changes: 16 additions & 1 deletion packages/main/test/pages/TabContainer.html
Original file line number Diff line number Diff line change
Expand Up @@ -798,11 +798,19 @@ <h2>Text only Start And End Overflow Custom Overflow Buttons</h2>
</section>
<section>
<h3>Add new selected tab programmatically</h3>
<ui5-button id="buttonAddTabs">add tabs</ui5-button>
<ui5-tabcontainer id="tabContainerAddTabsProgrammatically">
<ui5-tab text="Tab 0" selected></ui5-tab>
<ui5-tab text="Tab 1"></ui5-tab>
</ui5-tabcontainer>
<ui5-button id="buttonAddTabs">add tabs</ui5-button>
</section>
<section>
<h3>No explicitly selected tab</h3>
<ui5-button id="buttonAddTabAtNoExplicitlySelectedTab">add new tab at the beginning</ui5-button>
<ui5-tabcontainer id="tabContainerNoExplicitlySelectedTab">
<ui5-tab text="Tab 0"></ui5-tab>
<ui5-tab text="Tab 1"></ui5-tab>
</ui5-tabcontainer>
</section>

</section>
Expand Down Expand Up @@ -937,6 +945,13 @@ <h3>Dynamically Insert Tab and Focus It</h3>
addTab();
});

document.getElementById("buttonAddTabAtNoExplicitlySelectedTab").addEventListener("click", function () {
const newTab = document.createElement("ui5-tab");
newTab.text = "New Tab";

document.getElementById("tabContainerNoExplicitlySelectedTab").prepend(newTab);
});

document.getElementById("insertAndFocusNewTab").addEventListener("click", () => {
const tab = document.createElement("ui5-tab");
tab.id = "newlyInsertedFocusedTab";
Expand Down
23 changes: 23 additions & 0 deletions packages/main/test/specs/TabContainer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,29 @@ describe("TabContainer general interaction", () => {
assert.notOk(await allTabs[4].getProperty("selected"), "The fifth tab should not be selected");
});

it("tests effective selected tab when there is no explicitly selected tab", async () => {
const tabContainer = await browser.$("#tabContainerNoExplicitlySelectedTab");
let allTabs = await tabContainer.$$("ui5-tab");
let effectiveSelectedArr = await Promise.all(allTabs.map(tab => tab.getProperty("effectiveSelected")));
let effectiveSelectedTabs = effectiveSelectedArr.filter(Boolean);

// Assert
assert.strictEqual(effectiveSelectedTabs.length, 1, "Only 1 tab is effectively selected");
assert.ok(await allTabs[0].getProperty("effectiveSelected"), "First tab is effectively selected");

// Act
await browser.$("#buttonAddTabAtNoExplicitlySelectedTab").click();

allTabs = await tabContainer.$$("ui5-tab");
effectiveSelectedArr = await Promise.all(allTabs.map(tab => tab.getProperty("effectiveSelected")));
effectiveSelectedTabs = effectiveSelectedArr.filter(Boolean);

// Assert
assert.strictEqual(effectiveSelectedTabs.length, 1, "Only 1 tab is effectively selected");
assert.ok(await allTabs[0].getProperty("effectiveSelected"), "First tab is effectively selected");
});


it("tests tabs dom ref", async () => {
const productsTabDomRef = await browser.$(() => document.querySelector("[stable-dom-ref='products-ref']").getDomRef());
const productsTabStableDomRef = await browser.$(() => document.querySelector("[stable-dom-ref='products-ref']").shadowRoot.firstElementChild);
Expand Down

0 comments on commit ae8d969

Please sign in to comment.