rn-system-bar 3.2.3 → 3.2.5

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.
@@ -1,6 +1,5 @@
1
1
  // ─────────────────────────────────────────────
2
- // rn-system-bar · SystemBarModule.swift v5
3
- // New: Network, Battery, Haptics, Screencast, FontScale
2
+ // rn-system-bar · SystemBarModule.swift
4
3
  // ─────────────────────────────────────────────
5
4
 
6
5
  import Foundation
@@ -18,7 +17,7 @@ class SystemBarModule: RCTEventEmitter {
18
17
  return [
19
18
  "SystemBar_NetworkChange",
20
19
  "SystemBar_BatteryChange",
21
- "SystemBar_ScreencastChange",
20
+ "SystemBar_SystemScreencastChange",
22
21
  "SystemBar_FontScaleChange",
23
22
  ]
24
23
  }
@@ -77,6 +76,9 @@ class SystemBarModule: RCTEventEmitter {
77
76
  DispatchQueue.main.async { UIApplication.shared.isIdleTimerDisabled = enable }
78
77
  }
79
78
 
79
+ // setSecureScreen — iOS doesn't support this via public API (no-op)
80
+ @objc func setSecureScreen(_ enable: Bool) {}
81
+
80
82
  // ═══════════════════════════════════════════════
81
83
  // ORIENTATION
82
84
  // ═══════════════════════════════════════════════
@@ -85,11 +87,11 @@ class SystemBarModule: RCTEventEmitter {
85
87
  DispatchQueue.main.async {
86
88
  var mask: UIInterfaceOrientationMask
87
89
  switch mode {
88
- case "portrait": mask = .portrait
89
- case "landscape": mask = .landscape
90
- case "landscape-left": mask = .landscapeLeft
91
- case "landscape-right":mask = .landscapeRight
92
- default: mask = .all
90
+ case "portrait": mask = .portrait
91
+ case "landscape": mask = .landscape
92
+ case "landscape-left": mask = .landscapeLeft
93
+ case "landscape-right": mask = .landscapeRight
94
+ default: mask = .all
93
95
  }
94
96
  if #available(iOS 16.0, *) {
95
97
  (UIApplication.shared.connectedScenes.first as? UIWindowScene)?
@@ -101,14 +103,13 @@ class SystemBarModule: RCTEventEmitter {
101
103
  }
102
104
 
103
105
  // ═══════════════════════════════════════════════
104
- // 🆕 NETWORK INFO
106
+ // NETWORK INFO
105
107
  // ═══════════════════════════════════════════════
106
108
 
107
109
  private func currentNetworkMap() -> [String: Any] {
108
110
  var isConnected = false
109
111
  var type = "unknown"
110
112
 
111
- // Use NWPathMonitor snapshot via reachability
112
113
  if let reachability = SCNetworkReachabilityCreateWithName(nil, "apple.com") {
113
114
  var flags: SCNetworkReachabilityFlags = []
114
115
  SCNetworkReachabilityGetFlags(reachability, &flags)
@@ -118,13 +119,12 @@ class SystemBarModule: RCTEventEmitter {
118
119
  else { type = "none" }
119
120
  }
120
121
 
121
- let airplaneMode = false // iOS doesn't expose this to apps
122
122
  return [
123
- "type": type,
124
- "isConnected": isConnected,
125
- "isAirplaneMode": airplaneMode,
126
- "ssid": NSNull(),
127
- "cellularGeneration": NSNull(),
123
+ "type": type,
124
+ "isConnected": isConnected,
125
+ "isAirplaneMode": false, // iOS does not expose this to apps
126
+ "ssid": NSNull(),
127
+ "cellularGeneration": NSNull(),
128
128
  ]
129
129
  }
130
130
 
@@ -145,23 +145,24 @@ class SystemBarModule: RCTEventEmitter {
145
145
  }
146
146
 
147
147
  @objc func stopNetworkListener() {
148
- networkMonitor?.cancel(); networkMonitor = nil
148
+ networkMonitor?.cancel()
149
+ networkMonitor = nil
149
150
  }
150
151
 
151
152
  // ═══════════════════════════════════════════════
152
- // 🆕 BATTERY
153
+ // BATTERY
153
154
  // ═══════════════════════════════════════════════
154
155
 
155
156
  private func currentBatteryMap() -> [String: Any] {
156
157
  UIDevice.current.isBatteryMonitoringEnabled = true
157
- let raw = UIDevice.current.batteryLevel // -1 if unknown
158
+ let raw = UIDevice.current.batteryLevel // -1 if unknown
158
159
  let level = raw >= 0 ? Int(raw * 100) : -1
159
160
  let state: String
160
161
  switch UIDevice.current.batteryState {
161
- case .charging: state = "charging"
162
- case .full: state = "full"
163
- case .unplugged: state = "discharging"
164
- default: state = "unknown"
162
+ case .charging: state = "charging"
163
+ case .full: state = "full"
164
+ case .unplugged: state = "discharging"
165
+ default: state = "unknown"
165
166
  }
166
167
  let isCharging = state == "charging" || state == "full"
167
168
  return [
@@ -183,10 +184,12 @@ class SystemBarModule: RCTEventEmitter {
183
184
  UIDevice.current.isBatteryMonitoringEnabled = true
184
185
  let nc = NotificationCenter.default
185
186
  batteryObservers = [
186
- nc.addObserver(forName: UIDevice.batteryLevelDidChangeNotification, object: nil, queue: .main) { [weak self] _ in
187
+ nc.addObserver(forName: UIDevice.batteryLevelDidChangeNotification,
188
+ object: nil, queue: .main) { [weak self] _ in
187
189
  self?.emit("SystemBar_BatteryChange", body: self?.currentBatteryMap() ?? [:])
188
190
  },
189
- nc.addObserver(forName: UIDevice.batteryStateDidChangeNotification, object: nil, queue: .main) { [weak self] _ in
191
+ nc.addObserver(forName: UIDevice.batteryStateDidChangeNotification,
192
+ object: nil, queue: .main) { [weak self] _ in
190
193
  self?.emit("SystemBar_BatteryChange", body: self?.currentBatteryMap() ?? [:])
191
194
  },
192
195
  ]
@@ -199,7 +202,7 @@ class SystemBarModule: RCTEventEmitter {
199
202
  }
200
203
 
201
204
  // ═══════════════════════════════════════════════
202
- // 🆕 HAPTIC FEEDBACK
205
+ // HAPTIC FEEDBACK
203
206
  // ═══════════════════════════════════════════════
204
207
 
205
208
  @objc func haptic(_ pattern: String) {
@@ -226,8 +229,7 @@ class SystemBarModule: RCTEventEmitter {
226
229
  }
227
230
 
228
231
  // ═══════════════════════════════════════════════
229
- // 🆕 SYSTEM SCREENCAST (external display / AirPlay mirror)
230
- // Detects OS-level external screens via UIScreen.
232
+ // SYSTEM SCREENCAST (external display / AirPlay mirror)
231
233
  // ═══════════════════════════════════════════════
232
234
 
233
235
  private func currentSystemScreencastMap() -> [String: Any] {
@@ -251,7 +253,8 @@ class SystemBarModule: RCTEventEmitter {
251
253
  screencastObserver = NotificationCenter.default.addObserver(
252
254
  forName: UIScreen.didConnectNotification, object: nil, queue: .main
253
255
  ) { [weak self] _ in
254
- self?.emit("SystemBar_SystemScreencastChange", body: self?.currentSystemScreencastMap() ?? [:])
256
+ self?.emit("SystemBar_SystemScreencastChange",
257
+ body: self?.currentSystemScreencastMap() ?? [:])
255
258
  }
256
259
  }
257
260
 
@@ -261,45 +264,30 @@ class SystemBarModule: RCTEventEmitter {
261
264
  }
262
265
 
263
266
  // ═══════════════════════════════════════════════
264
- // APP-ONLY CAST (Android MediaRouter — iOS stubs)
265
- // AirPlay is system-managed on iOS; no public API for app-only casting.
266
- // ═══════════════════════════════════════════════
267
-
268
- @objc func startAppCastScan() {
269
- // iOS: AirPlay is system-managed — no-op. Emit idle state.
270
- emit("SystemBar_AppCastChange", body: [
271
- "state": "idle", "devices": [], "connectedDevice": NSNull(), "error": NSNull()
272
- ])
273
- }
274
- @objc func stopAppCastScan() {}
275
-
276
- @objc func connectAppCast(_ deviceId: String, pairingPin: String?) {
277
- emit("SystemBar_AppCastChange", body: [
278
- "state": "idle", "devices": [], "connectedDevice": NSNull(),
279
- "error": "App-only cast not supported on iOS"
280
- ])
281
- }
282
-
283
- @objc func disconnectAppCast() {}
284
-
285
- @objc
286
- func getAppCastInfo(_ resolve: @escaping RCTPromiseResolveBlock,
287
- rejecter reject: RCTPromiseRejectBlock) {
288
- resolve([
289
- "state": "idle", "devices": [], "connectedDevice": NSNull(), "error": NSNull()
290
- ])
291
- }
292
-
293
- // setSecureScreen — iOS doesn't support this via public API (no-op)
294
- @objc func setSecureScreen(_ enable: Bool) {}
295
-
296
- // ═══════════════════════════════════════════════
297
- // 🆕 FONT SCALE
267
+ // FONT SCALE
298
268
  // ═══════════════════════════════════════════════
299
269
 
300
270
  private func currentFontScaleMap() -> [String: Any] {
271
+ let category = UIApplication.shared.preferredContentSizeCategory
272
+ // Map Apple's content size category to a numeric scale factor
273
+ let scale: Double
274
+ switch category {
275
+ case .extraSmall: scale = 0.82
276
+ case .small: scale = 0.88
277
+ case .medium: scale = 0.94
278
+ case .large: scale = 1.00 // default
279
+ case .extraLarge: scale = 1.12
280
+ case .extraExtraLarge: scale = 1.24
281
+ case .extraExtraExtraLarge: scale = 1.35
282
+ case .accessibilityMedium: scale = 1.60
283
+ case .accessibilityLarge: scale = 1.90
284
+ case .accessibilityExtraLarge: scale = 2.35
285
+ case .accessibilityExtraExtraLarge: scale = 2.75
286
+ case .accessibilityExtraExtraExtraLarge: scale = 3.12
287
+ default: scale = 1.00
288
+ }
301
289
  return [
302
- "fontScale": Double(UIApplication.shared.preferredContentSizeCategory == .large ? 1.0 : 1.0),
290
+ "fontScale": scale,
303
291
  "density": Double(UIScreen.main.scale),
304
292
  ]
305
293
  }
@@ -323,16 +311,15 @@ class SystemBarModule: RCTEventEmitter {
323
311
  fontScaleObserver = nil
324
312
  }
325
313
 
326
- // ── Android-only stubs ─────────────────────
314
+ // ── Android-only stubs (no-op on iOS) ─────────
327
315
  @objc func setNavigationBarColor(_ color: String) {}
328
316
  @objc func setNavigationBarVisibility(_ mode: String) {}
329
317
  @objc func setNavigationBarButtonStyle(_ style: String) {}
330
318
  @objc func setNavigationBarStyle(_ style: String) {}
331
319
  @objc func setNavigationBarBehavior(_ behavior: String) {}
332
- // color: hex | "transparent" | "translucent" — Android only
333
320
  @objc func setStatusBarColor(_ color: String) {}
334
- @objc func setVolumeHUDVisible(_ visible: Bool) {}
335
- @objc func immersiveMode(_ enable: Bool) {}
336
321
  @objc func setStatusBarStyle(_ style: String) {}
337
322
  @objc func setStatusBarVisibility(_ visible: Bool) {}
323
+ @objc func setVolumeHUDVisible(_ visible: Bool) {}
324
+ @objc func immersiveMode(_ enable: Bool) {}
338
325
  }
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "./src/SystemBar";
2
2
  export * from "./src/types";
3
3
  export { setGlobalThemeMode, useTheme } from "./src/useTheme";
4
- export { useAppCast, useScreencast, useSystemBar, useSystemScreencast, useTheme as useThemeHook, useThemeSystemBar, } from "./src/useSystemBar";
5
- export type { SystemBarConfig, ThemedSystemBarConfig, UseAppCastReturn, } from "./src/useSystemBar";
4
+ export { useBattery, useFontScale, useNetwork, useScreencast, useSystemBar, useSystemScreencast, useTheme as useThemeHook, useThemeSystemBar, } from "./src/useSystemBar";
5
+ export type { SystemBarConfig, ThemedSystemBarConfig, } from "./src/useSystemBar";
package/lib/index.js CHANGED
@@ -17,7 +17,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
17
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.useThemeSystemBar = exports.useThemeHook = exports.useSystemScreencast = exports.useSystemBar = exports.useScreencast = exports.useAppCast = exports.useTheme = exports.setGlobalThemeMode = void 0;
20
+ exports.useThemeSystemBar = exports.useThemeHook = exports.useSystemScreencast = exports.useSystemBar = exports.useScreencast = exports.useNetwork = exports.useFontScale = exports.useBattery = exports.useTheme = exports.setGlobalThemeMode = void 0;
21
21
  // All imperative JS/TS APIs
22
22
  __exportStar(require("./src/SystemBar"), exports);
23
23
  // All TypeScript types
@@ -28,7 +28,9 @@ Object.defineProperty(exports, "setGlobalThemeMode", { enumerable: true, get: fu
28
28
  Object.defineProperty(exports, "useTheme", { enumerable: true, get: function () { return useTheme_1.useTheme; } });
29
29
  // React hooks
30
30
  var useSystemBar_1 = require("./src/useSystemBar");
31
- Object.defineProperty(exports, "useAppCast", { enumerable: true, get: function () { return useSystemBar_1.useAppCast; } });
31
+ Object.defineProperty(exports, "useBattery", { enumerable: true, get: function () { return useSystemBar_1.useBattery; } });
32
+ Object.defineProperty(exports, "useFontScale", { enumerable: true, get: function () { return useSystemBar_1.useFontScale; } });
33
+ Object.defineProperty(exports, "useNetwork", { enumerable: true, get: function () { return useSystemBar_1.useNetwork; } });
32
34
  Object.defineProperty(exports, "useScreencast", { enumerable: true, get: function () { return useSystemBar_1.useScreencast; } });
33
35
  Object.defineProperty(exports, "useSystemBar", { enumerable: true, get: function () { return useSystemBar_1.useSystemBar; } });
34
36
  Object.defineProperty(exports, "useSystemScreencast", { enumerable: true, get: function () { return useSystemBar_1.useSystemScreencast; } });
@@ -1,42 +1,17 @@
1
- import type { AppCastInfo, NavigationBarBehavior, NavigationBarButtonStyle, NavigationBarColorValue, NavigationBarStyle, NavigationBarVisibility, Orientation, StatusBarColorValue, StatusBarStyle, SystemScreencastInfo, VolumeStream } from "./types";
2
- /**
3
- * Set the navigation bar background colour.
4
- *
5
- * @param color
6
- * - Any hex string → solid colour e.g. `"#1a1a2e"`
7
- * - `"transparent"` → fully transparent (content draws behind bar)
8
- * - `"translucent"` → semi-transparent (system scrim over content)
9
- *
10
- * @example
11
- * setNavigationBarColor("#000000"); // solid black
12
- * setNavigationBarColor("transparent"); // glass / edge-to-edge
13
- * setNavigationBarColor("translucent"); // frosted glass
14
- */
1
+ import type { BatteryInfo, FontScaleInfo, HapticPattern, NavigationBarBehavior, NavigationBarButtonStyle, NavigationBarColorValue, NavigationBarStyle, NavigationBarVisibility, NetworkInfo, Orientation, StatusBarColorValue, StatusBarStyle, SystemScreencastInfo, VolumeStream } from "./types";
15
2
  export declare const setNavigationBarColor: (color: NavigationBarColorValue) => void;
16
- /**
17
- * Hide or show the navigation bar.
18
- *
19
- * @param mode `"visible"` | `"hidden"`
20
- */
21
3
  export declare const setNavigationBarVisibility: (mode: NavigationBarVisibility) => void;
22
4
  export declare const setNavigationBarButtonStyle: (style: NavigationBarButtonStyle) => void;
23
5
  export declare const setNavigationBarStyle: (style: NavigationBarStyle) => void;
24
6
  export declare const setNavigationBarBehavior: (behavior: NavigationBarBehavior) => void;
25
- /**
26
- * Set the status bar background colour (Android only).
27
- *
28
- * @param color
29
- * - Any hex string → solid colour
30
- * - `"transparent"` → fully transparent
31
- * - `"translucent"` → semi-transparent
32
- */
33
7
  export declare const setStatusBarColor: (color: StatusBarColorValue) => void;
34
8
  export declare const setStatusBarStyle: (style: StatusBarStyle) => void;
35
9
  export declare const setStatusBarVisibility: (visible: boolean) => void;
36
10
  export declare const setBrightness: (level: number) => void;
37
11
  export declare const getBrightness: () => Promise<number>;
38
12
  /**
39
- * Subscribe to system brightness changes (polls every 500 ms on Android).
13
+ * Subscribe to system brightness changes.
14
+ * Android: polls every 500 ms. iOS: UIScreen brightness.
40
15
  * @returns unsubscribe function
41
16
  */
42
17
  export declare const onBrightnessChange: (callback: (brightness: number) => void) => (() => void);
@@ -44,7 +19,7 @@ export declare const setVolume: (level: number, stream?: VolumeStream) => void;
44
19
  export declare const getVolume: (stream?: VolumeStream) => Promise<number>;
45
20
  export declare const setVolumeHUDVisible: (visible: boolean) => void;
46
21
  /**
47
- * Subscribe to system volume changes (hardware buttons, other apps).
22
+ * Subscribe to system volume changes.
48
23
  * @returns unsubscribe function
49
24
  */
50
25
  export declare const onVolumeChange: (callback: (volume: number, stream: VolumeStream) => void) => (() => void);
@@ -53,55 +28,49 @@ export declare const immersiveMode: (enable: boolean) => void;
53
28
  export declare const setSecureScreen: (enable: boolean) => void;
54
29
  export declare const setOrientation: (mode: Orientation) => void;
55
30
  /**
56
- * One-shot snapshot of system-level external display state.
57
- * Works on both Android (DisplayManager) and iOS (UIScreen.screens).
31
+ * One-shot snapshot of the current network state.
58
32
  */
59
- export declare const getSystemScreencastInfo: () => Promise<SystemScreencastInfo>;
33
+ export declare const getNetworkInfo: () => Promise<NetworkInfo>;
60
34
  /**
61
- * Subscribe to system external-display changes.
62
- * Fires when an HDMI / Miracast / AirPlay display connects or disconnects.
35
+ * Subscribe to network changes (connectivity, type).
63
36
  * @returns unsubscribe function
64
37
  */
65
- export declare const onSystemScreencastChange: (callback: (info: SystemScreencastInfo) => void) => (() => void);
66
- /** @deprecated Use getSystemScreencastInfo() */
67
- export declare const getScreencastInfo: () => Promise<SystemScreencastInfo>;
68
- /** @deprecated Use onSystemScreencastChange() */
69
- export declare const onScreencastChange: (callback: (info: SystemScreencastInfo) => void) => (() => void);
38
+ export declare const onNetworkChange: (callback: (info: NetworkInfo) => void) => (() => void);
70
39
  /**
71
- * Start scanning for nearby castable devices (Chromecast, TV, etc.).
72
- * Listen for results via `onAppCastChange`.
73
- * Android: uses MediaRouter. iOS: no-op (AirPlay is system-only).
40
+ * One-shot snapshot of the current battery state.
74
41
  */
75
- export declare const startAppCastScan: () => void;
42
+ export declare const getBatteryInfo: () => Promise<BatteryInfo>;
76
43
  /**
77
- * Stop the device discovery scan.
44
+ * Subscribe to battery level / state changes.
45
+ * @returns unsubscribe function
78
46
  */
79
- export declare const stopAppCastScan: () => void;
47
+ export declare const onBatteryChange: (callback: (info: BatteryInfo) => void) => (() => void);
80
48
  /**
81
- * Connect to a discovered device and begin casting this app's screen.
82
- * @param deviceId The `id` field from `AppCastDevice` (MediaRouter route ID).
83
- * @param pairingPin Optional PIN string if `requiresPairing` is true.
49
+ * Trigger a haptic feedback pattern.
50
+ * iOS: UIFeedbackGenerator. Android: Vibrator.
51
+ *
52
+ * @param pattern "light" | "medium" | "heavy" | "success" | "warning" | "error" | "selection"
84
53
  */
85
- export declare const connectAppCast: (deviceId: string, pairingPin?: string) => void;
54
+ export declare const haptic: (pattern?: HapticPattern) => void;
86
55
  /**
87
- * Disconnect the active in-app cast session.
56
+ * One-shot snapshot of system-level external display state.
88
57
  */
89
- export declare const disconnectAppCast: () => void;
58
+ export declare const getSystemScreencastInfo: () => Promise<SystemScreencastInfo>;
90
59
  /**
91
- * Get the current in-app cast snapshot (state + device list).
60
+ * Subscribe to external-display connect / disconnect events.
61
+ * @returns unsubscribe function
92
62
  */
93
- export declare const getAppCastInfo: () => Promise<AppCastInfo>;
63
+ export declare const onSystemScreencastChange: (callback: (info: SystemScreencastInfo) => void) => (() => void);
94
64
  /**
95
- * Subscribe to in-app cast state changes.
96
- * Fires on: device discovered/lost, state changes (scanning → connecting → connected),
97
- * pairing requests, errors.
98
- *
99
- * @example
100
- * const unsub = onAppCastChange((info) => {
101
- * if (info.state === "connected") console.log("Casting to", info.connectedDevice?.name);
102
- * if (info.error) console.warn("Cast error:", info.error);
103
- * });
104
- *
65
+ * One-shot snapshot of the system font scale and screen density.
66
+ */
67
+ export declare const getFontScaleInfo: () => Promise<FontScaleInfo>;
68
+ /**
69
+ * Subscribe to font scale / accessibility text size changes.
105
70
  * @returns unsubscribe function
106
71
  */
107
- export declare const onAppCastChange: (callback: (info: AppCastInfo) => void) => (() => void);
72
+ export declare const onFontScaleChange: (callback: (info: FontScaleInfo) => void) => (() => void);
73
+ /** @deprecated Use getSystemScreencastInfo() */
74
+ export declare const getScreencastInfo: () => Promise<SystemScreencastInfo>;
75
+ /** @deprecated Use onSystemScreencastChange() */
76
+ export declare const onScreencastChange: (callback: (info: SystemScreencastInfo) => void) => (() => void);