Skip to content

Commit

Permalink
fix(vue): tapping the active tab button now correctly resets the tab …
Browse files Browse the repository at this point in the history
…stack (#24935)

resolves #24934
  • Loading branch information
liamdebeasi committed Mar 14, 2022
1 parent d46e1e8 commit 4534c8b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 13 deletions.
31 changes: 27 additions & 4 deletions packages/vue-router/src/locationHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,39 @@ export const createLocationHistory = () => {
* and every entry that appears after it.
*/
const clearHistory = (routeInfo?: RouteInfo) => {
Object.keys(tabsHistory).forEach(key => {
tabsHistory[key] = [];
});

if (routeInfo) {

/**
* If there is no route index in locationHistory
* then there will not be any route index in
* tabs either.
*/
const existingRouteIndex = locationHistory.findIndex(r => r.position === routeInfo.position);
if (existingRouteIndex === -1) return;

locationHistory.splice(existingRouteIndex);

/**
* We also need to search the current tab
* to correctly reset the individual tab
* stack. We should not clear the entire
* tab stack as that means we will lose
* a reference to the root tab route.
*/
const { tab } = routeInfo;
const tabHistory = tabsHistory[tab];
if (tab && tabHistory) {
const existingTabRouteIndex = tabHistory.findIndex(r => r.position === routeInfo.position);
if (existingTabRouteIndex === -1) return;

tabsHistory[tab].splice(existingTabRouteIndex);
}

} else {
Object.keys(tabsHistory).forEach(key => {
tabsHistory[key] = [];
});

locationHistory.length = 0;
}
}
Expand Down
19 changes: 14 additions & 5 deletions packages/vue-router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,13 +409,22 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
router.push(routerLink);
}

const resetTab = (tab: string, originalHref: string) => {
const resetTab = (tab: string) => {
/**
* Resetting the tab should go back
* to the initial view in the tab stack.
* It should not push a new instance of the
* root tab page onto the stack.
*
* To do this, we get the initial view in the
* tab stack and subtract the position of that
* entry from our current position. From there
* we call router.go() to move us back the
* appropriate number of positions.
*/
const routeInfo = locationHistory.getFirstRouteInfoForTab(tab);
if (routeInfo) {
const newRouteInfo = { ...routeInfo };
newRouteInfo.pathname = originalHref;
incomingRouteParams = { ...newRouteInfo, routerAction: 'pop', routerDirection: 'back' };
router.push({ path: newRouteInfo.pathname, query: parseQuery(newRouteInfo.search) });
router.go(routeInfo.position - currentHistoryPosition);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/vue/src/components/IonTabButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const IonTabButton = /*@__PURE__*/ defineComponent({
*/
if (prevActiveTab === tab) {
if (originalHref !== currentHref) {
ionRouter.resetTab(tab, originalHref);
ionRouter.resetTab(tab);
}
} else {
ionRouter.changeTab(tab, currentHref)
Expand Down
53 changes: 50 additions & 3 deletions packages/vue/test-app/tests/e2e/specs/tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,66 @@ describe('Tabs', () => {
cy.ionPageHidden('tab1');
});

it('should return to tab root when clicking tab button', () => {
it('should return to tab root when clicking tab button after going back', () => {
cy.visit('http://localhost:8080/tabs')

cy.get('#child-one').click();
cy.ionPageVisible('tab1childone');
cy.ionPageHidden('tab1');

cy.get('#child-two').click();
cy.ionPageHidden('tab1childone');
cy.ionPageVisible('tab1childtwo');

cy.get('ion-tab-button#tab-button-tab1').click();

cy.ionPageVisible('tab1');

// TODO this page is not removed
//cy.ionPageDoesNotExist('tab1childone');
cy.ionPageDoesNotExist('tab1childone');
cy.ionPageDoesNotExist('tab1childtwo');
})

// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/24934
it('should return to tab root when clicking tab button', () => {
cy.visit('http://localhost:8080/tabs')

cy.get('#child-one').click();
cy.ionPageVisible('tab1childone');
cy.ionPageHidden('tab1');

cy.get('#child-two').click();
cy.ionPageHidden('tab1childone');
cy.ionPageVisible('tab1childtwo');

cy.ionBackClick('tab1childtwo');
cy.ionPageVisible('tab1childone');
cy.ionPageDoesNotExist('tab1childtwo');

cy.get('ion-tab-button#tab-button-tab1').click();

cy.ionPageVisible('tab1');
cy.ionPageDoesNotExist('tab1chilone');
})

// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/24934
it('should return to tab root after replacing history', () => {
cy.visit('http://localhost:8080/tabs')

cy.get('#child-one').click();
cy.ionPageVisible('tab1childone');
cy.ionPageHidden('tab1');

cy.get('ion-tab-button#tab-button-tab1').click();
cy.ionPageVisible('tab1');
cy.ionPageDoesNotExist('tab1chilone');

cy.get('#child-one').click();
cy.ionPageVisible('tab1childone');
cy.ionPageHidden('tab1');

cy.get('ion-tab-button#tab-button-tab1').click();
cy.ionPageVisible('tab1');
cy.ionPageDoesNotExist('tab1chilone');
})

it('should be able to create and destroy tabs', () => {
Expand Down

0 comments on commit 4534c8b

Please sign in to comment.