diff --git a/src/__tests__/NavigationStateUtils-test.js b/src/__tests__/NavigationStateUtils-test.js index e7347d3..1c36c56 100644 --- a/src/__tests__/NavigationStateUtils-test.js +++ b/src/__tests__/NavigationStateUtils-test.js @@ -8,7 +8,6 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.get(state, 'a')).toEqual({ key: 'a', @@ -21,7 +20,6 @@ describe('StateUtils', () => { const state = { index: 1, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.indexOf(state, 'a')).toBe(0); expect(NavigationStateUtils.indexOf(state, 'b')).toBe(1); @@ -32,7 +30,6 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.has(state, 'b')).toBe(true); expect(NavigationStateUtils.has(state, 'c')).toBe(false); @@ -43,11 +40,10 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }], - isTransitioning: false, }; const newState = { index: 1, - isTransitioning: false, + routes: [{ key: 'a', routeName }, { key: 'b', routeName }], }; expect(NavigationStateUtils.push(state, { key: 'b', routeName })).toEqual( @@ -59,7 +55,6 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }], - isTransitioning: false, }; expect(() => NavigationStateUtils.push(state, { key: 'a', routeName }) @@ -71,12 +66,10 @@ describe('StateUtils', () => { const state = { index: 1, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 0, routes: [{ key: 'a', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.pop(state)).toEqual(newState); }); @@ -85,7 +78,6 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.pop(state)).toBe(state); }); @@ -95,12 +87,10 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 1, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.jumpToIndex(state, 0)).toBe(state); expect(NavigationStateUtils.jumpToIndex(state, 1)).toEqual(newState); @@ -110,7 +100,6 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect(() => NavigationStateUtils.jumpToIndex(state, 2)).toThrow( 'invalid index 2 to jump to' @@ -121,12 +110,10 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 1, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.jumpTo(state, 'a')).toBe(state); expect(NavigationStateUtils.jumpTo(state, 'b')).toEqual(newState); @@ -136,7 +123,6 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect(() => NavigationStateUtils.jumpTo(state, 'c')).toThrow( 'invalid index -1 to jump to' @@ -147,12 +133,10 @@ describe('StateUtils', () => { const state = { index: 1, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.back(state)).toEqual(newState); expect(NavigationStateUtils.back(newState)).toBe(newState); @@ -162,12 +146,10 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 1, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect(NavigationStateUtils.forward(state)).toEqual(newState); expect(NavigationStateUtils.forward(newState)).toBe(newState); @@ -178,12 +160,10 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 1, routes: [{ key: 'a', routeName }, { key: 'c', routeName }], - isTransitioning: false, }; expect( NavigationStateUtils.replaceAt(state, 'b', { key: 'c', routeName }) @@ -194,12 +174,10 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 1, routes: [{ key: 'a', routeName }, { key: 'c', routeName }], - isTransitioning: false, }; expect( NavigationStateUtils.replaceAtIndex(state, 1, { key: 'c', routeName }) @@ -210,7 +188,6 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; expect( NavigationStateUtils.replaceAtIndex(state, 1, state.routes[1]) @@ -222,12 +199,10 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 1, routes: [{ key: 'x', routeName }, { key: 'y', routeName }], - isTransitioning: false, }; expect( NavigationStateUtils.reset(state, [ @@ -245,12 +220,10 @@ describe('StateUtils', () => { const state = { index: 0, routes: [{ key: 'a', routeName }, { key: 'b', routeName }], - isTransitioning: false, }; const newState = { index: 0, routes: [{ key: 'x', routeName }, { key: 'y', routeName }], - isTransitioning: false, }; expect( NavigationStateUtils.reset( diff --git a/src/__tests__/getChildEventSubscriber-test.js b/src/__tests__/getChildEventSubscriber-test.js index 31028b8..00e8313 100644 --- a/src/__tests__/getChildEventSubscriber-test.js +++ b/src/__tests__/getChildEventSubscriber-test.js @@ -18,7 +18,6 @@ it('child action events only flow when focused', () => { routeName: 'FooRoute', routes: [{ key: 'key0' }, { key: 'key1' }], index: 0, - isTransitioning: false, }; const focusedTestState = { ...testState, @@ -76,20 +75,21 @@ it('grandchildren subscription', () => { key: 'parent', routes: [{ key: 'key0' }, { key: 'key1' }], index: 1, - isTransitioning: false, }, ], + transitions: { + pushing: [], + popping: ['parent'], + }, index: 0, - isTransitioning: false, }; const parentTransitionState = { ...parentBlurState, index: 1, - isTransitioning: true, + transitions: { pushing: ['key1'], popping: [] }, }; const parentFocusState = { ...parentTransitionState, - isTransitioning: false, }; const childActionHandler = jest.fn(); const childWillFocusHandler = jest.fn(); @@ -136,13 +136,16 @@ it('grandchildren transitions', () => { .addListener; const makeFakeState = (childIndex, childIsTransitioning) => ({ index: 1, - isTransitioning: false, + routes: [ { key: 'nothing' }, { key: 'parent', index: childIndex, - isTransitioning: childIsTransitioning, + transitions: { + pushing: [], + popping: childIsTransitioning ? ['key2'] : [], + }, routes: [{ key: 'key0' }, { key: 'key1' }, { key: 'key2' }], }, ], @@ -229,13 +232,16 @@ it('grandchildren pass through transitions', () => { .addListener; const makeFakeState = (childIndex, childIsTransitioning) => ({ index: childIndex, - isTransitioning: childIsTransitioning, + transitions: { + pushing: [], + popping: childIsTransitioning ? ['key2'] : [], + }, routes: [ { key: 'nothing' }, { key: 'parent', index: 1, - isTransitioning: false, + routes: [{ key: 'key0' }, { key: 'key1' }, { key: 'key2' }], }, ].slice(0, childIndex + 1), @@ -322,7 +328,6 @@ it('child focus with transition', () => { routeName: 'FooRoute', routes: [{ key: 'key0' }, { key: 'key1' }], index: 0, - isTransitioning: false, }; const childWillFocusHandler = jest.fn(); const childDidFocusHandler = jest.fn(); @@ -345,7 +350,7 @@ it('child focus with transition', () => { state: { ...testState, index: 1, - isTransitioning: true, + transitions: { pushing: [], popping: ['key1'] }, }, }); expect(childWillFocusHandler.mock.calls.length).toBe(1); @@ -355,12 +360,11 @@ it('child focus with transition', () => { lastState: { ...testState, index: 1, - isTransitioning: true, + transitions: { pushing: [], popping: ['key1'] }, }, state: { ...testState, index: 1, - isTransitioning: false, }, }); expect(childDidFocusHandler.mock.calls.length).toBe(1); @@ -370,12 +374,11 @@ it('child focus with transition', () => { lastState: { ...testState, index: 1, - isTransitioning: false, }, state: { ...testState, index: 0, - isTransitioning: true, + transitions: { pushing: [], popping: ['key1'] }, }, }); expect(childWillBlurHandler.mock.calls.length).toBe(1); @@ -385,12 +388,11 @@ it('child focus with transition', () => { lastState: { ...testState, index: 0, - isTransitioning: true, + transitions: { pushing: [], popping: ['key1'] }, }, state: { ...testState, index: 0, - isTransitioning: false, }, }); expect(childDidBlurHandler.mock.calls.length).toBe(1); @@ -415,7 +417,6 @@ it('child focus with immediate transition', () => { routeName: 'FooRoute', routes: [{ key: 'key0' }, { key: 'key1' }], index: 0, - isTransitioning: false, }; const childWillFocusHandler = jest.fn(); const childDidFocusHandler = jest.fn(); @@ -491,12 +492,11 @@ it('immediate back with uncompleted transition will focus first screen again', ( state: { index: 1, routes: [{ key: 'key0' }, { key: 'key1' }], - isTransitioning: true, + transitions: { pushing: [], popping: ['key1'] }, }, lastState: { index: 0, routes: [{ key: 'key0' }], - isTransitioning: false, }, action: { type: 'Any action, does not matter here' }, }); @@ -509,12 +509,12 @@ it('immediate back with uncompleted transition will focus first screen again', ( state: { index: 0, routes: [{ key: 'key0' }], - isTransitioning: true, + transitions: { pushing: [], popping: ['key0'] }, }, lastState: { index: 1, routes: [{ key: 'key0' }, { key: 'key1' }], - isTransitioning: true, + transitions: { pushing: [], popping: ['key1'] }, }, action: { type: 'Any action, does not matter here' }, }); @@ -527,12 +527,11 @@ it('immediate back with uncompleted transition will focus first screen again', ( state: { index: 0, routes: [{ key: 'key0' }], - isTransitioning: false, }, lastState: { index: 0, routes: [{ key: 'key0' }], - isTransitioning: true, + transitions: { pushing: [], popping: ['key0'] }, }, action: { type: 'Any action, does not matter here' }, }); diff --git a/src/getChildEventSubscriber.js b/src/getChildEventSubscriber.js index fb04195..b8b7f11 100644 --- a/src/getChildEventSubscriber.js +++ b/src/getChildEventSubscriber.js @@ -98,7 +98,10 @@ export default function getChildEventSubscriber( action, type: eventName, }; - const isTransitioning = !!state && state.isTransitioning; + const isTransitioning = + !!state && + state.transitions && + (state.transitions.pushing.length || state.transitions.popping.length); const previouslylastFocusEvent = lastFocusEvent; diff --git a/src/getChildrenNavigationCache.js b/src/getChildrenNavigationCache.js index 9143dda..255735e 100644 --- a/src/getChildrenNavigationCache.js +++ b/src/getChildrenNavigationCache.js @@ -7,7 +7,7 @@ export default function getChildrenNavigationCache(navigation) { navigation._childrenNavigation || (navigation._childrenNavigation = {}); let childKeys = navigation.state.routes.map(route => route.key); Object.keys(childrenNavigationCache).forEach(cacheKey => { - if (!childKeys.includes(cacheKey) && !navigation.state.isTransitioning) { + if (!childKeys.includes(cacheKey)) { delete childrenNavigationCache[cacheKey]; } }); diff --git a/src/routers/StackRouter.js b/src/routers/StackRouter.js index 81f6a3d..6f63315 100644 --- a/src/routers/StackRouter.js +++ b/src/routers/StackRouter.js @@ -69,8 +69,11 @@ export default (routeConfigs, stackConfig = {}) => { return { key: 'StackRouterRoot', - isTransitioning: false, index: 0, + transitions: { + pushing: [], + popping: [], + }, routes: [ { params: action.params, @@ -108,7 +111,10 @@ export default (routeConfigs, stackConfig = {}) => { }; return { key: 'StackRouterRoot', - isTransitioning: false, + transitions: { + pushing: [], + popping: [], + }, index: 0, routes: [route], }; @@ -254,10 +260,17 @@ export default (routeConfigs, stackConfig = {}) => { ); return { ...newState, - isTransitioning: - state.index !== newState.index - ? action.immediate !== true - : state.isTransitioning, + transitions: + state.index !== newState.index && action.immediate !== true + ? { + // Figure out which routes should transition + pushing: [], + popping: [], + } + : { + pushing: [], + popping: [], + }, }; } } @@ -297,10 +310,10 @@ export default (routeConfigs, stackConfig = {}) => { // Remove the now unused routes at the tail of the routes array const routes = state.routes.slice(0, lastRouteIndex + 1); + const route = state.routes[lastRouteIndex]; // Apply params if provided, otherwise leave route identity intact if (action.params) { - const route = state.routes[lastRouteIndex]; routes[lastRouteIndex] = { ...route, params: { @@ -309,13 +322,17 @@ export default (routeConfigs, stackConfig = {}) => { }, }; } - // Return state with new index. Change isTransitioning only if index has changed + return { ...state, - isTransitioning: - state.index !== lastRouteIndex - ? action.immediate !== true - : state.isTransitioning, + transitions: { + ...state.transitions, + pushing: + // Return state with new index. Change transitioning routes only if index has changed + state.index !== lastRouteIndex && action.immediate !== true + ? [...state.transitions.pushing, route.key] + : state.transitions.pushing, + }, index: lastRouteIndex, routes, }; @@ -347,7 +364,13 @@ export default (routeConfigs, stackConfig = {}) => { } return { ...StateUtils.push(state, route), - isTransitioning: action.immediate !== true, + transitions: { + ...state.transitions, + pushing: + action.immediate !== true + ? [...state.transitions.pushing, route.key] + : state.transitions.pushing, + }, }; } else if ( action.type === StackActions.PUSH && @@ -389,7 +412,13 @@ export default (routeConfigs, stackConfig = {}) => { }; return { ...StateUtils.push(state, route), - isTransitioning: action.immediate !== true, + transitions: { + ...state.transitions, + pushing: + action.immediate !== true + ? [...state.transitions.pushing, route.key] + : state.transitions.pushing, + }, }; } } @@ -409,7 +438,16 @@ export default (routeConfigs, stackConfig = {}) => { if (state.index > 0) { return { ...state, - isTransitioning: action.immediate !== true, + transitions: { + ...state.transitions, + popping: + action.immediate !== true && state.routes.length > 1 + ? [ + ...state.transitions.popping, + state.routes[state.routes.length - 1].key, + ] + : state.transitions.popping, + }, index: 0, routes: [state.routes[0]], }; @@ -456,12 +494,20 @@ export default (routeConfigs, stackConfig = {}) => { if ( action.type === StackActions.COMPLETE_TRANSITION && (action.key == null || action.key === state.key) && - action.toChildKey === state.routes[state.index].key && - state.isTransitioning + (state.transitions.pushing.length || state.transitions.popping.length) ) { + const { pushing, popping } = state.transitions; + return { ...state, - isTransitioning: false, + transitions: { + pushing: action.toChildKey + ? pushing.filter(key => key !== action.toChildKey) + : [], + popping: action.toChildKey + ? popping.filter(key => key !== action.toChildKey) + : [], + }, }; } @@ -533,14 +579,18 @@ export default (routeConfigs, stackConfig = {}) => { action.type === StackActions.POP ) { const { key, n, immediate } = action; + let backRoute; let backRouteIndex = state.index; if (action.type === StackActions.POP && n != null) { // determine the index to go back *from*. In this case, n=1 means to go // back from state.index, as if it were a normal "BACK" action backRouteIndex = Math.max(1, state.index - n + 1); + backRoute = state.routes[state.index]; } else if (key) { - const backRoute = state.routes.find(route => route.key === key); + backRoute = state.routes.find(route => route.key === key); backRouteIndex = state.routes.indexOf(backRoute); + } else { + backRoute = state.routes[state.index]; } if (backRouteIndex > 0) { @@ -548,7 +598,13 @@ export default (routeConfigs, stackConfig = {}) => { ...state, routes: state.routes.slice(0, backRouteIndex), index: backRouteIndex - 1, - isTransitioning: immediate !== true, + transitions: { + ...state.transitions, + popping: + immediate !== true && backRoute + ? [...state.transitions.popping, backRoute.key] + : state.transitions.popping, + }, }; } } diff --git a/src/routers/SwitchRouter.js b/src/routers/SwitchRouter.js index 2df009a..2902378 100644 --- a/src/routers/SwitchRouter.js +++ b/src/routers/SwitchRouter.js @@ -123,7 +123,6 @@ export default (routeConfigs, config = {}) => { const initialState = { routes, index: initialRouteIndex, - isTransitioning: false, }; if (backBehavior === 'history') { const initialKey = routes[initialRouteIndex].key; diff --git a/src/routers/__tests__/Routers-test.js b/src/routers/__tests__/Routers-test.js index 9a86bc3..7f7d295 100644 --- a/src/routers/__tests__/Routers-test.js +++ b/src/routers/__tests__/Routers-test.js @@ -231,7 +231,7 @@ it('Handles deep action', () => { const state1 = TestRouter.getStateForAction({ type: NavigationActions.INIT }); const expectedState = { index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { @@ -431,13 +431,13 @@ it('Inner actions are only unpacked if the current tab matches', () => { const screenApreState = { index: 0, key: 'Init', - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routeName: 'Foo', routes: [{ key: 'Init', routeName: 'Bar' }], }; const preState = { index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routes: [screenApreState], }; diff --git a/src/routers/__tests__/StackRouter-test.js b/src/routers/__tests__/StackRouter-test.js index d3a9647..905c3a5 100644 --- a/src/routers/__tests__/StackRouter-test.js +++ b/src/routers/__tests__/StackRouter-test.js @@ -91,7 +91,7 @@ describe('StackRouter', () => { expect( router.getComponentForState({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routes: [ { key: 'a', routeName: 'foo' }, { key: 'b', routeName: 'bar' }, @@ -102,7 +102,7 @@ describe('StackRouter', () => { expect( router.getComponentForState({ index: 1, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routes: [ { key: 'a', routeName: 'foo' }, { key: 'b', routeName: 'bar' }, @@ -126,7 +126,7 @@ describe('StackRouter', () => { expect( router.getComponentForState({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routes: [ { key: 'a', routeName: 'foo' }, { key: 'b', routeName: 'bar' }, @@ -137,7 +137,7 @@ describe('StackRouter', () => { expect( router.getComponentForState({ index: 1, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routes: [ { key: 'a', routeName: 'foo' }, { key: 'b', routeName: 'bar' }, @@ -365,7 +365,7 @@ describe('StackRouter', () => { const initState = TestRouter.getStateForAction(NavigationActions.init()); expect(initState).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [{ key: 'id-0', routeName: 'foo' }], }); @@ -443,13 +443,13 @@ describe('StackRouter', () => { const state2 = TestStackRouter.getStateForAction(action); expect(state2).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { index: 0, key: 'id-1', - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routeName: 'foo', params: { fooThing: '22', @@ -534,7 +534,7 @@ describe('StackRouter', () => { const state = { index: 3, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routes: [ { key: 'A', routeName: 'foo' }, { key: 'B', routeName: 'bar', params: { bazId: '321' } }, @@ -545,7 +545,7 @@ describe('StackRouter', () => { const poppedState = TestRouter.getStateForAction(StackActions.pop(), state); expect(poppedState.routes.length).toBe(3); expect(poppedState.index).toBe(2); - expect(poppedState.isTransitioning).toBe(true); + expect(poppedState.transitions).toEqual({ pushing: [], popping: ['D'] }); const poppedState2 = TestRouter.getStateForAction( StackActions.pop({ n: 2, immediate: true }), @@ -553,7 +553,7 @@ describe('StackRouter', () => { ); expect(poppedState2.routes.length).toBe(2); expect(poppedState2.index).toBe(1); - expect(poppedState2.isTransitioning).toBe(false); + expect(poppedState2.transitions).toEqual({ pushing: [], popping: [] }); const poppedState3 = TestRouter.getStateForAction( StackActions.pop({ n: 5 }), @@ -561,7 +561,7 @@ describe('StackRouter', () => { ); expect(poppedState3.routes.length).toBe(1); expect(poppedState3.index).toBe(0); - expect(poppedState3.isTransitioning).toBe(true); + expect(poppedState3.transitions).toEqual({ pushing: [], popping: ['D'] }); }); it('popToTop works as expected', () => { @@ -572,7 +572,7 @@ describe('StackRouter', () => { const state = { index: 2, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routes: [ { key: 'A', routeName: 'foo' }, { key: 'B', routeName: 'bar', params: { bazId: '321' } }, @@ -585,7 +585,7 @@ describe('StackRouter', () => { ); expect(poppedState.routes.length).toBe(1); expect(poppedState.index).toBe(0); - expect(poppedState.isTransitioning).toBe(true); + expect(poppedState.transitions).toEqual({ popping: ['C'], pushing: [] }); const poppedState2 = TestRouter.getStateForAction( StackActions.popToTop(), poppedState @@ -597,7 +597,10 @@ describe('StackRouter', () => { ); expect(poppedImmediatelyState.routes.length).toBe(1); expect(poppedImmediatelyState.index).toBe(0); - expect(poppedImmediatelyState.isTransitioning).toBe(false); + expect(poppedImmediatelyState.transitions).toEqual({ + pushing: [], + popping: [], + }); }); it('Navigate does not push duplicate routeName', () => { @@ -700,7 +703,7 @@ describe('StackRouter', () => { state ); - expect(state2.isTransitioning).toEqual(true); + expect(state2.transitions).toEqual({ popping: [], pushing: ['id-5'] }); expect(state2.index).toEqual(1); expect(state2.routes[1].index).toEqual(1); expect(state2.routes[1].routes[1].index).toEqual(1); @@ -889,7 +892,7 @@ describe('StackRouter', () => { const state = router.getStateForAction({ type: NavigationActions.INIT }); expect(state).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { @@ -917,7 +920,7 @@ describe('StackRouter', () => { ); expect(state3).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { @@ -1055,7 +1058,10 @@ describe('StackRouter', () => { state ); expect(state2 && state2.index).toEqual(1); - expect(state2 && state2.isTransitioning).toEqual(true); + expect(state2 && state2.transitions).toEqual({ + popping: [], + pushing: ['id-1'], + }); const state3 = router.getStateForAction( { type: StackActions.COMPLETE_TRANSITION, @@ -1064,7 +1070,7 @@ describe('StackRouter', () => { state2 ); expect(state3 && state3.index).toEqual(1); - expect(state3 && state3.isTransitioning).toEqual(false); + expect(state3 && state3.transitions).toEqual({ pushing: [], popping: [] }); }); it('Completion action does not work with incorrect key', () => { @@ -1080,7 +1086,7 @@ describe('StackRouter', () => { const state = { key: 'StackKey', index: 1, - isTransitioning: true, + transitions: { pushing: ['b'], popping: [] }, routes: [{ key: 'a', routeName: 'Foo' }, { key: 'b', routeName: 'Foo' }], }; const outputState = router.getStateForAction( @@ -1091,7 +1097,7 @@ describe('StackRouter', () => { }, state ); - expect(outputState.isTransitioning).toEqual(true); + expect(outputState.transitions).toEqual({ pushing: ['b'], popping: [] }); }); it('Completion action does not work with incorrect toChildKey', () => { @@ -1107,19 +1113,19 @@ describe('StackRouter', () => { const state = { key: 'StackKey', index: 1, - isTransitioning: true, + transitions: { pushing: ['b'], popping: [] }, routes: [{ key: 'a', routeName: 'Foo' }, { key: 'b', routeName: 'Foo' }], }; const outputState = router.getStateForAction( { type: StackActions.COMPLETE_TRANSITION, - // for this action to toggle isTransitioning, toChildKey should be state.routes[state.index].key, + // for this action to toggle transitions, toChildKey should be state.routes[state.index].key, toChildKey: 'incorrect', key: 'StackKey', }, state ); - expect(outputState.isTransitioning).toEqual(true); + expect(outputState.transitions).toEqual({ pushing: ['b'], popping: [] }); }); it('Back action parent is prioritized over inactive child routers', () => { @@ -1150,6 +1156,7 @@ describe('StackRouter', () => { { routeName: 'foo', key: 'f1' }, { routeName: 'boo', key: 'z' }, ], + transitions: { pushing: [], popping: [] }, }; const testState = TestRouter.getStateForAction( { type: NavigationActions.BACK }, @@ -1178,7 +1185,7 @@ describe('StackRouter', () => { const state = router.getStateForAction({ type: NavigationActions.INIT }); expect(state).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { @@ -1206,7 +1213,7 @@ describe('StackRouter', () => { ); expect(state3).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { @@ -1236,7 +1243,7 @@ describe('StackRouter', () => { const state = { index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, routes: [ { index: 1, @@ -1321,7 +1328,7 @@ describe('StackRouter', () => { const state = router.getStateForAction({ type: NavigationActions.INIT }); expect(state).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { @@ -1345,7 +1352,7 @@ describe('StackRouter', () => { const state = router.getStateForAction({ type: NavigationActions.INIT }); expect(state).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { @@ -1371,7 +1378,7 @@ describe('StackRouter', () => { const state = router.getStateForAction({ type: NavigationActions.INIT }); expect(state).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { @@ -1723,7 +1730,7 @@ describe('StackRouter', () => { ]); }); - it('Navigate action to previous nested StackRouter causes isTransitioning start', () => { + it('Navigate action to previous nested StackRouter causes no transitions', () => { const ChildNavigator = () =>
; ChildNavigator.router = StackRouter({ Baz: { screen: () => }, @@ -1740,6 +1747,7 @@ describe('StackRouter', () => { }, router.getStateForAction({ type: NavigationActions.INIT }) ); + const state2 = router.getStateForAction( { type: NavigationActions.NAVIGATE, @@ -1747,8 +1755,9 @@ describe('StackRouter', () => { }, state ); + expect(state2.index).toEqual(0); - expect(state2.isTransitioning).toEqual(true); + expect(state2.transitions).toEqual({ pushing: [], popping: [] }); }); it('Handles the navigate action with params and nested StackRouter as a first action', () => { @@ -1781,19 +1790,19 @@ describe('StackRouter', () => { expect(state).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'id-2', params: { code: 'test', foo: 'bar' }, routeName: 'main', routes: [ { index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'id-1', params: { code: 'test', foo: 'bar', id: '4' }, routeName: 'profile', @@ -1840,19 +1849,19 @@ describe('StackRouter', () => { expect(state2).toEqual({ index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'StackRouterRoot', routes: [ { index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'id-5', params: { code: '', foo: 'bar' }, routeName: 'main', routes: [ { index: 0, - isTransitioning: false, + transitions: { pushing: [], popping: [] }, key: 'id-4', params: { code: '', foo: 'bar', id: '4' }, routeName: 'profile', @@ -1899,9 +1908,12 @@ describe('StackRouter', () => { state ); expect(state2.index).toEqual(0); - expect(state2.isTransitioning).toEqual(false); + expect(state2.transitions).toEqual({ pushing: [], popping: [] }); expect(state2.routes[0].index).toEqual(1); - expect(state2.routes[0].isTransitioning).toEqual(true); + expect(state2.routes[0].transitions).toEqual({ + popping: [], + pushing: ['id-2'], + }); expect(!!key).toEqual(true); const state3 = router.getStateForAction( { @@ -1911,9 +1923,12 @@ describe('StackRouter', () => { state2 ); expect(state3 && state3.index).toEqual(0); - expect(state3 && state3.isTransitioning).toEqual(false); + expect(state3 && state3.transitions).toEqual({ popping: [], pushing: [] }); expect(state3 && state3.routes[0].index).toEqual(1); - expect(state3 && state3.routes[0].isTransitioning).toEqual(false); + expect(state3 && state3.routes[0].transitions).toEqual({ + popping: [], + pushing: [], + }); }); it('order of handling navigate action is correct for nested stackrouters', () => { diff --git a/src/routers/__tests__/TabRouter-test.js b/src/routers/__tests__/TabRouter-test.js index 23fef29..fcdd195 100644 --- a/src/routers/__tests__/TabRouter-test.js +++ b/src/routers/__tests__/TabRouter-test.js @@ -26,7 +26,6 @@ describe('TabRouter', () => { { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }, ], - isTransitioning: false, }; expect(state).toEqual(expectedState); const state2 = router.getStateForAction( @@ -39,7 +38,6 @@ describe('TabRouter', () => { { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }, ], - isTransitioning: false, }; expect(state2).toEqual(expectedState2); expect(router.getComponentForState(expectedState)).toEqual(ScreenA); @@ -65,7 +63,6 @@ describe('TabRouter', () => { { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }, ], - isTransitioning: false, }; expect(state).toEqual(expectedState); const state2 = router.getStateForAction( @@ -78,7 +75,6 @@ describe('TabRouter', () => { { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }, ], - isTransitioning: false, }; expect(state2).toEqual(expectedState2); expect(router.getComponentForState(expectedState)).toEqual(ScreenA); @@ -102,7 +98,6 @@ describe('TabRouter', () => { { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }, ], - isTransitioning: false, }); }); @@ -118,7 +113,6 @@ describe('TabRouter', () => { { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar', params: { name: 'Qux' } }, ], - isTransitioning: false, }); }); @@ -230,7 +224,7 @@ describe('TabRouter', () => { const state = router.getStateForAction(navAction); expect(state).toEqual({ index: 1, - isTransitioning: false, + routes: [ { key: 'Foo', @@ -238,7 +232,7 @@ describe('TabRouter', () => { }, { index: 1, - isTransitioning: false, + key: 'Baz', routeName: 'Baz', params: { foo: '42' }, @@ -281,14 +275,14 @@ describe('TabRouter', () => { let state = router.getStateForAction(navAction); expect(state).toEqual({ index: 1, - isTransitioning: false, + routes: [ { key: 'Foo', routeName: 'Foo' }, { index: 0, key: 'Baz', routeName: 'Baz', - isTransitioning: false, + routes: [ { key: 'Boo', routeName: 'Boo' }, { key: 'Bar', routeName: 'Bar' }, @@ -308,7 +302,7 @@ describe('TabRouter', () => { ); expect(state && state.routes[1]).toEqual({ index: 0, - isTransitioning: false, + key: 'Baz', routeName: 'Baz', routes: [ @@ -335,14 +329,14 @@ describe('TabRouter', () => { }); expect(state).toEqual({ index: 1, - isTransitioning: false, + routes: [ { key: 'Foo', routeName: 'Foo' }, { index: 1, key: 'Baz', routeName: 'Baz', - isTransitioning: false, + routes: [ { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }, @@ -357,14 +351,14 @@ describe('TabRouter', () => { ); expect(state2).toEqual({ index: 1, - isTransitioning: false, + routes: [ { key: 'Foo', routeName: 'Foo' }, { index: 0, key: 'Baz', routeName: 'Baz', - isTransitioning: false, + routes: [ { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }, @@ -403,19 +397,19 @@ describe('TabRouter', () => { const state = router.getStateForAction(INIT_ACTION); expect(state).toEqual({ index: 0, - isTransitioning: false, + routes: [ { index: 0, key: 'Foo', routeName: 'Foo', - isTransitioning: false, + routes: [ { index: 0, key: 'Fee', routeName: 'Fee', - isTransitioning: false, + routes: [ { key: 'Boo', routeName: 'Boo' }, { key: 'Baz', routeName: 'Baz' }, @@ -425,7 +419,7 @@ describe('TabRouter', () => { index: 0, key: 'Bar', routeName: 'Bar', - isTransitioning: false, + routes: [ { key: 'Zoo', routeName: 'Zoo' }, { key: 'Zap', routeName: 'Zap' }, @@ -442,19 +436,19 @@ describe('TabRouter', () => { ); expect(state2).toEqual({ index: 0, - isTransitioning: false, + routes: [ { index: 1, key: 'Foo', routeName: 'Foo', - isTransitioning: false, + routes: [ { index: 0, key: 'Fee', routeName: 'Fee', - isTransitioning: false, + routes: [ { key: 'Boo', routeName: 'Boo' }, { key: 'Baz', routeName: 'Baz' }, @@ -464,7 +458,7 @@ describe('TabRouter', () => { index: 1, key: 'Bar', routeName: 'Bar', - isTransitioning: false, + routes: [ { key: 'Zoo', routeName: 'Zoo' }, { key: 'Zap', routeName: 'Zap' }, @@ -494,19 +488,19 @@ describe('TabRouter', () => { }); expect(state4).toEqual({ index: 0, - isTransitioning: false, + routes: [ { index: 1, key: 'Foo', routeName: 'Foo', - isTransitioning: false, + routes: [ { index: 0, key: 'Fee', routeName: 'Fee', - isTransitioning: false, + routes: [ { key: 'Boo', routeName: 'Boo' }, { key: 'Baz', routeName: 'Baz' }, @@ -516,7 +510,7 @@ describe('TabRouter', () => { index: 1, key: 'Bar', routeName: 'Bar', - isTransitioning: false, + routes: [ { key: 'Zoo', routeName: 'Zoo' }, { key: 'Zap', routeName: 'Zap' }, @@ -557,7 +551,7 @@ describe('TabRouter', () => { const state = router.getStateForAction({ type: NavigationActions.INIT }); const expectedState = { index: 0, - isTransitioning: false, + routes: [ { key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }, @@ -567,7 +561,7 @@ describe('TabRouter', () => { const state2 = router.getStateForAction(expectedAction, state); const expectedState2 = { index: 1, - isTransitioning: false, + routes: [ { key: 'Foo', routeName: 'Foo', params: undefined }, { @@ -628,13 +622,13 @@ describe('TabRouter', () => { const state = { index: 0, - isTransitioning: false, + routes: [ { index: 1, key: 'Foo', routeName: 'Foo', - isTransitioning: false, + routes: [ { key: 'Boo', routeName: 'Boo' }, { key: 'Baz', routeName: 'Baz' }, @@ -660,7 +654,7 @@ describe('TabRouter', () => { expect(state0).toEqual({ index: 0, - isTransitioning: false, + routes: [{ key: 'a', routeName: 'a' }, { key: 'b', routeName: 'b' }], }); @@ -673,7 +667,7 @@ describe('TabRouter', () => { expect(state1).toEqual({ index: 1, - isTransitioning: false, + routes: [ { key: 'a', routeName: 'a' }, { key: 'b', routeName: 'b', params }, @@ -762,13 +756,13 @@ describe('TabRouter', () => { const screenApreState = { index: 0, key: 'Foo', - isTransitioning: false, + routeName: 'Foo', routes: [{ key: 'Bar', routeName: 'Bar' }], }; const preState = { index: 0, - isTransitioning: false, + routes: [screenApreState], };