fix(react): fixes swipe to go back regression (#21791)

This commit is contained in:
Ely Lucas
2020-07-21 22:30:44 -06:00
committed by GitHub
parent 4199762d3e
commit a15cd01bc3
11 changed files with 118 additions and 10 deletions

View File

@ -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,

View File

@ -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!;

View File

@ -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')
})
})
})

View File

@ -1,6 +1,6 @@
const port = 3000;
describe('Multiple Tabs', () => {
describe('IonRouterOutlet Ref', () => {
/*
This spec tests that setting a ref on an IonRouterOutlet works
*/

View 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')
})
})

View File

@ -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)

View File

@ -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>
);

View File

@ -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>

View File

@ -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;

View File

@ -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>
);
};

View File

@ -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,
});