@@ -21,6 +21,17 @@ interface InternalProps extends IonTabBarProps {
2121 forwardedRef ?: React . ForwardedRef < HTMLIonIconElement > ;
2222 onSetCurrentTab : ( tab : string , routeInfo : RouteInfo ) => void ;
2323 routeInfo : RouteInfo ;
24+ /**
25+ * This prop is set by the `IonTabs` component. If
26+ * the value is `undefined`, then the `ion-tab-bar`
27+ * component was not found within the slotted content.
28+ * Most likely, the tab bar was not passed as a direct
29+ * child of `IonTabs`.
30+ *
31+ * A workaround will be used to determine if the tabs
32+ * are being used as a basic tab navigation or with
33+ * the router.
34+ */
2435 routerOutletRef ?: React . RefObject < HTMLIonRouterOutletElement > | undefined ;
2536}
2637
@@ -40,10 +51,12 @@ interface IonTabBarState {
4051
4152class IonTabBarUnwrapped extends React . PureComponent < InternalProps , IonTabBarState > {
4253 context ! : React . ContextType < typeof NavContext > ;
54+ private tabBarRef : React . RefObject < HTMLIonTabBarElement > ;
4355
4456 constructor ( props : InternalProps ) {
4557 super ( props ) ;
4658 const tabs : { [ key : string ] : TabUrls } = { } ;
59+ this . tabBarRef = React . createRef < HTMLIonTabBarElement > ( ) ;
4760 React . Children . forEach ( ( props as any ) . children , ( child : any ) => {
4861 if (
4962 child != null &&
@@ -183,12 +196,33 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
183196 ) {
184197 const tappedTab = this . state . tabs [ e . detail . tab ] ;
185198 const originalHref = tappedTab . originalHref ;
199+ let hasIonRouterOutlet = ! ! this . props . routerOutletRef ?. current ;
200+
201+ /**
202+ * If `hasRouterOutlet` prop is not provided,
203+ * then the `IonTabBar` could not be found
204+ * within the slotted content of `IonTabs`.
205+ * This means that the tab bar might not
206+ * have been passed as a direct child of
207+ * `IonTabs`.
208+ *
209+ * In this case, the router outlet needs to be
210+ * searched for within the `IonTabBar` component.
211+ * This is necessary to determine if the tabs
212+ * are being used as a basic tab navigation or
213+ * with the router.
214+ */
215+ if ( ! hasIonRouterOutlet ) {
216+ const ionRouterOutlet = this . tabBarRef . current ?. closest ( 'ion-tabs' ) ?. querySelector ( 'ion-router-outlet' ) ;
217+ hasIonRouterOutlet = ! ! ionRouterOutlet ;
218+ }
219+
186220 /**
187221 * If the router outlet is not defined, then the tabs is being used
188222 * as a basic tab navigation without the router. In this case, we
189223 * don't want to update the href else the URL will change.
190224 */
191- const currentHref = this . props . routerOutletRef ?. current ? e . detail . href : '' ;
225+ const currentHref = hasIonRouterOutlet ? e . detail . href : '' ;
192226 const { activeTab : prevActiveTab } = this . state ;
193227
194228 if ( onClickFn ) {
@@ -212,7 +246,7 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
212246 if ( this . props . onIonTabsDidChange ) {
213247 this . props . onIonTabsDidChange ( new CustomEvent ( 'ionTabDidChange' , { detail : { tab : e . detail . tab } } ) ) ;
214248 }
215- if ( this . props . routerOutletRef ?. current ) {
249+ if ( hasIonRouterOutlet ) {
216250 this . setActiveTabOnContext ( e . detail . tab ) ;
217251 this . context . changeTab ( e . detail . tab , currentHref , e . detail . routeOptions ) ;
218252 }
@@ -249,7 +283,7 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
249283 render ( ) {
250284 const { activeTab } = this . state ;
251285 return (
252- < IonTabBarInner { ...this . props } selectedTab = { activeTab } >
286+ < IonTabBarInner ref = { this . tabBarRef } { ...this . props } selectedTab = { activeTab } >
253287 { React . Children . map ( this . props . children as any , this . renderTabButton ( activeTab ) ) }
254288 </ IonTabBarInner >
255289 ) ;
0 commit comments