Skip to content

Commit 8ce2cfa

Browse files
committed
feat: introduce featureFlags struct & add controlledBottomTabs flag (#24)
## Description This PR explores more comprehensive approach to handling library behaviour configuration. Currently we have two configuration points: `enableScreens` (which seems to not work so well) & `enableFreeze`. This PR introduces (temporarily) third configuration point, which in future is meant as the only configuration point. Newly added `featureFlags` structure will contain all flags for behaviour configuration & will be the only place to do it. Currently only a single feature flag is added there & we'll move rest of them in follow ups. The `featureFlags` object contains additional logic to prevent misconfiguration & changing the values more than a single time. The `controlledBottomTabs` flag denotes whether the bottom tabs are driven by JS or native side (who manages the navigation state) & introduces changes in behaviour. ## Checklist - [ ] Ensured that CI passes
1 parent 2928e28 commit 8ce2cfa

File tree

4 files changed

+80
-30
lines changed

4 files changed

+80
-30
lines changed

src/components/BottomTabs.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
StyleSheet,
1414
type ViewProps,
1515
} from 'react-native';
16+
import featureFlags from '../flags';
1617

1718
export interface BottomTabsProps extends ViewProps {
1819
// Events
@@ -38,7 +39,8 @@ function BottomTabs(props: BottomTabsProps) {
3839

3940
const {
4041
onNativeFocusChange,
41-
experimentalControlNavigationStateInJS = false,
42+
experimentalControlNavigationStateInJS = featureFlags.experiment
43+
.controlledBottomTabs,
4244
...filteredProps
4345
} = props;
4446

src/flags.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
const RNS_CONTROLLED_BOTTOM_TABS_DEFAULT = false;
2+
3+
// TODO: Migrate freeze here
4+
5+
/**
6+
* Exposes information useful for downstream navigation library implementers,
7+
* so they can keep reasonable backward compatibility, if desired.
8+
*
9+
* We don't mean for this object to only grow in number of fields, however at the same time
10+
* we won't be very hasty to reduce it. Expect gradual changes.
11+
*/
12+
export const compatibilityFlags = {
13+
/**
14+
* Because of a bug introduced in https://github.com/software-mansion/react-native-screens/pull/1646
15+
* react-native-screens v3.21 changed how header's backTitle handles whitespace strings in https://github.com/software-mansion/react-native-screens/pull/1726
16+
* To allow for backwards compatibility in @react-navigation/native-stack we need a way to check if this version or newer is used.
17+
* See https://github.com/react-navigation/react-navigation/pull/11423 for more context.
18+
*/
19+
isNewBackTitleImplementation: true,
20+
21+
/**
22+
* With version 4.0.0 the header implementation has been changed. To allow for backward compat
23+
* with native-stack@v6 we want to expose a way to check whether the new implementation
24+
* is in use or not.
25+
*
26+
* See:
27+
* * https://github.com/software-mansion/react-native-screens/pull/2325
28+
* * https://github.com/react-navigation/react-navigation/pull/12125
29+
*/
30+
usesHeaderFlexboxImplementation: true,
31+
} as const;
32+
33+
const _featureFlags = {
34+
experiment: {
35+
controlledBottomTabs: RNS_CONTROLLED_BOTTOM_TABS_DEFAULT,
36+
},
37+
stable: {},
38+
};
39+
40+
/**
41+
* Exposes configurable global behaviour of the library.
42+
*
43+
* Most of these can be overridden on particular component level, these are global switches.
44+
*/
45+
export const featureFlags = {
46+
/**
47+
* Flags to enable experimental features. These might be removed w/o notice or moved to stable.
48+
*/
49+
experiment: {
50+
get controlledBottomTabs() {
51+
return _featureFlags.experiment.controlledBottomTabs;
52+
},
53+
set controlledBottomTabs(value: boolean) {
54+
if (
55+
value !== _featureFlags.experiment.controlledBottomTabs &&
56+
_featureFlags.experiment.controlledBottomTabs !==
57+
RNS_CONTROLLED_BOTTOM_TABS_DEFAULT
58+
) {
59+
console.error(
60+
`[RNScreens] controlledBottomTabs feature flag modified for a second time; this might lead to unexpected effects`,
61+
);
62+
}
63+
_featureFlags.experiment.controlledBottomTabs = value;
64+
},
65+
},
66+
/**
67+
* Section for stable flags, which can be used to configure library behaviour.
68+
*/
69+
stable: {},
70+
};
71+
72+
export default featureFlags;

src/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,14 @@ export { default as BottomTabsScreen } from './components/BottomTabsScreen';
4848
*/
4949
export {
5050
isSearchBarAvailableForCurrentPlatform,
51-
compatibilityFlags,
5251
executeNativeBackPress,
5352
} from './utils';
5453

54+
/**
55+
* Flags
56+
*/
57+
export { compatibilityFlags, featureFlags } from './flags';
58+
5559
/**
5660
* Hooks
5761
*/

src/utils.ts

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,3 @@ export function executeNativeBackPress() {
1010
BackHandler.exitApp();
1111
return true;
1212
}
13-
14-
/**
15-
* Exposes information useful for downstream navigation library implementers,
16-
* so they can keep reasonable backward compatibility, if desired.
17-
*
18-
* We don't mean for this object to only grow in number of fields, however at the same time
19-
* we won't be very hasty to reduce it. Expect gradual changes.
20-
*/
21-
export const compatibilityFlags = {
22-
/**
23-
* Because of a bug introduced in https://github.com/software-mansion/react-native-screens/pull/1646
24-
* react-native-screens v3.21 changed how header's backTitle handles whitespace strings in https://github.com/software-mansion/react-native-screens/pull/1726
25-
* To allow for backwards compatibility in @react-navigation/native-stack we need a way to check if this version or newer is used.
26-
* See https://github.com/react-navigation/react-navigation/pull/11423 for more context.
27-
*/
28-
isNewBackTitleImplementation: true,
29-
30-
/**
31-
* With version 4.0.0 the header implementation has been changed. To allow for backward compat
32-
* with native-stack@v6 we want to expose a way to check whether the new implementation
33-
* is in use or not.
34-
*
35-
* See:
36-
* * https://github.com/software-mansion/react-native-screens/pull/2325
37-
* * https://github.com/react-navigation/react-navigation/pull/12125
38-
*/
39-
usesHeaderFlexboxImplementation: true,
40-
};

0 commit comments

Comments
 (0)