@capgo/capacitor-native-navigation 8.4.0 → 8.4.1

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.
@@ -3,7 +3,6 @@ ext {
3
3
  androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
4
4
  androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
5
5
  androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
6
- materialVersion = project.hasProperty('materialVersion') ? rootProject.ext.materialVersion : '1.12.0'
7
6
  }
8
7
 
9
8
  buildscript {
@@ -54,7 +53,6 @@ dependencies {
54
53
  implementation project(':capacitor-android')
55
54
  annotationProcessor project(':capacitor-android')
56
55
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
57
- implementation "com.google.android.material:material:$materialVersion"
58
56
  testImplementation "junit:junit:$junitVersion"
59
57
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
60
58
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
@@ -1883,18 +1883,29 @@ public class NativeNavigationPlugin extends Plugin {
1883
1883
  }
1884
1884
 
1885
1885
  private JSObject currentInsets() {
1886
+ // View layout uses device pixels; CSS variables must be density-independent
1887
+ // or a 3x screen writes `192px` which CSS treats as 192 CSS px.
1886
1888
  int top = navbarVisible ? statusBarInset() + dp(DEFAULT_NAVBAR_DP) : 0;
1887
1889
  int bottom = tabbarVisible ? navigationBarInset() + dp(tabbarStyle.totalHeight()) + dp(tabbarStyle.bottomGap) : 0;
1888
1890
  JSObject insets = new JSObject();
1889
- insets.put("top", top);
1891
+ insets.put("top", cssPx(top));
1890
1892
  insets.put("right", 0);
1891
- insets.put("bottom", bottom);
1893
+ insets.put("bottom", cssPx(bottom));
1892
1894
  insets.put("left", 0);
1893
- insets.put("navbarHeight", top);
1894
- insets.put("tabbarHeight", bottom);
1895
+ insets.put("navbarHeight", cssPx(top));
1896
+ insets.put("tabbarHeight", cssPx(bottom));
1895
1897
  return insets;
1896
1898
  }
1897
1899
 
1900
+ /** Converts a layout pixel value to CSS pixels for WebView CSS variables. */
1901
+ private int cssPx(int devicePx) {
1902
+ float density = getContext().getResources().getDisplayMetrics().density;
1903
+ if (density <= 0f) {
1904
+ return devicePx;
1905
+ }
1906
+ return Math.round(devicePx / density);
1907
+ }
1908
+
1898
1909
  private JSObject insetsResult() {
1899
1910
  JSObject result = new JSObject();
1900
1911
  result.put("insets", currentInsets());
@@ -69,6 +69,7 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
69
69
  private var tabBaseImages: [UIImage?] = []
70
70
  private var tabSelectedImages: [UIImage?] = []
71
71
  private var suppressTabSelectEvent = false
72
+ private var tabSelectEmittedForReTap = false
72
73
  private var transitionSnapshot: UIView?
73
74
  private var activeTransitionId: String?
74
75
  private var activeTransitionDirection = "forward"
@@ -543,17 +544,27 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
543
544
  if usesSystemLiquidGlass {
544
545
  hostWebView(in: viewController)
545
546
  }
547
+ tabSelectEmittedForReTap = false
548
+ if !suppressTabSelectEvent,
549
+ tabBarController.selectedViewController === viewController {
550
+ notifyTabSelect(index: viewController.tabBarItem.tag)
551
+ tabSelectEmittedForReTap = true
552
+ }
546
553
  return true
547
554
  }
548
555
 
549
556
  public func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
550
557
  guard !suppressTabSelectEvent else {
558
+ tabSelectEmittedForReTap = false
551
559
  hostWebViewInSelectedSystemTab()
552
560
  return
553
561
  }
554
562
  let index = viewController.tabBarItem.tag
555
563
  hostWebViewInSelectedSystemTab()
556
- notifyTabSelect(index: index)
564
+ if !tabSelectEmittedForReTap {
565
+ notifyTabSelect(index: index)
566
+ }
567
+ tabSelectEmittedForReTap = false
557
568
  }
558
569
 
559
570
  private func notifyTabSelect(index: Int) {
@@ -1791,7 +1802,13 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
1791
1802
 
1792
1803
  if let container = systemTabRootContainer {
1793
1804
  container.frame = rootView.bounds
1794
- webView?.frame = container.bounds
1805
+ // Capacitor's root view is the WKWebView. After the webview is
1806
+ // hosted in a tab content controller, stretching it to this
1807
+ // container's full bounds overflows the tab VC (clipsToBounds is
1808
+ // off) and paints over the system tab bar.
1809
+ if !isWebViewHostedInSystemTabController {
1810
+ webView?.frame = container.bounds
1811
+ }
1795
1812
  }
1796
1813
 
1797
1814
  if let container = navContainer {
@@ -1852,8 +1869,11 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
1852
1869
 
1853
1870
  private func bringChromeToFront() {
1854
1871
  if usesSystemLiquidGlass && tabbarStyle.shape != .curve {
1872
+ if let tabBarController = tabBarController {
1873
+ (systemTabRootContainer ?? bridge?.viewController?.view)?.bringSubviewToFront(tabBarController.view)
1874
+ }
1855
1875
  if let navContainer = navContainer {
1856
- bridge?.viewController?.view.bringSubviewToFront(navContainer)
1876
+ (systemTabRootContainer ?? bridge?.viewController?.view)?.bringSubviewToFront(navContainer)
1857
1877
  }
1858
1878
  bringLiftedWebViewOverlaysToFront()
1859
1879
  return
@@ -1975,7 +1995,12 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
1975
1995
  let usesSystemTabbar = usesSystemLiquidGlass && tabbarStyle.shape != .curve
1976
1996
  let nativeTabHeight = max(tabBar?.frame.height ?? 0, 49 + safeInsets.bottom)
1977
1997
  let customTabHeight = tabbarHeight + safeInsets.bottom + tabbarStyle.bottomGap
1978
- let tabHeight = isEnabled && tabbarVisible ? (usesSystemTabbar ? nativeTabHeight : customTabHeight) : 0
1998
+ // Hosted in the tab content VC: the WebView already ends above the
1999
+ // bar. Reporting the bar height as CSS overlap lifts the FAB by a
2000
+ // second bar.
2001
+ let tabHeight = isEnabled && tabbarVisible && !isWebViewHostedInSystemTabController
2002
+ ? (usesSystemTabbar ? nativeTabHeight : customTabHeight)
2003
+ : 0
1979
2004
  return [
1980
2005
  "top": navHeight,
1981
2006
  "right": safeInsets.right,
@@ -2674,6 +2699,7 @@ final class NativeNavigationTabContentController: UIViewController {
2674
2699
  let view = UIView()
2675
2700
  view.backgroundColor = .systemBackground
2676
2701
  view.isOpaque = true
2702
+ view.clipsToBounds = true
2677
2703
  self.view = view
2678
2704
  }
2679
2705
 
@@ -2714,7 +2740,8 @@ final class NativeNavigationTabContentController: UIViewController {
2714
2740
  snapshotPlaceholder = nil
2715
2741
  hostedWebView = webView
2716
2742
  if webView.superview !== view {
2717
- webView.removeFromSuperview()
2743
+ // addSubview reparents in one step. removeFromSuperview() first
2744
+ // leaves a frame of this VC's backing colour (system white).
2718
2745
  view.addSubview(webView)
2719
2746
  }
2720
2747
  webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-native-navigation",
3
- "version": "8.4.0",
3
+ "version": "8.4.1",
4
4
  "description": "Capacitor plugin for native navbar, tabbar, safe-area handling, and WebView snapshot transitions.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",