react-native-navigation-mode 1.0.4 → 1.1.0

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
@@ -85,6 +85,7 @@ const isGesture = await isGestureNavigation(); // 🎯 Always accurate
85
85
  - 🎯 **Direct Native Detection** - No hacky workarounds or dimension-based guessing
86
86
  - ⚡ **Turbo Module** - Built with the latest React Native architecture
87
87
  - 🔄 **Real-time Detection** - Accurate navigation mode identification
88
+ - 📏 **Navigation Bar Height** - Get exact navigation bar height in dp for precise UI calculations
88
89
  - 📱 **Cross Platform** - Android detection + iOS compatibility
89
90
  - 🎣 **React Hooks** - Easy integration with `useNavigationMode()`
90
91
  - 📦 **Zero Dependencies** - Lightweight and performant
@@ -131,6 +132,16 @@ const navInfo = await getNavigationMode();
131
132
  console.log('Navigation type:', navInfo.type); // '3_button', '2_button', 'gesture', or 'unknown'
132
133
  ```
133
134
 
135
+ ### Navigation Bar Height
136
+
137
+ ```typescript
138
+ import { getNavigationBarHeight } from 'react-native-navigation-mode';
139
+
140
+ // Get navigation bar height in dp
141
+ const height = await getNavigationBarHeight();
142
+ console.log('Navigation bar height:', height); // number (dp)
143
+ ```
144
+
134
145
  ### React Hook (Recommended)
135
146
 
136
147
  ```typescript
@@ -166,7 +177,7 @@ export default function AdaptiveUI() {
166
177
  return (
167
178
  <View
168
179
  style={{
169
- paddingBottom: navigationMode?.isGestureNavigation ? 34 : 48 // Adjust for gesture nav
180
+ paddingBottom: navigationMode?.navigationBarHeight
170
181
  }}
171
182
  >
172
183
  {/* Your content */}
@@ -187,6 +198,10 @@ Returns comprehensive navigation mode information.
187
198
 
188
199
  Quick check if device is using gesture navigation.
189
200
 
201
+ #### `getNavigationBarHeight(): Promise<number>`
202
+
203
+ Returns the navigation bar height in density-independent pixels (dp).
204
+
190
205
  ### Hooks
191
206
 
192
207
  #### `useNavigationMode(): { navigationMode, loading, error }`
@@ -197,24 +212,27 @@ React hook for navigation mode detection with loading and error states.
197
212
 
198
213
  #### `NavigationModeInfo`
199
214
 
200
- | Property | Type | Description |
201
- | ------------------- | ---------------------------------------------- | ------------------------------------------------ |
202
- | type | `'3_button' \| '2_button' \| 'gesture' \| 'unknown'` | Navigation mode type |
203
- | isGestureNavigation | `boolean` | Whether gesture navigation is active |
204
- | interactionMode | `number \| undefined` | Raw Android interaction mode (0, 1, 2, or -1) |
215
+ | Property | Type | Description |
216
+ | ------------------- | ------------------------------------------------- | --------------------------------------------- |
217
+ | type | `'3_button' | '2_button' | 'gesture' | 'unknown'` | Navigation mode type |
218
+ | isGestureNavigation | `boolean` | Whether gesture navigation is active |
219
+ | interactionMode | `number | undefined` | Raw Android interaction mode (0, 1, 2, or -1) |
220
+ | navigationBarHeight | `number | undefined` | Navigation bar height in dp |
205
221
 
206
222
  ## Platform Support
207
223
 
208
224
  | Platform | Support | Notes |
209
225
  |----------|---------|-------|
210
- | Android | ✅ Full | Detects all navigation modes via native Android APIs |
211
- | iOS | ✅ Compatible | Always returns `gesture` (iOS uses gesture navigation) |
226
+ | Android | ✅ Full | Detects all navigation modes and navigation bar height via native Android APIs |
227
+ | iOS | ✅ Compatible | Always returns `gesture` and `navigationBarHeight: 0` (iOS uses gesture navigation) |
212
228
 
213
229
  ### Android Compatibility
214
230
 
215
231
  - **API 21+** - Basic navigation bar detection
216
232
  - **API 29+** - Full navigation mode detection (`config_navBarInteractionMode`)
217
233
  - **All versions** - Fallback detection methods included
234
+ - **API 30+** - WindowInsets-based navigation bar height detection
235
+ - **API 24-29** - Resource-based navigation bar height fallback
218
236
 
219
237
  ## How It Works
220
238
 
@@ -236,7 +254,7 @@ The library uses multiple detection methods for maximum accuracy:
236
254
 
237
255
  ## Notes
238
256
 
239
- 1. 🍎 **iOS Behavior** - iOS always returns `isGestureNavigation: true` since iOS doesn't have 3-button navigation
257
+ 1. 1. 🍎 **iOS Behavior** - iOS always returns `isGestureNavigation: true` and `navigationBarHeight: 0` since iOS doesn't have Android-style navigation bars
240
258
  2. ⚡ **Performance** - Turbo module ensures minimal performance impact
241
259
  3. 🔄 **Real-time** - Navigation mode is detected at call time, reflecting current device settings
242
260
 
@@ -1,14 +1,15 @@
1
1
  package com.navigationmode
2
2
 
3
+ import android.app.Activity
3
4
  import android.content.Context
4
5
  import android.content.res.Resources
5
6
  import android.os.Build
6
7
  import android.provider.Settings
7
- import android.view.ViewConfiguration
8
+ import android.view.WindowInsets
9
+ import com.facebook.react.bridge.Arguments
8
10
  import com.facebook.react.bridge.Promise
9
11
  import com.facebook.react.bridge.ReactApplicationContext
10
12
  import com.facebook.react.bridge.WritableMap
11
- import com.facebook.react.bridge.Arguments
12
13
  import com.facebook.react.module.annotations.ReactModule
13
14
 
14
15
  @ReactModule(name = NavigationModeModule.NAME)
@@ -21,11 +22,49 @@ class NavigationModeModule(reactContext: ReactApplicationContext) :
21
22
 
22
23
  override fun getName(): String = NAME
23
24
 
25
+ private fun getNavigationBarHeight(context: Context): Int {
26
+ // Try to get Activity for WindowInsets
27
+ val activity = if (context is Activity) context else reactApplicationContext.currentActivity
28
+ val density = context.resources.displayMetrics.density // Get device density
29
+
30
+ if (activity != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
31
+ val insets = activity.window.decorView.rootWindowInsets
32
+ if (insets != null) {
33
+ val navBar = insets.getInsets(WindowInsets.Type.navigationBars())
34
+ return (navBar.bottom / density).toInt() // Convert pixels to dp
35
+ }
36
+ }
37
+
38
+ // Fallback to resource-based approach for API < 30
39
+ val resources = context.resources
40
+ val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
41
+ return if (resourceId > 0) {
42
+ // getDimensionPixelSize returns pixels, convert to dp
43
+ (resources.getDimensionPixelSize(resourceId) / density).toInt()
44
+ } else {
45
+ 0 // Fallback for devices without a navigation bar
46
+ }
47
+ }
48
+
49
+ override fun getNavigationBarHeight(promise: Promise) {
50
+ try {
51
+ val context = reactApplicationContext
52
+ val navBarHeight = getNavigationBarHeight(context)
53
+ promise.resolve(navBarHeight)
54
+ } catch (e: Exception) {
55
+ promise.reject("NAV_BAR_HEIGHT_ERROR", "Failed to get navigation bar height: ${e.message}", e)
56
+ }
57
+ }
58
+
24
59
  override fun getNavigationMode(promise: Promise) {
25
60
  try {
26
61
  val result = Arguments.createMap()
27
62
  val context = reactApplicationContext
28
63
 
64
+ // Use reactApplicationContext for navigation bar height
65
+ val navBarHeight = getNavigationBarHeight(context)
66
+ result.putInt("navigationBarHeight", navBarHeight)
67
+
29
68
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
30
69
  val navBarInteractionMode = getNavBarInteractionMode(context)
31
70
  result.putInt("interactionMode", navBarInteractionMode)
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","Platform","NativeModule","OS","getEnforcing"],"sourceRoot":"../../src","sources":["NativeNavigationMode.ts"],"mappings":";;AACA,SAASA,mBAAmB,EAAEC,QAAQ,QAAQ,cAAc;AAa5D;AACA;AACA,MAAMC,YAAY,GAChBD,QAAQ,CAACE,EAAE,KAAK,SAAS,GACrBH,mBAAmB,CAACI,YAAY,CAAO,gBAAgB,CAAC,GACxD,IAAI;AAEV,eAAeF,YAAY","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","Platform","NativeModule","OS","getEnforcing"],"sourceRoot":"../../src","sources":["NativeNavigationMode.ts"],"mappings":";;AACA,SAASA,mBAAmB,EAAEC,QAAQ,QAAQ,cAAc;AAe5D;AACA;AACA,MAAMC,YAAY,GAChBD,QAAQ,CAACE,EAAE,KAAK,SAAS,GACrBH,mBAAmB,CAACI,YAAY,CAAO,gBAAgB,CAAC,GACxD,IAAI;AAEV,eAAeF,YAAY","ignoreList":[]}
@@ -13,7 +13,8 @@ export function getNavigationMode() {
13
13
  // iOS always uses gesture navigation (no 3-button navigation exists)
14
14
  return Promise.resolve({
15
15
  type: 'gesture',
16
- isGestureNavigation: true
16
+ isGestureNavigation: true,
17
+ navigationBarHeight: 0 // iOS doesn't have a navigation bar like Android
17
18
  });
18
19
  }
19
20
 
@@ -36,6 +37,21 @@ export function isGestureNavigation() {
36
37
  return NavigationModeModule.isGestureNavigation();
37
38
  }
38
39
 
40
+ /**
41
+ * Get the navigation bar height in dp
42
+ * @returns Promise<number> - navigation bar height in dp
43
+ */
44
+ export function getNavigationBarHeight() {
45
+ // null check is redundant as it's always null for iOS but it's there to satisfy TypeScript
46
+ if (Platform.OS === 'ios' || NavigationModeModule === null) {
47
+ // iOS doesn't have a navigation bar like Android
48
+ return Promise.resolve(0);
49
+ }
50
+
51
+ // Only call native module on Android
52
+ return NavigationModeModule.getNavigationBarHeight();
53
+ }
54
+
39
55
  /**
40
56
  * Hook for React components to get navigation mode
41
57
  */
@@ -76,6 +92,7 @@ export function useNavigationMode() {
76
92
  export default {
77
93
  getNavigationMode,
78
94
  isGestureNavigation,
95
+ getNavigationBarHeight,
79
96
  useNavigationMode
80
97
  };
81
98
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","React","NavigationModeModule","getNavigationMode","OS","Promise","resolve","type","isGestureNavigation","useNavigationMode","navigationMode","setNavigationMode","useState","loading","setLoading","error","setError","useEffect","mounted","fetchNavigationMode","mode","err","Error"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,OAAOC,KAAK,MAAM,OAAO;AACzB,OAAOC,oBAAoB,MAEpB,2BAAwB;AAI/B;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAA,EAAgC;EAC/D;EACA,IAAIH,QAAQ,CAACI,EAAE,KAAK,KAAK,IAAIF,oBAAoB,KAAK,IAAI,EAAE;IAC1D;IACA,OAAOG,OAAO,CAACC,OAAO,CAAC;MACrBC,IAAI,EAAE,SAAS;MACfC,mBAAmB,EAAE;IACvB,CAAC,CAAC;EACJ;;EAEA;EACA,OAAON,oBAAoB,CAACC,iBAAiB,CAAC,CAAC;AACjD;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASK,mBAAmBA,CAAA,EAAqB;EACtD;EACA,IAAIR,QAAQ,CAACI,EAAE,KAAK,KAAK,IAAIF,oBAAoB,KAAK,IAAI,EAAE;IAC1D;IACA,OAAOG,OAAO,CAACC,OAAO,CAAC,IAAI,CAAC;EAC9B;;EAEA;EACA,OAAOJ,oBAAoB,CAACM,mBAAmB,CAAC,CAAC;AACnD;;AAEA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAA,EAAG;EAClC,MAAM,CAACC,cAAc,EAAEC,iBAAiB,CAAC,GACvCV,KAAK,CAACW,QAAQ,CAA4B,IAAI,CAAC;EACjD,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAGb,KAAK,CAACW,QAAQ,CAAC,IAAI,CAAC;EAClD,MAAM,CAACG,KAAK,EAAEC,QAAQ,CAAC,GAAGf,KAAK,CAACW,QAAQ,CAAe,IAAI,CAAC;EAE5DX,KAAK,CAACgB,SAAS,CAAC,MAAM;IACpB,IAAIC,OAAO,GAAG,IAAI;IAElB,eAAeC,mBAAmBA,CAAA,EAAG;MACnC,IAAI;QACF,MAAMC,IAAI,GAAG,MAAMjB,iBAAiB,CAAC,CAAC;QACtC,IAAIe,OAAO,EAAE;UACXP,iBAAiB,CAACS,IAAI,CAAC;UACvBJ,QAAQ,CAAC,IAAI,CAAC;QAChB;MACF,CAAC,CAAC,OAAOK,GAAG,EAAE;QACZ,IAAIH,OAAO,EAAE;UACXF,QAAQ,CAACK,GAAG,YAAYC,KAAK,GAAGD,GAAG,GAAG,IAAIC,KAAK,CAAC,eAAe,CAAC,CAAC;QACnE;MACF,CAAC,SAAS;QACR,IAAIJ,OAAO,EAAE;UACXJ,UAAU,CAAC,KAAK,CAAC;QACnB;MACF;IACF;IAEAK,mBAAmB,CAAC,CAAC;IAErB,OAAO,MAAM;MACXD,OAAO,GAAG,KAAK;IACjB,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IAAER,cAAc;IAAEG,OAAO;IAAEE;EAAM,CAAC;AAC3C;AAEA,eAAe;EACbZ,iBAAiB;EACjBK,mBAAmB;EACnBC;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["Platform","React","NavigationModeModule","getNavigationMode","OS","Promise","resolve","type","isGestureNavigation","navigationBarHeight","getNavigationBarHeight","useNavigationMode","navigationMode","setNavigationMode","useState","loading","setLoading","error","setError","useEffect","mounted","fetchNavigationMode","mode","err","Error"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,OAAOC,KAAK,MAAM,OAAO;AACzB,OAAOC,oBAAoB,MAEpB,2BAAwB;AAI/B;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAA,EAAgC;EAC/D;EACA,IAAIH,QAAQ,CAACI,EAAE,KAAK,KAAK,IAAIF,oBAAoB,KAAK,IAAI,EAAE;IAC1D;IACA,OAAOG,OAAO,CAACC,OAAO,CAAC;MACrBC,IAAI,EAAE,SAAS;MACfC,mBAAmB,EAAE,IAAI;MACzBC,mBAAmB,EAAE,CAAC,CAAE;IAC1B,CAAC,CAAC;EACJ;;EAEA;EACA,OAAOP,oBAAoB,CAACC,iBAAiB,CAAC,CAAC;AACjD;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASK,mBAAmBA,CAAA,EAAqB;EACtD;EACA,IAAIR,QAAQ,CAACI,EAAE,KAAK,KAAK,IAAIF,oBAAoB,KAAK,IAAI,EAAE;IAC1D;IACA,OAAOG,OAAO,CAACC,OAAO,CAAC,IAAI,CAAC;EAC9B;;EAEA;EACA,OAAOJ,oBAAoB,CAACM,mBAAmB,CAAC,CAAC;AACnD;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASE,sBAAsBA,CAAA,EAAoB;EACxD;EACA,IAAIV,QAAQ,CAACI,EAAE,KAAK,KAAK,IAAIF,oBAAoB,KAAK,IAAI,EAAE;IAC1D;IACA,OAAOG,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAC3B;;EAEA;EACA,OAAOJ,oBAAoB,CAACQ,sBAAsB,CAAC,CAAC;AACtD;;AAEA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAA,EAAG;EAClC,MAAM,CAACC,cAAc,EAAEC,iBAAiB,CAAC,GACvCZ,KAAK,CAACa,QAAQ,CAA4B,IAAI,CAAC;EACjD,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAGf,KAAK,CAACa,QAAQ,CAAC,IAAI,CAAC;EAClD,MAAM,CAACG,KAAK,EAAEC,QAAQ,CAAC,GAAGjB,KAAK,CAACa,QAAQ,CAAe,IAAI,CAAC;EAE5Db,KAAK,CAACkB,SAAS,CAAC,MAAM;IACpB,IAAIC,OAAO,GAAG,IAAI;IAElB,eAAeC,mBAAmBA,CAAA,EAAG;MACnC,IAAI;QACF,MAAMC,IAAI,GAAG,MAAMnB,iBAAiB,CAAC,CAAC;QACtC,IAAIiB,OAAO,EAAE;UACXP,iBAAiB,CAACS,IAAI,CAAC;UACvBJ,QAAQ,CAAC,IAAI,CAAC;QAChB;MACF,CAAC,CAAC,OAAOK,GAAG,EAAE;QACZ,IAAIH,OAAO,EAAE;UACXF,QAAQ,CAACK,GAAG,YAAYC,KAAK,GAAGD,GAAG,GAAG,IAAIC,KAAK,CAAC,eAAe,CAAC,CAAC;QACnE;MACF,CAAC,SAAS;QACR,IAAIJ,OAAO,EAAE;UACXJ,UAAU,CAAC,KAAK,CAAC;QACnB;MACF;IACF;IAEAK,mBAAmB,CAAC,CAAC;IAErB,OAAO,MAAM;MACXD,OAAO,GAAG,KAAK;IACjB,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IAAER,cAAc;IAAEG,OAAO;IAAEE;EAAM,CAAC;AAC3C;AAEA,eAAe;EACbd,iBAAiB;EACjBK,mBAAmB;EACnBE,sBAAsB;EACtBC;AACF,CAAC","ignoreList":[]}
@@ -3,10 +3,12 @@ export interface NavigationModeInfo {
3
3
  type: '3_button' | '2_button' | 'gesture' | 'unknown';
4
4
  isGestureNavigation: boolean;
5
5
  interactionMode?: number;
6
+ navigationBarHeight?: number;
6
7
  }
7
8
  export interface Spec extends TurboModule {
8
9
  getNavigationMode(): Promise<NavigationModeInfo>;
9
10
  isGestureNavigation(): Promise<boolean>;
11
+ getNavigationBarHeight(): Promise<number>;
10
12
  }
11
13
  declare const NativeModule: Spec | null;
12
14
  export default NativeModule;
@@ -1 +1 @@
1
- {"version":3,"file":"NativeNavigationMode.d.ts","sourceRoot":"","sources":["../../../src/NativeNavigationMode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;IACtD,mBAAmB,EAAE,OAAO,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjD,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC;AAID,QAAA,MAAM,YAAY,aAGR,CAAC;AAEX,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"NativeNavigationMode.d.ts","sourceRoot":"","sources":["../../../src/NativeNavigationMode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;IACtD,mBAAmB,EAAE,OAAO,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjD,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C;AAID,QAAA,MAAM,YAAY,aAGR,CAAC;AAEX,eAAe,YAAY,CAAC"}
@@ -10,6 +10,11 @@ export declare function getNavigationMode(): Promise<NavigationModeInfo>;
10
10
  * @returns Promise<boolean> - true if gesture navigation is active
11
11
  */
12
12
  export declare function isGestureNavigation(): Promise<boolean>;
13
+ /**
14
+ * Get the navigation bar height in dp
15
+ * @returns Promise<number> - navigation bar height in dp
16
+ */
17
+ export declare function getNavigationBarHeight(): Promise<number>;
13
18
  /**
14
19
  * Hook for React components to get navigation mode
15
20
  */
@@ -21,6 +26,7 @@ export declare function useNavigationMode(): {
21
26
  declare const _default: {
22
27
  readonly getNavigationMode: typeof getNavigationMode;
23
28
  readonly isGestureNavigation: typeof isGestureNavigation;
29
+ readonly getNavigationBarHeight: typeof getNavigationBarHeight;
24
30
  readonly useNavigationMode: typeof useNavigationMode;
25
31
  };
26
32
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAA6B,EAC3B,KAAK,kBAAkB,EACxB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAY/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC,CAStD;AAED;;GAEG;AACH,wBAAgB,iBAAiB;;;;EAmChC;;;;;;AAED,wBAIW"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAA6B,EAC3B,KAAK,kBAAkB,EACxB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAa/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC,CAStD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CASxD;AAED;;GAEG;AACH,wBAAgB,iBAAiB;;;;EAmChC;;;;;;;AAED,wBAKW"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-navigation-mode",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Detect Android navigation mode (3-button, 2-button, or gesture)",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -5,11 +5,13 @@ export interface NavigationModeInfo {
5
5
  type: '3_button' | '2_button' | 'gesture' | 'unknown';
6
6
  isGestureNavigation: boolean;
7
7
  interactionMode?: number;
8
+ navigationBarHeight?: number;
8
9
  }
9
10
 
10
11
  export interface Spec extends TurboModule {
11
12
  getNavigationMode(): Promise<NavigationModeInfo>;
12
13
  isGestureNavigation(): Promise<boolean>;
14
+ getNavigationBarHeight(): Promise<number>;
13
15
  }
14
16
 
15
17
  // Only get the native module on Android
package/src/index.tsx CHANGED
@@ -17,6 +17,7 @@ export function getNavigationMode(): Promise<NavigationModeInfo> {
17
17
  return Promise.resolve({
18
18
  type: 'gesture',
19
19
  isGestureNavigation: true,
20
+ navigationBarHeight: 0, // iOS doesn't have a navigation bar like Android
20
21
  });
21
22
  }
22
23
 
@@ -39,6 +40,21 @@ export function isGestureNavigation(): Promise<boolean> {
39
40
  return NavigationModeModule.isGestureNavigation();
40
41
  }
41
42
 
43
+ /**
44
+ * Get the navigation bar height in dp
45
+ * @returns Promise<number> - navigation bar height in dp
46
+ */
47
+ export function getNavigationBarHeight(): Promise<number> {
48
+ // null check is redundant as it's always null for iOS but it's there to satisfy TypeScript
49
+ if (Platform.OS === 'ios' || NavigationModeModule === null) {
50
+ // iOS doesn't have a navigation bar like Android
51
+ return Promise.resolve(0);
52
+ }
53
+
54
+ // Only call native module on Android
55
+ return NavigationModeModule.getNavigationBarHeight();
56
+ }
57
+
42
58
  /**
43
59
  * Hook for React components to get navigation mode
44
60
  */
@@ -82,5 +98,6 @@ export function useNavigationMode() {
82
98
  export default {
83
99
  getNavigationMode,
84
100
  isGestureNavigation,
101
+ getNavigationBarHeight,
85
102
  useNavigationMode,
86
103
  } as const;