├── .npmrc ├── .husky └── pre-commit ├── plugin ├── android │ ├── .gitignore │ ├── src │ │ └── main │ │ │ ├── res │ │ │ └── .gitkeep │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── capacitorjs │ │ │ └── plugins │ │ │ └── googlemaps │ │ │ ├── CapacitorGoogleMapsStyleSpan.kt │ │ │ ├── CapacitorGoogleMapsPoint.kt │ │ │ ├── GoogleMapPadding.kt │ │ │ ├── CapacitorGoogleMapTileOverlay.kt │ │ │ ├── CapacitorGoogleMapsBounds.kt │ │ │ ├── CapacitorClusterManagerRenderer.kt │ │ │ ├── GoogleMapCameraConfig.kt │ │ │ └── CapacitorGoogleMapsCircle.kt │ ├── settings.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── proguard-rules.pro │ └── gradle.properties ├── e2e-tests │ ├── .npmrc │ ├── .env.example │ ├── android │ │ ├── app │ │ │ ├── .gitignore │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ ├── res │ │ │ │ │ │ ├── drawable │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── values │ │ │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ │ ├── drawable-land-hdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-mdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-xhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-hdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-mdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── drawable-land-xxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-xxxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xxxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── xml │ │ │ │ │ │ │ └── file_paths.xml │ │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ │ ├── layout │ │ │ │ │ │ │ └── activity_main.xml │ │ │ │ │ │ └── drawable-v24 │ │ │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ │ ├── java │ │ │ │ │ │ └── io │ │ │ │ │ │ │ └── ionic │ │ │ │ │ │ │ └── starter │ │ │ │ │ │ │ └── MainActivity.java │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── test │ │ │ │ │ └── java │ │ │ │ │ │ └── com │ │ │ │ │ │ └── getcapacitor │ │ │ │ │ │ └── myapp │ │ │ │ │ │ └── ExampleUnitTest.java │ │ │ │ └── androidTest │ │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── getcapacitor │ │ │ │ │ └── myapp │ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ ├── capacitor.build.gradle │ │ │ ├── proguard-rules.pro │ │ │ └── build.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── settings.gradle │ │ ├── variables.gradle │ │ ├── build.gradle │ │ ├── capacitor.settings.gradle │ │ ├── gradle.properties │ │ └── .gitignore │ ├── src │ │ ├── react-app-env.d.ts │ │ ├── App.test.tsx │ │ ├── pages │ │ │ ├── Home.tsx │ │ │ └── Map │ │ │ │ └── ResizeMap.tsx │ │ ├── reportWebVitals.ts │ │ ├── setupTests.ts │ │ ├── index.tsx │ │ ├── components │ │ │ ├── BaseTestingPage.tsx │ │ │ ├── Menu.tsx │ │ │ └── Menu.css │ │ └── App.tsx │ ├── ios │ │ ├── App │ │ │ ├── App │ │ │ │ ├── Assets.xcassets │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ │ ├── AppIcon-512@2x.png │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Splash.imageset │ │ │ │ │ │ ├── splash-2732x2732.png │ │ │ │ │ │ ├── splash-2732x2732-1.png │ │ │ │ │ │ ├── splash-2732x2732-2.png │ │ │ │ │ │ └── Contents.json │ │ │ │ ├── config.xml │ │ │ │ ├── capacitor.config.json │ │ │ │ ├── Base.lproj │ │ │ │ │ ├── Main.storyboard │ │ │ │ │ └── LaunchScreen.storyboard │ │ │ │ └── Info.plist │ │ │ ├── App.xcodeproj │ │ │ │ └── project.xcworkspace │ │ │ │ │ └── contents.xcworkspacedata │ │ │ ├── App.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── Podfile │ │ └── .gitignore │ ├── ionic.config.json │ ├── public │ │ ├── assets │ │ │ ├── icon │ │ │ │ ├── icon.png │ │ │ │ ├── pin.png │ │ │ │ ├── favicon.png │ │ │ │ └── marker.svg │ │ │ └── shapes.svg │ │ ├── manifest.json │ │ └── index.html │ ├── capacitor.config.json │ ├── scripts │ │ ├── build_local_package.sh │ │ ├── run_Android_E2E.sh │ │ └── create_E2E_AVD.sh │ ├── .ionic │ │ └── e2e.env │ ├── tests │ │ ├── pageobjects │ │ │ ├── basic-echo │ │ │ │ └── basic-echo.page.ts │ │ │ ├── map │ │ │ │ └── create-and-destroy.page.ts │ │ │ ├── markers │ │ │ │ ├── add-and-remove.page.ts │ │ │ │ ├── multiple-markers.page.ts │ │ │ │ └── marker-customization.page.ts │ │ │ └── page.ts │ │ └── specs │ │ │ ├── basic-echo │ │ │ └── basic-echo.spec.ts │ │ │ ├── map │ │ │ └── create-and-destroy.spec.ts │ │ │ └── markers │ │ │ └── add-and-remove.spec.ts │ ├── .gitignore │ ├── tsconfig.json │ ├── ionic.e2e.config.ts │ └── package.json ├── unit-tests │ ├── android │ │ ├── app │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ ├── res │ │ │ │ │ │ ├── values │ │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ │ ├── colors.xml │ │ │ │ │ │ │ └── themes.xml │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ │ ├── values-night │ │ │ │ │ │ │ └── themes.xml │ │ │ │ │ │ └── drawable-v24 │ │ │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ │ ├── java │ │ │ │ │ │ └── io │ │ │ │ │ │ │ └── ionic │ │ │ │ │ │ │ └── googlemapstest │ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ └── test │ │ │ │ │ └── java │ │ │ │ │ └── io │ │ │ │ │ └── ionic │ │ │ │ │ └── googlemapstest │ │ │ │ │ └── GoogleMapsUnitTests.kt │ │ │ ├── proguard-rules.pro │ │ │ └── build.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── settings.gradle │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── gradlew.bat │ └── ios │ │ └── GoogleMapsPlugin │ │ ├── TestApp │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── TestAppApp.swift │ │ ├── TestApp.entitlements │ │ └── ContentView.swift │ │ ├── GoogleMapsPlugin.xcodeproj │ │ └── project.xcworkspace │ │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── contents.xcworkspacedata │ │ └── GoogleMapsPluginTests │ │ └── GoogleMapsPluginTests.swift ├── ios │ ├── .gitignore │ ├── Sources │ │ └── CapacitorGoogleMapsPlugin │ │ │ ├── GoogleMapPadding.swift │ │ │ ├── TileOverlay.swift │ │ │ ├── GoogleMapCameraConfig.swift │ │ │ ├── GoogleMapErrors.swift │ │ │ ├── Circle.swift │ │ │ └── Polyline.swift │ └── Tests │ │ └── CapacitorGoogleMapsPluginTests │ │ └── CapacitorGoogleMapsTests.swift ├── src │ └── index.ts ├── tsconfig.json ├── rollup.config.js ├── CapacitorGoogleMaps.podspec ├── swiftlint.config.js ├── .gitignore ├── Package.swift └── eslint.config.cjs ├── example-app-spm ├── .npmrc ├── .env.example ├── ios │ ├── debug.xcconfig │ ├── App │ │ ├── CapApp-SPM │ │ │ ├── Sources │ │ │ │ └── CapApp-SPM │ │ │ │ │ └── CapApp-SPM.swift │ │ │ ├── README.md │ │ │ ├── .gitignore │ │ │ └── Package.swift │ │ ├── App │ │ │ ├── Assets.xcassets │ │ │ │ ├── Contents.json │ │ │ │ ├── Splash.imageset │ │ │ │ │ ├── splash-2732x2732.png │ │ │ │ │ ├── splash-2732x2732-1.png │ │ │ │ │ ├── splash-2732x2732-2.png │ │ │ │ │ └── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ ├── AppIcon-512@2x.png │ │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj │ │ │ │ ├── Main.storyboard │ │ │ │ └── LaunchScreen.storyboard │ │ │ └── Info.plist │ │ └── App.xcodeproj │ │ │ └── project.xcworkspace │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── .gitignore ├── public │ ├── assets │ │ ├── icon │ │ │ ├── pin.png │ │ │ ├── icon.png │ │ │ ├── favicon.png │ │ │ └── marker.svg │ │ └── shapes.svg │ ├── manifest.json │ └── index.html ├── ionic.config.json ├── capacitor.config.json ├── src │ ├── App.test.tsx │ ├── custom-elements.d.ts │ ├── react-app-env.d.ts │ ├── pages │ │ ├── Home.tsx │ │ └── Map │ │ │ └── ResizeMap.tsx │ ├── reportWebVitals.ts │ ├── setupTests.ts │ ├── components │ │ ├── BaseTestingPage.tsx │ │ ├── Menu.tsx │ │ └── Menu.css │ ├── index.tsx │ └── App.tsx ├── .gitignore ├── tsconfig.json ├── CHANGELOG.md └── package.json ├── pnpm-workspace.yaml ├── .gitignore ├── CHANGELOG.md ├── lerna.json ├── .github ├── workflows │ ├── basic-tests.yml │ ├── reusable_lint-packages.yml │ ├── reusable_setup.yml │ ├── bot.yml │ ├── needs-reply.yml │ ├── release-rc.yml │ ├── release.yml │ ├── release-dev.yml │ ├── release-from-prerelease.yml │ ├── dev-releases-for-pr.yml │ ├── reusable_verify-packages.yml │ └── reusable_release-npm.yml ├── ionic-issue-bot.yml ├── ISSUE_TEMPLATE │ ├── feature-request.md │ └── bug-report.md ├── bot.yml ├── OLD │ ├── docs-production.yml │ └── docs-preview.yml └── actions │ └── setup-tools │ └── action.yml ├── publish-ios.yml ├── scripts └── docgen_updates.js ├── publish-android.yml ├── package.json └── CONTRIBUTING.md /.npmrc: -------------------------------------------------------------------------------- 1 | provenance=false -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm run lint 2 | -------------------------------------------------------------------------------- /plugin/android/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /plugin/android/src/main/res/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example-app-spm/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false -------------------------------------------------------------------------------- /plugin/e2e-tests/.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false -------------------------------------------------------------------------------- /example-app-spm/.env.example: -------------------------------------------------------------------------------- 1 | REACT_APP_GOOGLE_MAPS_API_KEY= -------------------------------------------------------------------------------- /example-app-spm/ios/debug.xcconfig: -------------------------------------------------------------------------------- 1 | CAPACITOR_DEBUG = true 2 | -------------------------------------------------------------------------------- /plugin/e2e-tests/.env.example: -------------------------------------------------------------------------------- 1 | REACT_APP_GOOGLE_MAPS_API_KEY= -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | !/build/.npmkeep 3 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'plugin' 3 | - 'example-app-spm' -------------------------------------------------------------------------------- /plugin/e2e-tests/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/CapApp-SPM/Sources/CapApp-SPM/CapApp-SPM.swift: -------------------------------------------------------------------------------- 1 | public let isCapacitorApp = true 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | package-lock.json 4 | Podfile.lock 5 | Package.resolved 6 | .env 7 | test.sh -------------------------------------------------------------------------------- /plugin/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Google Maps Test 3 | -------------------------------------------------------------------------------- /example-app-spm/public/assets/icon/pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/example-app-spm/public/assets/icon/pin.png -------------------------------------------------------------------------------- /plugin/e2e-tests/ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "e2e-tests", 3 | "integrations": { 4 | "capacitor": {} 5 | }, 6 | "type": "react" 7 | } 8 | -------------------------------------------------------------------------------- /example-app-spm/ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-app-spm", 3 | "integrations": { 4 | "capacitor": {} 5 | }, 6 | "type": "react" 7 | } 8 | -------------------------------------------------------------------------------- /example-app-spm/public/assets/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/example-app-spm/public/assets/icon/icon.png -------------------------------------------------------------------------------- /plugin/e2e-tests/public/assets/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/public/assets/icon/icon.png -------------------------------------------------------------------------------- /plugin/e2e-tests/public/assets/icon/pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/public/assets/icon/pin.png -------------------------------------------------------------------------------- /example-app-spm/public/assets/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/example-app-spm/public/assets/icon/favicon.png -------------------------------------------------------------------------------- /plugin/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':capacitor-android' 2 | project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') -------------------------------------------------------------------------------- /plugin/e2e-tests/public/assets/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/public/assets/icon/favicon.png -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/TestApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /plugin/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /plugin/e2e-tests/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "io.ionic.starter", 3 | "appName": "e2e-tests", 4 | "webDir": "build", 5 | "bundledWebRuntime": false 6 | } 7 | -------------------------------------------------------------------------------- /plugin/e2e-tests/scripts/build_local_package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ../ && npm install && npm run pack-local 4 | cd ./e2e-tests && npm install ../capacitor-google-maps.tgz -------------------------------------------------------------------------------- /example-app-spm/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "com.capacitorjs.maps_spm", 3 | "appName": "example-app-spm", 4 | "webDir": "build", 5 | "bundledWebRuntime": false 6 | } 7 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /plugin/unit-tests/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/TestApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/.gitignore: -------------------------------------------------------------------------------- 1 | App/build 2 | App/Pods 3 | App/App/public 4 | DerivedData 5 | xcuserdata 6 | 7 | # Cordova plugins for Capacitor 8 | capacitor-cordova-ios-plugins 9 | 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-land-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-land-hdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-land-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-land-mdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-land-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-land-xhdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-port-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-port-hdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-port-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-port-mdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-port-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-port-xhdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/ios/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /Packages 3 | xcuserdata/ 4 | DerivedData/ 5 | .swiftpm/configuration/registries.json 6 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 7 | .netrc 8 | .DS_Store 9 | .build -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/java/io/ionic/starter/MainActivity.java: -------------------------------------------------------------------------------- 1 | package io.ionic.starter; 2 | 3 | import com.getcapacitor.BridgeActivity; 4 | 5 | public class MainActivity extends BridgeActivity {} 6 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-land-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-land-xxhdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-land-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-land-xxxhdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-port-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-port-xxhdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-port-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/drawable-port-xxxhdpi/splash.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example-app-spm/ios/App/CapApp-SPM/README.md: -------------------------------------------------------------------------------- 1 | # CapApp-SPM 2 | 3 | This SPM is used to host SPM dependencies for you Capacitor project 4 | 5 | Do not modify the contents of it or there may be unintended consequences. 6 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/unit-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/java/io/ionic/googlemapstest/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package io.ionic.googlemapstest 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | 5 | class MainActivity : AppCompatActivity() { 6 | } -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/capacitor-google-maps/HEAD/plugin/e2e-tests/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png -------------------------------------------------------------------------------- /plugin/unit-tests/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "Google Maps Test" 2 | include ':app' 3 | include ':capacitor-android' 4 | project(':capacitor-android').projectDir = new File('../../node_modules/@capacitor/android/capacitor') 5 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/CapApp-SPM/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include ':capacitor-cordova-android-plugins' 3 | project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') 4 | 5 | apply from: 'capacitor.settings.gradle' -------------------------------------------------------------------------------- /plugin/android/src/main/java/com/capacitorjs/plugins/googlemaps/CapacitorGoogleMapsStyleSpan.kt: -------------------------------------------------------------------------------- 1 | package com.capacitorjs.plugins.googlemaps 2 | 3 | import android.graphics.Color 4 | 5 | data class CapacitorGoogleMapsStyleSpan(val color: Int, val segments: Double?) 6 | -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/TestApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /example-app-spm/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders without crashing', () => { 6 | const { baseElement } = render(); 7 | expect(baseElement).toBeDefined(); 8 | }); 9 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders without crashing', () => { 6 | const { baseElement } = render(); 7 | expect(baseElement).toBeDefined(); 8 | }); 9 | -------------------------------------------------------------------------------- /example-app-spm/ios/.gitignore: -------------------------------------------------------------------------------- 1 | App/build 2 | App/Pods 3 | App/output 4 | App/App/public 5 | DerivedData 6 | xcuserdata 7 | 8 | # Cordova plugins for Capacitor 9 | capacitor-cordova-ios-plugins 10 | 11 | # Generated Config files 12 | App/App/capacitor.config.json 13 | App/App/config.xml 14 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Nov 19 08:06:49 PST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /example-app-spm/src/custom-elements.d.ts: -------------------------------------------------------------------------------- 1 | declare module "react" { 2 | namespace JSX { 3 | interface IntrinsicElements { 4 | "capacitor-google-map": React.DetailedHTMLProps< 5 | React.HTMLAttributes, 6 | HTMLElement 7 | >; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /example-app-spm/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare global { 4 | namespace JSX { 5 | interface IntrinsicElements { 6 | 'capacitor-google-map': React.DetailedHTMLProps, HTMLElement>; 7 | } 8 | } 9 | } 10 | 11 | export {}; 12 | -------------------------------------------------------------------------------- /plugin/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "io.ionic.starter", 3 | "appName": "e2e-tests", 4 | "webDir": "build", 5 | "bundledWebRuntime": false, 6 | "packageClassList": [ 7 | "AppPlugin", 8 | "CapacitorGoogleMapsPlugin", 9 | "HapticsPlugin", 10 | "KeyboardPlugin", 11 | "StatusBarPlugin" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon-512@2x.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | e2e-tests 4 | e2e-tests 5 | io.ionic.starter 6 | io.ionic.starter 7 | 8 | -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/TestApp/TestAppApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestAppApp.swift 3 | // TestApp 4 | // 5 | // Created by Joseph Pender on 11/18/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct TestAppApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon-512@2x.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/GoogleMapsPlugin.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/GoogleMapsPlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/TestApp/TestApp.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | keychain-access-groups 6 | 7 | $(AppIdentifierPrefix)io.ionic.TestApp 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": { 3 | "version": { 4 | "allowBranch": "main", 5 | "conventionalCommits": true, 6 | "createRelease": "github", 7 | "message": "chore(release): publish [skip ci]", 8 | "tagVersionPrefix": "" 9 | } 10 | }, 11 | "version": "independent", 12 | "npmClient": "pnpm", 13 | "$schema": "node_modules/lerna/schemas/lerna-schema.json" 14 | } 15 | -------------------------------------------------------------------------------- /plugin/e2e-tests/.ionic/e2e.env: -------------------------------------------------------------------------------- 1 | E2E_ANDROID_ACTIVITY=io.ionic.starter.MainActivity 2 | E2E_IOS_SIMULATOR_DEVICE_NAME=iPhone 13 Pro Max 3 | E2E_IOS_SIMULATOR_PLATFORM_VERSION=15.0 4 | E2E_IOS_DEVICE_NAME=iPhone 12 Pro Max 5 | E2E_IOS_DEVICE_PLATFORM_VERSION=15.2 6 | E2E_ANDROID_EMULATOR_DEVICE_NAME=e2eDevice 7 | E2E_ANDROID_EMULATOR_PLATFORM_VERSION=12 8 | E2E_ANDROID_DEVICE_NAME=G8X 9 | E2E_ANDROID_DEVICE_PLATFORM_VERSION=11 -------------------------------------------------------------------------------- /example-app-spm/src/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import BaseTestingPage from '../components/BaseTestingPage'; 2 | 3 | const Home: React.FC = () => { 4 | return ( 5 | 6 |

7 | Choose a testing page from the menu to get started! 8 |

9 |
10 | ); 11 | }; 12 | 13 | export default Home; 14 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import BaseTestingPage from '../components/BaseTestingPage'; 2 | 3 | const Home: React.FC = () => { 4 | return ( 5 | 6 |

7 | Choose a testing page from the menu to get started! 8 |

9 |
10 | ); 11 | }; 12 | 13 | export default Home; 14 | -------------------------------------------------------------------------------- /example-app-spm/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { onCLS, onINP, onFCP, onLCP, onTTFB, Metric } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: (metric: Metric) => void) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | onCLS(onPerfEntry); 6 | onINP(onPerfEntry); 7 | onFCP(onPerfEntry); 8 | onLCP(onPerfEntry); 9 | onTTFB(onPerfEntry); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/pageobjects/basic-echo/basic-echo.page.ts: -------------------------------------------------------------------------------- 1 | import { IonicButton, IonicInput } from '@ionic/e2e-components-ionic'; 2 | 3 | import Page from '../page'; 4 | 5 | class BasicEchoPage extends Page { 6 | get runEchoButton() { 7 | return new IonicButton('#runEchoButton'); 8 | } 9 | get commandOutputTextarea() { 10 | return new IonicInput('#commandOutput'); 11 | } 12 | } 13 | 14 | export default new BasicEchoPage(); 15 | -------------------------------------------------------------------------------- /.github/workflows/basic-tests.yml: -------------------------------------------------------------------------------- 1 | name: "Basic Tests" 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - 'synchronize' 7 | - 'opened' 8 | 9 | jobs: 10 | setup: 11 | uses: ./.github/workflows/reusable_setup.yml 12 | 13 | lint-test: 14 | needs: 'setup' 15 | uses: ./.github/workflows/reusable_lint-packages.yml 16 | 17 | verify-packages: 18 | needs: 'setup' 19 | uses: ./.github/workflows/reusable_verify-packages.yml 20 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-namespace */ 2 | import { LatLngBounds, MapType, Marker, Polygon, Circle, Polyline, StyleSpan } from './definitions'; 3 | import { GoogleMap } from './map'; 4 | 5 | export { GoogleMap, LatLngBounds, MapType, Marker, Polygon, Circle, Polyline, StyleSpan }; 6 | 7 | declare global { 8 | export namespace JSX { 9 | export interface IntrinsicElements { 10 | 'capacitor-google-map': any; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/TestApp/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // TestApp 4 | // 5 | // Created by Joseph Pender on 11/18/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | var body: some View { 12 | Text("Hello, world!") 13 | .padding() 14 | } 15 | } 16 | 17 | struct ContentView_Previews: PreviewProvider { 18 | static var previews: some View { 19 | ContentView() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example-app-spm/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | .vscode 21 | .idea 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # Optional eslint cache 28 | .eslintcache 29 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /example-app-spm/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | 7 | // Mock matchmedia 8 | window.matchMedia = window.matchMedia || function() { 9 | return { 10 | matches: false, 11 | addListener: function() {}, 12 | removeListener: function() {} 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | 7 | // Mock matchmedia 8 | window.matchMedia = window.matchMedia || function() { 9 | return { 10 | matches: false, 11 | addListener: function() {}, 12 | removeListener: function() {} 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /plugin/ios/Sources/CapacitorGoogleMapsPlugin/GoogleMapPadding.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Capacitor 3 | 4 | public struct GoogleMapPadding { 5 | let top: Float 6 | let bottom: Float 7 | let left: Float 8 | let right: Float 9 | 10 | init(fromJSObject: JSObject) throws { 11 | top = fromJSObject["top"] as? Float ?? 0 12 | bottom = fromJSObject["bottom"] as? Float ?? 0 13 | left = fromJSObject["left"] as? Float ?? 0 14 | right = fromJSObject["right"] as? Float ?? 0 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /example-app-spm/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Ionic App", 3 | "name": "My Ionic App", 4 | "icons": [ 5 | { 6 | "src": "assets/icon/favicon.png", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "assets/icon/icon.png", 12 | "type": "image/png", 13 | "sizes": "512x512", 14 | "purpose": "maskable" 15 | } 16 | ], 17 | "start_url": ".", 18 | "display": "standalone", 19 | "theme_color": "#ffffff", 20 | "background_color": "#ffffff" 21 | } 22 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | 14 | @Test 15 | public void addition_isCorrect() throws Exception { 16 | assertEquals(4, 2 + 2); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugin/e2e-tests/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Ionic App", 3 | "name": "My Ionic App", 4 | "icons": [ 5 | { 6 | "src": "assets/icon/favicon.png", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "assets/icon/icon.png", 12 | "type": "image/png", 13 | "sizes": "512x512", 14 | "purpose": "maskable" 15 | } 16 | ], 17 | "start_url": ".", 18 | "display": "standalone", 19 | "theme_color": "#ffffff", 20 | "background_color": "#ffffff" 21 | } 22 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "splash-2732x2732-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "splash-2732x2732-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "splash-2732x2732.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "splash-2732x2732-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "splash-2732x2732-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "splash-2732x2732.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /plugin/e2e-tests/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | .vscode 21 | .idea 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # Optional eslint cache 28 | .eslintcache 29 | 30 | .ionic/* 31 | !.ionic/e2e.env 32 | !.ionic/wdio.config.ts 33 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/pageobjects/map/create-and-destroy.page.ts: -------------------------------------------------------------------------------- 1 | import { IonicButton, IonicTextarea } from '@ionic/e2e-components-ionic'; 2 | 3 | import Page from '../page'; 4 | 5 | class CreateAndDestroyMapPage extends Page { 6 | get createMapButton() { 7 | return new IonicButton("#createMapButton"); 8 | } 9 | get destroyMapButton() { 10 | return new IonicButton("#destroyMapButton"); 11 | } 12 | get commandOutputTextarea() { 13 | return new IonicTextarea('#commandOutput'); 14 | } 15 | } 16 | 17 | export default new CreateAndDestroyMapPage(); -------------------------------------------------------------------------------- /plugin/e2e-tests/android/variables.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | minSdkVersion = 23 3 | compileSdkVersion = 35 4 | targetSdkVersion = 35 5 | androidxActivityVersion = '1.9.2' 6 | androidxAppCompatVersion = '1.7.0' 7 | androidxCoordinatorLayoutVersion = '1.2.0' 8 | androidxCoreVersion = '1.15.0' 9 | androidxFragmentVersion = '1.8.4' 10 | androidxWebkitVersion = '1.12.1' 11 | androidxJunitVersion = '1.2.1' 12 | androidxEspressoCoreVersion = '3.6.1' 13 | cordovaAndroidVersion = '10.1.1' 14 | coreSplashScreenVersion = '1.0.1' 15 | junitVersion = '4.13.2' 16 | } -------------------------------------------------------------------------------- /plugin/ios/Tests/CapacitorGoogleMapsPluginTests/CapacitorGoogleMapsTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import Plugin 3 | 4 | class CapacitorGoogleMapsTests: XCTestCase { 5 | 6 | func testEcho() { 7 | // This is an example of a functional test case for a plugin. 8 | // Use XCTAssert and related functions to verify your tests produce the correct results. 9 | 10 | let implementation = CapacitorGoogleMaps() 11 | let value = "Hello, World!" 12 | let result = implementation.echo(value) 13 | 14 | XCTAssertEqual(value, result) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowUnreachableCode": false, 4 | "declaration": true, 5 | "declarationDir": "dist/typings", 6 | "esModuleInterop": true, 7 | "inlineSources": true, 8 | "lib": ["dom", "es2017"], 9 | "module": "esnext", 10 | "moduleResolution": "node", 11 | "noFallthroughCasesInSwitch": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "outDir": "dist/esm", 15 | "pretty": true, 16 | "sourceMap": true, 17 | "strict": true, 18 | "target": "es2017" 19 | }, 20 | "files": ["src/index.ts"] 21 | } 22 | -------------------------------------------------------------------------------- /plugin/rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'dist/esm/index.js', 3 | output: [ 4 | { 5 | file: 'dist/plugin.js', 6 | format: 'iife', 7 | name: 'capacitorCapacitorGoogleMaps', 8 | globals: { 9 | '@capacitor/core': 'capacitorExports', 10 | }, 11 | sourcemap: true, 12 | inlineDynamicImports: true, 13 | }, 14 | { 15 | file: 'dist/plugin.cjs.js', 16 | format: 'cjs', 17 | sourcemap: true, 18 | inlineDynamicImports: true, 19 | }, 20 | ], 21 | external: ['@capacitor/core', '@googlemaps/js-api-loader', '@googlemaps/markerclusterer'], 22 | }; 23 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/test/java/io/ionic/googlemapstest/GoogleMapsUnitTests.kt: -------------------------------------------------------------------------------- 1 | package io.ionic.googlemapstest 2 | 3 | import com.capacitorjs.plugins.googlemaps.CapacitorGoogleMaps 4 | import org.junit.Assert.assertEquals 5 | import org.junit.Test 6 | import org.junit.runner.RunWith 7 | import org.robolectric.RobolectricTestRunner 8 | 9 | @RunWith(RobolectricTestRunner::class) 10 | class GoogleMapsUnitTests { 11 | @Test 12 | fun exampleTest() { 13 | val plugin = CapacitorGoogleMaps() 14 | 15 | val valueOf = plugin.echo("Hello world!") 16 | assertEquals("Hello world!", valueOf) 17 | } 18 | } -------------------------------------------------------------------------------- /.github/workflows/reusable_lint-packages.yml: -------------------------------------------------------------------------------- 1 | name: "Lint Packages" 2 | 3 | on: 4 | workflow_call: 5 | secrets: 6 | CAP_GH_RELEASE_TOKEN: 7 | required: false 8 | 9 | jobs: 10 | lint: 11 | runs-on: 'macos-15' 12 | timeout-minutes: 30 13 | steps: 14 | - uses: actions/checkout@v3 15 | with: 16 | fetch-depth: 0 17 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN || github.token }} 18 | 19 | - name: 'Setup Tools' 20 | uses: ./.github/actions/setup-tools 21 | 22 | - name: 'Lint Packages' 23 | shell: bash 24 | run: | 25 | pnpm run lint 26 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.github/workflows/reusable_setup.yml: -------------------------------------------------------------------------------- 1 | name: "Setup" 2 | 3 | on: 4 | workflow_call: 5 | secrets: 6 | CAP_GH_RELEASE_TOKEN: 7 | required: false 8 | 9 | jobs: 10 | setup: 11 | strategy: 12 | matrix: 13 | os: ['ubuntu-22.04', 'macos-15'] 14 | runs-on: ${{ matrix.os }} 15 | timeout-minutes: 30 16 | steps: 17 | - uses: actions/checkout@v3 18 | with: 19 | fetch-depth: 0 20 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN || github.token }} 21 | 22 | - name: 'Setup Tools' 23 | uses: ./.github/actions/setup-tools 24 | with: 25 | skip-install-on-cache-hit: 'true' 26 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/pageobjects/markers/add-and-remove.page.ts: -------------------------------------------------------------------------------- 1 | import { IonicButton, IonicTextarea } from '@ionic/e2e-components-ionic'; 2 | 3 | import Page from "../page"; 4 | 5 | class AddAndRemoveMarkers extends Page { 6 | get createMapButton() { 7 | return new IonicButton("#createMapButton") 8 | } 9 | get addMarkerButton() { 10 | return new IonicButton("#addMarkerButton") 11 | } 12 | get removeMarkerButton() { 13 | return new IonicButton("#removeMarkerButton") 14 | } 15 | get commandOutputTextarea() { 16 | return new IonicTextarea('#commandOutput'); 17 | } 18 | } 19 | 20 | 21 | export default new AddAndRemoveMarkers(); -------------------------------------------------------------------------------- /.github/workflows/bot.yml: -------------------------------------------------------------------------------- 1 | name: Bot 2 | 3 | on: 4 | issues: 5 | types: [opened, edited, labeled] 6 | pull_request: 7 | types: [opened] 8 | issue_comment: 9 | types: [created] 10 | 11 | jobs: 12 | bot: 13 | name: ${{ github.event_name }}/${{ github.event.action }} 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | - uses: ionic-team/bot@main 18 | with: 19 | repo-token: ${{ secrets.BOT_TOKEN }} 20 | env: 21 | GIT_AUTHOR_NAME: Ionitron 22 | GIT_AUTHOR_EMAIL: hi@ionicframework.com 23 | GIT_COMMITTER_NAME: Ionitron 24 | GIT_COMMITTER_EMAIL: hi@ionicframework.com 25 | -------------------------------------------------------------------------------- /.github/workflows/needs-reply.yml: -------------------------------------------------------------------------------- 1 | name: Close old issues that need reply 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Close old issues that need reply 12 | uses: imhoffd/needs-reply@v2 13 | with: 14 | repo-token: ${{ secrets.BOT_TOKEN }} 15 | issue-label: 'needs reply' 16 | days-before-close: 15 17 | close-message: | 18 | It looks like this issue didn't get the information it needed, so I'll close it for now. If I made a mistake, sorry! I am just a bot. 19 | 20 | Have a great day! 21 | Ionitron 💙 22 | -------------------------------------------------------------------------------- /example-app-spm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src", 25 | "src/**/*.d.ts" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /plugin/android/src/main/java/com/capacitorjs/plugins/googlemaps/CapacitorGoogleMapsPoint.kt: -------------------------------------------------------------------------------- 1 | package com.capacitorjs.plugins.googlemaps 2 | 3 | import org.json.JSONObject 4 | 5 | class CapacitorGoogleMapsPoint() { 6 | var x: Float = 0.00f 7 | var y: Float = 0.00f 8 | 9 | constructor(fromJSONObject: JSONObject) : this() { 10 | if(fromJSONObject.has("x")) { 11 | this.x = fromJSONObject.getDouble("x").toFloat() 12 | } 13 | 14 | if(fromJSONObject.has("y")) { 15 | this.y = fromJSONObject.getDouble("y").toFloat() 16 | } 17 | } 18 | 19 | constructor(x: Float, y: Float) : this() { 20 | this.x = x; 21 | this.y = y 22 | } 23 | } -------------------------------------------------------------------------------- /plugin/ios/Sources/CapacitorGoogleMapsPlugin/TileOverlay.swift: -------------------------------------------------------------------------------- 1 | import Capacitor 2 | 3 | public struct TileOverlay: Codable { 4 | let url: String 5 | let opacity: Float? 6 | let visible: Bool? 7 | let zIndex: Int32 8 | 9 | init(fromJSObject: JSObject) throws { 10 | guard let url = fromJSObject["url"] as? String else { 11 | throw GoogleMapErrors.invalidArguments("TileOverlay object is missing the required 'url' property") 12 | } 13 | self.url = url 14 | self.opacity = fromJSObject["opacity"] as? Float 15 | self.visible = fromJSObject["isFlat"] as? Bool 16 | self.zIndex = Int32((fromJSObject["zIndex"] as? Int) ?? 0) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example-app-spm/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [0.1.0](https://github.com/ionic-team/capacitor-google-maps/compare/example-app-spm@0.0.2...example-app-spm@0.1.0) (2025-12-08) 7 | 8 | 9 | ### Features 10 | 11 | * Google Maps npm library updates ([#151](https://github.com/ionic-team/capacitor-google-maps/issues/151)) ([6a9d6cb](https://github.com/ionic-team/capacitor-google-maps/commit/6a9d6cb7d899ab8baf9a70b79c38ee4a13fe312e)) 12 | 13 | 14 | 15 | 16 | 17 | ## 0.0.2 (2025-10-03) 18 | 19 | **Note:** Version bump only for package example-app-spm 20 | -------------------------------------------------------------------------------- /.github/ionic-issue-bot.yml: -------------------------------------------------------------------------------- 1 | triage: 2 | label: triage 3 | removeLabelWhenProjectAssigned: false 4 | dryRun: false 5 | 6 | lockClosed: 7 | days: 15 8 | maxIssuesPerRun: 100 9 | message: > 10 | Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. 11 | If this is still an issue with the latest version of the plugin, please create a new issue and ensure the template is fully filled out. 12 | dryRun: false 13 | 14 | comment: 15 | labels: 16 | - label: "type: bug" 17 | message: > 18 | This issue has been labeled as `type: bug`. This label is added to issues 19 | that that have been reproduced and are being tracked in our internal issue tracker. 20 | dryRun: false -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/capacitor.build.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | 3 | android { 4 | compileOptions { 5 | sourceCompatibility JavaVersion.VERSION_21 6 | targetCompatibility JavaVersion.VERSION_21 7 | } 8 | } 9 | 10 | apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" 11 | dependencies { 12 | implementation project(':capacitor-app') 13 | implementation project(':capacitor-google-maps') 14 | implementation project(':capacitor-haptics') 15 | implementation project(':capacitor-keyboard') 16 | implementation project(':capacitor-status-bar') 17 | 18 | } 19 | 20 | 21 | if (hasProperty('postBuildExtras')) { 22 | postBuildExtras() 23 | } 24 | -------------------------------------------------------------------------------- /plugin/CapacitorGoogleMaps.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = 'CapacitorGoogleMaps' 7 | s.version = package['version'] 8 | s.summary = package['description'] 9 | s.license = package['license'] 10 | s.homepage = package['repository']['url'] 11 | s.author = package['author'] 12 | s.source = { :git => package['repository']['url'], :tag => s.version.to_s } 13 | s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}' 14 | s.ios.deployment_target = '15.0' 15 | s.dependency 'Capacitor' 16 | s.dependency 'GoogleMaps', '~> 9.4' 17 | s.dependency 'Google-Maps-iOS-Utils', '6.1.0' 18 | s.swift_version = '5.1' 19 | s.static_framework = true 20 | end 21 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | ext.kotlin_version = '1.6.0' 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath "com.android.tools.build:gradle:4.2.2" 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | google() 19 | mavenCentral() 20 | } 21 | } 22 | 23 | task clean(type: Delete) { 24 | delete rootProject.buildDir 25 | } -------------------------------------------------------------------------------- /plugin/android/src/main/java/com/capacitorjs/plugins/googlemaps/GoogleMapPadding.kt: -------------------------------------------------------------------------------- 1 | package com.capacitorjs.plugins.googlemaps 2 | 3 | import org.json.JSONObject 4 | 5 | class GoogleMapPadding(fromJSONObject: JSONObject) { 6 | var top: Int = 0 7 | var bottom: Int = 0 8 | var left: Int = 0 9 | var right: Int = 0 10 | 11 | init { 12 | if(fromJSONObject.has("top")) { 13 | top = fromJSONObject.getInt("top") 14 | } 15 | 16 | if(fromJSONObject.has("bottom")) { 17 | bottom = fromJSONObject.getInt("bottom") 18 | } 19 | 20 | if(fromJSONObject.has("left")) { 21 | left = fromJSONObject.getInt("left") 22 | } 23 | 24 | if(fromJSONObject.has("right")) { 25 | right = fromJSONObject.getInt("right") 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /plugin/swiftlint.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | module.exports = { 3 | included: ['${PWD}/ios/Sources', '${PWD}/ios/Tests'], 4 | identifier_name: { 5 | min_length: { 6 | warning: 3, 7 | error: 1, 8 | }, 9 | }, 10 | excluded: ['node_modules', 'ios/Pods'], 11 | opt_in_rules: [ 12 | 'implicitly_unwrapped_optional', 13 | 'file_name_no_space', 14 | 'force_unwrapping', 15 | 'function_default_parameter_at_end', 16 | 'lower_acl_than_parent', 17 | 'modifier_order', 18 | 'overridden_super_call', 19 | 'unowned_variable_capture', 20 | 'unused_import', 21 | ], 22 | line_length: { 23 | warning: 150, 24 | error: 300, 25 | ignores_function_declarations: true, 26 | ignores_comments: true, 27 | ignores_interpolated_strings: true, 28 | ignores_urls: true, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /plugin/android/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/pageobjects/page.ts: -------------------------------------------------------------------------------- 1 | export default class Page { 2 | public async hideToolBars() { 3 | await driver.execute(() => { 4 | for (let i = 0; i < document.getElementsByTagName('ion-toolbar').length; i++) { 5 | const toolbar: HTMLElement | null = document.getElementsByTagName('ion-toolbar').item(i) as HTMLElement; 6 | if (toolbar !== null) { 7 | toolbar.style.display = 'none'; 8 | } 9 | } 10 | }); 11 | } 12 | 13 | public async showToolBars() { 14 | await driver.execute(() => { 15 | for (let i = 0; i < document.getElementsByTagName('ion-toolbar').length; i++) { 16 | const toolbar: HTMLElement | null = document.getElementsByTagName('ion-toolbar').item(i) as HTMLElement; 17 | if (toolbar !== null) { 18 | toolbar.style.display = ''; 19 | } 20 | } 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/pageobjects/markers/multiple-markers.page.ts: -------------------------------------------------------------------------------- 1 | import { IonicButton, IonicTextarea } from '@ionic/e2e-components-ionic'; 2 | 3 | import Page from "../page"; 4 | 5 | class MultipleMarkers extends Page { 6 | get createMapButton() { 7 | return new IonicButton("#createMapButton") 8 | } 9 | get addMarkersButton() { 10 | return new IonicButton("#addMarkersButton") 11 | } 12 | get enableClusteringButton() { 13 | return new IonicButton("#enableClusteringButton") 14 | } 15 | get disableClusteringButton() { 16 | return new IonicButton("#disableClusteringButton") 17 | } 18 | get removeMarkersButton() { 19 | return new IonicButton("#removeMarkersButton") 20 | } 21 | get commandOutputTextarea() { 22 | return new IonicTextarea('#commandOutput'); 23 | } 24 | } 25 | 26 | export default new MultipleMarkers(); -------------------------------------------------------------------------------- /plugin/e2e-tests/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:8.7.2' 11 | classpath 'com.google.gms:google-services:4.4.2' 12 | classpath 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1' 13 | 14 | // NOTE: Do not place your application dependencies here; they belong 15 | // in the individual module build.gradle files 16 | } 17 | } 18 | 19 | apply from: "variables.gradle" 20 | 21 | allprojects { 22 | repositories { 23 | google() 24 | mavenCentral() 25 | } 26 | } 27 | 28 | task clean(type: Delete) { 29 | delete rootProject.buildDir 30 | } 31 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import * as serviceWorkerRegistration from './serviceWorkerRegistration'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want your app to work offline and load faster, you can change 15 | // unregister() to register() below. Note this comes with some pitfalls. 16 | // Learn more about service workers: https://cra.link/PWA 17 | serviceWorkerRegistration.unregister(); 18 | 19 | // If you want to start measuring performance in your app, pass a function 20 | // to log results (for example: reportWebVitals(console.log)) 21 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 22 | reportWebVitals(); 23 | -------------------------------------------------------------------------------- /publish-ios.yml: -------------------------------------------------------------------------------- 1 | name: Publish Native iOS Libraries 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | plugins: 7 | description: 'Specify a set of plugins to publish (as a JSON array, ex: [\"camera\", \"browser\"])' 8 | required: true 9 | jobs: 10 | publish-ios: 11 | runs-on: macos-15 12 | timeout-minutes: 30 13 | steps: 14 | - run: sudo xcode-select --switch /Applications/Xcode_16.4.app 15 | - uses: actions/setup-node@v3 16 | with: 17 | node-version: 16 18 | - uses: actions/checkout@v3 19 | - name: Install Cocoapods 20 | run: | 21 | gem install cocoapods 22 | - name: Deploy to Cocoapods 23 | run: | 24 | set -eo pipefail 25 | npm run publish:cocoapod 26 | env: 27 | COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} 28 | working-directory: plugin 29 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/capacitor.settings.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | include ':capacitor-android' 3 | project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') 4 | 5 | include ':capacitor-app' 6 | project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android') 7 | 8 | include ':capacitor-google-maps' 9 | project(':capacitor-google-maps').projectDir = new File('../../android') 10 | 11 | include ':capacitor-haptics' 12 | project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android') 13 | 14 | include ':capacitor-keyboard' 15 | project(':capacitor-keyboard').projectDir = new File('../node_modules/@capacitor/keyboard/android') 16 | 17 | include ':capacitor-status-bar' 18 | project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacitor/status-bar/android') 19 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '15.0' 2 | use_frameworks! 3 | 4 | # workaround to avoid Xcode caching of Pods that requires 5 | # Product -> Clean Build Folder after new Cordova plugins installed 6 | # Requires CocoaPods 1.6 or newer 7 | install! 'cocoapods', :disable_input_output_paths => true 8 | 9 | def capacitor_pods 10 | pod 'Capacitor', :path => '../../node_modules/@capacitor/ios' 11 | pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios' 12 | pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app' 13 | pod 'CapacitorGoogleMaps', :path => '../../..' 14 | pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics' 15 | pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard' 16 | pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar' 17 | end 18 | 19 | target 'App' do 20 | capacitor_pods 21 | # Add your Pods here 22 | end 23 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import android.content.Context; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | import androidx.test.platform.app.InstrumentationRegistry; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * @see Testing documentation 15 | */ 16 | @RunWith(AndroidJUnit4.class) 17 | public class ExampleInstrumentedTest { 18 | 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 23 | 24 | assertEquals("com.getcapacitor.app", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/release-rc.yml: -------------------------------------------------------------------------------- 1 | name: "Release RC" 2 | 3 | on: workflow_dispatch 4 | 5 | jobs: 6 | setup: 7 | uses: ./.github/workflows/reusable_setup.yml 8 | secrets: 9 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 10 | 11 | lint-test: 12 | needs: 'setup' 13 | uses: ./.github/workflows/reusable_lint-packages.yml 14 | secrets: 15 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 16 | 17 | build-packages: 18 | needs: 'setup' 19 | uses: ./.github/workflows/reusable_build-packages.yml 20 | secrets: 21 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 22 | 23 | release-npm-rc: 24 | needs: ['build-packages', 'lint-test'] 25 | uses: ./.github/workflows/reusable_release-npm.yml 26 | with: 27 | create-dev-release: false 28 | create-rc-release: true 29 | secrets: 30 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 31 | NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} -------------------------------------------------------------------------------- /example-app-spm/src/components/BaseTestingPage.tsx: -------------------------------------------------------------------------------- 1 | import { IonButtons, IonContent, IonHeader, IonMenuButton, IonPage, IonTitle, IonToolbar } from '@ionic/react'; 2 | 3 | const BaseTestingPage: React.FC<{ children?: React.ReactNode; pageTitle: string }> = ({ children, pageTitle }) => { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | {pageTitle} 12 | 13 | 14 | 15 | 16 | 17 | {pageTitle} 18 | 19 | 20 | {children} 21 | 22 | 23 | ); 24 | }; 25 | 26 | export default BaseTestingPage; 27 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/components/BaseTestingPage.tsx: -------------------------------------------------------------------------------- 1 | import { IonButtons, IonContent, IonHeader, IonMenuButton, IonPage, IonTitle, IonToolbar } from '@ionic/react'; 2 | 3 | const BaseTestingPage: React.FC<{ children?: React.ReactNode; pageTitle: string }> = ({ children, pageTitle }) => { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | {pageTitle} 12 | 13 | 14 | 15 | 16 | 17 | {pageTitle} 18 | 19 | 20 | {children} 21 | 22 | 23 | ); 24 | }; 25 | 26 | export default BaseTestingPage; 27 | -------------------------------------------------------------------------------- /example-app-spm/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App'; 4 | import * as serviceWorkerRegistration from './serviceWorkerRegistration'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const container = document.getElementById('root'); 8 | if (container) { 9 | const root = createRoot(container); 10 | root.render( 11 | 12 | 13 | 14 | ); 15 | } 16 | 17 | // If you want your app to work offline and load faster, you can change 18 | // unregister() to register() below. Note this comes with some pitfalls. 19 | // Learn more about service workers: https://cra.link/PWA 20 | serviceWorkerRegistration.unregister(); 21 | 22 | // If you want to start measuring performance in your app, pass a function 23 | // to log results (for example: reportWebVitals(console.log)) 24 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 25 | reportWebVitals(); 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ⚡️ Feature Request 3 | about: Request a feature or change 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Feature Request 11 | 12 | ### Plugin 13 | 16 | 17 | 18 | 19 | ### Description 20 | 23 | 24 | 25 | 26 | ### Platform(s) 27 | 30 | 31 | 32 | 33 | ### Preferred Solution 34 | 35 | 36 | 37 | 38 | ### Alternatives 39 | 40 | 41 | 42 | 43 | ### Additional Context 44 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Release" 2 | 3 | on: workflow_dispatch 4 | 5 | permissions: 6 | contents: write 7 | id-token: write 8 | 9 | jobs: 10 | setup: 11 | uses: ./.github/workflows/reusable_setup.yml 12 | secrets: 13 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 14 | 15 | lint-test: 16 | needs: 'setup' 17 | uses: ./.github/workflows/reusable_lint-packages.yml 18 | secrets: 19 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 20 | 21 | verify-packages: 22 | needs: 'setup' 23 | uses: ./.github/workflows/reusable_verify-packages.yml 24 | secrets: 25 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 26 | 27 | release-npm: 28 | needs: ['verify-packages', 'lint-test'] 29 | uses: ./.github/workflows/reusable_release-npm.yml 30 | with: 31 | create-dev-release: false 32 | create-rc-release: false 33 | secrets: 34 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 35 | NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/release-dev.yml: -------------------------------------------------------------------------------- 1 | name: "Release Dev" 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | # - 'main' 8 | workflow_dispatch: 9 | 10 | jobs: 11 | setup: 12 | uses: ./.github/workflows/reusable_setup.yml 13 | secrets: 14 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 15 | 16 | lint-test: 17 | needs: 'setup' 18 | uses: ./.github/workflows/reusable_lint-packages.yml 19 | secrets: 20 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 21 | 22 | build-packages: 23 | needs: 'setup' 24 | uses: ./.github/workflows/reusable_build-packages.yml 25 | secrets: 26 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 27 | 28 | release-npm-dev: 29 | needs: ['build-packages', 'lint-test'] 30 | uses: ./.github/workflows/reusable_release-npm.yml 31 | with: 32 | create-dev-release: true 33 | create-rc-release: false 34 | secrets: 35 | CAP_GH_RELEASE_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 36 | NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} -------------------------------------------------------------------------------- /example-app-spm/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ionic App 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /plugin/e2e-tests/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ionic App 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /plugin/e2e-tests/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 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | # AndroidX package structure to make it clearer which packages are bundled with the 20 | # Android operating system, and which are packaged with your app's APK 21 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 22 | android.useAndroidX=true 23 | 24 | -------------------------------------------------------------------------------- /plugin/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 | org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=2g 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | # AndroidX package structure to make it clearer which packages are bundled with the 20 | # Android operating system, and which are packaged with your app's APK 21 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 22 | android.useAndroidX=true 23 | -------------------------------------------------------------------------------- /plugin/android/src/main/java/com/capacitorjs/plugins/googlemaps/CapacitorGoogleMapTileOverlay.kt: -------------------------------------------------------------------------------- 1 | package com.capacitorjs.plugins.googlemaps 2 | 3 | import com.google.android.gms.maps.model.TileOverlay 4 | import org.json.JSONObject 5 | 6 | class CapacitorGoogleMapTileOverlay(fromJSONObject: JSONObject) { 7 | var url: String 8 | var opacity: Float? = null 9 | var zIndex: Float? = null 10 | var visible: Boolean? = null 11 | var googleMapTileOverlay: TileOverlay? = null 12 | 13 | init { 14 | if (!fromJSONObject.has("url")) { 15 | throw InvalidArgumentsError("TileOverlay object is missing the required 'url' property") 16 | } 17 | url = fromJSONObject.getString("url") 18 | if (fromJSONObject.has("opacity")) { 19 | opacity = fromJSONObject.optDouble("opacity").toFloat() 20 | } 21 | if (fromJSONObject.has("visible")) { 22 | visible = fromJSONObject.optBoolean("visible") 23 | } 24 | if (fromJSONObject.has("zIndex")) { 25 | zIndex = fromJSONObject.optLong("zIndex").toFloat() 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/pageobjects/markers/marker-customization.page.ts: -------------------------------------------------------------------------------- 1 | import { IonicButton, IonicTextarea } from '@ionic/e2e-components-ionic'; 2 | 3 | import Page from '../page'; 4 | 5 | class MarkerCustomizations extends Page { 6 | get createMapButton() { 7 | return new IonicButton('#createMapButton'); 8 | } 9 | 10 | get addMarkerImageButton() { 11 | return new IonicButton('#addMarkerImageButton'); 12 | } 13 | 14 | get addMarkerColorButton() { 15 | return new IonicButton('#addMarkerColorButton'); 16 | } 17 | 18 | get addMultipleImageMarkersButton() { 19 | return new IonicButton('#addMultipleImageMarkersButton'); 20 | } 21 | 22 | get addMultipleColorMarkersButton() { 23 | return new IonicButton('#addMultipleColorMarkersButton'); 24 | } 25 | 26 | get removeAllMarkersButton() { 27 | return new IonicButton('#removeAllMarkersButton'); 28 | } 29 | 30 | get destroyMapButton() { 31 | return new IonicButton('#destroyMapButton'); 32 | } 33 | 34 | get commandOutputTextarea() { 35 | return new IonicTextarea('#commandOutput'); 36 | } 37 | } 38 | 39 | export default new MarkerCustomizations(); 40 | -------------------------------------------------------------------------------- /.github/workflows/release-from-prerelease.yml: -------------------------------------------------------------------------------- 1 | name: "Release from Prerelease" 2 | 3 | on: workflow_dispatch 4 | 5 | permissions: 6 | contents: write 7 | id-token: write 8 | 9 | jobs: 10 | deploy-npm-latest-from-pre: 11 | runs-on: macos-15 12 | timeout-minutes: 30 13 | steps: 14 | - uses: actions/checkout@v3 15 | with: 16 | fetch-depth: 0 17 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 18 | 19 | - name: 'Setup Tools' 20 | uses: ./.github/actions/setup-tools 21 | 22 | - name: "NPM Identity" 23 | run: | 24 | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" >> ~/.npmrc 25 | npm whoami 26 | 27 | - name: "Git Config" 28 | run: | 29 | git config user.name "Github Workflow (on behalf of ${{ github.actor }})" 30 | git config user.email "users.noreply.github.com" 31 | 32 | - name: Version & Publish 33 | env: 34 | NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} 35 | GH_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 36 | run: | 37 | pnpm run ci:publish:latest-from-pre 38 | -------------------------------------------------------------------------------- /plugin/ios/Sources/CapacitorGoogleMapsPlugin/GoogleMapCameraConfig.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Capacitor 3 | 4 | public struct GoogleMapCameraConfig { 5 | let coordinate: LatLng? 6 | let zoom: Float? 7 | let bearing: Double? 8 | let angle: Double? 9 | let animate: Bool? 10 | let animationDuration: Double? 11 | 12 | init(fromJSObject: JSObject) throws { 13 | zoom = fromJSObject["zoom"] as? Float 14 | bearing = fromJSObject["bearing"] as? Double 15 | angle = fromJSObject["angle"] as? Double 16 | animate = fromJSObject["animate"] as? Bool 17 | animationDuration = fromJSObject["animationDuration"] as? Double 18 | 19 | if let latLngObj = fromJSObject["coordinate"] as? JSObject { 20 | guard let lat = latLngObj["lat"] as? Double, let lng = latLngObj["lng"] as? Double else { 21 | throw GoogleMapErrors.invalidArguments("LatLng object is missing the required 'lat' and/or 'lng' property") 22 | } 23 | 24 | self.coordinate = LatLng(lat: lat, lng: lng) 25 | } else { 26 | self.coordinate = nil 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/bot.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - name: add-comment 3 | on: 4 | issues: 5 | types: [labeled] 6 | condition: 'payload.label.name == "needs reproduction"' 7 | config: 8 | comment: | 9 | This issue needs more information before it can be addressed. 10 | In particular, the reporter needs to provide a minimal sample app that demonstrates the issue. 11 | If no sample app is provided within 15 days, the issue will be closed. 12 | 13 | Please see the Contributing Guide for [how to create a Sample App](https://github.com/ionic-team/capacitor/blob/HEAD/CONTRIBUTING.md#creating-a-code-reproduction). 14 | 15 | Thanks! 16 | Ionitron 💙 17 | - name: add-label 18 | on: 19 | issues: 20 | types: [labeled] 21 | condition: 'payload.label.name == "needs reproduction"' 22 | config: 23 | label: 'needs reply' 24 | - name: remove-label 25 | on: 26 | issue_comment: 27 | types: [created] 28 | config: 29 | label: 'needs reply' 30 | exclude-labeler: true 31 | - name: add-platform-labels 32 | on: 33 | issues: 34 | types: [opened, edited] 35 | -------------------------------------------------------------------------------- /example-app-spm/public/assets/shapes.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /plugin/e2e-tests/public/assets/shapes.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/specs/basic-echo/basic-echo.spec.ts: -------------------------------------------------------------------------------- 1 | import * as IonicE2E from '@ionic/e2e'; 2 | import { waitForLoad, pause, setDevice, switchToWeb, url } from '@ionic/e2e'; 3 | 4 | import SetAndGetValuePage from '../../pageobjects/basic-echo/basic-echo.page'; 5 | 6 | describe.skip('Google Maps - Basic Echo', function () { 7 | before(async function () { 8 | await waitForLoad(); 9 | await switchToWeb(); 10 | await url('/basic-echo/run-basic-echo'); 11 | await pause(500); 12 | }); 13 | 14 | beforeEach(async function () { 15 | await setDevice(IonicE2E.Device.Mobile); 16 | await switchToWeb(); 17 | await SetAndGetValuePage.hideToolBars(); 18 | }); 19 | 20 | after(async function () { 21 | await switchToWeb(); 22 | await SetAndGetValuePage.showToolBars(); 23 | await pause(500); 24 | }); 25 | 26 | it('should run a basic echo from plugin.', async () => { 27 | const runEchoButton = await SetAndGetValuePage.runEchoButton; 28 | const commandOutput = await $((await SetAndGetValuePage.commandOutputTextarea).selector).$('textarea'); 29 | 30 | await runEchoButton.tap(); 31 | await expect(commandOutput).toHaveValue('WOW!'); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /plugin/android/src/main/java/com/capacitorjs/plugins/googlemaps/CapacitorGoogleMapsBounds.kt: -------------------------------------------------------------------------------- 1 | package com.capacitorjs.plugins.googlemaps 2 | 3 | import org.json.JSONObject 4 | 5 | class CapacitorGoogleMapsBounds(fromJSONObject: JSONObject) { 6 | var width: Int = 0 7 | var height: Int = 0 8 | var x: Int = 0 9 | var y: Int = 0 10 | 11 | init { 12 | if(!fromJSONObject.has("width")) { 13 | throw InvalidArgumentsError("GoogleMapConfig object is missing the required 'width' property") 14 | } 15 | 16 | if(!fromJSONObject.has("height")) { 17 | throw InvalidArgumentsError("GoogleMapConfig object is missing the required 'height' property") 18 | } 19 | 20 | if(!fromJSONObject.has("x")) { 21 | throw InvalidArgumentsError("GoogleMapConfig object is missing the required 'x' property") 22 | } 23 | 24 | if(!fromJSONObject.has("y")) { 25 | throw InvalidArgumentsError("GoogleMapConfig object is missing the required 'y' property") 26 | } 27 | 28 | width = fromJSONObject.getInt("width") 29 | height = fromJSONObject.getInt("height") 30 | x = fromJSONObject.getInt("x") 31 | y = fromJSONObject.getInt("y") 32 | } 33 | } -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/GoogleMapsPluginTests/GoogleMapsPluginTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import GoogleMapsPlugin 3 | 4 | class GoogleMapsPluginTests: XCTestCase { 5 | var plugin: CapacitorGoogleMaps? 6 | 7 | override func setUpWithError() throws { 8 | self.plugin = CapacitorGoogleMaps() 9 | // Put setup code here. This method is called before the invocation of each test method in the class. 10 | } 11 | 12 | override func tearDownWithError() throws { 13 | // Put teardown code here. This method is called after the invocation of each test method in the class. 14 | } 15 | 16 | func exampleTest() throws { 17 | do { 18 | if let plugin = self.plugin { 19 | let value = try plugin.echo("Hello world!") 20 | 21 | XCTAssertEqual("Hello world!", value) 22 | } 23 | } catch { 24 | print("Example Test Error \(error)") 25 | XCTFail() 26 | } 27 | } 28 | 29 | func testPerformanceExample() throws { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /plugin/.gitignore: -------------------------------------------------------------------------------- 1 | # node files 2 | dist 3 | node_modules 4 | 5 | # iOS files 6 | Pods 7 | Podfile.lock 8 | Build 9 | xcuserdata 10 | 11 | # macOS files 12 | .DS_Store 13 | 14 | 15 | 16 | # Based on Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore 17 | 18 | # Built application files 19 | *.apk 20 | *.ap_ 21 | 22 | # Files for the ART/Dalvik VM 23 | *.dex 24 | 25 | # Java class files 26 | *.class 27 | 28 | # Generated files 29 | bin 30 | gen 31 | out 32 | 33 | # Gradle files 34 | .gradle 35 | build 36 | 37 | # Local configuration file (sdk path, etc) 38 | local.properties 39 | 40 | # Proguard folder generated by Eclipse 41 | proguard 42 | 43 | # Log Files 44 | *.log 45 | 46 | # Android Studio Navigation editor temp files 47 | .navigation 48 | 49 | # Android Studio captures folder 50 | captures 51 | 52 | # IntelliJ 53 | *.iml 54 | .idea 55 | 56 | # Keystore files 57 | # Uncomment the following line if you do not want to check your keystore files in. 58 | #*.jks 59 | 60 | # External native build folder generated in Android Studio 2.2 and later 61 | .externalNativeBuild 62 | *.tgz 63 | 64 | /Packages 65 | xcuserdata/ 66 | DerivedData/ 67 | .swiftpm/configuration/registries.json 68 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 69 | .netrc 70 | Package.resolved 71 | /.build -------------------------------------------------------------------------------- /.github/OLD/docs-production.yml: -------------------------------------------------------------------------------- 1 | name: Deploy docs to production 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - main 8 | paths: 9 | - .github/workflows/docs-production.yml 10 | - website/** 11 | 12 | permissions: 13 | contents: read 14 | deployments: write 15 | id-token: write 16 | 17 | env: 18 | SLUG: ssl-pinning 19 | 20 | defaults: 21 | run: 22 | working-directory: website 23 | 24 | jobs: 25 | deploy: 26 | runs-on: ubuntu-latest 27 | timeout-minutes: 15 28 | environment: 29 | name: production 30 | url: https://ionic.io/docs/${{ env.SLUG }} 31 | steps: 32 | - uses: actions/checkout@v3 33 | 34 | - name: 'Setup Tools' 35 | uses: ./.github/actions/setup-tools 36 | 37 | - name: Build 38 | run: pnpm run build-docs 39 | 40 | - uses: aws-actions/configure-aws-credentials@v1 41 | with: 42 | role-to-assume: arn:aws:iam::319312831725:role/github-docs 43 | aws-region: us-east-1 44 | 45 | - name: Deploy 46 | run: | 47 | aws s3 sync build/ s3://ionic-docs/production/${{ env.SLUG }}/ --exclude '*.html' --cache-control max-age=31536000 --only-show-errors 48 | aws s3 sync build/ s3://ionic-docs/production/${{ env.SLUG }}/ --exclude '*' --include '*.html' --cache-control max-age=60 --only-show-errors 49 | -------------------------------------------------------------------------------- /.github/OLD/docs-preview.yml: -------------------------------------------------------------------------------- 1 | name: Deploy docs PR preview 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - .github/workflows/docs-preview.yml 7 | - website/** 8 | 9 | permissions: 10 | contents: read 11 | deployments: write 12 | id-token: write 13 | 14 | env: 15 | SLUG: ssl-pinning-${{ github.event.number }}-${{ github.run_id }} 16 | 17 | defaults: 18 | run: 19 | working-directory: website 20 | 21 | jobs: 22 | deploy: 23 | runs-on: ubuntu-latest 24 | timeout-minutes: 15 25 | environment: 26 | name: preview-${{ github.event.number }} 27 | url: https://${{ env.SLUG }}.ionicpreview.com 28 | steps: 29 | - uses: actions/checkout@v3 30 | 31 | - name: 'Setup Tools' 32 | uses: ./.github/actions/setup-tools 33 | 34 | - name: Build 35 | run: pnpm run build-docs 36 | 37 | - uses: aws-actions/configure-aws-credentials@v1 38 | with: 39 | role-to-assume: arn:aws:iam::319312831725:role/github-docs 40 | aws-region: us-east-1 41 | 42 | - name: Deploy 43 | run: | 44 | aws s3 sync build/ s3://ionic-docs/preview/${{ env.SLUG }}/ --exclude '*.html' --cache-control max-age=31536000 --only-show-errors 45 | aws s3 sync build/ s3://ionic-docs/preview/${{ env.SLUG }}/ --exclude '*' --include '*.html' --cache-control max-age=60 --only-show-errors -------------------------------------------------------------------------------- /plugin/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.9 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "CapacitorGoogleMaps", 6 | platforms: [.iOS(.v15)], 7 | products: [ 8 | .library( 9 | name: "CapacitorGoogleMaps", 10 | targets: ["CapacitorGoogleMapsPlugin"]) 11 | ], 12 | dependencies: [ 13 | .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0"), 14 | .package(url: "https://github.com/googlemaps/ios-maps-sdk.git", .upToNextMajor(from:"9.4.0")), 15 | .package(url: "https://github.com/googlemaps/google-maps-ios-utils.git", .exact("6.1.0")) 16 | ], 17 | targets: [ 18 | .target( 19 | name: "CapacitorGoogleMapsPlugin", 20 | dependencies: [ 21 | .product(name: "Capacitor", package: "capacitor-swift-pm"), 22 | .product(name: "Cordova", package: "capacitor-swift-pm"), 23 | .product(name: "GoogleMaps", package: "ios-maps-sdk"), 24 | .product(name: "GoogleMapsUtils", package: "google-maps-ios-utils") 25 | ], 26 | path: "ios/Sources/CapacitorGoogleMapsPlugin"), 27 | .testTarget( 28 | name: "CapacitorGoogleMapsPluginTests", 29 | dependencies: ["CapacitorGoogleMapsPlugin"], 30 | path: "ios/Tests/CapacitorGoogleMapsPluginTests") 31 | ] 32 | ) -------------------------------------------------------------------------------- /.github/actions/setup-tools/action.yml: -------------------------------------------------------------------------------- 1 | name: "Setup Tools" 2 | description: "Setup tools needed in repo" 3 | 4 | inputs: 5 | skip-install-on-cache-hit: 6 | description: "If a Cache Hit happens, skip pnpm install" 7 | required: true 8 | default: "false" 9 | 10 | runs: 11 | using: "composite" 12 | steps: 13 | - name: Install Node.js 14 | uses: actions/setup-node@v3 15 | with: 16 | node-version: 20 17 | 18 | - name: Install PNPM 19 | uses: pnpm/action-setup@v2 20 | id: pnpm-install 21 | with: 22 | version: 9 23 | run_install: false 24 | 25 | - name: Get pnpm store directory 26 | id: pnpm-cache 27 | shell: bash 28 | run: | 29 | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_ENV 30 | 31 | - name: Setup PNPM cache 32 | id: cache-pnpm-store 33 | uses: actions/cache@v3 34 | env: 35 | STORE_PATH: ${{ env.STORE_PATH }} 36 | with: 37 | path: ${{ env.STORE_PATH }} 38 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 39 | restore-keys: | 40 | ${{ runner.os }}-pnpm-store- 41 | 42 | - name: Install dependencies 43 | if: inputs.skip-install-on-cache-hit == 'false' || (inputs.skip-install-on-cache-hit == 'true' && steps.cache-pnpm-store.cache-hit == 'false') 44 | shell: bash 45 | run: pnpm install --no-frozen-lockfile 46 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ionic.e2e.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-anonymous-default-export */ 2 | export default { 3 | appRootDir: '.', 4 | wdio: { 5 | logLevel: 'trace', // options are "trace" or "error" 6 | 'ios:simulator': { 7 | 'appium:platformName': 'iOS', 8 | 'appium:deviceName': 'iPhone 13 Pro Max', 9 | 'appium:platformVersion': '15.2', 10 | 'appium:isHeadless': true, 11 | 'appium:wdaLaunchTimeout': 600000, 12 | }, 13 | 'ios:device': {}, 14 | 'android:emulator': { 15 | 'appium:platformName': 'Android', 16 | 'appium:deviceName': 'e2eDevice', 17 | 'appium:avd': 'e2eDevice', 18 | 'appium:isHeadless': true, 19 | 'appium:platformVersion': '11.0', 20 | 'appium:appPackage': 'io.ionic.starter', 21 | 'appium:appWaitActivity': 'io.ionic.starter.MainActivity', 22 | 'appium:autoGrantPermissions': true, 23 | 'appium:allowTestPackages': true, 24 | 'appium:appWaitDuration': 60000, 25 | 'appium:adbExecTimeout': 300000, 26 | 'appium:deviceReadyTimeout': 3000, 27 | 'appium:androidDeviceReadyTimeout': 3000, 28 | 'appium:avdLaunchTimeout': 300000, 29 | 'appium:avdReadyTimeout': 300000, 30 | 'appium:appWaitForLaunch': false, 31 | 'appium:newCommandTimeout': 300, 32 | 'appium:avdArgs': '-no-window -noaudio -verbose -accel on -no-boot-anim -no-snapshot-save', 33 | }, 34 | 'android:device': {}, 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /example-app-spm/public/assets/icon/marker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /plugin/e2e-tests/public/assets/icon/marker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /plugin/android/src/main/java/com/capacitorjs/plugins/googlemaps/CapacitorClusterManagerRenderer.kt: -------------------------------------------------------------------------------- 1 | package com.capacitorjs.plugins.googlemaps 2 | 3 | import android.content.Context 4 | import com.google.android.gms.maps.GoogleMap 5 | import com.google.android.gms.maps.model.MarkerOptions 6 | import com.google.maps.android.clustering.ClusterManager 7 | import com.google.maps.android.clustering.view.DefaultClusterRenderer 8 | 9 | class CapacitorClusterManagerRenderer( 10 | context: Context, 11 | map: GoogleMap?, 12 | clusterManager: ClusterManager?, 13 | minClusterSize: Int? 14 | ) : DefaultClusterRenderer(context, map, clusterManager) { 15 | 16 | init { 17 | if(minClusterSize != null && minClusterSize > 0) { 18 | super.setMinClusterSize(minClusterSize) 19 | } 20 | } 21 | 22 | override fun onBeforeClusterItemRendered(item: CapacitorGoogleMapMarker, markerOptions: MarkerOptions) { 23 | super.onBeforeClusterItemRendered(item, markerOptions) 24 | 25 | item.markerOptions?.let { 26 | markerOptions.position(it.position) 27 | markerOptions.title(it.title) 28 | markerOptions.snippet(it.snippet) 29 | markerOptions.alpha(it.alpha) 30 | markerOptions.flat(it.isFlat) 31 | markerOptions.draggable(it.isDraggable) 32 | if(null != it.icon) { 33 | markerOptions.icon(it.icon) 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚨 Bug Report 3 | about: Report something not working 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Bug Report 11 | 12 | ### Plugin(s) 13 | 16 | 17 | 18 | 19 | ### Capacitor Version 20 | 23 | 24 | ``` 25 | PASTE OUTPUT HERE 26 | ``` 27 | 28 | ### Platform(s) 29 | 32 | 33 | 34 | 35 | ### Current Behavior 36 | 39 | 40 | 41 | 42 | ### Expected Behavior 43 | 46 | 47 | 48 | 49 | ### Code Reproduction 50 | 54 | 55 | 56 | 57 | ### Other Technical Details 58 | 61 | 62 | 63 | 64 | ### Additional Context 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /scripts/docgen_updates.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const glob = require('glob'); 4 | const { execSync } = require('child_process'); 5 | 6 | const tempPath = path.resolve('tmp_geojson_backup'); 7 | let geojsonPath = '' 8 | 9 | try { 10 | geojsonPath = geojsonDependencyPath(); 11 | if (geojsonPath && fs.existsSync(geojsonPath)) { 12 | fs.renameSync(geojsonPath, tempPath); 13 | } 14 | execSync('docgen --api GoogleMapInterface --output-readme README.md --output-json dist/docs.json', { stdio: 'inherit' }); 15 | } finally { 16 | if (fs.existsSync(tempPath) && geojsonPath) { 17 | fs.renameSync(tempPath, geojsonPath); 18 | } 19 | } 20 | 21 | /** 22 | * Returns the @types/geojson dependency path 23 | * 24 | * This dependency had interfaces with the exact name that as this plugin's. 25 | * This was causing docgen to generate documentation from geojson instead of our interfaces. 26 | * This script gets wherever geojson is installed to temporarily remove it from installed packages so that docgen gets our interfaces. 27 | */ 28 | function geojsonDependencyPath() { 29 | // 1. check npm install path 30 | const geojsonPathNpm = path.resolve('../node_modules/@types/geojson'); 31 | if (fs.existsSync(geojsonPathNpm)) { 32 | return geojsonPathNpm; 33 | } 34 | // 2. check pnpm-style path 35 | const pnpmGlobs = glob.sync('../node_modules/.pnpm/@types+geojson@*/node_modules/@types/geojson'); 36 | if (pnpmGlobs.length > 0) { 37 | const geojsonPathPnpm = path.resolve(pnpmGlobs[0]); 38 | if (fs.existsSync(geojsonPathPnpm)) { 39 | return geojsonPathPnpm; 40 | } 41 | } 42 | // 3. no geojson found 43 | return ''; 44 | } 45 | -------------------------------------------------------------------------------- /.github/workflows/dev-releases-for-pr.yml: -------------------------------------------------------------------------------- 1 | name: Release Dev Build for PR 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - synchronize 8 | 9 | permissions: 10 | contents: write 11 | id-token: write 12 | 13 | jobs: 14 | release-dev-of-plugins: 15 | if: false 16 | runs-on: ubuntu-latest 17 | timeout-minutes: 30 18 | permissions: 19 | pull-requests: write 20 | id-token: write 21 | steps: 22 | - uses: actions/checkout@v3 23 | with: 24 | fetch-depth: 0 25 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 26 | 27 | - name: 'Setup Tools' 28 | uses: ./.github/actions/setup-tools 29 | 30 | - name: "NPM Identity" 31 | run: | 32 | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" >> ~/.npmrc 33 | npm whoami 34 | 35 | - name: Version & Publish 36 | env: 37 | PR_NUMBER: ${{ github.event.pull_request.number }} 38 | GH_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 39 | NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} 40 | run: | 41 | npm whoami 42 | npm version prerelease --no-git-tag-version -f --preid dev-$PR_NUMBER-$(date +%Y%m%dT%H%M%S) 43 | npm publish --tag dev 44 | working-directory: ./plugin 45 | 46 | - name: get-npm-version 47 | id: package-version 48 | uses: martinbeentjes/npm-get-version-action@v1.3.1 49 | with: 50 | path: ./plugin 51 | 52 | - uses: mshick/add-pr-comment@v2 53 | with: 54 | message: | 55 | Released dev build of Google Maps with dev version: ${{ steps.package-version.outputs.current-version }} 56 | -------------------------------------------------------------------------------- /plugin/eslint.config.cjs: -------------------------------------------------------------------------------- 1 | const eslintjs = require('@eslint/js'); 2 | const tseslint = require('@typescript-eslint/eslint-plugin'); 3 | const tseslintparser = require('@typescript-eslint/parser'); 4 | const prettierConfig = require('eslint-config-prettier'); 5 | 6 | module.exports = [ 7 | { 8 | ignores: ['node_modules/**', 'dist/**', 'build/**', 'e2e-tests/**', 'unit-tests/**', 'android/**', 'ios/**', 'types/**', 'eslint.config.*'], 9 | }, 10 | eslintjs.configs.recommended, 11 | { 12 | files: ['**/*.ts', '**/*.js'], 13 | languageOptions: { 14 | parser: tseslintparser, 15 | ecmaVersion: 'latest', 16 | sourceType: 'module', 17 | globals: { 18 | browser: 'readonly', 19 | window: 'readonly', 20 | document: 'readonly', 21 | console: 'readonly', 22 | HTMLElement: 'readonly', 23 | customElements: 'readonly', 24 | ResizeObserver: 'readonly', 25 | DOMRect: 'readonly', 26 | setTimeout: 'readonly', 27 | setInterval: 'readonly', 28 | clearInterval: 'readonly', 29 | clearTimeout: 'readonly', 30 | screen: 'readonly', 31 | navigator: 'readonly', 32 | GeolocationPosition: 'readonly', 33 | google: 'readonly', 34 | }, 35 | }, 36 | plugins: { 37 | '@typescript-eslint': tseslint, 38 | }, 39 | rules: { 40 | ...tseslint.configs.recommended.rules, 41 | '@typescript-eslint/no-explicit-any': 'off', 42 | '@typescript-eslint/no-unused-expressions': 'off', 43 | indent: ['error', 2], 44 | 'linebreak-style': ['error', 'unix'], 45 | quotes: ['error', 'single'], 46 | semi: ['error', 'always'], 47 | }, 48 | }, 49 | prettierConfig, 50 | ]; 51 | 52 | -------------------------------------------------------------------------------- /plugin/e2e-tests/scripts/run_Android_E2E.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ -z "$ANDROID_SDK_ROOT" ]]; then 6 | export ANDROID_SDK_ROOT=~/Library/Android/sdk 7 | fi 8 | if [[ -n "$JAVA_HOME_11_X64" ]]; then 9 | export JAVA_HOME=$JAVA_HOME_11_X64 10 | else 11 | export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jre/Contents/Home 12 | fi 13 | 14 | # Check to see if we are not in a Github Action 15 | if [[ -z $GITHUB_ACTION ]]; then 16 | 17 | ABD=$ANDROID_SDK_ROOT/platform-tools/adb 18 | EMU=$ANDROID_SDK_ROOT/emulator/emulator 19 | 20 | echo "Not in GH Action. Checking for e2eDevice Emulator..." 21 | $PWD/scripts/create_E2E_AVD.sh 22 | 23 | set +e 24 | 25 | echo 'Searching for e2eDevice...' 26 | devicesCount=`${ABD} devices | grep -c emulator` 27 | 28 | if [[ $devicesCount =~ 0 ]]; then 29 | echo 'Starting emulator...' 30 | ${EMU} -avd "e2eDevice" -no-window -noaudio -accel on -no-boot-anim -no-snapshot-save & 31 | fi 32 | 33 | bootanim="" 34 | failcounter=0 35 | timeout_in_sec=360 36 | 37 | until [[ "$bootanim" =~ "stopped" ]]; do 38 | bootanim=`${ABD} -e shell getprop init.svc.bootanim 2>&1 &` 39 | if [[ "$bootanim" =~ "device not found" || "$bootanim" =~ "device offline" 40 | || "$bootanim" =~ "running" ]]; then 41 | let "failcounter += 1" 42 | echo "Waiting for emulator to start" 43 | if [[ $failcounter -gt timeout_in_sec ]]; then 44 | echo "Timeout ($timeout_in_sec seconds) reached; failed to start emulator" 45 | exit 1 46 | fi 47 | fi 48 | sleep 1 49 | done 50 | 51 | echo "Emulator is ready" 52 | 53 | sleep 4 54 | 55 | set -e 56 | 57 | fi 58 | 59 | E2E_MODE=simulator 60 | 61 | npm run sync 62 | npm run e2e:android:build 63 | npm run e2e:android:run 64 | -------------------------------------------------------------------------------- /publish-android.yml: -------------------------------------------------------------------------------- 1 | name: Publish Native Android Libraries 2 | 3 | on: 4 | workflow_call: 5 | secrets: 6 | ANDROID_OSSRH_USERNAME: 7 | required: true 8 | ANDROID_OSSRH_PASSWORD: 9 | required: true 10 | ANDROID_SIGNING_KEY_ID: 11 | required: true 12 | ANDROID_SIGNING_PASSWORD: 13 | required: true 14 | ANDROID_SIGNING_KEY: 15 | required: true 16 | ANDROID_SONATYPE_STAGING_PROFILE_ID: 17 | required: true 18 | CAP_GH_RELEASE_TOKEN: 19 | required: true 20 | workflow_dispatch: 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | timeout-minutes: 30 25 | permissions: 26 | contents: read 27 | packages: write 28 | steps: 29 | - uses: actions/checkout@v3 30 | with: 31 | fetch-depth: 0 32 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 33 | - name: set up JDK 21 34 | uses: actions/setup-java@v4 35 | with: 36 | java-version: '21' 37 | distribution: 'zulu' 38 | - name: Grant execute permission for publishing script 39 | run: chmod +x ./scripts/publish-android.sh 40 | - name: Run publish script 41 | working-directory: ./scripts 42 | env: 43 | GITHUB_CAPACITOR_VERSION: ${{ github.event.inputs.capacitor-version }} 44 | ANDROID_OSSRH_USERNAME: ${{ secrets.ANDROID_OSSRH_USERNAME }} 45 | ANDROID_OSSRH_PASSWORD: ${{ secrets.ANDROID_OSSRH_PASSWORD }} 46 | ANDROID_SIGNING_KEY_ID: ${{ secrets.ANDROID_SIGNING_KEY_ID }} 47 | ANDROID_SIGNING_PASSWORD: ${{ secrets.ANDROID_SIGNING_PASSWORD }} 48 | ANDROID_SIGNING_KEY: ${{ secrets.ANDROID_SIGNING_KEY }} 49 | ANDROID_SONATYPE_STAGING_PROFILE_ID: ${{ secrets.ANDROID_SONATYPE_STAGING_PROFILE_ID }} 50 | run: ./publish-android.sh 51 | -------------------------------------------------------------------------------- /.github/workflows/reusable_verify-packages.yml: -------------------------------------------------------------------------------- 1 | name: "Verify Packages" 2 | 3 | on: 4 | workflow_call: 5 | secrets: 6 | CAP_GH_RELEASE_TOKEN: 7 | required: false 8 | 9 | jobs: 10 | 11 | verify-ios: 12 | runs-on: macos-15 13 | timeout-minutes: 30 14 | strategy: 15 | matrix: 16 | xcode: 17 | - /Applications/Xcode_16.4.app 18 | steps: 19 | - uses: actions/checkout@v3 20 | with: 21 | fetch-depth: 0 22 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN || github.token }} 23 | 24 | - name: 'Setup Tools' 25 | uses: ./.github/actions/setup-tools 26 | 27 | - run: sudo xcode-select --switch ${{ matrix.xcode }} 28 | 29 | - run: pnpm run verify:ios 30 | working-directory: ./plugin 31 | 32 | verify-android: 33 | runs-on: ubuntu-22.04 34 | timeout-minutes: 30 35 | steps: 36 | - uses: actions/checkout@v3 37 | with: 38 | fetch-depth: 0 39 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN || github.token }} 40 | 41 | - name: 'Setup Tools' 42 | uses: ./.github/actions/setup-tools 43 | 44 | - name: set up JDK 21 45 | uses: actions/setup-java@v4 46 | with: 47 | java-version: '21' 48 | distribution: 'zulu' 49 | 50 | - run: npm run verify:android 51 | working-directory: ./plugin 52 | 53 | verify-web: 54 | runs-on: ubuntu-22.04 55 | timeout-minutes: 30 56 | steps: 57 | - uses: actions/checkout@v3 58 | with: 59 | fetch-depth: 0 60 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN || github.token }} 61 | 62 | - name: 'Setup Tools' 63 | uses: ./.github/actions/setup-tools 64 | 65 | - run: npm run verify:web 66 | working-directory: ./plugin 67 | -------------------------------------------------------------------------------- /plugin/android/src/main/java/com/capacitorjs/plugins/googlemaps/GoogleMapCameraConfig.kt: -------------------------------------------------------------------------------- 1 | package com.capacitorjs.plugins.googlemaps 2 | 3 | import com.google.android.gms.maps.model.LatLng 4 | import org.json.JSONObject 5 | 6 | class GoogleMapCameraConfig(fromJSONObject: JSONObject) { 7 | var coordinate: LatLng? = null 8 | var zoom: Double? = null 9 | var angle: Double? = null 10 | var bearing: Double? = null 11 | var animate: Boolean? = null 12 | var animationDuration: Double? = null 13 | 14 | init { 15 | if (fromJSONObject.has("zoom")) { 16 | zoom = fromJSONObject.getDouble("zoom") 17 | } 18 | 19 | if(fromJSONObject.has("angle")) { 20 | angle = fromJSONObject.getDouble("angle") 21 | } 22 | 23 | if (fromJSONObject.has("bearing")) { 24 | bearing = fromJSONObject.getDouble("bearing") 25 | } 26 | 27 | if (fromJSONObject.has("animate")) { 28 | animate = fromJSONObject.getBoolean("animate") 29 | } 30 | 31 | if (fromJSONObject.has("animationDuration")) { 32 | animationDuration = fromJSONObject.getDouble("animationDuration") 33 | } 34 | 35 | if (fromJSONObject.has("coordinate")) { 36 | val coordinateJSONObject = fromJSONObject.getJSONObject("coordinate") 37 | if(!coordinateJSONObject.has("lat") || !coordinateJSONObject.has("lng")) { 38 | throw InvalidArgumentsError("LatLng object is missing the required 'lat' and/or 'lng' property") 39 | } 40 | 41 | val lat = coordinateJSONObject.getDouble("lat") 42 | val lng = coordinateJSONObject.getDouble("lng") 43 | coordinate = LatLng(lat, lng) 44 | } else { 45 | coordinate = null 46 | } 47 | } 48 | 49 | 50 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root", 3 | "private": true, 4 | "scripts": { 5 | "prepare": "husky", 6 | "build": "lerna run build && yes | cp ./plugin/README.md ./README.md", 7 | "lint": "pnpm lerna run lint", 8 | "fmt": "pnpm lerna run fmt", 9 | "publish:cocoapod": "lerna run publish:cocoapod --concurrency 1", 10 | "ci:publish:nightly": "lerna publish prerelease --conventional-commits --conventional-prerelease --preid nightly-$(date +\"%Y%m%dT%H%M%S\") --force-publish --no-changelog --no-git-tag-version --dist-tag nightly --no-push --yes", 11 | "ci:publish:alpha": "lerna publish prerelease --conventional-commits --conventional-prerelease --preid alpha --force-publish --dist-tag next --yes", 12 | "ci:publish:beta": "lerna publish prerelease --conventional-commits --conventional-prerelease --preid beta --force-publish --dist-tag next --yes", 13 | "ci:publish:rc": "lerna publish prerelease --conventional-commits --conventional-prerelease --preid rc --force-publish --dist-tag next --yes", 14 | "ci:publish:latest": "lerna publish --conventional-commits --dist-tag latest --no-verify-access --yes", 15 | "ci:publish:latest-from-pre": "lerna publish --conventional-graduate --conventional-commits --dist-tag latest --no-verify-access --force-publish --yes", 16 | "ci:publish:dev": "lerna publish prerelease --conventional-commits --conventional-prerelease --preid dev-$(date +\"%Y%m%dT%H%M%S\") --force-publish --no-changelog --no-git-tag-version --dist-tag dev --no-push --yes" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "^24.10.1", 20 | "glob": "^13.0.0", 21 | "husky": "^9.1.7", 22 | "lerna": "^9.0.1", 23 | "typescript": "^5.9.3" 24 | }, 25 | "engines": { 26 | "node": ">=20", 27 | "pnpm": ">=8" 28 | }, 29 | "workspaces": [ 30 | "plugin" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdkVersion 31 8 | buildToolsVersion "30.0.3" 9 | 10 | defaultConfig { 11 | applicationId "io.ionic.googlemapstest" 12 | minSdkVersion 22 13 | targetSdkVersion 31 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.ext.junit.runners.AndroidJUnit4" 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility JavaVersion.VERSION_1_8 28 | targetCompatibility JavaVersion.VERSION_1_8 29 | } 30 | kotlinOptions { 31 | jvmTarget = '1.8' 32 | } 33 | sourceSets { 34 | main.java.srcDirs += '../../../android' 35 | } 36 | testOptions { 37 | unitTests { 38 | includeAndroidResources = true 39 | } 40 | unitTests.all { 41 | testLogging { 42 | events "passed", "skipped", "failed", "standardOut", "standardError" 43 | outputs.upToDateWhen {false} 44 | showStandardStreams = false 45 | } 46 | } 47 | } 48 | } 49 | 50 | dependencies { 51 | implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}" 52 | implementation 'androidx.core:core-ktx:1.7.0' 53 | implementation 'androidx.appcompat:appcompat:1.4.0' 54 | implementation 'com.google.android.material:material:1.4.0' 55 | implementation 'junit:junit:4.13.2' 56 | testImplementation 'org.robolectric:robolectric:4.7.1' 57 | implementation project(':capacitor-android') 58 | } -------------------------------------------------------------------------------- /plugin/unit-tests/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /plugin/e2e-tests/scripts/create_E2E_AVD.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CPU_ARCH=`uname -p`"" 4 | 5 | SDKMANAGER=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager 6 | AVDMANAGER=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/avdmanager 7 | ABD=$ANDROID_SDK_ROOT/platform-tools/adb 8 | EMU=$ANDROID_SDK_ROOT/emulator/emulator 9 | 10 | E2E_DEVICE_EXISTS=`${EMU} -list-avds | grep -c e2eDevice` 11 | 12 | if [[ $E2E_DEVICE_EXISTS -lt 1 ]]; then 13 | echo "Creating e2eDevice AVD..." 14 | echo "" 15 | 16 | echo "CPU_ARCH: $CPU_ARCH" 17 | echo "JAVA_HOME: $JAVA_HOME" 18 | echo "ANDROID_SDK_ROOT: $ANDROID_SDK_ROOT" 19 | echo "" 20 | echo "--------------------------" 21 | echo "" 22 | 23 | echo "Accepting Lics..." 24 | sh -c \yes | ${SDKMANAGER} --licenses > /dev/null 25 | 26 | echo "Installing build-tools..." 27 | ${SDKMANAGER} --install 'build-tools;31.0.0' platform-tools 'platforms;android-31' 28 | echo "Installing emulator..." 29 | ${SDKMANAGER} --install emulator --channel=0 30 | echo "Installing sys-image..." 31 | 32 | # If we are on arm (m1 mac) use arm images, else use x86_64 33 | if [ "$CPU_ARCH" = "arm" ]; then 34 | ${SDKMANAGER} --install 'system-images;android-31;google_apis;arm64-v8a' --channel=0 35 | else 36 | ${SDKMANAGER} --install 'system-images;android-31;google_apis;x86_64' --channel=0 37 | fi 38 | 39 | echo "Killing all running emulators..." 40 | ${ABD} devices | grep emulator | cut -f1 | while read line; do ${ABD} -s $line emu kill; done; 41 | 42 | echo "Creating AVD..." 43 | if [ "$CPU_ARCH" = "arm" ]; then 44 | ${AVDMANAGER} --verbose create avd -n e2eDevice -k "system-images;android-31;google_apis;arm64-v8a" --device "pixel_3a" 45 | else 46 | ${AVDMANAGER} --verbose create avd -n e2eDevice -k "system-images;android-31;google_apis;x86_64" --device "pixel_3a" 47 | fi 48 | 49 | else 50 | echo "e2eDevice AVD exists!" 51 | fi 52 | 53 | echo "" 54 | 55 | 56 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/CapApp-SPM/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.9 2 | import PackageDescription 3 | 4 | // DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands 5 | let package = Package( 6 | name: "CapApp-SPM", 7 | platforms: [.iOS(.v15)], 8 | products: [ 9 | .library( 10 | name: "CapApp-SPM", 11 | targets: ["CapApp-SPM"]) 12 | ], 13 | dependencies: [ 14 | .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", exact: "8.0.0"), 15 | .package(name: "CapacitorApp", path: "../../../../node_modules/.pnpm/@capacitor+app@8.0.0_@capacitor+core@8.0.0/node_modules/@capacitor/app"), 16 | .package(name: "CapacitorGoogleMaps", path: "../../../../plugin"), 17 | .package(name: "CapacitorHaptics", path: "../../../../node_modules/.pnpm/@capacitor+haptics@8.0.0_@capacitor+core@8.0.0/node_modules/@capacitor/haptics"), 18 | .package(name: "CapacitorKeyboard", path: "../../../../node_modules/.pnpm/@capacitor+keyboard@8.0.0_@capacitor+core@8.0.0/node_modules/@capacitor/keyboard"), 19 | .package(name: "CapacitorStatusBar", path: "../../../../node_modules/.pnpm/@capacitor+status-bar@8.0.0_@capacitor+core@8.0.0/node_modules/@capacitor/status-bar") 20 | ], 21 | targets: [ 22 | .target( 23 | name: "CapApp-SPM", 24 | dependencies: [ 25 | .product(name: "Capacitor", package: "capacitor-swift-pm"), 26 | .product(name: "Cordova", package: "capacitor-swift-pm"), 27 | .product(name: "CapacitorApp", package: "CapacitorApp"), 28 | .product(name: "CapacitorGoogleMaps", package: "CapacitorGoogleMaps"), 29 | .product(name: "CapacitorHaptics", package: "CapacitorHaptics"), 30 | .product(name: "CapacitorKeyboard", package: "CapacitorKeyboard"), 31 | .product(name: "CapacitorStatusBar", package: "CapacitorStatusBar") 32 | ] 33 | ) 34 | ] 35 | ) 36 | -------------------------------------------------------------------------------- /example-app-spm/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { IonApp, IonRouterOutlet, IonSplitPane, setupIonicReact } from '@ionic/react'; 2 | import { IonReactRouter } from '@ionic/react-router'; 3 | import { Redirect, Route } from 'react-router-dom'; 4 | import Menu from './components/Menu'; 5 | 6 | /* Core CSS required for Ionic components to work properly */ 7 | import '@ionic/react/css/core.css'; 8 | 9 | /* Basic CSS for apps built with Ionic */ 10 | import '@ionic/react/css/normalize.css'; 11 | import '@ionic/react/css/structure.css'; 12 | import '@ionic/react/css/typography.css'; 13 | 14 | /* Optional CSS utils that can be commented out */ 15 | import '@ionic/react/css/padding.css'; 16 | import '@ionic/react/css/float-elements.css'; 17 | import '@ionic/react/css/text-alignment.css'; 18 | import '@ionic/react/css/text-transformation.css'; 19 | import '@ionic/react/css/flex-utils.css'; 20 | import '@ionic/react/css/display.css'; 21 | 22 | /* Theme variables */ 23 | import './theme/variables.css'; 24 | 25 | import { getRouterSetup } from './routes'; 26 | import Home from './pages/Home'; 27 | 28 | setupIonicReact(); 29 | 30 | const App: React.FC = () => { 31 | const routes = getRouterSetup(); 32 | 33 | return ( 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {routes.map((route, idx) => { 46 | return ( 47 | 48 | 49 | 50 | ); 51 | })} 52 | 53 | 54 | 55 | 56 | ); 57 | }; 58 | 59 | export default App; 60 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | e2e-tests 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 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSAllowsArbitraryLoads 28 | 29 | 30 | NSLocationWhenInUseUsageDescription 31 | Using Test App Location 32 | UILaunchStoryboardName 33 | LaunchScreen 34 | UIMainStoryboardFile 35 | Main 36 | UIRequiredDeviceCapabilities 37 | 38 | armv7 39 | 40 | UISupportedInterfaceOrientations 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UISupportedInterfaceOrientations~ipad 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationPortraitUpsideDown 50 | UIInterfaceOrientationLandscapeLeft 51 | UIInterfaceOrientationLandscapeRight 52 | 53 | UIViewControllerBasedStatusBarAppearance 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { IonApp, IonRouterOutlet, IonSplitPane, setupIonicReact } from '@ionic/react'; 2 | import { IonReactRouter } from '@ionic/react-router'; 3 | import { Redirect, Route } from 'react-router-dom'; 4 | import Menu from './components/Menu'; 5 | 6 | /* Core CSS required for Ionic components to work properly */ 7 | import '@ionic/react/css/core.css'; 8 | 9 | /* Basic CSS for apps built with Ionic */ 10 | import '@ionic/react/css/normalize.css'; 11 | import '@ionic/react/css/structure.css'; 12 | import '@ionic/react/css/typography.css'; 13 | 14 | /* Optional CSS utils that can be commented out */ 15 | import '@ionic/react/css/padding.css'; 16 | import '@ionic/react/css/float-elements.css'; 17 | import '@ionic/react/css/text-alignment.css'; 18 | import '@ionic/react/css/text-transformation.css'; 19 | import '@ionic/react/css/flex-utils.css'; 20 | import '@ionic/react/css/display.css'; 21 | 22 | /* Theme variables */ 23 | import './theme/variables.css'; 24 | 25 | import { getRouterSetup } from './routes'; 26 | import Home from './pages/Home'; 27 | 28 | setupIonicReact(); 29 | 30 | const App: React.FC = () => { 31 | const routes = getRouterSetup(); 32 | 33 | return ( 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {routes.map((route, idx) => { 46 | return ( 47 | 48 | 49 | 50 | ); 51 | })} 52 | 53 | 54 | 55 | 56 | ); 57 | }; 58 | 59 | export default App; 60 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/specs/map/create-and-destroy.spec.ts: -------------------------------------------------------------------------------- 1 | import * as IonicE2E from '@ionic/e2e'; 2 | import { waitForLoad, pause, setDevice, switchToWeb, url } from '@ionic/e2e'; 3 | 4 | import CreateAndDestroyMapPage from '../../pageobjects/map/create-and-destroy.page'; 5 | 6 | 7 | describe('Google Maps - Create and Destroy Map', function () { 8 | before(async function () { 9 | await waitForLoad(); 10 | await switchToWeb(); 11 | await url('/maps/create-and-destroy'); 12 | await pause(500); 13 | }); 14 | 15 | beforeEach(async function () { 16 | await setDevice(IonicE2E.Device.Mobile); 17 | await switchToWeb(); 18 | await CreateAndDestroyMapPage.hideToolBars(); 19 | }); 20 | 21 | after(async function () { 22 | await switchToWeb(); 23 | await CreateAndDestroyMapPage.showToolBars(); 24 | await pause(500); 25 | }); 26 | 27 | it('should create and destroy a map', async function() { 28 | const createMapButton = await CreateAndDestroyMapPage.createMapButton; 29 | const destroyMapButton = await CreateAndDestroyMapPage.destroyMapButton; 30 | const getCommandOutputText = async function() { 31 | return (await CreateAndDestroyMapPage.commandOutputTextarea).getValue(); 32 | } 33 | 34 | await createMapButton.tap(); 35 | await pause(500); 36 | await expect(await getCommandOutputText()).toBe('Maps created'); 37 | 38 | await destroyMapButton.tap(); 39 | await pause(500); 40 | await expect(await getCommandOutputText()).toBe('Maps destroyed'); 41 | }); 42 | 43 | it('should throw when attempting to destroy a non-existent map', async function() { 44 | const destroyMapButton = await CreateAndDestroyMapPage.destroyMapButton; 45 | const getCommandOutputText = async function() { 46 | return (await CreateAndDestroyMapPage.commandOutputTextarea).getValue(); 47 | } 48 | 49 | await destroyMapButton.tap(); 50 | await pause(100); 51 | await expect(await getCommandOutputText()).toBe('Map not found for provided id.'); 52 | }); 53 | 54 | 55 | }); 56 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /plugin/unit-tests/ios/GoogleMapsPlugin/TestApp/Assets.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" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CAPACITOR_DEBUG 6 | $(CAPACITOR_DEBUG) 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleDisplayName 10 | example-app-spm 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | $(MARKETING_VERSION) 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | 32 | NSLocationWhenInUseUsageDescription 33 | Using Test App Location 34 | UILaunchStoryboardName 35 | LaunchScreen 36 | UIMainStoryboardFile 37 | Main 38 | UIRequiredDeviceCapabilities 39 | 40 | armv7 41 | 42 | UISupportedInterfaceOrientations 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | UISupportedInterfaceOrientations~ipad 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationPortraitUpsideDown 52 | UIInterfaceOrientationLandscapeLeft 53 | UIInterfaceOrientationLandscapeRight 54 | 55 | UIViewControllerBasedStatusBarAppearance 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /plugin/ios/Sources/CapacitorGoogleMapsPlugin/GoogleMapErrors.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public enum GoogleMapErrors: Error { 4 | case invalidMapId 5 | case mapNotFound 6 | case markerNotFound 7 | case invalidArguments(_ description: String) 8 | case invalidAPIKey 9 | case permissionsDeniedLocation 10 | case unhandledError(_ description: String) 11 | case tileOverlayNotFound 12 | } 13 | 14 | public struct GoogleMapErrorObject { 15 | let extra: [String: Any]? 16 | let code: Int 17 | let message: String 18 | init(_ code: Int, _ message: String, _ extra: [String: Any]? = nil) { 19 | self.code = code 20 | self.message = message 21 | self.extra = extra 22 | } 23 | 24 | var asDictionary: [String: Any] { 25 | return ["code": code, "message": message, "extra": extra ?? []] 26 | } 27 | } 28 | 29 | public func getErrorObject(_ error: Error) -> GoogleMapErrorObject { 30 | switch error { 31 | case GoogleMapErrors.invalidMapId: 32 | return GoogleMapErrorObject(1, "Missing or invalid map id.") 33 | case GoogleMapErrors.mapNotFound: 34 | return GoogleMapErrorObject(2, "Map not found for provided id.") 35 | case GoogleMapErrors.markerNotFound: 36 | return GoogleMapErrorObject(3, "Marker not found for provided id.") 37 | case GoogleMapErrors.invalidArguments(let msg): 38 | return GoogleMapErrorObject(4, "Invalid Arguments Provided: \(msg)") 39 | case GoogleMapErrors.permissionsDeniedLocation: 40 | return GoogleMapErrorObject(5, "Permissions denied for accessing device location.") 41 | case GoogleMapErrors.invalidAPIKey: 42 | return GoogleMapErrorObject(6, "Missing or invalid Google Maps SDK API key.") 43 | case GoogleMapErrors.tileOverlayNotFound: 44 | return GoogleMapErrorObject(7, "Tile overlay not found for provided id.") 45 | case GoogleMapErrors.unhandledError(let msg): 46 | return GoogleMapErrorObject(0, "Unhandled Error: \(msg)") 47 | default: 48 | return GoogleMapErrorObject(0, "Unhandled Error: \(error.localizedDescription)") 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /example-app-spm/ios/App/App/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /plugin/e2e-tests/ios/App/App/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /example-app-spm/src/components/Menu.tsx: -------------------------------------------------------------------------------- 1 | import { IonContent, IonIcon, IonItem, IonLabel, IonList, IonListHeader, IonMenu, IonMenuToggle } from '@ionic/react'; 2 | import { useLocation } from 'react-router-dom'; 3 | import './Menu.css'; 4 | import { useEffect, useState } from 'react'; 5 | import { getMenuList, RouteGroup } from '../routes'; 6 | import { homeOutline } from 'ionicons/icons'; 7 | 8 | const Menu: React.FC = () => { 9 | const location = useLocation(); 10 | const [menu, setMenu] = useState([]); 11 | 12 | useEffect(() => { 13 | setMenu(getMenuList()); 14 | }, []); 15 | 16 | return ( 17 | 18 | 19 | 20 | 21 | 28 | 29 | Home 30 | 31 | 32 | 33 | {menu.map((routeGroup, indx) => { 34 | return ( 35 | 36 | {routeGroup.groupName} 37 | {routeGroup.pages.map((routeDescription, index) => { 38 | return ( 39 | 40 | 47 | 48 | {routeDescription.title} 49 | 50 | 51 | ); 52 | })} 53 | 54 | ); 55 | })} 56 | 57 | 58 | ); 59 | }; 60 | 61 | export default Menu; 62 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/components/Menu.tsx: -------------------------------------------------------------------------------- 1 | import { IonContent, IonIcon, IonItem, IonLabel, IonList, IonListHeader, IonMenu, IonMenuToggle } from '@ionic/react'; 2 | import { useLocation } from 'react-router-dom'; 3 | import './Menu.css'; 4 | import { useEffect, useState } from 'react'; 5 | import { getMenuList, RouteGroup } from '../routes'; 6 | import { homeOutline } from 'ionicons/icons'; 7 | 8 | const Menu: React.FC = () => { 9 | const location = useLocation(); 10 | const [menu, setMenu] = useState([]); 11 | 12 | useEffect(() => { 13 | setMenu(getMenuList()); 14 | }, []); 15 | 16 | return ( 17 | 18 | 19 | 20 | 21 | 28 | 29 | Home 30 | 31 | 32 | 33 | {menu.map((routeGroup, indx) => { 34 | return ( 35 | 36 | {routeGroup.groupName} 37 | {routeGroup.pages.map((routeDescription, index) => { 38 | return ( 39 | 40 | 47 | 48 | {routeDescription.title} 49 | 50 | 51 | ); 52 | })} 53 | 54 | ); 55 | })} 56 | 57 | 58 | ); 59 | }; 60 | 61 | export default Menu; 62 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/.gitignore: -------------------------------------------------------------------------------- 1 | # Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore 2 | 3 | # Built application files 4 | *.apk 5 | *.aar 6 | *.ap_ 7 | *.aab 8 | 9 | # Files for the ART/Dalvik VM 10 | *.dex 11 | 12 | # Java class files 13 | *.class 14 | 15 | # Generated files 16 | bin/ 17 | gen/ 18 | out/ 19 | # Uncomment the following line in case you need and you don't have the release build type files in your app 20 | # release/ 21 | 22 | # Gradle files 23 | .gradle/ 24 | build/ 25 | 26 | # Local configuration file (sdk path, etc) 27 | local.properties 28 | 29 | # Proguard folder generated by Eclipse 30 | proguard/ 31 | 32 | # Log Files 33 | *.log 34 | 35 | # Android Studio Navigation editor temp files 36 | .navigation/ 37 | 38 | # Android Studio captures folder 39 | captures/ 40 | 41 | # IntelliJ 42 | *.iml 43 | .idea/workspace.xml 44 | .idea/tasks.xml 45 | .idea/gradle.xml 46 | .idea/assetWizardSettings.xml 47 | .idea/dictionaries 48 | .idea/libraries 49 | # Android Studio 3 in .gitignore file. 50 | .idea/caches 51 | .idea/modules.xml 52 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 53 | .idea/navEditor.xml 54 | 55 | # Keystore files 56 | # Uncomment the following lines if you do not want to check your keystore files in. 57 | #*.jks 58 | #*.keystore 59 | 60 | # External native build folder generated in Android Studio 2.2 and later 61 | .externalNativeBuild 62 | .cxx/ 63 | 64 | # Google Services (e.g. APIs or Firebase) 65 | # google-services.json 66 | 67 | # Freeline 68 | freeline.py 69 | freeline/ 70 | freeline_project_description.json 71 | 72 | # fastlane 73 | fastlane/report.xml 74 | fastlane/Preview.html 75 | fastlane/screenshots 76 | fastlane/test_output 77 | fastlane/readme.md 78 | 79 | # Version control 80 | vcs.xml 81 | 82 | # lint 83 | lint/intermediates/ 84 | lint/generated/ 85 | lint/outputs/ 86 | lint/tmp/ 87 | # lint/reports/ 88 | 89 | # Android Profiling 90 | *.hprof 91 | 92 | # Cordova plugins for Capacitor 93 | capacitor-cordova-android-plugins 94 | 95 | # Copied web assets 96 | app/src/main/assets/public 97 | 98 | # Generated Config files 99 | app/src/main/assets/capacitor.config.json 100 | app/src/main/assets/capacitor.plugins.json 101 | app/src/main/res/xml/config.xml 102 | -------------------------------------------------------------------------------- /plugin/ios/Sources/CapacitorGoogleMapsPlugin/Circle.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Capacitor 3 | 4 | public struct Circle { 5 | let center: LatLng 6 | let radius: Double 7 | let strokeWidth: CGFloat 8 | let strokeColor: UIColor 9 | let fillColor: UIColor 10 | let tappable: Bool? 11 | let title: String? 12 | let zIndex: Int32 13 | let tag: String? 14 | 15 | init(from jsObject: JSObject) throws { 16 | var strokeColor = UIColor.blue 17 | var strokeWidth: CGFloat = 1.0 18 | var fillColor = UIColor.blue 19 | 20 | guard let centerLatLng = jsObject["center"] as? JSObject else { 21 | throw GoogleMapErrors.invalidArguments("Circle object is missing the required 'center' property") 22 | } 23 | 24 | guard let lat = centerLatLng["lat"] as? Double, let lng = centerLatLng["lng"] as? Double else { 25 | throw GoogleMapErrors.invalidArguments("LatLng object is missing the required 'lat' and/or 'lng' property") 26 | } 27 | 28 | guard let radius = jsObject["radius"] as? Double else { 29 | throw GoogleMapErrors.invalidArguments("Circle object is missing the required 'radius' property") 30 | } 31 | 32 | if let width = jsObject["strokeWeight"] as? Float { 33 | strokeWidth = CGFloat(width) 34 | } 35 | 36 | let strokeOpacity = jsObject["strokeOpacity"] as? Double 37 | 38 | if let hexColor = jsObject["strokeColor"] as? String { 39 | strokeColor = UIColor(hex: hexColor) ?? UIColor.blue 40 | } 41 | 42 | strokeColor = strokeColor.withAlphaComponent(strokeOpacity ?? 1.0) 43 | 44 | let fillOpacity = jsObject["fillOpacity"] as? Double 45 | 46 | if let hexColor = jsObject["fillColor"] as? String { 47 | fillColor = UIColor(hex: hexColor) ?? UIColor.blue 48 | } 49 | 50 | fillColor = fillColor.withAlphaComponent(fillOpacity ?? 1.0) 51 | 52 | self.center = LatLng(lat: lat, lng: lng) 53 | self.radius = radius 54 | self.fillColor = fillColor 55 | self.strokeColor = strokeColor 56 | self.strokeWidth = strokeWidth 57 | self.tag = jsObject["tag"] as? String 58 | self.tappable = jsObject["clickable"] as? Bool 59 | self.title = jsObject["title"] as? String 60 | self.zIndex = Int32((jsObject["zIndex"] as? Int) ?? 0) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /example-app-spm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-app-spm", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@capacitor/android": "^8.0.0", 7 | "@capacitor/app": "^8.0.0", 8 | "@capacitor/core": "^8.0.0", 9 | "@capacitor/google-maps": "workspace:*", 10 | "@capacitor/haptics": "^8.0.0", 11 | "@capacitor/ios": "^8.0.0", 12 | "@capacitor/keyboard": "^8.0.0", 13 | "@capacitor/status-bar": "^8.0.0", 14 | "@ionic/react": "^8.7.11", 15 | "@ionic/react-router": "^8.7.11", 16 | "@testing-library/jest-dom": "^6.9.1", 17 | "@testing-library/react": "^16.3.0", 18 | "@testing-library/user-event": "^14.6.1", 19 | "@types/google.maps": "~3.58.1", 20 | "@types/jest": "^30.0.0", 21 | "@types/node": "^24.10.2", 22 | "@types/react": "^19.2.7", 23 | "@types/react-dom": "^19.2.3", 24 | "@types/react-router": "^5.1.20", 25 | "@types/react-router-dom": "^5.3.3", 26 | "ionicons": "^8.0.13", 27 | "react": "^19.2.1", 28 | "react-dom": "^19.2.1", 29 | "react-router": "^5.3.4", 30 | "react-router-dom": "^5.3.4", 31 | "react-scripts": "^5.0.1", 32 | "typescript": "^5.9.3", 33 | "web-vitals": "^5.1.0", 34 | "workbox-background-sync": "^7.4.0", 35 | "workbox-broadcast-update": "^7.4.0", 36 | "workbox-cacheable-response": "^7.4.0", 37 | "workbox-core": "^7.4.0", 38 | "workbox-expiration": "^7.4.0", 39 | "workbox-google-analytics": "^7.4.0", 40 | "workbox-navigation-preload": "^7.4.0", 41 | "workbox-precaching": "^7.4.0", 42 | "workbox-range-requests": "^7.4.0", 43 | "workbox-routing": "^7.4.0", 44 | "workbox-strategies": "^7.4.0", 45 | "workbox-streams": "^7.4.0" 46 | }, 47 | "scripts": { 48 | "start": "react-scripts start", 49 | "build": "react-scripts build", 50 | "eject": "react-scripts eject", 51 | "sync": "npm run build && npx cap sync" 52 | }, 53 | "eslintConfig": { 54 | "extends": [ 55 | "react-app", 56 | "react-app/jest" 57 | ] 58 | }, 59 | "browserslist": { 60 | "production": [ 61 | ">0.2%", 62 | "not dead", 63 | "not op_mini all" 64 | ], 65 | "development": [ 66 | "last 1 chrome version", 67 | "last 1 firefox version", 68 | "last 1 safari version" 69 | ] 70 | }, 71 | "devDependencies": { 72 | "@capacitor/cli": "^8.0.0" 73 | }, 74 | "description": "An Ionic project" 75 | } -------------------------------------------------------------------------------- /example-app-spm/src/components/Menu.css: -------------------------------------------------------------------------------- 1 | ion-menu ion-content { 2 | --background: var(--ion-item-background, var(--ion-background-color, #fff)); 3 | } 4 | 5 | ion-menu.md ion-content { 6 | --padding-start: 8px; 7 | --padding-end: 8px; 8 | --padding-top: 20px; 9 | --padding-bottom: 20px; 10 | } 11 | 12 | ion-menu.md ion-list { 13 | padding: 20px 0; 14 | } 15 | 16 | ion-menu.md ion-note { 17 | margin-bottom: 30px; 18 | } 19 | 20 | ion-menu.md ion-list-header, 21 | ion-menu.md ion-note { 22 | padding-left: 10px; 23 | } 24 | 25 | ion-menu.md ion-list#inbox-list { 26 | border-bottom: 1px solid var(--ion-color-step-150, #d7d8da); 27 | } 28 | 29 | ion-menu.md ion-list#inbox-list ion-list-header { 30 | font-size: 22px; 31 | font-weight: 600; 32 | min-height: 20px; 33 | } 34 | 35 | ion-menu.md ion-list#labels-list ion-list-header { 36 | font-size: 16px; 37 | margin-bottom: 18px; 38 | color: #757575; 39 | min-height: 26px; 40 | } 41 | 42 | ion-menu.md ion-item { 43 | --padding-start: 10px; 44 | --padding-end: 10px; 45 | border-radius: 4px; 46 | } 47 | 48 | ion-menu.md ion-item.selected { 49 | --background: rgba(var(--ion-color-primary-rgb), 0.14); 50 | } 51 | 52 | ion-menu.md ion-item.selected ion-icon { 53 | color: var(--ion-color-primary); 54 | } 55 | 56 | ion-menu.md ion-item ion-icon { 57 | color: #616e7e; 58 | } 59 | 60 | ion-menu.md ion-item ion-label { 61 | font-weight: 500; 62 | } 63 | 64 | ion-menu.ios ion-content { 65 | --padding-bottom: 20px; 66 | } 67 | 68 | ion-menu.ios ion-list { 69 | padding: 20px 0 0 0; 70 | } 71 | 72 | ion-menu.ios ion-note { 73 | line-height: 24px; 74 | margin-bottom: 20px; 75 | } 76 | 77 | ion-menu.ios ion-item { 78 | --padding-start: 16px; 79 | --padding-end: 16px; 80 | --min-height: 50px; 81 | } 82 | 83 | ion-menu.ios ion-item ion-icon { 84 | font-size: 24px; 85 | color: #73849a; 86 | } 87 | 88 | ion-menu.ios ion-item .selected ion-icon { 89 | color: var(--ion-color-primary); 90 | } 91 | 92 | ion-menu.ios ion-list#labels-list ion-list-header { 93 | margin-bottom: 8px; 94 | } 95 | 96 | ion-menu.ios ion-list-header, 97 | ion-menu.ios ion-note { 98 | padding-left: 16px; 99 | padding-right: 16px; 100 | } 101 | 102 | ion-menu.ios ion-note { 103 | margin-bottom: 8px; 104 | } 105 | 106 | ion-note { 107 | display: inline-block; 108 | font-size: 16px; 109 | color: var(--ion-color-medium-shade); 110 | } 111 | 112 | ion-item.selected { 113 | --color: var(--ion-color-primary); 114 | } 115 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/components/Menu.css: -------------------------------------------------------------------------------- 1 | ion-menu ion-content { 2 | --background: var(--ion-item-background, var(--ion-background-color, #fff)); 3 | } 4 | 5 | ion-menu.md ion-content { 6 | --padding-start: 8px; 7 | --padding-end: 8px; 8 | --padding-top: 20px; 9 | --padding-bottom: 20px; 10 | } 11 | 12 | ion-menu.md ion-list { 13 | padding: 20px 0; 14 | } 15 | 16 | ion-menu.md ion-note { 17 | margin-bottom: 30px; 18 | } 19 | 20 | ion-menu.md ion-list-header, 21 | ion-menu.md ion-note { 22 | padding-left: 10px; 23 | } 24 | 25 | ion-menu.md ion-list#inbox-list { 26 | border-bottom: 1px solid var(--ion-color-step-150, #d7d8da); 27 | } 28 | 29 | ion-menu.md ion-list#inbox-list ion-list-header { 30 | font-size: 22px; 31 | font-weight: 600; 32 | min-height: 20px; 33 | } 34 | 35 | ion-menu.md ion-list#labels-list ion-list-header { 36 | font-size: 16px; 37 | margin-bottom: 18px; 38 | color: #757575; 39 | min-height: 26px; 40 | } 41 | 42 | ion-menu.md ion-item { 43 | --padding-start: 10px; 44 | --padding-end: 10px; 45 | border-radius: 4px; 46 | } 47 | 48 | ion-menu.md ion-item.selected { 49 | --background: rgba(var(--ion-color-primary-rgb), 0.14); 50 | } 51 | 52 | ion-menu.md ion-item.selected ion-icon { 53 | color: var(--ion-color-primary); 54 | } 55 | 56 | ion-menu.md ion-item ion-icon { 57 | color: #616e7e; 58 | } 59 | 60 | ion-menu.md ion-item ion-label { 61 | font-weight: 500; 62 | } 63 | 64 | ion-menu.ios ion-content { 65 | --padding-bottom: 20px; 66 | } 67 | 68 | ion-menu.ios ion-list { 69 | padding: 20px 0 0 0; 70 | } 71 | 72 | ion-menu.ios ion-note { 73 | line-height: 24px; 74 | margin-bottom: 20px; 75 | } 76 | 77 | ion-menu.ios ion-item { 78 | --padding-start: 16px; 79 | --padding-end: 16px; 80 | --min-height: 50px; 81 | } 82 | 83 | ion-menu.ios ion-item ion-icon { 84 | font-size: 24px; 85 | color: #73849a; 86 | } 87 | 88 | ion-menu.ios ion-item .selected ion-icon { 89 | color: var(--ion-color-primary); 90 | } 91 | 92 | ion-menu.ios ion-list#labels-list ion-list-header { 93 | margin-bottom: 8px; 94 | } 95 | 96 | ion-menu.ios ion-list-header, 97 | ion-menu.ios ion-note { 98 | padding-left: 16px; 99 | padding-right: 16px; 100 | } 101 | 102 | ion-menu.ios ion-note { 103 | margin-bottom: 8px; 104 | } 105 | 106 | ion-note { 107 | display: inline-block; 108 | font-size: 16px; 109 | color: var(--ion-color-medium-shade); 110 | } 111 | 112 | ion-item.selected { 113 | --color: var(--ion-color-primary); 114 | } 115 | -------------------------------------------------------------------------------- /plugin/android/src/main/java/com/capacitorjs/plugins/googlemaps/CapacitorGoogleMapsCircle.kt: -------------------------------------------------------------------------------- 1 | package com.capacitorjs.plugins.googlemaps 2 | 3 | import android.graphics.Color 4 | import com.google.android.gms.maps.model.Circle 5 | import com.google.android.gms.maps.model.LatLng 6 | import org.json.JSONObject 7 | 8 | class CapacitorGoogleMapsCircle(fromJSONObject: JSONObject) { 9 | var center: LatLng 10 | var radius: Float 11 | var strokeWidth: Float = 1.0f 12 | var strokeColor: Int = Color.BLUE 13 | var fillColor: Int = Color.BLUE 14 | var clickable: Boolean 15 | var zIndex: Float = 0.00f 16 | var tag: String = "" 17 | var googleMapsCircle: Circle? = null 18 | 19 | init { 20 | if (!fromJSONObject.has("center")) { 21 | throw InvalidArgumentsError("Circle object is missing the required 'center' property") 22 | } 23 | 24 | if (!fromJSONObject.has("radius")) { 25 | throw InvalidArgumentsError("Circle object is missing the required 'radius' property") 26 | } 27 | 28 | val latLng = fromJSONObject.getJSONObject("center") 29 | if (!latLng.has("lat") || !latLng.has("lng")) { 30 | throw InvalidArgumentsError("LatLng object is missing the required 'lat' and/or 'lng' property") 31 | } 32 | 33 | val lat = latLng.getDouble("lat") 34 | val lng = latLng.getDouble("lng") 35 | 36 | center = LatLng(lat, lng) 37 | 38 | radius = fromJSONObject.getDouble("radius").toFloat() 39 | 40 | val strokeOpacity = fromJSONObject.optDouble("strokeOpacity", 1.0) 41 | strokeColor = this.processColor(fromJSONObject.getString("strokeColor"), strokeOpacity) 42 | 43 | val fillOpacity = fromJSONObject.optDouble("fillOpacity", 1.0) 44 | fillColor = this.processColor(fromJSONObject.getString("fillColor"), fillOpacity) 45 | 46 | strokeWidth = fromJSONObject.optDouble("strokeWeight", 1.0).toFloat() 47 | clickable = fromJSONObject.optBoolean("clickable", false) 48 | zIndex = fromJSONObject.optDouble("zIndex", 1.0).toFloat() 49 | tag = fromJSONObject.optString("tag", "") 50 | } 51 | 52 | 53 | private fun processColor(hex: String, opacity: Double): Int { 54 | val colorInt = Color.parseColor(hex) 55 | 56 | val alpha = (opacity * 255.0).toInt() 57 | val red = android.graphics.Color.red(colorInt) 58 | val green = android.graphics.Color.green(colorInt) 59 | val blue = android.graphics.Color.blue(colorInt) 60 | 61 | return Color.argb(alpha, red, green, blue) 62 | } 63 | } -------------------------------------------------------------------------------- /plugin/unit-tests/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /plugin/e2e-tests/tests/specs/markers/add-and-remove.spec.ts: -------------------------------------------------------------------------------- 1 | import * as IonicE2E from '@ionic/e2e'; 2 | import { waitForLoad, pause, setDevice, switchToWeb, url } from '@ionic/e2e'; 3 | 4 | import AddAndRemoveMarkers from '../../pageobjects/markers/add-and-remove.page'; 5 | 6 | 7 | describe('Google Maps - Add and Remove Marker', function () { 8 | let createdMarkerId = ""; 9 | 10 | before(async function () { 11 | await waitForLoad(); 12 | await switchToWeb(); 13 | await url('/markers/add-and-remove'); 14 | await pause(500); 15 | }); 16 | 17 | beforeEach(async function () { 18 | await setDevice(IonicE2E.Device.Mobile); 19 | await switchToWeb(); 20 | await AddAndRemoveMarkers.hideToolBars(); 21 | }); 22 | 23 | after(async function () { 24 | await switchToWeb(); 25 | await AddAndRemoveMarkers.showToolBars(); 26 | await pause(500); 27 | }); 28 | 29 | it("should create a map and add a marker", async function() { 30 | const createMapButton = await AddAndRemoveMarkers.createMapButton; 31 | const addMarkerButton = await AddAndRemoveMarkers.addMarkerButton; 32 | const getCommandOutputText = async function() { 33 | return (await AddAndRemoveMarkers.commandOutputTextarea).getValue(); 34 | } 35 | 36 | await createMapButton.tap(); 37 | await pause(500); 38 | await expect(await getCommandOutputText()).toBe('Map created'); 39 | 40 | await addMarkerButton.tap(); 41 | await pause(500); 42 | await expect(await getCommandOutputText()).toContain('Marker added: '); 43 | 44 | const markerId = (await getCommandOutputText()).replace("Marker added: ", ""); 45 | await expect(markerId).not.toBeFalsy(); 46 | 47 | createdMarkerId = markerId; 48 | }); 49 | 50 | it("should remove the created marker", async function() { 51 | const removeMarkerButton = await AddAndRemoveMarkers.removeMarkerButton; 52 | const commandOutput = await $((await AddAndRemoveMarkers.commandOutputTextarea).selector).$('textarea'); 53 | 54 | await removeMarkerButton.tap(); 55 | await pause(500); 56 | await expect(commandOutput).toHaveValueContaining(`Marker removed: ${createdMarkerId}`); 57 | }); 58 | 59 | it("should throw when attempting to remove a non-existent marker", async function() { 60 | const removeMarkerButton = await AddAndRemoveMarkers.removeMarkerButton; 61 | const commandOutput = await $((await AddAndRemoveMarkers.commandOutputTextarea).selector).$('textarea'); 62 | 63 | await removeMarkerButton.tap(); 64 | await pause(500); 65 | await expect(commandOutput).toHaveValueContaining(`Marker not found for provided id.`); 66 | }); 67 | }); -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | See [`CONTRIBUTING.md`](https://github.com/ionic-team/capacitor/blob/HEAD/CONTRIBUTING.md) in the Capacitor repo for more general contribution guidelines. 4 | 5 | ## Developing Capacitor Plugins 6 | 7 | ### Local Setup 8 | 9 | 1. Fork and clone this repo. 10 | 2. Install the monorepo dependencies. 11 | 12 | ```shell 13 | npm install 14 | ``` 15 | 16 | 3. Install SwiftLint if you're on macOS. Contributions to iOS code will be linted in CI if you don't have macOS. 17 | 18 | ```shell 19 | brew install swiftlint 20 | ``` 21 | 22 | Sometimes, it may be necessary to work on Capacitor in parallel with the plugin(s). In this case, a few extra steps are necessary: 23 | 24 | 4. Follow the Capacitor repo's [local setup instructions](https://github.com/ionic-team/capacitor/blob/HEAD/CONTRIBUTING.md#local-setup). 25 | 5. Toggle each plugin to use your local copy of Capacitor. 26 | 27 | ```shell 28 | npm install 29 | npm run toggle-local 30 | ``` 31 | 32 | :bulb: *Remember not to commit unnecessary changes to `package.json` and `package-lock.json`.* 33 | 34 | 6. Make sure your app is using local copies of the Capacitor plugin and Capacitor core. 35 | 36 | ```shell 37 | cd my-app/ 38 | npm install ../path/to/capacitor-plugins/ 39 | npm install ../path/to/capacitor/core 40 | npm install ../path/to/capacitor/android 41 | npm install ../path/to/capacitor/ios 42 | ``` 43 | 44 | ### Monorepo Scripts 45 | 46 | To aid in managing these plugins, this repo has a variety of scripts (located in `scripts/`) that can be run with `npm`. 47 | 48 | #### `npm run set-capacitor-version ""` 49 | 50 | This script is for setting the version (or version range) of Capacitor packages in each plugin's `package.json`. 51 | 52 | #### `npm run toggle-local` 53 | 54 | > :memo: Requires [Capacitor](https://github.com/ionic-team/capacitor/) to be cloned in a sibling directory. 55 | 56 | This script is for switching between Capacitor packages from npm and Capacitor packages installed locally. 57 | 58 | > If you get npm errors, you can try installing from scratch: 59 | > 60 | > 1. Reset the changes in `package.json` files. 61 | > 1. Clear out all `node_modules`. 62 | > 63 | > ```shell 64 | > npx lerna exec 'rm -fr package-lock.json && rm -fr node_modules' 65 | > rm -fr node_modules 66 | > ``` 67 | > 1. Install with local dependencies: 68 | > 69 | > ``` 70 | > npm run toggle-local 71 | > ``` 72 | 73 | #### `npm run apply-patches ""` 74 | 75 | This script is for copying git changes from one plugin to all plugins. 76 | 77 | To use: 78 | 79 | 1. Make sure your staging area is clean, e.g. `git reset` 80 | 1. Stage the changes from (and only from) your package, e.g. `git add -p -- text-zoom/` 81 | 1. Run the script with `` being the npm name of your package, e.g. `npm run apply-patches @capacitor/text-zoom` 82 | -------------------------------------------------------------------------------- /.github/workflows/reusable_release-npm.yml: -------------------------------------------------------------------------------- 1 | name: "Release to NPM" 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | create-dev-release: 7 | required: false 8 | type: boolean 9 | default: false 10 | create-rc-release: 11 | required: false 12 | type: boolean 13 | default: false 14 | secrets: 15 | CAP_GH_RELEASE_TOKEN: 16 | required: true 17 | NPM_TOKEN: 18 | required: true 19 | 20 | permissions: 21 | contents: write 22 | id-token: write 23 | 24 | jobs: 25 | build: 26 | runs-on: 'ubuntu-22.04' 27 | timeout-minutes: 30 28 | steps: 29 | - uses: actions/checkout@v3 30 | with: 31 | fetch-depth: 0 32 | token: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 33 | 34 | - name: 'Setup Tools' 35 | uses: ./.github/actions/setup-tools 36 | 37 | - name: 'Check Current Release Type' 38 | shell: bash 39 | run: | 40 | RELEASE_TYPE="$([[ "$(git describe --abbrev=0 --tags)" =~ ^[0-9]{1,}[\.][0-9]{1,}[\.][0-9]{1,}[-]((beta)|(rc)|(alpha))[\.][0-9]{1,}$ ]] && echo "prerelease" || echo "release")" 41 | echo "releasetype=$RELEASE_TYPE" >> $GITHUB_ENV 42 | 43 | - name: "NPM Identity" 44 | run: | 45 | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc 46 | npm whoami 47 | 48 | - name: "Git Config" 49 | run: | 50 | git config user.name "Github Workflow (on behalf of ${{ github.actor }})" 51 | git config user.email "users.noreply.github.com" 52 | 53 | - name: 'Dev Release' 54 | if: inputs.create-dev-release 55 | shell: bash 56 | env: 57 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 58 | GH_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 59 | run: | 60 | pnpm ci:publish:dev 61 | 62 | - name: 'RC Release' 63 | if: "!inputs.create-dev-release && inputs.create-rc-release" 64 | shell: bash 65 | env: 66 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 67 | GH_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 68 | run: | 69 | pnpm run ci:publish:rc 70 | 71 | - name: 'Release from PreRelease' 72 | if: ${{ !inputs.create-dev-release && !inputs.create-rc-release && env.releasetype == 'prerelease' }} 73 | shell: bash 74 | env: 75 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 76 | GH_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 77 | run: | 78 | pnpm run ci:publish:latest-from-pre 79 | 80 | - name: 'Release from Release' 81 | if: ${{ !inputs.create-dev-release && !inputs.create-rc-release && env.releasetype == 'release' }} 82 | shell: bash 83 | env: 84 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 85 | GH_TOKEN: ${{ secrets.CAP_GH_RELEASE_TOKEN }} 86 | run: | 87 | pnpm run ci:publish:latest 88 | -------------------------------------------------------------------------------- /plugin/ios/Sources/CapacitorGoogleMapsPlugin/Polyline.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Capacitor 3 | 4 | public struct StyleSpan { 5 | let color: UIColor 6 | let segments: Double? 7 | } 8 | 9 | public struct Polyline { 10 | let path: [LatLng] 11 | let strokeWidth: CGFloat 12 | let strokeColor: UIColor 13 | let title: String? 14 | let tappable: Bool? 15 | let geodesic: Bool? 16 | let zIndex: Int32 17 | let tag: String? 18 | let styleSpans: [StyleSpan] 19 | 20 | init(fromJSObject: JSObject) throws { 21 | var strokeColor = UIColor.blue 22 | var strokeWidth: CGFloat = 1.0 23 | var path: [LatLng] = [] 24 | var styleSpans: [StyleSpan] = [] 25 | 26 | if let width = fromJSObject["strokeWeight"] as? Float { 27 | strokeWidth = CGFloat(width) 28 | } 29 | 30 | let strokeOpacity = fromJSObject["strokeOpacity"] as? Double 31 | 32 | if let hexColor = fromJSObject["strokeColor"] as? String { 33 | strokeColor = UIColor(hex: hexColor) ?? UIColor.blue 34 | } 35 | 36 | strokeColor = strokeColor.withAlphaComponent(strokeOpacity ?? 1.0) 37 | 38 | guard let pathJSArray = fromJSObject["path"] as? JSArray else { 39 | throw GoogleMapErrors.invalidArguments("Polyline object is missing the required 'path' property") 40 | } 41 | 42 | try pathJSArray.forEach { obj in 43 | guard let jsCoord = obj as? JSObject else { 44 | throw GoogleMapErrors.invalidArguments("LatLng object is missing the required 'lat' and/or 'lng' property") 45 | } 46 | 47 | guard let lat = jsCoord["lat"] as? Double, let lng = jsCoord["lng"] as? Double else { 48 | throw GoogleMapErrors.invalidArguments("LatLng object is missing the required 'lat' and/or 'lng' property") 49 | } 50 | 51 | path.append(LatLng(lat: lat, lng: lng)) 52 | } 53 | 54 | if let styleSpanJSArray = fromJSObject["styleSpans"] as? JSArray { 55 | styleSpanJSArray.forEach({ obj in 56 | if let styleSpanObj = obj as? JSObject, 57 | let hexColor = styleSpanObj["color"] as? String, 58 | let color = UIColor(hex: hexColor) { 59 | let segments = styleSpanObj["segments"] as? Double 60 | styleSpans.append(StyleSpan(color: color, segments: segments)) 61 | } 62 | }) 63 | } 64 | 65 | self.strokeColor = strokeColor 66 | self.strokeWidth = strokeWidth 67 | self.tag = fromJSObject["tag"] as? String 68 | self.title = fromJSObject["title"] as? String 69 | self.tappable = fromJSObject["clickable"] as? Bool 70 | self.geodesic = fromJSObject["geodesic"] as? Bool 71 | self.zIndex = Int32((fromJSObject["zIndex"] as? Int) ?? 0) 72 | self.path = path 73 | self.styleSpans = styleSpans 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /plugin/e2e-tests/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' 3 | } 4 | 5 | apply plugin: 'com.android.application' 6 | 7 | def getApiKey() { 8 | Properties properties = new Properties() 9 | if (project.rootProject.file('local.properties').canRead()) { 10 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 11 | 12 | if(properties.containsKey("REACT_APP_GOOGLE_MAPS_API_KEY")) { 13 | return properties['REACT_APP_GOOGLE_MAPS_API_KEY'] 14 | } 15 | } 16 | return System.getenv('REACT_APP_GOOGLE_MAPS_API_KEY') 17 | } 18 | 19 | 20 | android { 21 | namespace "io.ionic.starter" 22 | compileSdkVersion rootProject.ext.compileSdkVersion 23 | defaultConfig { 24 | applicationId "io.ionic.starter" 25 | minSdkVersion rootProject.ext.minSdkVersion 26 | targetSdkVersion rootProject.ext.targetSdkVersion 27 | versionCode 1 28 | versionName "1.0" 29 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 30 | aaptOptions { 31 | // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. 32 | // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61 33 | ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' 34 | } 35 | manifestPlaceholders = [MAPS_API_KEY:"${getApiKey()}"] 36 | } 37 | buildTypes { 38 | release { 39 | minifyEnabled false 40 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 41 | } 42 | } 43 | } 44 | 45 | repositories { 46 | flatDir{ 47 | dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' 48 | } 49 | } 50 | 51 | dependencies { 52 | implementation fileTree(include: ['*.jar'], dir: 'libs') 53 | implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" 54 | implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" 55 | implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion" 56 | implementation project(':capacitor-android') 57 | testImplementation "junit:junit:$junitVersion" 58 | androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" 59 | androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" 60 | implementation project(':capacitor-cordova-android-plugins') 61 | } 62 | 63 | apply from: 'capacitor.build.gradle' 64 | 65 | try { 66 | def servicesJSON = file('google-services.json') 67 | if (servicesJSON.text) { 68 | apply plugin: 'com.google.gms.google-services' 69 | } 70 | } catch(Exception e) { 71 | logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") 72 | } 73 | -------------------------------------------------------------------------------- /plugin/e2e-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "e2e-tests", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": { 6 | "@capacitor/app": "next", 7 | "@capacitor/android": "next", 8 | "@capacitor/core": "next", 9 | "@capacitor/google-maps": "file:..", 10 | "@capacitor/haptics": "next", 11 | "@capacitor/ios": "next", 12 | "@capacitor/keyboard": "next", 13 | "@capacitor/status-bar": "next", 14 | "@ionic/react": "^8.7.9", 15 | "@ionic/react-router": "^8.7.9", 16 | "@testing-library/jest-dom": "^6.9.1", 17 | "@testing-library/react": "^16.3.0", 18 | "@testing-library/user-event": "^14.6.1", 19 | "@types/jest": "^30.0.0", 20 | "@types/node": "^24.10.1", 21 | "@types/react": "^19.2.6", 22 | "@types/react-dom": "^19.2.3", 23 | "@types/react-router": "^5.1.20", 24 | "@types/react-router-dom": "^5.3.3", 25 | "ionicons": "^8.0.13", 26 | "react": "^19.2.0", 27 | "react-dom": "^19.2.0", 28 | "react-router": "^5.3.4", 29 | "react-router-dom": "^5.3.4", 30 | "react-scripts": "^5.0.1", 31 | "typescript": "^5.9.3", 32 | "web-vitals": "^5.1.0", 33 | "workbox-background-sync": "^7.3.0", 34 | "workbox-broadcast-update": "^7.3.0", 35 | "workbox-cacheable-response": "^7.3.0", 36 | "workbox-core": "^7.3.0", 37 | "workbox-expiration": "^7.3.0", 38 | "workbox-google-analytics": "^7.3.0", 39 | "workbox-navigation-preload": "^7.3.0", 40 | "workbox-precaching": "^7.3.0", 41 | "workbox-range-requests": "^7.3.0", 42 | "workbox-routing": "^7.3.0", 43 | "workbox-strategies": "^7.3.0", 44 | "workbox-streams": "^7.3.0" 45 | }, 46 | "scripts": { 47 | "start": "react-scripts start", 48 | "build": "react-scripts build", 49 | "test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'", 50 | "eject": "react-scripts eject", 51 | "sync": "npm run build && npx cap sync", 52 | "ionic-e2e": "ionic-e2e", 53 | "e2e:ios:build": "npm run ionic-e2e build ios:simulator", 54 | "e2e:ios:run": "npm run ionic-e2e run ios:simulator", 55 | "e2e:ios": "E2E_MODE=simulator && npm run sync && npm run e2e:ios:build && npm run e2e:ios:run", 56 | "e2e:android:build": "npm run ionic-e2e build android:emulator", 57 | "e2e:android:run": "npm run ionic-e2e run android:emulator", 58 | "e2e:android": "./scripts/run_Android_E2E.sh", 59 | "e2e:prepare": "./scripts/build_local_package.sh" 60 | }, 61 | "eslintConfig": { 62 | "extends": [ 63 | "react-app", 64 | "react-app/jest" 65 | ] 66 | }, 67 | "browserslist": { 68 | "production": [ 69 | ">0.2%", 70 | "not dead", 71 | "not op_mini all" 72 | ], 73 | "development": [ 74 | "last 1 chrome version", 75 | "last 1 firefox version", 76 | "last 1 safari version" 77 | ] 78 | }, 79 | "devDependencies": { 80 | "@capacitor/cli": "next", 81 | "@ionic/e2e": "0.2.0-next.6", 82 | "@ionic/e2e-components-ionic": "0.2.0-next.6", 83 | "appium": "^1.22.1" 84 | }, 85 | "description": "An Ionic project" 86 | } -------------------------------------------------------------------------------- /example-app-spm/src/pages/Map/ResizeMap.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { GoogleMap } from '@capacitor/google-maps'; 3 | import { 4 | IonButton, 5 | IonTextarea, 6 | } from '@ionic/react'; 7 | import BaseTestingPage from '../../components/BaseTestingPage'; 8 | 9 | const ResizeMapPage: React.FC = () => { 10 | const [map, setMap] = useState(); 11 | const [commandOutput, setCommandOutput] = useState(''); 12 | const [mapWidth, setMapWidth] = useState(window.outerWidth); 13 | const [mapHeight, setMapHeight] = useState(window.outerWidth); 14 | 15 | const apiKey = process.env.REACT_APP_GOOGLE_MAPS_API_KEY; 16 | 17 | async function createMap() { 18 | setCommandOutput(''); 19 | setMap(null); 20 | try { 21 | const mapRef = document.getElementById('map_resize')!; 22 | 23 | const newMap = await GoogleMap.create({ 24 | element: mapRef, 25 | id: 'test-map-resize', 26 | apiKey: apiKey!, 27 | config: { 28 | center: { 29 | lat: 33.6, 30 | lng: -117.9, 31 | }, 32 | zoom: 8, 33 | }, 34 | forceCreate: true, 35 | }); 36 | 37 | setMap(newMap); 38 | setCommandOutput('Map created'); 39 | } catch (err: any) { 40 | setCommandOutput(err.message); 41 | } 42 | } 43 | 44 | async function destroyMap() { 45 | setCommandOutput(''); 46 | try { 47 | if (map) { 48 | await map.destroy(); 49 | setMap(null); 50 | setCommandOutput('Map destroyed'); 51 | } 52 | } catch (err: any) { 53 | setCommandOutput(err.message); 54 | } 55 | } 56 | 57 | async function enlargeMap() { 58 | setMapWidth(window.outerWidth); 59 | setMapHeight(window.outerWidth); 60 | } 61 | 62 | async function shrinkMap() { 63 | setMapWidth(mapWidth / 2); 64 | setMapHeight(mapHeight / 2); 65 | } 66 | 67 | return ( 68 | 69 |
70 | 71 | Create Map 72 | 73 | 74 | Destroy Map 75 | 76 | Enlarge Map 77 | Shrink Map 78 |
79 |
80 | 85 |
86 | 96 |
97 | ); 98 | }; 99 | 100 | export default ResizeMapPage; 101 | -------------------------------------------------------------------------------- /plugin/e2e-tests/src/pages/Map/ResizeMap.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { GoogleMap } from '@capacitor/google-maps'; 3 | import { 4 | IonButton, 5 | IonTextarea, 6 | } from '@ionic/react'; 7 | import BaseTestingPage from '../../components/BaseTestingPage'; 8 | 9 | const ResizeMapPage: React.FC = () => { 10 | const [map, setMap] = useState(); 11 | const [commandOutput, setCommandOutput] = useState(''); 12 | const [mapWidth, setMapWidth] = useState(window.outerWidth); 13 | const [mapHeight, setMapHeight] = useState(window.outerWidth); 14 | 15 | const apiKey = process.env.REACT_APP_GOOGLE_MAPS_API_KEY; 16 | 17 | async function createMap() { 18 | setCommandOutput(''); 19 | setMap(null); 20 | try { 21 | const mapRef = document.getElementById('map_resize')!; 22 | 23 | const newMap = await GoogleMap.create({ 24 | element: mapRef, 25 | id: 'test-map-resize', 26 | apiKey: apiKey!, 27 | config: { 28 | center: { 29 | lat: 33.6, 30 | lng: -117.9, 31 | }, 32 | zoom: 8, 33 | }, 34 | forceCreate: true, 35 | }); 36 | 37 | setMap(newMap); 38 | setCommandOutput('Map created'); 39 | } catch (err: any) { 40 | setCommandOutput(err.message); 41 | } 42 | } 43 | 44 | async function destroyMap() { 45 | setCommandOutput(''); 46 | try { 47 | if (map) { 48 | await map.destroy(); 49 | setMap(null); 50 | setCommandOutput('Map destroyed'); 51 | } 52 | } catch (err: any) { 53 | setCommandOutput(err.message); 54 | } 55 | } 56 | 57 | async function enlargeMap() { 58 | setMapWidth(window.outerWidth); 59 | setMapHeight(window.outerWidth); 60 | } 61 | 62 | async function shrinkMap() { 63 | setMapWidth(mapWidth / 2); 64 | setMapHeight(mapHeight / 2); 65 | } 66 | 67 | return ( 68 | 69 |
70 | 71 | Create Map 72 | 73 | 74 | Destroy Map 75 | 76 | Enlarge Map 77 | Shrink Map 78 |
79 |
80 | 85 |
86 | 96 |
97 | ); 98 | }; 99 | 100 | export default ResizeMapPage; 101 | --------------------------------------------------------------------------------