Skip to content

Commit a51abf9

Browse files
authored
1.6.0 (#74)
1 parent 7e52c0a commit a51abf9

File tree

4 files changed

+149
-82
lines changed

4 files changed

+149
-82
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,18 @@ const entry: SystemBarsEntry = SystemBars.replaceStackEntry(
191191
);
192192
```
193193

194+
#### SystemBars.setStyle
195+
196+
```ts
197+
SystemBars.setStyle(style /*: SystemBarsProps["style"] */);
198+
```
199+
200+
#### SystemBars.setHidden
201+
202+
```ts
203+
SystemBars.setHidden(style /*: SystemBarsProps["hidden"] */);
204+
```
205+
194206
## Third-party libraries 🧩
195207

196208
If you're an author and your package interferes with edge-to-edge, refer to the [`react-native-is-edge-to-edge` `README.md`](./react-native-is-edge-to-edge) for compatibility instructions.

example/android/app/src/main/res/values/styles.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<style name="AppTheme" parent="Theme.EdgeToEdge">
55
<!-- Customize your theme here. -->
66
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
7-
<item name="enforceNavigationBarContrast">true</item>
7+
<item name="enforceNavigationBarContrast">false</item>
88
</style>
99

1010
</resources>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-edge-to-edge",
3-
"version": "1.5.1",
3+
"version": "1.6.0",
44
"license": "MIT",
55
"description": "Effortlessly enable edge-to-edge display in React Native",
66
"author": "Mathieu Acthernoene <[email protected]>",

src/SystemBars.ts

Lines changed: 135 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,28 @@ import { Appearance, Platform, StatusBar, useColorScheme } from "react-native";
33
import NativeModule from "./specs/NativeEdgeToEdgeModule";
44
import { SystemBarsEntry, SystemBarsProps, SystemBarStyle } from "./types";
55

6-
type MergeableBarStyle = "light" | "dark" | undefined;
6+
type ResolvedBarStyle = "light" | "dark" | undefined;
77

8-
function getColorScheme(): "light" | "dark" {
9-
return Appearance?.getColorScheme() ?? "light";
8+
function isLightColorScheme() {
9+
const colorScheme = Appearance?.getColorScheme() ?? "light";
10+
return colorScheme === "light";
11+
}
12+
13+
function resolveSystemBarStyle(
14+
style: SystemBarStyle | undefined,
15+
): ResolvedBarStyle {
16+
switch (style) {
17+
case "auto":
18+
return isLightColorScheme() ? "dark" : "light";
19+
case "inverted":
20+
return isLightColorScheme() ? "light" : "dark";
21+
default:
22+
return style;
23+
}
1024
}
1125

1226
function toNativeBarStyle(
13-
style: MergeableBarStyle,
27+
style: ResolvedBarStyle,
1428
): "default" | "light-content" | "dark-content" {
1529
return style === "light" || style === "dark" ? `${style}-content` : "default";
1630
}
@@ -43,26 +57,23 @@ function mergeEntriesStack(entriesStack: SystemBarsEntry[]) {
4357
);
4458
}
4559

60+
function resolveProps({ hidden, style }: SystemBarsProps) {
61+
const compactStyle = typeof style === "string";
62+
const compactHidden = typeof hidden === "boolean";
63+
64+
return {
65+
statusBarStyle: compactStyle ? style : style?.statusBar,
66+
navigationBarStyle: compactStyle ? style : style?.navigationBar,
67+
statusBarHidden: compactHidden ? hidden : hidden?.statusBar,
68+
navigationBarHidden: compactHidden ? hidden : hidden?.navigationBar,
69+
};
70+
}
71+
4672
/**
4773
* Returns an object to insert in the props stack from the props.
4874
*/
4975
function createStackEntry(props: SystemBarsProps): SystemBarsEntry {
50-
return {
51-
statusBarStyle:
52-
typeof props.style === "string" ? props.style : props.style?.statusBar,
53-
navigationBarStyle:
54-
typeof props.style === "string"
55-
? props.style
56-
: props.style?.navigationBar,
57-
statusBarHidden:
58-
typeof props.hidden === "boolean"
59-
? props.hidden
60-
: props.hidden?.statusBar,
61-
navigationBarHidden:
62-
typeof props.hidden === "boolean"
63-
? props.hidden
64-
: props.hidden?.navigationBar,
65-
};
76+
return resolveProps(props);
6677
}
6778

6879
const entriesStack: SystemBarsEntry[] = [];
@@ -71,9 +82,9 @@ const entriesStack: SystemBarsEntry[] = [];
7182
let updateImmediate: NodeJS.Immediate | null = null;
7283

7384
// The current merged values from the entries stack.
74-
let currentMergedEntries: {
75-
statusBarStyle: MergeableBarStyle;
76-
navigationBarStyle: MergeableBarStyle;
85+
const currentValues: {
86+
statusBarStyle: ResolvedBarStyle;
87+
navigationBarStyle: ResolvedBarStyle;
7788
statusBarHidden: boolean;
7889
navigationBarHidden: boolean;
7990
} = {
@@ -83,6 +94,53 @@ let currentMergedEntries: {
8394
navigationBarHidden: false,
8495
};
8596

97+
function setStatusBarStyle(style: ResolvedBarStyle) {
98+
if (style !== currentValues.statusBarStyle) {
99+
currentValues.statusBarStyle = style;
100+
101+
const nativeStyle = toNativeBarStyle(style);
102+
103+
if (Platform.OS === "android") {
104+
NativeModule?.setStatusBarStyle(nativeStyle);
105+
} else if (Platform.OS === "ios") {
106+
StatusBar.setBarStyle(nativeStyle, true);
107+
}
108+
}
109+
}
110+
111+
function setNavigationBarStyle(style: ResolvedBarStyle) {
112+
if (style !== currentValues.navigationBarStyle) {
113+
currentValues.navigationBarStyle = style;
114+
115+
if (Platform.OS === "android") {
116+
const nativeStyle = toNativeBarStyle(style);
117+
NativeModule?.setNavigationBarStyle(nativeStyle);
118+
}
119+
}
120+
}
121+
122+
function setStatusBarHidden(hidden: boolean) {
123+
if (hidden !== currentValues.statusBarHidden) {
124+
currentValues.statusBarHidden = hidden;
125+
126+
if (Platform.OS === "android") {
127+
NativeModule?.setStatusBarHidden(hidden);
128+
} else if (Platform.OS === "ios") {
129+
StatusBar.setHidden(hidden, "fade"); // 'slide' doesn't work in this context
130+
}
131+
}
132+
}
133+
134+
function setNavigationBarHidden(hidden: boolean) {
135+
if (hidden !== currentValues.navigationBarHidden) {
136+
currentValues.navigationBarHidden = hidden;
137+
138+
if (Platform.OS === "android") {
139+
NativeModule?.setNavigationBarHidden(hidden);
140+
}
141+
}
142+
}
143+
86144
/**
87145
* Updates the native system bars with the entries from the stack.
88146
*/
@@ -93,59 +151,20 @@ function updateEntriesStack() {
93151
}
94152

95153
updateImmediate = setImmediate(() => {
96-
const isLightColorScheme = getColorScheme() === "light";
97-
const autoBarStyle = isLightColorScheme ? "dark" : "light";
98-
const invertedBarStyle = isLightColorScheme ? "light" : "dark";
99-
100154
const mergedEntries = mergeEntriesStack(entriesStack);
101-
102-
const statusBarStyle: MergeableBarStyle =
103-
mergedEntries.statusBarStyle === "auto"
104-
? autoBarStyle
105-
: mergedEntries.statusBarStyle === "inverted"
106-
? invertedBarStyle
107-
: mergedEntries.statusBarStyle;
108-
109-
const navigationBarStyle: MergeableBarStyle =
110-
mergedEntries.navigationBarStyle === "auto"
111-
? autoBarStyle
112-
: mergedEntries.navigationBarStyle === "inverted"
113-
? invertedBarStyle
114-
: mergedEntries.navigationBarStyle;
115-
116155
const { statusBarHidden, navigationBarHidden } = mergedEntries;
117156

118-
if (statusBarStyle !== currentMergedEntries.statusBarStyle) {
119-
const style = toNativeBarStyle(statusBarStyle);
120-
121-
Platform.OS === "android"
122-
? NativeModule?.setStatusBarStyle(style)
123-
: StatusBar.setBarStyle(style, true);
124-
}
125-
126-
if (statusBarHidden !== currentMergedEntries.statusBarHidden) {
127-
Platform.OS === "android"
128-
? NativeModule?.setStatusBarHidden(statusBarHidden)
129-
: StatusBar.setHidden(statusBarHidden, "fade"); // 'slide' doesn't work in this context
130-
}
131-
132-
if (Platform.OS === "android") {
133-
if (navigationBarStyle !== currentMergedEntries.navigationBarStyle) {
134-
const style = toNativeBarStyle(navigationBarStyle);
135-
NativeModule?.setNavigationBarStyle(style);
136-
}
137-
138-
if (navigationBarHidden !== currentMergedEntries.navigationBarHidden) {
139-
NativeModule?.setNavigationBarHidden(navigationBarHidden);
140-
}
141-
}
157+
const statusBarStyle = resolveSystemBarStyle(
158+
mergedEntries.statusBarStyle,
159+
);
160+
const navigationBarStyle = resolveSystemBarStyle(
161+
mergedEntries.navigationBarStyle,
162+
);
142163

143-
currentMergedEntries = {
144-
statusBarStyle,
145-
navigationBarStyle,
146-
statusBarHidden,
147-
navigationBarHidden,
148-
};
164+
setStatusBarStyle(statusBarStyle);
165+
setNavigationBarStyle(navigationBarStyle);
166+
setStatusBarHidden(statusBarHidden);
167+
setNavigationBarHidden(navigationBarHidden);
149168
});
150169
}
151170
}
@@ -195,14 +214,48 @@ function replaceStackEntry(
195214
return newEntry;
196215
}
197216

198-
export function SystemBars({ hidden, style }: SystemBarsProps) {
199-
const statusBarStyle = typeof style === "string" ? style : style?.statusBar;
200-
const navigationBarStyle =
201-
typeof style === "string" ? style : style?.navigationBar;
202-
const statusBarHidden =
203-
typeof hidden === "boolean" ? hidden : hidden?.statusBar;
204-
const navigationBarHidden =
205-
typeof hidden === "boolean" ? hidden : hidden?.navigationBar;
217+
/**
218+
* Set the SystemBars style.
219+
*
220+
* @param style SystemBars style to set.
221+
*/
222+
function setStyle(style: SystemBarsProps["style"]) {
223+
const props = resolveProps({ style });
224+
225+
const statusBarStyle = resolveSystemBarStyle(props.statusBarStyle);
226+
const navigationBarStyle = resolveSystemBarStyle(props.navigationBarStyle);
227+
228+
if (typeof statusBarStyle === "string") {
229+
setStatusBarStyle(statusBarStyle);
230+
}
231+
if (typeof navigationBarStyle === "string") {
232+
setNavigationBarStyle(navigationBarStyle);
233+
}
234+
}
235+
236+
/**
237+
* Show or hide the SystemBars
238+
*
239+
* @param hidden Hide the SystemBars.
240+
*/
241+
function setHidden(hidden: SystemBarsProps["hidden"]) {
242+
const { statusBarHidden, navigationBarHidden } = resolveProps({ hidden });
243+
244+
if (typeof statusBarHidden === "boolean") {
245+
setStatusBarHidden(statusBarHidden);
246+
}
247+
if (typeof navigationBarHidden === "boolean") {
248+
setNavigationBarHidden(navigationBarHidden);
249+
}
250+
}
251+
252+
export function SystemBars(props: SystemBarsProps) {
253+
const {
254+
statusBarStyle,
255+
navigationBarStyle,
256+
statusBarHidden,
257+
navigationBarHidden,
258+
} = resolveProps(props);
206259

207260
const stableProps = useMemo<SystemBarsProps>(
208261
() => ({
@@ -252,3 +305,5 @@ export function SystemBars({ hidden, style }: SystemBarsProps) {
252305
SystemBars.pushStackEntry = pushStackEntry;
253306
SystemBars.popStackEntry = popStackEntry;
254307
SystemBars.replaceStackEntry = replaceStackEntry;
308+
SystemBars.setStyle = setStyle;
309+
SystemBars.setHidden = setHidden;

0 commit comments

Comments
 (0)