Skip to content

Commit 6b01200

Browse files
committed
fix(react): use as standalone in react
1 parent bbcbf5c commit 6b01200

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

packages/react/src/components/navigation/IonTabBar.tsx

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4152
class 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

Comments
 (0)