react-native-navigation-mode 1.0.2 → 1.0.4
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/NavigationMode.podspec +3 -2
- package/README.md +3 -1
- package/ios/NavigationMode.h +6 -6
- package/lib/module/NativeNavigationMode.js +5 -2
- package/lib/module/NativeNavigationMode.js.map +1 -1
- package/lib/module/index.js +8 -2
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/NativeNavigationMode.d.ts +2 -2
- package/lib/typescript/src/NativeNavigationMode.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/NativeNavigationMode.ts +9 -2
- package/src/index.tsx +6 -2
- package/ios/NavigationMode.mm +0 -28
package/NavigationMode.podspec
CHANGED
|
@@ -13,7 +13,8 @@ Pod::Spec.new do |s|
|
|
|
13
13
|
s.platforms = { :ios => "11.0" }
|
|
14
14
|
s.source = { :git => package["repository"]["url"], :tag => "#{s.version}" }
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
# No source files needed for iOS since we handle everything in JS
|
|
17
|
+
s.source_files = "ios/NavigationMode.h"
|
|
18
|
+
|
|
18
19
|
install_modules_dependencies(s)
|
|
19
20
|
end
|
package/README.md
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
</table>
|
|
33
33
|
</div>
|
|
34
34
|
|
|
35
|
+
---
|
|
35
36
|
|
|
36
37
|
## 🤔 Why This Library?
|
|
37
38
|
|
|
@@ -59,7 +60,7 @@ With Android 15 enforcing edge-to-edge display for apps targeting API 35 and Goo
|
|
|
59
60
|
- **Edge-to-edge enforcement** - Android 16 will remove the opt-out entirely
|
|
60
61
|
- **Expo SDK 53+** - New projects use edge-to-edge by default
|
|
61
62
|
- **React Native 0.79+** - Built-in support for 16KB page size and edge-to-edge
|
|
62
|
-
- **Safe area management** - Critical for preventing content overlap with system bars
|
|
63
|
+
- **Safe area management** - Critical for preventing content overlap with system bars (especially noticeable in 3-button navigation mode).
|
|
63
64
|
|
|
64
65
|
### Real-World Impact
|
|
65
66
|
|
|
@@ -88,6 +89,7 @@ const isGesture = await isGestureNavigation(); // 🎯 Always accurate
|
|
|
88
89
|
- 🎣 **React Hooks** - Easy integration with `useNavigationMode()`
|
|
89
90
|
- 📦 **Zero Dependencies** - Lightweight and performant
|
|
90
91
|
- 🛡️ **TypeScript** - Full type safety out of the box
|
|
92
|
+
- ↕️ **Edge To Edge Support** - Full support for `react-native-edge-to-edge`
|
|
91
93
|
|
|
92
94
|
## Installation
|
|
93
95
|
|
package/ios/NavigationMode.h
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// Placeholder header for iOS - actual functionality handled in JavaScript
|
|
2
|
+
// This library only provides native functionality on Android
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
#ifndef NavigationMode_h
|
|
5
|
+
#define NavigationMode_h
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
// Empty placeholder - no native iOS implementation needed
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
NS_ASSUME_NONNULL_END
|
|
9
|
+
#endif /* NavigationMode_h */
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { TurboModuleRegistry } from 'react-native';
|
|
4
|
-
|
|
3
|
+
import { TurboModuleRegistry, Platform } from 'react-native';
|
|
4
|
+
// Only get the native module on Android
|
|
5
|
+
// On iOS, we'll handle everything in JavaScript
|
|
6
|
+
const NativeModule = Platform.OS === 'android' ? TurboModuleRegistry.getEnforcing('NavigationMode') : null;
|
|
7
|
+
export default NativeModule;
|
|
5
8
|
//# sourceMappingURL=NativeNavigationMode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeNavigationMode.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;
|
|
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":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -8,13 +8,16 @@ import NavigationModeModule from "./NativeNavigationMode.js";
|
|
|
8
8
|
* Returns navigation type, interaction mode, and device info
|
|
9
9
|
*/
|
|
10
10
|
export function getNavigationMode() {
|
|
11
|
-
|
|
11
|
+
// null check is redundant as it's always null for iOS but it's there to satisfy TypeScript
|
|
12
|
+
if (Platform.OS === 'ios' || NavigationModeModule === null) {
|
|
12
13
|
// iOS always uses gesture navigation (no 3-button navigation exists)
|
|
13
14
|
return Promise.resolve({
|
|
14
15
|
type: 'gesture',
|
|
15
16
|
isGestureNavigation: true
|
|
16
17
|
});
|
|
17
18
|
}
|
|
19
|
+
|
|
20
|
+
// Only call native module on Android
|
|
18
21
|
return NavigationModeModule.getNavigationMode();
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -23,10 +26,13 @@ export function getNavigationMode() {
|
|
|
23
26
|
* @returns Promise<boolean> - true if gesture navigation is active
|
|
24
27
|
*/
|
|
25
28
|
export function isGestureNavigation() {
|
|
26
|
-
|
|
29
|
+
// null check is redundant as it's always null for iOS but it's there to satisfy TypeScript
|
|
30
|
+
if (Platform.OS === 'ios' || NavigationModeModule === null) {
|
|
27
31
|
// iOS always uses gesture navigation
|
|
28
32
|
return Promise.resolve(true);
|
|
29
33
|
}
|
|
34
|
+
|
|
35
|
+
// Only call native module on Android
|
|
30
36
|
return NavigationModeModule.isGestureNavigation();
|
|
31
37
|
}
|
|
32
38
|
|
package/lib/module/index.js.map
CHANGED
|
@@ -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,IAAIH,QAAQ,CAACI,EAAE,KAAK,KAAK,EAAE;
|
|
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":[]}
|
|
@@ -8,6 +8,6 @@ export interface Spec extends TurboModule {
|
|
|
8
8
|
getNavigationMode(): Promise<NavigationModeInfo>;
|
|
9
9
|
isGestureNavigation(): Promise<boolean>;
|
|
10
10
|
}
|
|
11
|
-
declare const
|
|
12
|
-
export default
|
|
11
|
+
declare const NativeModule: Spec | null;
|
|
12
|
+
export default NativeModule;
|
|
13
13
|
//# sourceMappingURL=NativeNavigationMode.d.ts.map
|
|
@@ -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
|
|
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 +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,
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-navigation-mode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
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",
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
"@eslint/js": "^9.22.0",
|
|
75
75
|
"@evilmartians/lefthook": "^1.5.0",
|
|
76
76
|
"@react-native-community/cli": "15.0.0-alpha.2",
|
|
77
|
-
"@react-native/babel-preset": "0.79.
|
|
78
|
-
"@react-native/eslint-config": "
|
|
77
|
+
"@react-native/babel-preset": "0.79.5",
|
|
78
|
+
"@react-native/eslint-config": "0.79.5",
|
|
79
79
|
"@release-it/conventional-changelog": "^9.0.2",
|
|
80
80
|
"@semantic-release/changelog": "^6.0.3",
|
|
81
81
|
"@semantic-release/git": "^10.0.1",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"jest": "^29.7.0",
|
|
92
92
|
"prettier": "^3.0.3",
|
|
93
93
|
"react": "19.0.0",
|
|
94
|
-
"react-native": "0.79.
|
|
94
|
+
"react-native": "0.79.5",
|
|
95
95
|
"react-native-builder-bob": "^0.40.11",
|
|
96
96
|
"release-it": "^17.10.0",
|
|
97
97
|
"semantic-release": "^24.1.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TurboModule } from 'react-native';
|
|
2
|
-
import { TurboModuleRegistry } from 'react-native';
|
|
2
|
+
import { TurboModuleRegistry, Platform } from 'react-native';
|
|
3
3
|
|
|
4
4
|
export interface NavigationModeInfo {
|
|
5
5
|
type: '3_button' | '2_button' | 'gesture' | 'unknown';
|
|
@@ -12,4 +12,11 @@ export interface Spec extends TurboModule {
|
|
|
12
12
|
isGestureNavigation(): Promise<boolean>;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
// Only get the native module on Android
|
|
16
|
+
// On iOS, we'll handle everything in JavaScript
|
|
17
|
+
const NativeModule =
|
|
18
|
+
Platform.OS === 'android'
|
|
19
|
+
? TurboModuleRegistry.getEnforcing<Spec>('NavigationMode')
|
|
20
|
+
: null;
|
|
21
|
+
|
|
22
|
+
export default NativeModule;
|
package/src/index.tsx
CHANGED
|
@@ -11,7 +11,8 @@ export type { NavigationModeInfo };
|
|
|
11
11
|
* Returns navigation type, interaction mode, and device info
|
|
12
12
|
*/
|
|
13
13
|
export function getNavigationMode(): Promise<NavigationModeInfo> {
|
|
14
|
-
|
|
14
|
+
// null check is redundant as it's always null for iOS but it's there to satisfy TypeScript
|
|
15
|
+
if (Platform.OS === 'ios' || NavigationModeModule === null) {
|
|
15
16
|
// iOS always uses gesture navigation (no 3-button navigation exists)
|
|
16
17
|
return Promise.resolve({
|
|
17
18
|
type: 'gesture',
|
|
@@ -19,6 +20,7 @@ export function getNavigationMode(): Promise<NavigationModeInfo> {
|
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
// Only call native module on Android
|
|
22
24
|
return NavigationModeModule.getNavigationMode();
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -27,11 +29,13 @@ export function getNavigationMode(): Promise<NavigationModeInfo> {
|
|
|
27
29
|
* @returns Promise<boolean> - true if gesture navigation is active
|
|
28
30
|
*/
|
|
29
31
|
export function isGestureNavigation(): Promise<boolean> {
|
|
30
|
-
|
|
32
|
+
// null check is redundant as it's always null for iOS but it's there to satisfy TypeScript
|
|
33
|
+
if (Platform.OS === 'ios' || NavigationModeModule === null) {
|
|
31
34
|
// iOS always uses gesture navigation
|
|
32
35
|
return Promise.resolve(true);
|
|
33
36
|
}
|
|
34
37
|
|
|
38
|
+
// Only call native module on Android
|
|
35
39
|
return NavigationModeModule.isGestureNavigation();
|
|
36
40
|
}
|
|
37
41
|
|
package/ios/NavigationMode.mm
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#import "NavigationMode.h"
|
|
2
|
-
|
|
3
|
-
@implementation NavigationMode
|
|
4
|
-
|
|
5
|
-
RCT_EXPORT_MODULE()
|
|
6
|
-
|
|
7
|
-
- (void)getNavigationMode:(RCTPromiseResolveBlock)resolve
|
|
8
|
-
reject:(RCTPromiseRejectBlock)reject {
|
|
9
|
-
// iOS always uses gesture navigation - handled in TypeScript
|
|
10
|
-
NSDictionary *result = @{
|
|
11
|
-
@"type": @"gesture",
|
|
12
|
-
@"isGestureNavigation": @YES
|
|
13
|
-
};
|
|
14
|
-
resolve(result);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
- (void)isGestureNavigation:(RCTPromiseResolveBlock)resolve
|
|
18
|
-
reject:(RCTPromiseRejectBlock)reject {
|
|
19
|
-
// iOS always uses gesture navigation - handled in TypeScript
|
|
20
|
-
resolve(@YES);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
24
|
-
(const facebook::react::ObjCTurboModule::InitParams &)params {
|
|
25
|
-
return std::make_shared<facebook::react::NativeNavigationModeSpecJSI>(params);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@end
|