@jacques_gordon/expo-mapbox-navigation 1.0.7 → 2.0.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.
- package/ExpoMapboxNavigation.podspec +39 -0
- package/LICENSE +21 -0
- package/README.md +103 -209
- package/android/build.gradle +101 -39
- package/android/src/main/java/expo/modules/mapboxnavigation/ExpoMapboxNavigationModule.kt +81 -77
- package/android/src/main/java/expo/modules/mapboxnavigation/ExpoMapboxNavigationView.kt +260 -142
- package/app.plugin.js +216 -1
- package/build/index.d.ts +121 -2
- package/build/index.js +34 -3
- package/build/src/index.d.ts +121 -0
- package/build/src/index.js +39 -0
- package/package.json +37 -37
- package/plugin/src/index.js +216 -0
- package/src/index.tsx +162 -0
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/9.2.0/checksums/checksums.lock +0 -0
- package/android/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/9.2.0/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/build/MapboxNavigation.types.d.ts +0 -132
- package/build/MapboxNavigation.types.js +0 -2
- package/build/MapboxNavigationView.d.ts +0 -30
- package/build/MapboxNavigationView.js +0 -41
- package/expo-module.config.json +0 -9
- package/ios/ExpoMapboxNavigation.podspec +0 -25
- package/ios/ExpoMapboxNavigationModule.swift +0 -81
- package/ios/ExpoMapboxNavigationView.swift +0 -236
- package/plugin/index.js +0 -167
package/app.plugin.js
CHANGED
|
@@ -1 +1,216 @@
|
|
|
1
|
-
|
|
1
|
+
const { withAppBuildGradle, withProjectBuildGradle, withAndroidManifest, withInfoPlist, withDangerousMod } = require('@expo/config-plugins');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
// Config Plugin for @jacques_gordon/expo-mapbox-navigation
|
|
7
|
+
//
|
|
8
|
+
// This plugin:
|
|
9
|
+
// 1. Adds Mapbox Maven repository to android/build.gradle
|
|
10
|
+
// 2. Forces NDK 27 for 16 KB page size compatibility
|
|
11
|
+
// 3. Enables jniLibs.useLegacyPackaging = false (required for 16 KB pages)
|
|
12
|
+
// 4. Adds Mapbox access token to android resources & iOS Info.plist
|
|
13
|
+
// 5. Adds background location & audio modes for iOS
|
|
14
|
+
// 6. Supports androidColorOverrides for UI theming
|
|
15
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
const NDK_VERSION = '27.0.12077973';
|
|
18
|
+
const MAPBOX_MAPS_MIN_VERSION = '11.11.0';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {import('@expo/config-plugins').ConfigPlugin<{
|
|
22
|
+
* accessToken: string,
|
|
23
|
+
* mapboxMapsVersion?: string,
|
|
24
|
+
* androidColorOverrides?: Record<string, string>
|
|
25
|
+
* }>}
|
|
26
|
+
*/
|
|
27
|
+
const withMapboxNavigation = (config, options = {}) => {
|
|
28
|
+
const {
|
|
29
|
+
accessToken,
|
|
30
|
+
mapboxMapsVersion = MAPBOX_MAPS_MIN_VERSION,
|
|
31
|
+
androidColorOverrides = {},
|
|
32
|
+
} = options;
|
|
33
|
+
|
|
34
|
+
if (!accessToken) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
'[@jacques_gordon/expo-mapbox-navigation] `accessToken` is required in the plugin config.\n' +
|
|
37
|
+
'Add it to your app.json plugins array:\n' +
|
|
38
|
+
' ["@jacques_gordon/expo-mapbox-navigation", { "accessToken": "pk.your_token" }]'
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Validate mapboxMapsVersion >= 11.11.0
|
|
43
|
+
const [major, minor] = mapboxMapsVersion.split('.').map(Number);
|
|
44
|
+
if (major < 11 || (major === 11 && minor < 11)) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`[@jacques_gordon/expo-mapbox-navigation] mapboxMapsVersion must be >= 11.11.0.\n` +
|
|
47
|
+
`Provided: ${mapboxMapsVersion}\n` +
|
|
48
|
+
`This minimum version is required to fix the CameraAnimationsUtils crash (issue #43).`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ── Android: project-level build.gradle ─────────────────────────────────
|
|
53
|
+
config = withProjectBuildGradle(config, (mod) => {
|
|
54
|
+
let contents = mod.modResults.contents;
|
|
55
|
+
|
|
56
|
+
// Add Mapbox Maven repo if not already present
|
|
57
|
+
if (!contents.includes('api.mapbox.com/downloads/v2/releases/maven')) {
|
|
58
|
+
const mavenBlock = `
|
|
59
|
+
maven {
|
|
60
|
+
url 'https://api.mapbox.com/downloads/v2/releases/maven'
|
|
61
|
+
authentication { basic(BasicAuthentication) }
|
|
62
|
+
credentials {
|
|
63
|
+
username = 'mapbox'
|
|
64
|
+
password = project.hasProperty('MAPBOX_DOWNLOADS_TOKEN')
|
|
65
|
+
? project.property('MAPBOX_DOWNLOADS_TOKEN')
|
|
66
|
+
: System.getenv('MAPBOX_DOWNLOADS_TOKEN') ?: ""
|
|
67
|
+
}
|
|
68
|
+
}`;
|
|
69
|
+
|
|
70
|
+
// Insert into allprojects.repositories if it exists
|
|
71
|
+
if (contents.includes('allprojects') && contents.includes('repositories')) {
|
|
72
|
+
contents = contents.replace(
|
|
73
|
+
/allprojects\s*\{[\s\S]*?repositories\s*\{/,
|
|
74
|
+
(match) => match + mavenBlock
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
mod.modResults.contents = contents;
|
|
80
|
+
return mod;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// ── Android: app-level build.gradle ─────────────────────────────────────
|
|
84
|
+
config = withAppBuildGradle(config, (mod) => {
|
|
85
|
+
let contents = mod.modResults.contents;
|
|
86
|
+
|
|
87
|
+
// Force NDK 27 for 16 KB page size
|
|
88
|
+
if (!contents.includes('ndkVersion')) {
|
|
89
|
+
contents = contents.replace(
|
|
90
|
+
/android\s*\{/,
|
|
91
|
+
`android {\n ndkVersion "${NDK_VERSION}" // Required for 16 KB page size (expo-mapbox-navigation)`
|
|
92
|
+
);
|
|
93
|
+
} else if (!contents.includes(NDK_VERSION)) {
|
|
94
|
+
// Replace any existing ndkVersion
|
|
95
|
+
contents = contents.replace(
|
|
96
|
+
/ndkVersion\s+["'][^"']*["']/,
|
|
97
|
+
`ndkVersion "${NDK_VERSION}" // Forced by expo-mapbox-navigation for 16KB page size`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Enable useLegacyPackaging = false for 16 KB page alignment
|
|
102
|
+
if (!contents.includes('useLegacyPackaging')) {
|
|
103
|
+
contents = contents.replace(
|
|
104
|
+
/android\s*\{/,
|
|
105
|
+
`android {\n packagingOptions {\n jniLibs {\n useLegacyPackaging = false // 16 KB page size support\n }\n }`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Pin Mapbox Maps version via resolutionStrategy
|
|
110
|
+
const resolutionBlock = `
|
|
111
|
+
configurations.all {
|
|
112
|
+
resolutionStrategy {
|
|
113
|
+
// Force Mapbox Maps SDK >= ${mapboxMapsVersion} — required for NavigationCamera compatibility
|
|
114
|
+
force "com.mapbox.maps:android:${mapboxMapsVersion}"
|
|
115
|
+
}
|
|
116
|
+
}`;
|
|
117
|
+
|
|
118
|
+
if (!contents.includes('com.mapbox.maps:android')) {
|
|
119
|
+
contents = contents + '\n' + resolutionBlock;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
mod.modResults.contents = contents;
|
|
123
|
+
return mod;
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// ── Android: AndroidManifest — add access token as meta-data ─────────────
|
|
127
|
+
config = withAndroidManifest(config, (mod) => {
|
|
128
|
+
const mainApp = mod.modResults.manifest.application?.[0];
|
|
129
|
+
if (mainApp) {
|
|
130
|
+
if (!mainApp['meta-data']) {
|
|
131
|
+
mainApp['meta-data'] = [];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const tokenMeta = mainApp['meta-data'].find(
|
|
135
|
+
(m) => m.$?.['android:name'] === 'com.mapbox.token'
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (!tokenMeta) {
|
|
139
|
+
mainApp['meta-data'].push({
|
|
140
|
+
$: {
|
|
141
|
+
'android:name': 'com.mapbox.token',
|
|
142
|
+
'android:value': accessToken,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return mod;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// ── Android: Write color overrides resource file ──────────────────────────
|
|
151
|
+
if (Object.keys(androidColorOverrides).length > 0) {
|
|
152
|
+
config = withDangerousMod(config, [
|
|
153
|
+
'android',
|
|
154
|
+
async (mod) => {
|
|
155
|
+
const colorsDir = path.join(
|
|
156
|
+
mod.modRequest.platformProjectRoot,
|
|
157
|
+
'app/src/main/res/values'
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
if (!fs.existsSync(colorsDir)) {
|
|
161
|
+
fs.mkdirSync(colorsDir, { recursive: true });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const colorEntries = Object.entries(androidColorOverrides)
|
|
165
|
+
.map(([name, value]) => ` <color name="${name}">${value}</color>`)
|
|
166
|
+
.join('\n');
|
|
167
|
+
|
|
168
|
+
const colorsXml = `<?xml version="1.0" encoding="utf-8"?>
|
|
169
|
+
<!-- Generated by @jacques_gordon/expo-mapbox-navigation config plugin -->
|
|
170
|
+
<resources>
|
|
171
|
+
${colorEntries}
|
|
172
|
+
</resources>
|
|
173
|
+
`;
|
|
174
|
+
|
|
175
|
+
fs.writeFileSync(
|
|
176
|
+
path.join(colorsDir, 'mapbox_navigation_colors.xml'),
|
|
177
|
+
colorsXml
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
return mod;
|
|
181
|
+
},
|
|
182
|
+
]);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ── iOS: Info.plist ──────────────────────────────────────────────────────
|
|
186
|
+
config = withInfoPlist(config, (mod) => {
|
|
187
|
+
// Mapbox public token
|
|
188
|
+
mod.modResults.MBXAccessToken = accessToken;
|
|
189
|
+
|
|
190
|
+
// Location permissions (required for navigation)
|
|
191
|
+
if (!mod.modResults.NSLocationWhenInUseUsageDescription) {
|
|
192
|
+
mod.modResults.NSLocationWhenInUseUsageDescription =
|
|
193
|
+
'Your location is used for turn-by-turn navigation.';
|
|
194
|
+
}
|
|
195
|
+
if (!mod.modResults.NSLocationAlwaysAndWhenInUseUsageDescription) {
|
|
196
|
+
mod.modResults.NSLocationAlwaysAndWhenInUseUsageDescription =
|
|
197
|
+
'Your location is used for turn-by-turn navigation even when the app is in the background.';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Background modes required for navigation audio + location tracking
|
|
201
|
+
if (!mod.modResults.UIBackgroundModes) {
|
|
202
|
+
mod.modResults.UIBackgroundModes = [];
|
|
203
|
+
}
|
|
204
|
+
for (const mode of ['audio', 'location']) {
|
|
205
|
+
if (!mod.modResults.UIBackgroundModes.includes(mode)) {
|
|
206
|
+
mod.modResults.UIBackgroundModes.push(mode);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return mod;
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
return config;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
module.exports = withMapboxNavigation;
|
package/build/index.d.ts
CHANGED
|
@@ -1,2 +1,121 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import { ViewStyle } from 'react-native';
|
|
2
|
+
export interface Coordinate {
|
|
3
|
+
latitude: number;
|
|
4
|
+
longitude: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Voice/distance unit system for navigation instructions.
|
|
8
|
+
*
|
|
9
|
+
* Fixes Issue #31: previously always defaulted to imperial.
|
|
10
|
+
* - "metric" → km/m for distances, km/h for speed
|
|
11
|
+
* - "imperial" → mi/ft for distances, mph for speed
|
|
12
|
+
* - undefined → auto-detected from device locale
|
|
13
|
+
*/
|
|
14
|
+
export type VoiceUnits = 'metric' | 'imperial';
|
|
15
|
+
export type NavigationProfile = 'driving-traffic' | 'driving' | 'walking' | 'cycling';
|
|
16
|
+
export interface MapboxNavigationViewProps {
|
|
17
|
+
/** Navigation route waypoints. Minimum 2 coordinates required. */
|
|
18
|
+
coordinates: Coordinate[];
|
|
19
|
+
/**
|
|
20
|
+
* Indices into `coordinates` that are considered waypoints.
|
|
21
|
+
* First and last must be included. Defaults to all points.
|
|
22
|
+
*/
|
|
23
|
+
waypointIndices?: number[];
|
|
24
|
+
/**
|
|
25
|
+
* BCP-47 language/locale tag for map labels and voice instructions.
|
|
26
|
+
* Example: "fr", "en-US", "de-DE". Defaults to device locale.
|
|
27
|
+
*/
|
|
28
|
+
language?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Unit system for voice instructions and distance display.
|
|
31
|
+
* - "metric" → kilometres and metres (default outside US/UK)
|
|
32
|
+
* - "imperial" → miles and feet (default in US/UK)
|
|
33
|
+
* - undefined → auto-detected from device locale
|
|
34
|
+
*
|
|
35
|
+
* Fixes Issue #31.
|
|
36
|
+
*/
|
|
37
|
+
voiceUnits?: VoiceUnits;
|
|
38
|
+
/**
|
|
39
|
+
* Mapbox Directions profile.
|
|
40
|
+
* Android: omit the "mapbox/" prefix (handled internally).
|
|
41
|
+
*/
|
|
42
|
+
navigationProfile?: NavigationProfile;
|
|
43
|
+
/** Road / feature types to exclude from the route */
|
|
44
|
+
excludeTypes?: string[];
|
|
45
|
+
/** Mapbox map style URL. Defaults to Mapbox Navigation Day style. */
|
|
46
|
+
mapStyle?: string;
|
|
47
|
+
/** Whether audio is initially muted. Defaults to false. */
|
|
48
|
+
mute?: boolean;
|
|
49
|
+
/** Maximum vehicle height in metres (for height-restricted routes). */
|
|
50
|
+
maxHeight?: number;
|
|
51
|
+
/** Maximum vehicle width in metres (for width-restricted routes). */
|
|
52
|
+
maxWidth?: number;
|
|
53
|
+
/**
|
|
54
|
+
* When true, uses the Mapbox Map Matching API instead of the
|
|
55
|
+
* standard Directions API. Useful when you want a route that
|
|
56
|
+
* exactly follows the given coordinates.
|
|
57
|
+
*/
|
|
58
|
+
useMapMatching?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* URL template for a custom raster tile overlay.
|
|
61
|
+
* Must include {x}, {y}, {z} placeholders.
|
|
62
|
+
* Example: "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
63
|
+
*/
|
|
64
|
+
customRasterTileUrl?: string;
|
|
65
|
+
/** Map layer ID above which the custom raster layer is placed. */
|
|
66
|
+
customRasterAboveLayerId?: string;
|
|
67
|
+
onRouteProgressChanged?: (event: {
|
|
68
|
+
nativeEvent: RouteProgressEvent;
|
|
69
|
+
}) => void;
|
|
70
|
+
onRoutesReady?: (event: {
|
|
71
|
+
nativeEvent: RoutesReadyEvent;
|
|
72
|
+
}) => void;
|
|
73
|
+
onNavigationFinished?: (event: {
|
|
74
|
+
nativeEvent: {};
|
|
75
|
+
}) => void;
|
|
76
|
+
onNavigationCancelled?: (event: {
|
|
77
|
+
nativeEvent: {};
|
|
78
|
+
}) => void;
|
|
79
|
+
onRoutesFailed?: (event: {
|
|
80
|
+
nativeEvent: {
|
|
81
|
+
message: string;
|
|
82
|
+
};
|
|
83
|
+
}) => void;
|
|
84
|
+
onArrival?: (event: {
|
|
85
|
+
nativeEvent: {};
|
|
86
|
+
}) => void;
|
|
87
|
+
style?: ViewStyle;
|
|
88
|
+
}
|
|
89
|
+
export interface RouteProgressEvent {
|
|
90
|
+
distanceRemaining: number;
|
|
91
|
+
durationRemaining: number;
|
|
92
|
+
distanceTraveled: number;
|
|
93
|
+
fractionTraveled: number;
|
|
94
|
+
currentStepDistanceRemaining: number;
|
|
95
|
+
}
|
|
96
|
+
export interface RoutesReadyEvent {
|
|
97
|
+
routeCount: number;
|
|
98
|
+
distanceMeters: number;
|
|
99
|
+
durationSeconds: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* MapboxNavigationView
|
|
103
|
+
*
|
|
104
|
+
* Renders the Mapbox Drop-In Navigation UI inside your Expo/React Native app.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```tsx
|
|
108
|
+
* <MapboxNavigationView
|
|
109
|
+
* style={{ flex: 1 }}
|
|
110
|
+
* coordinates={[
|
|
111
|
+
* { latitude: 48.8566, longitude: 2.3522 },
|
|
112
|
+
* { latitude: 51.5074, longitude: -0.1278 },
|
|
113
|
+
* ]}
|
|
114
|
+
* voiceUnits="metric"
|
|
115
|
+
* language="fr"
|
|
116
|
+
* onArrival={() => console.log('Arrived!')}
|
|
117
|
+
* />
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare function MapboxNavigationView(props: MapboxNavigationViewProps): any;
|
|
121
|
+
export default MapboxNavigationView;
|
package/build/index.js
CHANGED
|
@@ -3,6 +3,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MapboxNavigationView =
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
exports.MapboxNavigationView = MapboxNavigationView;
|
|
7
|
+
const expo_modules_core_1 = require("expo-modules-core");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const react_native_1 = require("react-native");
|
|
10
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
+
// Native view
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
const NativeView = (0, expo_modules_core_1.requireNativeViewManager)('ExpoMapboxNavigation');
|
|
14
|
+
/**
|
|
15
|
+
* MapboxNavigationView
|
|
16
|
+
*
|
|
17
|
+
* Renders the Mapbox Drop-In Navigation UI inside your Expo/React Native app.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <MapboxNavigationView
|
|
22
|
+
* style={{ flex: 1 }}
|
|
23
|
+
* coordinates={[
|
|
24
|
+
* { latitude: 48.8566, longitude: 2.3522 },
|
|
25
|
+
* { latitude: 51.5074, longitude: -0.1278 },
|
|
26
|
+
* ]}
|
|
27
|
+
* voiceUnits="metric"
|
|
28
|
+
* language="fr"
|
|
29
|
+
* onArrival={() => console.log('Arrived!')}
|
|
30
|
+
* />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function MapboxNavigationView(props) {
|
|
34
|
+
return (react_1.default.createElement(NativeView, { ...props, style: [styles.fullSize, props.style] }));
|
|
35
|
+
}
|
|
36
|
+
const styles = react_native_1.StyleSheet.create({
|
|
37
|
+
fullSize: { flex: 1 },
|
|
38
|
+
});
|
|
39
|
+
exports.default = MapboxNavigationView;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ViewStyle } from 'react-native';
|
|
2
|
+
export interface Coordinate {
|
|
3
|
+
latitude: number;
|
|
4
|
+
longitude: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Voice/distance unit system for navigation instructions.
|
|
8
|
+
*
|
|
9
|
+
* Fixes Issue #31: previously always defaulted to imperial.
|
|
10
|
+
* - "metric" → km/m for distances, km/h for speed
|
|
11
|
+
* - "imperial" → mi/ft for distances, mph for speed
|
|
12
|
+
* - undefined → auto-detected from device locale
|
|
13
|
+
*/
|
|
14
|
+
export type VoiceUnits = 'metric' | 'imperial';
|
|
15
|
+
export type NavigationProfile = 'driving-traffic' | 'driving' | 'walking' | 'cycling';
|
|
16
|
+
export interface MapboxNavigationViewProps {
|
|
17
|
+
/** Navigation route waypoints. Minimum 2 coordinates required. */
|
|
18
|
+
coordinates: Coordinate[];
|
|
19
|
+
/**
|
|
20
|
+
* Indices into `coordinates` that are considered waypoints.
|
|
21
|
+
* First and last must be included. Defaults to all points.
|
|
22
|
+
*/
|
|
23
|
+
waypointIndices?: number[];
|
|
24
|
+
/**
|
|
25
|
+
* BCP-47 language/locale tag for map labels and voice instructions.
|
|
26
|
+
* Example: "fr", "en-US", "de-DE". Defaults to device locale.
|
|
27
|
+
*/
|
|
28
|
+
language?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Unit system for voice instructions and distance display.
|
|
31
|
+
* - "metric" → kilometres and metres (default outside US/UK)
|
|
32
|
+
* - "imperial" → miles and feet (default in US/UK)
|
|
33
|
+
* - undefined → auto-detected from device locale
|
|
34
|
+
*
|
|
35
|
+
* Fixes Issue #31.
|
|
36
|
+
*/
|
|
37
|
+
voiceUnits?: VoiceUnits;
|
|
38
|
+
/**
|
|
39
|
+
* Mapbox Directions profile.
|
|
40
|
+
* Android: omit the "mapbox/" prefix (handled internally).
|
|
41
|
+
*/
|
|
42
|
+
navigationProfile?: NavigationProfile;
|
|
43
|
+
/** Road / feature types to exclude from the route */
|
|
44
|
+
excludeTypes?: string[];
|
|
45
|
+
/** Mapbox map style URL. Defaults to Mapbox Navigation Day style. */
|
|
46
|
+
mapStyle?: string;
|
|
47
|
+
/** Whether audio is initially muted. Defaults to false. */
|
|
48
|
+
mute?: boolean;
|
|
49
|
+
/** Maximum vehicle height in metres (for height-restricted routes). */
|
|
50
|
+
maxHeight?: number;
|
|
51
|
+
/** Maximum vehicle width in metres (for width-restricted routes). */
|
|
52
|
+
maxWidth?: number;
|
|
53
|
+
/**
|
|
54
|
+
* When true, uses the Mapbox Map Matching API instead of the
|
|
55
|
+
* standard Directions API. Useful when you want a route that
|
|
56
|
+
* exactly follows the given coordinates.
|
|
57
|
+
*/
|
|
58
|
+
useMapMatching?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* URL template for a custom raster tile overlay.
|
|
61
|
+
* Must include {x}, {y}, {z} placeholders.
|
|
62
|
+
* Example: "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
63
|
+
*/
|
|
64
|
+
customRasterTileUrl?: string;
|
|
65
|
+
/** Map layer ID above which the custom raster layer is placed. */
|
|
66
|
+
customRasterAboveLayerId?: string;
|
|
67
|
+
onRouteProgressChanged?: (event: {
|
|
68
|
+
nativeEvent: RouteProgressEvent;
|
|
69
|
+
}) => void;
|
|
70
|
+
onRoutesReady?: (event: {
|
|
71
|
+
nativeEvent: RoutesReadyEvent;
|
|
72
|
+
}) => void;
|
|
73
|
+
onNavigationFinished?: (event: {
|
|
74
|
+
nativeEvent: {};
|
|
75
|
+
}) => void;
|
|
76
|
+
onNavigationCancelled?: (event: {
|
|
77
|
+
nativeEvent: {};
|
|
78
|
+
}) => void;
|
|
79
|
+
onRoutesFailed?: (event: {
|
|
80
|
+
nativeEvent: {
|
|
81
|
+
message: string;
|
|
82
|
+
};
|
|
83
|
+
}) => void;
|
|
84
|
+
onArrival?: (event: {
|
|
85
|
+
nativeEvent: {};
|
|
86
|
+
}) => void;
|
|
87
|
+
style?: ViewStyle;
|
|
88
|
+
}
|
|
89
|
+
export interface RouteProgressEvent {
|
|
90
|
+
distanceRemaining: number;
|
|
91
|
+
durationRemaining: number;
|
|
92
|
+
distanceTraveled: number;
|
|
93
|
+
fractionTraveled: number;
|
|
94
|
+
currentStepDistanceRemaining: number;
|
|
95
|
+
}
|
|
96
|
+
export interface RoutesReadyEvent {
|
|
97
|
+
routeCount: number;
|
|
98
|
+
distanceMeters: number;
|
|
99
|
+
durationSeconds: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* MapboxNavigationView
|
|
103
|
+
*
|
|
104
|
+
* Renders the Mapbox Drop-In Navigation UI inside your Expo/React Native app.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```tsx
|
|
108
|
+
* <MapboxNavigationView
|
|
109
|
+
* style={{ flex: 1 }}
|
|
110
|
+
* coordinates={[
|
|
111
|
+
* { latitude: 48.8566, longitude: 2.3522 },
|
|
112
|
+
* { latitude: 51.5074, longitude: -0.1278 },
|
|
113
|
+
* ]}
|
|
114
|
+
* voiceUnits="metric"
|
|
115
|
+
* language="fr"
|
|
116
|
+
* onArrival={() => console.log('Arrived!')}
|
|
117
|
+
* />
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare function MapboxNavigationView(props: MapboxNavigationViewProps): any;
|
|
121
|
+
export default MapboxNavigationView;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MapboxNavigationView = MapboxNavigationView;
|
|
7
|
+
const expo_modules_core_1 = require("expo-modules-core");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const react_native_1 = require("react-native");
|
|
10
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
+
// Native view
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
const NativeView = (0, expo_modules_core_1.requireNativeViewManager)('ExpoMapboxNavigation');
|
|
14
|
+
/**
|
|
15
|
+
* MapboxNavigationView
|
|
16
|
+
*
|
|
17
|
+
* Renders the Mapbox Drop-In Navigation UI inside your Expo/React Native app.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <MapboxNavigationView
|
|
22
|
+
* style={{ flex: 1 }}
|
|
23
|
+
* coordinates={[
|
|
24
|
+
* { latitude: 48.8566, longitude: 2.3522 },
|
|
25
|
+
* { latitude: 51.5074, longitude: -0.1278 },
|
|
26
|
+
* ]}
|
|
27
|
+
* voiceUnits="metric"
|
|
28
|
+
* language="fr"
|
|
29
|
+
* onArrival={() => console.log('Arrived!')}
|
|
30
|
+
* />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function MapboxNavigationView(props) {
|
|
34
|
+
return (react_1.default.createElement(NativeView, { ...props, style: [styles.fullSize, props.style] }));
|
|
35
|
+
}
|
|
36
|
+
const styles = react_native_1.StyleSheet.create({
|
|
37
|
+
fullSize: { flex: 1 },
|
|
38
|
+
});
|
|
39
|
+
exports.default = MapboxNavigationView;
|
package/package.json
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jacques_gordon/expo-mapbox-navigation",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Expo module for Mapbox
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Expo module for Mapbox Navigation SDK with 16KB page size support, NDK27, and Mapbox Maps v11.11.0+",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"build",
|
|
9
|
-
"ios",
|
|
10
|
-
"android",
|
|
11
|
-
"plugin",
|
|
12
|
-
"app.plugin.js",
|
|
13
|
-
"expo-module.config.json",
|
|
14
|
-
"README.md"
|
|
15
|
-
],
|
|
16
7
|
"scripts": {
|
|
17
|
-
"build": "
|
|
18
|
-
"clean": "
|
|
19
|
-
"lint": "
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"prepublishOnly": "expo-module prepublishOnly"
|
|
8
|
+
"build": "tsc -p tsconfig.json",
|
|
9
|
+
"clean": "rm -rf build",
|
|
10
|
+
"lint": "tsc --noEmit",
|
|
11
|
+
"test": "echo \"Tests require a full Expo project with EAS Build. See README.\"",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
23
13
|
},
|
|
24
14
|
"keywords": [
|
|
25
15
|
"expo",
|
|
26
16
|
"mapbox",
|
|
27
17
|
"navigation",
|
|
28
|
-
"turn-by-turn",
|
|
29
18
|
"react-native",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
19
|
+
"maps",
|
|
20
|
+
"directions",
|
|
21
|
+
"16kb-page-size",
|
|
22
|
+
"ndk27"
|
|
33
23
|
],
|
|
34
|
-
"license": "MIT",
|
|
35
24
|
"repository": {
|
|
36
25
|
"type": "git",
|
|
37
|
-
"url": "https://github.com/
|
|
26
|
+
"url": "https://github.com/jacques_gordon/expo-mapbox-navigation.git"
|
|
38
27
|
},
|
|
39
28
|
"bugs": {
|
|
40
|
-
"url": "https://github.com/
|
|
29
|
+
"url": "https://github.com/jacques_gordon/expo-mapbox-navigation/issues"
|
|
41
30
|
},
|
|
42
|
-
"
|
|
31
|
+
"author": "Jacques Gordon",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"homepage": "https://github.com/jacques_gordon/expo-mapbox-navigation#readme",
|
|
43
34
|
"peerDependencies": {
|
|
44
35
|
"expo": ">=53.0.0",
|
|
45
36
|
"react": "*",
|
|
46
|
-
"react-native": "*"
|
|
37
|
+
"react-native": "*",
|
|
38
|
+
"@rnmapbox/maps": ">=10.1.0"
|
|
47
39
|
},
|
|
48
40
|
"devDependencies": {
|
|
49
|
-
"
|
|
50
|
-
"@types/react": "^19.2.17",
|
|
51
|
-
"expo-module-scripts": "^56.0.3",
|
|
52
|
-
"expo-modules-core": "^2.0.0",
|
|
53
|
-
"tsup": "^8.5.1",
|
|
41
|
+
"expo-module-scripts": "^3.5.0",
|
|
54
42
|
"typescript": "^5.3.0"
|
|
55
43
|
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"expo-modules-core": ">=2.0.0"
|
|
46
|
+
},
|
|
56
47
|
"expo": {
|
|
57
|
-
"fyi": "https://
|
|
58
|
-
"config": "./plugin/build/index.js"
|
|
48
|
+
"fyi": "https://github.com/jacques_gordon/expo-mapbox-navigation"
|
|
59
49
|
},
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
50
|
+
"files": [
|
|
51
|
+
"android",
|
|
52
|
+
"ios",
|
|
53
|
+
"src",
|
|
54
|
+
"build",
|
|
55
|
+
"plugin",
|
|
56
|
+
"*.podspec",
|
|
57
|
+
"app.plugin.js",
|
|
58
|
+
"README.md",
|
|
59
|
+
"LICENSE"
|
|
60
|
+
],
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
63
|
}
|
|
64
|
-
}
|
|
64
|
+
}
|