Skip to content

Commit c778176

Browse files
merge release-8.7.6 (#30720)
v8.7.6
2 parents 912f09b + ce048a5 commit c778176

31 files changed

+255
-155
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [8.7.6](https://github.com/ionic-team/ionic-framework/compare/v8.7.5...v8.7.6) (2025-10-08)
7+
8+
9+
### Bug Fixes
10+
11+
* **tabs:** respect stencil lifecycle order for tab selection ([#30702](https://github.com/ionic-team/ionic-framework/issues/30702)) ([7bb9535](https://github.com/ionic-team/ionic-framework/commit/7bb9535f601d2469ce60687a9c03f8b1cfe4aba4)), closes [#30611](https://github.com/ionic-team/ionic-framework/issues/30611)
12+
13+
14+
15+
16+
617
## [8.7.5](https://github.com/ionic-team/ionic-framework/compare/v8.7.4...v8.7.5) (2025-09-24)
718

819

core/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [8.7.6](https://github.com/ionic-team/ionic-framework/compare/v8.7.5...v8.7.6) (2025-10-08)
7+
8+
9+
### Bug Fixes
10+
11+
* **tabs:** respect stencil lifecycle order for tab selection ([#30702](https://github.com/ionic-team/ionic-framework/issues/30702)) ([7bb9535](https://github.com/ionic-team/ionic-framework/commit/7bb9535f601d2469ce60687a9c03f8b1cfe4aba4)), closes [#30611](https://github.com/ionic-team/ionic-framework/issues/30611)
12+
13+
14+
15+
16+
617
## [8.7.5](https://github.com/ionic-team/ionic-framework/compare/v8.7.4...v8.7.5) (2025-09-24)
718

819

core/package-lock.json

Lines changed: 9 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ionic/core",
3-
"version": "8.7.5",
3+
"version": "8.7.6",
44
"description": "Base components for Ionic",
55
"keywords": [
66
"ionic",
@@ -31,7 +31,7 @@
3131
"loader/"
3232
],
3333
"dependencies": {
34-
"@stencil/core": "4.36.2",
34+
"@stencil/core": "4.38.0",
3535
"ionicons": "^8.0.13",
3636
"tslib": "^2.1.0"
3737
},

core/src/components/tab-bar/tab-bar.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import type { TabBarChangedEventDetail } from './tab-bar-interface';
2222
})
2323
export class TabBar implements ComponentInterface {
2424
private keyboardCtrl: KeyboardController | null = null;
25+
private didLoad = false;
2526

2627
@Element() el!: HTMLElement;
2728

@@ -40,6 +41,12 @@ export class TabBar implements ComponentInterface {
4041
@Prop() selectedTab?: string;
4142
@Watch('selectedTab')
4243
selectedTabChanged() {
44+
// Skip the initial watcher call that happens during component load
45+
// We handle that in componentDidLoad to ensure children are ready
46+
if (!this.didLoad) {
47+
return;
48+
}
49+
4350
if (this.selectedTab !== undefined) {
4451
this.ionTabBarChanged.emit({
4552
tab: this.selectedTab,
@@ -65,8 +72,19 @@ export class TabBar implements ComponentInterface {
6572
*/
6673
@Event() ionTabBarLoaded!: EventEmitter<void>;
6774

68-
componentWillLoad() {
69-
this.selectedTabChanged();
75+
componentDidLoad() {
76+
this.ionTabBarLoaded.emit();
77+
// Set the flag to indicate the component has loaded
78+
// This allows the watcher to emit changes from this point forward
79+
this.didLoad = true;
80+
81+
// Emit the initial selected tab after the component is fully loaded
82+
// This ensures all child components (ion-tab-button) are ready
83+
if (this.selectedTab !== undefined) {
84+
this.ionTabBarChanged.emit({
85+
tab: this.selectedTab,
86+
});
87+
}
7088
}
7189

7290
async connectedCallback() {
@@ -90,10 +108,6 @@ export class TabBar implements ComponentInterface {
90108
}
91109
}
92110

93-
componentDidLoad() {
94-
this.ionTabBarLoaded.emit();
95-
}
96-
97111
render() {
98112
const { color, translucent, keyboardVisible } = this;
99113
const mode = getIonMode(this);
-36 Bytes
Loading
-47 Bytes
Loading

core/src/components/tabs/tabs.tsx

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,32 +65,33 @@ export class Tabs implements NavOutlet {
6565
this.ionNavWillLoad.emit();
6666
}
6767

68-
componentWillRender() {
68+
componentDidLoad() {
69+
this.updateTabBar();
70+
}
71+
72+
componentDidUpdate() {
73+
this.updateTabBar();
74+
}
75+
76+
private updateTabBar() {
6977
const tabBar = this.el.querySelector('ion-tab-bar');
70-
if (tabBar) {
71-
let tab = this.selectedTab ? this.selectedTab.tab : undefined;
72-
73-
// Fallback: if no selectedTab is set but we're using router mode,
74-
// determine the active tab from the current URL. This works around
75-
// timing issues in React Router integration where setRouteId may not
76-
// be called in time for the initial render.
77-
// TODO(FW-6724): Remove this with React Router upgrade
78-
if (!tab && this.useRouter && typeof window !== 'undefined') {
79-
const currentPath = window.location.pathname;
80-
const tabButtons = this.el.querySelectorAll('ion-tab-button');
81-
82-
// Look for a tab button that matches the current path pattern
83-
for (const tabButton of tabButtons) {
84-
const tabId = tabButton.getAttribute('tab');
85-
if (tabId && currentPath.includes(tabId)) {
86-
tab = tabId;
87-
break;
88-
}
89-
}
90-
}
78+
if (!tabBar) {
79+
return;
80+
}
9181

92-
tabBar.selectedTab = tab;
82+
const tab = this.selectedTab ? this.selectedTab.tab : undefined;
83+
84+
// If tabs has no selected tab but tab-bar already has a selected-tab set,
85+
// don't overwrite it. This handles cases where tab-bar is used without ion-tab elements.
86+
if (tab === undefined) {
87+
return;
88+
}
89+
90+
if (tabBar.selectedTab === tab) {
91+
return;
9392
}
93+
94+
tabBar.selectedTab = tab;
9495
}
9596

9697
/**
@@ -162,6 +163,7 @@ export class Tabs implements NavOutlet {
162163
this.selectedTab = selectedTab;
163164
this.ionTabsWillChange.emit({ tab: selectedTab.tab });
164165
selectedTab.active = true;
166+
this.updateTabBar();
165167
return Promise.resolve();
166168
}
167169

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
"core",
44
"packages/*"
55
],
6-
"version": "8.7.5"
6+
"version": "8.7.6"
77
}

packages/angular-server/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [8.7.6](https://github.com/ionic-team/ionic-framework/compare/v8.7.5...v8.7.6) (2025-10-08)
7+
8+
**Note:** Version bump only for package @ionic/angular-server
9+
10+
11+
12+
13+
614
## [8.7.5](https://github.com/ionic-team/ionic-framework/compare/v8.7.4...v8.7.5) (2025-09-24)
715

816
**Note:** Version bump only for package @ionic/angular-server

0 commit comments

Comments
 (0)