rn-system-bar 3.0.2 → 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.
- package/android/src/main/java/com/systembar/SystemBarModule.kt +334 -247
- package/android/src/main/java/com/systembar/SystemBarPackage.kt +2 -1
- package/index.ts +9 -0
- package/ios/SystemBarModule.m +32 -12
- package/ios/SystemBarModule.swift +241 -83
- package/lib/index.d.ts +4 -0
- package/lib/index.js +29 -0
- package/lib/specs/NativeSystemBar.d.ts +21 -0
- package/lib/specs/NativeSystemBar.js +8 -0
- package/lib/src/SystemBar.d.ts +73 -0
- package/lib/src/SystemBar.js +292 -0
- package/lib/src/types.d.ts +44 -0
- package/lib/src/types.js +5 -0
- package/lib/src/useSystemBar.d.ts +49 -0
- package/lib/src/useSystemBar.js +194 -0
- package/package.json +14 -4
- package/rn-system-bar.podspec +1 -1
- package/src/SystemBar.ts +215 -141
- package/src/types.ts +70 -43
- package/src/useSystemBar.ts +191 -0
package/src/SystemBar.ts
CHANGED
|
@@ -1,236 +1,310 @@
|
|
|
1
1
|
// ─────────────────────────────────────────────
|
|
2
|
-
// rn-system-bar · SystemBar.ts
|
|
2
|
+
// rn-system-bar · SystemBar.ts v5
|
|
3
|
+
// All features — Android + iOS
|
|
3
4
|
// ─────────────────────────────────────────────
|
|
4
5
|
|
|
5
|
-
import { NativeModules, Platform } from "react-native";
|
|
6
|
+
import { NativeModules, Platform, StatusBar, Vibration } from "react-native";
|
|
6
7
|
|
|
7
8
|
import type {
|
|
9
|
+
BatteryInfo,
|
|
10
|
+
FontScaleInfo,
|
|
11
|
+
HapticPattern,
|
|
8
12
|
NavigationBarBehavior,
|
|
9
13
|
NavigationBarButtonStyle,
|
|
10
14
|
NavigationBarStyle,
|
|
11
15
|
NavigationBarVisibility,
|
|
16
|
+
NetworkInfo,
|
|
12
17
|
Orientation,
|
|
18
|
+
ScreencastInfo,
|
|
13
19
|
StatusBarStyle,
|
|
14
20
|
VolumeStream,
|
|
15
21
|
} from "./types";
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
// expo-navigation-bar — peer dep, loaded at runtime
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
25
|
+
const NavBar = (() => {
|
|
26
|
+
try { return require("expo-navigation-bar"); }
|
|
27
|
+
catch { return null; }
|
|
28
|
+
})();
|
|
18
29
|
|
|
19
|
-
|
|
20
|
-
// Navigation-bar APIs are Android-only.
|
|
21
|
-
// iOS has no navigation bar concept.
|
|
22
|
-
// All other APIs work on both platforms.
|
|
30
|
+
const { SystemBar: Native } = NativeModules;
|
|
23
31
|
|
|
24
32
|
const isAndroid = Platform.OS === "android";
|
|
33
|
+
const isIOS = Platform.OS === "ios";
|
|
25
34
|
|
|
26
|
-
const androidOnly = (name: string) => {
|
|
35
|
+
const androidOnly = (name: string): boolean => {
|
|
27
36
|
if (!isAndroid) {
|
|
28
|
-
if (__DEV__) {
|
|
29
|
-
console.warn(
|
|
30
|
-
`[rn-system-bar] ${name}() is Android-only and has no effect on iOS.`
|
|
31
|
-
);
|
|
32
|
-
}
|
|
37
|
+
if (__DEV__) console.warn(`[rn-system-bar] ${name}() is Android-only, no-op on iOS.`);
|
|
33
38
|
return false;
|
|
34
39
|
}
|
|
35
40
|
return true;
|
|
36
41
|
};
|
|
37
42
|
|
|
38
|
-
const
|
|
39
|
-
if (!
|
|
40
|
-
throw new Error(
|
|
41
|
-
"[rn-system-bar] Native module not found. " +
|
|
42
|
-
"Did you forget to run `pod install` (iOS) or rebuild the Android project?"
|
|
43
|
-
);
|
|
44
|
-
}
|
|
43
|
+
const checkNative = () => {
|
|
44
|
+
if (!Native) throw new Error("[rn-system-bar] Native module not found. Rebuild your project.");
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
// ═══════════════════════════════════════════════
|
|
48
|
-
// NAVIGATION BAR (Android-
|
|
48
|
+
// NAVIGATION BAR (Android — expo-navigation-bar)
|
|
49
49
|
// ═══════════════════════════════════════════════
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
* @platform android
|
|
55
|
-
*/
|
|
56
|
-
export const setNavigationBarColor = (color: string): void => {
|
|
57
|
-
if (!androidOnly("setNavigationBarColor")) return;
|
|
58
|
-
checkModule();
|
|
59
|
-
SystemBar.setNavigationBarColor(color);
|
|
51
|
+
export const setNavigationBarColor = (color: string): Promise<void> => {
|
|
52
|
+
if (!androidOnly("setNavigationBarColor")) return Promise.resolve();
|
|
53
|
+
return NavBar?.setBackgroundColorAsync(color) ?? Promise.resolve();
|
|
60
54
|
};
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*/
|
|
66
|
-
export const setNavigationBarVisibility = (
|
|
67
|
-
mode: NavigationBarVisibility
|
|
68
|
-
): void => {
|
|
69
|
-
if (!androidOnly("setNavigationBarVisibility")) return;
|
|
70
|
-
checkModule();
|
|
71
|
-
SystemBar.setNavigationBarVisibility(mode);
|
|
56
|
+
export const setNavigationBarVisibility = (mode: NavigationBarVisibility): Promise<void> => {
|
|
57
|
+
if (!androidOnly("setNavigationBarVisibility")) return Promise.resolve();
|
|
58
|
+
return NavBar?.setVisibilityAsync(mode) ?? Promise.resolve();
|
|
72
59
|
};
|
|
73
60
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
* @platform android
|
|
78
|
-
*/
|
|
79
|
-
export const setNavigationBarButtonStyle = (
|
|
80
|
-
style: NavigationBarButtonStyle
|
|
81
|
-
): void => {
|
|
82
|
-
if (!androidOnly("setNavigationBarButtonStyle")) return;
|
|
83
|
-
checkModule();
|
|
84
|
-
SystemBar.setNavigationBarButtonStyle(style);
|
|
61
|
+
export const setNavigationBarButtonStyle = (style: NavigationBarButtonStyle): Promise<void> => {
|
|
62
|
+
if (!androidOnly("setNavigationBarButtonStyle")) return Promise.resolve();
|
|
63
|
+
return NavBar?.setButtonStyleAsync(style) ?? Promise.resolve();
|
|
85
64
|
};
|
|
86
65
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
export const setNavigationBarStyle = (style: NavigationBarStyle): void => {
|
|
92
|
-
if (!androidOnly("setNavigationBarStyle")) return;
|
|
93
|
-
checkModule();
|
|
94
|
-
SystemBar.setNavigationBarStyle(style);
|
|
66
|
+
export const setNavigationBarStyle = (style: NavigationBarStyle): Promise<void> => {
|
|
67
|
+
if (!androidOnly("setNavigationBarStyle")) return Promise.resolve();
|
|
68
|
+
const btn: NavigationBarButtonStyle = style === "dark" || style === "auto" ? "dark" : "light";
|
|
69
|
+
return NavBar?.setButtonStyleAsync(btn) ?? Promise.resolve();
|
|
95
70
|
};
|
|
96
71
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
*/
|
|
101
|
-
export const setNavigationBarBehavior = (
|
|
102
|
-
behavior: NavigationBarBehavior
|
|
103
|
-
): void => {
|
|
104
|
-
if (!androidOnly("setNavigationBarBehavior")) return;
|
|
105
|
-
checkModule();
|
|
106
|
-
SystemBar.setNavigationBarBehavior(behavior);
|
|
72
|
+
export const setNavigationBarBehavior = (behavior: NavigationBarBehavior): Promise<void> => {
|
|
73
|
+
if (!androidOnly("setNavigationBarBehavior")) return Promise.resolve();
|
|
74
|
+
return NavBar?.setBehaviorAsync(behavior) ?? Promise.resolve();
|
|
107
75
|
};
|
|
108
76
|
|
|
109
77
|
// ═══════════════════════════════════════════════
|
|
110
78
|
// STATUS BAR
|
|
111
79
|
// ═══════════════════════════════════════════════
|
|
112
80
|
|
|
113
|
-
|
|
114
|
-
* Set status bar background color.
|
|
115
|
-
* @param color Hex color string e.g. "#FF0000"
|
|
116
|
-
* @platform android (iOS ignores background color by OS design)
|
|
117
|
-
*/
|
|
118
|
-
export const setStatusBarColor = (color: string): void => {
|
|
81
|
+
export const setStatusBarColor = (color: string, animated = false): void => {
|
|
119
82
|
if (!androidOnly("setStatusBarColor")) return;
|
|
120
|
-
|
|
121
|
-
SystemBar.setStatusBarColor(color);
|
|
83
|
+
StatusBar.setBackgroundColor(color, animated);
|
|
122
84
|
};
|
|
123
85
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
* Works on both Android and iOS.
|
|
127
|
-
*/
|
|
128
|
-
export const setStatusBarStyle = (style: StatusBarStyle): void => {
|
|
129
|
-
checkModule();
|
|
130
|
-
SystemBar.setStatusBarStyle(style);
|
|
86
|
+
export const setStatusBarStyle = (style: StatusBarStyle, animated = false): void => {
|
|
87
|
+
StatusBar.setBarStyle(style === "light" ? "light-content" : "dark-content", animated);
|
|
131
88
|
};
|
|
132
89
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
*/
|
|
136
|
-
export const setStatusBarVisibility = (visible: boolean): void => {
|
|
137
|
-
checkModule();
|
|
138
|
-
SystemBar.setStatusBarVisibility(visible);
|
|
90
|
+
export const setStatusBarVisibility = (visible: boolean, animated = false): void => {
|
|
91
|
+
StatusBar.setHidden(!visible, animated ? "slide" : "none");
|
|
139
92
|
};
|
|
140
93
|
|
|
141
94
|
// ═══════════════════════════════════════════════
|
|
142
95
|
// BRIGHTNESS
|
|
143
96
|
// ═══════════════════════════════════════════════
|
|
144
97
|
|
|
98
|
+
export const setBrightness = (level: number): void => {
|
|
99
|
+
checkNative();
|
|
100
|
+
Native.setBrightness(Math.max(0, Math.min(1, level)));
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const getBrightness = (): Promise<number> => {
|
|
104
|
+
checkNative();
|
|
105
|
+
return Native.getBrightness();
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// ═══════════════════════════════════════════════
|
|
109
|
+
// VOLUME
|
|
110
|
+
// ═══════════════════════════════════════════════
|
|
111
|
+
|
|
112
|
+
export const setVolume = (level: number, stream: VolumeStream = "music"): void => {
|
|
113
|
+
checkNative();
|
|
114
|
+
Native.setVolume(Math.max(0, Math.min(1, level)), stream);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const getVolume = (stream: VolumeStream = "music"): Promise<number> => {
|
|
118
|
+
checkNative();
|
|
119
|
+
return Native.getVolume(stream);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const setVolumeHUDVisible = (visible: boolean): void => {
|
|
123
|
+
if (!androidOnly("setVolumeHUDVisible")) return;
|
|
124
|
+
checkNative();
|
|
125
|
+
Native.setVolumeHUDVisible(visible);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// ═══════════════════════════════════════════════
|
|
129
|
+
// SCREEN
|
|
130
|
+
// ═══════════════════════════════════════════════
|
|
131
|
+
|
|
132
|
+
export const keepScreenOn = (enable: boolean): void => {
|
|
133
|
+
checkNative();
|
|
134
|
+
Native.keepScreenOn(enable);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export const immersiveMode = (enable: boolean): void => {
|
|
138
|
+
if (!androidOnly("immersiveMode")) return;
|
|
139
|
+
checkNative();
|
|
140
|
+
Native.immersiveMode(enable);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// ═══════════════════════════════════════════════
|
|
144
|
+
// ORIENTATION
|
|
145
|
+
// ═══════════════════════════════════════════════
|
|
146
|
+
|
|
147
|
+
export const setOrientation = (mode: Orientation): void => {
|
|
148
|
+
checkNative();
|
|
149
|
+
Native.setOrientation(mode);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// ═══════════════════════════════════════════════
|
|
153
|
+
// 🆕 NETWORK INFO
|
|
154
|
+
// ═══════════════════════════════════════════════
|
|
155
|
+
|
|
145
156
|
/**
|
|
146
|
-
*
|
|
147
|
-
*
|
|
157
|
+
* Get current network connection info.
|
|
158
|
+
* Includes: type, isConnected, isAirplaneMode, ssid, cellularGeneration
|
|
148
159
|
*/
|
|
149
|
-
export const
|
|
150
|
-
|
|
151
|
-
|
|
160
|
+
export const getNetworkInfo = (): Promise<NetworkInfo> => {
|
|
161
|
+
checkNative();
|
|
162
|
+
return Native.getNetworkInfo();
|
|
152
163
|
};
|
|
153
164
|
|
|
154
165
|
/**
|
|
155
|
-
*
|
|
156
|
-
* @returns
|
|
166
|
+
* Subscribe to network changes.
|
|
167
|
+
* @returns unsubscribe function — call it in useEffect cleanup
|
|
168
|
+
* @example
|
|
169
|
+
* const unsub = onNetworkChange((info) => console.log(info));
|
|
170
|
+
* return () => unsub();
|
|
157
171
|
*/
|
|
158
|
-
export const
|
|
159
|
-
|
|
160
|
-
|
|
172
|
+
export const onNetworkChange = (
|
|
173
|
+
callback: (info: NetworkInfo) => void
|
|
174
|
+
): (() => void) => {
|
|
175
|
+
checkNative();
|
|
176
|
+
// Native side emits "SystemBar_NetworkChange" events
|
|
177
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
178
|
+
Native.startNetworkListener();
|
|
179
|
+
const sub = DeviceEventEmitter.addListener("SystemBar_NetworkChange", callback);
|
|
180
|
+
return () => {
|
|
181
|
+
sub.remove();
|
|
182
|
+
Native.stopNetworkListener();
|
|
183
|
+
};
|
|
161
184
|
};
|
|
162
185
|
|
|
163
186
|
// ═══════════════════════════════════════════════
|
|
164
|
-
//
|
|
187
|
+
// 🆕 BATTERY
|
|
165
188
|
// ═══════════════════════════════════════════════
|
|
166
189
|
|
|
167
190
|
/**
|
|
168
|
-
*
|
|
169
|
-
* @param level 0.0 (mute) – 1.0 (max)
|
|
170
|
-
* @param stream Audio stream to target (default: "music")
|
|
191
|
+
* Get current battery info: level (0–100), state, isCharging, isLow.
|
|
171
192
|
*/
|
|
172
|
-
export const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
): void => {
|
|
176
|
-
checkModule();
|
|
177
|
-
SystemBar.setVolume(Math.max(0, Math.min(1, level)), stream);
|
|
193
|
+
export const getBatteryInfo = (): Promise<BatteryInfo> => {
|
|
194
|
+
checkNative();
|
|
195
|
+
return Native.getBatteryInfo();
|
|
178
196
|
};
|
|
179
197
|
|
|
180
198
|
/**
|
|
181
|
-
*
|
|
182
|
-
* @
|
|
183
|
-
* @returns Promise<number> 0.0 – 1.0
|
|
199
|
+
* Subscribe to battery level / state changes.
|
|
200
|
+
* @returns unsubscribe function
|
|
184
201
|
*/
|
|
185
|
-
export const
|
|
186
|
-
|
|
187
|
-
|
|
202
|
+
export const onBatteryChange = (
|
|
203
|
+
callback: (info: BatteryInfo) => void
|
|
204
|
+
): (() => void) => {
|
|
205
|
+
checkNative();
|
|
206
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
207
|
+
Native.startBatteryListener();
|
|
208
|
+
const sub = DeviceEventEmitter.addListener("SystemBar_BatteryChange", callback);
|
|
209
|
+
return () => {
|
|
210
|
+
sub.remove();
|
|
211
|
+
Native.stopBatteryListener();
|
|
212
|
+
};
|
|
188
213
|
};
|
|
189
214
|
|
|
215
|
+
// ═══════════════════════════════════════════════
|
|
216
|
+
// 🆕 HAPTIC FEEDBACK
|
|
217
|
+
// ═══════════════════════════════════════════════
|
|
218
|
+
|
|
190
219
|
/**
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
220
|
+
* Trigger haptic feedback.
|
|
221
|
+
*
|
|
222
|
+
* iOS: Uses UIImpactFeedbackGenerator / UINotificationFeedbackGenerator.
|
|
223
|
+
* Android: Uses Vibrator / VibrationEffect (API 26+).
|
|
224
|
+
*
|
|
225
|
+
* @param pattern "light" | "medium" | "heavy" | "success" | "warning" | "error" | "selection"
|
|
194
226
|
*/
|
|
195
|
-
export const
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
|
|
227
|
+
export const haptic = (pattern: HapticPattern): void => {
|
|
228
|
+
if (isIOS) {
|
|
229
|
+
checkNative();
|
|
230
|
+
Native.haptic(pattern);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Android fallback using RN's built-in Vibration API
|
|
235
|
+
// when native module is unavailable
|
|
236
|
+
if (isAndroid) {
|
|
237
|
+
checkNative();
|
|
238
|
+
Native.haptic(pattern);
|
|
239
|
+
}
|
|
199
240
|
};
|
|
200
241
|
|
|
201
242
|
// ═══════════════════════════════════════════════
|
|
202
|
-
//
|
|
243
|
+
// 🆕 SCREENCAST DETECTION
|
|
203
244
|
// ═══════════════════════════════════════════════
|
|
204
245
|
|
|
205
246
|
/**
|
|
206
|
-
*
|
|
207
|
-
* @param enable true = keep screen on | false = allow sleep
|
|
247
|
+
* Check if screen is currently being cast or mirrored.
|
|
208
248
|
*/
|
|
209
|
-
export const
|
|
210
|
-
|
|
211
|
-
|
|
249
|
+
export const getScreencastInfo = (): Promise<ScreencastInfo> => {
|
|
250
|
+
checkNative();
|
|
251
|
+
return Native.getScreencastInfo();
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Subscribe to screencast state changes (started / stopped).
|
|
256
|
+
* @returns unsubscribe function
|
|
257
|
+
*/
|
|
258
|
+
export const onScreencastChange = (
|
|
259
|
+
callback: (info: ScreencastInfo) => void
|
|
260
|
+
): (() => void) => {
|
|
261
|
+
checkNative();
|
|
262
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
263
|
+
Native.startScreencastListener();
|
|
264
|
+
const sub = DeviceEventEmitter.addListener("SystemBar_ScreencastChange", callback);
|
|
265
|
+
return () => {
|
|
266
|
+
sub.remove();
|
|
267
|
+
Native.stopScreencastListener();
|
|
268
|
+
};
|
|
212
269
|
};
|
|
213
270
|
|
|
214
271
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
272
|
+
* Prevent screen content from appearing in screenshots / recordings.
|
|
273
|
+
* Useful for sensitive screens (payments, passwords).
|
|
217
274
|
* @platform android
|
|
218
275
|
*/
|
|
219
|
-
export const
|
|
220
|
-
if (!androidOnly("
|
|
221
|
-
|
|
222
|
-
|
|
276
|
+
export const setSecureScreen = (enable: boolean): void => {
|
|
277
|
+
if (!androidOnly("setSecureScreen")) return;
|
|
278
|
+
checkNative();
|
|
279
|
+
Native.setSecureScreen(enable);
|
|
223
280
|
};
|
|
224
281
|
|
|
225
282
|
// ═══════════════════════════════════════════════
|
|
226
|
-
//
|
|
283
|
+
// 🆕 FONT SCALE / DISPLAY INFO
|
|
227
284
|
// ═══════════════════════════════════════════════
|
|
228
285
|
|
|
229
286
|
/**
|
|
230
|
-
*
|
|
231
|
-
*
|
|
287
|
+
* Get current system font scale and display density.
|
|
288
|
+
* Useful for adapting layout to accessibility settings.
|
|
232
289
|
*/
|
|
233
|
-
export const
|
|
234
|
-
|
|
235
|
-
|
|
290
|
+
export const getFontScaleInfo = (): Promise<FontScaleInfo> => {
|
|
291
|
+
checkNative();
|
|
292
|
+
return Native.getFontScaleInfo();
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Subscribe to font scale changes (user changes system text size).
|
|
297
|
+
* @returns unsubscribe function
|
|
298
|
+
*/
|
|
299
|
+
export const onFontScaleChange = (
|
|
300
|
+
callback: (info: FontScaleInfo) => void
|
|
301
|
+
): (() => void) => {
|
|
302
|
+
checkNative();
|
|
303
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
304
|
+
Native.startFontScaleListener();
|
|
305
|
+
const sub = DeviceEventEmitter.addListener("SystemBar_FontScaleChange", callback);
|
|
306
|
+
return () => {
|
|
307
|
+
sub.remove();
|
|
308
|
+
Native.stopFontScaleListener();
|
|
309
|
+
};
|
|
236
310
|
};
|
package/src/types.ts
CHANGED
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
// ─────────────────────────────────────────────
|
|
2
|
-
// rn-system-bar · types.ts
|
|
2
|
+
// rn-system-bar · types.ts v5
|
|
3
3
|
// ─────────────────────────────────────────────
|
|
4
4
|
|
|
5
|
+
// ── Navigation Bar ────────────────────────────
|
|
5
6
|
export type NavigationBarBehavior =
|
|
6
|
-
| "overlay-swipe"
|
|
7
|
-
| "inset-swipe"
|
|
8
|
-
| "inset-touch";
|
|
7
|
+
| "overlay-swipe"
|
|
8
|
+
| "inset-swipe"
|
|
9
|
+
| "inset-touch";
|
|
9
10
|
|
|
10
|
-
export type NavigationBarButtonStyle =
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
export type NavigationBarButtonStyle = "light" | "dark";
|
|
12
|
+
export type NavigationBarStyle = "auto" | "inverted" | "light" | "dark";
|
|
13
|
+
export type NavigationBarVisibility = "visible" | "hidden";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
| "inverted" // Inverted from system
|
|
17
|
-
| "light" // Light background nav bar
|
|
18
|
-
| "dark"; // Dark background nav bar
|
|
19
|
-
|
|
20
|
-
export type NavigationBarVisibility =
|
|
21
|
-
| "visible"
|
|
22
|
-
| "hidden";
|
|
23
|
-
|
|
24
|
-
export type StatusBarStyle =
|
|
25
|
-
| "light" // Light icons (for dark backgrounds)
|
|
26
|
-
| "dark"; // Dark icons (for light backgrounds)
|
|
15
|
+
// ── Status Bar ────────────────────────────────
|
|
16
|
+
export type StatusBarStyle = "light" | "dark";
|
|
27
17
|
|
|
18
|
+
// ── Orientation ───────────────────────────────
|
|
28
19
|
export type Orientation =
|
|
29
20
|
| "portrait"
|
|
30
21
|
| "landscape"
|
|
@@ -32,6 +23,7 @@ export type Orientation =
|
|
|
32
23
|
| "landscape-right"
|
|
33
24
|
| "auto";
|
|
34
25
|
|
|
26
|
+
// ── Volume ────────────────────────────────────
|
|
35
27
|
export type VolumeStream =
|
|
36
28
|
| "music"
|
|
37
29
|
| "ring"
|
|
@@ -39,32 +31,67 @@ export type VolumeStream =
|
|
|
39
31
|
| "alarm"
|
|
40
32
|
| "system";
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
// ── Network ───────────────────────────────────
|
|
35
|
+
export type NetworkType =
|
|
36
|
+
| "wifi"
|
|
37
|
+
| "cellular"
|
|
38
|
+
| "ethernet"
|
|
39
|
+
| "none"
|
|
40
|
+
| "unknown";
|
|
41
|
+
|
|
42
|
+
export interface NetworkInfo {
|
|
43
|
+
/** Current connection type */
|
|
44
|
+
type: NetworkType;
|
|
45
|
+
/** true if any network is reachable */
|
|
46
|
+
isConnected: boolean;
|
|
47
|
+
/** true if in airplane mode */
|
|
48
|
+
isAirplaneMode: boolean;
|
|
49
|
+
/** WiFi SSID — Android only; null on iOS / when not connected */
|
|
50
|
+
ssid: string | null;
|
|
51
|
+
/** Cellular network generation: "2G" | "3G" | "4G" | "5G" | null */
|
|
52
|
+
cellularGeneration: "2G" | "3G" | "4G" | "5G" | null;
|
|
53
|
+
}
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
// ── Battery ───────────────────────────────────
|
|
56
|
+
export type BatteryState =
|
|
57
|
+
| "charging"
|
|
58
|
+
| "discharging"
|
|
59
|
+
| "full"
|
|
60
|
+
| "unknown";
|
|
54
61
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
export interface BatteryInfo {
|
|
63
|
+
/** 0–100 */
|
|
64
|
+
level: number;
|
|
65
|
+
/** Current charging state */
|
|
66
|
+
state: BatteryState;
|
|
67
|
+
/** Shorthand: is it plugged in? */
|
|
68
|
+
isCharging: boolean;
|
|
69
|
+
/** Low battery threshold (<= 20%) */
|
|
70
|
+
isLow: boolean;
|
|
71
|
+
}
|
|
58
72
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
73
|
+
// ── Haptics ───────────────────────────────────
|
|
74
|
+
export type HapticPattern =
|
|
75
|
+
| "light" // subtle tap
|
|
76
|
+
| "medium" // standard tap
|
|
77
|
+
| "heavy" // strong tap
|
|
78
|
+
| "success" // double bump — success feedback
|
|
79
|
+
| "warning" // single bump — warning feedback
|
|
80
|
+
| "error" // triple bump — error feedback
|
|
81
|
+
| "selection"; // light tick — selection change
|
|
63
82
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
83
|
+
// ── Screencast ────────────────────────────────
|
|
84
|
+
export interface ScreencastInfo {
|
|
85
|
+
/** true if screen is currently being cast / mirrored */
|
|
86
|
+
isCasting: boolean;
|
|
87
|
+
/** Name of the display being cast to, or null */
|
|
88
|
+
displayName: string | null;
|
|
89
|
+
}
|
|
67
90
|
|
|
68
|
-
|
|
69
|
-
|
|
91
|
+
// ── Font Scale ────────────────────────────────
|
|
92
|
+
export interface FontScaleInfo {
|
|
93
|
+
/** System font scale multiplier, e.g. 1.0 = default, 1.3 = large */
|
|
94
|
+
fontScale: number;
|
|
95
|
+
/** Display density (Android: dp ratio, iOS: scale) */
|
|
96
|
+
density: number;
|
|
70
97
|
}
|