mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 09:34:19 +08:00
fix(react): fixes swipe to go back regression (#21791)
This commit is contained in:
@ -39,9 +39,11 @@ class IonRouterInner extends React.PureComponent<IonRouteProps, IonRouteState> {
|
||||
locationHistory = new LocationHistory();
|
||||
viewStack = new ReactRouterViewStack();
|
||||
routeMangerContextState: RouteManagerContextState = {
|
||||
canGoBack: () => this.locationHistory.canGoBack(),
|
||||
clearOutlet: this.viewStack.clear,
|
||||
getViewItemForTransition: this.viewStack.getViewItemForTransition,
|
||||
getChildrenToRender: this.viewStack.getChildrenToRender,
|
||||
goBack: () => this.handleNavigateBack(),
|
||||
createViewItem: this.viewStack.createViewItem,
|
||||
findViewItemByRouteInfo: this.viewStack.findViewItemByRouteInfo,
|
||||
findLeavingViewItemByRouteInfo: this.viewStack.findLeavingViewItemByRouteInfo,
|
||||
|
@ -4,7 +4,8 @@ import {
|
||||
StackContext,
|
||||
StackContextState,
|
||||
ViewItem,
|
||||
generateId
|
||||
generateId,
|
||||
getConfig
|
||||
} from '@ionic/react';
|
||||
import React from 'react';
|
||||
import { matchPath } from 'react-router-dom';
|
||||
@ -38,6 +39,7 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
|
||||
componentDidMount() {
|
||||
if (this.routerOutletElement) {
|
||||
this.setupRouterOutlet(this.routerOutletElement);
|
||||
// console.log(`SM Mount - ${this.routerOutletElement.id} (${this.id})`);
|
||||
this.handlePageTransition(this.props.routeInfo);
|
||||
}
|
||||
@ -111,6 +113,28 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
this.handlePageTransition(routeInfo);
|
||||
}
|
||||
|
||||
async setupRouterOutlet(routerOutlet: HTMLIonRouterOutletElement) {
|
||||
|
||||
const canStart = () => {
|
||||
const config = getConfig();
|
||||
const swipeEnabled = config && config.get('swipeBackEnabled', routerOutlet.mode === 'ios');
|
||||
if (swipeEnabled) {
|
||||
return this.context.canGoBack();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const onStart = () => {
|
||||
this.context.goBack();
|
||||
};
|
||||
routerOutlet.swipeHandler = {
|
||||
canStart,
|
||||
onStart,
|
||||
onEnd: _shouldContinue => true
|
||||
};
|
||||
}
|
||||
|
||||
async transitionPage(routeInfo: RouteInfo, enteringViewItem: ViewItem, leavingViewItem?: ViewItem) {
|
||||
|
||||
const routerOutlet = this.routerOutletElement!;
|
||||
|
@ -4,7 +4,7 @@ This spec covers that routes can be added and navigated to at runtime.
|
||||
Fixes bug reported in https://github.com/ionic-team/ionic/issues/21329
|
||||
*/
|
||||
|
||||
describe('Dynamic Route Tests', () => {
|
||||
describe('Dynamic Routes', () => {
|
||||
it('/dynamic-routes, when adding a dynamic route, we should be able to navigate to it', () => {
|
||||
cy.visit(`http://localhost:${port}/dynamic-routes`)
|
||||
cy.ionPageVisible('dynamic-routes-home')
|
||||
@ -19,4 +19,4 @@ describe('Dynamic Route Tests', () => {
|
||||
cy.get('a').contains('Take me to the newRoute').click();
|
||||
cy.ionPageVisible('dynamic-routes-failed')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
const port = 3000;
|
||||
|
||||
describe('Multiple Tabs', () => {
|
||||
describe('IonRouterOutlet Ref', () => {
|
||||
/*
|
||||
This spec tests that setting a ref on an IonRouterOutlet works
|
||||
*/
|
||||
|
18
packages/react-router/test-app/cypress/integration/swipe-to-go-back.js
vendored
Normal file
18
packages/react-router/test-app/cypress/integration/swipe-to-go-back.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
const port = 3000;
|
||||
|
||||
describe('Swipe To Go Back', () => {
|
||||
/*
|
||||
This spec tests that swipe to go back works
|
||||
*/
|
||||
|
||||
it('/swipe-to-go-back, ', () => {
|
||||
cy.visit(`http://localhost:${port}/swipe-to-go-back`)
|
||||
cy.ionPageVisible('main')
|
||||
cy.ionNav('ion-item', 'Details')
|
||||
cy.ionPageVisible('details')
|
||||
cy.wait(350);
|
||||
cy.ionSwipeRight();
|
||||
cy.ionPageVisible('main')
|
||||
})
|
||||
|
||||
})
|
@ -66,6 +66,14 @@ Cypress.Commands.add('ionNav', (element, contains) => {
|
||||
cy.wait(250);
|
||||
})
|
||||
|
||||
Cypress.Commands.add('ionSwipeRight', (element, contains) => {
|
||||
cy.get('ion-router-outlet')
|
||||
.trigger('mousedown', { position: "left" })
|
||||
.trigger('mousemove', { clientX: 100, clientY: 275 })
|
||||
.trigger('mouseup', { force: true })
|
||||
cy.wait(150);
|
||||
})
|
||||
|
||||
Cypress.Commands.add('ionMenuNav', (contains) => {
|
||||
// cy.get('ion-menu.show-menu').should('exist');
|
||||
// cy.wait(1000)
|
||||
|
@ -34,6 +34,7 @@ import NestedOutlet2 from './pages/nested-outlet/NestedOutlet2';
|
||||
import ReplaceAction from './pages/replace-action/Replace';
|
||||
import TabsContext from './pages/tab-context/TabContext';
|
||||
import { OutletRef } from './pages/outlet-ref/OutletRef';
|
||||
import { SwipeToGoBack } from './pages/swipe-to-go-back/SwipToGoBack';
|
||||
debugger;
|
||||
const App: React.FC = () => {
|
||||
return (
|
||||
@ -49,6 +50,7 @@ const App: React.FC = () => {
|
||||
<Route path="/replace-action" component={ReplaceAction} />
|
||||
<Route path="/tab-context" component={TabsContext} />
|
||||
<Route path="/outlet-ref" component={OutletRef} />
|
||||
<Route path="/swipe-to-go-back" component={SwipeToGoBack} />
|
||||
</IonReactRouter>
|
||||
</IonApp>
|
||||
);
|
||||
|
@ -41,6 +41,9 @@ const Main: React.FC<MainProps> = () => {
|
||||
<IonItem routerLink="/outlet-ref">
|
||||
<IonLabel>Outlet Ref</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem routerLink="/swipe-to-go-back">
|
||||
<IonLabel>Swipe to go back</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
|
@ -22,8 +22,6 @@ export const OutletRef: React.FC<OutletRefProps> = () => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const Main: React.FC<{ outletId?: string; }> = ({ outletId }) => {
|
||||
return (
|
||||
<IonPage data-pageid="main">
|
||||
@ -38,5 +36,3 @@ const Main: React.FC<{ outletId?: string; }> = ({ outletId }) => {
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default Main;
|
||||
|
@ -0,0 +1,53 @@
|
||||
import React from 'react';
|
||||
import { IonRouterOutlet, IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonItem, IonButtons, IonBackButton } from '@ionic/react';
|
||||
import { Route } from 'react-router';
|
||||
|
||||
interface SwipeToGoBackProps {
|
||||
}
|
||||
|
||||
export const SwipeToGoBack: React.FC<SwipeToGoBackProps> = () => {
|
||||
|
||||
|
||||
return (
|
||||
<IonRouterOutlet id="swipe-to-go-back">
|
||||
<Route path="/swipe-to-go-back" component={Main} exact />
|
||||
<Route path="/swipe-to-go-back/details" component={Details} />
|
||||
</IonRouterOutlet>
|
||||
);
|
||||
};
|
||||
|
||||
const Main: React.FC = () => {
|
||||
return (
|
||||
<IonPage data-pageid="main">
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>Main</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent>
|
||||
<IonItem routerLink="/swipe-to-go-back/details">
|
||||
Details
|
||||
</IonItem>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
const Details: React.FC = () => {
|
||||
return (
|
||||
<IonPage data-pageid="details">
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonButtons>
|
||||
<IonBackButton></IonBackButton>
|
||||
</IonButtons>
|
||||
<IonTitle>Details</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent>
|
||||
<div>Details</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
@ -6,24 +6,26 @@ import { ViewItem } from './ViewItem';
|
||||
|
||||
export interface RouteManagerContextState {
|
||||
addViewItem: (viewItem: ViewItem) => void;
|
||||
canGoBack: () => boolean;
|
||||
clearOutlet: (outletId: string) => void;
|
||||
createViewItem: (outletId: string, reactElement: React.ReactElement, routeInfo: RouteInfo, page?: HTMLElement) => ViewItem;
|
||||
findLeavingViewItemByRouteInfo: (routeInfo: RouteInfo, outletId?: string) => ViewItem | undefined;
|
||||
// findViewItemByPathname: (pathname: string, outletId?: string) => ViewItem | undefined;
|
||||
findViewItemByRouteInfo: (routeInfo: RouteInfo, outletId?: string) => ViewItem | undefined;
|
||||
getChildrenToRender: (outletId: string, ionRouterOutlet: React.ReactElement, routeInfo: RouteInfo, reRender: () => void) => React.ReactNode[];
|
||||
getViewItemForTransition: (pathname: string) => ViewItem | undefined;
|
||||
goBack: () => void;
|
||||
unMountViewItem: (viewItem: ViewItem) => void;
|
||||
}
|
||||
|
||||
export const RouteManagerContext = /*@__PURE__*/React.createContext<RouteManagerContextState>({
|
||||
addViewItem: () => undefined,
|
||||
canGoBack: () => undefined as any,
|
||||
clearOutlet: () => undefined,
|
||||
createViewItem: () => undefined as any,
|
||||
findLeavingViewItemByRouteInfo: () => undefined,
|
||||
// findViewItemByPathname: () => undefined,
|
||||
findViewItemByRouteInfo: () => undefined,
|
||||
getChildrenToRender: () => undefined as any,
|
||||
getViewItemForTransition: () => undefined,
|
||||
goBack: () => undefined,
|
||||
unMountViewItem: () => undefined,
|
||||
});
|
||||
|
Reference in New Issue
Block a user