rn-system-bar 3.0.3 → 3.1.0

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.
@@ -0,0 +1,191 @@
1
+ // ─────────────────────────────────────────────
2
+ // rn-system-bar · useSystemBar.ts v5
3
+ // Hooks: useSystemBar, useBattery, useNetwork,
4
+ // useScreencast, useFontScale
5
+ // ─────────────────────────────────────────────
6
+
7
+ import { useEffect, useRef, useState } from "react";
8
+ import type {
9
+ BatteryInfo,
10
+ FontScaleInfo,
11
+ HapticPattern,
12
+ NavigationBarBehavior,
13
+ NavigationBarButtonStyle,
14
+ NavigationBarStyle,
15
+ NavigationBarVisibility,
16
+ NetworkInfo,
17
+ Orientation,
18
+ ScreencastInfo,
19
+ StatusBarStyle,
20
+ } from "./types";
21
+ import * as SystemBar from "./SystemBar";
22
+
23
+ // ─────────────────────────────────────────────
24
+ // useSystemBar — apply config safely
25
+ // ─────────────────────────────────────────────
26
+ export interface SystemBarConfig {
27
+ navigationBarColor?: string;
28
+ navigationBarVisibility?: NavigationBarVisibility;
29
+ navigationBarButtonStyle?: NavigationBarButtonStyle;
30
+ navigationBarStyle?: NavigationBarStyle;
31
+ navigationBarBehavior?: NavigationBarBehavior;
32
+ statusBarColor?: string;
33
+ statusBarStyle?: StatusBarStyle;
34
+ statusBarVisible?: boolean;
35
+ statusBarAnimated?: boolean;
36
+ keepScreenOn?: boolean;
37
+ immersiveMode?: boolean;
38
+ brightness?: number;
39
+ orientation?: Orientation;
40
+ secureScreen?: boolean;
41
+ }
42
+
43
+ export const useSystemBar = (config: SystemBarConfig) => {
44
+ const configRef = useRef("");
45
+ const configStr = JSON.stringify(config);
46
+
47
+ useEffect(() => {
48
+ if (configRef.current === configStr) return;
49
+ configRef.current = configStr;
50
+
51
+ const apply = async () => {
52
+ const p: Promise<void>[] = [];
53
+
54
+ if (config.navigationBarColor !== undefined) p.push(SystemBar.setNavigationBarColor(config.navigationBarColor));
55
+ if (config.navigationBarVisibility !== undefined) p.push(SystemBar.setNavigationBarVisibility(config.navigationBarVisibility));
56
+ if (config.navigationBarButtonStyle !== undefined) p.push(SystemBar.setNavigationBarButtonStyle(config.navigationBarButtonStyle));
57
+ if (config.navigationBarStyle !== undefined) p.push(SystemBar.setNavigationBarStyle(config.navigationBarStyle));
58
+ if (config.navigationBarBehavior !== undefined) p.push(SystemBar.setNavigationBarBehavior(config.navigationBarBehavior));
59
+
60
+ await Promise.allSettled(p);
61
+
62
+ if (config.statusBarColor !== undefined) SystemBar.setStatusBarColor(config.statusBarColor, config.statusBarAnimated);
63
+ if (config.statusBarStyle !== undefined) SystemBar.setStatusBarStyle(config.statusBarStyle, config.statusBarAnimated);
64
+ if (config.statusBarVisible !== undefined) SystemBar.setStatusBarVisibility(config.statusBarVisible, config.statusBarAnimated);
65
+ if (config.keepScreenOn !== undefined) SystemBar.keepScreenOn(config.keepScreenOn);
66
+ if (config.immersiveMode !== undefined) SystemBar.immersiveMode(config.immersiveMode);
67
+ if (config.brightness !== undefined) SystemBar.setBrightness(config.brightness);
68
+ if (config.orientation !== undefined) SystemBar.setOrientation(config.orientation);
69
+ if (config.secureScreen !== undefined) SystemBar.setSecureScreen(config.secureScreen);
70
+ };
71
+
72
+ apply().catch(() => {
73
+ if (__DEV__) console.warn("[rn-system-bar] useSystemBar: one or more settings failed.");
74
+ });
75
+ // eslint-disable-next-line react-hooks/exhaustive-deps
76
+ }, [configStr]);
77
+ };
78
+
79
+ // ─────────────────────────────────────────────
80
+ // 🆕 useBattery
81
+ // ─────────────────────────────────────────────
82
+ /**
83
+ * Reactive battery info. Auto-updates on level/state changes.
84
+ * @example
85
+ * const { level, isCharging, isLow, state } = useBattery();
86
+ */
87
+ export const useBattery = () => {
88
+ const [info, setInfo] = useState<BatteryInfo>({
89
+ level: -1,
90
+ state: "unknown",
91
+ isCharging: false,
92
+ isLow: false,
93
+ });
94
+
95
+ useEffect(() => {
96
+ let unsub: (() => void) | undefined;
97
+ SystemBar.getBatteryInfo().then(setInfo).catch(() => {});
98
+ unsub = SystemBar.onBatteryChange(setInfo);
99
+ return () => unsub?.();
100
+ }, []);
101
+
102
+ return info;
103
+ };
104
+
105
+ // ─────────────────────────────────────────────
106
+ // 🆕 useNetwork
107
+ // ─────────────────────────────────────────────
108
+ /**
109
+ * Reactive network info. Auto-updates on connection changes.
110
+ * @example
111
+ * const { isConnected, type, isAirplaneMode } = useNetwork();
112
+ */
113
+ export const useNetwork = () => {
114
+ const [info, setInfo] = useState<NetworkInfo>({
115
+ type: "unknown",
116
+ isConnected: false,
117
+ isAirplaneMode: false,
118
+ ssid: null,
119
+ cellularGeneration: null,
120
+ });
121
+
122
+ useEffect(() => {
123
+ let unsub: (() => void) | undefined;
124
+ SystemBar.getNetworkInfo().then(setInfo).catch(() => {});
125
+ unsub = SystemBar.onNetworkChange(setInfo);
126
+ return () => unsub?.();
127
+ }, []);
128
+
129
+ return info;
130
+ };
131
+
132
+ // ─────────────────────────────────────────────
133
+ // 🆕 useScreencast
134
+ // ─────────────────────────────────────────────
135
+ /**
136
+ * Reactive screencast detection.
137
+ * @example
138
+ * const { isCasting, displayName } = useScreencast();
139
+ */
140
+ export const useScreencast = () => {
141
+ const [info, setInfo] = useState<ScreencastInfo>({
142
+ isCasting: false,
143
+ displayName: null,
144
+ });
145
+
146
+ useEffect(() => {
147
+ let unsub: (() => void) | undefined;
148
+ SystemBar.getScreencastInfo().then(setInfo).catch(() => {});
149
+ unsub = SystemBar.onScreencastChange(setInfo);
150
+ return () => unsub?.();
151
+ }, []);
152
+
153
+ return info;
154
+ };
155
+
156
+ // ─────────────────────────────────────────────
157
+ // 🆕 useFontScale
158
+ // ─────────────────────────────────────────────
159
+ /**
160
+ * Reactive font scale info. Updates when user changes system text size.
161
+ * @example
162
+ * const { fontScale, density } = useFontScale();
163
+ */
164
+ export const useFontScale = () => {
165
+ const [info, setInfo] = useState<FontScaleInfo>({
166
+ fontScale: 1.0,
167
+ density: 1.0,
168
+ });
169
+
170
+ useEffect(() => {
171
+ let unsub: (() => void) | undefined;
172
+ SystemBar.getFontScaleInfo().then(setInfo).catch(() => {});
173
+ unsub = SystemBar.onFontScaleChange(setInfo);
174
+ return () => unsub?.();
175
+ }, []);
176
+
177
+ return info;
178
+ };
179
+
180
+ // ─────────────────────────────────────────────
181
+ // 🆕 useHaptic
182
+ // ─────────────────────────────────────────────
183
+ /**
184
+ * Returns a stable haptic trigger function.
185
+ * @example
186
+ * const triggerHaptic = useHaptic();
187
+ * <Button onPress={() => triggerHaptic("success")} />
188
+ */
189
+ export const useHaptic = () => {
190
+ return (pattern: HapticPattern) => SystemBar.haptic(pattern);
191
+ };