@amazon-devices/react-navigation__stack 8.0.9000000000 → 8.0.9000000002

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.
Files changed (81) hide show
  1. package/SystemModules/amzn__react-navigation__stack-8.private.modules.txt +39 -34
  2. package/kepler-compatibility.json +4 -2
  3. package/lib/module/index.js +0 -34
  4. package/lib/typescript/src/index.d.ts +1 -1
  5. package/lib/typescript/src/index.d.ts.map +1 -1
  6. package/oss-attribution/attribution.txt +76 -0
  7. package/oss-attribution/licenseInfos.json +27 -0
  8. package/package.json +1 -1
  9. package/src/index.tsx +0 -55
  10. package/SystemBundles/98ca5eeb45684e3e5615c766e1d3a956fee53d14cd6c2318098c23c210bd76d7.bundle +0 -13464
  11. package/SystemBundles/98ca5eeb45684e3e5615c766e1d3a956fee53d14cd6c2318098c23c210bd76d7.map +0 -4638
  12. package/lib/module/TransitionConfigs/CardStyleInterpolators.js +0 -394
  13. package/lib/module/TransitionConfigs/HeaderStyleInterpolators.js +0 -262
  14. package/lib/module/TransitionConfigs/TransitionPresets.js +0 -156
  15. package/lib/module/TransitionConfigs/TransitionSpecs.js +0 -124
  16. package/lib/module/navigators/createStackNavigator.js +0 -71
  17. package/lib/module/types.js +0 -4
  18. package/lib/module/utils/CardAnimationContext.js +0 -5
  19. package/lib/module/utils/GestureHandlerRefContext.js +0 -5
  20. package/lib/module/utils/ModalPresentationContext.js +0 -5
  21. package/lib/module/utils/conditional.js +0 -28
  22. package/lib/module/utils/findLastIndex.js +0 -11
  23. package/lib/module/utils/gestureActivationCriteria.js +0 -60
  24. package/lib/module/utils/getDistanceForDirection.js +0 -15
  25. package/lib/module/utils/getInvertedMultiplier.js +0 -15
  26. package/lib/module/utils/getModalRoutesKeys.js +0 -12
  27. package/lib/module/utils/getShadowStyle.js +0 -24
  28. package/lib/module/utils/throttle.js +0 -14
  29. package/lib/module/utils/useCardAnimation.js +0 -12
  30. package/lib/module/utils/useGestureHandlerRef.js +0 -12
  31. package/lib/module/utils/useKeyboardManager.js +0 -90
  32. package/lib/module/views/GestureHandler.android.js +0 -4
  33. package/lib/module/views/GestureHandler.ios.js +0 -4
  34. package/lib/module/views/GestureHandler.js +0 -21
  35. package/lib/module/views/GestureHandler.kepler.js +0 -4
  36. package/lib/module/views/GestureHandlerNative.js +0 -18
  37. package/lib/module/views/Header/Header.js +0 -56
  38. package/lib/module/views/Header/HeaderContainer.js +0 -128
  39. package/lib/module/views/Header/HeaderSegment.js +0 -142
  40. package/lib/module/views/Screens.js +0 -42
  41. package/lib/module/views/Stack/Card.js +0 -433
  42. package/lib/module/views/Stack/CardA11yWrapper.js +0 -43
  43. package/lib/module/views/Stack/CardContainer.js +0 -276
  44. package/lib/module/views/Stack/CardContent.js +0 -74
  45. package/lib/module/views/Stack/CardStack.js +0 -493
  46. package/lib/module/views/Stack/StackView.js +0 -339
  47. package/src/TransitionConfigs/CardStyleInterpolators.tsx +0 -460
  48. package/src/TransitionConfigs/HeaderStyleInterpolators.tsx +0 -286
  49. package/src/TransitionConfigs/TransitionPresets.tsx +0 -182
  50. package/src/TransitionConfigs/TransitionSpecs.tsx +0 -124
  51. package/src/navigators/createStackNavigator.tsx +0 -120
  52. package/src/types.tsx +0 -639
  53. package/src/utils/CardAnimationContext.tsx +0 -7
  54. package/src/utils/GestureHandlerRefContext.tsx +0 -5
  55. package/src/utils/ModalPresentationContext.tsx +0 -3
  56. package/src/utils/conditional.tsx +0 -33
  57. package/src/utils/findLastIndex.tsx +0 -9
  58. package/src/utils/gestureActivationCriteria.tsx +0 -70
  59. package/src/utils/getDistanceForDirection.tsx +0 -19
  60. package/src/utils/getInvertedMultiplier.tsx +0 -17
  61. package/src/utils/getModalRoutesKeys.ts +0 -21
  62. package/src/utils/getShadowStyle.tsx +0 -37
  63. package/src/utils/throttle.tsx +0 -16
  64. package/src/utils/useCardAnimation.tsx +0 -15
  65. package/src/utils/useGestureHandlerRef.tsx +0 -15
  66. package/src/utils/useKeyboardManager.tsx +0 -103
  67. package/src/views/GestureHandler.android.tsx +0 -1
  68. package/src/views/GestureHandler.ios.tsx +0 -1
  69. package/src/views/GestureHandler.kepler.tsx +0 -1
  70. package/src/views/GestureHandler.tsx +0 -23
  71. package/src/views/GestureHandlerNative.tsx +0 -23
  72. package/src/views/Header/Header.tsx +0 -73
  73. package/src/views/Header/HeaderContainer.tsx +0 -191
  74. package/src/views/Header/HeaderSegment.tsx +0 -203
  75. package/src/views/Screens.tsx +0 -45
  76. package/src/views/Stack/Card.tsx +0 -646
  77. package/src/views/Stack/CardA11yWrapper.tsx +0 -67
  78. package/src/views/Stack/CardContainer.tsx +0 -339
  79. package/src/views/Stack/CardContent.tsx +0 -92
  80. package/src/views/Stack/CardStack.tsx +0 -844
  81. package/src/views/Stack/StackView.tsx +0 -485
@@ -1,485 +0,0 @@
1
- import {
2
- HeaderShownContext,
3
- SafeAreaProviderCompat,
4
- } from '@amazon-devices/react-navigation__elements';
5
- import {
6
- CommonActions,
7
- type LocaleDirection,
8
- type ParamListBase,
9
- type Route,
10
- type RouteProp,
11
- StackActions,
12
- type StackNavigationState,
13
- } from '@amazon-devices/react-navigation__native';
14
- import * as React from 'react';
15
- import { StyleSheet, View } from 'react-native';
16
- import { SafeAreaInsetsContext } from '@amazon-devices/react-native-safe-area-context';
17
-
18
- import type {
19
- StackDescriptor,
20
- StackDescriptorMap,
21
- StackNavigationConfig,
22
- StackNavigationHelpers,
23
- } from '../../types';
24
- import { ModalPresentationContext } from '../../utils/ModalPresentationContext';
25
- import { GestureHandlerRootView } from '../GestureHandler';
26
- import {
27
- HeaderContainer,
28
- type Props as HeaderContainerProps,
29
- } from '../Header/HeaderContainer';
30
- import { CardStack, getAnimationEnabled } from './CardStack';
31
-
32
- type Props = StackNavigationConfig & {
33
- direction: LocaleDirection;
34
- state: StackNavigationState<ParamListBase>;
35
- navigation: StackNavigationHelpers;
36
- descriptors: StackDescriptorMap;
37
- describe: (
38
- route: RouteProp<ParamListBase>,
39
- placeholder: boolean
40
- ) => StackDescriptor;
41
- };
42
-
43
- type State = {
44
- // Local copy of the routes which are actually rendered
45
- routes: Route<string>[];
46
- // Previous routes, to compare whether routes have changed or not
47
- previousRoutes: Route<string>[];
48
- // Previous descriptors, to compare whether descriptors have changed or not
49
- previousDescriptors: StackDescriptorMap;
50
- // List of routes being opened, we need to animate pushing of these new routes
51
- openingRouteKeys: string[];
52
- // List of routes being closed, we need to animate popping of these routes
53
- closingRouteKeys: string[];
54
- // List of routes being replaced, we need to keep a copy until the new route animates in
55
- replacingRouteKeys: string[];
56
- // Since the local routes can vary from the routes from props, we need to keep the descriptors for old routes
57
- // Otherwise we won't be able to access the options for routes that were removed
58
- descriptors: StackDescriptorMap;
59
- };
60
-
61
- const GestureHandlerWrapper = GestureHandlerRootView ?? View;
62
-
63
- /**
64
- * Compare two arrays with primitive values as the content.
65
- * We need to make sure that both values and order match.
66
- */
67
- const isArrayEqual = (a: any[], b: any[]) =>
68
- a.length === b.length && a.every((it, index) => Object.is(it, b[index]));
69
-
70
- export class StackView extends React.Component<Props, State> {
71
- static getDerivedStateFromProps(
72
- props: Readonly<Props>,
73
- state: Readonly<State>
74
- ) {
75
- // If there was no change in routes, we don't need to compute anything
76
- if (
77
- (props.state.routes === state.previousRoutes ||
78
- isArrayEqual(
79
- props.state.routes.map((r) => r.key),
80
- state.previousRoutes.map((r) => r.key)
81
- )) &&
82
- state.routes.length
83
- ) {
84
- let routes = state.routes;
85
- let previousRoutes = state.previousRoutes;
86
- let descriptors = props.descriptors;
87
- let previousDescriptors = state.previousDescriptors;
88
-
89
- if (props.descriptors !== state.previousDescriptors) {
90
- descriptors = state.routes.reduce<StackDescriptorMap>((acc, route) => {
91
- acc[route.key] =
92
- props.descriptors[route.key] || state.descriptors[route.key];
93
-
94
- return acc;
95
- }, {});
96
-
97
- previousDescriptors = props.descriptors;
98
- }
99
-
100
- if (props.state.routes !== state.previousRoutes) {
101
- // if any route objects have changed, we should update them
102
- const map = props.state.routes.reduce<Record<string, Route<string>>>(
103
- (acc, route) => {
104
- acc[route.key] = route;
105
- return acc;
106
- },
107
- {}
108
- );
109
-
110
- routes = state.routes.map((route) => map[route.key] || route);
111
- previousRoutes = props.state.routes;
112
- }
113
-
114
- return {
115
- routes,
116
- previousRoutes,
117
- descriptors,
118
- previousDescriptors,
119
- };
120
- }
121
-
122
- // Here we determine which routes were added or removed to animate them
123
- // We keep a copy of the route being removed in local state to be able to animate it
124
-
125
- let routes =
126
- props.state.index < props.state.routes.length - 1
127
- ? // Remove any extra routes from the state
128
- // The last visible route should be the focused route, i.e. at current index
129
- props.state.routes.slice(0, props.state.index + 1)
130
- : props.state.routes;
131
-
132
- // Now we need to determine which routes were added and removed
133
- const { previousRoutes } = state;
134
-
135
- let { openingRouteKeys, closingRouteKeys, replacingRouteKeys } = state;
136
-
137
- const previousFocusedRoute = previousRoutes[previousRoutes.length - 1] as
138
- | Route<string>
139
- | undefined;
140
- const nextFocusedRoute = routes[routes.length - 1];
141
-
142
- const isAnimationEnabled = (key: string) => {
143
- const descriptor = props.descriptors[key] || state.descriptors[key];
144
-
145
- return getAnimationEnabled(descriptor?.options.animation);
146
- };
147
-
148
- const getAnimationTypeForReplace = (key: string) => {
149
- const descriptor = props.descriptors[key] || state.descriptors[key];
150
-
151
- return descriptor.options.animationTypeForReplace ?? 'push';
152
- };
153
-
154
- if (
155
- previousFocusedRoute &&
156
- previousFocusedRoute.key !== nextFocusedRoute.key
157
- ) {
158
- // We only need to animate routes if the focused route changed
159
- // Animating previous routes won't be visible coz the focused route is on top of everything
160
-
161
- if (
162
- previousRoutes.some((r) => r.key === nextFocusedRoute.key) &&
163
- !routes.some((r) => r.key === previousFocusedRoute.key)
164
- ) {
165
- // The previously focused route was removed, and the new focused route was already present
166
- // We treat this as a pop
167
-
168
- if (
169
- isAnimationEnabled(previousFocusedRoute.key) &&
170
- !closingRouteKeys.includes(previousFocusedRoute.key)
171
- ) {
172
- closingRouteKeys = [...closingRouteKeys, previousFocusedRoute.key];
173
-
174
- // Sometimes a route can be closed before the opening animation finishes
175
- // So we also need to remove it from the opening list
176
- openingRouteKeys = openingRouteKeys.filter(
177
- (key) => key !== previousFocusedRoute.key
178
- );
179
- replacingRouteKeys = replacingRouteKeys.filter(
180
- (key) => key !== previousFocusedRoute.key
181
- );
182
-
183
- // Keep a copy of route being removed in the state to be able to animate it
184
- routes = [...routes, previousFocusedRoute];
185
- }
186
- } else {
187
- // A route has come to the focus, we treat this as a push
188
- // A replace or rearranging can also trigger this
189
- // The animation should look like push
190
-
191
- if (
192
- isAnimationEnabled(nextFocusedRoute.key) &&
193
- !openingRouteKeys.includes(nextFocusedRoute.key)
194
- ) {
195
- // In this case, we need to animate pushing the focused route
196
- // We don't care about animating any other added routes because they won't be visible
197
- openingRouteKeys = [...openingRouteKeys, nextFocusedRoute.key];
198
-
199
- closingRouteKeys = closingRouteKeys.filter(
200
- (key) => key !== nextFocusedRoute.key
201
- );
202
- replacingRouteKeys = replacingRouteKeys.filter(
203
- (key) => key !== nextFocusedRoute.key
204
- );
205
-
206
- if (!routes.some((r) => r.key === previousFocusedRoute.key)) {
207
- // The previous focused route isn't present in state, we treat this as a replace
208
-
209
- openingRouteKeys = openingRouteKeys.filter(
210
- (key) => key !== previousFocusedRoute.key
211
- );
212
-
213
- if (getAnimationTypeForReplace(nextFocusedRoute.key) === 'pop') {
214
- closingRouteKeys = [
215
- ...closingRouteKeys,
216
- previousFocusedRoute.key,
217
- ];
218
-
219
- // By default, new routes have a push animation, so we add it to `openingRouteKeys` before
220
- // But since user configured it to animate the old screen like a pop, we need to add this without animation
221
- // So remove it from `openingRouteKeys` which will remove the animation
222
- openingRouteKeys = openingRouteKeys.filter(
223
- (key) => key !== nextFocusedRoute.key
224
- );
225
-
226
- // Keep the route being removed at the end to animate it out
227
- routes = [...routes, previousFocusedRoute];
228
- } else {
229
- replacingRouteKeys = [
230
- ...replacingRouteKeys,
231
- previousFocusedRoute.key,
232
- ];
233
-
234
- closingRouteKeys = closingRouteKeys.filter(
235
- (key) => key !== previousFocusedRoute.key
236
- );
237
-
238
- // Keep the old route in the state because it's visible under the new route, and removing it will feel abrupt
239
- // We need to insert it just before the focused one (the route being pushed)
240
- // After the push animation is completed, routes being replaced will be removed completely
241
- routes = routes.slice();
242
- routes.splice(routes.length - 1, 0, previousFocusedRoute);
243
- }
244
- }
245
- }
246
- }
247
- } else if (replacingRouteKeys.length || closingRouteKeys.length) {
248
- // Keep the routes we are closing or replacing if animation is enabled for them
249
- routes = routes.slice();
250
- routes.splice(
251
- routes.length - 1,
252
- 0,
253
- ...state.routes.filter(({ key }) =>
254
- isAnimationEnabled(key)
255
- ? replacingRouteKeys.includes(key) || closingRouteKeys.includes(key)
256
- : false
257
- )
258
- );
259
- }
260
-
261
- if (!routes.length) {
262
- throw new Error(
263
- 'There should always be at least one route in the navigation state.'
264
- );
265
- }
266
-
267
- const descriptors = routes.reduce<StackDescriptorMap>((acc, route) => {
268
- acc[route.key] =
269
- props.descriptors[route.key] || state.descriptors[route.key];
270
-
271
- return acc;
272
- }, {});
273
-
274
- return {
275
- routes,
276
- previousRoutes: props.state.routes,
277
- previousDescriptors: props.descriptors,
278
- openingRouteKeys,
279
- closingRouteKeys,
280
- replacingRouteKeys,
281
- descriptors,
282
- };
283
- }
284
-
285
- state: State = {
286
- routes: [],
287
- previousRoutes: [],
288
- previousDescriptors: {},
289
- openingRouteKeys: [],
290
- closingRouteKeys: [],
291
- replacingRouteKeys: [],
292
- descriptors: {},
293
- };
294
-
295
- private getPreviousRoute = ({ route }: { route: Route<string> }) => {
296
- const { closingRouteKeys, replacingRouteKeys } = this.state;
297
- const routes = this.state.routes.filter(
298
- (r) =>
299
- r.key === route.key ||
300
- (!closingRouteKeys.includes(r.key) &&
301
- !replacingRouteKeys.includes(r.key))
302
- );
303
-
304
- const index = routes.findIndex((r) => r.key === route.key);
305
-
306
- return routes[index - 1];
307
- };
308
-
309
- private renderHeader = (props: HeaderContainerProps) => {
310
- return <HeaderContainer {...props} />;
311
- };
312
-
313
- private handleOpenRoute = ({ route }: { route: Route<string> }) => {
314
- const { state, navigation } = this.props;
315
- const { closingRouteKeys, replacingRouteKeys } = this.state;
316
-
317
- if (
318
- closingRouteKeys.some((key) => key === route.key) &&
319
- replacingRouteKeys.every((key) => key !== route.key) &&
320
- state.routeNames.includes(route.name) &&
321
- !state.routes.some((r) => r.key === route.key)
322
- ) {
323
- // If route isn't present in current state, but was closing, assume that a close animation was cancelled
324
- // So we need to add this route back to the state
325
- navigation.dispatch((state) => {
326
- const routes = [
327
- ...state.routes.filter((r) => r.key !== route.key),
328
- route,
329
- ];
330
-
331
- return CommonActions.reset({
332
- ...state,
333
- routes,
334
- index: routes.length - 1,
335
- });
336
- });
337
- } else {
338
- this.setState((state) => ({
339
- routes: state.replacingRouteKeys.length
340
- ? state.routes.filter(
341
- (r) => !state.replacingRouteKeys.includes(r.key)
342
- )
343
- : state.routes,
344
- openingRouteKeys: state.openingRouteKeys.filter(
345
- (key) => key !== route.key
346
- ),
347
- closingRouteKeys: state.closingRouteKeys.filter(
348
- (key) => key !== route.key
349
- ),
350
- replacingRouteKeys: [],
351
- }));
352
- }
353
- };
354
-
355
- private handleCloseRoute = ({ route }: { route: Route<string> }) => {
356
- const { state, navigation } = this.props;
357
-
358
- if (state.routes.some((r) => r.key === route.key)) {
359
- // If a route exists in state, trigger a pop
360
- // This will happen in when the route was closed from the card component
361
- // e.g. When the close animation triggered from a gesture ends
362
- navigation.dispatch({
363
- ...StackActions.pop(),
364
- source: route.key,
365
- target: state.key,
366
- });
367
- } else {
368
- // We need to clean up any state tracking the route and pop it immediately
369
- this.setState((state) => ({
370
- routes: state.routes.filter((r) => r.key !== route.key),
371
- openingRouteKeys: state.openingRouteKeys.filter(
372
- (key) => key !== route.key
373
- ),
374
- closingRouteKeys: state.closingRouteKeys.filter(
375
- (key) => key !== route.key
376
- ),
377
- }));
378
- }
379
- };
380
-
381
- private handleTransitionStart = (
382
- { route }: { route: Route<string> },
383
- closing: boolean
384
- ) =>
385
- this.props.navigation.emit({
386
- type: 'transitionStart',
387
- data: { closing },
388
- target: route.key,
389
- });
390
-
391
- private handleTransitionEnd = (
392
- { route }: { route: Route<string> },
393
- closing: boolean
394
- ) =>
395
- this.props.navigation.emit({
396
- type: 'transitionEnd',
397
- data: { closing },
398
- target: route.key,
399
- });
400
-
401
- private handleGestureStart = ({ route }: { route: Route<string> }) => {
402
- this.props.navigation.emit({
403
- type: 'gestureStart',
404
- target: route.key,
405
- });
406
- };
407
-
408
- private handleGestureEnd = ({ route }: { route: Route<string> }) => {
409
- this.props.navigation.emit({
410
- type: 'gestureEnd',
411
- target: route.key,
412
- });
413
- };
414
-
415
- private handleGestureCancel = ({ route }: { route: Route<string> }) => {
416
- this.props.navigation.emit({
417
- type: 'gestureCancel',
418
- target: route.key,
419
- });
420
- };
421
-
422
- render() {
423
- const {
424
- state,
425
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
426
- descriptors: _,
427
- ...rest
428
- } = this.props;
429
-
430
- const { routes, descriptors, openingRouteKeys, closingRouteKeys } =
431
- this.state;
432
-
433
- const preloadedDescriptors =
434
- state.preloadedRoutes.reduce<StackDescriptorMap>((acc, route) => {
435
- acc[route.key] = acc[route.key] || this.props.describe(route, true);
436
- return acc;
437
- }, {});
438
-
439
- return (
440
- <GestureHandlerWrapper style={styles.container}>
441
- <SafeAreaProviderCompat>
442
- <SafeAreaInsetsContext.Consumer>
443
- {(insets) => (
444
- <ModalPresentationContext.Consumer>
445
- {(isParentModal) => (
446
- <HeaderShownContext.Consumer>
447
- {(isParentHeaderShown) => (
448
- <CardStack
449
- insets={insets!}
450
- isParentHeaderShown={isParentHeaderShown}
451
- isParentModal={isParentModal}
452
- getPreviousRoute={this.getPreviousRoute}
453
- routes={routes}
454
- openingRouteKeys={openingRouteKeys}
455
- closingRouteKeys={closingRouteKeys}
456
- onOpenRoute={this.handleOpenRoute}
457
- onCloseRoute={this.handleCloseRoute}
458
- onTransitionStart={this.handleTransitionStart}
459
- onTransitionEnd={this.handleTransitionEnd}
460
- renderHeader={this.renderHeader}
461
- state={state}
462
- descriptors={descriptors}
463
- onGestureStart={this.handleGestureStart}
464
- onGestureEnd={this.handleGestureEnd}
465
- onGestureCancel={this.handleGestureCancel}
466
- preloadedDescriptors={preloadedDescriptors}
467
- {...rest}
468
- />
469
- )}
470
- </HeaderShownContext.Consumer>
471
- )}
472
- </ModalPresentationContext.Consumer>
473
- )}
474
- </SafeAreaInsetsContext.Consumer>
475
- </SafeAreaProviderCompat>
476
- </GestureHandlerWrapper>
477
- );
478
- }
479
- }
480
-
481
- const styles = StyleSheet.create({
482
- container: {
483
- flex: 1,
484
- },
485
- });