capacitor-plugin-status-bar 2.0.1 → 2.0.2
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/README.md
CHANGED
|
@@ -137,7 +137,7 @@ getSafeAreaInsets() => Promise<SafeAreaInsets>
|
|
|
137
137
|
|
|
138
138
|
Get the safe area insets.
|
|
139
139
|
Returns the insets for status bar, navigation bar, and notch areas.
|
|
140
|
-
Values are in pixels on
|
|
140
|
+
Values are in CSS pixels (dp) on all platforms.
|
|
141
141
|
|
|
142
142
|
**Returns:** <code>Promise<<a href="#safeareainsets">SafeAreaInsets</a>></code>
|
|
143
143
|
|
|
@@ -21,7 +21,6 @@ import androidx.core.view.WindowInsetsCompat;
|
|
|
21
21
|
|
|
22
22
|
import com.getcapacitor.Plugin;
|
|
23
23
|
|
|
24
|
-
import java.util.Objects;
|
|
25
24
|
|
|
26
25
|
/**
|
|
27
26
|
* Android Status Bar utilities with Android 10-15+ (API 29-35+) support.
|
|
@@ -279,60 +278,45 @@ public class StatusBar extends Plugin {
|
|
|
279
278
|
* Returns the insets for status bar, navigation bar, and notch areas.
|
|
280
279
|
*
|
|
281
280
|
* @param activity The activity to get the insets from
|
|
282
|
-
* @return A map containing top, bottom, left, and right inset values in pixels
|
|
281
|
+
* @return A map containing top, bottom, left, and right inset values in dp (density-independent pixels)
|
|
283
282
|
*/
|
|
284
283
|
public java.util.Map<String, Integer> getSafeAreaInsets(Activity activity) {
|
|
285
284
|
Log.d(TAG, "getSafeAreaInsets");
|
|
286
285
|
java.util.Map<String, Integer> insets = new java.util.HashMap<>();
|
|
286
|
+
float density = activity.getResources().getDisplayMetrics().density;
|
|
287
287
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
Log.w(TAG, "getSafeAreaInsets: windowInsets is null");
|
|
315
|
-
}
|
|
288
|
+
View decorView = activity.getWindow().getDecorView();
|
|
289
|
+
WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(decorView);
|
|
290
|
+
|
|
291
|
+
if (windowInsets != null) {
|
|
292
|
+
// Use WindowInsetsCompat for accurate, type-specific insets across all API levels
|
|
293
|
+
androidx.core.graphics.Insets statusBars = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars());
|
|
294
|
+
androidx.core.graphics.Insets navBars = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars());
|
|
295
|
+
androidx.core.graphics.Insets displayCutout = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout());
|
|
296
|
+
|
|
297
|
+
int topPx = Math.max(statusBars.top, displayCutout.top);
|
|
298
|
+
int bottomPx = Math.max(navBars.bottom, displayCutout.bottom);
|
|
299
|
+
int leftPx = Math.max(navBars.left, displayCutout.left);
|
|
300
|
+
int rightPx = Math.max(navBars.right, displayCutout.right);
|
|
301
|
+
|
|
302
|
+
// Convert physical pixels to dp (CSS pixels) for the WebView layer
|
|
303
|
+
insets.put("top", Math.round(topPx / density));
|
|
304
|
+
insets.put("bottom", Math.round(bottomPx / density));
|
|
305
|
+
insets.put("left", Math.round(leftPx / density));
|
|
306
|
+
insets.put("right", Math.round(rightPx / density));
|
|
307
|
+
|
|
308
|
+
Log.d(TAG, "getSafeAreaInsets: topPx=" + topPx + " bottomPx=" + bottomPx
|
|
309
|
+
+ " density=" + density
|
|
310
|
+
+ " -> top=" + insets.get("top") + "dp"
|
|
311
|
+
+ " bottom=" + insets.get("bottom") + "dp"
|
|
312
|
+
+ " left=" + insets.get("left") + "dp"
|
|
313
|
+
+ " right=" + insets.get("right") + "dp");
|
|
316
314
|
} else {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
insets.put("right", windowInsets.getSystemWindowInsetRight());
|
|
323
|
-
|
|
324
|
-
Log.d(TAG, "getSafeAreaInsets (API 29): top=" + insets.get("top")
|
|
325
|
-
+ ", bottom=" + insets.get("bottom")
|
|
326
|
-
+ ", left=" + insets.get("left")
|
|
327
|
-
+ ", right=" + insets.get("right"));
|
|
328
|
-
} else {
|
|
329
|
-
// Fallback to zero insets
|
|
330
|
-
insets.put("top", 0);
|
|
331
|
-
insets.put("bottom", 0);
|
|
332
|
-
insets.put("left", 0);
|
|
333
|
-
insets.put("right", 0);
|
|
334
|
-
Log.w(TAG, "getSafeAreaInsets: windowInsets is null");
|
|
335
|
-
}
|
|
315
|
+
insets.put("top", 0);
|
|
316
|
+
insets.put("bottom", 0);
|
|
317
|
+
insets.put("left", 0);
|
|
318
|
+
insets.put("right", 0);
|
|
319
|
+
Log.w(TAG, "getSafeAreaInsets: windowInsets is null");
|
|
336
320
|
}
|
|
337
321
|
|
|
338
322
|
return insets;
|
|
@@ -432,26 +416,37 @@ public class StatusBar extends Plugin {
|
|
|
432
416
|
// Add to the top of the decor view
|
|
433
417
|
decorView.addView(overlay);
|
|
434
418
|
|
|
435
|
-
//
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
419
|
+
// Listen on decorView for reliable insets dispatch across all API levels,
|
|
420
|
+
// then use WindowInsetsCompat.Type.statusBars() for accurate status-bar-only height
|
|
421
|
+
ViewCompat.setOnApplyWindowInsetsListener(decorView, (v, windowInsets) -> {
|
|
422
|
+
int top = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
|
|
423
|
+
View statusOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
|
|
424
|
+
if (statusOverlay != null) {
|
|
425
|
+
ViewGroup.LayoutParams params = statusOverlay.getLayoutParams();
|
|
426
|
+
if (params.height != top) {
|
|
427
|
+
params.height = top;
|
|
428
|
+
statusOverlay.setLayoutParams(params);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
int bottom = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
|
433
|
+
View navOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
|
|
434
|
+
if (navOverlay != null) {
|
|
435
|
+
ViewGroup.LayoutParams params = navOverlay.getLayoutParams();
|
|
436
|
+
if (params.height != bottom) {
|
|
437
|
+
params.height = bottom;
|
|
438
|
+
navOverlay.setLayoutParams(params);
|
|
439
|
+
}
|
|
443
440
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
v.setLayoutParams(params);
|
|
447
|
-
// Don't set color here - it's set before listener and should not be overridden
|
|
441
|
+
|
|
442
|
+
ViewCompat.onApplyWindowInsets(v, windowInsets);
|
|
448
443
|
return windowInsets;
|
|
449
444
|
});
|
|
450
|
-
|
|
445
|
+
decorView.requestApplyInsets();
|
|
451
446
|
} else {
|
|
452
447
|
Log.d(TAG, "ensureStatusBarOverlay: updating existing overlay");
|
|
453
448
|
existing.setBackgroundColor(color);
|
|
454
|
-
|
|
449
|
+
decorView.requestApplyInsets();
|
|
455
450
|
}
|
|
456
451
|
}
|
|
457
452
|
|
|
@@ -483,25 +478,39 @@ public class StatusBar extends Plugin {
|
|
|
483
478
|
|
|
484
479
|
decorView.addView(overlay);
|
|
485
480
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
481
|
+
// Insets sizing is handled by the shared decorView listener in ensureStatusBarOverlay.
|
|
482
|
+
// If status bar overlay was not created yet, set up the listener here.
|
|
483
|
+
if (decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG) == null) {
|
|
484
|
+
ViewCompat.setOnApplyWindowInsetsListener(decorView, (v, windowInsets) -> {
|
|
485
|
+
int top = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
|
|
486
|
+
View statusOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
|
|
487
|
+
if (statusOverlay != null) {
|
|
488
|
+
ViewGroup.LayoutParams params = statusOverlay.getLayoutParams();
|
|
489
|
+
if (params.height != top) {
|
|
490
|
+
params.height = top;
|
|
491
|
+
statusOverlay.setLayoutParams(params);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
int bottom = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
|
496
|
+
View navOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
|
|
497
|
+
if (navOverlay != null) {
|
|
498
|
+
ViewGroup.LayoutParams params = navOverlay.getLayoutParams();
|
|
499
|
+
if (params.height != bottom) {
|
|
500
|
+
params.height = bottom;
|
|
501
|
+
navOverlay.setLayoutParams(params);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
ViewCompat.onApplyWindowInsets(v, windowInsets);
|
|
506
|
+
return windowInsets;
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
decorView.requestApplyInsets();
|
|
501
510
|
} else {
|
|
502
511
|
Log.d(TAG, "ensureNavBarOverlay: updating existing overlay");
|
|
503
512
|
existing.setBackgroundColor(color);
|
|
504
|
-
|
|
513
|
+
decorView.requestApplyInsets();
|
|
505
514
|
}
|
|
506
515
|
}
|
|
507
516
|
|
package/dist/docs.json
CHANGED
|
@@ -150,7 +150,7 @@
|
|
|
150
150
|
"parameters": [],
|
|
151
151
|
"returns": "Promise<SafeAreaInsets>",
|
|
152
152
|
"tags": [],
|
|
153
|
-
"docs": "Get the safe area insets.\nReturns the insets for status bar, navigation bar, and notch areas.\nValues are in pixels on
|
|
153
|
+
"docs": "Get the safe area insets.\nReturns the insets for status bar, navigation bar, and notch areas.\nValues are in CSS pixels (dp) on all platforms.",
|
|
154
154
|
"complexTypes": [
|
|
155
155
|
"SafeAreaInsets"
|
|
156
156
|
],
|
|
@@ -90,7 +90,7 @@ export interface StatusBarPlugin {
|
|
|
90
90
|
/**
|
|
91
91
|
* Get the safe area insets.
|
|
92
92
|
* Returns the insets for status bar, navigation bar, and notch areas.
|
|
93
|
-
* Values are in pixels on
|
|
93
|
+
* Values are in CSS pixels (dp) on all platforms.
|
|
94
94
|
*/
|
|
95
95
|
getSafeAreaInsets(): Promise<SafeAreaInsets>;
|
|
96
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,KAIX;AAJD,WAAY,KAAK;IACf,wBAAe,CAAA;IACf,sBAAa,CAAA;IACb,0BAAiB,CAAA;AACnB,CAAC,EAJW,KAAK,KAAL,KAAK,QAIhB;AAWD,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,mCAAa,CAAA;IACb,mCAAa,CAAA;IACb,qCAAe,CAAA;AACjB,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["export enum Style {\n LIGHT = 'LIGHT',\n DARK = 'DARK',\n CUSTOM = 'CUSTOM',\n}\n\n/**\n * Full HEX color format only (6 or 8 digits).\n * - 6 digits: #RRGGBB (e.g., #FFFFFF, #000000, #FF5733)\n * - 8 digits: #RRGGBBAA with alpha channel (e.g., #FFFFFF00, #FF5733CC)\n *\n * Note: Short 3-digit format (#FFF) is NOT supported.\n */\nexport type StatusBarColor = `#${string}`;\n\nexport enum StatusBarAnimation {\n NONE = 'none',\n FADE = 'fade',\n SLIDE = 'slide',\n}\n\ntype StatusBarStyleNoDefaultOptions = {\n style: Style;\n};\n\ntype StatusBarStyleOptions =\n | StatusBarStyleNoDefaultOptions\n | {\n style: Style.CUSTOM;\n color: StatusBarColor;\n };\n\nexport type StatusBarOptions = StatusBarStyleOptions;\n\nexport type StatusBarShowOptions = {\n animated: boolean;\n};\n\nexport type StatusBarHideOptions = {\n /**\n * The animation type for hiding the status bar.\n * - 'fade': Makes the background transparent without removing the status bar and navigation bar.\n * - 'slide': Hides the status bar and navigation bar completely (default behavior).\n */\n animation: StatusBarAnimation;\n};\n\nexport type StatusBarSetOverlaysWebViewOptions = {\n value: boolean;\n};\n\nexport type StatusBarSetBackgroundOptions = {\n color: StatusBarColor;\n};\n\nexport type SafeAreaInsets = {\n top: number;\n bottom: number;\n left: number;\n right: number;\n};\n\nexport interface StatusBarPlugin {\n /**\n * Set the status bar and navigation bar style and color.\n * @param options - The options to set the status bar style and color.\n * @param options.style - The style of the status bar.\n * @param options.color - The color of the status bar.\n */\n setStyle(options: StatusBarOptions): Promise<void>;\n /**\n * Show the status bar.\n * @param options - The options to show the status bar.\n * @param options.animated - Whether to animate the status bar.\n */\n show(options: StatusBarShowOptions): Promise<void>;\n /**\n * Hide the status bar.\n * @param options - The options to hide the status bar.\n * @param options.animation - The animation type: 'fade' makes background transparent, 'slide' hides bars completely.\n */\n hide(options: StatusBarHideOptions): Promise<void>;\n /**\n * Set whether the status bar overlays the web view.\n *\n * **iOS only** - On Android this is a no-op (resolves without error).\n *\n * - `true`: Web content extends behind the status bar (transparent background),\n * allowing content to be visible through the status bar area on scroll.\n * - `false`: Restores the status bar background to the color set by `setStyle`\n * or falls back to the default style from Capacitor config.\n *\n * @param options - The options to set the status bar overlays web view.\n * @param options.value - Whether the status bar overlays the web view (required).\n */\n setOverlaysWebView(options: StatusBarSetOverlaysWebViewOptions): Promise<void>;\n /**\n * Set the window background color.\n * @param options - The options to set the window background color.\n * @param options.color - The background color in HEX format.\n */\n setBackground(options: StatusBarSetBackgroundOptions): Promise<void>;\n /**\n * Get the safe area insets.\n * Returns the insets for status bar, navigation bar, and notch areas.\n * Values are in pixels on
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,KAIX;AAJD,WAAY,KAAK;IACf,wBAAe,CAAA;IACf,sBAAa,CAAA;IACb,0BAAiB,CAAA;AACnB,CAAC,EAJW,KAAK,KAAL,KAAK,QAIhB;AAWD,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,mCAAa,CAAA;IACb,mCAAa,CAAA;IACb,qCAAe,CAAA;AACjB,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["export enum Style {\n LIGHT = 'LIGHT',\n DARK = 'DARK',\n CUSTOM = 'CUSTOM',\n}\n\n/**\n * Full HEX color format only (6 or 8 digits).\n * - 6 digits: #RRGGBB (e.g., #FFFFFF, #000000, #FF5733)\n * - 8 digits: #RRGGBBAA with alpha channel (e.g., #FFFFFF00, #FF5733CC)\n *\n * Note: Short 3-digit format (#FFF) is NOT supported.\n */\nexport type StatusBarColor = `#${string}`;\n\nexport enum StatusBarAnimation {\n NONE = 'none',\n FADE = 'fade',\n SLIDE = 'slide',\n}\n\ntype StatusBarStyleNoDefaultOptions = {\n style: Style;\n};\n\ntype StatusBarStyleOptions =\n | StatusBarStyleNoDefaultOptions\n | {\n style: Style.CUSTOM;\n color: StatusBarColor;\n };\n\nexport type StatusBarOptions = StatusBarStyleOptions;\n\nexport type StatusBarShowOptions = {\n animated: boolean;\n};\n\nexport type StatusBarHideOptions = {\n /**\n * The animation type for hiding the status bar.\n * - 'fade': Makes the background transparent without removing the status bar and navigation bar.\n * - 'slide': Hides the status bar and navigation bar completely (default behavior).\n */\n animation: StatusBarAnimation;\n};\n\nexport type StatusBarSetOverlaysWebViewOptions = {\n value: boolean;\n};\n\nexport type StatusBarSetBackgroundOptions = {\n color: StatusBarColor;\n};\n\nexport type SafeAreaInsets = {\n top: number;\n bottom: number;\n left: number;\n right: number;\n};\n\nexport interface StatusBarPlugin {\n /**\n * Set the status bar and navigation bar style and color.\n * @param options - The options to set the status bar style and color.\n * @param options.style - The style of the status bar.\n * @param options.color - The color of the status bar.\n */\n setStyle(options: StatusBarOptions): Promise<void>;\n /**\n * Show the status bar.\n * @param options - The options to show the status bar.\n * @param options.animated - Whether to animate the status bar.\n */\n show(options: StatusBarShowOptions): Promise<void>;\n /**\n * Hide the status bar.\n * @param options - The options to hide the status bar.\n * @param options.animation - The animation type: 'fade' makes background transparent, 'slide' hides bars completely.\n */\n hide(options: StatusBarHideOptions): Promise<void>;\n /**\n * Set whether the status bar overlays the web view.\n *\n * **iOS only** - On Android this is a no-op (resolves without error).\n *\n * - `true`: Web content extends behind the status bar (transparent background),\n * allowing content to be visible through the status bar area on scroll.\n * - `false`: Restores the status bar background to the color set by `setStyle`\n * or falls back to the default style from Capacitor config.\n *\n * @param options - The options to set the status bar overlays web view.\n * @param options.value - Whether the status bar overlays the web view (required).\n */\n setOverlaysWebView(options: StatusBarSetOverlaysWebViewOptions): Promise<void>;\n /**\n * Set the window background color.\n * @param options - The options to set the window background color.\n * @param options.color - The background color in HEX format.\n */\n setBackground(options: StatusBarSetBackgroundOptions): Promise<void>;\n /**\n * Get the safe area insets.\n * Returns the insets for status bar, navigation bar, and notch areas.\n * Values are in CSS pixels (dp) on all platforms.\n */\n getSafeAreaInsets(): Promise<SafeAreaInsets>;\n}\n"]}
|
|
@@ -230,13 +230,19 @@ import Capacitor
|
|
|
230
230
|
|
|
231
231
|
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
|
232
232
|
let window = windowScene.windows.first {
|
|
233
|
+
// Use statusBarManager for accurate status bar height
|
|
234
|
+
let statusBarHeight = windowScene.statusBarManager?.statusBarFrame.height ?? 0
|
|
233
235
|
let safeAreaInsets = window.safeAreaInsets
|
|
234
|
-
|
|
236
|
+
|
|
237
|
+
// top: status bar height specifically
|
|
238
|
+
insets["top"] = statusBarHeight
|
|
239
|
+
// bottom: home indicator / navigation bar area
|
|
235
240
|
insets["bottom"] = safeAreaInsets.bottom
|
|
241
|
+
// left/right: safe area for landscape / display cutouts
|
|
236
242
|
insets["left"] = safeAreaInsets.left
|
|
237
243
|
insets["right"] = safeAreaInsets.right
|
|
238
244
|
|
|
239
|
-
print("StatusBar: getSafeAreaInsets - top=\(
|
|
245
|
+
print("StatusBar: getSafeAreaInsets - top=\(statusBarHeight), bottom=\(safeAreaInsets.bottom), left=\(safeAreaInsets.left), right=\(safeAreaInsets.right)")
|
|
240
246
|
} else {
|
|
241
247
|
print("StatusBar: getSafeAreaInsets - Unable to get window, returning zero insets")
|
|
242
248
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "capacitor-plugin-status-bar",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Capacitor plugin for managing the status bar style, visibility, and color on iOS and Android. Control overlay modes, background colors, and appearance for native mobile applications.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|