@applicaster/zapp-react-native-ui-components 16.0.0-alpha.1054344748 → 16.0.0-alpha.1108851646
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -66,7 +66,7 @@ export class AnimationManager {
|
|
|
66
66
|
*
|
|
67
67
|
* @param {object} to contains style to animate and scenes index
|
|
68
68
|
* @param {string} action push|back
|
|
69
|
-
* @param {number}
|
|
69
|
+
* @param {number} stepsBack number of steps back
|
|
70
70
|
*/
|
|
71
71
|
stateForAction({ to, scenes }, action, stepsBack) {
|
|
72
72
|
let rootIndex = to.index;
|
|
@@ -17,14 +17,13 @@ const fullWidthDimensions = {
|
|
|
17
17
|
type Props = {
|
|
18
18
|
children: any;
|
|
19
19
|
style: any;
|
|
20
|
-
pointerEvents
|
|
21
|
-
overlayStyle
|
|
22
|
-
animating
|
|
20
|
+
pointerEvents: ViewProps["pointerEvents"];
|
|
21
|
+
overlayStyle: ViewStyle;
|
|
22
|
+
animating: boolean;
|
|
23
23
|
contentStyle: ViewStyle;
|
|
24
24
|
pathname: string;
|
|
25
25
|
isActive: boolean;
|
|
26
26
|
screenData: NavigationScreenData;
|
|
27
|
-
screenUniqueId?: string;
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
export function CurrentScreenContextProvider({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { append, compose, identity, tail, update } from "ramda";
|
|
3
|
+
import { append, compose, identity, tail, take, update } from "ramda";
|
|
4
4
|
|
|
5
5
|
import { AnimationManager } from "./AnimationManager";
|
|
6
6
|
import { Scene } from "./Scene";
|
|
@@ -18,23 +18,11 @@ export const NAV_ACTION_REPLACE = "REPLACE";
|
|
|
18
18
|
|
|
19
19
|
export const NAV_ACTION_BACK = "POP";
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// The screen element rendered for the current route
|
|
29
|
-
type SceneChild = React.ReactElement<{
|
|
30
|
-
pathname: string;
|
|
31
|
-
screenData: NavigationScreenData;
|
|
32
|
-
}>;
|
|
33
|
-
|
|
34
|
-
type TransitionerScene = {
|
|
35
|
-
children: SceneChild;
|
|
36
|
-
key: string;
|
|
37
|
-
screenUniqueId: string;
|
|
21
|
+
type SceneProps = {
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
overlayStyle: any;
|
|
24
|
+
style: any;
|
|
25
|
+
animating: boolean;
|
|
38
26
|
};
|
|
39
27
|
|
|
40
28
|
/**
|
|
@@ -43,7 +31,7 @@ type TransitionerScene = {
|
|
|
43
31
|
* @param {Object} children
|
|
44
32
|
* @returns { children: Object, key: string }
|
|
45
33
|
*/
|
|
46
|
-
function prepareScene(children
|
|
34
|
+
function prepareScene(children) {
|
|
47
35
|
return {
|
|
48
36
|
children,
|
|
49
37
|
key: children.props.pathname,
|
|
@@ -57,10 +45,7 @@ function prepareScene(children: SceneChild): TransitionerScene {
|
|
|
57
45
|
* @param {any} props Component's props
|
|
58
46
|
* @param {any} state Component's state
|
|
59
47
|
*/
|
|
60
|
-
function scenesForBackTransition(
|
|
61
|
-
props: Pick<Props, "children">,
|
|
62
|
-
{ scenes }: Pick<State, "scenes">
|
|
63
|
-
): TransitionerScene[] {
|
|
48
|
+
function scenesForBackTransition(props: SceneProps, { scenes }) {
|
|
64
49
|
return scenes.length > 1
|
|
65
50
|
? identity(scenes)
|
|
66
51
|
: [prepareScene(props.children), scenes[0]];
|
|
@@ -68,8 +53,7 @@ function scenesForBackTransition(
|
|
|
68
53
|
|
|
69
54
|
type Props = {
|
|
70
55
|
transitionConfig: any;
|
|
71
|
-
|
|
72
|
-
children: SceneChild;
|
|
56
|
+
children: React.ReactNode;
|
|
73
57
|
navigator: {
|
|
74
58
|
previousAction: string;
|
|
75
59
|
currentRoute: string;
|
|
@@ -94,12 +78,13 @@ type Props = {
|
|
|
94
78
|
};
|
|
95
79
|
|
|
96
80
|
type State = {
|
|
81
|
+
animatedValue: any;
|
|
97
82
|
animating: boolean;
|
|
98
83
|
duration: number;
|
|
99
84
|
easing: any;
|
|
100
85
|
from: any;
|
|
101
86
|
to: any;
|
|
102
|
-
scenes:
|
|
87
|
+
scenes: any;
|
|
103
88
|
};
|
|
104
89
|
|
|
105
90
|
const styles = {
|
|
@@ -107,18 +92,11 @@ const styles = {
|
|
|
107
92
|
} as const;
|
|
108
93
|
|
|
109
94
|
export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
110
|
-
private animationManager: AnimationManager;
|
|
111
|
-
|
|
112
|
-
private transitionId: number;
|
|
113
|
-
|
|
114
95
|
constructor(props: Props) {
|
|
115
96
|
super(props);
|
|
116
97
|
|
|
117
98
|
this.animationManager = new AnimationManager(props);
|
|
118
99
|
|
|
119
|
-
// Bumped by every animated transition; end callbacks of older ones are ignored
|
|
120
|
-
this.transitionId = 0;
|
|
121
|
-
|
|
122
100
|
this.state = {
|
|
123
101
|
scenes: [prepareScene(props.children)], // starting with index: 0
|
|
124
102
|
...this.animationManager.initialState(),
|
|
@@ -135,36 +113,28 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
135
113
|
* and trigger push animation with callbacks.
|
|
136
114
|
*/
|
|
137
115
|
pushTransitionStart() {
|
|
138
|
-
const transitionId = ++this.transitionId;
|
|
139
|
-
|
|
140
116
|
this.setState(
|
|
141
117
|
{
|
|
142
|
-
|
|
143
|
-
scenes: [
|
|
144
|
-
...this.state.scenes.slice(0, this.state.to.index + 1),
|
|
145
|
-
prepareScene(this.props.children),
|
|
146
|
-
],
|
|
118
|
+
scenes: append(prepareScene(this.props.children), this.state.scenes),
|
|
147
119
|
...this.animationManager.stateForAction(this.state, NAV_ACTION_PUSH),
|
|
148
120
|
},
|
|
149
121
|
() => {
|
|
150
|
-
this.animationManager.animate(this.state,
|
|
151
|
-
this.pushTransitionEnd(transitionId)
|
|
152
|
-
);
|
|
122
|
+
this.animationManager.animate(this.state, this.pushTransitionEnd);
|
|
153
123
|
}
|
|
154
124
|
);
|
|
155
125
|
}
|
|
156
126
|
|
|
157
127
|
/**
|
|
158
128
|
* Trigger back animation.
|
|
159
|
-
* The
|
|
129
|
+
* The last scene in the array is removed in the "backTransitionEnd" callback,
|
|
160
130
|
* only after the animation is complete.
|
|
161
131
|
*/
|
|
162
132
|
backTransitionStart(previousRoute: string) {
|
|
163
|
-
const transitionId = ++this.transitionId;
|
|
164
133
|
const currentRoute = this.props.navigator?.currentRoute;
|
|
165
134
|
|
|
166
135
|
const diffLengthRoutes =
|
|
167
|
-
|
|
136
|
+
(previousRoute?.match(/river\//g) || []).length -
|
|
137
|
+
(currentRoute?.match(/river\//g) || []).length;
|
|
168
138
|
|
|
169
139
|
const stepsBack =
|
|
170
140
|
diffLengthRoutes && diffLengthRoutes > 0 ? diffLengthRoutes : 1;
|
|
@@ -180,32 +150,30 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
180
150
|
},
|
|
181
151
|
() => {
|
|
182
152
|
this.animationManager.animate(this.state, () =>
|
|
183
|
-
this.backTransitionEnd(
|
|
153
|
+
this.backTransitionEnd(stepsBack)
|
|
184
154
|
);
|
|
185
155
|
}
|
|
186
156
|
);
|
|
187
157
|
}
|
|
188
158
|
|
|
189
|
-
shouldSkipAnimationForRoute(route
|
|
159
|
+
shouldSkipAnimationForRoute(route) {
|
|
190
160
|
// We are skipping animations for some routes, likes hooks & the player mainly
|
|
191
161
|
|
|
192
162
|
return route.includes("/playable") || route.includes("/hook");
|
|
193
163
|
}
|
|
194
164
|
|
|
195
|
-
shouldResetStateForRoute(route
|
|
165
|
+
shouldResetStateForRoute(route) {
|
|
196
166
|
// We are resetting the transitioner state for root routes
|
|
197
167
|
|
|
198
|
-
return
|
|
168
|
+
return (route?.match(/river\//g) || []).length === 1;
|
|
199
169
|
}
|
|
200
170
|
|
|
201
|
-
transitionWithoutAnimation(resetState
|
|
202
|
-
|
|
203
|
-
// so the new scene replaces the one being backed to
|
|
204
|
-
const scenes = this.state.scenes.slice(0, this.state.to.index + 1);
|
|
171
|
+
transitionWithoutAnimation(resetState) {
|
|
172
|
+
const { scenes } = this.state;
|
|
205
173
|
const newScene = prepareScene(this.props.children);
|
|
206
174
|
const isLastSceneHook = scenes[scenes.length - 1].key.startsWith("/hook");
|
|
207
175
|
|
|
208
|
-
let newState
|
|
176
|
+
let newState;
|
|
209
177
|
|
|
210
178
|
if (resetState) {
|
|
211
179
|
newState = {
|
|
@@ -295,27 +263,20 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
295
263
|
}
|
|
296
264
|
}
|
|
297
265
|
|
|
298
|
-
// Sets state.animating to false
|
|
299
|
-
|
|
300
|
-
pushTransitionEnd(transitionId: number) {
|
|
301
|
-
if (transitionId !== this.transitionId) return;
|
|
302
|
-
|
|
266
|
+
// Sets state.animating to false
|
|
267
|
+
pushTransitionEnd() {
|
|
303
268
|
this.setState({
|
|
304
269
|
animating: false,
|
|
305
270
|
});
|
|
306
271
|
}
|
|
307
272
|
|
|
308
273
|
// Sets state.animating to false
|
|
309
|
-
// and
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
backTransitionEnd(transitionId: number) {
|
|
313
|
-
if (transitionId !== this.transitionId) return;
|
|
314
|
-
|
|
315
|
-
this.setState(({ scenes, to }) => ({
|
|
274
|
+
// and remove last scene from scenes stack
|
|
275
|
+
backTransitionEnd(stepsBack) {
|
|
276
|
+
this.setState({
|
|
316
277
|
animating: false,
|
|
317
|
-
scenes: scenes.
|
|
318
|
-
})
|
|
278
|
+
scenes: take(this.state.scenes.length - stepsBack, this.state.scenes),
|
|
279
|
+
});
|
|
319
280
|
}
|
|
320
281
|
|
|
321
282
|
// On initial state, both "to" and "from" point to a single scene
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { v4 as uuidV4 } from "uuid";
|
|
2
|
+
import { Text, View } from "react-native";
|
|
4
3
|
|
|
5
4
|
import { AnimationManager } from "../AnimationManager";
|
|
6
5
|
import {
|
|
7
6
|
NAV_ACTION_BACK,
|
|
8
7
|
NAV_ACTION_PUSH,
|
|
9
|
-
NAV_ACTION_REPLACE,
|
|
10
8
|
TransitionerComponent,
|
|
11
9
|
} from "../Transitioner";
|
|
12
10
|
import { act, render } from "@testing-library/react-native";
|
|
@@ -68,26 +66,6 @@ const sceneFor = (route) => (
|
|
|
68
66
|
</View>
|
|
69
67
|
);
|
|
70
68
|
|
|
71
|
-
const root = "/river/root";
|
|
72
|
-
const child = `${root}/river/child`;
|
|
73
|
-
const grandchild = `${child}/river/grandchild`;
|
|
74
|
-
|
|
75
|
-
const propsFor = (route, previousAction, children = sceneFor(route)) => ({
|
|
76
|
-
navigator: {
|
|
77
|
-
previousAction,
|
|
78
|
-
currentRoute: route,
|
|
79
|
-
screenData: {},
|
|
80
|
-
},
|
|
81
|
-
transitionConfig: sceneTransitionConfig,
|
|
82
|
-
layoutData: {
|
|
83
|
-
isTablet: false,
|
|
84
|
-
isTabletPortrait: false,
|
|
85
|
-
},
|
|
86
|
-
children,
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
const sceneKeys = (ref) => ref.current.state.scenes.map((scene) => scene.key);
|
|
90
|
-
|
|
91
69
|
describe("<TransitionerComponent />", () => {
|
|
92
70
|
it("renders correctly", () => {
|
|
93
71
|
const wrapper = render(
|
|
@@ -105,12 +83,26 @@ describe("<TransitionerComponent />", () => {
|
|
|
105
83
|
.mockImplementation((_, done) => done());
|
|
106
84
|
|
|
107
85
|
const ref = React.createRef();
|
|
86
|
+
const root = "/river/root";
|
|
87
|
+
const child = `${root}/river/child`;
|
|
88
|
+
const grandchild = `${child}/river/grandchild`;
|
|
89
|
+
|
|
90
|
+
const propsFor = (route, previousAction) => ({
|
|
91
|
+
navigator: {
|
|
92
|
+
previousAction,
|
|
93
|
+
currentRoute: route,
|
|
94
|
+
screenData: {},
|
|
95
|
+
},
|
|
96
|
+
transitionConfig: sceneTransitionConfig,
|
|
97
|
+
layoutData: {
|
|
98
|
+
isTablet: false,
|
|
99
|
+
isTabletPortrait: false,
|
|
100
|
+
},
|
|
101
|
+
children: sceneFor(route),
|
|
102
|
+
});
|
|
108
103
|
|
|
109
104
|
const { rerender } = render(
|
|
110
|
-
<TransitionerComponent
|
|
111
|
-
ref={ref}
|
|
112
|
-
{...propsFor(root, NAV_ACTION_REPLACE)}
|
|
113
|
-
/>
|
|
105
|
+
<TransitionerComponent ref={ref} {...propsFor(root, "REPLACE")} />
|
|
114
106
|
);
|
|
115
107
|
|
|
116
108
|
act(() => {
|
|
@@ -137,286 +129,6 @@ describe("<TransitionerComponent />", () => {
|
|
|
137
129
|
);
|
|
138
130
|
});
|
|
139
131
|
|
|
140
|
-
expect(
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
describe("with interruptible animations", () => {
|
|
144
|
-
// End callback of the animation that is currently "running"
|
|
145
|
-
let runningAnimationEnd = null;
|
|
146
|
-
|
|
147
|
-
const finishAnimation = () => {
|
|
148
|
-
act(() => {
|
|
149
|
-
const done = runningAnimationEnd;
|
|
150
|
-
runningAnimationEnd = null;
|
|
151
|
-
done?.();
|
|
152
|
-
});
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const mountTransitioner = ({
|
|
156
|
-
initialRoute = root,
|
|
157
|
-
renderScene = sceneFor,
|
|
158
|
-
} = {}) => {
|
|
159
|
-
const ref = React.createRef();
|
|
160
|
-
|
|
161
|
-
const transitioner = (route, action) => (
|
|
162
|
-
<TransitionerComponent
|
|
163
|
-
ref={ref}
|
|
164
|
-
{...propsFor(route, action, renderScene(route))}
|
|
165
|
-
/>
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
const { rerender } = render(
|
|
169
|
-
transitioner(initialRoute, NAV_ACTION_REPLACE)
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
const navigate = (route, action) => {
|
|
173
|
-
act(() => {
|
|
174
|
-
rerender(transitioner(route, action));
|
|
175
|
-
});
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
return { ref, navigate };
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
beforeEach(() => {
|
|
182
|
-
let sceneCount = 0;
|
|
183
|
-
uuidV4.mockImplementation(() => `scene-${++sceneCount}`);
|
|
184
|
-
|
|
185
|
-
jest
|
|
186
|
-
.spyOn(AnimationManager.prototype, "animate")
|
|
187
|
-
.mockImplementation((_, done) => {
|
|
188
|
-
runningAnimationEnd = done;
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
const setValue = Animated.Value.prototype.setValue;
|
|
192
|
-
|
|
193
|
-
// RN 0.77: setValue() stops the running animation, which calls
|
|
194
|
-
// its end callback synchronously with { finished: false }
|
|
195
|
-
jest
|
|
196
|
-
.spyOn(Animated.Value.prototype, "setValue")
|
|
197
|
-
.mockImplementation(function (value) {
|
|
198
|
-
const interrupted = runningAnimationEnd;
|
|
199
|
-
runningAnimationEnd = null;
|
|
200
|
-
interrupted?.();
|
|
201
|
-
|
|
202
|
-
return setValue.call(this, value);
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
afterEach(() => {
|
|
207
|
-
runningAnimationEnd = null;
|
|
208
|
-
jest.restoreAllMocks();
|
|
209
|
-
uuidV4.mockReset();
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it("drops interrupted scenes when going back twice during a back animation", () => {
|
|
213
|
-
const { ref, navigate } = mountTransitioner();
|
|
214
|
-
|
|
215
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
216
|
-
finishAnimation();
|
|
217
|
-
navigate(grandchild, NAV_ACTION_PUSH);
|
|
218
|
-
finishAnimation();
|
|
219
|
-
|
|
220
|
-
navigate(child, NAV_ACTION_BACK);
|
|
221
|
-
navigate(root, NAV_ACTION_BACK);
|
|
222
|
-
|
|
223
|
-
expect(ref.current.state.animating).toBe(true);
|
|
224
|
-
|
|
225
|
-
finishAnimation();
|
|
226
|
-
|
|
227
|
-
expect(sceneKeys(ref)).toEqual([root]);
|
|
228
|
-
expect(ref.current.state.animating).toBe(false);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
it("remounts the screen when revisiting it after a quick double back", () => {
|
|
232
|
-
const mounts = {};
|
|
233
|
-
|
|
234
|
-
const MountProbe = ({ pathname }) => {
|
|
235
|
-
React.useEffect(() => {
|
|
236
|
-
mounts[pathname] = (mounts[pathname] || 0) + 1;
|
|
237
|
-
}, [pathname]);
|
|
238
|
-
|
|
239
|
-
return <Text>{pathname}</Text>;
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
const { ref, navigate } = mountTransitioner({
|
|
243
|
-
renderScene: (route) => <MountProbe pathname={route} />,
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
247
|
-
finishAnimation();
|
|
248
|
-
|
|
249
|
-
const originalChildId = ref.current.state.scenes[1].screenUniqueId;
|
|
250
|
-
|
|
251
|
-
navigate(grandchild, NAV_ACTION_PUSH);
|
|
252
|
-
finishAnimation();
|
|
253
|
-
navigate(child, NAV_ACTION_BACK);
|
|
254
|
-
navigate(root, NAV_ACTION_BACK);
|
|
255
|
-
finishAnimation();
|
|
256
|
-
|
|
257
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
258
|
-
finishAnimation();
|
|
259
|
-
|
|
260
|
-
const { scenes, to } = ref.current.state;
|
|
261
|
-
|
|
262
|
-
expect(scenes).toHaveLength(2);
|
|
263
|
-
expect(to.index).toBe(1);
|
|
264
|
-
expect(scenes[1].screenUniqueId).not.toBe(originalChildId);
|
|
265
|
-
expect(mounts[child]).toBe(2);
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it("keeps a single scene when going back from the first scene", () => {
|
|
269
|
-
const { ref, navigate } = mountTransitioner({ initialRoute: child });
|
|
270
|
-
|
|
271
|
-
navigate(root, NAV_ACTION_BACK);
|
|
272
|
-
finishAnimation();
|
|
273
|
-
|
|
274
|
-
expect(sceneKeys(ref)).toEqual([root]);
|
|
275
|
-
expect(ref.current.state.to.index).toBe(0);
|
|
276
|
-
expect(ref.current.state.animating).toBe(false);
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
it("pushes a fresh scene after a completed single back", () => {
|
|
280
|
-
const { ref, navigate } = mountTransitioner();
|
|
281
|
-
|
|
282
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
283
|
-
finishAnimation();
|
|
284
|
-
|
|
285
|
-
const originalChildId = ref.current.state.scenes[1].screenUniqueId;
|
|
286
|
-
|
|
287
|
-
navigate(root, NAV_ACTION_BACK);
|
|
288
|
-
finishAnimation();
|
|
289
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
290
|
-
finishAnimation();
|
|
291
|
-
|
|
292
|
-
const { scenes, to } = ref.current.state;
|
|
293
|
-
|
|
294
|
-
expect(sceneKeys(ref)).toEqual([root, child]);
|
|
295
|
-
expect(to.index).toBe(1);
|
|
296
|
-
expect(scenes[1].screenUniqueId).not.toBe(originalChildId);
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
it("ignores the end of a back animation that a newer back superseded", () => {
|
|
300
|
-
const { ref, navigate } = mountTransitioner();
|
|
301
|
-
|
|
302
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
303
|
-
finishAnimation();
|
|
304
|
-
navigate(grandchild, NAV_ACTION_PUSH);
|
|
305
|
-
finishAnimation();
|
|
306
|
-
|
|
307
|
-
navigate(child, NAV_ACTION_BACK);
|
|
308
|
-
|
|
309
|
-
const supersededEnd = runningAnimationEnd;
|
|
310
|
-
|
|
311
|
-
// Deliver the interrupted animation's end late, after the newer one started
|
|
312
|
-
Animated.Value.prototype.setValue.mockImplementation(() => {});
|
|
313
|
-
|
|
314
|
-
navigate(root, NAV_ACTION_BACK);
|
|
315
|
-
|
|
316
|
-
act(() => {
|
|
317
|
-
supersededEnd();
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
expect(ref.current.state.animating).toBe(true);
|
|
321
|
-
expect(sceneKeys(ref)).toEqual([root, child, grandchild]);
|
|
322
|
-
|
|
323
|
-
finishAnimation();
|
|
324
|
-
|
|
325
|
-
expect(sceneKeys(ref)).toEqual([root]);
|
|
326
|
-
expect(ref.current.state.animating).toBe(false);
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
it("drops the pushed scene when going back before its push animation ends", () => {
|
|
330
|
-
const { ref, navigate } = mountTransitioner();
|
|
331
|
-
|
|
332
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
333
|
-
navigate(root, NAV_ACTION_BACK);
|
|
334
|
-
|
|
335
|
-
expect(ref.current.state.animating).toBe(true);
|
|
336
|
-
|
|
337
|
-
finishAnimation();
|
|
338
|
-
|
|
339
|
-
expect(sceneKeys(ref)).toEqual([root]);
|
|
340
|
-
expect(ref.current.state.animating).toBe(false);
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
it("pushes right after the visible scene even when stale scenes are left behind", () => {
|
|
344
|
-
const { ref, navigate } = mountTransitioner();
|
|
345
|
-
|
|
346
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
347
|
-
finishAnimation();
|
|
348
|
-
|
|
349
|
-
// Leftover past to.index, as some other path could leave behind
|
|
350
|
-
act(() => {
|
|
351
|
-
ref.current.setState(({ scenes }) => ({
|
|
352
|
-
scenes: [
|
|
353
|
-
...scenes,
|
|
354
|
-
{
|
|
355
|
-
...scenes[1],
|
|
356
|
-
key: `${root}/river/stale`,
|
|
357
|
-
screenUniqueId: "stale",
|
|
358
|
-
},
|
|
359
|
-
],
|
|
360
|
-
}));
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
navigate(grandchild, NAV_ACTION_PUSH);
|
|
364
|
-
finishAnimation();
|
|
365
|
-
|
|
366
|
-
const { scenes, to } = ref.current.state;
|
|
367
|
-
|
|
368
|
-
expect(sceneKeys(ref)).toEqual([root, child, grandchild]);
|
|
369
|
-
expect(scenes[to.index].key).toBe(grandchild);
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
it("shows the replaced screen when going home during a back animation", () => {
|
|
373
|
-
const home = "/river/home";
|
|
374
|
-
const { ref, navigate } = mountTransitioner();
|
|
375
|
-
|
|
376
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
377
|
-
finishAnimation();
|
|
378
|
-
|
|
379
|
-
navigate(root, NAV_ACTION_BACK);
|
|
380
|
-
navigate(home, NAV_ACTION_REPLACE);
|
|
381
|
-
|
|
382
|
-
const { scenes, to } = ref.current.state;
|
|
383
|
-
|
|
384
|
-
expect(scenes[to.index].key).toBe(home);
|
|
385
|
-
|
|
386
|
-
finishAnimation();
|
|
387
|
-
|
|
388
|
-
expect(sceneKeys(ref)).toEqual([home]);
|
|
389
|
-
expect(ref.current.state.animating).toBe(false);
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
it("shows the pushed screen when pushing during a back animation", () => {
|
|
393
|
-
const sibling = `${root}/river/sibling`;
|
|
394
|
-
const { ref, navigate } = mountTransitioner();
|
|
395
|
-
|
|
396
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
397
|
-
finishAnimation();
|
|
398
|
-
|
|
399
|
-
navigate(root, NAV_ACTION_BACK);
|
|
400
|
-
navigate(sibling, NAV_ACTION_PUSH);
|
|
401
|
-
|
|
402
|
-
const { scenes, to } = ref.current.state;
|
|
403
|
-
|
|
404
|
-
expect(scenes[to.index].key).toBe(sibling);
|
|
405
|
-
|
|
406
|
-
finishAnimation();
|
|
407
|
-
|
|
408
|
-
expect(sceneKeys(ref)).not.toContain(child);
|
|
409
|
-
expect(ref.current.state.animating).toBe(false);
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
it("keeps both scenes when pushing during a push animation", () => {
|
|
413
|
-
const { ref, navigate } = mountTransitioner();
|
|
414
|
-
|
|
415
|
-
navigate(child, NAV_ACTION_PUSH);
|
|
416
|
-
navigate(grandchild, NAV_ACTION_PUSH);
|
|
417
|
-
|
|
418
|
-
expect(sceneKeys(ref)).toEqual([child, grandchild]);
|
|
419
|
-
expect(ref.current.state.to.index).toBe(1);
|
|
420
|
-
});
|
|
132
|
+
expect(ref.current.state.scenes.map((scene) => scene.key)).toEqual([root]);
|
|
421
133
|
});
|
|
422
134
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "16.0.0-alpha.
|
|
3
|
+
"version": "16.0.0-alpha.1108851646",
|
|
4
4
|
"description": "Applicaster Zapp React Native ui components for the Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "16.0.0-alpha.
|
|
32
|
-
"@applicaster/zapp-react-native-bridge": "16.0.0-alpha.
|
|
33
|
-
"@applicaster/zapp-react-native-redux": "16.0.0-alpha.
|
|
34
|
-
"@applicaster/zapp-react-native-utils": "16.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "16.0.0-alpha.1108851646",
|
|
32
|
+
"@applicaster/zapp-react-native-bridge": "16.0.0-alpha.1108851646",
|
|
33
|
+
"@applicaster/zapp-react-native-redux": "16.0.0-alpha.1108851646",
|
|
34
|
+
"@applicaster/zapp-react-native-utils": "16.0.0-alpha.1108851646",
|
|
35
35
|
"fast-json-stable-stringify": "^2.1.0",
|
|
36
36
|
"promise": "^8.3.0",
|
|
37
37
|
"react-native-sortables": "1.7.1",
|