rn-system-bar 3.1.7 → 3.1.8

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.
@@ -226,36 +226,70 @@ class SystemBarModule: RCTEventEmitter {
226
226
  }
227
227
 
228
228
  // ═══════════════════════════════════════════════
229
- // 🆕 SCREENCAST
229
+ // 🆕 SYSTEM SCREENCAST (external display / AirPlay mirror)
230
+ // Detects OS-level external screens via UIScreen.
230
231
  // ═══════════════════════════════════════════════
231
232
 
232
- private func currentScreencastMap() -> [String: Any] {
233
+ private func currentSystemScreencastMap() -> [String: Any] {
233
234
  let isCasting = UIScreen.screens.count > 1
234
235
  return [
235
236
  "isCasting": isCasting,
236
237
  "displayName": isCasting ? "External Display" : NSNull(),
238
+ "displays": UIScreen.screens.dropFirst().enumerated().map { idx, _ in
239
+ ["id": idx + 1, "name": "External Display \(idx + 1)", "isValid": true]
240
+ },
237
241
  ]
238
242
  }
239
243
 
240
244
  @objc
241
- func getScreencastInfo(_ resolve: @escaping RCTPromiseResolveBlock,
242
- rejecter reject: RCTPromiseRejectBlock) {
243
- resolve(currentScreencastMap())
245
+ func getSystemScreencastInfo(_ resolve: @escaping RCTPromiseResolveBlock,
246
+ rejecter reject: RCTPromiseRejectBlock) {
247
+ resolve(currentSystemScreencastMap())
244
248
  }
245
249
 
246
- @objc func startScreencastListener() {
250
+ @objc func startSystemScreencastListener() {
247
251
  screencastObserver = NotificationCenter.default.addObserver(
248
252
  forName: UIScreen.didConnectNotification, object: nil, queue: .main
249
253
  ) { [weak self] _ in
250
- self?.emit("SystemBar_ScreencastChange", body: self?.currentScreencastMap() ?? [:])
254
+ self?.emit("SystemBar_SystemScreencastChange", body: self?.currentSystemScreencastMap() ?? [:])
251
255
  }
252
256
  }
253
257
 
254
- @objc func stopScreencastListener() {
258
+ @objc func stopSystemScreencastListener() {
255
259
  if let obs = screencastObserver { NotificationCenter.default.removeObserver(obs) }
256
260
  screencastObserver = nil
257
261
  }
258
262
 
263
+ // ═══════════════════════════════════════════════
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
+
259
293
  // setSecureScreen — iOS doesn't support this via public API (no-op)
260
294
  @objc func setSecureScreen(_ enable: Bool) {}
261
295
 
@@ -295,9 +329,10 @@ class SystemBarModule: RCTEventEmitter {
295
329
  @objc func setNavigationBarButtonStyle(_ style: String) {}
296
330
  @objc func setNavigationBarStyle(_ style: String) {}
297
331
  @objc func setNavigationBarBehavior(_ behavior: String) {}
332
+ // color: hex | "transparent" | "translucent" — Android only
298
333
  @objc func setStatusBarColor(_ color: String) {}
299
334
  @objc func setVolumeHUDVisible(_ visible: Bool) {}
300
335
  @objc func immersiveMode(_ enable: Bool) {}
301
336
  @objc func setStatusBarStyle(_ style: String) {}
302
337
  @objc func setStatusBarVisibility(_ visible: Bool) {}
303
- }
338
+ }
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./src/SystemBar";
2
2
  export * from "./src/types";
3
- export { useSystemBar, useScreencast } from "./src/useSystemBar";
4
- export type { SystemBarConfig } from "./src/useSystemBar";
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";
package/lib/index.js CHANGED
@@ -17,9 +17,20 @@ 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.useScreencast = exports.useSystemBar = void 0;
20
+ exports.useThemeSystemBar = exports.useThemeHook = exports.useSystemScreencast = exports.useSystemBar = exports.useScreencast = exports.useAppCast = exports.useTheme = exports.setGlobalThemeMode = void 0;
21
+ // All imperative JS/TS APIs
21
22
  __exportStar(require("./src/SystemBar"), exports);
23
+ // All TypeScript types
22
24
  __exportStar(require("./src/types"), exports);
25
+ // Theme hook (standalone access)
26
+ var useTheme_1 = require("./src/useTheme");
27
+ Object.defineProperty(exports, "setGlobalThemeMode", { enumerable: true, get: function () { return useTheme_1.setGlobalThemeMode; } });
28
+ Object.defineProperty(exports, "useTheme", { enumerable: true, get: function () { return useTheme_1.useTheme; } });
29
+ // React hooks
23
30
  var useSystemBar_1 = require("./src/useSystemBar");
24
- Object.defineProperty(exports, "useSystemBar", { enumerable: true, get: function () { return useSystemBar_1.useSystemBar; } });
31
+ Object.defineProperty(exports, "useAppCast", { enumerable: true, get: function () { return useSystemBar_1.useAppCast; } });
25
32
  Object.defineProperty(exports, "useScreencast", { enumerable: true, get: function () { return useSystemBar_1.useScreencast; } });
33
+ Object.defineProperty(exports, "useSystemBar", { enumerable: true, get: function () { return useSystemBar_1.useSystemBar; } });
34
+ Object.defineProperty(exports, "useSystemScreencast", { enumerable: true, get: function () { return useSystemBar_1.useSystemScreencast; } });
35
+ Object.defineProperty(exports, "useThemeHook", { enumerable: true, get: function () { return useSystemBar_1.useTheme; } });
36
+ Object.defineProperty(exports, "useThemeSystemBar", { enumerable: true, get: function () { return useSystemBar_1.useThemeSystemBar; } });
@@ -15,7 +15,16 @@ export interface Spec extends TurboModule {
15
15
  setVolumeHUDVisible(visible: boolean): void;
16
16
  keepScreenOn(enable: boolean): void;
17
17
  immersiveMode(enable: boolean): void;
18
+ setSecureScreen(enable: boolean): void;
18
19
  setOrientation(mode: string): void;
20
+ getSystemScreencastInfo(): Promise<Object>;
21
+ startSystemScreencastListener(): void;
22
+ stopSystemScreencastListener(): void;
23
+ startAppCastScan(): void;
24
+ stopAppCastScan(): void;
25
+ connectAppCast(deviceId: string, pairingPin: string | null): void;
26
+ disconnectAppCast(): void;
27
+ getAppCastInfo(): Promise<Object>;
19
28
  }
20
29
  declare const _default: Spec;
21
30
  export default _default;
@@ -1,15 +1,42 @@
1
- import type { NavigationBarBehavior, NavigationBarButtonStyle, NavigationBarStyle, NavigationBarVisibility, Orientation, ScreencastInfo, StatusBarStyle, VolumeStream } from "./types";
2
- export declare const setNavigationBarColor: (color: string) => void;
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
+ */
15
+ export declare const setNavigationBarColor: (color: NavigationBarColorValue) => void;
16
+ /**
17
+ * Hide or show the navigation bar.
18
+ *
19
+ * @param mode `"visible"` | `"hidden"`
20
+ */
3
21
  export declare const setNavigationBarVisibility: (mode: NavigationBarVisibility) => void;
4
22
  export declare const setNavigationBarButtonStyle: (style: NavigationBarButtonStyle) => void;
5
23
  export declare const setNavigationBarStyle: (style: NavigationBarStyle) => void;
6
24
  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
+ export declare const setStatusBarColor: (color: StatusBarColorValue) => void;
7
34
  export declare const setStatusBarStyle: (style: StatusBarStyle) => void;
8
35
  export declare const setStatusBarVisibility: (visible: boolean) => void;
9
36
  export declare const setBrightness: (level: number) => void;
10
37
  export declare const getBrightness: () => Promise<number>;
11
38
  /**
12
- * Subscribe to system brightness changes (polls every 500ms on Android).
39
+ * Subscribe to system brightness changes (polls every 500 ms on Android).
13
40
  * @returns unsubscribe function
14
41
  */
15
42
  export declare const onBrightnessChange: (callback: (brightness: number) => void) => (() => void);
@@ -25,5 +52,56 @@ export declare const keepScreenOn: (enable: boolean) => void;
25
52
  export declare const immersiveMode: (enable: boolean) => void;
26
53
  export declare const setSecureScreen: (enable: boolean) => void;
27
54
  export declare const setOrientation: (mode: Orientation) => void;
28
- export declare const getScreencastInfo: () => Promise<ScreencastInfo>;
29
- export declare const onScreencastChange: (callback: (info: ScreencastInfo) => void) => (() => void);
55
+ /**
56
+ * One-shot snapshot of system-level external display state.
57
+ * Works on both Android (DisplayManager) and iOS (UIScreen.screens).
58
+ */
59
+ export declare const getSystemScreencastInfo: () => Promise<SystemScreencastInfo>;
60
+ /**
61
+ * Subscribe to system external-display changes.
62
+ * Fires when an HDMI / Miracast / AirPlay display connects or disconnects.
63
+ * @returns unsubscribe function
64
+ */
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);
70
+ /**
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).
74
+ */
75
+ export declare const startAppCastScan: () => void;
76
+ /**
77
+ * Stop the device discovery scan.
78
+ */
79
+ export declare const stopAppCastScan: () => void;
80
+ /**
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.
84
+ */
85
+ export declare const connectAppCast: (deviceId: string, pairingPin?: string) => void;
86
+ /**
87
+ * Disconnect the active in-app cast session.
88
+ */
89
+ export declare const disconnectAppCast: () => void;
90
+ /**
91
+ * Get the current in-app cast snapshot (state + device list).
92
+ */
93
+ export declare const getAppCastInfo: () => Promise<AppCastInfo>;
94
+ /**
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
+ *
105
+ * @returns unsubscribe function
106
+ */
107
+ export declare const onAppCastChange: (callback: (info: AppCastInfo) => void) => (() => void);
@@ -5,7 +5,7 @@
5
5
  // All APIs → native Kotlin / iOS Swift.
6
6
  // ─────────────────────────────────────────────
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.onScreencastChange = exports.getScreencastInfo = exports.setOrientation = exports.setSecureScreen = exports.immersiveMode = exports.keepScreenOn = exports.onVolumeChange = exports.setVolumeHUDVisible = exports.getVolume = exports.setVolume = exports.onBrightnessChange = exports.getBrightness = exports.setBrightness = exports.setStatusBarVisibility = exports.setStatusBarStyle = exports.setNavigationBarBehavior = exports.setNavigationBarStyle = exports.setNavigationBarButtonStyle = exports.setNavigationBarVisibility = exports.setNavigationBarColor = void 0;
8
+ exports.onAppCastChange = exports.getAppCastInfo = exports.disconnectAppCast = exports.connectAppCast = exports.stopAppCastScan = exports.startAppCastScan = exports.onScreencastChange = exports.getScreencastInfo = exports.onSystemScreencastChange = exports.getSystemScreencastInfo = exports.setOrientation = exports.setSecureScreen = exports.immersiveMode = exports.keepScreenOn = exports.onVolumeChange = exports.setVolumeHUDVisible = exports.getVolume = exports.setVolume = exports.onBrightnessChange = exports.getBrightness = exports.setBrightness = exports.setStatusBarVisibility = exports.setStatusBarStyle = exports.setStatusBarColor = exports.setNavigationBarBehavior = exports.setNavigationBarStyle = exports.setNavigationBarButtonStyle = exports.setNavigationBarVisibility = exports.setNavigationBarColor = void 0;
9
9
  const react_native_1 = require("react-native");
10
10
  const { SystemBar: Native } = react_native_1.NativeModules;
11
11
  const isAndroid = react_native_1.Platform.OS === "android";
@@ -24,13 +24,31 @@ const checkNative = () => {
24
24
  // ═══════════════════════════════════════════════
25
25
  // NAVIGATION BAR (Android — 100% native)
26
26
  // ═══════════════════════════════════════════════
27
+ /**
28
+ * Set the navigation bar background colour.
29
+ *
30
+ * @param color
31
+ * - Any hex string → solid colour e.g. `"#1a1a2e"`
32
+ * - `"transparent"` → fully transparent (content draws behind bar)
33
+ * - `"translucent"` → semi-transparent (system scrim over content)
34
+ *
35
+ * @example
36
+ * setNavigationBarColor("#000000"); // solid black
37
+ * setNavigationBarColor("transparent"); // glass / edge-to-edge
38
+ * setNavigationBarColor("translucent"); // frosted glass
39
+ */
27
40
  const setNavigationBarColor = (color) => {
28
41
  if (!androidOnly("setNavigationBarColor"))
29
42
  return;
30
43
  checkNative();
31
- Native.setNavigationBarColor(color);
44
+ Native.setNavigationBarColor(color); // Kotlin handles the special values
32
45
  };
33
46
  exports.setNavigationBarColor = setNavigationBarColor;
47
+ /**
48
+ * Hide or show the navigation bar.
49
+ *
50
+ * @param mode `"visible"` | `"hidden"`
51
+ */
34
52
  const setNavigationBarVisibility = (mode) => {
35
53
  if (!androidOnly("setNavigationBarVisibility"))
36
54
  return;
@@ -62,6 +80,21 @@ exports.setNavigationBarBehavior = setNavigationBarBehavior;
62
80
  // ═══════════════════════════════════════════════
63
81
  // STATUS BAR (native — no RN StatusBar)
64
82
  // ═══════════════════════════════════════════════
83
+ /**
84
+ * Set the status bar background colour (Android only).
85
+ *
86
+ * @param color
87
+ * - Any hex string → solid colour
88
+ * - `"transparent"` → fully transparent
89
+ * - `"translucent"` → semi-transparent
90
+ */
91
+ const setStatusBarColor = (color) => {
92
+ if (!androidOnly("setStatusBarColor"))
93
+ return;
94
+ checkNative();
95
+ Native.setStatusBarColor(color);
96
+ };
97
+ exports.setStatusBarColor = setStatusBarColor;
65
98
  const setStatusBarStyle = (style) => {
66
99
  checkNative();
67
100
  Native.setStatusBarStyle(style);
@@ -86,7 +119,7 @@ const getBrightness = () => {
86
119
  };
87
120
  exports.getBrightness = getBrightness;
88
121
  /**
89
- * Subscribe to system brightness changes (polls every 500ms on Android).
122
+ * Subscribe to system brightness changes (polls every 500 ms on Android).
90
123
  * @returns unsubscribe function
91
124
  */
92
125
  const onBrightnessChange = (callback) => {
@@ -166,21 +199,137 @@ const setOrientation = (mode) => {
166
199
  };
167
200
  exports.setOrientation = setOrientation;
168
201
  // ═══════════════════════════════════════════════
169
- // SCREENCAST
202
+ // SYSTEM SCREENCAST (external display / HDMI / Miracast)
203
+ // Reads DisplayManager — detects any externally mirrored display.
170
204
  // ═══════════════════════════════════════════════
171
- const getScreencastInfo = () => {
205
+ /**
206
+ * One-shot snapshot of system-level external display state.
207
+ * Works on both Android (DisplayManager) and iOS (UIScreen.screens).
208
+ */
209
+ const getSystemScreencastInfo = () => {
210
+ checkNative();
211
+ return Native.getSystemScreencastInfo();
212
+ };
213
+ exports.getSystemScreencastInfo = getSystemScreencastInfo;
214
+ /**
215
+ * Subscribe to system external-display changes.
216
+ * Fires when an HDMI / Miracast / AirPlay display connects or disconnects.
217
+ * @returns unsubscribe function
218
+ */
219
+ const onSystemScreencastChange = (callback) => {
172
220
  checkNative();
173
- return Native.getScreencastInfo();
221
+ const { DeviceEventEmitter } = require("react-native");
222
+ Native.startSystemScreencastListener();
223
+ const sub = DeviceEventEmitter.addListener("SystemBar_SystemScreencastChange", callback);
224
+ return () => {
225
+ sub.remove();
226
+ Native.stopSystemScreencastListener();
227
+ };
174
228
  };
175
- exports.getScreencastInfo = getScreencastInfo;
176
- const onScreencastChange = (callback) => {
229
+ exports.onSystemScreencastChange = onSystemScreencastChange;
230
+ // ─────────────────────────────────────────────
231
+ // Legacy aliases (backward compat)
232
+ // ─────────────────────────────────────────────
233
+ /** @deprecated Use getSystemScreencastInfo() */
234
+ exports.getScreencastInfo = exports.getSystemScreencastInfo;
235
+ /** @deprecated Use onSystemScreencastChange() */
236
+ exports.onScreencastChange = exports.onSystemScreencastChange;
237
+ // ═══════════════════════════════════════════════
238
+ // APP-ONLY CAST (MediaRouter — Chromecast / TV)
239
+ // Mirrors only this app's screen — NOT the whole system.
240
+ // Flow: startAppCastScan() → onAppCastChange (devices arrive)
241
+ // → connectAppCast(deviceId) → onAppCastChange (state = "connected")
242
+ // → disconnectAppCast()
243
+ // ═══════════════════════════════════════════════
244
+ /**
245
+ * Start scanning for nearby castable devices (Chromecast, TV, etc.).
246
+ * Listen for results via `onAppCastChange`.
247
+ * Android: uses MediaRouter. iOS: no-op (AirPlay is system-only).
248
+ */
249
+ const startAppCastScan = () => {
250
+ if (!androidOnly("startAppCastScan"))
251
+ return;
252
+ checkNative();
253
+ Native.startAppCastScan();
254
+ };
255
+ exports.startAppCastScan = startAppCastScan;
256
+ /**
257
+ * Stop the device discovery scan.
258
+ */
259
+ const stopAppCastScan = () => {
260
+ if (!androidOnly("stopAppCastScan"))
261
+ return;
262
+ checkNative();
263
+ Native.stopAppCastScan();
264
+ };
265
+ exports.stopAppCastScan = stopAppCastScan;
266
+ /**
267
+ * Connect to a discovered device and begin casting this app's screen.
268
+ * @param deviceId The `id` field from `AppCastDevice` (MediaRouter route ID).
269
+ * @param pairingPin Optional PIN string if `requiresPairing` is true.
270
+ */
271
+ const connectAppCast = (deviceId, pairingPin) => {
272
+ if (!androidOnly("connectAppCast"))
273
+ return;
274
+ checkNative();
275
+ Native.connectAppCast(deviceId, pairingPin !== null && pairingPin !== void 0 ? pairingPin : null);
276
+ };
277
+ exports.connectAppCast = connectAppCast;
278
+ /**
279
+ * Disconnect the active in-app cast session.
280
+ */
281
+ const disconnectAppCast = () => {
282
+ if (!androidOnly("disconnectAppCast"))
283
+ return;
284
+ checkNative();
285
+ Native.disconnectAppCast();
286
+ };
287
+ exports.disconnectAppCast = disconnectAppCast;
288
+ /**
289
+ * Get the current in-app cast snapshot (state + device list).
290
+ */
291
+ const getAppCastInfo = () => {
292
+ if (!isAndroid) {
293
+ return Promise.resolve({
294
+ state: "idle",
295
+ devices: [],
296
+ connectedDevice: null,
297
+ error: null,
298
+ });
299
+ }
300
+ checkNative();
301
+ return Native.getAppCastInfo();
302
+ };
303
+ exports.getAppCastInfo = getAppCastInfo;
304
+ /**
305
+ * Subscribe to in-app cast state changes.
306
+ * Fires on: device discovered/lost, state changes (scanning → connecting → connected),
307
+ * pairing requests, errors.
308
+ *
309
+ * @example
310
+ * const unsub = onAppCastChange((info) => {
311
+ * if (info.state === "connected") console.log("Casting to", info.connectedDevice?.name);
312
+ * if (info.error) console.warn("Cast error:", info.error);
313
+ * });
314
+ *
315
+ * @returns unsubscribe function
316
+ */
317
+ const onAppCastChange = (callback) => {
318
+ if (!isAndroid) {
319
+ // iOS: immediately call with idle state, return no-op
320
+ callback({
321
+ state: "idle",
322
+ devices: [],
323
+ connectedDevice: null,
324
+ error: null,
325
+ });
326
+ return () => { };
327
+ }
177
328
  checkNative();
178
329
  const { DeviceEventEmitter } = require("react-native");
179
- Native.startScreencastListener();
180
- const sub = DeviceEventEmitter.addListener("SystemBar_ScreencastChange", callback);
330
+ const sub = DeviceEventEmitter.addListener("SystemBar_AppCastChange", callback);
181
331
  return () => {
182
332
  sub.remove();
183
- Native.stopScreencastListener();
184
333
  };
185
334
  };
186
- exports.onScreencastChange = onScreencastChange;
335
+ exports.onAppCastChange = onAppCastChange;
@@ -3,6 +3,37 @@ export type NavigationBarButtonStyle = "light" | "dark";
3
3
  export type NavigationBarStyle = "auto" | "inverted" | "light" | "dark";
4
4
  export type NavigationBarVisibility = "visible" | "hidden";
5
5
  export type StatusBarStyle = "light" | "dark";
6
+ /**
7
+ * Navigation bar color value.
8
+ *
9
+ * - Any CSS hex string → solid colour e.g. "#1a1a2e", "#000"
10
+ * - `"transparent"` → fully transparent (FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS +
11
+ * transparent color; content draws behind bar)
12
+ * - `"translucent"` → semi-transparent (FLAG_TRANSLUCENT_NAVIGATION)
13
+ */
14
+ export type NavigationBarColorValue = string | "transparent" | "translucent";
15
+ /**
16
+ * Status bar background color value.
17
+ *
18
+ * - Any CSS hex string → solid colour
19
+ * - `"transparent"` → fully transparent (draws behind content)
20
+ * - `"translucent"` → semi-transparent
21
+ */
22
+ export type StatusBarColorValue = string | "transparent" | "translucent";
23
+ /**
24
+ * "system" → follow the OS Appearance (dark/light).
25
+ * "dark" → force dark.
26
+ * "light" → force light.
27
+ */
28
+ export type ThemeMode = "system" | "dark" | "light";
29
+ export interface ThemeState {
30
+ /** Resolved dark-mode flag. Always a concrete boolean. */
31
+ isDark: boolean;
32
+ /** Currently active override ("system" = following OS). */
33
+ mode: ThemeMode;
34
+ /** Set the override mode. Pass "system" to revert to OS. */
35
+ setMode: (mode: ThemeMode) => void;
36
+ }
6
37
  export type Orientation = "portrait" | "landscape" | "landscape-left" | "landscape-right" | "auto";
7
38
  export type VolumeStream = "music" | "ring" | "notification" | "alarm" | "system";
8
39
  export interface ScreencastDisplay {
@@ -10,8 +41,37 @@ export interface ScreencastDisplay {
10
41
  name: string;
11
42
  isValid: boolean;
12
43
  }
13
- export interface ScreencastInfo {
44
+ /** Result of getSystemScreencastInfo() — physical/HDMI/Miracast external display. */
45
+ export interface SystemScreencastInfo {
14
46
  isCasting: boolean;
15
47
  displayName: string | null;
16
48
  displays: ScreencastDisplay[];
17
49
  }
50
+ /** Connection state of the in-app cast session. */
51
+ export type AppCastState = "idle" | "scanning" | "connecting" | "connected" | "disconnecting";
52
+ /** A discovered castable device (TV, Chromecast, etc.). */
53
+ export interface AppCastDevice {
54
+ /** Unique route ID from MediaRouter. */
55
+ id: string;
56
+ /** Human-readable device name e.g. "Living Room TV". */
57
+ name: string;
58
+ /** Device description / model string (may be null). */
59
+ description: string | null;
60
+ /** Signal strength 0–100, or null if unavailable. */
61
+ signalStrength: number | null;
62
+ /** Whether a pairing/PIN step is required. */
63
+ requiresPairing: boolean;
64
+ }
65
+ /** Full snapshot of in-app cast state. */
66
+ export interface AppCastInfo {
67
+ state: AppCastState;
68
+ /** Devices found during the last scan. */
69
+ devices: AppCastDevice[];
70
+ /** The device currently connected (or connecting). */
71
+ connectedDevice: AppCastDevice | null;
72
+ /** Error message from the last failed operation. */
73
+ error: string | null;
74
+ }
75
+ /** @deprecated Use SystemScreencastInfo */
76
+ export interface ScreencastInfo extends SystemScreencastInfo {
77
+ }
@@ -1,11 +1,11 @@
1
- import type { NavigationBarBehavior, NavigationBarButtonStyle, NavigationBarStyle, NavigationBarVisibility, Orientation, ScreencastInfo, StatusBarStyle } from "./types";
1
+ import type { AppCastInfo, NavigationBarBehavior, NavigationBarButtonStyle, NavigationBarColorValue, NavigationBarStyle, NavigationBarVisibility, Orientation, StatusBarColorValue, StatusBarStyle, SystemScreencastInfo, ThemeMode, ThemeState } from "./types";
2
2
  export interface SystemBarConfig {
3
- navigationBarColor?: string;
3
+ navigationBarColor?: NavigationBarColorValue;
4
4
  navigationBarVisibility?: NavigationBarVisibility;
5
5
  navigationBarButtonStyle?: NavigationBarButtonStyle;
6
6
  navigationBarStyle?: NavigationBarStyle;
7
7
  navigationBarBehavior?: NavigationBarBehavior;
8
- statusBarColor?: string;
8
+ statusBarColor?: StatusBarColorValue;
9
9
  statusBarStyle?: StatusBarStyle;
10
10
  statusBarVisible?: boolean;
11
11
  statusBarAnimated?: boolean;
@@ -16,4 +16,35 @@ export interface SystemBarConfig {
16
16
  secureScreen?: boolean;
17
17
  }
18
18
  export declare const useSystemBar: (config: SystemBarConfig) => void;
19
- export declare const useScreencast: () => ScreencastInfo;
19
+ export interface ThemedSystemBarConfig {
20
+ /** Config applied when the resolved theme is DARK. */
21
+ dark?: SystemBarConfig;
22
+ /** Config applied when the resolved theme is LIGHT. */
23
+ light?: SystemBarConfig;
24
+ /**
25
+ * Static config merged under both themes.
26
+ * Theme-specific (dark/light) values always win.
27
+ */
28
+ base?: SystemBarConfig;
29
+ }
30
+ export declare const useThemeSystemBar: (config: ThemedSystemBarConfig) => ThemeState;
31
+ export { useTheme } from "./useTheme";
32
+ export type { ThemeMode, ThemeState };
33
+ export declare const useSystemScreencast: () => SystemScreencastInfo;
34
+ /** @deprecated Renamed to useSystemScreencast() */
35
+ export declare const useScreencast: () => SystemScreencastInfo;
36
+ export interface UseAppCastReturn extends AppCastInfo {
37
+ /** Start scanning for nearby castable devices (TV, Chromecast, etc.). */
38
+ scan: () => void;
39
+ /** Stop the device discovery scan. */
40
+ stopScan: () => void;
41
+ /**
42
+ * Connect to a discovered device and begin casting this app's screen.
43
+ * @param deviceId The `id` field from `AppCastDevice`.
44
+ * @param pairingPin Optional PIN string if `requiresPairing` is true.
45
+ */
46
+ connect: (deviceId: string, pairingPin?: string) => void;
47
+ /** End the active cast session and return to idle. */
48
+ disconnect: () => void;
49
+ }
50
+ export declare const useAppCast: () => UseAppCastReturn;