diff --git a/docs/navigation/api.md b/docs/navigation/api.md deleted file mode 100644 index 6424b4a3..00000000 --- a/docs/navigation/api.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: api -sidebar_position: 5 -title: API reference ---- - -`Navigation` is the default export and also a named export. - -```tsx -import Navigation, { NAVIGATION_MAP_VIEW_IMPL, NavigationViewport } from '@rnmapbox/navigation'; -``` - -## Navigation - -| Method | Description | -| -------------------------------------------------------- | --------------------------------------------------------------------------- | -| `setAccessToken(accessToken: string): void` | Must be called before any request; navigation is billed to this token. | -| `getSdkVersion(): string` | Version of the native Navigation SDK linked into the app. | -| `requestRoutes(options: RouteRequestOptions): Promise` | Routes through `options.waypoints`. Rejects with fewer than two waypoints. | -| `previewRoute(route: Route \| null): void` | Shows `route` on navigation maps until guidance starts or `stopNavigation`; `null` removes it. Throws if `route` was released. | -| `startActiveGuidance(route: Route, options?: { simulate?: boolean }): Promise` | Starts guidance along `route` and switches the camera to `following`. `simulate` drives it with simulated locations. | -| `stopNavigation(): void` | Stops guidance and removes the route from navigation maps. | -| `getRouteStats(): RouteStats` | `{ live, released, collected }` counts of native routes, for leak checks. | -| `setCameraState(state: CameraState): void` | `'following'`, `'overview'` or `'idle'`. | -| `getCameraState(): CameraState` | Current camera state. | -| `addCameraStateListener(listener: (state: CameraState) => void): EventSubscription` | Called whenever the camera state changes, whether from JS, guidance or a map gesture. | -| `addRouteProgressListener(listener: (event: RouteProgressEvent) => void): EventSubscription` | Route progress during guidance. | - -## Components and constants - -| Export | Description | -| -------------------------- | ------------------------------------------------------------------------------------------------- | -| `NAVIGATION_MAP_VIEW_IMPL` | Pass as `mapViewImpl` to an `@rnmapbox/maps` `MapView` to make it a navigation map. | -| `NavigationViewport` | Child of a navigation map. `padding?: { top?, right?, bottom?, left? }` in points from the map's edges, ignoring the safe area. | -| `NavigationView` | Full-screen navigation UI, see [NavigationView](navigation-view.md). Not released yet. | - -## Types - -```ts -/** GeoJSON order, same as @rnmapbox/maps. */ -type Position = [longitude: number, latitude: number]; - -type Waypoint = Position | { coordinate: Position; name?: string }; - -type RouteRequestOptions = { - /** Origin first, destination last. */ - waypoints: Waypoint[]; - /** Defaults to 'driving-traffic'. */ - profile?: 'driving-traffic' | 'driving' | 'walking' | 'cycling'; - /** Also return alternative routes. Defaults to false. */ - alternatives?: boolean; - /** Road classes to avoid, e.g. ['toll', 'ferry']. */ - exclude?: string[]; - /** Language of instructions, e.g. 'en' or 'de-DE'. */ - language?: string; - units?: 'metric' | 'imperial'; -}; - -type RouteResponse = { main: Route; alternatives: Route[] }; - -interface Route { - readonly distance: number; // meters - readonly expectedTravelTime: number; // seconds - readonly geometry: LineString; // GeoJSON, a new object on every read - readonly legs: RouteLeg[]; // a new array on every read - readonly isReleased: boolean; - /** Frees the native route. Calling it again does nothing. */ - release(): void; -} - -type RouteLeg = { - distance: number; // meters - expectedTravelTime: number; // seconds - stepCount: number; - /** Names of the main roads, e.g. "Market Street, Embarcadero". */ - summary: string; -}; - -type RouteStats = { live: number; released: number; collected: number }; - -type CameraState = 'following' | 'overview' | 'idle'; - -type RouteProgressEvent = { - distanceRemaining: number; // meters - distanceTraveled: number; // meters - durationRemaining: number; // seconds - fractionTraveled: number; // 0..1 - stepDistanceRemaining: number; // meters to the next maneuver - /** Primary banner text of the next maneuver, e.g. "Turn right onto Market Street". */ - maneuverInstruction: string; - /** Mapbox Directions maneuver type, e.g. "turn", "arrive". Empty if unknown. */ - maneuverType: string; - /** Mapbox Directions maneuver modifier, e.g. "right", "slight left". Empty if unknown. */ - maneuverModifier: string; -}; -``` diff --git a/docs/navigation/api/Components/NavigationView.md b/docs/navigation/api/Components/NavigationView.md new file mode 100644 index 00000000..2fd997b3 --- /dev/null +++ b/docs/navigation/api/Components/NavigationView.md @@ -0,0 +1,29 @@ +--- +sidebar_label: NavigationView +sidebar_position: 1 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# NavigationView() + +```ts +function NavigationView(props: NavigationViewProps): Element; +``` + +Full-screen turn-by-turn navigation UI: `NavigationViewController` from `MapboxNavigationUIKit` on iOS, and an +equivalent built from the Navigation SDK UI components on Android. + +It uses the app's single navigation session: mounting it, or giving it a new route, starts guidance along that route, +replacing any active guidance, and unmounting it or the user ending the trip stops guidance. Show one at a time. + +## Parameters + +| Parameter | Type | Description | +| ------ | ------ | ------ | +| `props` | [`NavigationViewProps`](NavigationViewProps.md) | See [NavigationViewProps](NavigationViewProps.md). | + +## Returns + +`Element` diff --git a/docs/navigation/api/Components/NavigationViewError.md b/docs/navigation/api/Components/NavigationViewError.md new file mode 100644 index 00000000..6a4cd8e1 --- /dev/null +++ b/docs/navigation/api/Components/NavigationViewError.md @@ -0,0 +1,22 @@ +--- +sidebar_label: NavigationViewError +sidebar_position: 4 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# NavigationViewError + +```ts +type NavigationViewError = object; +``` + +Passed to `onError` of [NavigationView](NavigationView.md) and [RNNavigationView](RNNavigationView.md). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `code` | `string` | E.g. `route_request_failed`, `route_released`, `start_failed`. | +| `message` | `string` | Human-readable, from the SDK where it has one. | diff --git a/docs/navigation/api/Components/NavigationViewProps.md b/docs/navigation/api/Components/NavigationViewProps.md new file mode 100644 index 00000000..f2fdab47 --- /dev/null +++ b/docs/navigation/api/Components/NavigationViewProps.md @@ -0,0 +1,30 @@ +--- +sidebar_label: NavigationViewProps +sidebar_position: 6 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# NavigationViewProps + +```ts +type NavigationViewProps = object; +``` + +Props of [NavigationView](NavigationView.md). Pass either `route` or `waypoints`. + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `mute?` | `boolean` | Mutes voice instructions. The view's own mute button also toggles them. | +| `onArrive?` | (`event`: [`ArriveEvent`](../Events/ArriveEvent.md)) => `void` | Same event as [Navigation.addArriveListener](../Core/Navigation.md#addarrivelistener). | +| `onCancel?` | () => `void` | The user ended the trip; guidance has stopped. Unmount the view. | +| `onError?` | (`error`: [`NavigationViewError`](NavigationViewError.md)) => `void` | The route request or the start of guidance failed. | +| `onRouteProgress?` | (`event`: [`RouteProgressEvent`](../Events/RouteProgressEvent.md)) => `void` | Same event as [Navigation.addRouteProgressListener](../Core/Navigation.md#addrouteprogresslistener). | +| `route?` | [`Route`](../Routes/Route.md) | Route from `requestRoutes`. Keep it unreleased while it's passed to the view. | +| `simulate?` | `boolean` | Drive the route with simulated locations. Read when guidance starts. | +| `style?` | `StyleProp`\<`ViewStyle`\> | - | +| `testID?` | `string` | - | +| `waypoints?` | [`Waypoint`](../Routes/Waypoint.md)[] | Used when `route` isn't set: the view requests a route through them, origin first, and releases it on unmount. | diff --git a/docs/navigation/api/Components/NavigationViewport.md b/docs/navigation/api/Components/NavigationViewport.md new file mode 100644 index 00000000..61fc272f --- /dev/null +++ b/docs/navigation/api/Components/NavigationViewport.md @@ -0,0 +1,27 @@ +--- +sidebar_label: NavigationViewport +sidebar_position: 2 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# NavigationViewport() + +```ts +function NavigationViewport(props: NavigationViewportProps): Element; +``` + +Configures the navigation camera of the `@rnmapbox/maps` `MapView` it's a child of: +``. +Without it the SDK defaults apply: the safe area plus a small margin on iOS, no padding on Android. + +## Parameters + +| Parameter | Type | Description | +| ------ | ------ | ------ | +| `props` | [`NavigationViewportProps`](NavigationViewportProps.md) | See [NavigationViewportProps](NavigationViewportProps.md). | + +## Returns + +`Element` diff --git a/docs/navigation/api/Components/NavigationViewportProps.md b/docs/navigation/api/Components/NavigationViewportProps.md new file mode 100644 index 00000000..16fd885d --- /dev/null +++ b/docs/navigation/api/Components/NavigationViewportProps.md @@ -0,0 +1,21 @@ +--- +sidebar_label: NavigationViewportProps +sidebar_position: 5 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# NavigationViewportProps + +```ts +type NavigationViewportProps = object; +``` + +Props of [NavigationViewport](NavigationViewport.md). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `padding?` | [`ViewportPadding`](ViewportPadding.md) | Area the navigation camera keeps the puck and the route in, e.g. to keep them clear of UI drawn over the map. Applies to `following`, `overview` and the route preview. | diff --git a/docs/navigation/api/Components/RNNavigationView.md b/docs/navigation/api/Components/RNNavigationView.md new file mode 100644 index 00000000..ef8c3aa3 --- /dev/null +++ b/docs/navigation/api/Components/RNNavigationView.md @@ -0,0 +1,30 @@ +--- +sidebar_label: RNNavigationView +sidebar_position: 3 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RNNavigationView() + +```ts +function RNNavigationView(props: RNNavigationViewProps): Element; +``` + +`` built in React Native from the headless API, on an `@rnmapbox/maps` navigation map: a maneuver +banner with lanes, speed limit, road name, trip progress, mute, overview/recenter and end buttons, and an arrival +message. + +It uses the app's single navigation session like ``. Use it as is, or copy it as a starting point +for your own UI. + +## Parameters + +| Parameter | Type | Description | +| ------ | ------ | ------ | +| `props` | [`RNNavigationViewProps`](RNNavigationViewProps.md) | See [RNNavigationViewProps](RNNavigationViewProps.md). | + +## Returns + +`Element` diff --git a/docs/navigation/api/Components/RNNavigationViewProps.md b/docs/navigation/api/Components/RNNavigationViewProps.md new file mode 100644 index 00000000..9001df46 --- /dev/null +++ b/docs/navigation/api/Components/RNNavigationViewProps.md @@ -0,0 +1,33 @@ +--- +sidebar_label: RNNavigationViewProps +sidebar_position: 7 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RNNavigationViewProps + +```ts +type RNNavigationViewProps = NavigationViewProps & object; +``` + +Props of [RNNavigationView](RNNavigationView.md): [NavigationViewProps](NavigationViewProps.md), plus the props below. + +## Type Declaration + +### children? + +```ts +children?: ReactNode; +``` + +Rendered inside the `MapView`, e.g. extra sources and layers. + +### styleURL? + +```ts +styleURL?: string; +``` + +Defaults to Mapbox Standard. diff --git a/docs/navigation/api/Components/ViewportPadding.md b/docs/navigation/api/Components/ViewportPadding.md new file mode 100644 index 00000000..d3269913 --- /dev/null +++ b/docs/navigation/api/Components/ViewportPadding.md @@ -0,0 +1,24 @@ +--- +sidebar_label: ViewportPadding +sidebar_position: 8 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# ViewportPadding + +```ts +type ViewportPadding = object; +``` + +Points from the map's edges, ignoring the safe area. + +## Properties + +| Property | Type | +| ------ | ------ | +| `bottom?` | `number` | +| `left?` | `number` | +| `right?` | `number` | +| `top?` | `number` | diff --git a/docs/navigation/api/Components/_category_.json b/docs/navigation/api/Components/_category_.json new file mode 100644 index 00000000..57bbce61 --- /dev/null +++ b/docs/navigation/api/Components/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Components", + "position": 2 +} diff --git a/docs/navigation/api/Core/CameraState.md b/docs/navigation/api/Core/CameraState.md new file mode 100644 index 00000000..a0a441e9 --- /dev/null +++ b/docs/navigation/api/Core/CameraState.md @@ -0,0 +1,16 @@ +--- +sidebar_label: CameraState +sidebar_position: 3 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# CameraState + +```ts +type CameraState = "following" | "overview" | "idle"; +``` + +Camera of navigation maps. `following` follows the puck, tilted and rotated with the route; `overview` fits the rest +of the route; `idle` leaves the map to the user's gestures and `@rnmapbox/maps` `Camera`. diff --git a/docs/navigation/api/Core/NAVIGATION_MAP_VIEW_IMPL.md b/docs/navigation/api/Core/NAVIGATION_MAP_VIEW_IMPL.md new file mode 100644 index 00000000..720060b9 --- /dev/null +++ b/docs/navigation/api/Core/NAVIGATION_MAP_VIEW_IMPL.md @@ -0,0 +1,16 @@ +--- +sidebar_label: NAVIGATION_MAP_VIEW_IMPL +sidebar_position: 2 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# NAVIGATION_MAP_VIEW_IMPL + +```ts +const NAVIGATION_MAP_VIEW_IMPL: "rnmbxnav" = 'rnmbxnav'; +``` + +Pass as `mapViewImpl` to an `@rnmapbox/maps` `MapView` to render the route line, the puck and the +navigation camera on it: ``. diff --git a/docs/navigation/api/Core/Navigation.md b/docs/navigation/api/Core/Navigation.md new file mode 100644 index 00000000..8a895366 --- /dev/null +++ b/docs/navigation/api/Core/Navigation.md @@ -0,0 +1,323 @@ +--- +sidebar_label: Navigation +sidebar_position: 1 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# Navigation + +```ts +const Navigation: object; +``` + +The headless navigation API: route requests, the app's single guidance session, and its events. +It's also the default export. + +## Type Declaration + +### addArriveListener() + +```ts +addArriveListener(listener: (event: ArriveEvent) => void): EventSubscription; +``` + +Called when guidance reaches a waypoint, the final destination included. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `listener` | (`event`: [`ArriveEvent`](../Events/ArriveEvent.md)) => `void` | + +#### Returns + +`EventSubscription` + +### addCameraStateListener() + +```ts +addCameraStateListener(listener: (state: CameraState) => void): EventSubscription; +``` + +Called whenever the camera state changes, whether from JS, guidance or a map gesture. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `listener` | (`state`: [`CameraState`](CameraState.md)) => `void` | + +#### Returns + +`EventSubscription` + +### addLocationListener() + +```ts +addLocationListener(listener: (event: LocationEvent) => void): EventSubscription; +``` + +The location snapped to the road or route, with its speed limit and road name. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `listener` | (`event`: [`LocationEvent`](../Events/LocationEvent.md)) => `void` | + +#### Returns + +`EventSubscription` + +### addOffRouteListener() + +```ts +addOffRouteListener(listener: (offRoute: boolean) => void): EventSubscription; +``` + +Called with `true` when the user leaves the route, then with `false` once guidance follows a route again. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `listener` | (`offRoute`: `boolean`) => `void` | + +#### Returns + +`EventSubscription` + +### addRouteChangeListener() + +```ts +addRouteChangeListener(listener: (event: RouteChangeEvent) => void): EventSubscription; +``` + +Called when guidance switches to another route on its own. Every listener gets the same new `Route`; the previous +one stays valid until released. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `listener` | (`event`: [`RouteChangeEvent`](../Events/RouteChangeEvent.md)) => `void` | + +#### Returns + +`EventSubscription` + +### addRouteProgressListener() + +```ts +addRouteProgressListener(listener: (event: RouteProgressEvent) => void): EventSubscription; +``` + +Called as guidance moves along the route, from the headless API and `` alike. Events already on +their way to JS can still arrive after `stopNavigation`. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `listener` | (`event`: [`RouteProgressEvent`](../Events/RouteProgressEvent.md)) => `void` | + +#### Returns + +`EventSubscription` + +### addVoiceInstructionListener() + +```ts +addVoiceInstructionListener(listener: (event: VoiceInstructionEvent) => void): EventSubscription; +``` + +Called when an instruction is due, whether or not the SDK speaks it; for apps doing their own text to speech. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `listener` | (`event`: [`VoiceInstructionEvent`](../Events/VoiceInstructionEvent.md)) => `void` | + +#### Returns + +`EventSubscription` + +### getCameraState() + +```ts +getCameraState(): CameraState; +``` + +The camera state of navigation maps, see [setCameraState](#setcamerastate). + +#### Returns + +[`CameraState`](CameraState.md) + +### getRouteStats() + +```ts +getRouteStats(): RouteStats; +``` + +Counts of native routes, for leak checks. + +#### Returns + +[`RouteStats`](../Routes/RouteStats.md) + +### getSdkVersion() + +```ts +getSdkVersion(): string; +``` + +Version of the native Mapbox Navigation SDK linked into the app. + +#### Returns + +`string` + +### isVoiceMuted() + +```ts +isVoiceMuted(): boolean; +``` + +Whether voice instructions are muted, by [setVoiceMuted](#setvoicemuted) or ``'s mute button. + +#### Returns + +`boolean` + +### previewRoute() + +```ts +previewRoute(route: Route | null): void; +``` + +Shows `route` on navigation maps until guidance starts or `stopNavigation` is called; `null` removes it. +Throws if `route` was released. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `route` | [`Route`](../Routes/Route.md) \| `null` | + +#### Returns + +`void` + +### requestRoutes() + +```ts +requestRoutes(options: RouteRequestOptions): Promise; +``` + +Requests routes through `options.waypoints`. The routes hold native memory: `release()` the ones you don't keep. +Rejects with fewer than two waypoints. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `options` | [`RouteRequestOptions`](../Routes/RouteRequestOptions.md) | + +#### Returns + +`Promise`\<[`RouteResponse`](../Routes/RouteResponse.md)\> + +### setAccessToken() + +```ts +setAccessToken(accessToken: string): void; +``` + +Must be called before any request; navigation is billed to this token. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `accessToken` | `string` | + +#### Returns + +`void` + +### setCameraState() + +```ts +setCameraState(state: CameraState): void; +``` + +Camera of every navigation map (``). +`idle` hands the camera back to the user's gestures and `@rnmapbox/maps` `Camera`. +Guidance switches it to `following`; a pan, zoom, rotate or pitch gesture on any navigation map +switches it to `idle`. Use [addCameraStateListener](#addcamerastatelistener) to follow those changes. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `state` | [`CameraState`](CameraState.md) | + +#### Returns + +`void` + +### setVoiceMuted() + +```ts +setVoiceMuted(muted: boolean): void; +``` + +Mutes the SDK's voice instructions for all guidance, including ``. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `muted` | `boolean` | + +#### Returns + +`void` + +### startActiveGuidance() + +```ts +startActiveGuidance(route: Route, options?: StartActiveGuidanceOptions): Promise; +``` + +Starts active guidance along `route`, replacing any active guidance, and switches the camera to `following`. +Rejects if `route` was released. Guidance keeps its own reference to the native route until `stopNavigation`, +so `route` can be released at any time. + +#### Parameters + +| Parameter | Type | +| ------ | ------ | +| `route` | [`Route`](../Routes/Route.md) | +| `options?` | [`StartActiveGuidanceOptions`](StartActiveGuidanceOptions.md) | + +#### Returns + +`Promise`\<`void`\> + +### stopNavigation() + +```ts +stopNavigation(): void; +``` + +Stops guidance and removes the route from navigation maps. The camera switches to `idle` and eases back to +north-up. + +#### Returns + +`void` diff --git a/docs/navigation/api/Core/StartActiveGuidanceOptions.md b/docs/navigation/api/Core/StartActiveGuidanceOptions.md new file mode 100644 index 00000000..88f7bc1b --- /dev/null +++ b/docs/navigation/api/Core/StartActiveGuidanceOptions.md @@ -0,0 +1,21 @@ +--- +sidebar_label: StartActiveGuidanceOptions +sidebar_position: 4 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# StartActiveGuidanceOptions + +```ts +type StartActiveGuidanceOptions = object; +``` + +Options of [Navigation.startActiveGuidance](Navigation.md#startactiveguidance). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `simulate?` | `boolean` | Drive the route with simulated locations instead of the device's location. | diff --git a/docs/navigation/api/Core/_category_.json b/docs/navigation/api/Core/_category_.json new file mode 100644 index 00000000..ff30fcc9 --- /dev/null +++ b/docs/navigation/api/Core/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Core", + "position": 1 +} diff --git a/docs/navigation/api/Events/ArriveEvent.md b/docs/navigation/api/Events/ArriveEvent.md new file mode 100644 index 00000000..310f553e --- /dev/null +++ b/docs/navigation/api/Events/ArriveEvent.md @@ -0,0 +1,22 @@ +--- +sidebar_label: ArriveEvent +sidebar_position: 1 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# ArriveEvent + +```ts +type ArriveEvent = object; +``` + +From [Navigation.addArriveListener](../Core/Navigation.md#addarrivelistener) and `onArrive`. + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `isFinalDestination` | `boolean` | The waypoint is the route's last one. | +| `waypointIndex` | `CodegenTypes.Int32` | Index in the route's waypoints, origin being 0. | diff --git a/docs/navigation/api/Events/Lane.md b/docs/navigation/api/Events/Lane.md new file mode 100644 index 00000000..22bb042e --- /dev/null +++ b/docs/navigation/api/Events/Lane.md @@ -0,0 +1,23 @@ +--- +sidebar_label: Lane +sidebar_position: 2 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# Lane + +```ts +type Lane = object; +``` + +A lane at the next maneuver, in `lanes` of [RouteProgressEvent](RouteProgressEvent.md). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `activeDirection` | `string` | The indication to follow in this lane, e.g. "right". Empty if unknown or not valid. | +| `indications` | `ReadonlyArray`\<`string`\> | E.g. `["straight", "right"]`. | +| `valid` | `boolean` | The lane can be used to complete the maneuver. | diff --git a/docs/navigation/api/Events/LocationEvent.md b/docs/navigation/api/Events/LocationEvent.md new file mode 100644 index 00000000..57516795 --- /dev/null +++ b/docs/navigation/api/Events/LocationEvent.md @@ -0,0 +1,26 @@ +--- +sidebar_label: LocationEvent +sidebar_position: 3 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# LocationEvent + +```ts +type LocationEvent = object; +``` + +The location snapped to the road or the route. + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `course` | `number` | Degrees clockwise from north; -1 if unknown. | +| `latitude` | `number` | - | +| `longitude` | `number` | - | +| `roadName` | `string` | Empty if unknown. | +| `speed` | `number` | Meters per second; -1 if unknown. | +| `speedLimit?` | [`SpeedLimit`](SpeedLimit.md) | Missing where the road has no known speed limit. | diff --git a/docs/navigation/api/Events/RouteChangeEvent.md b/docs/navigation/api/Events/RouteChangeEvent.md new file mode 100644 index 00000000..a7f02999 --- /dev/null +++ b/docs/navigation/api/Events/RouteChangeEvent.md @@ -0,0 +1,22 @@ +--- +sidebar_label: RouteChangeEvent +sidebar_position: 4 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RouteChangeEvent + +```ts +type RouteChangeEvent = object; +``` + +From [Navigation.addRouteChangeListener](../Core/Navigation.md#addroutechangelistener). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `reason` | `"reroute"` \| `"alternative"` | `reroute` after going off route, `alternative` when guidance switched to an alternative route. | +| `route` | [`Route`](../Routes/Route.md) | The route guidance follows now. Release it when you're done with it. | diff --git a/docs/navigation/api/Events/RouteProgressEvent.md b/docs/navigation/api/Events/RouteProgressEvent.md new file mode 100644 index 00000000..8276c4fa --- /dev/null +++ b/docs/navigation/api/Events/RouteProgressEvent.md @@ -0,0 +1,33 @@ +--- +sidebar_label: RouteProgressEvent +sidebar_position: 5 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RouteProgressEvent + +```ts +type RouteProgressEvent = object; +``` + +From [Navigation.addRouteProgressListener](../Core/Navigation.md#addrouteprogresslistener) and `onRouteProgress`. + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `distanceRemaining` | `number` | Meters. | +| `distanceTraveled` | `number` | Meters. | +| `durationRemaining` | `number` | Seconds. | +| `fractionTraveled` | `number` | 0..1 | +| `lanes` | `ReadonlyArray`\<[`Lane`](Lane.md)\> | Lanes at the next maneuver, left to right. Empty if the route has no lane data there. | +| `legIndex` | `CodegenTypes.Int32` | Index of the current leg, in [Route](../Routes/Route.md) `legs`. | +| `maneuverInstruction` | `string` | Primary banner text of the next maneuver, e.g. "Turn right onto Market Street". | +| `maneuverModifier` | `string` | Mapbox Directions maneuver modifier, e.g. "right", "slight left". Empty if unknown. | +| `maneuverType` | `string` | Mapbox Directions maneuver type, e.g. "turn", "arrive". Empty if unknown. | +| `secondaryInstruction` | `string` | Secondary banner text, e.g. the destination of an exit. Empty if none. | +| `stepDistanceRemaining` | `number` | Meters to the next maneuver. | +| `stepIndex` | `CodegenTypes.Int32` | Index of the current step in the current leg. | +| `subInstruction` | `string` | Sub banner text, e.g. "Then turn left". Empty if none or if the sub banner shows lanes. | diff --git a/docs/navigation/api/Events/SpeedLimit.md b/docs/navigation/api/Events/SpeedLimit.md new file mode 100644 index 00000000..423ce88c --- /dev/null +++ b/docs/navigation/api/Events/SpeedLimit.md @@ -0,0 +1,23 @@ +--- +sidebar_label: SpeedLimit +sidebar_position: 6 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# SpeedLimit + +```ts +type SpeedLimit = object; +``` + +Posted speed limit, in [LocationEvent](LocationEvent.md). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `sign` | `string` | "mutcd" (US-style rectangle) or "vienna" (red circle). | +| `speed` | `number` | In `unit`. | +| `unit` | `string` | "km/h" or "mph". | diff --git a/docs/navigation/api/Events/VoiceInstructionEvent.md b/docs/navigation/api/Events/VoiceInstructionEvent.md new file mode 100644 index 00000000..49bc6a8b --- /dev/null +++ b/docs/navigation/api/Events/VoiceInstructionEvent.md @@ -0,0 +1,23 @@ +--- +sidebar_label: VoiceInstructionEvent +sidebar_position: 7 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# VoiceInstructionEvent + +```ts +type VoiceInstructionEvent = object; +``` + +From [Navigation.addVoiceInstructionListener](../Core/Navigation.md#addvoiceinstructionlistener). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `distanceAlongStep` | `number` | Meters from the start of the step at which the instruction is announced. | +| `ssml` | `string` | Empty if the route has no SSML. | +| `text` | `string` | Plain text of the instruction, e.g. "In 500 feet, turn right onto Market Street". | diff --git a/docs/navigation/api/Events/_category_.json b/docs/navigation/api/Events/_category_.json new file mode 100644 index 00000000..dc2a6284 --- /dev/null +++ b/docs/navigation/api/Events/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Events", + "position": 4 +} diff --git a/docs/navigation/api/Routes/LineString.md b/docs/navigation/api/Routes/LineString.md new file mode 100644 index 00000000..425c5ed3 --- /dev/null +++ b/docs/navigation/api/Routes/LineString.md @@ -0,0 +1,22 @@ +--- +sidebar_label: LineString +sidebar_position: 2 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# LineString + +```ts +type LineString = object; +``` + +GeoJSON LineString. + +## Properties + +| Property | Type | +| ------ | ------ | +| `coordinates` | [`Position`](Position.md)[] | +| `type` | `"LineString"` | diff --git a/docs/navigation/api/Routes/Position.md b/docs/navigation/api/Routes/Position.md new file mode 100644 index 00000000..d5e51996 --- /dev/null +++ b/docs/navigation/api/Routes/Position.md @@ -0,0 +1,15 @@ +--- +sidebar_label: Position +sidebar_position: 3 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# Position + +```ts +type Position = [longitude: number, latitude: number]; +``` + +GeoJSON order, same as `@rnmapbox/maps`. diff --git a/docs/navigation/api/Routes/Route.md b/docs/navigation/api/Routes/Route.md new file mode 100644 index 00000000..642e5d7f --- /dev/null +++ b/docs/navigation/api/Routes/Route.md @@ -0,0 +1,41 @@ +--- +sidebar_label: Route +sidebar_position: 1 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# Route + +A route from [Navigation.requestRoutes](../Core/Navigation.md#requestroutes), backed by the native SDK route. +The getters read a copy taken when the route was created, so they're synchronous. +Routes don't survive a JS reload. + +Call `release()` when you're done with it; the garbage collector only releases it eventually. Reading any +property but `isReleased` after `release()` throws an error with `code: 'route_released'`. +Guidance and the route preview keep their own reference, so releasing a route they use doesn't affect them. + +## Methods + +### release() + +```ts +release(): void; +``` + +Frees the native route. Calling it again does nothing. + +#### Returns + +`void` + +## Properties + +| Property | Modifier | Type | Description | +| ------ | ------ | ------ | ------ | +| `distance` | `readonly` | `number` | Meters. | +| `expectedTravelTime` | `readonly` | `number` | Seconds. | +| `geometry` | `readonly` | [`LineString`](LineString.md) | A new object on every read. | +| `isReleased` | `readonly` | `boolean` | Whether `release()` was called. Readable after release. | +| `legs` | `readonly` | [`RouteLeg`](RouteLeg.md)[] | A new array on every read. | diff --git a/docs/navigation/api/Routes/RouteLeg.md b/docs/navigation/api/Routes/RouteLeg.md new file mode 100644 index 00000000..4402033b --- /dev/null +++ b/docs/navigation/api/Routes/RouteLeg.md @@ -0,0 +1,25 @@ +--- +sidebar_label: RouteLeg +sidebar_position: 4 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RouteLeg + +```ts +type RouteLeg = object; +``` + +The part of a route between two consecutive waypoints. + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `distance` | `number` | Meters. | +| `expectedTravelTime` | `number` | Seconds. | +| `stepCount` | `number` | Same as `steps.length`. | +| `steps` | [`RouteStep`](RouteStep.md)[] | - | +| `summary` | `string` | Names of the main roads, e.g. "Market Street, Embarcadero". | diff --git a/docs/navigation/api/Routes/RouteRequestOptions.md b/docs/navigation/api/Routes/RouteRequestOptions.md new file mode 100644 index 00000000..0212962c --- /dev/null +++ b/docs/navigation/api/Routes/RouteRequestOptions.md @@ -0,0 +1,26 @@ +--- +sidebar_label: RouteRequestOptions +sidebar_position: 5 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RouteRequestOptions + +```ts +type RouteRequestOptions = object; +``` + +Options of [Navigation.requestRoutes](../Core/Navigation.md#requestroutes). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `alternatives?` | `boolean` | Also return alternative routes. Defaults to `false`. | +| `exclude?` | `string`[] | Road classes to avoid, e.g. `['toll', 'ferry']`. | +| `language?` | `string` | Language of instructions, e.g. `en` or `de-DE`. | +| `profile?` | `"driving-traffic"` \| `"driving"` \| `"walking"` \| `"cycling"` | Mapbox Directions profile. Defaults to `driving-traffic`. | +| `units?` | `"metric"` \| `"imperial"` | Unit of the distances in voice instructions. | +| `waypoints` | [`Waypoint`](Waypoint.md)[] | Origin first, destination last. | diff --git a/docs/navigation/api/Routes/RouteResponse.md b/docs/navigation/api/Routes/RouteResponse.md new file mode 100644 index 00000000..611bcd26 --- /dev/null +++ b/docs/navigation/api/Routes/RouteResponse.md @@ -0,0 +1,22 @@ +--- +sidebar_label: RouteResponse +sidebar_position: 6 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RouteResponse + +```ts +type RouteResponse = object; +``` + +Result of [Navigation.requestRoutes](../Core/Navigation.md#requestroutes). `alternatives` is empty unless requested. + +## Properties + +| Property | Type | +| ------ | ------ | +| `alternatives` | [`Route`](Route.md)[] | +| `main` | [`Route`](Route.md) | diff --git a/docs/navigation/api/Routes/RouteStats.md b/docs/navigation/api/Routes/RouteStats.md new file mode 100644 index 00000000..e9e1746b --- /dev/null +++ b/docs/navigation/api/Routes/RouteStats.md @@ -0,0 +1,23 @@ +--- +sidebar_label: RouteStats +sidebar_position: 7 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RouteStats + +```ts +type RouteStats = object; +``` + +From [Navigation.getRouteStats](../Core/Navigation.md#getroutestats). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `collected` | `number` | Routes the garbage collector released. | +| `live` | `number` | Routes JS holds that weren't released yet. | +| `released` | `number` | Routes released with `release()`. | diff --git a/docs/navigation/api/Routes/RouteStep.md b/docs/navigation/api/Routes/RouteStep.md new file mode 100644 index 00000000..56f386ac --- /dev/null +++ b/docs/navigation/api/Routes/RouteStep.md @@ -0,0 +1,26 @@ +--- +sidebar_label: RouteStep +sidebar_position: 8 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# RouteStep + +```ts +type RouteStep = object; +``` + +A maneuver and the road up to the next one, in `steps` of [RouteLeg](RouteLeg.md). + +## Properties + +| Property | Type | Description | +| ------ | ------ | ------ | +| `distance` | `number` | Meters. | +| `expectedTravelTime` | `number` | Seconds. | +| `instruction` | `string` | E.g. "Turn right onto Market Street". | +| `maneuverModifier` | `string` | Mapbox Directions maneuver modifier, e.g. "right". Empty if none. | +| `maneuverType` | `string` | Mapbox Directions maneuver type, e.g. "turn", "arrive". | +| `name` | `string` | Name of the road the step is on. Empty if unnamed. | diff --git a/docs/navigation/api/Routes/Waypoint.md b/docs/navigation/api/Routes/Waypoint.md new file mode 100644 index 00000000..259a137d --- /dev/null +++ b/docs/navigation/api/Routes/Waypoint.md @@ -0,0 +1,20 @@ +--- +sidebar_label: Waypoint +sidebar_position: 9 +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# Waypoint + +```ts +type Waypoint = + | Position + | { + coordinate: Position; + name?: string; +}; +``` + +A coordinate, or a coordinate with the name the navigation UI shows for it, e.g. on arrival. diff --git a/docs/navigation/api/Routes/_category_.json b/docs/navigation/api/Routes/_category_.json new file mode 100644 index 00000000..b1132168 --- /dev/null +++ b/docs/navigation/api/Routes/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Routes", + "position": 3 +} diff --git a/docs/navigation/api/_category_.json b/docs/navigation/api/_category_.json new file mode 100644 index 00000000..c29a165b --- /dev/null +++ b/docs/navigation/api/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "API reference", + "collapsed": false, + "link": { + "type": "doc", + "id": "navigation/api/index" + } +} diff --git a/docs/navigation/api/index.md b/docs/navigation/api/index.md new file mode 100644 index 00000000..abb45d30 --- /dev/null +++ b/docs/navigation/api/index.md @@ -0,0 +1,57 @@ +--- +slug: /navigation/api +sidebar_label: Overview +custom_edit_url: null +--- + +{/* Generated from rnmapbox/navigation/src by `yarn docs`. Don't edit. */} + +# API reference + +## Core + +| Name | Description | +| ------ | ------ | +| [Navigation](Core/Navigation.md) | The headless navigation API: route requests, the app's single guidance session, and its events. It's also the default export. | +| [NAVIGATION\_MAP\_VIEW\_IMPL](Core/NAVIGATION_MAP_VIEW_IMPL.md) | Pass as `mapViewImpl` to an `@rnmapbox/maps` `MapView` to render the route line, the puck and the navigation camera on it: ``. | +| [CameraState](Core/CameraState.md) | Camera of navigation maps. `following` follows the puck, tilted and rotated with the route; `overview` fits the rest of the route; `idle` leaves the map to the user's gestures and `@rnmapbox/maps` `Camera`. | +| [StartActiveGuidanceOptions](Core/StartActiveGuidanceOptions.md) | Options of [Navigation.startActiveGuidance](Core/Navigation.md#startactiveguidance). | + +## Components + +| Name | Description | +| ------ | ------ | +| [NavigationView](Components/NavigationView.md) | Full-screen turn-by-turn navigation UI: `NavigationViewController` from `MapboxNavigationUIKit` on iOS, and an equivalent built from the Navigation SDK UI components on Android. | +| [NavigationViewport](Components/NavigationViewport.md) | Configures the navigation camera of the `@rnmapbox/maps` `MapView` it's a child of: ``. Without it the SDK defaults apply: the safe area plus a small margin on iOS, no padding on Android. | +| [RNNavigationView](Components/RNNavigationView.md) | `` built in React Native from the headless API, on an `@rnmapbox/maps` navigation map: a maneuver banner with lanes, speed limit, road name, trip progress, mute, overview/recenter and end buttons, and an arrival message. | +| [NavigationViewError](Components/NavigationViewError.md) | Passed to `onError` of [NavigationView](Components/NavigationView.md) and [RNNavigationView](Components/RNNavigationView.md). | +| [NavigationViewportProps](Components/NavigationViewportProps.md) | Props of [NavigationViewport](Components/NavigationViewport.md). | +| [NavigationViewProps](Components/NavigationViewProps.md) | Props of [NavigationView](Components/NavigationView.md). Pass either `route` or `waypoints`. | +| [RNNavigationViewProps](Components/RNNavigationViewProps.md) | Props of [RNNavigationView](Components/RNNavigationView.md): [NavigationViewProps](Components/NavigationViewProps.md), plus the props below. | +| [ViewportPadding](Components/ViewportPadding.md) | Points from the map's edges, ignoring the safe area. | + +## Routes + +| Name | Description | +| ------ | ------ | +| [Route](Routes/Route.md) | A route from [Navigation.requestRoutes](Core/Navigation.md#requestroutes), backed by the native SDK route. The getters read a copy taken when the route was created, so they're synchronous. Routes don't survive a JS reload. | +| [LineString](Routes/LineString.md) | GeoJSON LineString. | +| [Position](Routes/Position.md) | GeoJSON order, same as `@rnmapbox/maps`. | +| [RouteLeg](Routes/RouteLeg.md) | The part of a route between two consecutive waypoints. | +| [RouteRequestOptions](Routes/RouteRequestOptions.md) | Options of [Navigation.requestRoutes](Core/Navigation.md#requestroutes). | +| [RouteResponse](Routes/RouteResponse.md) | Result of [Navigation.requestRoutes](Core/Navigation.md#requestroutes). `alternatives` is empty unless requested. | +| [RouteStats](Routes/RouteStats.md) | From [Navigation.getRouteStats](Core/Navigation.md#getroutestats). | +| [RouteStep](Routes/RouteStep.md) | A maneuver and the road up to the next one, in `steps` of [RouteLeg](Routes/RouteLeg.md). | +| [Waypoint](Routes/Waypoint.md) | A coordinate, or a coordinate with the name the navigation UI shows for it, e.g. on arrival. | + +## Events + +| Type Alias | Description | +| ------ | ------ | +| [ArriveEvent](Events/ArriveEvent.md) | From [Navigation.addArriveListener](Core/Navigation.md#addarrivelistener) and `onArrive`. | +| [Lane](Events/Lane.md) | A lane at the next maneuver, in `lanes` of [RouteProgressEvent](Events/RouteProgressEvent.md). | +| [LocationEvent](Events/LocationEvent.md) | The location snapped to the road or the route. | +| [RouteChangeEvent](Events/RouteChangeEvent.md) | From [Navigation.addRouteChangeListener](Core/Navigation.md#addroutechangelistener). | +| [RouteProgressEvent](Events/RouteProgressEvent.md) | From [Navigation.addRouteProgressListener](Core/Navigation.md#addrouteprogresslistener) and `onRouteProgress`. | +| [SpeedLimit](Events/SpeedLimit.md) | Posted speed limit, in [LocationEvent](Events/LocationEvent.md). | +| [VoiceInstructionEvent](Events/VoiceInstructionEvent.md) | From [Navigation.addVoiceInstructionListener](Core/Navigation.md#addvoiceinstructionlistener). | diff --git a/docs/navigation/getting-started.md b/docs/navigation/getting-started.md index 15a26388..9d40c3b3 100644 --- a/docs/navigation/getting-started.md +++ b/docs/navigation/getting-started.md @@ -76,7 +76,40 @@ export function NavigationScreen() { `Navigation.previewRoute(route)` shows a route on navigation maps before guidance starts, and `Navigation.setCameraState('overview')` fits the rest of the route. -The headless API has no arrival event in the current release; one is in progress in [rnmapbox/navigation#9](https://github.com/rnmapbox/navigation/pull/9). [``](navigation-view.md) reports arrivals with `onArrive`. +## Guidance events + +Subscribe to the events you need while guidance runs. Each listener returns a subscription; `remove()` it on unmount. + +```tsx +const [offRoute, setOffRoute] = useState(false); + +useEffect(() => { + const subscriptions = [ + Navigation.addArriveListener(({ waypointIndex, isFinalDestination }) => { + if (isFinalDestination) { + Navigation.stopNavigation(); + } + }), + Navigation.addOffRouteListener(setOffRoute), + Navigation.addRouteChangeListener(({ route, reason }) => { + // `reason` is 'reroute' or 'alternative'. Release `route` when you're done with it. + }), + ]; + return () => subscriptions.forEach((subscription) => subscription.remove()); +}, []); +``` + +| Listener | Event | +| ----------------------------- | --------------------------------------------------------------------------------------------- | +| `addRouteProgressListener` | Distances and durations remaining, and the next maneuver's banner and lanes. | +| `addLocationListener` | Location snapped to the road or route, with `speed`, `course`, `roadName` and `speedLimit`. | +| `addArriveListener` | `{ waypointIndex, isFinalDestination }` when a waypoint is reached; the origin is index 0. | +| `addOffRouteListener` | `true` when the user leaves the route, `false` once guidance follows a route again. | +| `addRouteChangeListener` | `{ route, reason }` when guidance switches to a new `Route` after a reroute. | +| `addVoiceInstructionListener` | `{ text, ssml, distanceAlongStep }`, for apps doing their own text to speech. | +| `addCameraStateListener` | Camera state changes, see [Camera](#camera). | + +The SDK speaks voice instructions during any guidance; `Navigation.setVoiceMuted(true)` mutes them. See the [API reference](api/index.md) for the event types. ## Routes diff --git a/docs/navigation/install.md b/docs/navigation/install.md index a543c96e..a66c1c70 100644 --- a/docs/navigation/install.md +++ b/docs/navigation/install.md @@ -8,6 +8,8 @@ import TabItem from '@theme/TabItem'; Set up `@rnmapbox/maps` first, following its [install guide](../install.md). `@rnmapbox/navigation` needs `@rnmapbox/maps` 10.3.11 or newer. +`@rnmapbox/navigation` is published under the `next` tag while it's in alpha. + # Install ```bash -npm install @rnmapbox/navigation @rnmapbox/maps +npm install @rnmapbox/navigation@next @rnmapbox/maps ``` ```bash -yarn add @rnmapbox/navigation @rnmapbox/maps +yarn add @rnmapbox/navigation@next @rnmapbox/maps ``` @@ -62,6 +64,8 @@ end `pod install` adds `MapboxCommon`, `MapboxCoreMaps`, `MapboxNavigationNative` and `Turf` to the frameworks CocoaPods embeds. +With React Native 0.87+ and Xcode 26, also add the Navigation SDK's binary frameworks to `rnmapbox-maps`' framework search paths, see [Troubleshooting](troubleshooting.md#xcode-26-unable-to-resolve-module-dependency-turf). + ### Info.plist Add `NSLocationWhenInUseUsageDescription`. For ``, also add `audio` to `UIBackgroundModes`: the SDK's voice controller asserts on it in debug builds. @@ -112,9 +116,62 @@ With `targetSdkVersion` 35 or higher both libraries use the `-ndk27` artifacts ( -There's no Expo config plugin in the current release. Use a [development build](https://docs.expo.dev/develop/development-builds/introduction/), as Expo Go doesn't include the native SDKs, and apply the iOS and Android setup yourself. +Use a [development build](https://docs.expo.dev/develop/development-builds/introduction/); Expo Go doesn't include the native SDKs. Add both config plugins to `app.json`: + +```json +{ + "expo": { + "plugins": [ + ["@rnmapbox/maps", { "RNMapboxMapsVersion": "11.23.1" }], + "@rnmapbox/navigation" + ] + } +} +``` + +The `@rnmapbox/navigation` plugin only changes iOS: + +- sets `$RNMapboxMapsSwiftPackageManager = { link: false }` in the Podfile, see the iOS tab; +- adds the Navigation SDK's binary frameworks to `rnmapbox-maps`' framework search paths, which Xcode 26 needs with React Native 0.87+; +- sets `NSLocationWhenInUseUsageDescription`, unless `locationWhenInUsePermission` is `false`. + +On Android the `@rnmapbox/maps` plugin already adds the Mapbox Maven repository, and the Navigation SDK's manifest adds the location, foreground service and notification permissions. + +### Options + +```json +["@rnmapbox/navigation", { + "RNMapboxNavigationVersion": "3.23.1", + "locationWhenInUsePermission": "Shows your location during navigation." +}] +``` + +| Option | Description | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `RNMapboxNavigationVersion` | Navigation SDK version on both platforms. Set the maps plugin's `RNMapboxMapsVersion` to the matching 11.N. | +| `locationWhenInUsePermission` | iOS `NSLocationWhenInUseUsageDescription`, or `false` to leave it unset. | + +For `` on iOS, also add the `audio` background mode, which the plugin doesn't set: + +```json +{ + "expo": { + "ios": { + "infoPlist": { "UIBackgroundModes": ["audio"] } + } + } +} +``` + +### Build + +```bash +npx expo prebuild --clean +npx expo run:ios +npx expo run:android +``` -A config plugin is in progress in [rnmapbox/navigation#7](https://github.com/rnmapbox/navigation/pull/7). +Rerun `prebuild` after changing plugin options. diff --git a/docs/navigation/navigation-view.md b/docs/navigation/navigation-view.md index 0ae92c87..5fa1cf06 100644 --- a/docs/navigation/navigation-view.md +++ b/docs/navigation/navigation-view.md @@ -4,10 +4,6 @@ sidebar_position: 4 title: NavigationView --- -:::info Not released yet -`` is on the `main` branch of [rnmapbox/navigation](https://github.com/rnmapbox/navigation) and isn't part of `0.1.0-alpha.0`. It ships with the next release. -::: - `` is a full-screen turn-by-turn navigation UI: `NavigationViewController` from `MapboxNavigationUIKit` on iOS, and an equivalent built from the Navigation SDK UI components on Android (maneuver banner with lanes and shields, speed limit, trip progress, mute, overview, recenter and end buttons). On iOS, add `audio` to `UIBackgroundModes` in `Info.plist`, see [Install](install.md). @@ -32,6 +28,8 @@ import { NavigationView } from '@rnmapbox/navigation'; ## Props +See [`NavigationViewProps`](api/Components/NavigationViewProps.md) in the API reference. + | Prop | Type | Description | | ----------------- | -------------------------------------------- | ----------------------------------------------------------------------------------- | | `route` | `Route` | A route from `requestRoutes`. Keep it unreleased while it's passed to the view. | @@ -54,4 +52,4 @@ import { NavigationView } from '@rnmapbox/navigation'; - `addRouteProgressListener` and `addCameraStateListener` also report its guidance. - Show one `NavigationView` at a time. On iOS it's embedded as a child of the nearest view controller. -Android `` has no end-of-route, feedback or alternative-route UI, no day/night styles, no road name label, and doesn't show reroutes as such. +Android `` has no end-of-route, feedback or alternative-route UI, no day/night styles, no road name label, and doesn't show reroutes as such. For the same UI on both platforms, see [``](rn-navigation-view.md). diff --git a/docs/navigation/overview.md b/docs/navigation/overview.md index 38ac026f..362dcd71 100644 --- a/docs/navigation/overview.md +++ b/docs/navigation/overview.md @@ -9,13 +9,13 @@ title: Overview It requests routes, runs an active-guidance session and reports route progress. The Navigation SDK draws the route line, the puck and the navigation camera on a regular `@rnmapbox/maps` `MapView`, so your existing layers, sources and annotations keep working on the same map. :::caution Alpha -`@rnmapbox/navigation` is in early alpha. The current release is `0.1.0-alpha.0`, and APIs may change between releases. +`@rnmapbox/navigation` is in early alpha. The current release is `0.1.0-alpha.1`, published to npm under the `next` tag, and APIs may change between releases. ::: ## Requirements - React Native 0.79+ with the New Architecture. -- `@rnmapbox/maps` 10.3.11 or newer (peer dependency). +- `@rnmapbox/maps` 10.3.11 or newer (peer dependency). Navigation maps plug into its map view factory hooks, which have their current form since 10.3.11. - iOS: React Native's minimum deployment target. The Navigation SDK for iOS 3.23.1 is added as a Swift package. - Android: `minSdkVersion` 24, `compileSdkVersion` 36. - A Mapbox account and a public access token (`pk.…`). No secret downloads token is needed. @@ -35,24 +35,36 @@ The Navigation SDK pins the Maps SDK it's built against, and `@rnmapbox/maps` mu - Route requests, with `Route` objects backed by the native SDK route. - Route preview and active guidance, simulated or on the device's location. - Navigation maps: an `@rnmapbox/maps` `MapView` with the SDK's route line, puck and navigation camera. -- Route progress and camera state events. -- [``](navigation-view.md), the SDK's full-screen turn-by-turn UI. Not released yet, see its page. +- Events for route progress, camera state, location, arrival, off-route, reroutes and voice instructions. +- [``](navigation-view.md), the SDK's full-screen turn-by-turn UI. +- [``](rn-navigation-view.md), a turn-by-turn UI written in React Native on top of the headless API. +- An Expo config plugin, see [Install](install.md). -## Coming next +## Choose an approach -These are in open pull requests and not released yet: +There are three ways to build a navigation screen. They all share the app's single navigation session. -- ``, a navigation UI written in React Native on top of the headless API, plus location, arrival, off-route, reroute and voice instruction events ([rnmapbox/navigation#9](https://github.com/rnmapbox/navigation/pull/9)). -- An Expo config plugin ([rnmapbox/navigation#7](https://github.com/rnmapbox/navigation/pull/7)). +| | Headless API + your own `MapView` | `` | `` | +| --- | --- | --- | --- | +| What you get | A navigation map with the route line, puck and camera. All UI is yours. | A complete UI in React Native: maneuver banner, lanes, speed limit, trip progress, buttons. | The Navigation SDK's own UI: `NavigationViewController` on iOS, the SDK UI components on Android. | +| Customizability | Full. Any `@rnmapbox/maps` layers, sources and annotations, any React Native UI. | High. Change the map style, add map children, or copy its source as a starting point. | Low. Props for the route, simulation and mute; the look is the SDK's. | +| Platform parity | Same on both platforms, since the UI is yours. | Same on both platforms. | Differs: Android has no end-of-route or feedback UI, no day/night styles and no road name label. | +| Effort | Most: you build banners, buttons and arrival handling from the [events](api/index.md). | Little: drop it in, pass `waypoints` or a `route`. | Least, for the full SDK experience. | + +Start with `` if you want a ready UI that matches the rest of your React Native app, `` if you want the SDK's UI as is, and the headless API when navigation is one part of a custom map screen. ## Known limitations -- No explicit offline routing API. Requests use the SDK's default hybrid router. -- Navigation maps have no voice guidance, rerouting UI, alternatives or multi-leg UI. +- No explicit offline routing API. Requests use the SDK's default hybrid router, which only falls back to onboard routing with routing tiles already on the device. +- Navigation maps show no alternative routes during guidance. +- Android `` has no end-of-route, feedback or alternative-route UI, no day/night styles, no road name label, and doesn't show reroutes as such. +- The Expo config plugin is only tested with Expo SDK 58. - `@rnmapbox/maps` `LocationPuck` and `UserLocation` don't work on navigation maps: the navigation puck replaces the map's location provider. - One navigation session for all navigation maps. Per-map routes or cameras aren't supported. +- Route progress events already on their way to JS still arrive after `stopNavigation`. +- Not tested yet: live (non-simulated) guidance on a device, release builds, several navigation maps at once, and unmounting a map during guidance. -See the [README](https://github.com/rnmapbox/navigation#known-limitations) for the full list. +See also [Troubleshooting](troubleshooting.md). ## License diff --git a/docs/navigation/rn-navigation-view.md b/docs/navigation/rn-navigation-view.md new file mode 100644 index 00000000..d39c64f1 --- /dev/null +++ b/docs/navigation/rn-navigation-view.md @@ -0,0 +1,66 @@ +--- +id: rn-navigation-view +sidebar_position: 5 +title: RNNavigationView +--- + +`` is a turn-by-turn navigation UI written in React Native on top of the [headless API](getting-started.md), on an `@rnmapbox/maps` navigation map. It looks the same on iOS and Android. Use it as is, or copy [its source](https://github.com/rnmapbox/navigation/blob/main/src/RNNavigationView.tsx) as a starting point for your own UI. + +RNNavigationView during simulated guidance on iOS + +In `0.1.0-alpha.1` it shows: + +- a maneuver banner with the next instruction, the distance to it, and the lanes; +- the speed limit sign (US or Vienna style) and the current road name; +- arrival time, remaining time and distance; +- mute, overview/recenter and end buttons; +- an arrival message at the final destination. + +```tsx +import { RNNavigationView } from '@rnmapbox/navigation'; + + {}} + onCancel={() => close()} + onError={({ code, message }) => {}} +/> +``` + +## Props + +It takes the same props as [``](navigation-view.md#props) (`route` or `waypoints`, `simulate`, `mute`, `onRouteProgress`, `onArrive`, `onCancel`, `onError`, `style`, `testID`), plus: + +| Prop | Type | Description | +| ---------- | ----------- | ------------------------------------------------------------------------ | +| `styleURL` | `string` | Map style. Defaults to Mapbox Standard. | +| `children` | `ReactNode` | Rendered inside its `MapView`, e.g. extra sources and layers. | + +See [`RNNavigationViewProps`](api/Components/RNNavigationViewProps.md) in the API reference. + +## Session + +Like ``, it uses the app's single navigation session: mounting it, or giving it a new route, starts guidance along that route and replaces any other active guidance; unmounting it or tapping the end button stops guidance. Show one at a time. + +It reads the headless events (route progress, location, camera state, off-route, arrival), so your own `Navigation.add…Listener` subscriptions keep working alongside it. + +## Next release + +:::info Not released yet +These are on the `main` branch of [rnmapbox/navigation](https://github.com/rnmapbox/navigation) ([#10](https://github.com/rnmapbox/navigation/pull/10)) and not part of `0.1.0-alpha.1`. +::: + +RNNavigationView arrival card in night appearance + +- Road shields and exit numbers in the maneuver banner, from new `maneuverComponents` and `secondaryComponents` in route progress events. +- `distanceUnit` prop, `'metric'` or `'imperial'`, for the distances the view shows and the voice instructions of a route it requests through `waypoints`. It defaults to the new `Navigation.getDefaultDistanceUnit()`, from the device's region and measurement settings. +- Alternative routes: with `waypoints` the view requests them, navigation maps draw them, and tapping one switches guidance to it, reported by `addRouteChangeListener` with `reason: 'alternative'`. +- `appearance` prop, `'auto'` (default), `'day'` or `'night'`. `'auto'` switches at sunrise and sunset at the user's location; the UI and the Standard style's light preset follow it. +- An arrival card with the destination name and an end button. + +Road shields come from the Directions API's shield images, not the Mapbox designed shields the native banners use. diff --git a/docs/navigation/troubleshooting.md b/docs/navigation/troubleshooting.md new file mode 100644 index 00000000..13fce241 --- /dev/null +++ b/docs/navigation/troubleshooting.md @@ -0,0 +1,80 @@ +--- +id: troubleshooting +sidebar_position: 6 +title: Troubleshooting +--- + +## iOS: duplicate MapboxMaps symbols + +The app fails to link with `duplicate symbol` errors for MapboxMaps symbols, or logs `Class … is implemented in both …` for MapboxMaps classes at launch. + +The Navigation SDK is a Swift package that links MapboxMaps into the app. If `@rnmapbox/maps` links its own MapboxMaps too, the app has two copies. Make `@rnmapbox/maps` compile against the Navigation SDK's copy only, before `target` in `ios/Podfile`: + +```ruby +$RNMapboxMapsSwiftPackageManager = { link: false } +``` + +Then run `pod install`. Keep `$RNMapboxMaps.pre_install(installer)` and `$RNMapboxMaps.post_install(installer)` in the Podfile hooks, see [Install](install.md). The Expo config plugin sets this for you. + +## Xcode 26: unable to resolve module dependency 'Turf' + +``` +RNMBXCamera.swift:3:8: error: compilation search paths unable to resolve module dependency: 'Turf' +error: compilation search paths unable to resolve module dependency: 'MapboxCommon' +error: compilation search paths unable to resolve module dependency: 'MapboxCoreMaps' +``` + +React Native 0.87+ no longer turns off Xcode 26's explicit Swift modules. With `link: false`, `rnmapbox-maps` then only finds the binary frameworks of the Navigation SDK package on a framework search path. Add it in the Podfile's `post_install`: + +```ruby +post_install do |installer| + installer.pods_project.targets.select { |t| t.name == 'rnmapbox-maps' }.each do |target| + target.build_configurations.each do |config| + paths = Array(config.build_settings['FRAMEWORK_SEARCH_PATHS'] || '$(inherited)') + config.build_settings['FRAMEWORK_SEARCH_PATHS'] = paths | ['${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/'] + end + end + # ... +end +``` + +The `@rnmapbox/navigation` Expo config plugin already adds this. [rnmapbox/maps#4376](https://github.com/rnmapbox/maps/pull/4376) fixes it in `@rnmapbox/maps` itself; once you're on a release with it, the snippet is redundant but harmless. + +## iOS: Swift package resolution error for MapboxMaps + +Navigation SDK 3.N pins Maps SDK 11.N exactly, and `@rnmapbox/maps`' package requirement (`$RNMapboxMapsVersion`, default `~> 11.23.1`) must allow it. With a different Navigation SDK version, set `$RNMapboxMapsVersion = '= 11.N.x'` to match. + +## Android: Maps version resolution conflict + +Gradle fails with an error like: + +``` +Cannot find a version of 'com.mapbox.maps:android' that satisfies the version constraints +``` + +`@rnmapbox/navigation` adds a strict constraint on the Maps SDK version its Navigation SDK is built against (Nav 3.N → Maps 11.N), so a different version fails dependency resolution instead of silently mixing versions. Set `@rnmapbox/maps`' version to match, in `android/build.gradle`: + +```groovy +buildscript { + ext { + RNMapboxMapsVersion = '11.23.1' // matches Navigation SDK 3.23.1 + } +} +``` + +With Expo, set `RNMapboxMapsVersion` in the `@rnmapbox/maps` plugin options. To override the derived Maps version, set `RNMapboxNavigationMapsVersion`. + +Both libraries pick the `-ndk27` artifacts with `targetSdkVersion` 35 or higher. Keep `targetSdkVersion` in the root project `ext`, where both read it, otherwise one of them can pick the other variant. + +## iOS: assertion about UIBackgroundModes audio + +`` crashes in a debug build with an assertion from the Navigation SDK's voice controller about the `audio` background mode. Add it to `Info.plist`: + +```xml +UIBackgroundModes + + audio + +``` + +With Expo, add `"UIBackgroundModes": ["audio"]` to `ios.infoPlist` in `app.json` and run `npx expo prebuild` again. diff --git a/static/img/navigation/rn-navigation-view-alpha1.png b/static/img/navigation/rn-navigation-view-alpha1.png new file mode 100644 index 00000000..6d4f9d9f Binary files /dev/null and b/static/img/navigation/rn-navigation-view-alpha1.png differ diff --git a/static/img/navigation/rn-navigation-view-arrival.png b/static/img/navigation/rn-navigation-view-arrival.png new file mode 100644 index 00000000..bb7552e8 Binary files /dev/null and b/static/img/navigation/rn-navigation-view-arrival.png differ