rn-system-bar 3.1.0 → 3.1.3

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,13 +1,10 @@
1
1
  "use strict";
2
2
  // ─────────────────────────────────────────────
3
- // rn-system-bar · SystemBar.ts v5
4
- // All features — Android + iOS
3
+ // rn-system-bar · SystemBar.ts
5
4
  // ─────────────────────────────────────────────
6
5
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.onFontScaleChange = exports.getFontScaleInfo = exports.setSecureScreen = exports.onScreencastChange = exports.getScreencastInfo = exports.haptic = exports.onBatteryChange = exports.getBatteryInfo = exports.onNetworkChange = exports.getNetworkInfo = exports.setOrientation = exports.immersiveMode = exports.keepScreenOn = exports.setVolumeHUDVisible = exports.getVolume = exports.setVolume = exports.getBrightness = exports.setBrightness = exports.setStatusBarVisibility = exports.setStatusBarStyle = exports.setStatusBarColor = exports.setNavigationBarBehavior = exports.setNavigationBarStyle = exports.setNavigationBarButtonStyle = exports.setNavigationBarVisibility = exports.setNavigationBarColor = void 0;
6
+ exports.onScreencastChange = exports.getScreencastInfo = exports.setOrientation = exports.setSecureScreen = exports.immersiveMode = exports.keepScreenOn = exports.setVolumeHUDVisible = exports.getVolume = exports.setVolume = exports.getBrightness = exports.setBrightness = exports.setStatusBarVisibility = exports.setStatusBarStyle = exports.setStatusBarColor = exports.setNavigationBarBehavior = exports.setNavigationBarStyle = exports.setNavigationBarButtonStyle = exports.setNavigationBarVisibility = exports.setNavigationBarColor = void 0;
8
7
  const react_native_1 = require("react-native");
9
- // expo-navigation-bar — peer dep, loaded at runtime
10
- // eslint-disable-next-line @typescript-eslint/no-var-requires
11
8
  const NavBar = (() => {
12
9
  try {
13
10
  return require("expo-navigation-bar");
@@ -18,7 +15,6 @@ const NavBar = (() => {
18
15
  })();
19
16
  const { SystemBar: Native } = react_native_1.NativeModules;
20
17
  const isAndroid = react_native_1.Platform.OS === "android";
21
- const isIOS = react_native_1.Platform.OS === "ios";
22
18
  const androidOnly = (name) => {
23
19
  if (!isAndroid) {
24
20
  if (__DEV__)
@@ -32,13 +28,15 @@ const checkNative = () => {
32
28
  throw new Error("[rn-system-bar] Native module not found. Rebuild your project.");
33
29
  };
34
30
  // ═══════════════════════════════════════════════
35
- // NAVIGATION BAR (Android — expo-navigation-bar)
31
+ // NAVIGATION BAR (Android-only)
32
+ // Color → native Window API (edge-to-edge safe)
33
+ // Others → expo-navigation-bar (work in edge-to-edge)
36
34
  // ═══════════════════════════════════════════════
37
35
  const setNavigationBarColor = (color) => {
38
- var _a;
39
36
  if (!androidOnly("setNavigationBarColor"))
40
- return Promise.resolve();
41
- return (_a = NavBar === null || NavBar === void 0 ? void 0 : NavBar.setBackgroundColorAsync(color)) !== null && _a !== void 0 ? _a : Promise.resolve();
37
+ return;
38
+ checkNative();
39
+ Native.setNavigationBarColor(color);
42
40
  };
43
41
  exports.setNavigationBarColor = setNavigationBarColor;
44
42
  const setNavigationBarVisibility = (mode) => {
@@ -89,10 +87,17 @@ const setStatusBarVisibility = (visible, animated = false) => {
89
87
  exports.setStatusBarVisibility = setStatusBarVisibility;
90
88
  // ═══════════════════════════════════════════════
91
89
  // BRIGHTNESS
90
+ //
91
+ // setBrightness → updates BOTH window brightness (instant)
92
+ // AND system brightness (persisted).
93
+ // On first call: opens WRITE_SETTINGS if not granted.
94
+ //
95
+ // getBrightness → reads SYSTEM brightness so slider always
96
+ // matches the device brightness bar.
92
97
  // ═══════════════════════════════════════════════
93
98
  const setBrightness = (level) => {
94
99
  checkNative();
95
- Native.setBrightness(Math.max(0, Math.min(1, level)));
100
+ Native.setBrightness(Math.max(0.01, Math.min(1, level)));
96
101
  };
97
102
  exports.setBrightness = setBrightness;
98
103
  const getBrightness = () => {
@@ -135,6 +140,13 @@ const immersiveMode = (enable) => {
135
140
  Native.immersiveMode(enable);
136
141
  };
137
142
  exports.immersiveMode = immersiveMode;
143
+ const setSecureScreen = (enable) => {
144
+ if (!androidOnly("setSecureScreen"))
145
+ return;
146
+ checkNative();
147
+ Native.setSecureScreen(enable);
148
+ };
149
+ exports.setSecureScreen = setSecureScreen;
138
150
  // ═══════════════════════════════════════════════
139
151
  // ORIENTATION
140
152
  // ═══════════════════════════════════════════════
@@ -144,102 +156,13 @@ const setOrientation = (mode) => {
144
156
  };
145
157
  exports.setOrientation = setOrientation;
146
158
  // ═══════════════════════════════════════════════
147
- // 🆕 NETWORK INFO
148
- // ═══════════════════════════════════════════════
149
- /**
150
- * Get current network connection info.
151
- * Includes: type, isConnected, isAirplaneMode, ssid, cellularGeneration
152
- */
153
- const getNetworkInfo = () => {
154
- checkNative();
155
- return Native.getNetworkInfo();
156
- };
157
- exports.getNetworkInfo = getNetworkInfo;
158
- /**
159
- * Subscribe to network changes.
160
- * @returns unsubscribe function — call it in useEffect cleanup
161
- * @example
162
- * const unsub = onNetworkChange((info) => console.log(info));
163
- * return () => unsub();
164
- */
165
- const onNetworkChange = (callback) => {
166
- checkNative();
167
- // Native side emits "SystemBar_NetworkChange" events
168
- const { DeviceEventEmitter } = require("react-native");
169
- Native.startNetworkListener();
170
- const sub = DeviceEventEmitter.addListener("SystemBar_NetworkChange", callback);
171
- return () => {
172
- sub.remove();
173
- Native.stopNetworkListener();
174
- };
175
- };
176
- exports.onNetworkChange = onNetworkChange;
177
- // ═══════════════════════════════════════════════
178
- // 🆕 BATTERY
179
- // ═══════════════════════════════════════════════
180
- /**
181
- * Get current battery info: level (0–100), state, isCharging, isLow.
182
- */
183
- const getBatteryInfo = () => {
184
- checkNative();
185
- return Native.getBatteryInfo();
186
- };
187
- exports.getBatteryInfo = getBatteryInfo;
188
- /**
189
- * Subscribe to battery level / state changes.
190
- * @returns unsubscribe function
191
- */
192
- const onBatteryChange = (callback) => {
193
- checkNative();
194
- const { DeviceEventEmitter } = require("react-native");
195
- Native.startBatteryListener();
196
- const sub = DeviceEventEmitter.addListener("SystemBar_BatteryChange", callback);
197
- return () => {
198
- sub.remove();
199
- Native.stopBatteryListener();
200
- };
201
- };
202
- exports.onBatteryChange = onBatteryChange;
203
- // ═══════════════════════════════════════════════
204
- // 🆕 HAPTIC FEEDBACK
205
- // ═══════════════════════════════════════════════
206
- /**
207
- * Trigger haptic feedback.
208
- *
209
- * iOS: Uses UIImpactFeedbackGenerator / UINotificationFeedbackGenerator.
210
- * Android: Uses Vibrator / VibrationEffect (API 26+).
211
- *
212
- * @param pattern "light" | "medium" | "heavy" | "success" | "warning" | "error" | "selection"
213
- */
214
- const haptic = (pattern) => {
215
- if (isIOS) {
216
- checkNative();
217
- Native.haptic(pattern);
218
- return;
219
- }
220
- // Android fallback using RN's built-in Vibration API
221
- // when native module is unavailable
222
- if (isAndroid) {
223
- checkNative();
224
- Native.haptic(pattern);
225
- }
226
- };
227
- exports.haptic = haptic;
228
- // ═══════════════════════════════════════════════
229
- // 🆕 SCREENCAST DETECTION
159
+ // SCREENCAST
230
160
  // ═══════════════════════════════════════════════
231
- /**
232
- * Check if screen is currently being cast or mirrored.
233
- */
234
161
  const getScreencastInfo = () => {
235
162
  checkNative();
236
163
  return Native.getScreencastInfo();
237
164
  };
238
165
  exports.getScreencastInfo = getScreencastInfo;
239
- /**
240
- * Subscribe to screencast state changes (started / stopped).
241
- * @returns unsubscribe function
242
- */
243
166
  const onScreencastChange = (callback) => {
244
167
  checkNative();
245
168
  const { DeviceEventEmitter } = require("react-native");
@@ -251,42 +174,3 @@ const onScreencastChange = (callback) => {
251
174
  };
252
175
  };
253
176
  exports.onScreencastChange = onScreencastChange;
254
- /**
255
- * Prevent screen content from appearing in screenshots / recordings.
256
- * Useful for sensitive screens (payments, passwords).
257
- * @platform android
258
- */
259
- const setSecureScreen = (enable) => {
260
- if (!androidOnly("setSecureScreen"))
261
- return;
262
- checkNative();
263
- Native.setSecureScreen(enable);
264
- };
265
- exports.setSecureScreen = setSecureScreen;
266
- // ═══════════════════════════════════════════════
267
- // 🆕 FONT SCALE / DISPLAY INFO
268
- // ═══════════════════════════════════════════════
269
- /**
270
- * Get current system font scale and display density.
271
- * Useful for adapting layout to accessibility settings.
272
- */
273
- const getFontScaleInfo = () => {
274
- checkNative();
275
- return Native.getFontScaleInfo();
276
- };
277
- exports.getFontScaleInfo = getFontScaleInfo;
278
- /**
279
- * Subscribe to font scale changes (user changes system text size).
280
- * @returns unsubscribe function
281
- */
282
- const onFontScaleChange = (callback) => {
283
- checkNative();
284
- const { DeviceEventEmitter } = require("react-native");
285
- Native.startFontScaleListener();
286
- const sub = DeviceEventEmitter.addListener("SystemBar_FontScaleChange", callback);
287
- return () => {
288
- sub.remove();
289
- Native.stopFontScaleListener();
290
- };
291
- };
292
- exports.onFontScaleChange = onFontScaleChange;
@@ -5,40 +5,13 @@ export type NavigationBarVisibility = "visible" | "hidden";
5
5
  export type StatusBarStyle = "light" | "dark";
6
6
  export type Orientation = "portrait" | "landscape" | "landscape-left" | "landscape-right" | "auto";
7
7
  export type VolumeStream = "music" | "ring" | "notification" | "alarm" | "system";
8
- export type NetworkType = "wifi" | "cellular" | "ethernet" | "none" | "unknown";
9
- export interface NetworkInfo {
10
- /** Current connection type */
11
- type: NetworkType;
12
- /** true if any network is reachable */
13
- isConnected: boolean;
14
- /** true if in airplane mode */
15
- isAirplaneMode: boolean;
16
- /** WiFi SSID — Android only; null on iOS / when not connected */
17
- ssid: string | null;
18
- /** Cellular network generation: "2G" | "3G" | "4G" | "5G" | null */
19
- cellularGeneration: "2G" | "3G" | "4G" | "5G" | null;
8
+ export interface ScreencastDisplay {
9
+ id: number;
10
+ name: string;
11
+ isValid: boolean;
20
12
  }
21
- export type BatteryState = "charging" | "discharging" | "full" | "unknown";
22
- export interface BatteryInfo {
23
- /** 0–100 */
24
- level: number;
25
- /** Current charging state */
26
- state: BatteryState;
27
- /** Shorthand: is it plugged in? */
28
- isCharging: boolean;
29
- /** Low battery threshold (<= 20%) */
30
- isLow: boolean;
31
- }
32
- export type HapticPattern = "light" | "medium" | "heavy" | "success" | "warning" | "error" | "selection";
33
13
  export interface ScreencastInfo {
34
- /** true if screen is currently being cast / mirrored */
35
14
  isCasting: boolean;
36
- /** Name of the display being cast to, or null */
37
15
  displayName: string | null;
38
- }
39
- export interface FontScaleInfo {
40
- /** System font scale multiplier, e.g. 1.0 = default, 1.3 = large */
41
- fontScale: number;
42
- /** Display density (Android: dp ratio, iOS: scale) */
43
- density: number;
16
+ displays: ScreencastDisplay[];
44
17
  }
package/lib/src/types.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  // ─────────────────────────────────────────────
3
- // rn-system-bar · types.ts v5
3
+ // rn-system-bar · types.ts
4
4
  // ─────────────────────────────────────────────
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,4 @@
1
- import type { BatteryInfo, FontScaleInfo, HapticPattern, NavigationBarBehavior, NavigationBarButtonStyle, NavigationBarStyle, NavigationBarVisibility, NetworkInfo, Orientation, ScreencastInfo, StatusBarStyle } from "./types";
1
+ import type { NavigationBarBehavior, NavigationBarButtonStyle, NavigationBarStyle, NavigationBarVisibility, Orientation, ScreencastInfo, StatusBarStyle } from "./types";
2
2
  export interface SystemBarConfig {
3
3
  navigationBarColor?: string;
4
4
  navigationBarVisibility?: NavigationBarVisibility;
@@ -16,34 +16,4 @@ export interface SystemBarConfig {
16
16
  secureScreen?: boolean;
17
17
  }
18
18
  export declare const useSystemBar: (config: SystemBarConfig) => void;
19
- /**
20
- * Reactive battery info. Auto-updates on level/state changes.
21
- * @example
22
- * const { level, isCharging, isLow, state } = useBattery();
23
- */
24
- export declare const useBattery: () => BatteryInfo;
25
- /**
26
- * Reactive network info. Auto-updates on connection changes.
27
- * @example
28
- * const { isConnected, type, isAirplaneMode } = useNetwork();
29
- */
30
- export declare const useNetwork: () => NetworkInfo;
31
- /**
32
- * Reactive screencast detection.
33
- * @example
34
- * const { isCasting, displayName } = useScreencast();
35
- */
36
19
  export declare const useScreencast: () => ScreencastInfo;
37
- /**
38
- * Reactive font scale info. Updates when user changes system text size.
39
- * @example
40
- * const { fontScale, density } = useFontScale();
41
- */
42
- export declare const useFontScale: () => FontScaleInfo;
43
- /**
44
- * Returns a stable haptic trigger function.
45
- * @example
46
- * const triggerHaptic = useHaptic();
47
- * <Button onPress={() => triggerHaptic("success")} />
48
- */
49
- export declare const useHaptic: () => (pattern: HapticPattern) => void;
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
  // ─────────────────────────────────────────────
3
- // rn-system-bar · useSystemBar.ts v5
4
- // Hooks: useSystemBar, useBattery, useNetwork,
5
- // useScreencast, useFontScale
3
+ // rn-system-bar · useSystemBar.ts
6
4
  // ─────────────────────────────────────────────
7
5
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
6
  if (k2 === undefined) k2 = k;
@@ -38,7 +36,7 @@ var __importStar = (this && this.__importStar) || (function () {
38
36
  };
39
37
  })();
40
38
  Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.useHaptic = exports.useFontScale = exports.useScreencast = exports.useNetwork = exports.useBattery = exports.useSystemBar = void 0;
39
+ exports.useScreencast = exports.useSystemBar = void 0;
42
40
  const react_1 = require("react");
43
41
  const SystemBar = __importStar(require("./SystemBar"));
44
42
  const useSystemBar = (config) => {
@@ -51,7 +49,7 @@ const useSystemBar = (config) => {
51
49
  const apply = async () => {
52
50
  const p = [];
53
51
  if (config.navigationBarColor !== undefined)
54
- p.push(SystemBar.setNavigationBarColor(config.navigationBarColor));
52
+ SystemBar.setNavigationBarColor(config.navigationBarColor);
55
53
  if (config.navigationBarVisibility !== undefined)
56
54
  p.push(SystemBar.setNavigationBarVisibility(config.navigationBarVisibility));
57
55
  if (config.navigationBarButtonStyle !== undefined)
@@ -87,108 +85,19 @@ const useSystemBar = (config) => {
87
85
  };
88
86
  exports.useSystemBar = useSystemBar;
89
87
  // ─────────────────────────────────────────────
90
- // 🆕 useBattery
88
+ // useScreencast
91
89
  // ─────────────────────────────────────────────
92
- /**
93
- * Reactive battery info. Auto-updates on level/state changes.
94
- * @example
95
- * const { level, isCharging, isLow, state } = useBattery();
96
- */
97
- const useBattery = () => {
98
- const [info, setInfo] = (0, react_1.useState)({
99
- level: -1,
100
- state: "unknown",
101
- isCharging: false,
102
- isLow: false,
103
- });
104
- (0, react_1.useEffect)(() => {
105
- let unsub;
106
- SystemBar.getBatteryInfo().then(setInfo).catch(() => { });
107
- unsub = SystemBar.onBatteryChange(setInfo);
108
- return () => unsub === null || unsub === void 0 ? void 0 : unsub();
109
- }, []);
110
- return info;
111
- };
112
- exports.useBattery = useBattery;
113
- // ─────────────────────────────────────────────
114
- // 🆕 useNetwork
115
- // ─────────────────────────────────────────────
116
- /**
117
- * Reactive network info. Auto-updates on connection changes.
118
- * @example
119
- * const { isConnected, type, isAirplaneMode } = useNetwork();
120
- */
121
- const useNetwork = () => {
122
- const [info, setInfo] = (0, react_1.useState)({
123
- type: "unknown",
124
- isConnected: false,
125
- isAirplaneMode: false,
126
- ssid: null,
127
- cellularGeneration: null,
128
- });
129
- (0, react_1.useEffect)(() => {
130
- let unsub;
131
- SystemBar.getNetworkInfo().then(setInfo).catch(() => { });
132
- unsub = SystemBar.onNetworkChange(setInfo);
133
- return () => unsub === null || unsub === void 0 ? void 0 : unsub();
134
- }, []);
135
- return info;
136
- };
137
- exports.useNetwork = useNetwork;
138
- // ─────────────────────────────────────────────
139
- // 🆕 useScreencast
140
- // ─────────────────────────────────────────────
141
- /**
142
- * Reactive screencast detection.
143
- * @example
144
- * const { isCasting, displayName } = useScreencast();
145
- */
146
90
  const useScreencast = () => {
147
91
  const [info, setInfo] = (0, react_1.useState)({
148
92
  isCasting: false,
149
93
  displayName: null,
94
+ displays: [],
150
95
  });
151
96
  (0, react_1.useEffect)(() => {
152
- let unsub;
153
97
  SystemBar.getScreencastInfo().then(setInfo).catch(() => { });
154
- unsub = SystemBar.onScreencastChange(setInfo);
155
- return () => unsub === null || unsub === void 0 ? void 0 : unsub();
98
+ const unsub = SystemBar.onScreencastChange(setInfo);
99
+ return () => unsub();
156
100
  }, []);
157
101
  return info;
158
102
  };
159
103
  exports.useScreencast = useScreencast;
160
- // ─────────────────────────────────────────────
161
- // 🆕 useFontScale
162
- // ─────────────────────────────────────────────
163
- /**
164
- * Reactive font scale info. Updates when user changes system text size.
165
- * @example
166
- * const { fontScale, density } = useFontScale();
167
- */
168
- const useFontScale = () => {
169
- const [info, setInfo] = (0, react_1.useState)({
170
- fontScale: 1.0,
171
- density: 1.0,
172
- });
173
- (0, react_1.useEffect)(() => {
174
- let unsub;
175
- SystemBar.getFontScaleInfo().then(setInfo).catch(() => { });
176
- unsub = SystemBar.onFontScaleChange(setInfo);
177
- return () => unsub === null || unsub === void 0 ? void 0 : unsub();
178
- }, []);
179
- return info;
180
- };
181
- exports.useFontScale = useFontScale;
182
- // ─────────────────────────────────────────────
183
- // 🆕 useHaptic
184
- // ─────────────────────────────────────────────
185
- /**
186
- * Returns a stable haptic trigger function.
187
- * @example
188
- * const triggerHaptic = useHaptic();
189
- * <Button onPress={() => triggerHaptic("success")} />
190
- */
191
- const useHaptic = () => {
192
- return (pattern) => SystemBar.haptic(pattern);
193
- };
194
- exports.useHaptic = useHaptic;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-system-bar",
3
- "version": "3.1.0",
3
+ "version": "3.1.3",
4
4
  "description": "Control Android & iOS system bars, brightness, volume, orientation and screen flags from React Native.",
5
5
  "main": "lib/index.js",
6
6
  "react-native": "lib/index.js",
@@ -35,7 +35,8 @@
35
35
  },
36
36
  "scripts": {
37
37
  "build": "rimraf lib && npx tsc",
38
- "npm:prepublish": "npm publish --access public"
38
+ "npm:prepublish": "npm publish --access public",
39
+ "installing": "cd .. && npm install rn-system-bar@latest && cd rn-system-bar"
39
40
  },
40
41
  "devDependencies": {
41
42
  "@types/react": "^19.2.14",
@@ -14,7 +14,7 @@ Pod::Spec.new do |s|
14
14
  s.authors = package["author"]
15
15
 
16
16
  s.platforms = { :ios => "13.0" }
17
- # s.source = { :git => "https://github.com/your-org/rn-system-bar.git",
17
+ s.source = { :git => "https://github.com/your-org/rn-system-bar.git",
18
18
  :tag => "v#{s.version}" }
19
19
 
20
20
  s.source_files = "ios/**/*.{h,m,mm,swift}"