18 |
19 | @interface AppDelegateCarPlay : RCTAppDelegate
20 | @end
21 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/INavigationCallback.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | public interface INavigationCallback {
17 | void logDebugInfo(String info);
18 | }
19 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/CarSceneDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #import
17 | #import
18 |
19 | @interface CarSceneDelegate : BaseCarSceneDelegate
20 | @end
21 |
--------------------------------------------------------------------------------
/example/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { AppRegistry } from 'react-native';
18 | import App from './src/App';
19 | import { name as appName } from './app.json';
20 |
21 | AppRegistry.registerComponent(appName, () => App);
22 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "pipeline": {
4 | "build:android": {
5 | "inputs": [
6 | "package.json",
7 | "android",
8 | "!android/build",
9 | "src/*.ts",
10 | "src/*.tsx",
11 | "example/package.json",
12 | "example/android",
13 | "!example/android/.gradle",
14 | "!example/android/build",
15 | "!example/android/app/build"
16 | ],
17 | "outputs": []
18 | },
19 | "build:ios": {
20 | "inputs": [
21 | "package.json",
22 | "*.podspec",
23 | "ios",
24 | "src/*.ts",
25 | "src/*.tsx",
26 | "example/package.json",
27 | "example/ios",
28 | "!example/ios/build",
29 | "!example/ios/Pods"
30 | ],
31 | "outputs": []
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/CustomTypes.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | public class CustomTypes {
17 | public enum MapViewType {
18 | MAP,
19 | NAVIGATION
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/CustomTypes.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #ifndef CustomTypes_h
17 | #define CustomTypes_h
18 |
19 | typedef NS_ENUM(NSInteger, MapViewType) {
20 | MAP,
21 | NAVIGATION,
22 | };
23 |
24 | #endif /* CustomTypes_h */
25 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
20 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | *Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.*
2 |
3 | *List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*
4 |
5 | ## Pre-launch Checklist
6 |
7 | - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
8 | - [ ] I signed the [CLA].
9 | - [ ] I listed at least one issue that this PR fixes in the description above.
10 | - [ ] I updated/added relevant documentation
11 | - [ ] I added new tests to check the change I am making
12 | - [ ] All existing and new tests are passing.
13 |
14 |
15 | [Contributor Guide]: https://github.com/googlemaps/react-native-navigation-sdk/blob/main/CONTRIBUTING.md
16 | [CLA]: https://cla.developers.google.com/
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/Constants.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | *
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | public class Constants {
17 | public static final String LAT_FIELD_KEY = "lat";
18 | public static final String LNG_FIELD_KEY = "lng";
19 | }
20 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/PhoneSceneDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #import
17 | #import
18 |
19 | @interface PhoneSceneDelegate : UIResponder
20 |
21 | @property(nonatomic, strong) UIWindow *window;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/src/navigation/navigationView/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export * from './navigationViewController';
18 | export * from '../shared';
19 | export * from './stylingOptions';
20 | export * from './types';
21 | export { default as NavigationView } from './navigationView';
22 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/UIColor+Util.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | NS_ASSUME_NONNULL_BEGIN
20 |
21 | @interface UIColor (HexString)
22 |
23 | + (UIColor *)colorWithHexString:(NSString *)hexString;
24 |
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/INavigationAutoCallback.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import com.facebook.react.bridge.ReadableMap;
17 |
18 | public interface INavigationAutoCallback {
19 | void onCustomNavigationAutoEvent(String type, ReadableMap data);
20 | }
21 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/INavigationViewController.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | *
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import com.google.android.libraries.navigation.StylingOptions;
17 |
18 | public interface INavigationViewController {
19 | void setStylingOptions(StylingOptions stylingOptions);
20 | }
21 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | module.exports = {
18 | overrides: [
19 | {
20 | exclude: /\/node_modules\//,
21 | presets: ['module:react-native-builder-bob/babel-preset'],
22 | },
23 | {
24 | include: /\/node_modules\//,
25 | presets: ['module:@react-native/babel-preset'],
26 | },
27 | ],
28 | };
29 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": ".",
4 | "paths": {
5 | "@googlemaps/react-native-navigation-sdk": ["./src/index"]
6 | },
7 | "allowUnreachableCode": false,
8 | "allowUnusedLabels": false,
9 | "customConditions": ["react-native-strict-api"],
10 | "esModuleInterop": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "jsx": "react",
13 | "lib": ["ESNext"],
14 | "module": "ESNext",
15 | "moduleResolution": "bundler",
16 | "noEmit": true,
17 | "noFallthroughCasesInSwitch": true,
18 | "noImplicitReturns": true,
19 | "noImplicitUseStrict": false,
20 | "noStrictGenericChecks": false,
21 | "noUncheckedIndexedAccess": true,
22 | "noUnusedLocals": true,
23 | "noUnusedParameters": true,
24 | "resolveJsonModule": true,
25 | "skipLibCheck": true,
26 | "strict": true,
27 | "target": "ESNext",
28 | "verbatimModuleSyntax": true
29 | },
30 | "exclude": ["lib"]
31 | }
32 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2024 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | nmHoistingLimits: workspaces
16 |
17 | nodeLinker: node-modules
18 |
19 | plugins:
20 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
21 | spec: '@yarnpkg/plugin-interactive-tools'
22 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
23 | spec: '@yarnpkg/plugin-workspace-tools'
24 |
25 | yarnPath: .yarn/releases/yarn-3.6.4.cjs
26 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | 10.0.2.2
21 | localhost
22 |
23 |
--------------------------------------------------------------------------------
/example/babel.config.js:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | const path = require('path');
16 | const { getConfig } = require('react-native-builder-bob/babel-config');
17 | const pkg = require('../package.json');
18 |
19 | const root = path.resolve(__dirname, '..');
20 |
21 | module.exports = getConfig(
22 | {
23 | presets: ['module:@react-native/babel-preset'],
24 | },
25 | { root, pkg }
26 | );
27 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/RCTNavViewManager.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import
18 | #import
19 | #import "INavigationViewCallback.h"
20 | #import "RCTEventDispatcher.h"
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | @interface RCTNavViewManager : RCTViewManager
25 |
26 | - (instancetype)init;
27 |
28 | @end
29 |
30 | NS_ASSUME_NONNULL_END
31 |
--------------------------------------------------------------------------------
/scripts/format-java.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Copyright 2024 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | # Script to format or check formatting for Java files in /android and /example/android
17 |
18 | if [ "$1" = "--check" ]; then
19 | find android/src example/android/app/src -name "*.java" | xargs google-java-format --dry-run --set-exit-if-changed
20 | else
21 | find android/src example/android/app/src -name "*.java" | xargs google-java-format -i
22 | fi
23 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
16 | plugins { id("com.facebook.react.settings") }
17 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
18 | rootProject.name = 'SampleApp'
19 | include ':app'
20 | includeBuild('../node_modules/@react-native/gradle-plugin')
21 |
--------------------------------------------------------------------------------
/scripts/format-objc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Copyright 2024 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | # Script to format or check formatting for Objective-C files in /ios and /example/ios
17 |
18 | if [ "$1" = "--check" ]; then
19 | find ios example/ios/SampleApp -name "*.m" -o -name "*.h" | xargs clang-format -style=Google --dry-run -Werror
20 | else
21 | find ios example/ios/SampleApp -name "*.m" -o -name "*.h" | xargs clang-format -style=Google -i
22 | fi
23 |
--------------------------------------------------------------------------------
/example/src/screens/integration_tests/utils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // Delay function execution by given time in ms.
18 | export const delay = (timeInMs: number): Promise => {
19 | return new Promise(resolve => setTimeout(resolve, timeInMs));
20 | };
21 |
22 | // Remove decimals from any floating point number.
23 | export const roundDown = (value: number) => {
24 | const factor = Math.pow(10, 0);
25 | return Math.floor(value * factor) / factor;
26 | };
27 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/main.m:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 |
17 | #if defined(CARPLAY)
18 | #import "AppDelegateCarPlay.h"
19 | #else
20 | #import "AppDelegate.h"
21 | #endif
22 |
23 | int main(int argc, char *argv[]) {
24 | @autoreleasepool {
25 | #if defined(CARPLAY)
26 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegateCarPlay class]));
27 | #else
28 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
29 | #endif
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/NavEventDispatcher.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef NavEventDispatcher_h
18 | #define NavEventDispatcher_h
19 |
20 | #import
21 | #import
22 |
23 | NS_ASSUME_NONNULL_BEGIN
24 |
25 | @interface NavEventDispatcher : RCTEventEmitter
26 |
27 | - (void)sendEventName:(NSString *)eventName body:(id)body;
28 | - (bool)hasListeners;
29 |
30 | @end
31 |
32 | NS_ASSUME_NONNULL_END
33 |
34 | #endif /* NavEventDispatcher_h */
35 |
--------------------------------------------------------------------------------
/.github/workflows/license-check.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: Check license headers
16 | on:
17 | pull_request:
18 | push:
19 | branches:
20 | - main
21 |
22 | jobs:
23 | check-files-license-headers:
24 | runs-on: ubuntu-latest
25 | timeout-minutes: 30
26 | steps:
27 | - uses: actions/checkout@v4
28 | - uses: actions/setup-go@v5
29 | - name: Install addlicense
30 | run: go install github.com/google/addlicense@latest
31 | - name: Check license header
32 | run: ./scripts/addlicense.sh --check
33 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/NavAutoEventDispatcher.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef NavAutoEventDispatcher_h
18 | #define NavAutoEventDispatcher_h
19 |
20 | #import
21 | #import
22 |
23 | NS_ASSUME_NONNULL_BEGIN
24 |
25 | @interface NavAutoEventDispatcher : RCTEventEmitter
26 |
27 | - (void)sendEventName:(NSString *)eventName body:(id)body;
28 | - (bool)hasListeners;
29 |
30 | @end
31 |
32 | NS_ASSUME_NONNULL_END
33 |
34 | #endif /* NavAutoEventDispatcher_h */
35 |
--------------------------------------------------------------------------------
/scripts/addlicense.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Copyright 2024 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | addlicense -f header_template.txt $@ \
17 | --ignore "**/Pods/**" \
18 | --ignore "**/node_modules/**" \
19 | --ignore "**/android/**/build/**" \
20 | --ignore "**/android/.gradle/**" \
21 | --ignore "**/android/.idea/**" \
22 | --ignore "**/ios/build/**" \
23 | --ignore "example/vendor/**" \
24 | --ignore "lib/**" \
25 | --ignore "coverage/**" \
26 | --ignore ".yarn/**" \
27 | --ignore ".github/ISSUE_TEMPLATE/**" \
28 | .
29 |
--------------------------------------------------------------------------------
/example/src/styles/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2025 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // Re-export all styles for easy access
18 | export { Colors, Spacing, BorderRadius, Typography, Shadows } from './theme';
19 | export { CommonStyles, MapStyles, ControlStyles } from './components';
20 | export { MapStylingOptions } from './mapStyling';
21 |
22 | // Consolidated export for easy importing
23 | import { CommonStyles, MapStyles, ControlStyles } from './components';
24 |
25 | export const Styles = {
26 | Common: CommonStyles,
27 | Map: MapStyles,
28 | Control: ControlStyles,
29 | };
30 |
--------------------------------------------------------------------------------
/example/metro.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const path = require('path');
18 | const { getDefaultConfig } = require('@react-native/metro-config');
19 | const { withMetroConfig } = require('react-native-monorepo-config');
20 |
21 | const root = path.resolve(__dirname, '..');
22 |
23 | /**
24 | * Metro configuration
25 | * https://facebook.github.io/metro/docs/configuration
26 | *
27 | * @type {import('metro-config').MetroConfig}
28 | */
29 | module.exports = withMetroConfig(getDefaultConfig(__dirname), {
30 | root,
31 | dirname: __dirname,
32 | });
33 |
--------------------------------------------------------------------------------
/example/Gemfile:
--------------------------------------------------------------------------------
1 | # Copyright 2024 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | source 'https://rubygems.org'
16 |
17 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
18 | ruby ">= 2.6.10"
19 |
20 | # Exclude problematic versions of cocoapods and activesupport that causes build failures.
21 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
22 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
23 | gem 'xcodeproj', '< 1.26.0'
24 | gem 'concurrent-ruby', '< 1.3.4'
25 |
26 | # Ruby 3.4.0 has removed some libraries from the standard library.
27 | gem 'bigdecimal'
28 | gem 'logger'
29 | gem 'benchmark'
30 | gem 'mutex_m'
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/IMapViewFragment.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import android.view.View;
17 | import com.google.android.gms.maps.GoogleMap;
18 | import com.google.android.gms.maps.model.MapColorScheme;
19 |
20 | public interface IMapViewFragment {
21 | MapViewController getMapController();
22 |
23 | void setMapStyle(String url);
24 |
25 | GoogleMap getGoogleMap();
26 |
27 | void setMapColorScheme(@MapColorScheme int colorScheme);
28 |
29 | // Fragment
30 | boolean isAdded();
31 |
32 | View getView();
33 | }
34 |
--------------------------------------------------------------------------------
/example/react-native.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const path = require('path');
18 | const pkg = require('../package.json');
19 |
20 | module.exports = {
21 | project: {
22 | ios: {
23 | automaticPodsInstallation: true,
24 | },
25 | },
26 | dependencies: {
27 | [pkg.name]: {
28 | root: path.join(__dirname, '..'),
29 | platforms: {
30 | // Codegen script incorrectly fails without this
31 | // So we explicitly specify the platforms with empty object
32 | ios: {},
33 | android: {},
34 | },
35 | },
36 | },
37 | };
38 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # XDE
6 | .expo/
7 |
8 | # VSCode
9 | .vscode/
10 | jsconfig.json
11 |
12 | # Xcode
13 | #
14 | build/
15 | *.pbxuser
16 | !default.pbxuser
17 | *.mode1v3
18 | !default.mode1v3
19 | *.mode2v3
20 | !default.mode2v3
21 | *.perspectivev3
22 | !default.perspectivev3
23 | xcuserdata
24 | *.xccheckout
25 | *.moved-aside
26 | DerivedData
27 | *.hmap
28 | *.ipa
29 | *.xcuserstate
30 | project.xcworkspace
31 | .xcode.env.local
32 | Keys.plist
33 |
34 | # Android/IJ
35 | #
36 | .classpath
37 | .cxx
38 | .gradle
39 | .idea
40 | .project
41 | .settings
42 | .kotlin
43 | local.properties
44 | android.iml
45 |
46 | # Cocoapods
47 | #
48 | example/ios/Pods
49 | example/ios/Podfile.lock
50 |
51 | # Ruby
52 | example/vendor/
53 |
54 | # node.js
55 | #
56 | node_modules/
57 | npm-debug.log
58 | yarn-debug.log
59 | yarn-error.log
60 | package-lock.json
61 |
62 | # BUCK
63 | buck-out/
64 | \.buckd/
65 | android/app/libs
66 | android/keystores/debug.keystore
67 |
68 | # Yarn
69 | .yarn/*
70 | !.yarn/patches
71 | !.yarn/plugins
72 | !.yarn/releases
73 | !.yarn/sdks
74 | !.yarn/versions
75 |
76 | # Expo
77 | .expo/
78 |
79 | # Turborepo
80 | .turbo/
81 |
82 | # generated by bob
83 | lib/
84 |
85 | # tests
86 | coverage/
87 |
--------------------------------------------------------------------------------
/example/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /** @type {import('@jest/types').Config.InitialOptions} */
18 | module.exports = {
19 | rootDir: '..',
20 | testMatch: ['/e2e/**/*.test.js'],
21 | testTimeout: 120000,
22 | maxWorkers: 1,
23 | globalSetup: 'detox/runners/jest/globalSetup',
24 | globalTeardown: 'detox/runners/jest/globalTeardown',
25 | reporters: ['detox/runners/jest/reporter'],
26 | testEnvironment: 'detox/runners/jest/testEnvironment',
27 | verbose: true,
28 | globals: {
29 | detox: {
30 | configuration: process.env.DETOX_CONFIGURATION || 'ios.sim.debug',
31 | },
32 | },
33 | };
34 |
--------------------------------------------------------------------------------
/lefthook.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2024 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | pre-commit:
16 | parallel: true
17 | commands:
18 | format-objc:
19 | runner: sh
20 | run: ./scripts/format-objc.sh --check
21 | format-java:
22 | runner: sh
23 | run: ./scripts/format-java.sh --check
24 | license-check:
25 | runner: sh
26 | run: ./scripts/addlicense.sh --check
27 | lint:
28 | glob: '*.{js,ts,jsx,tsx}'
29 | run: npx eslint {staged_files}
30 | types:
31 | glob: '*.{js,ts, jsx, tsx}'
32 | run: npx tsc --noEmit
33 | commit-msg:
34 | parallel: true
35 | commands:
36 | commitlint:
37 | run: npx commitlint --edit
38 | rc: ~/.lefthookrc
39 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/NavViewModule.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import
18 | #import "NavViewController.h"
19 |
20 | NS_ASSUME_NONNULL_BEGIN
21 |
22 | @interface NavViewModule : NSObject
23 | @property(nonatomic, strong) NSMapTable *viewControllers;
24 |
25 | - (void)attachViewsToNavigationSession;
26 | - (void)navigationSessionDestroyed;
27 | - (void)informPromptVisibilityChange:(BOOL)visible;
28 | - (void)setTravelMode:(GMSNavigationTravelMode)travelMode;
29 |
30 | // Class method to access the singleton instance
31 | + (instancetype)sharedInstance;
32 |
33 | @end
34 |
35 | NS_ASSUME_NONNULL_END
36 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/support_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Support request
3 | about:
4 | If you have a support contract with Google, please create an issue in the Google
5 | Cloud Support console.
6 | title: '[Support Request]: '
7 | labels: 'triage me, type: question'
8 | assignees: ''
9 | ---
10 |
11 | **PLEASE READ**
12 |
13 | If you have a support contract with Google and questions related to how Navigation SDK works and its features should be used, please create an issue in the [support console](https://console.cloud.google.com/google/maps-apis/support/createcase). This will ensure a timely response.
14 |
15 | Links to the official native SDKs:
16 | - [Android](https://developers.google.com/maps/documentation/navigation/android-sdk)
17 | - [iOS](https://developers.google.com/maps/documentation/navigation/ios-sdk)
18 |
19 | Discover additional support services for the Google Maps Platform, including developer communities, technical guidance, and expert support at the Google Maps Platform [support resources page](https://developers.google.com/maps/support/).
20 |
21 | If your bug or feature request is not related to this particular library, please visit the Google Maps Platform [issue trackers](https://developers.google.com/maps/support/#issue_tracker).
22 |
23 | Check for answers on StackOverflow with the [google-maps](http://stackoverflow.com/questions/tagged/google-maps) tag.
24 |
25 | ---
26 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/JsErrors.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | public class JsErrors {
17 | public static final String NO_NAVIGATOR_ERROR_CODE = "NO_NAVIGATOR_ERROR_CODE";
18 | public static final String NO_NAVIGATOR_ERROR_MESSAGE =
19 | "Make sure to initialize the navigator is ready before executing.";
20 |
21 | public static final String NO_MAP_ERROR_CODE = "NO_MAP_ERROR_CODE";
22 | public static final String NO_MAP_ERROR_MESSAGE =
23 | "Make sure to initialize the map view has been initialized before executing.";
24 |
25 | public static final String NO_DESTINATIONS_ERROR_CODE = "NO_DESTINATIONS";
26 | public static final String NO_DESTINATIONS_ERROR_MESSAGE = "Destinations not set";
27 | }
28 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/BaseCarSceneDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #import
17 |
18 | NS_ASSUME_NONNULL_BEGIN
19 |
20 | @class NavViewController; // forward declaration
21 |
22 | @interface BaseCarSceneDelegate
23 | : UIResponder
24 |
25 | @property(nonatomic, strong) CPInterfaceController *interfaceController;
26 | @property(nonatomic, strong) CPWindow *carWindow;
27 | @property(nonatomic, strong) CPMapTemplate *mapTemplate;
28 | @property(nonatomic, strong) NavViewController *navViewController;
29 | @property(nonatomic, assign) BOOL sessionAttached;
30 | @property(nonatomic, assign) BOOL viewControllerRegistered;
31 |
32 | - (CPMapTemplate *)getTemplate;
33 |
34 | @end
35 |
36 | NS_ASSUME_NONNULL_END
37 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/sampleapp/SampleAndroidAutoService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.sampleapp;
18 |
19 | import androidx.annotation.NonNull;
20 | import androidx.car.app.CarAppService;
21 | import androidx.car.app.Session;
22 | import androidx.car.app.SessionInfo;
23 | import androidx.car.app.validation.HostValidator;
24 |
25 | public final class SampleAndroidAutoService extends CarAppService {
26 | @NonNull
27 | @Override
28 | public HostValidator createHostValidator() {
29 | // This sample allows all hosts to connect to the app.
30 | return HostValidator.ALLOW_ALL_HOSTS_VALIDATOR;
31 | }
32 |
33 | @Override
34 | @NonNull
35 | public Session onCreateSession(@NonNull SessionInfo sessionInfo) {
36 | return new SampleAndroidAutoSession(sessionInfo);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.github/actions/setup/action.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2024 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: Setup
16 | description: Setup Node.js and install dependencies
17 |
18 | runs:
19 | using: composite
20 | steps:
21 | - name: Setup Node.js
22 | uses: actions/setup-node@v3
23 | with:
24 | node-version-file: .nvmrc
25 |
26 | - name: Cache dependencies
27 | id: yarn-cache
28 | uses: actions/cache@v3
29 | with:
30 | path: |
31 | **/node_modules
32 | .yarn/install-state.gz
33 | key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}-${{ hashFiles('**/package.json', '!node_modules/**') }}
34 | restore-keys: |
35 | ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
36 | ${{ runner.os }}-yarn-
37 |
38 | - name: Install dependencies
39 | if: steps.yarn-cache.outputs.cache-hit != 'true'
40 | run: yarn install --immutable
41 | shell: bash
42 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/INavigationViewCallback.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef INavigationViewCallback_h
18 | #define INavigationViewCallback_h
19 |
20 | @import GoogleNavigation;
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | @protocol INavigationViewCallback
25 |
26 | @required
27 |
28 | - (void)handleMapReady;
29 | - (void)handleMapClick:(NSDictionary *)latLngMap;
30 | - (void)handleRecenterButtonClick;
31 | - (void)handleMarkerInfoWindowTapped:(GMSMarker *)marker;
32 | - (void)handleMarkerClick:(GMSMarker *)marker;
33 | - (void)handlePolylineClick:(GMSPolyline *)polyline;
34 | - (void)handlePolygonClick:(GMSPolygon *)polygon;
35 | - (void)handleCircleClick:(GMSCircle *)circle;
36 | - (void)handleGroundOverlayClick:(GMSGroundOverlay *)groundOverlay;
37 | - (void)handlePromptVisibilityChanged:(BOOL)isVisible;
38 | @end
39 |
40 | NS_ASSUME_NONNULL_END
41 |
42 | #endif /* INavigationViewCallback_h */
43 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/INavigationViewCallback.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import com.google.android.gms.maps.model.Circle;
17 | import com.google.android.gms.maps.model.GroundOverlay;
18 | import com.google.android.gms.maps.model.LatLng;
19 | import com.google.android.gms.maps.model.Marker;
20 | import com.google.android.gms.maps.model.Polygon;
21 | import com.google.android.gms.maps.model.Polyline;
22 |
23 | public interface INavigationViewCallback {
24 | void onMapReady();
25 |
26 | void onMarkerClick(Marker marker);
27 |
28 | void onPolylineClick(Polyline polyline);
29 |
30 | void onPolygonClick(Polygon polygon);
31 |
32 | void onCircleClick(Circle circle);
33 |
34 | void onGroundOverlayClick(GroundOverlay groundOverlay);
35 |
36 | void onMarkerInfoWindowTapped(Marker marker);
37 |
38 | void onMapClick(LatLng latLng);
39 | }
40 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/NavAutoModule.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #import
17 |
18 | NS_ASSUME_NONNULL_BEGIN
19 |
20 | @class NavViewController; // forward declaration
21 |
22 | @interface NavAutoModule : NSObject
23 | @property(nonatomic, strong, nullable) NavViewController *viewController;
24 |
25 | typedef void (^NavAutoModuleReadyCallback)(void);
26 |
27 | - (void)registerViewController:(NavViewController *)vc;
28 | - (void)unRegisterViewController;
29 | + (void)registerNavAutoModuleReadyCallback:(NavAutoModuleReadyCallback)callback;
30 | + (void)unregisterNavAutoModuleReadyCallback;
31 | - (void)onCustomNavigationAutoEvent:(NSString *)type data:(nullable NSDictionary *)data;
32 |
33 | // Class method to access the singleton instance
34 | + (instancetype)sharedInstance;
35 | + (instancetype)getOrCreateSharedInstance;
36 |
37 | @end
38 |
39 | NS_ASSUME_NONNULL_END
40 |
--------------------------------------------------------------------------------
/android/src/main/res/layout/fragment_nav_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
22 |
31 |
32 |
--------------------------------------------------------------------------------
/src/navigation/shared.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { RouteStatus } from './types';
17 |
18 | export const getRouteStatusFromStringValue = (value: string): RouteStatus => {
19 | switch (value) {
20 | case 'OK':
21 | return RouteStatus.OK;
22 |
23 | case 'NO_ROUTE_FOUND':
24 | return RouteStatus.NO_ROUTE_FOUND;
25 |
26 | case 'NETWORK_ERROR':
27 | return RouteStatus.NETWORK_ERROR;
28 |
29 | case 'QUOTA_CHECK_FAILED':
30 | return RouteStatus.QUOTA_CHECK_FAILED;
31 |
32 | case 'ROUTE_CANCELED':
33 | return RouteStatus.ROUTE_CANCELED;
34 |
35 | case 'LOCATION_DISABLED':
36 | return RouteStatus.LOCATION_DISABLED;
37 |
38 | case 'LOCATION_UNKNOWN':
39 | return RouteStatus.LOCATION_UNKNOWN;
40 |
41 | case 'WAYPOINT_ERROR':
42 | return RouteStatus.WAYPOINT_ERROR;
43 |
44 | case 'DUPLICATE_WAYPOINTS_ERROR':
45 | return RouteStatus.DUPLICATE_WAYPOINTS_ERROR;
46 |
47 | default:
48 | return RouteStatus.UNKNOWN;
49 | }
50 | };
51 |
--------------------------------------------------------------------------------
/example/android/app/src/androidTest/java/com/sampleapp/DetoxTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.sampleapp;
18 |
19 | import androidx.test.ext.junit.runners.AndroidJUnit4;
20 | import androidx.test.filters.LargeTest;
21 | import androidx.test.rule.ActivityTestRule;
22 | import com.wix.detox.Detox;
23 | import com.wix.detox.config.DetoxConfig;
24 | import org.junit.Rule;
25 | import org.junit.Test;
26 | import org.junit.runner.RunWith;
27 |
28 | @RunWith(AndroidJUnit4.class)
29 | @LargeTest
30 | public class DetoxTest {
31 | @Rule // (2)
32 | public ActivityTestRule mActivityRule =
33 | new ActivityTestRule<>(MainActivity.class, false, false);
34 |
35 | @Test
36 | public void runDetoxTests() {
37 | DetoxConfig detoxConfig = new DetoxConfig();
38 | detoxConfig.idlePolicyConfig.masterTimeoutSec = 90;
39 | detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60;
40 | detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 180 : 60);
41 |
42 | Detox.runTests(mActivityRule, detoxConfig);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/INavigationCallback.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef INavigationCallback_h
18 | #define INavigationCallback_h
19 |
20 | @import GoogleNavigation;
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | @protocol INavigationCallback
25 |
26 | @required
27 |
28 | - (void)onRemainingTimeOrDistanceChanged;
29 | - (void)onRouteChanged;
30 | - (void)onArrival:(NSDictionary *)waypoint;
31 | - (void)onTurnByTurn:(GMSNavigationNavInfo *)navInfo;
32 | - (void)onTurnByTurn:(GMSNavigationNavInfo *)navInfo
33 | distanceToNextDestinationMeters:(double)distanceToNextDestinationMeters
34 | timeToNextDestinationSeconds:(double)timeToNextDestinationSeconds;
35 | - (void)onNavigationReady;
36 | - (void)onNavigationInitError:(NSNumber *)errorCode;
37 | - (void)onStartGuidance;
38 | - (void)onRouteStatusResult:(GMSRouteStatus)routeStatus;
39 | - (void)onReroutingRequestedByOffRoute;
40 | - (void)onLocationChanged:(NSDictionary *)location;
41 | - (void)onPromptVisibilityChange:(BOOL)visible;
42 | @end
43 |
44 | #endif /* INavigationCallback_h */
45 |
46 | NS_ASSUME_NONNULL_END
47 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/INavViewFragment.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import com.google.android.libraries.navigation.ForceNightMode;
17 | import com.google.android.libraries.navigation.StylingOptions;
18 |
19 | public interface INavViewFragment extends IMapViewFragment {
20 | void setNavigationUiEnabled(boolean enableNavigationUi);
21 |
22 | void setTripProgressBarEnabled(boolean enabled);
23 |
24 | void setSpeedometerEnabled(boolean enabled);
25 |
26 | void setSpeedLimitIconEnabled(boolean enabled);
27 |
28 | void setTrafficIncidentCardsEnabled(boolean enabled);
29 |
30 | void setEtaCardEnabled(boolean enabled);
31 |
32 | void setHeaderEnabled(boolean enabled);
33 |
34 | void setRecenterButtonEnabled(boolean enabled);
35 |
36 | void showRouteOverview();
37 |
38 | void setNightModeOption(@ForceNightMode int nightModeOverride);
39 |
40 | void setReportIncidentButtonEnabled(boolean enabled);
41 |
42 | void setStylingOptions(StylingOptions stylingOptions);
43 |
44 | void applyStylingOptions();
45 | }
46 |
--------------------------------------------------------------------------------
/example/e2e/map.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {
18 | initializeIntegrationTestsPage,
19 | selectTestByName,
20 | waitForTestToFinish,
21 | expectSuccess,
22 | expectNoErrors,
23 | } from './shared.js';
24 |
25 | describe('Map view tests', () => {
26 | beforeEach(async () => {
27 | await initializeIntegrationTestsPage();
28 | });
29 |
30 | it('T01 - initialize map and test default values', async () => {
31 | await selectTestByName('testMapInitialization');
32 | await waitForTestToFinish();
33 | await expectNoErrors();
34 | await expectSuccess();
35 | });
36 |
37 | it('T02 - initialize map and test move camera', async () => {
38 | await selectTestByName('testMoveCamera');
39 | await waitForTestToFinish();
40 | await expectNoErrors();
41 | await expectSuccess();
42 | });
43 |
44 | it('T03 - initialize map and test camera tilt bearing zoom', async () => {
45 | await selectTestByName('testTiltZoomBearingCamera');
46 | await waitForTestToFinish();
47 | await expectNoErrors();
48 | await expectSuccess();
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/.github/workflows/release-please.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2024 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | ## Runs the release-please action for all new pushes to the main branch.
16 | ## This will create new release-PRs, create GitHub and npm releases,
17 | ## and update the CHANGELOG.md.
18 |
19 | on:
20 | push:
21 | branches: [main]
22 | workflow_dispatch:
23 |
24 | concurrency:
25 | group: ${{ github.workflow }}-${{ github.ref }}
26 | cancel-in-progress: true
27 |
28 | permissions:
29 | contents: write
30 | pull-requests: write
31 |
32 | name: Release Please
33 |
34 | jobs:
35 | build-and-test:
36 | uses: ./.github/workflows/ci.yml
37 |
38 | release-please:
39 | runs-on: ubuntu-latest
40 | needs: build-and-test
41 | outputs:
42 | release_ready: ${{ steps.release.outputs.release_created }}
43 | steps:
44 | - id: release
45 | name: Release Please
46 | uses: googleapis/release-please-action@v4
47 | with:
48 | token: ${{ secrets.SYNCED_GITHUB_TOKEN_REPO }}
49 |
50 | publish:
51 | needs: release-please
52 | if: ${{ needs.release-please.outputs.release_ready }}
53 | uses: ./.github/workflows/publish.yml
54 | secrets: inherit
55 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/CarSceneDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #import "CarSceneDelegate.h"
17 | #import
18 | #import
19 | #import
20 | #import
21 |
22 | @implementation CarSceneDelegate
23 |
24 | - (CPMapTemplate *)getTemplate {
25 | CPMapTemplate *template = [[CPMapTemplate alloc] init];
26 | [template showPanningInterfaceAnimated:YES];
27 |
28 | CPBarButton *customButton = [[CPBarButton alloc]
29 | initWithTitle:@"Custom Event"
30 | handler:^(CPBarButton *_Nonnull button) {
31 | NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
32 | dictionary[@"sampleDataKey"] = @"sampleDataContent";
33 | [[NavAutoModule getOrCreateSharedInstance] onCustomNavigationAutoEvent:@"sampleEvent"
34 | data:dictionary];
35 | }];
36 |
37 | template.leadingNavigationBarButtons = @[ customButton ];
38 | template.trailingNavigationBarButtons = @[];
39 | return template;
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/react-native-navigation-sdk.podspec:
--------------------------------------------------------------------------------
1 | =begin
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | =end
16 |
17 | require "json"
18 |
19 | package = JSON.parse(File.read(File.join(__dir__, "package.json")))
20 |
21 | Pod::Spec.new do |s|
22 | s.name = "react-native-navigation-sdk"
23 | s.header_dir = "ReactNativeGoogleMapsNavigation"
24 | s.module_name = "ReactNativeGoogleMapsNavigation"
25 | s.version = package["version"]
26 | s.summary = package["description"]
27 | s.homepage = package["homepage"]
28 | s.license = package["license"]
29 | s.authors = package["author"]
30 |
31 | s.platforms = { :ios => "16.0" }
32 | s.source = { :git => "https://github.com/googlemaps/react-native-navigation-sdk.git", :tag => "#{s.version}" }
33 |
34 | s.source_files = "ios/**/*.{h,m,mm,cpp}"
35 | s.public_header_files = [
36 | "ios/react-native-navigation-sdk/BaseCarSceneDelegate.h",
37 | "ios/react-native-navigation-sdk/INavigationCallback.h",
38 | "ios/react-native-navigation-sdk/NavAutoModule.h",
39 | "ios/react-native-navigation-sdk/NavModule.h",
40 | ]
41 |
42 | s.dependency "React-Core"
43 | s.dependency "GoogleNavigation", "10.6.0"
44 |
45 | install_modules_dependencies(s)
46 | end
47 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Disable new arch as it is not supported by the current version of package
2 | ENV['RCT_NEW_ARCH_ENABLED'] = '0'
3 |
4 | def node_require(script)
5 | # Resolve script with node to allow for hoisting
6 | require Pod::Executable.execute_command('node', ['-p',
7 | "require.resolve(
8 | '#{script}',
9 | {paths: [process.argv[1]]},
10 | )", __dir__]).strip
11 | end
12 |
13 | node_require('react-native/scripts/react_native_pods.rb')
14 | node_require('react-native-permissions/scripts/setup.rb')
15 |
16 | platform :ios, '16'
17 | prepare_react_native_project!
18 |
19 | setup_permissions([
20 | 'LocationAccuracy',
21 | 'LocationAlways',
22 | 'LocationWhenInUse',
23 | 'Notifications',
24 | ])
25 |
26 | linkage = ENV['USE_FRAMEWORKS']
27 | if linkage != nil
28 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
29 | use_frameworks! :linkage => linkage.to_sym
30 | end
31 |
32 | config = use_native_modules!
33 |
34 | target 'SampleApp' do
35 | use_react_native!(
36 | :path => config[:reactNativePath],
37 | # An absolute path to your application root.
38 | :app_path => "#{Pod::Config.instance.installation_root}/.."
39 | )
40 | end
41 |
42 | target 'SampleAppCarPlay' do
43 | use_react_native!(
44 | :path => config[:reactNativePath],
45 | # An absolute path to your application root.
46 | :app_path => "#{Pod::Config.instance.installation_root}/.."
47 | )
48 | end
49 |
50 | target 'SampleAppTests' do
51 | inherit! :complete
52 | # Pods for testing, shared between both SampleApp and SampleAppCarPlay
53 | end
54 |
55 | post_install do |installer|
56 | react_native_post_install(
57 | installer,
58 | config[:reactNativePath],
59 | :mac_catalyst_enabled => false,
60 | # :ccache_enabled => true
61 | )
62 | end
63 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/ObjectTranslationUtil.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import
18 | #import
19 | @import GoogleNavigation;
20 |
21 | @interface ObjectTranslationUtil : NSObject
22 |
23 | + (NSDictionary *)transformNavigationWaypointToDictionary:(GMSNavigationWaypoint *)waypoint;
24 | + (NSDictionary *)transformCoordinateToDictionary:(CLLocationCoordinate2D)coordinate;
25 | + (NSDictionary *)transformCLLocationToDictionary:(CLLocation *)location;
26 | + (NSDictionary *)transformRouteSegmentToDictionary:(GMSRouteLeg *)routeLeg;
27 | + (NSArray *)transformGMSPathToArray:(GMSPath *)path;
28 | + (NSDictionary *)transformMarkerToDictionary:(GMSMarker *)marker;
29 | + (NSDictionary *)transformPolylineToDictionary:(GMSPolyline *)polyline;
30 | + (NSDictionary *)transformPolygonToDictionary:(GMSPolygon *)polygon;
31 | + (NSDictionary *)transformCircleToDictionary:(GMSCircle *)circle;
32 | + (NSDictionary *)transformGroundOverlayToDictionary:(GMSGroundOverlay *)groundOverlay;
33 | + (GMSPath *)transformToPath:(NSArray *)latLngs;
34 | + (CLLocationCoordinate2D)getLocationCoordinateFrom:(NSDictionary *)latLngMap;
35 | + (BOOL)isIdOnUserData:(nullable id)userData;
36 | @end
37 |
--------------------------------------------------------------------------------
/example/src/styles/mapStyling.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2025 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Colors } from './theme';
18 |
19 | /**
20 | * Consistent navigation map view styling options using theme colors
21 | */
22 | export const MapStylingOptions = {
23 | android: {
24 | primaryDayModeThemeColor: Colors.mapStyling.primaryDay,
25 | primaryNightModeThemeColor: Colors.mapStyling.primaryNight,
26 | secondaryDayModeThemeColor: Colors.mapStyling.secondaryDay,
27 | secondaryNightModeThemeColor: Colors.mapStyling.secondaryNight,
28 | headerLargeManeuverIconColor: Colors.mapStyling.accent,
29 | headerSmallManeuverIconColor: Colors.mapStyling.accent,
30 | headerDistanceValueTextColor: Colors.mapStyling.accent,
31 | headerInstructionsFirstRowTextSize: '18f',
32 | },
33 | iOS: {
34 | navigationHeaderPrimaryBackgroundColor: Colors.mapStyling.primaryDay,
35 | navigationHeaderPrimaryBackgroundColorNightMode:
36 | Colors.mapStyling.primaryNight,
37 | navigationHeaderSecondaryBackgroundColor: Colors.mapStyling.secondaryDay,
38 | navigationHeaderSecondaryBackgroundColorNightMode:
39 | Colors.mapStyling.secondaryNight,
40 | navigationHeaderDistanceValueTextColor: Colors.mapStyling.accent,
41 | },
42 | } as const;
43 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: Feature request
2 | description: Suggest a feature or improvement for this package
3 | title: '[Feature request]: '
4 | labels: 'type: feature request, triage me'
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | Thank you for suggesting an improvement for googlemaps/react-native-navigation-sdk!
10 |
11 | If you have a support contract with Google, please create an issue in the [support console](https://console.cloud.google.com/google/maps-apis/support/createcase). This will ensure a timely response.
12 | - type: checkboxes
13 | attributes:
14 | label: Is there an existing issue for this?
15 | description: Please ensure your feature request is not already covered in [existing issues](https://github.com/googlemaps/react-native-navigation-sdk/issues).
16 | options:
17 | - label: I have searched the existing issues
18 | required: true
19 | - type: textarea
20 | attributes:
21 | label: Use case
22 | description: |
23 | Please tell us the problem you are running into that led to you wanting
24 | a new feature.
25 |
26 | Is your feature request related to a problem? Please give a clear and
27 | concise description of what the problem is.
28 |
29 | Describe the alternative solutions you've considered. Is there a package
30 | existing that already solves this?
31 | validations:
32 | required: true
33 | - type: textarea
34 | attributes:
35 | label: Proposal
36 | description: |
37 | Briefly but precisely describe what you would like the package to be able to do.
38 |
39 | Consider attaching something showing what you are imagining:
40 | * images
41 | * videos
42 | * code samples
43 | validations:
44 | required: true
45 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/NavModule.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef NavModule_h
18 | #define NavModule_h
19 |
20 | #import
21 | #import "INavigationCallback.h"
22 | @import GoogleNavigation;
23 |
24 | NS_ASSUME_NONNULL_BEGIN
25 |
26 | @interface NavModule : NSObject
30 |
31 | typedef void (^NavigationSessionReadyCallback)(void);
32 | typedef void (^NavigationSessionDisposedCallback)(void);
33 |
34 | @property BOOL enableUpdateInfo;
35 |
36 | - (BOOL)hasSession;
37 | - (BOOL)isNavigatorAvailable;
38 | - (GMSNavigationSession *)getSession;
39 | + (void)unregisterNavigationSessionReadyCallback;
40 | + (void)registerNavigationSessionReadyCallback:(NavigationSessionReadyCallback)callback;
41 | + (void)unregisterNavigationSessionDisposedCallback;
42 | + (void)registerNavigationSessionDisposedCallback:(NavigationSessionDisposedCallback)callback;
43 |
44 | // Class method to access the singleton instance
45 | + (instancetype)sharedInstance;
46 |
47 | @end
48 |
49 | NS_ASSUME_NONNULL_END
50 |
51 | #endif /* NavModule_h */
52 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/Package.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import com.facebook.proguard.annotations.DoNotStrip;
17 | import com.facebook.react.ReactPackage;
18 | import com.facebook.react.bridge.NativeModule;
19 | import com.facebook.react.bridge.ReactApplicationContext;
20 | import com.facebook.react.uimanager.ViewManager;
21 | import java.util.ArrayList;
22 | import java.util.Arrays;
23 | import java.util.List;
24 |
25 | @DoNotStrip
26 | public class Package implements ReactPackage {
27 |
28 | private NavViewManager mNavViewManager;
29 |
30 | @Override
31 | public List createViewManagers(ReactApplicationContext reactContext) {
32 | return Arrays.asList(NavViewManager.getInstance(reactContext));
33 | }
34 |
35 | @Override
36 | public List createNativeModules(ReactApplicationContext reactContext) {
37 | List modules = new ArrayList<>();
38 | NavViewManager viewManager = NavViewManager.getInstance(reactContext);
39 | modules.add(NavModule.getInstance(reactContext, viewManager));
40 | modules.add(new NavAutoModule(reactContext));
41 | modules.add(new NavViewModule(reactContext, viewManager));
42 |
43 | return modules;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/example/e2e/event_listener.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {
18 | initializeIntegrationTestsPage,
19 | agreeToTermsAndConditions,
20 | selectTestByName,
21 | waitForTestToFinish,
22 | expectSuccess,
23 | expectNoErrors,
24 | } from './shared.js';
25 |
26 | describe('Event listener tests', () => {
27 | beforeEach(async () => {
28 | await initializeIntegrationTestsPage();
29 | });
30 |
31 | it('T01 - test onRemainingTimeOrDistanceChanged event listener', async () => {
32 | await selectTestByName('testOnRemainingTimeOrDistanceChanged');
33 | await agreeToTermsAndConditions();
34 | await waitForTestToFinish();
35 | await expectNoErrors();
36 | await expectSuccess();
37 | });
38 |
39 | it('T02 - test onArrival event listener', async () => {
40 | await selectTestByName('testOnArrival');
41 | await agreeToTermsAndConditions();
42 | await waitForTestToFinish();
43 | await expectNoErrors();
44 | await expectSuccess();
45 | });
46 |
47 | it('T03 - test onRouteChanged event listener', async () => {
48 | await selectTestByName('testOnRouteChanged');
49 | await agreeToTermsAndConditions();
50 | await waitForTestToFinish();
51 | await expectNoErrors();
52 | await expectSuccess();
53 | });
54 | });
55 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/sampleapp/MainActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.sampleapp;
18 |
19 | import com.facebook.react.ReactActivity;
20 | import com.facebook.react.ReactActivityDelegate;
21 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
22 | import com.facebook.react.defaults.DefaultReactActivityDelegate;
23 |
24 | public class MainActivity extends ReactActivity {
25 |
26 | /**
27 | * Returns the name of the main component registered from JavaScript. This is used to schedule
28 | * rendering of the component.
29 | */
30 | @Override
31 | protected String getMainComponentName() {
32 | return "SampleApp";
33 | }
34 |
35 | /**
36 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
37 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
38 | * (aka React 18) with two boolean flags.
39 | */
40 | @Override
41 | protected ReactActivityDelegate createReactActivityDelegate() {
42 | return new DefaultReactActivityDelegate(
43 | this,
44 | getMainComponentName(),
45 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
46 | DefaultNewArchitectureEntryPoint.getFabricEnabled());
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2024 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # A workflow that publishes the library to CocoaPods
16 | name: Publish
17 |
18 | on:
19 | workflow_call: # called when release-please steps.release.outputs.release_created
20 | workflow_dispatch: # manually trigger if previous runs failed
21 |
22 | concurrency:
23 | group: publishing
24 | cancel-in-progress: true
25 |
26 | jobs:
27 | build-and-test:
28 | uses: ./.github/workflows/ci.yml
29 |
30 | publish:
31 | runs-on: ubuntu-latest
32 | needs: build-and-test
33 | steps:
34 | - name: Checkout
35 | uses: actions/checkout@v4
36 |
37 | - name: Setup Node for Dependency Installation
38 | uses: actions/setup-node@v4
39 | with:
40 | node-version: 20
41 | cache: npm
42 |
43 | - name: Install Dependencies
44 | run: npm install
45 |
46 | # Now configure node with the registry used for publishing
47 | - name: Setup Node for Publishing
48 | uses: actions/setup-node@v4
49 | with:
50 | node-version: 20
51 | registry-url: 'https://wombat-dressing-room.appspot.com/'
52 |
53 | - name: Publish
54 | # npm publish will trigger the build via the prepack hook
55 | run: npm publish
56 | env:
57 | NODE_AUTH_TOKEN: ${{ secrets.NPM_WOMBOT_TOKEN }}
58 |
--------------------------------------------------------------------------------
/src/auto/types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import type { MapViewController } from '../maps';
18 |
19 | /** Defines all callbacks to be emitted by NavViewAuto support. */
20 | export interface NavigationAutoCallbacks {
21 | /**
22 | * Callback function invoked when the screen availability changes.
23 | */
24 | onAutoScreenAvailabilityChanged?(available: boolean): void;
25 |
26 | /**
27 | * Callback function invoked when a custom navigation auto event is received.
28 | */
29 | onCustomNavigationAutoEvent?(event: CustomNavigationAutoEvent): void;
30 | }
31 |
32 | /**
33 | * CustomNavigationAutoEvent is an event that can be sent from the
34 | * native side to the React Native side, ment to be simple way to
35 | * implement custom events fired by the native side.
36 | */
37 | export interface CustomNavigationAutoEvent {
38 | /**
39 | * The event type.
40 | */
41 | type: string;
42 |
43 | /**
44 | * The event data.
45 | */
46 | data?: Record;
47 | }
48 |
49 | export interface MapViewAutoController extends MapViewController {
50 | /**
51 | * Cleans up the navigation module, releasing any resources that were allocated.
52 | */
53 | cleanup(): Promise;
54 |
55 | /**
56 | * Queries screen visibility.
57 | */
58 | isAutoScreenAvailable(): Promise;
59 | }
60 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/PhoneSceneDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #import "PhoneSceneDelegate.h"
17 | #import
18 | #import
19 | #import
20 |
21 | @implementation PhoneSceneDelegate
22 |
23 | - (void)scene:(UIScene *)scene
24 | willConnectToSession:(UISceneSession *)session
25 | options:(UISceneConnectionOptions *)connectionOptions {
26 | RCTAppDelegate *appDelegate = (RCTAppDelegate *)[UIApplication sharedApplication].delegate;
27 | if (!appDelegate) {
28 | return;
29 | }
30 |
31 | UIWindowScene *windowScene = (UIWindowScene *)scene;
32 | if (!windowScene) {
33 | return;
34 | }
35 |
36 | UIView *rootView = [appDelegate.rootViewFactory viewWithModuleName:appDelegate.moduleName
37 | initialProperties:appDelegate.initialProps
38 | launchOptions:nil];
39 | rootView.backgroundColor = [UIColor whiteColor];
40 |
41 | UIViewController *rootViewController = [[UIViewController alloc] init];
42 | rootViewController.view = rootView;
43 |
44 | UIWindow *window = [[UIWindow alloc] initWithWindowScene:windowScene];
45 | window.rootViewController = rootViewController;
46 | self.window = window;
47 |
48 | [appDelegate setWindow:window];
49 | [window makeKeyAndVisible];
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/CollectionUtil.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | public class CollectionUtil {
20 |
21 | private static Map mObjectMap = new HashMap<>();
22 |
23 | public static int getInt(String name, Map map, int defaultValue) {
24 | if (map.containsKey(name) && map.get(name) != null) {
25 | return ((Double) map.get(name)).intValue();
26 | }
27 | return defaultValue;
28 | }
29 |
30 | public static boolean getBool(String name, Map map, boolean defaultValue) {
31 | if (map.containsKey(name) && map.get(name) != null) {
32 | return ((Boolean) map.get(name)).booleanValue();
33 | }
34 | return defaultValue;
35 | }
36 |
37 | public static String getString(String name, Map map) {
38 | if (map.containsKey(name) && map.get(name) != null) return map.get(name).toString();
39 | return null;
40 | }
41 |
42 | public static double getDouble(String name, Map map, double defaultValue) {
43 | if (map.containsKey(name) && map.get(name) != null) {
44 | return ((Double) map.get(name));
45 | }
46 | return defaultValue;
47 | }
48 |
49 | public static void setValue(String name, Object value) {
50 | mObjectMap.put(name, value);
51 | }
52 |
53 | public static Map getMap() {
54 | return mObjectMap;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/example/src/checkPermissions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { useState, useEffect } from 'react';
18 | import { Platform } from 'react-native';
19 | import {
20 | PERMISSIONS,
21 | requestMultiple,
22 | RESULTS,
23 | } from 'react-native-permissions';
24 | import Snackbar from 'react-native-snackbar';
25 |
26 | const usePermissions = () => {
27 | const [arePermissionsApproved, setArePermissionsApproved] = useState(false);
28 |
29 | useEffect(() => {
30 | const check = async () => {
31 | const toRequestPermissions =
32 | Platform.OS === 'android'
33 | ? [PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION]
34 | : [PERMISSIONS.IOS.LOCATION_ALWAYS];
35 |
36 | try {
37 | const permissionStatuses = await requestMultiple(toRequestPermissions);
38 | const result = permissionStatuses[toRequestPermissions[0]!];
39 |
40 | if (result === RESULTS.GRANTED) {
41 | setArePermissionsApproved(true);
42 | } else {
43 | Snackbar.show({
44 | text: 'Location permissions are needed to proceed with the app. Please re-open and accept.',
45 | duration: Snackbar.LENGTH_SHORT,
46 | });
47 | }
48 | } catch (error) {
49 | console.error('Error requesting permissions', error);
50 | }
51 | };
52 |
53 | check();
54 | }, []);
55 |
56 | return { arePermissionsApproved };
57 | };
58 |
59 | export default usePermissions;
60 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/NavAutoEventDispatcher.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "NavAutoEventDispatcher.h"
18 |
19 | @implementation NavAutoEventDispatcher {
20 | bool hasListeners;
21 | }
22 |
23 | RCT_EXPORT_MODULE(NavAutoEventDispatcher);
24 |
25 | + (id)allocWithZone:(NSZone *)zone {
26 | static NavAutoEventDispatcher *sharedInstance = nil;
27 | static dispatch_once_t onceToken;
28 | dispatch_once(&onceToken, ^{
29 | sharedInstance = [super allocWithZone:zone];
30 | });
31 | return sharedInstance;
32 | }
33 |
34 | - (NSArray *)supportedEvents {
35 | return @[
36 | @"onCustomNavigationAutoEvent",
37 | @"onAutoScreenAvailabilityChanged",
38 | ];
39 | }
40 |
41 | // Will be called when this module's first listener is added.
42 | - (void)startObserving {
43 | hasListeners = YES;
44 | // Set up any upstream listeners or background tasks as necessary
45 | }
46 |
47 | // Will be called when this module's last listener is removed, or on dealloc.
48 | - (void)stopObserving {
49 | hasListeners = NO;
50 | // Remove upstream listeners, stop unnecessary background tasks
51 | }
52 |
53 | - (bool)hasListeners {
54 | return hasListeners;
55 | }
56 |
57 | - (void)sendEventName:(NSString *)eventName body:(id)body {
58 | if (hasListeners) {
59 | [self sendEventWithName:eventName body:body];
60 | } else {
61 | NSLog(@"NavAutoEventDispatcher sendEventName called without listeners: %@", eventName);
62 | }
63 | }
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/src/navigation/navigationView/stylingOptions.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export interface AndroidStylingOptions {
18 | primaryDayModeThemeColor?: string;
19 | secondaryDayModeThemeColor?: string;
20 | primaryNightModeThemeColor?: string;
21 | secondaryNightModeThemeColor?: string;
22 | headerLargeManeuverIconColor?: string;
23 | headerSmallManeuverIconColor?: string;
24 | headerNextStepTextColor?: string;
25 | headerNextStepTextSize?: string;
26 | headerDistanceValueTextColor?: string;
27 | headerDistanceUnitsTextColor?: string;
28 | headerDistanceValueTextSize?: string;
29 | headerDistanceUnitsTextSize?: string;
30 | headerInstructionsTextColor?: string;
31 | headerInstructionsFirstRowTextSize?: string;
32 | headerInstructionsSecondRowTextSize?: string;
33 | headerGuidanceRecommendedLaneColor?: string;
34 | }
35 |
36 | export interface iOSStylingOptions {
37 | navigationHeaderPrimaryBackgroundColor?: string;
38 | navigationHeaderSecondaryBackgroundColor?: string;
39 | navigationHeaderPrimaryBackgroundColorNightMode?: string;
40 | navigationHeaderSecondaryBackgroundColorNightMode?: string;
41 | navigationHeaderLargeManeuverIconColor?: string;
42 | navigationHeaderSmallManeuverIconColor?: string;
43 | navigationHeaderGuidanceRecommendedLaneColor?: string;
44 | navigationHeaderNextStepTextColor?: string;
45 | navigationHeaderDistanceValueTextColor?: string;
46 | navigationHeaderDistanceUnitsTextColor?: string;
47 | navigationHeaderInstructionsTextColor?: string;
48 | }
49 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # React Native: NavSDK Library Sample App
2 |
3 | ## Description
4 |
5 | This contains a sample application to showcase the functionality of the NavSDK library for React Native.
6 |
7 | ## Setup
8 |
9 | First, make sure you go through the setup from the main [README](../README.md).
10 |
11 | ### Android
12 |
13 | 1. Open the example/android folder in Android Studio and add your api key in local.properties by adding a line like this:
14 | * ```MAPS_API_KEY=YOUR_API_KEY``` - make sure that this key is pointing to a Google Cloud project which had Nav SDK enabled.
15 | * To enable Nav SDK in your project follow these guides:
16 | * **Android**: https://developers.google.com/maps/documentation/navigation/android-sdk/set-up-project
17 | * **iOS**: https://developers.google.com/maps/documentation/navigation/ios-sdk/config
18 |
19 | ### iOS
20 |
21 | 1. Using your preferred terminal, go to example/ios folder and run the command below.
22 |
23 | `RCT_NEW_ARCH_ENABLED=0 pod install`
24 |
25 | 2. Copy the `Keys.plist.sample` file located in `example/ios/SampleApp/` to a new file named `Keys.plist`. This file is git ignored and won't be accidentally committed. In your Google cloud console, add the Google API key to the project and add this newly created API key to the `Keys.plist` file.
26 |
27 | ```xml
28 | API_KEY
29 | Your API KEY
30 | ```
31 |
32 | ## Running the app
33 |
34 | 1. To run the sample app, navigate to the `example` folder in the root directory and use the following commands for your platform in the terminal.
35 |
36 | 1. Ensure all workspace dependencies are installed:
37 | `yarn install`
38 |
39 | 2. Start the metro bundler:
40 | * Android:
41 | `npx react-native run-android`
42 | * iOS:
43 | `npx react-native run-ios`
44 |
45 |
46 | 2. After the app initializes, accept the terms of services. You should see a map loaded in background if you have used the right API key.
47 |
48 | ### Android
49 | 1. On your Emulator, go to App Info for the installed app, then Permissions > Location and allow location for the app.
50 |
51 | 2. Restart the app, now the Navigation view should be displayed instead of the map.
52 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #import "AppDelegate.h"
17 |
18 | #import
19 | #import
20 | #import
21 |
22 | @implementation AppDelegate
23 |
24 | - (BOOL)application:(UIApplication *)application
25 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
26 | self.moduleName = @"SampleApp";
27 | self.dependencyProvider = [RCTAppDependencyProvider new];
28 |
29 | // You can add your custom initial props in the dictionary below.
30 | // They will be passed down to the ViewController used by React Native.
31 | self.initialProps = @{};
32 |
33 | // Note: Ensure that you have copied the Keys.plist.sample to Keys.plist
34 | // and have added the correct API_KEY value to the file.
35 | //
36 | // Get the path for the Keys.plist file in the main bundle and read API_KEY.
37 | NSString *path = [[NSBundle mainBundle] pathForResource:@"Keys" ofType:@"plist"];
38 | NSDictionary *keysDictionary = [NSDictionary dictionaryWithContentsOfFile:path];
39 | NSString *api_key = [keysDictionary objectForKey:@"API_KEY"];
40 |
41 | [GMSServices provideAPIKey:api_key];
42 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
43 | }
44 |
45 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
46 | return [self bundleURL];
47 | }
48 |
49 | - (NSURL *)bundleURL {
50 | #if DEBUG
51 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
52 | #else
53 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
54 | #endif
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | samplenavsdk
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(CURRENT_PROJECT_VERSION)
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSExceptionDomains
30 |
31 | localhost
32 |
33 | NSExceptionAllowsInsecureHTTPLoads
34 |
35 |
36 |
37 |
38 | NSLocationAlwaysAndWhenInUseUsageDescription
39 | [Add your description here]
40 | NSLocationAlwaysUsageDescription
41 | [Add your description here]
42 | NSLocationWhenInUseUsageDescription
43 | [Add your description here]
44 | RCTNewArchEnabled
45 |
46 | UIBackgroundModes
47 |
48 | location
49 | audio
50 | remote-notification
51 | fetch
52 |
53 | UILaunchStoryboardName
54 | LaunchScreen
55 | UIRequiredDeviceCapabilities
56 |
57 | armv7
58 |
59 | UISupportedInterfaceOrientations
60 |
61 | UIInterfaceOrientationPortrait
62 | UIInterfaceOrientationLandscapeLeft
63 | UIInterfaceOrientationLandscapeRight
64 |
65 | UIViewControllerBasedStatusBarAppearance
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g
14 |
15 | # CI heap issue fixes
16 | org.gradle.parallel=true
17 | org.gradle.daemon=true
18 |
19 | # When configured, Gradle will run in incubating parallel mode.
20 | # This option should only be used with decoupled projects. More details, visit
21 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
22 | # org.gradle.parallel=true
23 |
24 | # AndroidX package structure to make it clearer which packages are bundled with the
25 | # Android operating system, and which are packaged with your app's APK
26 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
27 | android.useAndroidX=true
28 |
29 | # Automatically convert third-party libraries to use AndroidX
30 | android.enableJetifier=true
31 |
32 | # Use this property to specify which architecture you want to build.
33 | # You can also override it from the CLI using
34 | # ./gradlew -PreactNativeArchitectures=x86_64
35 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
36 |
37 | # Use this property to enable support to the new architecture.
38 | # This will allow you to use TurboModules and the Fabric render in
39 | # your application. You should enable this flag either if you want
40 | # to write custom TurboModules/Fabric components OR use libraries that
41 | # are providing them.
42 | newArchEnabled=false
43 |
44 | # Use this property to enable or disable the Hermes JS engine.
45 | # If set to false, you will be using JSC instead.
46 | hermesEnabled=true
47 |
48 | # Use this property to enable edge-to-edge display support.
49 | # This allows your app to draw behind system bars for an immersive UI.
50 | # Note: Only works with ReactActivity and should not be used with custom Activity.
51 | edgeToEdgeEnabled=false
52 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/NavForwardingManager.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import android.content.Context;
17 | import com.google.android.libraries.navigation.Navigator;
18 |
19 | /** Starts and stops the forwarding of turn-by-turn nav info from Nav SDK. */
20 | public class NavForwardingManager {
21 | /** Registers a service to receive navigation updates from nav info */
22 | public static void startNavForwarding(
23 | Navigator navigator, Context context, INavigationCallback navigationCallback) {
24 | boolean success =
25 | navigator.registerServiceForNavUpdates(
26 | context.getPackageName(),
27 | NavInfoReceivingService.class.getName(),
28 | /* numNextStepsToPreview= */ Integer.MAX_VALUE); // Send all remaining steps.
29 | if (success) {
30 | navigationCallback.logDebugInfo("Successfully registered service for nav updates");
31 | } else {
32 | navigationCallback.logDebugInfo("Failed to register service for nav updates");
33 | }
34 | }
35 |
36 | /** Unregisters the service receiving navigation updates */
37 | public static void stopNavForwarding(
38 | Navigator navigator, Context context, INavigationCallback navigationCallback) {
39 | // Unregister the nav info receiving service.
40 | boolean success = navigator.unregisterServiceForNavUpdates();
41 | if (success) {
42 | navigationCallback.logDebugInfo("Unregistered service for nav updates");
43 | } else {
44 | // This may happen if no service had been registered.
45 | navigationCallback.logDebugInfo(
46 | "No service has been registered for nav updates. Turn by turn toggle is off.");
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/shared/types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * An immutable class representing a latitude/longitude pair.
19 | */
20 | export interface LatLng {
21 | /** Value representing the latitude of the location in degrees. */
22 | lat: number;
23 | /** Value representing the longitude of the location in degrees. */
24 | lng: number;
25 | }
26 |
27 | /**
28 | * An immutable class representing the device location in Navigation SDK.
29 | */
30 | export interface Location {
31 | /**
32 | * Value representing the latitude of the location in degrees.
33 | */
34 | lat: number;
35 |
36 | /**
37 | * Value representing the longitude of the location in degrees.
38 | */
39 | lng: number;
40 |
41 | /**
42 | * Number in meters that represents the altitude of the location.
43 | */
44 | altitude?: number;
45 |
46 | /**
47 | * The bearing at the time of this location in degrees.
48 | * Bearing is the horizontal direction of travel of this device and is
49 | * unrelated to the device orientation.
50 | */
51 | bearing?: number;
52 |
53 | /**
54 | * The speed at the time of this location in meters per second
55 | */
56 | speed: number;
57 |
58 | /**
59 | * Number in meters that represents the horizontal accuracy
60 | * of the location.
61 | */
62 | accuracy?: number;
63 |
64 | /**
65 | * Number in meters that represents the vertical accuracy of the location.
66 | */
67 | verticalAccuracy?: number;
68 |
69 | /**
70 | * The name of the provider associated with this location. Android only.
71 | */
72 | provider?: string;
73 |
74 | /**
75 | * Time when the location was sourced represented as
76 | * ellapse milliseconds since Unix Epoch.
77 | */
78 | time: number;
79 | }
80 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/NavEventDispatcher.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "NavEventDispatcher.h"
18 |
19 | @implementation NavEventDispatcher {
20 | bool hasListeners;
21 | }
22 |
23 | RCT_EXPORT_MODULE(NavEventDispatcher);
24 |
25 | + (id)allocWithZone:(NSZone *)zone {
26 | static NavEventDispatcher *sharedInstance = nil;
27 | static dispatch_once_t onceToken;
28 | dispatch_once(&onceToken, ^{
29 | sharedInstance = [super allocWithZone:zone];
30 | });
31 | return sharedInstance;
32 | }
33 |
34 | - (NSArray *)supportedEvents {
35 | return @[
36 | @"onRemainingTimeOrDistanceChanged",
37 | @"onRouteChanged",
38 | @"onTrafficUpdated",
39 | @"onArrival",
40 | @"onTurnByTurn",
41 | @"onNavigationReady",
42 | @"onNavigationInitError",
43 | @"onStartGuidance",
44 | @"onRouteStatusResult",
45 | @"onReroutingRequestedByOffRoute",
46 | @"onLocationChanged",
47 | @"onRawLocationChanged",
48 | @"logDebugInfo",
49 | ];
50 | }
51 |
52 | // Will be called when this module's first listener is added.
53 | - (void)startObserving {
54 | hasListeners = YES;
55 | // Set up any upstream listeners or background tasks as necessary
56 | }
57 |
58 | // Will be called when this module's last listener is removed, or on dealloc.
59 | - (void)stopObserving {
60 | hasListeners = NO;
61 | // Remove upstream listeners, stop unnecessary background tasks
62 | }
63 |
64 | - (bool)hasListeners {
65 | return hasListeners;
66 | }
67 |
68 | - (void)sendEventName:(NSString *)eventName body:(id)body {
69 | if (hasListeners) {
70 | [self sendEventWithName:eventName body:body];
71 | } else {
72 | NSLog(@"NavEventDispatcher sendEventName called without listeners: %@", eventName);
73 | }
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import groovy.json.JsonSlurper
16 |
17 | buildscript {
18 | ext.kotlin_version = '2.1.21'
19 | repositories {
20 | google()
21 | mavenCentral()
22 | }
23 |
24 | dependencies {
25 | classpath "com.android.tools.build:gradle:8.7.2"
26 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
27 | }
28 | }
29 |
30 | def isNewArchitectureEnabled() {
31 | return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
32 | }
33 |
34 | apply plugin: 'com.android.library'
35 |
36 | if (isNewArchitectureEnabled()) {
37 | apply plugin: "com.facebook.react"
38 | }
39 |
40 | android {
41 | namespace "com.google.android.react.navsdk"
42 | compileSdkVersion 35
43 |
44 | compileOptions {
45 | sourceCompatibility JavaVersion.VERSION_1_8
46 | targetCompatibility JavaVersion.VERSION_1_8
47 | }
48 |
49 | defaultConfig {
50 | minSdkVersion 24
51 | targetSdkVersion 36
52 | }
53 |
54 | buildFeatures {
55 | buildConfig true
56 | }
57 |
58 | buildTypes {
59 | release {
60 | minifyEnabled true
61 | }
62 | }
63 |
64 | lintOptions {
65 | abortOnError false
66 | disable "GradleCompatible"
67 | }
68 |
69 | compileOptions {
70 | sourceCompatibility JavaVersion.VERSION_1_8
71 | targetCompatibility JavaVersion.VERSION_1_8
72 | }
73 | }
74 |
75 | repositories {
76 | google()
77 | mavenCentral()
78 | }
79 |
80 | dependencies {
81 | implementation 'com.facebook.react:react-native:+'
82 | implementation "androidx.car.app:app:1.4.0"
83 | implementation "androidx.car.app:app-projected:1.4.0"
84 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
85 | implementation "com.google.android.libraries.navigation:navigation:7.1.0"
86 | api 'com.google.guava:guava:31.0.1-android'
87 | }
88 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/NavView.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import
18 | #import
19 | #import
20 | #import "CustomTypes.h"
21 | #import "INavigationViewCallback.h"
22 |
23 | @class NavViewController;
24 |
25 | @interface NavView : UIView
26 |
27 | @property(nonatomic, copy) RCTDirectEventBlock onRecenterButtonClick;
28 | @property(nonatomic, copy) RCTDirectEventBlock onMapReady;
29 | @property(nonatomic, copy) RCTDirectEventBlock onMapClick;
30 | @property(nonatomic, copy) RCTDirectEventBlock onMarkerInfoWindowTapped;
31 | @property(nonatomic, copy) RCTDirectEventBlock onMarkerClick;
32 | @property(nonatomic, copy) RCTDirectEventBlock onPolylineClick;
33 | @property(nonatomic, copy) RCTDirectEventBlock onPolygonClick;
34 | @property(nonatomic, copy) RCTDirectEventBlock onCircleClick;
35 | @property(nonatomic, copy) RCTDirectEventBlock onGroundOverlayClick;
36 | @property(nonatomic, copy) RCTDirectEventBlock onPromptVisibilityChanged;
37 |
38 | // Cleanup block that will be called when the view is removed from superview
39 | @property(nonatomic, copy) void (^cleanupBlock)(NSNumber *reactTag);
40 |
41 | - (NavViewController *)initializeViewControllerWithMapViewType:(MapViewType)mapViewType
42 | mapId:(NSString *)mapId
43 | stylingOptions:(NSDictionary *)stylingOptions
44 | mapColorScheme:(NSNumber *)colorScheme
45 | nightMode:(NSNumber *)nightMode;
46 |
47 | - (void)applyStylingOptions:(NSDictionary *)stylingOptions;
48 | - (void)applyMapColorScheme:(NSNumber *)colorScheme;
49 | - (void)applyNightMode:(NSNumber *)nightMode;
50 | - (NavViewController *)getViewController;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/sampleapp/MainApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.sampleapp;
18 |
19 | import android.app.Application;
20 | import androidx.annotation.NonNull;
21 | import com.facebook.react.PackageList;
22 | import com.facebook.react.ReactApplication;
23 | import com.facebook.react.ReactNativeApplicationEntryPoint;
24 | import com.facebook.react.ReactNativeHost;
25 | import com.facebook.react.ReactPackage;
26 | import com.facebook.react.defaults.DefaultReactNativeHost;
27 | import java.util.List;
28 |
29 | public class MainApplication extends Application implements ReactApplication {
30 |
31 | private final ReactNativeHost mReactNativeHost =
32 | new DefaultReactNativeHost(this) {
33 | @Override
34 | public boolean getUseDeveloperSupport() {
35 | return BuildConfig.DEBUG;
36 | }
37 |
38 | @NonNull
39 | @Override
40 | protected List getPackages() {
41 | @SuppressWarnings("UnnecessaryLocalVariable")
42 | List packages = new PackageList(this).getPackages();
43 | // Packages that cannot be autolinked yet can be added manually here, for example:
44 | // packages.add(new MyReactNativePackage());
45 | return packages;
46 | }
47 |
48 | @NonNull
49 | @Override
50 | protected String getJSMainModuleName() {
51 | return "index";
52 | }
53 |
54 | @Override
55 | protected boolean isNewArchEnabled() {
56 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
57 | }
58 | };
59 |
60 | @NonNull
61 | @Override
62 | public ReactNativeHost getReactNativeHost() {
63 | return mReactNativeHost;
64 | }
65 |
66 | @Override
67 | public void onCreate() {
68 | super.onCreate();
69 | ReactNativeApplicationEntryPoint.loadReactNative(this);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-navigation-sdk-sample",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-native start",
7 | "android": "react-native run-android",
8 | "android-release": "react-native run-android --mode release",
9 | "ios": "react-native run-ios",
10 | "ios:carplay": "react-native run-ios --scheme SampleAppCarPlay",
11 | "ios-release": "react-native run-ios --mode Release",
12 | "lint": "eslint .",
13 | "test": "jest",
14 | "build:android": "react-native build-android --extra-params \"--no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a\"",
15 | "build:ios": "react-native build-ios --mode Debug",
16 | "detox:build:ios-debug": "detox build --configuration ios.sim.debug",
17 | "detox:build:ios-release": "detox build --configuration ios.sim.release",
18 | "detox:build:android-debug": "detox build --configuration android.emu.debug",
19 | "detox:build:android-release": "detox build --configuration android.emu.release",
20 | "detox:test:ios-debug": "detox test --configuration ios.sim.debug",
21 | "detox:test:ios-release": "detox test --configuration ios.sim.release",
22 | "detox:test:android-debug": "detox test --configuration android.emu.debug",
23 | "detox:test:android-release": "detox test --configuration android.emu.release"
24 | },
25 | "dependencies": {
26 | "@react-navigation/native": "^6.1.18",
27 | "@react-navigation/stack": "^6.4.1",
28 | "react": "19.1.0",
29 | "react-native": "0.81.1",
30 | "react-native-gesture-handler": "2.25.0",
31 | "react-native-pager-view": "^6.9.1",
32 | "react-native-permissions": "^5.1.0",
33 | "react-native-safe-area-context": "^5.5.2",
34 | "react-native-screens": "4.15.4",
35 | "react-native-select-dropdown": "^4.0.1",
36 | "react-native-snackbar": "^2.8.0"
37 | },
38 | "devDependencies": {
39 | "@babel/core": "^7.25.2",
40 | "@babel/preset-env": "^7.25.3",
41 | "@babel/runtime": "^7.25.0",
42 | "@react-native-community/cli": "20.0.0",
43 | "@react-native-community/cli-platform-android": "20.0.0",
44 | "@react-native-community/cli-platform-ios": "20.0.0",
45 | "@react-native/babel-preset": "0.81.1",
46 | "@react-native/metro-config": "0.81.1",
47 | "@react-native/typescript-config": "0.81.1",
48 | "@types/jest": "^29.5.14",
49 | "@types/node": "^22.9.0",
50 | "detox": "^20.27.6",
51 | "jest": "^29.7.0",
52 | "react-native-builder-bob": "^0.40.13",
53 | "react-native-monorepo-config": "^0.1.9",
54 | "ts-jest": "^29.2.5"
55 | },
56 | "engines": {
57 | "node": ">=20"
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/navigation/navigation/NavigationProvider.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { createContext, type ReactNode, useContext } from 'react';
18 | import type {
19 | NavigationController,
20 | NavigationCallbacks,
21 | TermsAndConditionsDialogOptions,
22 | TaskRemovedBehavior,
23 | } from './types';
24 | import { useNavigationController } from './useNavigationController';
25 |
26 | interface NavigationContextProps {
27 | navigationController: NavigationController;
28 | addListeners: (listeners: Partial) => void;
29 | removeListeners: (listeners: Partial) => void;
30 | }
31 |
32 | const NavigationContext = createContext(
33 | undefined
34 | );
35 |
36 | interface NavigationProviderProps {
37 | termsAndConditionsDialogOptions: TermsAndConditionsDialogOptions;
38 | taskRemovedBehavior?: TaskRemovedBehavior;
39 | children: ReactNode;
40 | }
41 |
42 | export const NavigationProvider = ({
43 | termsAndConditionsDialogOptions,
44 | taskRemovedBehavior,
45 | children,
46 | }: NavigationProviderProps): React.JSX.Element => {
47 | const { navigationController, addListeners, removeListeners } =
48 | useNavigationController(
49 | termsAndConditionsDialogOptions,
50 | taskRemovedBehavior
51 | );
52 | return (
53 |
60 | {children}
61 |
62 | );
63 | };
64 |
65 | export const useNavigation = (): NavigationContextProps => {
66 | const context = useContext(NavigationContext);
67 | if (!context) {
68 | throw new Error('useNavigation must be used within a NavigationProvider');
69 | }
70 | const { navigationController, addListeners, removeListeners } = context;
71 |
72 | // Memoize the return value to ensure stable references
73 | return {
74 | navigationController,
75 | addListeners,
76 | removeListeners,
77 | };
78 | };
79 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | /**
16 | * Desugaring is required to be set on from navigation-sdk version 6.3.0 onwards.
17 | * Note that this enableDesugaring currently affects Detox testing with release builds.
18 | */
19 | def enableDesugaring = true
20 |
21 | buildscript {
22 | ext {
23 | buildToolsVersion = "36.0.0"
24 | minSdkVersion = 34
25 | compileSdkVersion = 36
26 | targetSdkVersion = 36
27 | ndkVersion = "27.1.12297006"
28 | }
29 | repositories {
30 | google()
31 | mavenCentral()
32 | }
33 | dependencies {
34 | classpath("com.android.tools.build:gradle")
35 | classpath("com.facebook.react:react-native-gradle-plugin")
36 | classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1")
37 | }
38 | }
39 |
40 | allprojects {
41 | repositories {
42 | maven {
43 | url("$rootDir/../node_modules/detox/Detox-android")
44 | }
45 | }
46 |
47 | // Required: you must exclude the Google Play service Maps SDK from
48 | // your transitive dependencies to make sure there won't be
49 | // multiple copies of Google Maps SDK in your binary, as the Navigation
50 | // SDK already bundles the Google Maps SDK.
51 | configurations {
52 | implementation {
53 | exclude group: 'com.google.android.gms', module: 'play-services-maps'
54 | }
55 | }
56 |
57 | subprojects {
58 | afterEvaluate { project ->
59 | if (project.hasProperty('android')) {
60 | android {
61 | compileOptions {
62 | coreLibraryDesugaringEnabled enableDesugaring
63 | }
64 | }
65 |
66 | dependencies {
67 | // Desugar Java 8+ APIs
68 | coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.3'
69 | }
70 | }
71 | }
72 | }
73 | }
74 |
75 | apply plugin: "com.facebook.react.rootproject"
76 |
--------------------------------------------------------------------------------
/example/e2e/shared.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { device, element, waitFor, by, expect, log } from 'detox';
18 |
19 | const NO_ERRORS_DETECTED_LABEL = 'No errors detected';
20 |
21 | export const agreeToTermsAndConditions = async () => {
22 | if (device.getPlatform() === 'ios') {
23 | await waitFor(element(by.text('OK')))
24 | .toBeVisible()
25 | .withTimeout(10000);
26 | await element(by.text('OK')).tap();
27 | } else if (device.getPlatform() === 'android') {
28 | await waitFor(element(by.text('GOT IT')))
29 | .toBeVisible()
30 | .withTimeout(10000);
31 | await element(by.text('GOT IT')).tap();
32 | }
33 | };
34 |
35 | export const waitForStepNumber = async number => {
36 | await waitFor(element(by.id('test_status_label')))
37 | .toHaveText(`Test status: Step #${number}`)
38 | .withTimeout(10000);
39 | };
40 |
41 | export const waitForTestToFinish = async (timeInMs = 60000) => {
42 | await expect(element(by.id('test_status_label'))).toExist();
43 | await waitFor(element(by.id('test_status_label')))
44 | .toHaveText(`Test status: Finished`)
45 | .withTimeout(timeInMs);
46 | };
47 |
48 | export const expectSuccess = async () => {
49 | await expect(element(by.id('test_result_label'))).toHaveText(
50 | 'Test result: Success'
51 | );
52 | };
53 |
54 | export async function expectNoErrors() {
55 | const failureMessageLabel = element(by.id('failure_message_label'));
56 | const attributes = await failureMessageLabel.getAttributes();
57 | if (attributes.text !== NO_ERRORS_DETECTED_LABEL) {
58 | log.error(attributes.text);
59 | }
60 | await expect(element(by.id('failure_message_label'))).toHaveText(
61 | NO_ERRORS_DETECTED_LABEL
62 | );
63 | }
64 |
65 | export const initializeIntegrationTestsPage = async () => {
66 | await device.launchApp({
67 | delete: true,
68 | permissions: { location: 'always' },
69 | });
70 | await element(by.id('integration_tests_button')).tap();
71 | };
72 |
73 | export const selectTestByName = async name => {
74 | await element(by.id('tests_menu_button')).tap();
75 | await element(by.id(name)).tap();
76 | };
77 |
--------------------------------------------------------------------------------
/src/navigation/navigationView/navigationViewController.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { commands, sendCommand } from '../../shared/viewManager';
17 | import type { CameraPerspective, NavigationViewController } from './types';
18 |
19 | export const getNavigationViewController = (
20 | viewId: number
21 | ): NavigationViewController => {
22 | return {
23 | setNavigationUIEnabled: (isOn: boolean) => {
24 | sendCommand(viewId, commands.setNavigationUIEnabled, [isOn]);
25 | },
26 |
27 | setTripProgressBarEnabled: (isOn: boolean) => {
28 | sendCommand(viewId, commands.setTripProgressBarEnabled, [isOn]);
29 | },
30 |
31 | setReportIncidentButtonEnabled: (isOn: boolean) => {
32 | sendCommand(viewId, commands.setReportIncidentButtonEnabled, [isOn]);
33 | },
34 |
35 | setSpeedometerEnabled: (isOn: boolean) => {
36 | sendCommand(viewId, commands.setSpeedometerEnabled, [isOn]);
37 | },
38 |
39 | setSpeedLimitIconEnabled: (isOn: boolean) => {
40 | sendCommand(viewId, commands.setSpeedLimitIconEnabled, [isOn]);
41 | },
42 |
43 | setTrafficIncidentCardsEnabled: (isOn: boolean) => {
44 | sendCommand(viewId, commands.setTrafficIncidentCardsEnabled, [isOn]);
45 | },
46 |
47 | setHeaderEnabled: (isOn: boolean) => {
48 | sendCommand(viewId, commands.setHeaderEnabled, [isOn]);
49 | },
50 |
51 | setFooterEnabled: (isOn: boolean) => {
52 | sendCommand(viewId, commands.setFooterEnabled, [isOn]);
53 | },
54 |
55 | showRouteOverview: () => {
56 | sendCommand(viewId, commands.showRouteOverview, []);
57 | },
58 |
59 | /**
60 | * @deprecated Prefer the `navigationNightMode` prop on `NavigationView`.
61 | */
62 | setNightMode: (index: number) => {
63 | sendCommand(viewId, commands.setNightMode, [index]);
64 | },
65 |
66 | setRecenterButtonEnabled(isEnabled: boolean) {
67 | sendCommand(viewId, commands.setRecenterButtonEnabled, [isEnabled]);
68 | },
69 |
70 | setFollowingPerspective: (perspective: CameraPerspective) => {
71 | sendCommand(viewId, commands.setFollowingPerspective, [perspective]);
72 | },
73 | };
74 | };
75 |
--------------------------------------------------------------------------------
/example/ios/SampleAppTests/SampleAppTests.m:
--------------------------------------------------------------------------------
1 | // Copyright 2023 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 | #import
17 |
18 | #import
19 | #import
20 |
21 | #define TIMEOUT_SECONDS 600
22 | #define TEXT_TO_LOOK_FOR @"Welcome to React"
23 |
24 | @interface SampleAppTests : XCTestCase
25 |
26 | @end
27 |
28 | @implementation SampleAppTests
29 |
30 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
31 | {
32 | if (test(view)) {
33 | return YES;
34 | }
35 | for (UIView *subview in [view subviews]) {
36 | if ([self findSubviewInView:subview matching:test]) {
37 | return YES;
38 | }
39 | }
40 | return NO;
41 | }
42 |
43 | - (void)testRendersWelcomeScreen
44 | {
45 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
46 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
47 | BOOL foundElement = NO;
48 |
49 | __block NSString *redboxError = nil;
50 | #ifdef DEBUG
51 | RCTSetLogFunction(
52 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
53 | if (level >= RCTLogLevelError) {
54 | redboxError = message;
55 | }
56 | });
57 | #endif
58 |
59 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
60 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
61 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
62 |
63 | foundElement = [self findSubviewInView:vc.view
64 | matching:^BOOL(UIView *view) {
65 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
66 | return YES;
67 | }
68 | return NO;
69 | }];
70 | }
71 |
72 | #ifdef DEBUG
73 | RCTSetLogFunction(RCTDefaultLogFunction);
74 | #endif
75 |
76 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
77 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/example/src/controls/ExampleAppButton.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2025 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import { Pressable, Text, StyleSheet } from 'react-native';
19 | import { Colors, BorderRadius, Typography, Spacing } from '../styles/theme';
20 |
21 | type ExampleAppButtonProps = {
22 | title: string;
23 | onPress: () => void;
24 | backgroundColor?: string;
25 | pressedBackgroundColor?: string;
26 | textColor?: string;
27 | disabled?: boolean;
28 | testID?: string;
29 | };
30 |
31 | export const ExampleAppButton = ({
32 | title,
33 | onPress,
34 | backgroundColor,
35 | pressedBackgroundColor: pressedColor,
36 | textColor: textColor,
37 | disabled = false,
38 | testID,
39 | }: ExampleAppButtonProps) => {
40 | const resolvedBackground = disabled
41 | ? Colors.buttonDisabled
42 | : (backgroundColor ?? Colors.button);
43 | const resolvedPressed = disabled
44 | ? Colors.buttonDisabled
45 | : (pressedColor ?? Colors.buttonPressed);
46 | const resolvedTextColor = disabled
47 | ? Colors.textDisabled
48 | : (textColor ?? Colors.buttonText);
49 |
50 | return (
51 | [
59 | styles.buttonBase,
60 | {
61 | backgroundColor:
62 | pressed && !disabled ? resolvedPressed : resolvedBackground,
63 | },
64 | disabled && styles.buttonDisabled,
65 | ]}
66 | >
67 |
75 | {title}
76 |
77 |
78 | );
79 | };
80 |
81 | const styles = StyleSheet.create({
82 | buttonBase: {
83 | paddingVertical: Spacing.md,
84 | paddingHorizontal: Spacing.lg,
85 | borderRadius: BorderRadius.lg,
86 | alignItems: 'center',
87 | marginVertical: Spacing.xs,
88 | },
89 | buttonText: {
90 | fontWeight: Typography.fontWeight.semibold,
91 | fontSize: Typography.fontSize.md,
92 | },
93 | buttonDisabled: {
94 | opacity: 0.6,
95 | },
96 | });
97 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2025 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | module.exports = {
18 | root: true,
19 | parser: '@typescript-eslint/parser',
20 | parserOptions: {
21 | ecmaVersion: 'latest',
22 | sourceType: 'module',
23 | ecmaFeatures: {
24 | jsx: true,
25 | },
26 | },
27 | env: {
28 | 'es2021': true,
29 | 'node': true,
30 | 'react-native/react-native': true,
31 | },
32 | plugins: [
33 | '@typescript-eslint',
34 | 'react',
35 | 'react-hooks',
36 | 'react-native',
37 | 'import',
38 | 'prettier',
39 | ],
40 | extends: [
41 | 'eslint:recommended',
42 | 'plugin:@typescript-eslint/recommended',
43 | 'plugin:react/recommended',
44 | 'plugin:react-hooks/recommended',
45 | 'plugin:react-native/all',
46 | 'plugin:import/errors',
47 | 'plugin:import/warnings',
48 | 'plugin:import/typescript',
49 | 'plugin:prettier/recommended',
50 | ],
51 | rules: {
52 | 'prettier/prettier': 'warn',
53 | 'react/react-in-jsx-scope': 'off',
54 | 'react-native/no-inline-styles': 'off',
55 | 'react-native/sort-styles': 'off',
56 | 'react-native/no-color-literals': 'off',
57 | 'react-hooks/rules-of-hooks': 'error',
58 | 'react-hooks/exhaustive-deps': 'warn',
59 | '@typescript-eslint/explicit-module-boundary-types': 'warn',
60 | '@typescript-eslint/no-explicit-any': 'error',
61 | '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], // Allow unused vars starting with _
62 | 'import/default': 'off', // Disable for now due to react-native-select-dropdown issues
63 | },
64 | settings: {
65 | 'react': {
66 | version: 'detect',
67 | },
68 | 'import/resolver': {
69 | typescript: {},
70 | },
71 | },
72 | overrides: [
73 | // Configuration files can use require()
74 | {
75 | files: ['**/*.config.js', '**/babel.config.js'],
76 | rules: {
77 | '@typescript-eslint/no-require-imports': 'off',
78 | },
79 | },
80 | // Test files
81 | {
82 | files: ['**/*.test.js', '**/*.test.ts', '**/e2e/**/*.js'],
83 | env: {
84 | jest: true,
85 | },
86 | rules: {
87 | '@typescript-eslint/explicit-module-boundary-types': 'off',
88 | },
89 | },
90 | // Example directory - less strict for demo code
91 | {
92 | files: ['example/**/*'],
93 | rules: {
94 | '@typescript-eslint/explicit-module-boundary-types': 'off',
95 | },
96 | },
97 | ],
98 | };
99 |
--------------------------------------------------------------------------------
/ios/react-native-navigation-sdk/UIColor+Util.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "UIColor+Util.h"
18 |
19 | @implementation UIColor (HexString)
20 |
21 | + (UIColor *)colorWithHexString:(NSString *)hexString {
22 | NSString *colorString = [[hexString stringByReplacingOccurrencesOfString:@"#"
23 | withString:@""] uppercaseString];
24 | CGFloat alpha, red, blue, green;
25 |
26 | switch ([colorString length]) {
27 | case 3: // #RGB
28 | alpha = 1.0f;
29 | red = [self colorComponentFrom:colorString start:0 length:1];
30 | green = [self colorComponentFrom:colorString start:1 length:1];
31 | blue = [self colorComponentFrom:colorString start:2 length:1];
32 | break;
33 | case 4: // #ARGB
34 | alpha = [self colorComponentFrom:colorString start:0 length:1];
35 | red = [self colorComponentFrom:colorString start:1 length:1];
36 | green = [self colorComponentFrom:colorString start:2 length:1];
37 | blue = [self colorComponentFrom:colorString start:3 length:1];
38 | break;
39 | case 6: // #RRGGBB
40 | alpha = 1.0f;
41 | red = [self colorComponentFrom:colorString start:0 length:2];
42 | green = [self colorComponentFrom:colorString start:2 length:2];
43 | blue = [self colorComponentFrom:colorString start:4 length:2];
44 | break;
45 | case 8: // #AARRGGBB
46 | alpha = [self colorComponentFrom:colorString start:0 length:2];
47 | red = [self colorComponentFrom:colorString start:2 length:2];
48 | green = [self colorComponentFrom:colorString start:4 length:2];
49 | blue = [self colorComponentFrom:colorString start:6 length:2];
50 | break;
51 | default:
52 | [NSException raise:@"Invalid color value"
53 | format:@"Color value %@ is invalid. It should be a hex value of the form #RBG, "
54 | @"#ARGB, #RRGGBB, or #AARRGGBB",
55 | hexString];
56 | break;
57 | }
58 | return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
59 | }
60 |
61 | #pragma mark - Helper Methods
62 | + (CGFloat)colorComponentFrom:(NSString *)string start:(NSUInteger)start length:(NSUInteger)length {
63 | NSString *substring = [string substringWithRange:NSMakeRange(start, length)];
64 | NSString *fullHex =
65 | length == 2 ? substring : [NSString stringWithFormat:@"%@%@", substring, substring];
66 | unsigned hexComponent;
67 | [[NSScanner scannerWithString:fullHex] scanHexInt:&hexComponent];
68 | return hexComponent / 255.0;
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/example/e2e/navigation.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {
18 | initializeIntegrationTestsPage,
19 | agreeToTermsAndConditions,
20 | selectTestByName,
21 | waitForTestToFinish,
22 | expectSuccess,
23 | expectNoErrors,
24 | } from './shared.js';
25 |
26 | describe('Navigation tests', () => {
27 | beforeEach(async () => {
28 | await initializeIntegrationTestsPage();
29 | });
30 |
31 | it('T01 - initialize navigation controller and test terms and conditions (TOS) dialog acceptance', async () => {
32 | await selectTestByName('testNavigationSessionInitialization');
33 | await agreeToTermsAndConditions();
34 | await waitForTestToFinish();
35 | await expectNoErrors();
36 | await expectSuccess();
37 | });
38 |
39 | it('T02 - initialize navigation controller and navigate to single destination', async () => {
40 | await selectTestByName('testNavigationToSingleDestination');
41 | await agreeToTermsAndConditions();
42 | await waitForTestToFinish();
43 | await expectNoErrors();
44 | await expectSuccess();
45 | });
46 |
47 | it('T03 - initialize navigation controller and navigate to multiple destinations', async () => {
48 | await selectTestByName('testNavigationToMultipleDestination');
49 | await agreeToTermsAndConditions();
50 | await waitForTestToFinish();
51 | await expectNoErrors();
52 | await expectSuccess();
53 | });
54 |
55 | it('T04 - initialize navigation controller and test route segments', async () => {
56 | await selectTestByName('testRouteSegments');
57 | await agreeToTermsAndConditions();
58 | await waitForTestToFinish();
59 | await expectNoErrors();
60 | await expectSuccess();
61 | });
62 |
63 | it('T05 - initialize navigation controller and test remaining time and distance', async () => {
64 | await selectTestByName('testGetCurrentTimeAndDistance');
65 | await agreeToTermsAndConditions();
66 | await waitForTestToFinish();
67 | await expectNoErrors();
68 | await expectSuccess();
69 | });
70 |
71 | it('T06 - expect navigation controller calls to fail when not initialized', async () => {
72 | await selectTestByName('testNavigationStateGuards');
73 | await waitForTestToFinish();
74 | await expectNoErrors();
75 | await expectSuccess();
76 | });
77 |
78 | it('T07 - require destinations before starting guidance', async () => {
79 | await selectTestByName('testStartGuidanceWithoutDestinations');
80 | await agreeToTermsAndConditions();
81 | await waitForTestToFinish();
82 | await expectNoErrors();
83 | await expectSuccess();
84 | });
85 | });
86 |
--------------------------------------------------------------------------------
/example/src/styles/theme.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2025 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export const Colors = {
18 | // Primary colors
19 | primary: '#2196F3',
20 | primaryDark: '#1976D2',
21 | primaryLight: '#BBDEFB',
22 |
23 | // Background colors
24 | background: '#f5f5f5',
25 | surface: '#ffffff',
26 | surfaceVariant: '#f8f9fa',
27 |
28 | // Text colors
29 | text: '#333333',
30 | textSecondary: '#666666',
31 | textDisabled: '#999999',
32 |
33 | // Status colors
34 | success: '#4CAF50',
35 | warning: '#FF9800',
36 | error: '#d32f2f',
37 | info: '#2196F3',
38 |
39 | // Border colors
40 | border: '#dddddd',
41 | borderLight: '#eeeeee',
42 |
43 | // Interactive colors
44 | button: '#2196f3',
45 | buttonPressed: '#1c89e1ff',
46 | buttonDisabled: '#cccccc',
47 | buttonText: '#ffffff',
48 |
49 | // Dropdown selection colors
50 | dropdownSelected: '#D2D9DF',
51 |
52 | // Navigation map view -specific colors
53 | mapStyling: {
54 | primaryDay: '#0076a8',
55 | primaryNight: '#3400a8',
56 | secondaryDay: '#0076a8',
57 | secondaryNight: '#3400a8',
58 | accent: '#f65308',
59 | },
60 | } as const;
61 |
62 | export const Spacing = {
63 | xs: 4,
64 | sm: 8,
65 | md: 12,
66 | lg: 16,
67 | xl: 20,
68 | xxl: 24,
69 | xxxl: 32,
70 | } as const;
71 |
72 | export const BorderRadius = {
73 | sm: 4,
74 | md: 8,
75 | lg: 12,
76 | xl: 16,
77 | } as const;
78 |
79 | export const Typography = {
80 | // Font sizes
81 | fontSize: {
82 | xs: 12,
83 | sm: 14,
84 | md: 16,
85 | lg: 18,
86 | xl: 20,
87 | xxl: 24,
88 | xxxl: 28,
89 | },
90 | // Font weights
91 | fontWeight: {
92 | normal: '400' as const,
93 | medium: '500' as const,
94 | semibold: '600' as const,
95 | bold: '700' as const,
96 | },
97 | // Line heights
98 | lineHeight: {
99 | tight: 1.2,
100 | normal: 1.4,
101 | relaxed: 1.6,
102 | },
103 | } as const;
104 |
105 | export const Shadows = {
106 | small: {
107 | shadowColor: '#000',
108 | shadowOffset: { width: 0, height: 1 },
109 | shadowOpacity: 0.1,
110 | shadowRadius: 2,
111 | elevation: 1,
112 | },
113 | medium: {
114 | shadowColor: '#000',
115 | shadowOffset: { width: 0, height: 2 },
116 | shadowOpacity: 0.1,
117 | shadowRadius: 4,
118 | elevation: 2,
119 | },
120 | large: {
121 | shadowColor: '#000',
122 | shadowOffset: { width: 0, height: 4 },
123 | shadowOpacity: 0.15,
124 | shadowRadius: 8,
125 | elevation: 4,
126 | },
127 | } as const;
128 |
--------------------------------------------------------------------------------
/example/ios/SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
10 |
16 |
22 |
23 |
24 |
25 |
26 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/example/.detoxrc.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /** @type {Detox.DetoxConfig} */
18 | module.exports = {
19 | testRunner: {
20 | args: {
21 | $0: 'jest',
22 | config: 'e2e/jest.config.js',
23 | },
24 | jest: {
25 | setupTimeout: 120000,
26 | },
27 | },
28 | apps: {
29 | 'ios.debug': {
30 | type: 'ios.app',
31 | binaryPath:
32 | 'ios/build/Build/Products/Debug-iphonesimulator/SampleApp.app',
33 | build:
34 | 'xcodebuild -workspace ios/SampleApp.xcworkspace -scheme SampleApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build',
35 | },
36 | 'ios.release': {
37 | type: 'ios.app',
38 | binaryPath:
39 | 'ios/build/Build/Products/Release-iphonesimulator/SampleApp.app',
40 | build:
41 | 'xcodebuild -workspace ios/SampleApp.xcworkspace -scheme SampleApp -configuration Release -sdk iphonesimulator -derivedDataPath ios/build',
42 | },
43 | 'android.debug': {
44 | type: 'android.apk',
45 | binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk',
46 | build:
47 | 'cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
48 | reversePorts: [8081],
49 | },
50 | 'android.release': {
51 | type: 'android.apk',
52 | binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
53 | build:
54 | 'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
55 | },
56 | },
57 | devices: {
58 | simulator: {
59 | type: 'ios.simulator',
60 | device: {
61 | type: 'iPhone 16 Pro',
62 | os: 'iOS 18.6',
63 | },
64 | },
65 | attached: {
66 | type: 'android.attached',
67 | device: {
68 | adbName: '.*',
69 | },
70 | },
71 | emulator: {
72 | type: 'android.emulator',
73 | device: {
74 | avdName: 'Pixel_9_Pro_API_35',
75 | },
76 | },
77 | },
78 | configurations: {
79 | 'ios.sim.debug': {
80 | device: 'simulator',
81 | app: 'ios.debug',
82 | },
83 | 'ios.sim.release': {
84 | device: 'simulator',
85 | app: 'ios.release',
86 | },
87 | 'android.att.debug': {
88 | device: 'attached',
89 | app: 'android.debug',
90 | },
91 | 'android.att.release': {
92 | device: 'attached',
93 | app: 'android.release',
94 | },
95 | 'android.emu.debug': {
96 | device: 'emulator',
97 | app: 'android.debug',
98 | },
99 | 'android.emu.release': {
100 | device: 'emulator',
101 | app: 'android.release',
102 | },
103 | },
104 | };
105 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
70 |
71 |
74 |
75 |
78 |
79 |
--------------------------------------------------------------------------------
/example/ios/SampleApp/Info-CarPlay.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | samplenavsdk-carplay
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(CURRENT_PROJECT_VERSION)
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSExceptionDomains
30 |
31 | localhost
32 |
33 | NSExceptionAllowsInsecureHTTPLoads
34 |
35 |
36 |
37 |
38 | NSLocationAlwaysAndWhenInUseUsageDescription
39 | [Enter any description related to the key]
40 | NSLocationWhenInUseUsageDescription
41 | [Add your description here]
42 | UIApplicationSceneManifest
43 |
44 | UIApplicationSupportsMultipleScenes
45 |
46 | UISceneConfigurations
47 |
48 | CPTemplateApplicationSceneSessionRoleApplication
49 |
50 |
51 | UISceneClassName
52 | CPTemplateApplicationScene
53 | UISceneConfigurationName
54 | CarPlay
55 | UISceneDelegateClassName
56 | $(PRODUCT_MODULE_NAME).CarSceneDelegate
57 |
58 |
59 | UIWindowSceneSessionRoleApplication
60 |
61 |
62 | UISceneClassName
63 | UIWindowScene
64 | UISceneConfigurationName
65 | Phone
66 | UISceneDelegateClassName
67 | $(PRODUCT_MODULE_NAME).PhoneSceneDelegate
68 |
69 |
70 |
71 |
72 | UIBackgroundModes
73 |
74 | location
75 | audio
76 | remote-notification
77 | fetch
78 |
79 | UILaunchStoryboardName
80 | LaunchScreen
81 | UIRequiredDeviceCapabilities
82 |
83 | armv7
84 |
85 | UISupportedInterfaceOrientations
86 |
87 | UIInterfaceOrientationPortrait
88 | UIInterfaceOrientationLandscapeLeft
89 | UIInterfaceOrientationLandscapeRight
90 |
91 | UIViewControllerBasedStatusBarAppearance
92 |
93 | [NSLocationAlwaysUsageDescription]
94 | Enter any description related to the key
95 | [NSLocationWhenInUseUsageDescription]
96 | Enter any description related to the key
97 |
98 |
99 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/Command.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import androidx.annotation.NonNull;
17 |
18 | public enum Command {
19 | MOVE_CAMERA(2, "moveCamera"),
20 | SET_MY_LOCATION_ENABLED(3, "setMyLocationEnabled"),
21 | SET_TRIP_PROGRESS_BAR_ENABLED(4, "setTripProgressBarEnabled"),
22 | SET_NAVIGATION_UI_ENABLED(5, "setNavigationUIEnabled"),
23 | SET_FOLLOWING_PERSPECTIVE(6, "setFollowingPerspective"),
24 | SET_NIGHT_MODE(7, "setNightMode"),
25 | SET_SPEEDOMETER_ENABLED(9, "setSpeedometerEnabled"),
26 | SET_SPEED_LIMIT_ICON_ENABLED(10, "setSpeedLimitIconEnabled"),
27 | SET_ZOOM_LEVEL(11, "setZoomLevel"),
28 | SET_INDOOR_ENABLED(12, "setIndoorEnabled"),
29 | SET_TRAFFIC_ENABLED(13, "setTrafficEnabled"),
30 | SET_COMPASS_ENABLED(14, "setCompassEnabled"),
31 | SET_MY_LOCATION_BUTTON_ENABLED(15, "setMyLocationButtonEnabled"),
32 | SET_ROTATE_GESTURES_ENABLED(16, "setRotateGesturesEnabled"),
33 | SET_SCROLL_GESTURES_ENABLED(17, "setScrollGesturesEnabled"),
34 | SET_SCROLL_GESTURES_ENABLED_DURING_ROTATE_OR_ZOOM(
35 | 18, "setScrollGesturesEnabledDuringRotateOrZoom"),
36 | SET_TILT_GESTURES_ENABLED(19, "setTiltGesturesEnabled"),
37 | SET_ZOOM_GESTURES_ENABLED(20, "setZoomGesturesEnabled"),
38 | SET_BUILDINGS_ENABLED(21, "setBuildingsEnabled"),
39 | SET_MAP_TYPE(22, "setMapType"),
40 | SET_MAP_TOOLBAR_ENABLED(23, "setMapToolbarEnabled"),
41 | CLEAR_MAP_VIEW(24, "clearMapView"),
42 | RESET_MIN_MAX_ZOOM_LEVEL(25, "resetMinMaxZoomLevel"),
43 | SET_MAP_STYLE(26, "setMapStyle"),
44 | ANIMATE_CAMERA(27, "animateCamera"),
45 | SHOW_ROUTE_OVERVIEW(28, "showRouteOverview"),
46 | SET_TRAFFIC_INCIDENT_CARDS_ENABLED(29, "setTrafficIncidentCardsEnabled"),
47 | SET_FOOTER_ENABLED(30, "setFooterEnabled"),
48 | SET_HEADER_ENABLED(31, "setHeaderEnabled"),
49 | REMOVE_MARKER(32, "removeMarker"),
50 | REMOVE_POLYLINE(33, "removePolyline"),
51 | REMOVE_POLYGON(34, "removePolygon"),
52 | REMOVE_CIRCLE(35, "removeCircle"),
53 | REMOVE_GROUND_OVERLAY(36, "removeGroundOverlay"),
54 | SET_ZOOM_CONTROLS_ENABLED(37, "setZoomControlsEnabled"),
55 | SET_RECENTER_BUTTON_ENABLED(38, "setRecenterButtonEnabled"),
56 | SET_PADDING(39, "setPadding"),
57 | SET_REPORT_INCIDENT_BUTTON_ENABLED(40, "setReportIncidentButtonEnabled");
58 |
59 | private final int value;
60 | private final String name;
61 |
62 | Command(int value, String name) {
63 | this.value = value;
64 | this.name = name;
65 | }
66 |
67 | public int getValue() {
68 | return value;
69 | }
70 |
71 | @NonNull
72 | public String toString() {
73 | return this.name;
74 | }
75 |
76 | public static Command find(int value) {
77 | for (Command i : Command.values()) {
78 | if (i.value == value) return i;
79 | }
80 | return null;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/example/src/helpers/overlayModal.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { type ReactNode } from 'react';
18 | import { View, Modal, StyleSheet, Pressable, ScrollView } from 'react-native';
19 | import { ExampleAppButton } from '../controls/ExampleAppButton';
20 |
21 | interface OverlayModalProps {
22 | visible: boolean;
23 | closeOverlay: () => void;
24 | children: ReactNode;
25 | height?: number;
26 | }
27 |
28 | const OverlayModal: React.FC = ({
29 | visible,
30 | closeOverlay,
31 | children,
32 | height: height,
33 | }) => {
34 | const modalContentStyle = [
35 | styles.modalContent,
36 | height != null ? { height } : null,
37 | ];
38 |
39 | return (
40 |
46 |
47 |
48 |
49 |
55 | {children}
56 |
57 |
58 |
63 |
64 |
65 |
66 |
67 | );
68 | };
69 |
70 | const styles = StyleSheet.create({
71 | overlay: {
72 | flex: 1,
73 | justifyContent: 'flex-end',
74 | },
75 | overlayTouchable: {
76 | ...StyleSheet.absoluteFillObject,
77 | },
78 | modalContent: {
79 | height: '60%',
80 | backgroundColor: '#fff',
81 | borderTopLeftRadius: 10,
82 | borderTopRightRadius: 10,
83 | shadowColor: '#000',
84 | shadowOffset: {
85 | width: 0,
86 | height: 2,
87 | },
88 | shadowOpacity: 0.25,
89 | shadowRadius: 4,
90 | elevation: 5,
91 | padding: 20,
92 | },
93 | scrollContainer: {
94 | flexGrow: 1,
95 | },
96 | scrollContentContainer: {
97 | flexGrow: 1,
98 | minHeight: '100%',
99 | },
100 | scrollContent: {
101 | flex: 1,
102 | },
103 | closeButtonContainer: {
104 | marginTop: 8,
105 | shadowColor: '#000',
106 | shadowOffset: {
107 | width: 0,
108 | height: -2,
109 | },
110 | shadowOpacity: 0.15,
111 | shadowRadius: 4,
112 | elevation: 4,
113 | },
114 | });
115 |
116 | export default OverlayModal;
117 |
--------------------------------------------------------------------------------
/example/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.7)
5 | base64
6 | nkf
7 | rexml
8 | activesupport (7.2.2.2)
9 | base64
10 | benchmark (>= 0.3)
11 | bigdecimal
12 | concurrent-ruby (~> 1.0, >= 1.3.1)
13 | connection_pool (>= 2.2.5)
14 | drb
15 | i18n (>= 1.6, < 2)
16 | logger (>= 1.4.2)
17 | minitest (>= 5.1)
18 | securerandom (>= 0.3)
19 | tzinfo (~> 2.0, >= 2.0.5)
20 | addressable (2.8.7)
21 | public_suffix (>= 2.0.2, < 7.0)
22 | algoliasearch (1.27.5)
23 | httpclient (~> 2.8, >= 2.8.3)
24 | json (>= 1.5.1)
25 | atomos (0.1.3)
26 | base64 (0.3.0)
27 | benchmark (0.4.1)
28 | bigdecimal (3.2.2)
29 | claide (1.1.0)
30 | cocoapods (1.15.2)
31 | addressable (~> 2.8)
32 | claide (>= 1.0.2, < 2.0)
33 | cocoapods-core (= 1.15.2)
34 | cocoapods-deintegrate (>= 1.0.3, < 2.0)
35 | cocoapods-downloader (>= 2.1, < 3.0)
36 | cocoapods-plugins (>= 1.0.0, < 2.0)
37 | cocoapods-search (>= 1.0.0, < 2.0)
38 | cocoapods-trunk (>= 1.6.0, < 2.0)
39 | cocoapods-try (>= 1.1.0, < 2.0)
40 | colored2 (~> 3.1)
41 | escape (~> 0.0.4)
42 | fourflusher (>= 2.3.0, < 3.0)
43 | gh_inspector (~> 1.0)
44 | molinillo (~> 0.8.0)
45 | nap (~> 1.0)
46 | ruby-macho (>= 2.3.0, < 3.0)
47 | xcodeproj (>= 1.23.0, < 2.0)
48 | cocoapods-core (1.15.2)
49 | activesupport (>= 5.0, < 8)
50 | addressable (~> 2.8)
51 | algoliasearch (~> 1.0)
52 | concurrent-ruby (~> 1.1)
53 | fuzzy_match (~> 2.0.4)
54 | nap (~> 1.0)
55 | netrc (~> 0.11)
56 | public_suffix (~> 4.0)
57 | typhoeus (~> 1.0)
58 | cocoapods-deintegrate (1.0.5)
59 | cocoapods-downloader (2.1)
60 | cocoapods-plugins (1.0.0)
61 | nap
62 | cocoapods-search (1.0.1)
63 | cocoapods-trunk (1.6.0)
64 | nap (>= 0.8, < 2.0)
65 | netrc (~> 0.11)
66 | cocoapods-try (1.2.0)
67 | colored2 (3.1.2)
68 | concurrent-ruby (1.3.3)
69 | connection_pool (2.5.3)
70 | drb (2.2.3)
71 | escape (0.0.4)
72 | ethon (0.15.0)
73 | ffi (>= 1.15.0)
74 | ffi (1.17.2)
75 | fourflusher (2.3.1)
76 | fuzzy_match (2.0.4)
77 | gh_inspector (1.1.3)
78 | httpclient (2.9.0)
79 | mutex_m
80 | i18n (1.14.7)
81 | concurrent-ruby (~> 1.0)
82 | json (2.13.2)
83 | logger (1.7.0)
84 | minitest (5.25.5)
85 | molinillo (0.8.0)
86 | mutex_m (0.3.0)
87 | nanaimo (0.3.0)
88 | nap (1.1.0)
89 | netrc (0.11.0)
90 | nkf (0.2.0)
91 | public_suffix (4.0.7)
92 | rexml (3.4.2)
93 | ruby-macho (2.5.1)
94 | securerandom (0.4.1)
95 | typhoeus (1.5.0)
96 | ethon (>= 0.9.0, < 0.16.0)
97 | tzinfo (2.0.6)
98 | concurrent-ruby (~> 1.0)
99 | xcodeproj (1.25.1)
100 | CFPropertyList (>= 2.3.3, < 4.0)
101 | atomos (~> 0.1.3)
102 | claide (>= 1.0.2, < 2.0)
103 | colored2 (~> 3.1)
104 | nanaimo (~> 0.3.0)
105 | rexml (>= 3.3.6, < 4.0)
106 |
107 | PLATFORMS
108 | ruby
109 |
110 | DEPENDENCIES
111 | activesupport (>= 6.1.7.5, != 7.1.0)
112 | benchmark
113 | bigdecimal
114 | cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
115 | concurrent-ruby (< 1.3.4)
116 | logger
117 | mutex_m
118 | xcodeproj (< 1.26.0)
119 |
120 | RUBY VERSION
121 | ruby 3.2.2p53
122 |
123 | BUNDLED WITH
124 | 2.4.10
125 |
--------------------------------------------------------------------------------
/android/src/main/java/com/google/android/react/navsdk/NavInfoReceivingService.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 | * except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | *
http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | *
Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 | package com.google.android.react.navsdk;
15 |
16 | import android.app.Service;
17 | import android.content.Intent;
18 | import android.os.Handler;
19 | import android.os.HandlerThread;
20 | import android.os.IBinder;
21 | import android.os.Looper;
22 | import android.os.Message;
23 | import android.os.Messenger;
24 | import android.os.Process;
25 | import androidx.annotation.Nullable;
26 | import androidx.lifecycle.LiveData;
27 | import androidx.lifecycle.MutableLiveData;
28 | import com.google.android.libraries.mapsplatform.turnbyturn.TurnByTurnManager;
29 | import com.google.android.libraries.mapsplatform.turnbyturn.model.NavInfo;
30 |
31 | /**
32 | * Receives turn-by-turn navigation information forwarded from NavSDK and posts each update to live
33 | * data, which is then displayed on a separate header in {@code NavInfoDisplayFragment}. This
34 | * service may be part of a different process aside from the main process, depending on how you want
35 | * to structure your app. The service binding will be able to handle interprocess communication to
36 | * receive nav info messages from the main process.
37 | */
38 | public class NavInfoReceivingService extends Service {
39 | /** The messenger used by the service to receive nav step updates. */
40 | private Messenger mIncomingMessenger;
41 |
42 | /** Used to read incoming messages. */
43 | private TurnByTurnManager mTurnByTurnManager;
44 |
45 | private static final MutableLiveData mNavInfoMutableLiveData = new MutableLiveData<>();
46 |
47 | private final class IncomingNavStepHandler extends Handler {
48 | public IncomingNavStepHandler(Looper looper) {
49 | super(looper);
50 | }
51 |
52 | @Override
53 | public void handleMessage(Message msg) {
54 | if (TurnByTurnManager.MSG_NAV_INFO == msg.what) {
55 | // Read the nav info from the message data.
56 | NavInfo navInfo = mTurnByTurnManager.readNavInfoFromBundle(msg.getData());
57 | // Post the value to LiveData to be displayed in the nav info header.
58 | mNavInfoMutableLiveData.postValue(navInfo);
59 | }
60 | }
61 | }
62 |
63 | @Nullable
64 | @Override
65 | public IBinder onBind(Intent intent) {
66 | return mIncomingMessenger.getBinder();
67 | }
68 |
69 | @Override
70 | public boolean onUnbind(Intent intent) {
71 | mNavInfoMutableLiveData.postValue(null);
72 | return super.onUnbind(intent);
73 | }
74 |
75 | @Override
76 | public void onCreate() {
77 | mTurnByTurnManager = TurnByTurnManager.createInstance();
78 | HandlerThread thread =
79 | new HandlerThread("NavInfoReceivingService", Process.THREAD_PRIORITY_DEFAULT);
80 | thread.start();
81 | mIncomingMessenger = new Messenger(new IncomingNavStepHandler(thread.getLooper()));
82 | }
83 |
84 | public static LiveData getNavInfoLiveData() {
85 | return mNavInfoMutableLiveData;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/shared/viewManager.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {
18 | Platform,
19 | UIManager,
20 | requireNativeComponent,
21 | type HostComponent,
22 | type ViewProps,
23 | } from 'react-native';
24 | import type { LatLng } from '.';
25 | import type {
26 | Circle,
27 | MapColorScheme,
28 | GroundOverlay,
29 | Marker,
30 | Polygon,
31 | Polyline,
32 | } from '../maps';
33 | import type {
34 | DirectEventHandler,
35 | Int32,
36 | } from 'react-native/Libraries/Types/CodegenTypesNamespace';
37 | import type {
38 | AndroidStylingOptions,
39 | NavigationNightMode,
40 | iOSStylingOptions,
41 | } from '../navigation';
42 |
43 | // NavViewManager is responsible for managing both the regular map fragment as well as the navigation map view fragment.
44 | export const viewManagerName =
45 | Platform.OS === 'android' ? 'NavViewManager' : 'RCTNavView';
46 |
47 | export const sendCommand = (
48 | viewId: number,
49 | command: number | undefined,
50 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
51 | args?: any[]
52 | ): void => {
53 | if (command === undefined) {
54 | throw new Error(
55 | "Command not found, please make sure you're using the referencing the right method"
56 | );
57 | }
58 |
59 | try {
60 | UIManager.dispatchViewManagerCommand(
61 | viewId,
62 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
63 | Platform.OS === 'android' ? (command.toString() as any) : command,
64 | args
65 | );
66 | } catch (exception) {
67 | console.error(exception);
68 | }
69 | };
70 |
71 | interface ViewManagerConfig {
72 | Commands: { [key: string]: number };
73 | }
74 |
75 | export const commands = (
76 | UIManager.getViewManagerConfig(viewManagerName) as ViewManagerConfig
77 | ).Commands;
78 |
79 | export interface NativeNavViewProps extends ViewProps {
80 | flex?: number | undefined;
81 | mapOptions: {
82 | mapViewType: Int32;
83 | mapId?: string;
84 | navigationStylingOptions?: AndroidStylingOptions | iOSStylingOptions;
85 | mapColorScheme?: MapColorScheme;
86 | navigationNightMode?: NavigationNightMode;
87 | };
88 | onMapReady?: DirectEventHandler;
89 | onMapClick?: DirectEventHandler;
90 | onMarkerClick?: DirectEventHandler;
91 | onPolylineClick?: DirectEventHandler;
92 | onPolygonClick?: DirectEventHandler;
93 | onCircleClick?: DirectEventHandler;
94 | onGroundOverlayClick?: DirectEventHandler;
95 | onMarkerInfoWindowTapped?: DirectEventHandler;
96 | onRecenterButtonClick?: DirectEventHandler;
97 | onPromptVisibilityChanged?: DirectEventHandler<{ visible: boolean }>;
98 | }
99 |
100 | type NativeNavViewManagerComponentType = HostComponent;
101 | export const NavViewManager = requireNativeComponent(
102 | viewManagerName
103 | ) as NativeNavViewManagerComponentType;
104 |
--------------------------------------------------------------------------------