Skip to content

Commit 41688f8

Browse files
authored
chore(examples): allow modifying route blueprints passed to StackContainer (#3626)
## Description **Expose `StackContainerWithDynamicRouteConfigs` component** It's a wrapper for `StackContainer`. It adds `StackRouteConfigContext`, which can be used to modify route options stored in route configurations. This is different from what <#3625> introduced, because this does not impact existing route instances. Only blueprints. I created separate component to keep the `StackContainer` logic thin.
1 parent 4c94d3a commit 41688f8

7 files changed

Lines changed: 80 additions & 5 deletions

File tree

apps/src/shared/gamma/containers/stack/StackContainer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ function useSanitizeRouteConfigs(
9595
routeConfigs?: StackRouteConfig[] | undefined | null,
9696
) {
9797
if (!routeConfigs || routeConfigs.length === 0) {
98-
throw new Error('[RNScreens] There must be at least one route configured');
98+
throw new Error('[Stack] There must be at least one route configured');
9999
}
100100

101101
// Do not recompute in case the routeConfigs have not changed
@@ -106,6 +106,6 @@ function useSanitizeRouteConfigs(
106106
}, [routeConfigs]);
107107

108108
if (!areNamesUnique) {
109-
throw new Error('[RNScreens] All routes must have unique names');
109+
throw new Error('[Stack] All routes must have unique names');
110110
}
111111
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import { StackContainer } from './StackContainer';
3+
import { StackContainerProps, StackRouteOptions } from './StackContainer.types';
4+
import { StackRouteConfigContext } from './contexts/StackRouteConfigContext';
5+
6+
/**
7+
* StackContainer wrapped in context allowing for modifying options
8+
* of route configs.
9+
* See StackRouteConfigContext.
10+
*/
11+
export function StackContainerWithDynamicRouteConfigs(
12+
props: StackContainerProps,
13+
) {
14+
const [routeConfigs, setRouteConfigs] = React.useState(props.routeConfigs);
15+
16+
const updateRouteConfigWithOptions = React.useCallback(
17+
(routeName: string, options: Partial<StackRouteOptions>) => {
18+
setRouteConfigs(prevConfigs => {
19+
const routeConfigIndex = prevConfigs.findIndex(
20+
config => config.name === routeName,
21+
);
22+
23+
if (routeConfigIndex === -1) {
24+
throw new Error(`Route with name "${routeName}" not found`);
25+
}
26+
27+
return prevConfigs.toSpliced(routeConfigIndex, 1, {
28+
...prevConfigs[routeConfigIndex],
29+
options,
30+
});
31+
});
32+
},
33+
[],
34+
);
35+
36+
return (
37+
<StackRouteConfigContext
38+
value={{
39+
routeConfigs,
40+
updateRouteConfigWithOptions,
41+
}}>
42+
<StackContainer routeConfigs={routeConfigs} />
43+
</StackRouteConfigContext>
44+
);
45+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import type {
3+
StackRouteConfig,
4+
StackRouteOptions,
5+
} from '../StackContainer.types';
6+
7+
export type StackRouteConfigContextPayload = {
8+
routeConfigs: StackRouteConfig[];
9+
updateRouteConfigWithOptions: (
10+
routeName: string,
11+
options: Partial<StackRouteOptions>,
12+
) => void;
13+
};
14+
15+
export const StackRouteConfigContext =
16+
React.createContext<StackRouteConfigContextPayload | null>(null);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
import { StackRouteConfigContext } from '../contexts/StackRouteConfigContext';
3+
4+
export function useStackRouteConfigContext() {
5+
const context = React.useContext(StackRouteConfigContext);
6+
7+
if (!context) {
8+
throw new Error(
9+
'useStackRouteConfigContext must be used within a StackContainerWithContext',
10+
);
11+
}
12+
13+
return context;
14+
}

apps/src/shared/gamma/containers/stack/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ export type {
55
} from './StackContainer.types';
66

77
export type { StackNavigationContextPayload } from './contexts/StackNavigationContext';
8+
export type { StackRouteConfigContextPayload } from './contexts/StackRouteConfigContext';
89

910
export { useStackNavigationContext } from './hooks/useStackNavigationContext';
11+
export { useStackRouteConfigContext } from './hooks/useStackRouteConfigContext';
1012

1113
export { StackContainer } from './StackContainer';
14+
export { StackContainerWithDynamicRouteConfigs } from './StackContainerWithDynamicRouteConfigs';

apps/src/tests/single-feature-tests/stack-v5/prevent-native-dismiss-nested-stack.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ function AScreen() {
8989
<RouteInformation routeName="A" />
9090
<PreventNativeDismissInfo />
9191
<NavigationButtons isPopEnabled routeNames={['A', 'B', 'NestedStack']} />
92-
<TogglePreventNativeDismiss />
9392
</CenteredLayoutView>
9493
);
9594
}
@@ -167,7 +166,6 @@ function NestedAScreen() {
167166
<RouteInformation routeName="NestedA" />
168167
<PreventNativeDismissInfo />
169168
<NavigationButtons isPopEnabled routeNames={['NestedA', 'NestedB']} />
170-
<TogglePreventNativeDismiss />
171169
</CenteredLayoutView>
172170
);
173171
}

apps/src/tests/single-feature-tests/stack-v5/prevent-native-dismiss-single-stack.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ function AScreen() {
7878
<RouteInformation routeName="A" />
7979
<PreventNativeDismissInfo />
8080
<NavigationButtons isPopEnabled={true} />
81-
<TogglePreventNativeDismiss />
8281
</CenteredLayoutView>
8382
);
8483
}

0 commit comments

Comments
 (0)