├── .clang-format ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github ├── DISCUSSION_TEMPLATE │ └── feature-request.yml ├── FUNDING.yml ├── ISSUE_TEMPLATE │ └── bug_report.yml ├── PULL_REQUEST_TEMPLATE.md ├── actions │ └── setup │ │ ├── action.yml │ │ └── android_dummy_secret.xml └── workflows │ ├── ci.yml │ ├── doc-publish.yml │ └── stale.yml ├── .gitignore ├── .husky └── _ │ ├── check │ └── format ├── .nvmrc ├── .prettierrc ├── .watchmanconfig ├── .yarn └── releases │ └── yarn-4.1.1.cjs ├── .yarnrc.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README-en.md ├── README.md ├── android ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ ├── main │ ├── AndroidManifest.xml │ ├── AndroidManifestNew.xml │ └── java │ │ └── com │ │ ├── airbnb │ │ └── android │ │ │ └── react │ │ │ └── maps │ │ │ ├── SizeReportingShadowNode.java │ │ │ ├── TrackableView.java │ │ │ ├── ViewAttacherGroup.java │ │ │ └── ViewChangesTracker.java │ │ └── mjstudio │ │ └── reactnativenavermap │ │ ├── RNCNaverMapPackage.kt │ │ ├── event │ │ ├── NaverMapCameraChangeEvent.kt │ │ ├── NaverMapCameraIdleEvent.kt │ │ ├── NaverMapClusterLeafTapEvent.kt │ │ ├── NaverMapCoordinateToScreenEvent.kt │ │ ├── NaverMapInitializeEvent.kt │ │ ├── NaverMapOptionChangeEvent.kt │ │ ├── NaverMapOverlayTapEvent.kt │ │ ├── NaverMapScreenToCoordinateEvent.kt │ │ └── NaverMapTapEvent.kt │ │ ├── mapview │ │ ├── RNCNaverMapView.kt │ │ ├── RNCNaverMapViewManager.kt │ │ └── RNCNaverMapViewWrapper.kt │ │ ├── overlay │ │ ├── RNCNaverMapOverlay.kt │ │ ├── arrowheadpath │ │ │ ├── RNCNaverMapArrowheadPath.kt │ │ │ └── RNCNaverMapArrowheadPathManager.kt │ │ ├── circle │ │ │ ├── RNCNaverMapCircle.kt │ │ │ └── RNCNaverMapCircleManager.kt │ │ ├── ground │ │ │ ├── RNCNaverMapGround.kt │ │ │ └── RNCNaverMapGroundManager.kt │ │ ├── marker │ │ │ ├── RNCNaverMapMarker.kt │ │ │ ├── RNCNaverMapMarkerManager.kt │ │ │ └── cluster │ │ │ │ ├── RNCNaverMapClusterDataHolder.kt │ │ │ │ ├── RNCNaverMapClusterKey.kt │ │ │ │ ├── RNCNaverMapClusterMarkerUpdater.kt │ │ │ │ ├── RNCNaverMapLeafDataHolder.kt │ │ │ │ ├── RNCNaverMapLeafMarkerHolder.kt │ │ │ │ └── RNCNaverMapLeafMarkerUpdater.kt │ │ ├── path │ │ │ ├── RNCNaverMapPath.kt │ │ │ └── RNCNaverMapPathManager.kt │ │ ├── polygon │ │ │ ├── RNCNaverMapPolygon.kt │ │ │ └── RNCNaverMapPolygonManager.kt │ │ └── polyline │ │ │ ├── RNCNaverMapPolyline.kt │ │ │ └── RNCNaverMapPolylineManager.kt │ │ └── util │ │ ├── ArgUtil.kt │ │ ├── CameraAnimationUtil.kt │ │ ├── DirectEventUtils.kt │ │ ├── LogUtil.kt │ │ ├── RNCNaverMapRegion.kt │ │ ├── RectUtil.kt │ │ ├── ViewEventEmitter.kt │ │ └── image │ │ ├── CreateDraweeHierarchy.kt │ │ ├── GetOverlayImage.kt │ │ ├── OverlayImageCache.kt │ │ ├── RNCNaverMapImageRenderableOverlay.kt │ │ └── RNCNaverMapTaggedImageRenderer.kt │ └── newarch │ ├── RNCNaverMapArrowheadPathManagerSpec.kt │ ├── RNCNaverMapCircleManagerSpec.kt │ ├── RNCNaverMapGroundManagerSpec.kt │ ├── RNCNaverMapMarkerManagerSpec.kt │ ├── RNCNaverMapPathManagerSpec.kt │ ├── RNCNaverMapPolygonManagerSpec.kt │ ├── RNCNaverMapPolylineManagerSpec.kt │ └── RNCNaverMapViewManagerSpec.kt ├── app.plugin.js ├── babel.config.js ├── example ├── .bundle │ └── config ├── .watchmanconfig ├── Gemfile ├── Gemfile.lock ├── README.md ├── android │ ├── .editorconfig │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── navermapexample │ │ │ │ ├── MainActivity.kt │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ ├── drawable │ │ │ ├── rn_edit_text_material.xml │ │ │ └── thumbnail.png │ │ │ ├── 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 │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── .xcode.env.local │ ├── File.swift │ ├── NaverMapExample-Bridging-Header.h │ ├── NaverMapExample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── NaverMapExample.xcscheme │ ├── NaverMapExample.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── NaverMapExample │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── 100.png │ │ │ │ ├── 102.png │ │ │ │ ├── 1024.png │ │ │ │ ├── 114.png │ │ │ │ ├── 120.png │ │ │ │ ├── 144.png │ │ │ │ ├── 152.png │ │ │ │ ├── 167.png │ │ │ │ ├── 172.png │ │ │ │ ├── 180.png │ │ │ │ ├── 196.png │ │ │ │ ├── 20.png │ │ │ │ ├── 216.png │ │ │ │ ├── 29.png │ │ │ │ ├── 40.png │ │ │ │ ├── 48.png │ │ │ │ ├── 50.png │ │ │ │ ├── 55.png │ │ │ │ ├── 57.png │ │ │ │ ├── 58.png │ │ │ │ ├── 60.png │ │ │ │ ├── 66.png │ │ │ │ ├── 72.png │ │ │ │ ├── 76.png │ │ │ │ ├── 80.png │ │ │ │ ├── 87.png │ │ │ │ ├── 88.png │ │ │ │ ├── 92.png │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ └── thumbnail.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── rn-naver- 1.png │ │ │ │ ├── rn-naver- 2.png │ │ │ │ └── rn-naver-.png │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── PrivacyInfo.xcprivacy │ │ └── main.m │ ├── NaverMapExampleTests │ │ ├── Info.plist │ │ └── NaverMapExampleTests.m │ ├── Podfile │ └── Podfile.lock ├── jest.config.js ├── metro.config.js ├── package.json ├── react-native.config.js └── src │ ├── App.tsx │ ├── component │ └── components.tsx │ ├── db │ └── CityDatabase.ts │ └── logo180.png ├── expo-config-plugin ├── src │ └── index.ts └── tsconfig.json ├── ios ├── Module │ ├── RNCNaverMapUtil.h │ └── RNCNaverMapUtil.mm ├── Overlay │ ├── ArrowheadPath │ │ ├── RNCNaverMapArrowheadPath.h │ │ └── RNCNaverMapArrowheadPath.mm │ ├── Circle │ │ ├── RNCNaverMapCircle.h │ │ └── RNCNaverMapCircle.mm │ ├── Cluster │ │ ├── RNCNaverMapClusterKey.h │ │ ├── RNCNaverMapClusterKey.mm │ │ ├── RNCNaverMapClusterMarkerUpdater.h │ │ ├── RNCNaverMapClusterMarkerUpdater.mm │ │ ├── RNCNaverMapLeafMarkerUpdater.h │ │ └── RNCNaverMapLeafMarkerUpdater.mm │ ├── Ground │ │ ├── RNCNaverMapGround.h │ │ └── RNCNaverMapGround.mm │ ├── Marker │ │ ├── RNCNaverMapMarker.h │ │ └── RNCNaverMapMarker.mm │ ├── Path │ │ ├── RNCNaverMapPath.h │ │ └── RNCNaverMapPath.mm │ ├── Polygon │ │ ├── RNCNaverMapPolygon.h │ │ └── RNCNaverMapPolygon.mm │ └── Polyline │ │ ├── RNCNaverMapPolyline.h │ │ └── RNCNaverMapPolyline.mm ├── RNCNaverMapView.h ├── RNCNaverMapView.mm ├── RNCNaverMapViewImpl.h ├── RNCNaverMapViewImpl.mm └── Util │ ├── ColorUtil.h │ ├── EasingAnimationUtil.h │ ├── FnUtil.h │ ├── Image │ └── ImageUtil.h │ └── MacroUtil.h ├── lefthook.yml ├── mj-studio-react-native-naver-map.podspec ├── package.json ├── public ├── doc.css └── favicon.png ├── script ├── clang-format.sh ├── clang-lint.sh ├── ktlint-format.sh ├── ktlint-lint.sh └── release.sh ├── src ├── __tests__ │ └── index.test.tsx ├── component │ ├── NaverMapArrowheadPathOverlay.tsx │ ├── NaverMapCircleOverlay.tsx │ ├── NaverMapGroundOverlay.tsx │ ├── NaverMapMarkerOverlay.tsx │ ├── NaverMapPathOverlay.tsx │ ├── NaverMapPolygonOverlay.tsx │ ├── NaverMapPolylineOverlay.tsx │ └── NaverMapView.tsx ├── index.tsx ├── internal │ ├── Util.ts │ └── util │ │ ├── Assert.ts │ │ ├── Const.ts │ │ └── useStableCallback.ts ├── spec │ ├── NativeRNCNaverMapUtil.ts │ ├── RNCNaverMapArrowheadPathNativeComponent.ts │ ├── RNCNaverMapCircleNativeComponent.ts │ ├── RNCNaverMapGroundNativeComponent.ts │ ├── RNCNaverMapMarkerNativeComponent.ts │ ├── RNCNaverMapPathNativeComponent.ts │ ├── RNCNaverMapPolygonNativeComponent.ts │ ├── RNCNaverMapPolylineNativeComponent.ts │ └── RNCNaverMapViewNativeComponent.ts ├── types │ ├── Align.ts │ ├── BaseOverlayProps.ts │ ├── Camera.ts │ ├── CameraAnimationEasing.ts │ ├── CameraChangeReason.ts │ ├── CameraMoveBaseParams.ts │ ├── CapType.ts │ ├── ClusterMarkerProp.ts │ ├── Coord.ts │ ├── JoinType.ts │ ├── LocationTrackingMode.ts │ ├── LogoAlign.ts │ ├── MapType.ts │ ├── MarkerImageProp.ts │ ├── MarkerSymbol.ts │ ├── Point.ts │ ├── Rect.ts │ └── Region.ts └── util │ └── NaverMapUtil.ts ├── tsconfig.build.json ├── tsconfig.json ├── turbo.json ├── typedoc.json └── yarn.lock /.clang-format: -------------------------------------------------------------------------------- 1 | # Config for clang-format version 16 2 | 3 | # Standard 4 | 5 | BasedOnStyle: llvm 6 | Standard: c++14 7 | 8 | # Indentation 9 | 10 | IndentWidth: 2 11 | ColumnLimit: 100 12 | 13 | # Includes 14 | 15 | SortIncludes: true 16 | SortUsingDeclarations: true 17 | 18 | # Pointer and reference alignment 19 | 20 | PointerAlignment: Left 21 | ReferenceAlignment: Left 22 | ReflowComments: true 23 | 24 | # Line breaking options 25 | 26 | BreakBeforeBraces: Attach 27 | BreakConstructorInitializers: BeforeColon 28 | AllowShortFunctionsOnASingleLine: Empty 29 | IndentCaseLabels: true 30 | NamespaceIndentation: Inner 31 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | ktlint_code_style = ktlint_official 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | expo-config-plugin/build 4 | docs/ 5 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "@react-native", 5 | "prettier" 6 | ], 7 | "plugins": ["prettier"], 8 | "rules": { 9 | "prettier/prettier": [ 10 | "error", 11 | { 12 | "quoteProps": "consistent", 13 | "singleQuote": true, 14 | "tabWidth": 2, 15 | "trailingComma": "es5", 16 | "useTabs": false 17 | } 18 | ], 19 | "react-native/no-inline-styles": "off", 20 | "@typescript-eslint/no-unused-vars": "off", 21 | "react/react-in-jsx-scope": "off" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | title: '[Feature Request]: ' 2 | labels: [ 'feature' ] 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | Thanks for taking the time to fill out this feature request! 8 | - type: checkboxes 9 | attributes: 10 | label: Is there an existing issue for this? 11 | description: Please search to see if an issue already exists for this feature request. 12 | options: 13 | - label: I have searched the existing issues 14 | required: true 15 | - type: textarea 16 | id: describe-problem 17 | attributes: 18 | label: Describe the problem 19 | description: Is your feature request related to a problem? Please describe. 20 | placeholder: I'm always frustrated when... 21 | validations: 22 | required: true 23 | - type: textarea 24 | id: solution 25 | attributes: 26 | label: Describe the solution 27 | description: Please describe the solution you'd like. A clear and concise description of what you want to happen. 28 | validations: 29 | required: true 30 | - type: textarea 31 | id: context 32 | attributes: 33 | label: Additional context 34 | description: Add any other context or screenshots about the feature request here. 35 | validations: 36 | required: false 37 | - type: checkboxes 38 | id: terms 39 | attributes: 40 | label: Code of Conduct 41 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/mym0404/react-native-kakao/blob/main/CODE_OF_CONDUCT.md) 42 | options: 43 | - label: I agree to follow this project's Code of Conduct 44 | required: true 45 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [mym0404] 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Type of change 4 | 5 | 6 | 7 | - [ ] New feature (non-breaking change which adds functionality) 8 | - [ ] Bug fix (non-breaking change which fixes an issue) 9 | - [ ] Enhance (enhance performance, api, etc) 10 | - [ ] Chore 11 | - [ ] This change requires a documentation update 12 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 13 | 14 | ## What does this change? 15 | 16 | 17 | 18 | Fixes # 🎯 19 | 20 | -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup 2 | description: Setup Node.js and install dependencies 3 | 4 | runs: 5 | using: composite 6 | steps: 7 | - name: Setup Node.js 8 | uses: actions/setup-node@v3 9 | with: 10 | node-version-file: .nvmrc 11 | 12 | - name: Cache dependencies 13 | id: yarn-cache 14 | uses: actions/cache@v3 15 | with: 16 | path: | 17 | **/node_modules 18 | .yarn/install-state.gz 19 | key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}-${{ hashFiles('**/package.json', '!node_modules/**') }} 20 | restore-keys: | 21 | ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} 22 | ${{ runner.os }}-yarn- 23 | 24 | - name: Install dependencies 25 | if: steps.yarn-cache.outputs.cache-hit != 'true' 26 | run: yarn install --immutable 27 | shell: bash 28 | 29 | - name: Prepare Dummy Secrets 30 | shell: bash 31 | run: | 32 | cat .github/actions/setup/android_dummy_secret.xml > example/android/app/src/main/res/values/secret.xml 33 | echo "NAVER_CLIENT_ID = dummy" > example/ios/Secret.xcconfig 34 | -------------------------------------------------------------------------------- /.github/actions/setup/android_dummy_secret.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | dummy 4 | 5 | -------------------------------------------------------------------------------- /.github/workflows/doc-publish.yml: -------------------------------------------------------------------------------- 1 | name: API DOC 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | publish-doc: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v4 13 | 14 | - name: Setup 15 | uses: ./.github/actions/setup 16 | 17 | - name: Build Docs 18 | run: yarn build:docs 19 | 20 | - name: Deploy Docs 21 | uses: peaceiris/actions-gh-pages@v3 22 | with: 23 | github_token: ${{ secrets.GH_TOKEN }} 24 | publish_dir: ./docs 25 | user_name: github-actions[bot] 26 | user_email: 41898282+github-actions[bot]@users.noreply.github.com 27 | 28 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PRs' 2 | on: 3 | schedule: 4 | - cron: '30 1 * * *' 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v9 11 | with: 12 | stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 2 days.' 13 | days-before-stale: 30 14 | days-before-close: 2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | .eslintcache 33 | 34 | # Android/IJ 35 | # 36 | .classpath 37 | .cxx 38 | .gradle 39 | .idea 40 | .project 41 | .settings 42 | local.properties 43 | android.iml 44 | 45 | # Cocoapods 46 | # 47 | example/ios/Pods 48 | 49 | # Ruby 50 | example/vendor/ 51 | 52 | # node.js 53 | # 54 | node_modules/ 55 | npm-debug.log 56 | yarn-debug.log 57 | yarn-error.log 58 | 59 | # BUCK 60 | buck-out/ 61 | \.buckd/ 62 | android/app/libs 63 | android/keystores/debug.keystore 64 | 65 | # Yarn 66 | .yarn/* 67 | !.yarn/patches 68 | !.yarn/plugins 69 | !.yarn/releases 70 | !.yarn/sdks 71 | !.yarn/versions 72 | 73 | # Expo 74 | .expo/ 75 | 76 | # Turborepo 77 | .turbo/ 78 | 79 | # generated by bob 80 | lib/ 81 | 82 | # secrets 83 | example/android/app/src/main/res/values/secret.xml 84 | example/ios/Secret.xcconfig 85 | .env 86 | 87 | docs/ 88 | 89 | example/.watchman-* 90 | *.bak 91 | -------------------------------------------------------------------------------- /.husky/_/check: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then 4 | set -x 5 | fi 6 | 7 | if [ "$LEFTHOOK" = "0" ]; then 8 | exit 0 9 | fi 10 | 11 | call_lefthook() 12 | { 13 | if test -n "$LEFTHOOK_BIN" 14 | then 15 | "$LEFTHOOK_BIN" "$@" 16 | elif lefthook -h >/dev/null 2>&1 17 | then 18 | lefthook "$@" 19 | else 20 | dir="$(git rev-parse --show-toplevel)" 21 | osArch=$(uname | tr '[:upper:]' '[:lower:]') 22 | cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/') 23 | if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" 24 | then 25 | "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@" 26 | elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" 27 | then 28 | "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@" 29 | elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" 30 | then 31 | "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@" 32 | elif test -f "$dir/node_modules/lefthook/bin/index.js" 33 | then 34 | "$dir/node_modules/lefthook/bin/index.js" "$@" 35 | 36 | elif bundle exec lefthook -h >/dev/null 2>&1 37 | then 38 | bundle exec lefthook "$@" 39 | elif yarn lefthook -h >/dev/null 2>&1 40 | then 41 | yarn lefthook "$@" 42 | elif pnpm lefthook -h >/dev/null 2>&1 43 | then 44 | pnpm lefthook "$@" 45 | elif swift package plugin lefthook >/dev/null 2>&1 46 | then 47 | swift package --disable-sandbox plugin lefthook "$@" 48 | elif command -v mint >/dev/null 2>&1 49 | then 50 | mint run csjones/lefthook-plugin "$@" 51 | elif command -v npx >/dev/null 2>&1 52 | then 53 | npx lefthook "$@" 54 | else 55 | echo "Can't find lefthook in PATH" 56 | fi 57 | fi 58 | } 59 | 60 | call_lefthook run "check" "$@" 61 | -------------------------------------------------------------------------------- /.husky/_/format: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then 4 | set -x 5 | fi 6 | 7 | if [ "$LEFTHOOK" = "0" ]; then 8 | exit 0 9 | fi 10 | 11 | call_lefthook() 12 | { 13 | if test -n "$LEFTHOOK_BIN" 14 | then 15 | "$LEFTHOOK_BIN" "$@" 16 | elif lefthook -h >/dev/null 2>&1 17 | then 18 | lefthook "$@" 19 | else 20 | dir="$(git rev-parse --show-toplevel)" 21 | osArch=$(uname | tr '[:upper:]' '[:lower:]') 22 | cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/') 23 | if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" 24 | then 25 | "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@" 26 | elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" 27 | then 28 | "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@" 29 | elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" 30 | then 31 | "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@" 32 | elif test -f "$dir/node_modules/lefthook/bin/index.js" 33 | then 34 | "$dir/node_modules/lefthook/bin/index.js" "$@" 35 | 36 | elif bundle exec lefthook -h >/dev/null 2>&1 37 | then 38 | bundle exec lefthook "$@" 39 | elif yarn lefthook -h >/dev/null 2>&1 40 | then 41 | yarn lefthook "$@" 42 | elif pnpm lefthook -h >/dev/null 2>&1 43 | then 44 | pnpm lefthook "$@" 45 | elif swift package plugin lefthook >/dev/null 2>&1 46 | then 47 | swift package --disable-sandbox plugin lefthook "$@" 48 | elif command -v mint >/dev/null 2>&1 49 | then 50 | mint run csjones/lefthook-plugin "$@" 51 | elif command -v npx >/dev/null 2>&1 52 | then 53 | npx lefthook "$@" 54 | else 55 | echo "Can't find lefthook in PATH" 56 | fi 57 | fi 58 | } 59 | 60 | call_lefthook run "format" "$@" 61 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v18 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "quoteProps": "consistent", 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "trailingComma": "es5", 6 | "useTabs": false 7 | } -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | nmHoistingLimits: workspaces 6 | 7 | nodeLinker: node-modules 8 | 9 | yarnPath: .yarn/releases/yarn-4.1.1.cjs 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 MJ Studio 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | NaverMap_kotlinVersion=1.7.0 2 | NaverMap_minSdkVersion=21 3 | NaverMap_targetSdkVersion=31 4 | NaverMap_compileSdkVersion=31 5 | NaverMap_ndkversion=21.4.7075529 6 | NaverMap_sdkVersion=3.21.0 7 | NaverMap_locationServiceVersion=21.2.0 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifestNew.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * This source code is licensed under the BSD-style license found in the 5 | * LICENSE file in the root directory of this source tree. An additional grant 6 | * of patent rights can be found in the PATENTS file in the same directory. 7 | */ 8 | 9 | package com.airbnb.android.react.maps; 10 | 11 | import com.facebook.react.uimanager.LayoutShadowNode; 12 | import com.facebook.react.uimanager.UIViewOperationQueue; 13 | 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | // Custom LayoutShadowNode implementation used in conjunction with the AirMapManager 18 | // which sends the width/height of the view after layout occurs. 19 | public class SizeReportingShadowNode extends LayoutShadowNode { 20 | 21 | @Override 22 | public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) { 23 | super.onCollectExtraUpdates(uiViewOperationQueue); 24 | 25 | Map data = new HashMap<>(); 26 | data.put("width", getLayoutWidth()); 27 | data.put("height", getLayoutHeight()); 28 | 29 | uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), data); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/TrackableView.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | public interface TrackableView { 4 | boolean updateCustomForTracking(); 5 | 6 | void update(int width, int height); 7 | } 8 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/ViewAttacherGroup.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | 6 | import com.facebook.react.views.view.ReactViewGroup; 7 | 8 | public class ViewAttacherGroup extends ReactViewGroup { 9 | 10 | public ViewAttacherGroup(Context context) { 11 | super(context); 12 | 13 | this.setWillNotDraw(true); 14 | this.setVisibility(VISIBLE); 15 | this.setAlpha(0.0f); 16 | this.setRemoveClippedSubviews(false); 17 | this.setClipBounds(new Rect(0, 0, 0, 0)); 18 | this.setOverflow("hidden"); // Change to ViewProps.HIDDEN until RN 0.57 is base 19 | } 20 | 21 | // This should make it more performant, avoid trying to hard to overlap layers with opacity. 22 | @Override 23 | public boolean hasOverlappingRendering() { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/ViewChangesTracker.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import android.os.Handler; 4 | import android.os.Looper; 5 | 6 | import java.util.LinkedList; 7 | 8 | public class ViewChangesTracker { 9 | 10 | private static ViewChangesTracker instance; 11 | private Handler handler; 12 | private LinkedList markers = new LinkedList<>(); 13 | private boolean hasScheduledFrame = false; 14 | private Runnable updateRunnable; 15 | private final long fps = 2; // FIXME flickering custom view 16 | 17 | private ViewChangesTracker() { 18 | handler = new Handler(Looper.myLooper()); 19 | updateRunnable = () -> { 20 | hasScheduledFrame = false; 21 | update(); 22 | 23 | if (markers.size() > 0) { 24 | handler.postDelayed(updateRunnable, 1000 / fps); 25 | } 26 | }; 27 | } 28 | 29 | public static ViewChangesTracker getInstance() { 30 | if (instance == null) { 31 | synchronized (ViewChangesTracker.class) { 32 | instance = new ViewChangesTracker(); 33 | } 34 | } 35 | 36 | return instance; 37 | } 38 | 39 | public void addMarker(TrackableView marker) { 40 | markers.add(marker); 41 | 42 | if (!hasScheduledFrame) { 43 | hasScheduledFrame = true; 44 | handler.postDelayed(updateRunnable, 1000 / fps); 45 | } 46 | } 47 | 48 | public void removeMarker(TrackableView marker) { 49 | markers.remove(marker); 50 | } 51 | 52 | public boolean containsMarker(TrackableView marker) { 53 | return markers.contains(marker); 54 | } 55 | 56 | private LinkedList markersToRemove = new LinkedList<>(); 57 | 58 | public void update() { 59 | for (TrackableView marker : markers) { 60 | if (!marker.updateCustomForTracking()) { 61 | markersToRemove.add(marker); 62 | } else { 63 | marker.update(0, 0); 64 | } 65 | } 66 | 67 | // Remove markers that are not active anymore 68 | if (markersToRemove.size() > 0) { 69 | markers.removeAll(markersToRemove); 70 | markersToRemove.clear(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/RNCNaverMapPackage.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import com.facebook.react.ReactPackage 4 | import com.facebook.react.bridge.NativeModule 5 | import com.facebook.react.bridge.ReactApplicationContext 6 | import com.facebook.react.uimanager.ViewManager 7 | import com.mjstudio.reactnativenavermap.mapview.RNCNaverMapViewManager 8 | import com.mjstudio.reactnativenavermap.overlay.arrowheadpath.RNCNaverMapArrowheadPathManager 9 | import com.mjstudio.reactnativenavermap.overlay.circle.RNCNaverMapCircleManager 10 | import com.mjstudio.reactnativenavermap.overlay.ground.RNCNaverMapGroundManager 11 | import com.mjstudio.reactnativenavermap.overlay.marker.RNCNaverMapMarkerManager 12 | import com.mjstudio.reactnativenavermap.overlay.path.RNCNaverMapPathManager 13 | import com.mjstudio.reactnativenavermap.overlay.polygon.RNCNaverMapPolygonManager 14 | import com.mjstudio.reactnativenavermap.overlay.polyline.RNCNaverMapPolylineManager 15 | 16 | class RNCNaverMapPackage : ReactPackage { 17 | override fun createViewManagers(reactContext: ReactApplicationContext): List> = 18 | mutableListOf>().apply { 19 | add(RNCNaverMapViewManager()) 20 | add(RNCNaverMapMarkerManager()) 21 | add(RNCNaverMapCircleManager()) 22 | add(RNCNaverMapPolygonManager()) 23 | add(RNCNaverMapPolylineManager()) 24 | add(RNCNaverMapPathManager()) 25 | add(RNCNaverMapArrowheadPathManager()) 26 | add(RNCNaverMapGroundManager()) 27 | } 28 | 29 | override fun createNativeModules(reactContext: ReactApplicationContext): List = emptyList() 30 | } 31 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapCameraChangeEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapCameraChangeEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | private val latitude: Double, 11 | private val longitude: Double, 12 | private val zoom: Double, 13 | private val tilt: Double, 14 | private val bearing: Double, 15 | private val reason: Int, 16 | private val regionLatitude: Double, 17 | private val regionLongitude: Double, 18 | private val regionLatitudeDelta: Double, 19 | private val regionLongitudeDelta: Double, 20 | ) : Event(surfaceId, viewId) { 21 | override fun getEventName(): String = EVENT_NAME 22 | 23 | override fun canCoalesce(): Boolean = false 24 | 25 | override fun getCoalescingKey(): Short = 0 26 | 27 | override fun getEventData(): WritableMap = 28 | Arguments.createMap().apply { 29 | putDouble("latitude", latitude) 30 | putDouble("longitude", longitude) 31 | putDouble("zoom", zoom) 32 | putDouble("tilt", tilt) 33 | putDouble("bearing", bearing) 34 | putInt("reason", reason) 35 | putDouble("regionLatitude", regionLatitude) 36 | putDouble("regionLongitude", regionLongitude) 37 | putDouble("regionLatitudeDelta", regionLatitudeDelta) 38 | putDouble("regionLongitudeDelta", regionLongitudeDelta) 39 | } 40 | 41 | companion object { 42 | const val EVENT_NAME = "topCameraChanged" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapCameraIdleEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapCameraIdleEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | private val latitude: Double, 11 | private val longitude: Double, 12 | private val zoom: Double, 13 | private val tilt: Double, 14 | private val bearing: Double, 15 | private val regionLatitude: Double, 16 | private val regionLongitude: Double, 17 | private val regionLatitudeDelta: Double, 18 | private val regionLongitudeDelta: Double, 19 | ) : Event(surfaceId, viewId) { 20 | override fun getEventName(): String = EVENT_NAME 21 | 22 | override fun canCoalesce(): Boolean = false 23 | 24 | override fun getCoalescingKey(): Short = 0 25 | 26 | override fun getEventData(): WritableMap = 27 | Arguments.createMap().apply { 28 | putDouble("latitude", latitude) 29 | putDouble("longitude", longitude) 30 | putDouble("zoom", zoom) 31 | putDouble("tilt", tilt) 32 | putDouble("bearing", bearing) 33 | putDouble("regionLatitude", regionLatitude) 34 | putDouble("regionLongitude", regionLongitude) 35 | putDouble("regionLatitudeDelta", regionLatitudeDelta) 36 | putDouble("regionLongitudeDelta", regionLongitudeDelta) 37 | } 38 | 39 | companion object { 40 | const val EVENT_NAME = "topCameraIdle" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapClusterLeafTapEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapClusterLeafTapEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | private val markerIdentifier: String, 11 | ) : Event(surfaceId, viewId) { 12 | override fun getEventName(): String = EVENT_NAME 13 | 14 | override fun canCoalesce(): Boolean = false 15 | 16 | override fun getCoalescingKey(): Short = 0 17 | 18 | override fun getEventData(): WritableMap = 19 | Arguments.createMap().apply { 20 | putString("markerIdentifier", markerIdentifier) 21 | } 22 | 23 | companion object { 24 | const val EVENT_NAME = "topTapClusterLeaf" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapCoordinateToScreenEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapCoordinateToScreenEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | private val isValid: Boolean, 11 | private val screenX: Double, 12 | private val screenY: Double, 13 | ) : Event(surfaceId, viewId) { 14 | override fun getEventName(): String = EVENT_NAME 15 | 16 | override fun canCoalesce(): Boolean = false 17 | 18 | override fun getCoalescingKey(): Short = 0 19 | 20 | override fun getEventData(): WritableMap = 21 | Arguments.createMap().apply { 22 | putDouble("screenX", screenX) 23 | putDouble("screenY", screenY) 24 | putBoolean("isValid", isValid) 25 | } 26 | 27 | companion object { 28 | const val EVENT_NAME = "topCoordinateToScreen" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapInitializeEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapInitializeEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | ) : Event(surfaceId, viewId) { 11 | override fun getEventName(): String = EVENT_NAME 12 | 13 | override fun canCoalesce(): Boolean = false 14 | 15 | override fun getCoalescingKey(): Short = 0 16 | 17 | override fun getEventData(): WritableMap = Arguments.createMap() 18 | 19 | companion object { 20 | const val EVENT_NAME = "topInitialized" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapOptionChangeEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapOptionChangeEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | ) : Event(surfaceId, viewId) { 11 | override fun getEventName(): String = EVENT_NAME 12 | 13 | override fun canCoalesce(): Boolean = false 14 | 15 | override fun getCoalescingKey(): Short = 0 16 | 17 | override fun getEventData(): WritableMap = Arguments.createMap() 18 | 19 | companion object { 20 | const val EVENT_NAME = "topOptionChanged" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapOverlayTapEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapOverlayTapEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | ) : Event(surfaceId, viewId) { 11 | override fun getEventName(): String = EVENT_NAME 12 | 13 | override fun canCoalesce(): Boolean = false 14 | 15 | override fun getCoalescingKey(): Short = 0 16 | 17 | override fun getEventData(): WritableMap = Arguments.createMap() 18 | 19 | companion object { 20 | const val EVENT_NAME = "topTapOverlay" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapScreenToCoordinateEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapScreenToCoordinateEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | private val isValid: Boolean, 11 | private val latitude: Double, 12 | private val longitude: Double, 13 | ) : Event(surfaceId, viewId) { 14 | override fun getEventName(): String = EVENT_NAME 15 | 16 | override fun canCoalesce(): Boolean = false 17 | 18 | override fun getCoalescingKey(): Short = 0 19 | 20 | override fun getEventData(): WritableMap = 21 | Arguments.createMap().apply { 22 | putDouble("latitude", latitude) 23 | putDouble("longitude", longitude) 24 | putBoolean("isValid", isValid) 25 | } 26 | 27 | companion object { 28 | const val EVENT_NAME = "topScreenToCoordinate" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/event/NaverMapTapEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.event 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.WritableMap 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | class NaverMapTapEvent( 8 | surfaceId: Int, 9 | viewId: Int, 10 | private val latitude: Double, 11 | private val longitude: Double, 12 | private val x: Double, 13 | private val y: Double, 14 | ) : Event(surfaceId, viewId) { 15 | override fun getEventName(): String = EVENT_NAME 16 | 17 | override fun canCoalesce(): Boolean = false 18 | 19 | override fun getCoalescingKey(): Short = 0 20 | 21 | override fun getEventData(): WritableMap = 22 | Arguments.createMap().apply { 23 | putDouble("latitude", latitude) 24 | putDouble("longitude", longitude) 25 | putDouble("x", x) 26 | putDouble("y", y) 27 | } 28 | 29 | companion object { 30 | const val EVENT_NAME = "topTapMap" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/mapview/RNCNaverMapViewWrapper.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.mapview 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.Choreographer 6 | import android.view.Choreographer.FrameCallback 7 | import android.view.View 8 | import android.widget.FrameLayout 9 | import com.facebook.react.bridge.LifecycleEventListener 10 | import com.facebook.react.uimanager.ThemedReactContext 11 | import com.naver.maps.map.MapView 12 | import com.naver.maps.map.NaverMapOptions 13 | 14 | @SuppressLint("ViewConstructor") 15 | class RNCNaverMapViewWrapper( 16 | val reactContext: ThemedReactContext, 17 | private val mapOptions: NaverMapOptions, 18 | ) : FrameLayout(reactContext), 19 | LifecycleEventListener { 20 | var mapView: RNCNaverMapView? = null 21 | private set 22 | private var savedState: Bundle? = Bundle() 23 | 24 | init { 25 | mapView = RNCNaverMapView(reactContext, mapOptions) 26 | addView(mapView) 27 | } 28 | 29 | override fun onAttachedToWindow() { 30 | super.onAttachedToWindow() 31 | mapView?.run { 32 | onCreate(savedState) 33 | onStart() 34 | } 35 | setupLayoutHack() 36 | } 37 | 38 | override fun onDetachedFromWindow() { 39 | mapView?.run { 40 | onSaveInstanceState( 41 | savedState ?: run { 42 | Bundle().also { this@RNCNaverMapViewWrapper.savedState = it } 43 | }, 44 | ) 45 | } 46 | super.onDetachedFromWindow() 47 | } 48 | 49 | fun onDropViewInstance() { 50 | mapView?.run { 51 | onStop() 52 | onDestroy() 53 | } 54 | removeAllViews() 55 | savedState?.clear() 56 | savedState = null 57 | mapView = null 58 | } 59 | 60 | // https://github.com/facebook/react-native/issues/17968#issuecomment-457236577 61 | private fun setupLayoutHack() { 62 | Choreographer.getInstance().postFrameCallback( 63 | object : FrameCallback { 64 | override fun doFrame(frameTimeNanos: Long) { 65 | manuallyLayoutChildren() 66 | getViewTreeObserver().dispatchOnGlobalLayout() 67 | if (isAttachedToWindow) { 68 | Choreographer 69 | .getInstance() 70 | .postFrameCallbackDelayed(this, 500) 71 | } 72 | } 73 | }, 74 | ) 75 | } 76 | 77 | private fun manuallyLayoutChildren() { 78 | for (i in 0 until childCount) { 79 | val child = getChildAt(i) 80 | child.measure( 81 | MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY), 82 | MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY), 83 | ) 84 | child.layout(0, 0, child.measuredWidth, child.measuredHeight) 85 | } 86 | } 87 | 88 | override fun onHostResume() { 89 | mapView?.onResume() 90 | } 91 | 92 | override fun onHostPause() { 93 | mapView?.onPause() 94 | } 95 | 96 | override fun onHostDestroy() {} 97 | 98 | companion object { 99 | /** 100 | * A helper to get react tag id by given MapView 101 | */ 102 | @JvmStatic 103 | fun getReactTagFromMapView(mapView: MapView): Int { 104 | // It is expected that the mapView is enclosed by [RNCNaverMapViewWrapper] as the first child. 105 | // Therefore, it must have a parent, and the parent ID is the reactTag. 106 | // In exceptional cases, such as receiving MapView messaging after the view has been unmounted, 107 | // the WebView will not have a parent. 108 | // In this case, we simply return -1 to indicate that it was not found. 109 | return (mapView.parent as? View)?.id ?: -1 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/RNCNaverMapOverlay.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay 2 | 3 | import android.content.Context 4 | import com.facebook.react.views.view.ReactViewGroup 5 | import com.naver.maps.map.NaverMap 6 | import com.naver.maps.map.overlay.Overlay 7 | 8 | abstract class RNCNaverMapOverlay( 9 | context: Context?, 10 | ) : ReactViewGroup(context) { 11 | abstract val overlay: T 12 | 13 | abstract fun addToMap(map: NaverMap) 14 | 15 | abstract fun removeFromMap(map: NaverMap) 16 | 17 | abstract fun onDropViewInstance() 18 | } 19 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/arrowheadpath/RNCNaverMapArrowheadPath.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.arrowheadpath 2 | 3 | import android.annotation.SuppressLint 4 | import com.facebook.react.uimanager.ThemedReactContext 5 | import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent 6 | import com.mjstudio.reactnativenavermap.overlay.RNCNaverMapOverlay 7 | import com.mjstudio.reactnativenavermap.util.emitEvent 8 | import com.naver.maps.map.NaverMap 9 | import com.naver.maps.map.overlay.ArrowheadPathOverlay 10 | 11 | @SuppressLint("ViewConstructor") 12 | class RNCNaverMapArrowheadPath( 13 | val reactContext: ThemedReactContext, 14 | ) : RNCNaverMapOverlay(reactContext) { 15 | override val overlay: ArrowheadPathOverlay by lazy { 16 | ArrowheadPathOverlay().apply { 17 | setOnClickListener { 18 | reactContext.emitEvent(id) { surfaceId, reactTag -> 19 | NaverMapOverlayTapEvent( 20 | surfaceId, 21 | reactTag, 22 | ) 23 | } 24 | true 25 | } 26 | } 27 | } 28 | 29 | override fun addToMap(map: NaverMap) { 30 | overlay.map = map 31 | } 32 | 33 | override fun removeFromMap(map: NaverMap) { 34 | overlay.map = null 35 | } 36 | 37 | override fun onDropViewInstance() { 38 | overlay.map = null 39 | overlay.onClickListener = null 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/circle/RNCNaverMapCircle.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.circle 2 | 3 | import android.annotation.SuppressLint 4 | import com.facebook.react.uimanager.ThemedReactContext 5 | import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent 6 | import com.mjstudio.reactnativenavermap.overlay.RNCNaverMapOverlay 7 | import com.mjstudio.reactnativenavermap.util.emitEvent 8 | import com.naver.maps.map.NaverMap 9 | import com.naver.maps.map.overlay.CircleOverlay 10 | 11 | @SuppressLint("ViewConstructor") 12 | class RNCNaverMapCircle( 13 | private val reactContext: ThemedReactContext, 14 | ) : RNCNaverMapOverlay(reactContext) { 15 | override val overlay: CircleOverlay by lazy { 16 | CircleOverlay().apply { 17 | setOnClickListener { 18 | reactContext.emitEvent(id) { surfaceId, reactTag -> 19 | NaverMapOverlayTapEvent( 20 | surfaceId, 21 | reactTag, 22 | ) 23 | } 24 | true 25 | } 26 | } 27 | } 28 | 29 | override fun addToMap(map: NaverMap) { 30 | overlay.map = map 31 | } 32 | 33 | override fun removeFromMap(map: NaverMap) { 34 | overlay.map = null 35 | } 36 | 37 | override fun onDropViewInstance() { 38 | overlay.map = null 39 | overlay.onClickListener = null 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/ground/RNCNaverMapGround.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.ground 2 | 3 | import android.annotation.SuppressLint 4 | import android.graphics.Bitmap 5 | import com.facebook.react.uimanager.ThemedReactContext 6 | import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent 7 | import com.mjstudio.reactnativenavermap.util.emitEvent 8 | import com.mjstudio.reactnativenavermap.util.image.RNCNaverMapImageRenderableOverlay 9 | import com.naver.maps.map.NaverMap 10 | import com.naver.maps.map.overlay.GroundOverlay 11 | import com.naver.maps.map.overlay.OverlayImage 12 | import com.naver.maps.map.util.MarkerIcons 13 | 14 | @SuppressLint("ViewConstructor") 15 | class RNCNaverMapGround( 16 | private val reactContext: ThemedReactContext, 17 | ) : RNCNaverMapImageRenderableOverlay(reactContext) { 18 | private var isImageSet = false 19 | 20 | override val overlay: GroundOverlay by lazy { 21 | GroundOverlay().apply { 22 | setOnClickListener { 23 | reactContext.emitEvent(id) { surfaceId, reactTag -> 24 | NaverMapOverlayTapEvent( 25 | surfaceId, 26 | reactTag, 27 | ) 28 | } 29 | true 30 | } 31 | } 32 | } 33 | 34 | override fun addToMap(map: NaverMap) { 35 | if (!isImageSet) { 36 | overlay.image = MarkerIcons.GREEN 37 | overlay.alpha = 0f 38 | } 39 | overlay.map = map 40 | } 41 | 42 | override fun removeFromMap(map: NaverMap) { 43 | overlay.map = null 44 | } 45 | 46 | override fun onDropViewInstance() { 47 | overlay.map = null 48 | overlay.onClickListener = null 49 | super.onDropViewInstance() 50 | } 51 | 52 | override fun setOverlayAlpha(alpha: Float) { 53 | overlay.alpha = alpha 54 | } 55 | 56 | override fun setOverlayImage(image: OverlayImage?) { 57 | isImageSet = true 58 | overlay.image = 59 | image ?: OverlayImage.fromBitmap(Bitmap.createBitmap(0, 0, Bitmap.Config.ARGB_8888)) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/ground/RNCNaverMapGroundManager.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.ground 2 | 3 | import com.facebook.react.bridge.ReadableMap 4 | import com.facebook.react.uimanager.ThemedReactContext 5 | import com.facebook.react.uimanager.annotations.ReactProp 6 | import com.mjstudio.reactnativenavermap.RNCNaverMapGroundManagerSpec 7 | import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent 8 | import com.mjstudio.reactnativenavermap.util.getLatLngBoundsOrNull 9 | import com.mjstudio.reactnativenavermap.util.isValidNumber 10 | import com.mjstudio.reactnativenavermap.util.registerDirectEvent 11 | import com.naver.maps.map.overlay.GroundOverlay 12 | 13 | class RNCNaverMapGroundManager : RNCNaverMapGroundManagerSpec() { 14 | override fun getName(): String = NAME 15 | 16 | override fun createViewInstance(context: ThemedReactContext): RNCNaverMapGround = RNCNaverMapGround(context) 17 | 18 | override fun onDropViewInstance(view: RNCNaverMapGround) { 19 | super.onDropViewInstance(view) 20 | view.onDropViewInstance() 21 | } 22 | 23 | override fun getExportedCustomDirectEventTypeConstants(): MutableMap = 24 | (super.getExportedCustomDirectEventTypeConstants() ?: mutableMapOf()).apply { 25 | registerDirectEvent(this, NaverMapOverlayTapEvent.EVENT_NAME) 26 | } 27 | 28 | private fun RNCNaverMapGround?.withOverlay(fn: (GroundOverlay) -> Unit) { 29 | this?.overlay?.run(fn) 30 | } 31 | 32 | @ReactProp(name = "zIndexValue") 33 | override fun setZIndexValue( 34 | view: RNCNaverMapGround?, 35 | value: Int, 36 | ) = view.withOverlay { 37 | it.zIndex = value 38 | } 39 | 40 | @ReactProp(name = "globalZIndexValue") 41 | override fun setGlobalZIndexValue( 42 | view: RNCNaverMapGround?, 43 | value: Int, 44 | ) = view.withOverlay { 45 | if (isValidNumber(value)) { 46 | it.globalZIndex = value 47 | } 48 | } 49 | 50 | @ReactProp(name = "isHidden") 51 | override fun setIsHidden( 52 | view: RNCNaverMapGround?, 53 | value: Boolean, 54 | ) = view.withOverlay { 55 | it.isVisible = !value 56 | } 57 | 58 | @ReactProp(name = "minZoom") 59 | override fun setMinZoom( 60 | view: RNCNaverMapGround?, 61 | value: Double, 62 | ) = view.withOverlay { 63 | it.minZoom = value 64 | } 65 | 66 | @ReactProp(name = "maxZoom") 67 | override fun setMaxZoom( 68 | view: RNCNaverMapGround?, 69 | value: Double, 70 | ) = view.withOverlay { 71 | it.maxZoom = value 72 | } 73 | 74 | @ReactProp(name = "isMinZoomInclusive") 75 | override fun setIsMinZoomInclusive( 76 | view: RNCNaverMapGround?, 77 | value: Boolean, 78 | ) = view.withOverlay { 79 | it.isMinZoomInclusive = value 80 | } 81 | 82 | @ReactProp(name = "isMaxZoomInclusive") 83 | override fun setIsMaxZoomInclusive( 84 | view: RNCNaverMapGround?, 85 | value: Boolean, 86 | ) = view.withOverlay { 87 | it.isMaxZoomInclusive = value 88 | } 89 | 90 | @ReactProp(name = "image") 91 | override fun setImage( 92 | view: RNCNaverMapGround?, 93 | value: ReadableMap?, 94 | ) { 95 | view?.setImage(value) 96 | } 97 | 98 | @ReactProp(name = "region") 99 | override fun setRegion( 100 | view: RNCNaverMapGround?, 101 | value: ReadableMap?, 102 | ) = view.withOverlay { 103 | value?.getLatLngBoundsOrNull()?. run { 104 | it.bounds = this 105 | } 106 | } 107 | 108 | // region PROPS 109 | 110 | companion object { 111 | const val NAME = "RNCNaverMapGround" 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/cluster/RNCNaverMapClusterDataHolder.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.marker.cluster 2 | 3 | internal data class RNCNaverMapClusterDataHolder internal constructor( 4 | val width: Double? = null, 5 | val height: Double? = null, 6 | ) 7 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/cluster/RNCNaverMapClusterKey.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.marker.cluster 2 | 3 | import com.naver.maps.geometry.LatLng 4 | import com.naver.maps.map.clustering.ClusteringKey 5 | 6 | internal data class RNCNaverMapClusterKey( 7 | val holder: RNCNaverMapLeafMarkerHolder, 8 | ) : ClusteringKey { 9 | override fun getPosition(): LatLng = holder.latlng 10 | } 11 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/cluster/RNCNaverMapClusterMarkerUpdater.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.marker.cluster 2 | 3 | import com.mjstudio.reactnativenavermap.util.px 4 | import com.naver.maps.map.clustering.ClusterMarkerInfo 5 | import com.naver.maps.map.clustering.DefaultClusterMarkerUpdater 6 | import com.naver.maps.map.overlay.Marker 7 | import com.naver.maps.map.overlay.Marker.SIZE_AUTO 8 | 9 | internal class RNCNaverMapClusterMarkerUpdater( 10 | private val holder: RNCNaverMapClusterDataHolder, 11 | ) : DefaultClusterMarkerUpdater() { 12 | override fun updateClusterMarker( 13 | info: ClusterMarkerInfo, 14 | marker: Marker, 15 | ) { 16 | super.updateClusterMarker(info, marker) 17 | val (width, height) = holder 18 | marker.width = width?.px ?: SIZE_AUTO 19 | marker.height = height?.px ?: SIZE_AUTO 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/cluster/RNCNaverMapLeafDataHolder.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.marker.cluster 2 | 3 | import com.facebook.drawee.generic.GenericDraweeHierarchy 4 | import com.facebook.drawee.view.DraweeHolder 5 | import com.facebook.react.bridge.ReactApplicationContext 6 | import com.mjstudio.reactnativenavermap.util.image.createDraweeHierarchy 7 | import com.naver.maps.map.clustering.Clusterer 8 | 9 | internal data class RNCNaverMapLeafDataHolder internal constructor( 10 | val identifier: String, 11 | val clusterer: Clusterer, 12 | val context: ReactApplicationContext, 13 | val markers: List, 14 | ) { 15 | private val imageHolder: DraweeHolder by lazy { 16 | DraweeHolder.create(createDraweeHierarchy(context.resources), context).apply { 17 | onAttach() 18 | } 19 | } 20 | 21 | fun onDetach() { 22 | markers.forEach { it.onDetach() } 23 | clusterer.map = null 24 | imageHolder.onDetach() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/cluster/RNCNaverMapLeafMarkerHolder.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.marker.cluster 2 | 3 | import com.facebook.drawee.generic.GenericDraweeHierarchy 4 | import com.facebook.drawee.view.DraweeHolder 5 | import com.facebook.react.bridge.ReactApplicationContext 6 | import com.mjstudio.reactnativenavermap.util.image.createDraweeHierarchy 7 | import com.naver.maps.geometry.LatLng 8 | 9 | internal data class RNCNaverMapLeafMarkerHolder( 10 | val identifier: String, 11 | val latlng: LatLng, 12 | val context: ReactApplicationContext, 13 | val image: Map<*, *>? = null, 14 | val width: Double?, 15 | val height: Double?, 16 | val onTapLeaf: (() -> Unit)?, 17 | ) { 18 | val imageHolder: DraweeHolder by lazy { 19 | DraweeHolder.create(createDraweeHierarchy(context.resources), context).apply { 20 | onAttach() 21 | } 22 | } 23 | 24 | fun onDetach() { 25 | imageHolder.onDetach() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/marker/cluster/RNCNaverMapLeafMarkerUpdater.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.marker.cluster 2 | 3 | import com.mjstudio.reactnativenavermap.util.image.getOverlayImage 4 | import com.mjstudio.reactnativenavermap.util.px 5 | import com.naver.maps.map.clustering.DefaultLeafMarkerUpdater 6 | import com.naver.maps.map.clustering.LeafMarkerInfo 7 | import com.naver.maps.map.overlay.Marker 8 | import com.naver.maps.map.overlay.Marker.SIZE_AUTO 9 | import com.naver.maps.map.util.MarkerIcons 10 | 11 | internal class RNCNaverMapLeafMarkerUpdater : DefaultLeafMarkerUpdater() { 12 | override fun updateLeafMarker( 13 | info: LeafMarkerInfo, 14 | marker: Marker, 15 | ) { 16 | super.updateLeafMarker(info, marker) 17 | 18 | (info.key as? RNCNaverMapClusterKey)?.let { (holder) -> 19 | val (_, _, _, image, width, height) = holder 20 | 21 | marker.width = width?.px ?: SIZE_AUTO 22 | marker.height = height?.px ?: SIZE_AUTO 23 | 24 | if (image != null) { 25 | marker.alpha = 0f 26 | getOverlayImage(holder.imageHolder, holder.context, image) { 27 | marker.icon = it ?: MarkerIcons.GREEN 28 | marker.alpha = 1f 29 | } 30 | } else { 31 | marker.alpha = 1f 32 | } 33 | 34 | marker.setOnClickListener { 35 | if (holder.onTapLeaf == null) { 36 | return@setOnClickListener false 37 | } 38 | holder.onTapLeaf.invoke() 39 | true 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/path/RNCNaverMapPath.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.path 2 | 3 | import android.annotation.SuppressLint 4 | import com.facebook.react.uimanager.ThemedReactContext 5 | import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent 6 | import com.mjstudio.reactnativenavermap.util.emitEvent 7 | import com.mjstudio.reactnativenavermap.util.image.RNCNaverMapImageRenderableOverlay 8 | import com.naver.maps.map.NaverMap 9 | import com.naver.maps.map.overlay.OverlayImage 10 | import com.naver.maps.map.overlay.PathOverlay 11 | 12 | @SuppressLint("ViewConstructor") 13 | class RNCNaverMapPath( 14 | val reactContext: ThemedReactContext, 15 | ) : RNCNaverMapImageRenderableOverlay(reactContext) { 16 | override val overlay: PathOverlay by lazy { 17 | PathOverlay().apply { 18 | setOnClickListener { 19 | reactContext.emitEvent(id) { surfaceId, reactTag -> 20 | NaverMapOverlayTapEvent( 21 | surfaceId, 22 | reactTag, 23 | ) 24 | } 25 | true 26 | } 27 | } 28 | } 29 | 30 | override fun addToMap(map: NaverMap) { 31 | overlay.map = map 32 | } 33 | 34 | override fun removeFromMap(map: NaverMap) { 35 | overlay.map = null 36 | } 37 | 38 | override fun onDropViewInstance() { 39 | overlay.map = null 40 | overlay.onClickListener = null 41 | super.onDropViewInstance() 42 | } 43 | 44 | override fun setOverlayAlpha(alpha: Float) { 45 | } 46 | 47 | override fun setOverlayImage(image: OverlayImage?) { 48 | overlay.patternImage = image 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/polygon/RNCNaverMapPolygon.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.polygon 2 | 3 | import android.annotation.SuppressLint 4 | import com.facebook.react.uimanager.ThemedReactContext 5 | import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent 6 | import com.mjstudio.reactnativenavermap.overlay.RNCNaverMapOverlay 7 | import com.mjstudio.reactnativenavermap.util.emitEvent 8 | import com.naver.maps.map.NaverMap 9 | import com.naver.maps.map.overlay.PolygonOverlay 10 | 11 | @SuppressLint("ViewConstructor") 12 | class RNCNaverMapPolygon( 13 | val reactContext: ThemedReactContext, 14 | ) : RNCNaverMapOverlay(reactContext) { 15 | override val overlay: PolygonOverlay by lazy { 16 | PolygonOverlay().apply { 17 | setOnClickListener { 18 | reactContext.emitEvent(id) { surfaceId, reactTag -> 19 | NaverMapOverlayTapEvent( 20 | surfaceId, 21 | reactTag, 22 | ) 23 | } 24 | true 25 | } 26 | } 27 | } 28 | 29 | override fun addToMap(map: NaverMap) { 30 | overlay.map = map 31 | } 32 | 33 | override fun removeFromMap(map: NaverMap) { 34 | overlay.map = null 35 | } 36 | 37 | override fun onDropViewInstance() { 38 | overlay.map = null 39 | overlay.onClickListener = null 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/overlay/polyline/RNCNaverMapPolyline.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.overlay.polyline 2 | 3 | import android.annotation.SuppressLint 4 | import com.facebook.react.uimanager.ThemedReactContext 5 | import com.mjstudio.reactnativenavermap.event.NaverMapOverlayTapEvent 6 | import com.mjstudio.reactnativenavermap.overlay.RNCNaverMapOverlay 7 | import com.mjstudio.reactnativenavermap.util.emitEvent 8 | import com.naver.maps.map.NaverMap 9 | import com.naver.maps.map.overlay.PolylineOverlay 10 | 11 | @SuppressLint("ViewConstructor") 12 | class RNCNaverMapPolyline( 13 | val reactContext: ThemedReactContext, 14 | ) : RNCNaverMapOverlay(reactContext) { 15 | override val overlay: PolylineOverlay by lazy { 16 | PolylineOverlay().apply { 17 | setOnClickListener { 18 | reactContext.emitEvent(id) { surfaceId, reactTag -> 19 | NaverMapOverlayTapEvent( 20 | surfaceId, 21 | reactTag, 22 | ) 23 | } 24 | true 25 | } 26 | } 27 | } 28 | 29 | override fun addToMap(map: NaverMap) { 30 | overlay.map = map 31 | } 32 | 33 | override fun removeFromMap(map: NaverMap) { 34 | overlay.map = null 35 | } 36 | 37 | override fun onDropViewInstance() { 38 | overlay.map = null 39 | overlay.onClickListener = null 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/CameraAnimationUtil.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util 2 | 3 | import com.naver.maps.map.CameraAnimation 4 | 5 | internal object CameraAnimationUtil { 6 | internal fun numberToCameraAnimationEasing(value: Int) = 7 | when (value) { 8 | 1 -> CameraAnimation.None 9 | 2 -> CameraAnimation.Linear 10 | 3 -> CameraAnimation.Fly 11 | else -> CameraAnimation.Easing 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/DirectEventUtils.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util 2 | 3 | internal fun registerDirectEvent( 4 | map: MutableMap, 5 | name: String, 6 | ) { 7 | map[name] = mutableMapOf("registrationName" to name.replace(Regex("""^top"""), "on")) 8 | } 9 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/LogUtil.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util 2 | 3 | import android.util.Log 4 | import com.mjstudio.reactnativenavermap.BuildConfig 5 | 6 | private fun debugE( 7 | tag: String, 8 | message: Any?, 9 | ) { 10 | if (BuildConfig.DEBUG) Log.e(tag, "⭐️" + message.toString()) 11 | } 12 | 13 | internal fun debugE(vararg message: Any?) { 14 | var str = "" 15 | for (i in message) { 16 | str += i.toString() + ", " 17 | } 18 | debugE("RNCNaverMapView", str) 19 | } 20 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/RNCNaverMapRegion.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util 2 | 3 | import com.naver.maps.geometry.LatLng 4 | import com.naver.maps.geometry.LatLngBounds 5 | 6 | internal data class RNCNaverMapRegion( 7 | val latitude: Double, 8 | val longitude: Double, 9 | val latitudeDelta: Double, 10 | val longitudeDelta: Double, 11 | ) { 12 | fun convertToBounds(): LatLngBounds = 13 | LatLngBounds( 14 | LatLng(latitude, longitude), 15 | LatLng( 16 | latitude + latitudeDelta, 17 | longitude + longitudeDelta, 18 | ), 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/RectUtil.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util 2 | 3 | import android.graphics.Rect 4 | import com.facebook.react.bridge.ReadableMap 5 | import kotlin.math.roundToInt 6 | 7 | internal object RectUtil { 8 | internal fun getRect( 9 | padding: ReadableMap?, 10 | density: Float, 11 | defaultValue: Double = 0.0, 12 | ): Rect? { 13 | if (padding != null) { 14 | val top = ((padding.getDoubleOrNull("top") ?: defaultValue) * density).roundToInt() 15 | val right = ((padding.getDoubleOrNull("right") ?: defaultValue) * density).roundToInt() 16 | val bottom = ((padding.getDoubleOrNull("bottom") ?: defaultValue) * density).roundToInt() 17 | val left = ((padding.getDoubleOrNull("left") ?: defaultValue) * density).roundToInt() 18 | return Rect(left, top, right, bottom) 19 | } 20 | return null 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/ViewEventEmitter.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util 2 | 3 | import com.facebook.react.bridge.ReactContext 4 | import com.facebook.react.uimanager.UIManagerHelper 5 | import com.facebook.react.uimanager.events.Event 6 | 7 | internal fun > ReactContext.emitEvent( 8 | reactTag: Int, 9 | callback: (surfaceId: Int, reactTag: Int) -> T, 10 | ) { 11 | val surfaceId = UIManagerHelper.getSurfaceId(this) 12 | UIManagerHelper 13 | .getEventDispatcherForReactTag(this, reactTag) 14 | ?.dispatchEvent(callback(surfaceId, reactTag)) 15 | } 16 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/image/CreateDraweeHierarchy.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util.image 2 | 3 | import android.content.res.Resources 4 | import com.facebook.drawee.drawable.ScalingUtils 5 | import com.facebook.drawee.generic.GenericDraweeHierarchy 6 | import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder 7 | 8 | internal fun createDraweeHierarchy(resources: Resources): GenericDraweeHierarchy = 9 | GenericDraweeHierarchyBuilder(resources) 10 | .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER) 11 | .setFadeDuration(0) 12 | .build() 13 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/image/OverlayImageCache.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util.image 2 | 3 | import com.naver.maps.map.overlay.OverlayImage 4 | import java.util.concurrent.ConcurrentHashMap 5 | 6 | object OverlayImageCache { 7 | private val store: MutableMap = ConcurrentHashMap() 8 | 9 | fun put( 10 | uri: String, 11 | image: OverlayImage, 12 | ) { 13 | store[uri] = image 14 | } 15 | 16 | operator fun get(uri: String): OverlayImage? = store[uri] 17 | } 18 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/image/RNCNaverMapImageRenderableOverlay.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util.image 2 | 3 | import android.content.Context 4 | import androidx.annotation.CallSuper 5 | import com.facebook.drawee.generic.GenericDraweeHierarchy 6 | import com.facebook.drawee.view.DraweeHolder 7 | import com.facebook.react.bridge.ReadableMap 8 | import com.mjstudio.reactnativenavermap.overlay.RNCNaverMapOverlay 9 | import com.naver.maps.map.overlay.Overlay 10 | import com.naver.maps.map.overlay.OverlayImage 11 | 12 | abstract class RNCNaverMapImageRenderableOverlay( 13 | private val context: Context, 14 | ) : RNCNaverMapOverlay(context) { 15 | private val imageHolder: DraweeHolder? by lazy { 16 | DraweeHolder.create(createDraweeHierarchy(resources), context)?.apply { 17 | onAttach() 18 | } 19 | } 20 | private var lastImage: ReadableMap? = null 21 | 22 | @CallSuper 23 | override fun onDropViewInstance() { 24 | imageHolder?.onDetach() 25 | } 26 | 27 | protected abstract fun setOverlayAlpha(alpha: Float) 28 | 29 | protected abstract fun setOverlayImage(image: OverlayImage?) 30 | 31 | protected open fun skipTryRender() = false 32 | 33 | protected fun setImageWithLastImage() { 34 | setImage(lastImage) 35 | } 36 | 37 | fun setImage(image: ReadableMap?) { 38 | lastImage = image 39 | if (skipTryRender()) return 40 | setOverlayAlpha(0f) 41 | getOverlayImage(imageHolder!!, context, image?.toHashMap()) { 42 | setOverlayImage(it) 43 | setOverlayAlpha(1f) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /android/src/main/java/com/mjstudio/reactnativenavermap/util/image/RNCNaverMapTaggedImageRenderer.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap.util.image 2 | 3 | import android.content.Context 4 | import com.facebook.drawee.generic.GenericDraweeHierarchy 5 | import com.facebook.drawee.view.DraweeHolder 6 | import com.facebook.react.bridge.ReadableMap 7 | import com.naver.maps.map.overlay.OverlayImage 8 | 9 | internal class RNCNaverMapTaggedImageRenderer( 10 | private val context: Context, 11 | ) { 12 | private var imageHolder: DraweeHolder? = null 13 | private var lastImage: ReadableMap? = null 14 | 15 | fun onAttach() { 16 | imageHolder = 17 | DraweeHolder.create(createDraweeHierarchy(context.resources), context)?.apply { 18 | onAttach() 19 | } 20 | } 21 | 22 | fun onDetach() { 23 | imageHolder?.onDetach() 24 | } 25 | 26 | fun setImage( 27 | image: ReadableMap?, 28 | onImageLoaded: (OverlayImage?) -> Unit, 29 | ) { 30 | lastImage = image 31 | getOverlayImage(imageHolder!!, context, image?.toHashMap(), onImageLoaded) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /android/src/newarch/RNCNaverMapArrowheadPathManagerSpec.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import android.view.View 4 | import com.facebook.react.uimanager.SimpleViewManager 5 | import com.facebook.react.uimanager.ViewManagerDelegate 6 | import com.facebook.react.viewmanagers.RNCNaverMapArrowheadPathManagerDelegate 7 | import com.facebook.react.viewmanagers.RNCNaverMapArrowheadPathManagerInterface 8 | 9 | abstract class RNCNaverMapArrowheadPathManagerSpec : 10 | SimpleViewManager(), 11 | RNCNaverMapArrowheadPathManagerInterface { 12 | private val mDelegate: ViewManagerDelegate 13 | 14 | init { 15 | mDelegate = RNCNaverMapArrowheadPathManagerDelegate(this) 16 | } 17 | 18 | override fun getDelegate(): ViewManagerDelegate? = mDelegate 19 | } 20 | -------------------------------------------------------------------------------- /android/src/newarch/RNCNaverMapCircleManagerSpec.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import android.view.View 4 | import com.facebook.react.uimanager.SimpleViewManager 5 | import com.facebook.react.uimanager.ViewManagerDelegate 6 | import com.facebook.react.viewmanagers.RNCNaverMapCircleManagerDelegate 7 | import com.facebook.react.viewmanagers.RNCNaverMapCircleManagerInterface 8 | 9 | abstract class RNCNaverMapCircleManagerSpec : 10 | SimpleViewManager(), 11 | RNCNaverMapCircleManagerInterface { 12 | private val mDelegate: ViewManagerDelegate 13 | 14 | init { 15 | mDelegate = RNCNaverMapCircleManagerDelegate(this) 16 | } 17 | 18 | override fun getDelegate(): ViewManagerDelegate? = mDelegate 19 | } 20 | -------------------------------------------------------------------------------- /android/src/newarch/RNCNaverMapGroundManagerSpec.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import android.view.View 4 | import com.facebook.react.uimanager.SimpleViewManager 5 | import com.facebook.react.uimanager.ViewManagerDelegate 6 | import com.facebook.react.viewmanagers.RNCNaverMapGroundManagerDelegate 7 | import com.facebook.react.viewmanagers.RNCNaverMapGroundManagerInterface 8 | 9 | abstract class RNCNaverMapGroundManagerSpec : 10 | SimpleViewManager(), 11 | RNCNaverMapGroundManagerInterface { 12 | private val mDelegate: ViewManagerDelegate 13 | 14 | init { 15 | mDelegate = RNCNaverMapGroundManagerDelegate(this) 16 | } 17 | 18 | override fun getDelegate(): ViewManagerDelegate? = mDelegate 19 | } 20 | -------------------------------------------------------------------------------- /android/src/newarch/RNCNaverMapMarkerManagerSpec.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import android.view.ViewGroup 4 | import com.facebook.react.uimanager.ViewGroupManager 5 | import com.facebook.react.uimanager.ViewManagerDelegate 6 | import com.facebook.react.viewmanagers.RNCNaverMapMarkerManagerDelegate 7 | import com.facebook.react.viewmanagers.RNCNaverMapMarkerManagerInterface 8 | 9 | abstract class RNCNaverMapMarkerManagerSpec : 10 | ViewGroupManager(), 11 | RNCNaverMapMarkerManagerInterface { 12 | private val mDelegate: ViewManagerDelegate 13 | 14 | init { 15 | mDelegate = RNCNaverMapMarkerManagerDelegate(this) 16 | } 17 | 18 | override fun getDelegate(): ViewManagerDelegate? = mDelegate 19 | } 20 | -------------------------------------------------------------------------------- /android/src/newarch/RNCNaverMapPathManagerSpec.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import android.view.View 4 | import com.facebook.react.uimanager.SimpleViewManager 5 | import com.facebook.react.uimanager.ViewManagerDelegate 6 | import com.facebook.react.viewmanagers.RNCNaverMapPathManagerDelegate 7 | import com.facebook.react.viewmanagers.RNCNaverMapPathManagerInterface 8 | 9 | abstract class RNCNaverMapPathManagerSpec : 10 | SimpleViewManager(), 11 | RNCNaverMapPathManagerInterface { 12 | private val mDelegate: ViewManagerDelegate 13 | 14 | init { 15 | mDelegate = RNCNaverMapPathManagerDelegate(this) 16 | } 17 | 18 | override fun getDelegate(): ViewManagerDelegate? = mDelegate 19 | } 20 | -------------------------------------------------------------------------------- /android/src/newarch/RNCNaverMapPolygonManagerSpec.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import android.view.View 4 | import com.facebook.react.uimanager.SimpleViewManager 5 | import com.facebook.react.uimanager.ViewManagerDelegate 6 | import com.facebook.react.viewmanagers.RNCNaverMapPolygonManagerDelegate 7 | import com.facebook.react.viewmanagers.RNCNaverMapPolygonManagerInterface 8 | 9 | abstract class RNCNaverMapPolygonManagerSpec : 10 | SimpleViewManager(), 11 | RNCNaverMapPolygonManagerInterface { 12 | private val mDelegate: ViewManagerDelegate 13 | 14 | init { 15 | mDelegate = RNCNaverMapPolygonManagerDelegate(this) 16 | } 17 | 18 | override fun getDelegate(): ViewManagerDelegate? = mDelegate 19 | } 20 | -------------------------------------------------------------------------------- /android/src/newarch/RNCNaverMapPolylineManagerSpec.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import android.view.View 4 | import com.facebook.react.uimanager.SimpleViewManager 5 | import com.facebook.react.uimanager.ViewManagerDelegate 6 | import com.facebook.react.viewmanagers.RNCNaverMapPolylineManagerDelegate 7 | import com.facebook.react.viewmanagers.RNCNaverMapPolylineManagerInterface 8 | 9 | abstract class RNCNaverMapPolylineManagerSpec : 10 | SimpleViewManager(), 11 | RNCNaverMapPolylineManagerInterface { 12 | private val mDelegate: ViewManagerDelegate 13 | 14 | init { 15 | mDelegate = RNCNaverMapPolylineManagerDelegate(this) 16 | } 17 | 18 | override fun getDelegate(): ViewManagerDelegate? = mDelegate 19 | } 20 | -------------------------------------------------------------------------------- /android/src/newarch/RNCNaverMapViewManagerSpec.kt: -------------------------------------------------------------------------------- 1 | package com.mjstudio.reactnativenavermap 2 | 3 | import android.view.ViewGroup 4 | import com.facebook.react.uimanager.ViewGroupManager 5 | import com.facebook.react.uimanager.ViewManagerDelegate 6 | import com.facebook.react.viewmanagers.RNCNaverMapViewManagerDelegate 7 | import com.facebook.react.viewmanagers.RNCNaverMapViewManagerInterface 8 | 9 | abstract class RNCNaverMapViewManagerSpec : 10 | ViewGroupManager(), 11 | RNCNaverMapViewManagerInterface { 12 | private val mDelegate: ViewManagerDelegate 13 | 14 | init { 15 | mDelegate = RNCNaverMapViewManagerDelegate(this) 16 | } 17 | 18 | override fun getDelegate(): ViewManagerDelegate? = mDelegate 19 | } 20 | -------------------------------------------------------------------------------- /app.plugin.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./expo-config-plugin/build'); 2 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures. 7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' 8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' 9 | -------------------------------------------------------------------------------- /example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.7) 5 | base64 6 | nkf 7 | rexml 8 | activesupport (7.0.8.1) 9 | concurrent-ruby (~> 1.0, >= 1.0.2) 10 | i18n (>= 1.6, < 2) 11 | minitest (>= 5.1) 12 | tzinfo (~> 2.0) 13 | addressable (2.8.6) 14 | public_suffix (>= 2.0.2, < 6.0) 15 | algoliasearch (1.27.5) 16 | httpclient (~> 2.8, >= 2.8.3) 17 | json (>= 1.5.1) 18 | atomos (0.1.3) 19 | base64 (0.2.0) 20 | claide (1.1.0) 21 | cocoapods (1.14.3) 22 | addressable (~> 2.8) 23 | claide (>= 1.0.2, < 2.0) 24 | cocoapods-core (= 1.14.3) 25 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 26 | cocoapods-downloader (>= 2.1, < 3.0) 27 | cocoapods-plugins (>= 1.0.0, < 2.0) 28 | cocoapods-search (>= 1.0.0, < 2.0) 29 | cocoapods-trunk (>= 1.6.0, < 2.0) 30 | cocoapods-try (>= 1.1.0, < 2.0) 31 | colored2 (~> 3.1) 32 | escape (~> 0.0.4) 33 | fourflusher (>= 2.3.0, < 3.0) 34 | gh_inspector (~> 1.0) 35 | molinillo (~> 0.8.0) 36 | nap (~> 1.0) 37 | ruby-macho (>= 2.3.0, < 3.0) 38 | xcodeproj (>= 1.23.0, < 2.0) 39 | cocoapods-core (1.14.3) 40 | activesupport (>= 5.0, < 8) 41 | addressable (~> 2.8) 42 | algoliasearch (~> 1.0) 43 | concurrent-ruby (~> 1.1) 44 | fuzzy_match (~> 2.0.4) 45 | nap (~> 1.0) 46 | netrc (~> 0.11) 47 | public_suffix (~> 4.0) 48 | typhoeus (~> 1.0) 49 | cocoapods-deintegrate (1.0.5) 50 | cocoapods-downloader (2.1) 51 | cocoapods-plugins (1.0.0) 52 | nap 53 | cocoapods-search (1.0.1) 54 | cocoapods-trunk (1.6.0) 55 | nap (>= 0.8, < 2.0) 56 | netrc (~> 0.11) 57 | cocoapods-try (1.2.0) 58 | colored2 (3.1.2) 59 | concurrent-ruby (1.2.3) 60 | escape (0.0.4) 61 | ethon (0.16.0) 62 | ffi (>= 1.15.0) 63 | ffi (1.16.3) 64 | fourflusher (2.3.1) 65 | fuzzy_match (2.0.4) 66 | gh_inspector (1.1.3) 67 | httpclient (2.8.3) 68 | i18n (1.14.4) 69 | concurrent-ruby (~> 1.0) 70 | json (2.7.1) 71 | minitest (5.22.3) 72 | molinillo (0.8.0) 73 | nanaimo (0.3.0) 74 | nap (1.1.0) 75 | netrc (0.11.0) 76 | nkf (0.2.0) 77 | public_suffix (4.0.7) 78 | rexml (3.2.6) 79 | ruby-macho (2.5.1) 80 | typhoeus (1.4.1) 81 | ethon (>= 0.9.0) 82 | tzinfo (2.0.6) 83 | concurrent-ruby (~> 1.0) 84 | xcodeproj (1.24.0) 85 | CFPropertyList (>= 2.3.3, < 4.0) 86 | atomos (~> 0.1.3) 87 | claide (>= 1.0.2, < 2.0) 88 | colored2 (~> 3.1) 89 | nanaimo (~> 0.3.0) 90 | rexml (~> 3.2.4) 91 | 92 | PLATFORMS 93 | ruby 94 | 95 | DEPENDENCIES 96 | activesupport (>= 6.1.7.5, != 7.1.0) 97 | cocoapods (>= 1.13, != 1.15.1, != 1.15.0) 98 | 99 | RUBY VERSION 100 | ruby 3.1.2p20 101 | 102 | BUNDLED WITH 103 | 2.5.7 104 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). 2 | 3 | # Getting Started 4 | 5 | >**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. 6 | 7 | ## Step 1: Start the Metro Server 8 | 9 | First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. 10 | 11 | To start Metro, run the following command from the _root_ of your React Native project: 12 | 13 | ```bash 14 | # using npm 15 | npm start 16 | 17 | # OR using Yarn 18 | yarn start 19 | ``` 20 | 21 | ## Step 2: Start your Application 22 | 23 | Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app: 24 | 25 | ### For Android 26 | 27 | ```bash 28 | # using npm 29 | npm run android 30 | 31 | # OR using Yarn 32 | yarn android 33 | ``` 34 | 35 | ### For iOS 36 | 37 | ```bash 38 | # using npm 39 | npm run ios 40 | 41 | # OR using Yarn 42 | yarn ios 43 | ``` 44 | 45 | If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly. 46 | 47 | This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively. 48 | 49 | ## Step 3: Modifying your App 50 | 51 | Now that you have successfully run the app, let's modify it. 52 | 53 | 1. Open `App.tsx` in your text editor of choice and edit some lines. 54 | 2. For **Android**: Press the R key twice or select **"Reload"** from the **Developer Menu** (Ctrl + M (on Window and Linux) or Cmd ⌘ + M (on macOS)) to see your changes! 55 | 56 | For **iOS**: Hit Cmd ⌘ + R in your iOS Simulator to reload the app and see your changes! 57 | 58 | ## Congratulations! :tada: 59 | 60 | You've successfully run and modified your React Native App. :partying_face: 61 | 62 | ### Now what? 63 | 64 | - If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps). 65 | - If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). 66 | 67 | # Troubleshooting 68 | 69 | If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. 70 | 71 | # Learn More 72 | 73 | To learn more about React Native, take a look at the following resources: 74 | 75 | - [React Native Website](https://reactnative.dev) - learn more about React Native. 76 | - [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment. 77 | - [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**. 78 | - [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts. 79 | - [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native. 80 | -------------------------------------------------------------------------------- /example/android/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig 2 | root = true 3 | 4 | [*.{kt,kts}] 5 | ktlint_code_style = ktlint_official 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/navermapexample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.navermapexample 2 | 3 | import com.facebook.react.ReactActivity 4 | import com.facebook.react.ReactActivityDelegate 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate 7 | 8 | class MainActivity : ReactActivity() { 9 | /** 10 | * Returns the name of the main component registered from JavaScript. This is used to schedule 11 | * rendering of the component. 12 | */ 13 | override fun getMainComponentName(): String = "NaverMapExample" 14 | 15 | /** 16 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] 17 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] 18 | */ 19 | override fun createReactActivityDelegate(): ReactActivityDelegate = DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) 20 | } 21 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/navermapexample/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.navermapexample 2 | 3 | import android.app.Application 4 | import com.facebook.react.PackageList 5 | import com.facebook.react.ReactApplication 6 | import com.facebook.react.ReactHost 7 | import com.facebook.react.ReactNativeHost 8 | import com.facebook.react.ReactPackage 9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost 11 | import com.facebook.react.defaults.DefaultReactNativeHost 12 | import com.facebook.soloader.SoLoader 13 | 14 | class MainApplication : 15 | Application(), 16 | ReactApplication { 17 | override val reactNativeHost: ReactNativeHost = 18 | object : DefaultReactNativeHost(this) { 19 | override fun getPackages(): List = 20 | PackageList(this).packages.apply { 21 | // Packages that cannot be autolinked yet can be added manually here, for example: 22 | // add(MyReactNativePackage()) 23 | } 24 | 25 | override fun getJSMainModuleName(): String = "index" 26 | 27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 28 | 29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 31 | } 32 | 33 | override val reactHost: ReactHost 34 | get() = getDefaultReactHost(applicationContext, reactNativeHost) 35 | 36 | override fun onCreate() { 37 | super.onCreate() 38 | SoLoader.init(this, false) 39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 40 | // If you opted-in for the New Architecture, we load the native entry point for this app. 41 | load() 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/drawable/thumbnail.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | NaverMapExample 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 24 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "26.1.10909125" 8 | kotlinVersion = "1.9.24" 9 | } 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle") 16 | classpath("com.facebook.react:react-native-gradle-plugin") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") 18 | } 19 | } 20 | 21 | allprojects { 22 | repositories { 23 | maven { 24 | url "https://repository.map.naver.com/archive/maven" 25 | } 26 | } 27 | } 28 | 29 | apply plugin: "com.facebook.react.rootproject" 30 | -------------------------------------------------------------------------------- /example/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 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 10 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 11 | # When configured, Gradle will run in incubating parallel mode. 12 | # This option should only be used with decoupled projects. More details, visit 13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 14 | # org.gradle.parallel=true 15 | # AndroidX package structure to make it clearer which packages are bundled with the 16 | # Android operating system, and which are packaged with your app's APK 17 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 18 | android.useAndroidX=true 19 | # Use this property to specify which architecture you want to build. 20 | # You can also override it from the CLI using 21 | # ./gradlew -PreactNativeArchitectures=x86_64 22 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 23 | # Use this property to enable support to the new architecture. 24 | # This will allow you to use TurboModules and the Fabric render in 25 | # your application. You should enable this flag either if you want 26 | # to write custom TurboModules/Fabric components OR use libraries that 27 | # are providing them. 28 | newArchEnabled=true 29 | # Use this property to enable or disable the Hermes JS engine. 30 | # If set to false, you will be using JSC instead. 31 | hermesEnabled=true 32 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } 2 | plugins { id("com.facebook.react.settings") } 3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand(["npx", "react-native@0.75.2", "config"]) } 4 | rootProject.name = 'NaverMapExample' 5 | include ':app' 6 | includeBuild('../node_modules/@react-native/gradle-plugin') 7 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NaverMapExample", 3 | "displayName": "NaverMapExample" 4 | } 5 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | presets: ['module:@react-native/babel-preset'], 6 | plugins: [ 7 | [ 8 | 'module-resolver', 9 | { 10 | extensions: ['.tsx', '.ts', '.js', '.json'], 11 | alias: { 12 | [pak.name]: path.join(__dirname, '..', pak.source), 13 | }, 14 | }, 15 | ], 16 | ], 17 | }; 18 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/App'; 3 | import { name as appName } from './app.json'; 4 | 5 | AppRegistry.registerComponent(appName, () => App); 6 | -------------------------------------------------------------------------------- /example/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /example/ios/.xcode.env.local: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /example/ios/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // NaverMapExample 4 | // 5 | 6 | import Foundation 7 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication*)application 8 | didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { 9 | self.moduleName = @"NaverMapExample"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL*)sourceURLForBridge:(RCTBridge*)bridge { 18 | return [self bundleURL]; 19 | } 20 | 21 | - (NSURL*)bundleURL { 22 | #if DEBUG 23 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 24 | #else 25 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 26 | #endif 27 | } 28 | 29 | - (BOOL)bridgelessEnabled { 30 | return YES; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/102.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/102.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/216.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/66.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/92.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/AppIcon.appiconset/92.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/thumbnail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "rn-naver- 1.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "rn-naver- 2.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "rn-naver-.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/thumbnail.imageset/rn-naver- 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/thumbnail.imageset/rn-naver- 1.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/thumbnail.imageset/rn-naver- 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/thumbnail.imageset/rn-naver- 2.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Images.xcassets/thumbnail.imageset/rn-naver-.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/ios/NaverMapExample/Images.xcassets/thumbnail.imageset/rn-naver-.png -------------------------------------------------------------------------------- /example/ios/NaverMapExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | NaverMapExample 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NMFClientId 28 | $(NAVER_CLIENT_ID) 29 | NSAppTransportSecurity 30 | 31 | NSAllowsArbitraryLoads 32 | 33 | NSAllowsLocalNetworking 34 | 35 | 36 | NSLocationAlwaysAndWhenInUseUsageDescription 37 | NSLocationAlwaysAndWhenInUseUsageDescription 38 | NSLocationTemporaryUsageDescriptionDictionary 39 | 40 | common-purpose 41 | NSLocationTemporaryUsageDescriptionDictionary 42 | 43 | NSLocationWhenInUseUsageDescription 44 | NSLocationWhenInUseUsageDescription 45 | UIBackgroundModes 46 | 47 | location 48 | 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | UIRequiredDeviceCapabilities 52 | 53 | arm64 54 | 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | UIViewControllerBasedStatusBarAppearance 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryFileTimestamp 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | C617.1 13 | 14 | 15 | 16 | NSPrivacyAccessedAPIType 17 | NSPrivacyAccessedAPICategoryUserDefaults 18 | NSPrivacyAccessedAPITypeReasons 19 | 20 | CA92.1 21 | 22 | 23 | 24 | NSPrivacyAccessedAPIType 25 | NSPrivacyAccessedAPICategorySystemBootTime 26 | NSPrivacyAccessedAPITypeReasons 27 | 28 | 35F9.1 29 | 30 | 31 | 32 | NSPrivacyCollectedDataTypes 33 | 34 | NSPrivacyTracking 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/NaverMapExample/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/ios/NaverMapExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/ios/NaverMapExampleTests/NaverMapExampleTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface NaverMapExampleTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation NaverMapExampleTests 15 | 16 | - (BOOL)findSubviewInView:(UIView*)view matching:(BOOL (^)(UIView* view))test { 17 | if (test(view)) { 18 | return YES; 19 | } 20 | for (UIView* subview in [view subviews]) { 21 | if ([self findSubviewInView:subview matching:test]) { 22 | return YES; 23 | } 24 | } 25 | return NO; 26 | } 27 | 28 | - (void)testRendersWelcomeScreen { 29 | UIViewController* vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 30 | NSDate* date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 31 | BOOL foundElement = NO; 32 | 33 | __block NSString* redboxError = nil; 34 | #ifdef DEBUG 35 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString* fileName, 36 | NSNumber* lineNumber, NSString* message) { 37 | if (level >= RCTLogLevelError) { 38 | redboxError = message; 39 | } 40 | }); 41 | #endif 42 | 43 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 44 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode 45 | beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 46 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes 47 | beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = 50 | [self findSubviewInView:vc.view 51 | matching:^BOOL(UIView* view) { 52 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 53 | return YES; 54 | } 55 | return NO; 56 | }]; 57 | } 58 | 59 | #ifdef DEBUG 60 | RCTSetLogFunction(RCTDefaultLogFunction); 61 | #endif 62 | 63 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 64 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", 65 | TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | #require Pod::Executable.execute_command('node', ['-p', 3 | # 'require.resolve( 4 | # "react-native/scripts/react_native_pods.rb", 5 | # {paths: [process.argv[1]]}, 6 | # )', __dir__]).strip 7 | 8 | ## RNPERMISSION 9 | def node_require(script) 10 | # Resolve script with node to allow for hoisting 11 | require Pod::Executable.execute_command('node', ['-p', 12 | "require.resolve( 13 | '#{script}', 14 | {paths: [process.argv[1]]}, 15 | )", __dir__]).strip 16 | end 17 | 18 | node_require('react-native/scripts/react_native_pods.rb') 19 | node_require('react-native-permissions/scripts/setup.rb') 20 | ########## 21 | 22 | platform :ios, min_ios_version_supported 23 | prepare_react_native_project! 24 | 25 | # ⬇️ uncomment wanted permissions 26 | setup_permissions([ 27 | # 'AppTrackingTransparency', 28 | # 'Bluetooth', 29 | # 'Calendars', 30 | # 'CalendarsWriteOnly', 31 | # 'Camera', 32 | # 'Contacts', 33 | # 'FaceID', 34 | 'LocationAccuracy', 35 | 'LocationAlways', 36 | 'LocationWhenInUse', 37 | # 'MediaLibrary', 38 | # 'Microphone', 39 | # 'Motion', 40 | # 'Notifications', 41 | # 'PhotoLibrary', 42 | # 'PhotoLibraryAddOnly', 43 | # 'Reminders', 44 | # 'Siri', 45 | # 'SpeechRecognition', 46 | # 'StoreKit', 47 | ]) 48 | 49 | linkage = ENV['USE_FRAMEWORKS'] 50 | if linkage != nil 51 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 52 | use_frameworks! :linkage => linkage.to_sym 53 | end 54 | 55 | target 'NaverMapExample' do 56 | config = use_native_modules! 57 | 58 | use_react_native!( 59 | :path => config[:reactNativePath], 60 | # An absolute path to your application root. 61 | :app_path => "#{Pod::Config.instance.installation_root}/.." 62 | ) 63 | 64 | post_install do |installer| 65 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 66 | react_native_post_install( 67 | installer, 68 | config[:reactNativePath], 69 | :mac_catalyst_enabled => false, 70 | # :ccache_enabled => true 71 | ) 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /example/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); 2 | const path = require('path'); 3 | const escape = require('escape-string-regexp'); 4 | const exclusionList = require('metro-config/src/defaults/exclusionList'); 5 | const pak = require('../package.json'); 6 | 7 | const root = path.resolve(__dirname, '..'); 8 | const modules = Object.keys({ ...pak.peerDependencies }); 9 | 10 | /** 11 | * Metro configuration 12 | * https://facebook.github.io/metro/docs/configuration 13 | * 14 | * @type {import('metro-config').MetroConfig} 15 | */ 16 | const config = { 17 | watchFolders: [root], 18 | 19 | // We need to make sure that only one version is loaded for peerDependencies 20 | // So we block them at the root, and alias them to the versions in example's node_modules 21 | resolver: { 22 | blacklistRE: exclusionList( 23 | modules.map( 24 | (m) => 25 | new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`) 26 | ) 27 | ), 28 | 29 | extraNodeModules: modules.reduce((acc, name) => { 30 | acc[name] = path.join(__dirname, 'node_modules', name); 31 | return acc; 32 | }, {}), 33 | }, 34 | 35 | transformer: { 36 | getTransformOptions: async () => ({ 37 | transform: { 38 | experimentalImportSupport: false, 39 | inlineRequires: true, 40 | }, 41 | }), 42 | }, 43 | }; 44 | 45 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 46 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mj-studio/react-native-naver-map-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start" 9 | }, 10 | "dependencies": { 11 | "@mj-studio/js-util": "1.1.16", 12 | "@react-native-community/slider": "4.5.2", 13 | "react": "18.3.1", 14 | "react-native": "0.75.2", 15 | "react-native-permissions": "4.1.5" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.20.0", 19 | "@babel/preset-env": "^7.20.0", 20 | "@babel/runtime": "^7.20.0", 21 | "@react-native/babel-preset": "0.75.2", 22 | "@react-native/metro-config": "0.75.2", 23 | "@react-native/typescript-config": "0.75.2", 24 | "babel-plugin-module-resolver": "5.0.2" 25 | }, 26 | "engines": { 27 | "node": ">=18" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /example/react-native.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | dependencies: { 6 | [pak.name]: { 7 | root: path.join(__dirname, '..'), 8 | }, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /example/src/component/components.tsx: -------------------------------------------------------------------------------- 1 | import { TouchableOpacity, Text, View, Switch } from 'react-native'; 2 | import Slider from '@react-native-community/slider'; 3 | import React from 'react'; 4 | 5 | export const Btn = ({ 6 | onPress, 7 | title, 8 | }: { 9 | title: string; 10 | onPress: () => void; 11 | }) => { 12 | return ( 13 | 25 | 26 | {title} 27 | 28 | 29 | ); 30 | }; 31 | 32 | export const Toggle = ({ 33 | onChange, 34 | text, 35 | value, 36 | }: { 37 | value: boolean; 38 | onChange: (value: boolean) => void; 39 | text: string; 40 | }) => { 41 | return ( 42 | 43 | 44 | {text} 45 | 46 | 55 | 56 | ); 57 | }; 58 | 59 | export const Range = ({ 60 | onChange, 61 | text, 62 | value, 63 | max, 64 | min, 65 | }: { 66 | value?: number; 67 | onChange?: (value: number) => void; 68 | text: string; 69 | min?: number; 70 | max?: number; 71 | }) => { 72 | return ( 73 | 74 | 75 | {text} 76 | 77 | 87 | 88 | ); 89 | }; 90 | -------------------------------------------------------------------------------- /example/src/logo180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/example/src/logo180.png -------------------------------------------------------------------------------- /expo-config-plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-shadow */ 2 | import { 3 | withInfoPlist, 4 | withAndroidManifest, 5 | AndroidConfig, 6 | type ConfigPlugin, 7 | } from '@expo/config-plugins'; 8 | 9 | const withNaverMap: ConfigPlugin<{ 10 | client_id: string; 11 | android?: { 12 | ACCESS_FINE_LOCATION?: boolean; 13 | ACCESS_COARSE_LOCATION?: boolean; 14 | ACCESS_BACKGROUND_LOCATION?: boolean; 15 | }; 16 | ios?: { 17 | NSLocationAlwaysAndWhenInUseUsageDescription?: string; 18 | NSLocationTemporaryUsageDescriptionDictionary?: { 19 | purposeKey: string; 20 | usageDescription: string; 21 | }; 22 | NSLocationWhenInUseUsageDescription?: string; 23 | }; 24 | }> = (config, { client_id, android = {}, ios = {} }) => { 25 | config = withInfoPlist(config, (config) => { 26 | config.modResults.NMFNcpKeyId = client_id; 27 | config.modResults.NMFClientId = client_id; // For legacy AI Naver API, https://www.ncloud.com/support/notice/all/1930?searchKeyword=map&page=1 28 | if (ios.NSLocationAlwaysAndWhenInUseUsageDescription) { 29 | config.modResults.NSLocationAlwaysAndWhenInUseUsageDescription = 30 | ios.NSLocationAlwaysAndWhenInUseUsageDescription; 31 | } 32 | if (ios.NSLocationWhenInUseUsageDescription) { 33 | config.modResults.NSLocationAlwaysUsageDescription = 34 | ios.NSLocationWhenInUseUsageDescription; 35 | } 36 | if (ios.NSLocationTemporaryUsageDescriptionDictionary) { 37 | const { purposeKey, usageDescription } = 38 | ios.NSLocationTemporaryUsageDescriptionDictionary; 39 | config.modResults.NSLocationTemporaryUsageDescriptionDictionary = { 40 | [purposeKey]: usageDescription, 41 | }; 42 | } 43 | return config; 44 | }); 45 | 46 | config = withAndroidManifest(config, (config) => { 47 | const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow( 48 | config.modResults 49 | ); 50 | 51 | const clientIdMetadataKeys = [ 52 | 'com.naver.maps.map.NCP_KEY_ID', 53 | 'com.naver.maps.map.CLIENT_ID', // For legacy AI Naver API, https://www.ncloud.com/support/notice/all/1930?searchKeyword=map&page=1 54 | ]; 55 | 56 | clientIdMetadataKeys.forEach((metadataKey) => { 57 | AndroidConfig.Manifest.addMetaDataItemToMainApplication( 58 | mainApplication, 59 | metadataKey, 60 | client_id 61 | ); 62 | }); 63 | 64 | return config; 65 | }); 66 | 67 | config = AndroidConfig.Permissions.withPermissions( 68 | config, 69 | [ 70 | android.ACCESS_FINE_LOCATION 71 | ? 'android.permission.ACCESS_FINE_LOCATION' 72 | : '', 73 | android.ACCESS_COARSE_LOCATION 74 | ? 'android.permission.ACCESS_COARSE_LOCATION' 75 | : '', 76 | android.ACCESS_BACKGROUND_LOCATION 77 | ? 'android.permission.ACCESS_BACKGROUND_LOCATION' 78 | : '', 79 | ].filter(Boolean) 80 | ); 81 | 82 | return config; 83 | }; 84 | 85 | export default withNaverMap; 86 | -------------------------------------------------------------------------------- /expo-config-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build", 4 | "rootDir": "src", 5 | "rootDirs": ["."], 6 | "skipLibCheck": true 7 | }, 8 | "include": ["./src"], 9 | "exclude": ["**/__mocks__/*", "**/__tests__/*"] 10 | } 11 | -------------------------------------------------------------------------------- /ios/Module/RNCNaverMapUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapUtil.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 5/10/24. 6 | // 7 | 8 | #import 9 | 10 | #ifdef RCT_NEW_ARCH_ENABLED 11 | #import "RNCNaverMapSpec.h" 12 | 13 | @interface RNCNaverMapUtil : NSObject 14 | #else 15 | #import 16 | 17 | @interface RNCNaverMapUtil : NSObject 18 | #endif 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ios/Module/RNCNaverMapUtil.mm: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapUtil.m 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 5/10/24. 6 | // 7 | 8 | #import "RNCNaverMapUtil.h" 9 | #import 10 | 11 | @implementation RNCNaverMapUtil 12 | 13 | RCT_EXPORT_MODULE() 14 | 15 | #ifdef RCT_NEW_ARCH_ENABLED 16 | - (std::shared_ptr)getTurboModule: 17 | (const facebook::react::ObjCTurboModule::InitParams&)params { 18 | return std::make_shared(params); 19 | } 20 | #endif 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /ios/Overlay/ArrowheadPath/RNCNaverMapArrowheadPath.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapArrowheadPath.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 5/1/24. 6 | // 7 | 8 | #import "ColorUtil.h" 9 | #import "FnUtil.h" 10 | #import "MacroUtil.h" 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | 18 | #import "RCTFabricComponentsPlugins.h" 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | @interface RNCNaverMapArrowheadPath : RCTViewComponentView 25 | 26 | @property(nonatomic, strong) NMFArrowheadPath* inner; 27 | 28 | @property(nonatomic, assign) NSInteger zIndexValue; 29 | @property(nonatomic, assign) NSInteger globalZIndexValue; 30 | @property(nonatomic, assign) BOOL isHidden; 31 | @property(nonatomic, assign) double minZoom; 32 | @property(nonatomic, assign) double maxZoom; 33 | @property(nonatomic, assign) BOOL isMinZoomInclusive; 34 | @property(nonatomic, assign) BOOL isMaxZoomInclusive; 35 | @property(nonatomic, copy) RCTDirectEventBlock onTapOverlay; 36 | 37 | @property(nonatomic, copy) NSArray* coords; 38 | @property(nonatomic, assign) double width; 39 | @property(nonatomic, assign) double outlineWidth; 40 | @property(nonatomic, assign) NSInteger color; 41 | @property(nonatomic, assign) NSInteger outlineColor; 42 | @property(nonatomic, assign) double headSizeRatio; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /ios/Overlay/Circle/RNCNaverMapCircle.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapCircle.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/6/24. 6 | // 7 | 8 | #import "ColorUtil.h" 9 | #import "FnUtil.h" 10 | #import "MacroUtil.h" 11 | #import "Utils.h" 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | 19 | #import "RCTFabricComponentsPlugins.h" 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | @interface RNCNaverMapCircle : RCTViewComponentView 26 | @property(nonatomic, strong) NMFCircleOverlay* inner; 27 | @end 28 | -------------------------------------------------------------------------------- /ios/Overlay/Circle/RNCNaverMapCircle.mm: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapCircle.m 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/6/24. 6 | // 7 | 8 | #import "RNCNaverMapCircle.h" 9 | 10 | #ifdef RCT_NEW_ARCH_ENABLED 11 | using namespace facebook::react; 12 | @interface RNCNaverMapCircle () 13 | 14 | @end 15 | #endif 16 | 17 | @implementation RNCNaverMapCircle { 18 | } 19 | 20 | - (std::shared_ptr)emitter { 21 | if (!_eventEmitter) 22 | return nullptr; 23 | return std::static_pointer_cast(_eventEmitter); 24 | } 25 | 26 | - (instancetype)init { 27 | if ((self = [super init])) { 28 | _inner = [NMFCircleOverlay new]; 29 | 30 | _inner.touchHandler = [self](NMFOverlay* overlay) -> BOOL { 31 | // In New Arch, this always returns YES at now. should be fixed. 32 | if (self.emitter) { 33 | self.emitter->onTapOverlay({}); 34 | return YES; 35 | } 36 | return NO; 37 | }; 38 | } 39 | 40 | return self; 41 | } 42 | 43 | - (instancetype)initWithFrame:(CGRect)frame { 44 | if (self = [super initWithFrame:frame]) { 45 | static const auto defaultProps = std::make_shared(); 46 | _props = defaultProps; 47 | } 48 | 49 | return self; 50 | } 51 | 52 | - (void)updateProps:(Props::Shared const&)props oldProps:(Props::Shared const&)oldProps { 53 | const auto& prev = *std::static_pointer_cast(_props); 54 | const auto& next = *std::static_pointer_cast(props); 55 | 56 | if (!nmap::isCoordEqual(prev.coord, next.coord)) 57 | _inner.center = nmap::createLatLng(next.coord); 58 | 59 | if (prev.zIndexValue != next.zIndexValue) 60 | _inner.zIndex = next.zIndexValue; 61 | if (prev.globalZIndexValue != next.globalZIndexValue && isValidNumber(next.globalZIndexValue)) 62 | _inner.globalZIndex = next.globalZIndexValue; 63 | if (prev.isHidden != next.isHidden) 64 | _inner.hidden = next.isHidden; 65 | if (prev.minZoom != next.minZoom) 66 | _inner.minZoom = next.minZoom; 67 | if (prev.maxZoom != next.maxZoom) 68 | _inner.maxZoom = next.maxZoom; 69 | if (prev.isMinZoomInclusive != next.isMinZoomInclusive) 70 | _inner.isMinZoomInclusive = next.isMinZoomInclusive; 71 | if (prev.isMaxZoomInclusive != next.isMaxZoomInclusive) 72 | _inner.isMaxZoomInclusive = next.isMaxZoomInclusive; 73 | 74 | if (prev.radius != next.radius) 75 | _inner.radius = next.radius; 76 | if (prev.outlineWidth != next.outlineWidth) 77 | _inner.outlineWidth = next.outlineWidth; 78 | if (prev.color != next.color) 79 | _inner.fillColor = nmap::intToColor(next.color); 80 | if (prev.outlineColor != next.outlineColor) 81 | _inner.outlineColor = nmap::intToColor(next.outlineColor); 82 | 83 | [super updateProps:props oldProps:oldProps]; 84 | } 85 | 86 | Class RNCNaverMapCircleCls(void) { 87 | return RNCNaverMapCircle.class; 88 | } 89 | 90 | + (ComponentDescriptorProvider)componentDescriptorProvider { 91 | return concreteComponentDescriptorProvider(); 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /ios/Overlay/Cluster/RNCNaverMapClusterKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapClusterKey.h 3 | // DoubleConversion 4 | // 5 | // Created by mj on 4/18/24. 6 | // 7 | 8 | #import 9 | #import 10 | #import 11 | #import 12 | 13 | typedef void (^OnTapLeafMarker)(); 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface RNCNaverMapClusterKey : NSObject 18 | 19 | @property(nonatomic, strong) NSString* identifier; 20 | @property(nonatomic, strong) NMGLatLng* position; 21 | @property(nonatomic, assign) 22 | facebook::react::RNCNaverMapViewClustersClustersMarkersImageStruct image; 23 | @property(nonatomic, assign) double width; 24 | @property(nonatomic, assign) double height; 25 | @property(nonatomic, nullable) OnTapLeafMarker onTapLeafMarker; 26 | 27 | + (instancetype) 28 | markerKeyWithIdentifier:(nonnull NSString*)identifier 29 | position:(nonnull NMGLatLng*)position 30 | image: 31 | (facebook::react::RNCNaverMapViewClustersClustersMarkersImageStruct)image 32 | width:(double)width 33 | height:(double)height 34 | onTapLeafMarker:(OnTapLeafMarker _Nullable)onTapLeafMarerk; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /ios/Overlay/Cluster/RNCNaverMapClusterKey.mm: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapClusterKey.m 3 | // DoubleConversion 4 | // 5 | // Created by mj on 4/18/24. 6 | // 7 | 8 | #import "RNCNaverMapClusterKey.h" 9 | 10 | @implementation RNCNaverMapClusterKey 11 | 12 | + (instancetype) 13 | markerKeyWithIdentifier:(NSString*)identifier 14 | position:(NMGLatLng*)position 15 | image: 16 | (facebook::react::RNCNaverMapViewClustersClustersMarkersImageStruct)image 17 | width:(double)width 18 | height:(double)height 19 | onTapLeafMarker:(OnTapLeafMarker _Nullable)onTapLeafMarerk { 20 | return [[RNCNaverMapClusterKey alloc] initWithIdentifier:identifier 21 | position:position 22 | image:image 23 | width:width 24 | height:height 25 | onTapLeafMarker:onTapLeafMarerk]; 26 | } 27 | 28 | - (instancetype) 29 | initWithIdentifier:(nonnull NSString*)identifier 30 | position:(nonnull NMGLatLng*)position 31 | image:(facebook::react::RNCNaverMapViewClustersClustersMarkersImageStruct)image 32 | width:(double)width 33 | height:(double)height 34 | onTapLeafMarker:(OnTapLeafMarker)onTapLeafMarker { 35 | if (self = [super init]) { 36 | _identifier = identifier; 37 | _position = position; 38 | _image = image; 39 | _width = width; 40 | _height = height; 41 | _onTapLeafMarker = onTapLeafMarker; 42 | } 43 | 44 | return self; 45 | } 46 | 47 | - (void)dealloc { 48 | _onTapLeafMarker = nil; 49 | } 50 | 51 | - (BOOL)isEqual:(id)object { 52 | if (self == object) { 53 | return YES; 54 | } 55 | 56 | if (object == nil || [self class] != [object class]) { 57 | return NO; 58 | } 59 | 60 | RNCNaverMapClusterKey* key = object; 61 | return [key.identifier isEqualToString:self.identifier]; 62 | } 63 | 64 | - (NSUInteger)hash { 65 | return self.identifier.hash; 66 | } 67 | 68 | - (nonnull id)copyWithZone:(NSZone*)zone { 69 | return [[[self class] alloc] initWithIdentifier:[self.identifier copy] 70 | position:[self.position copy] 71 | image:self.image 72 | width:self.width 73 | height:self.height 74 | onTapLeafMarker:self.onTapLeafMarker]; 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /ios/Overlay/Cluster/RNCNaverMapClusterMarkerUpdater.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapClusterMarkerUpdater.m 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/18/24. 6 | // 7 | #import "RNCNaverMapClusterKey.h" 8 | #import 9 | 10 | @interface RNCNaverMapClusterMarkerUpdater : NMCDefaultClusterMarkerUpdater 11 | 12 | // invalid number means undefined in js 13 | @property(nonatomic, assign) double width; 14 | // invalid number means undefined in js 15 | @property(nonatomic, assign) double height; 16 | 17 | - (instancetype)initWith:(double)width height:(double)height; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ios/Overlay/Cluster/RNCNaverMapClusterMarkerUpdater.mm: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapClusterMarkerUpdater.m 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/18/24. 6 | // 7 | #import "RNCNaverMapClusterMarkerUpdater.h" 8 | #import "MacroUtil.h" 9 | #import "RNCNaverMapClusterKey.h" 10 | 11 | @implementation RNCNaverMapClusterMarkerUpdater 12 | 13 | - (instancetype)initWith:(double)width height:(double)height { 14 | if (self = [super init]) { 15 | _width = width; 16 | _height = height; 17 | } 18 | return self; 19 | } 20 | 21 | #pragma clang diagnostic push 22 | #pragma clang diagnostic ignored "-Wmissing-selector-name" 23 | - (void)updateClusterMarker:(NMCClusterMarkerInfo*)info:(NMFMarker*)marker { 24 | [super updateClusterMarker:info:marker]; 25 | marker.width = isValidNumber(_width) && _width ? _width : NMF_MARKER_SIZE_AUTO; 26 | marker.height = isValidNumber(_height) && _height ? _height : NMF_MARKER_SIZE_AUTO; 27 | } 28 | #pragma clang diagnostic pop 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /ios/Overlay/Cluster/RNCNaverMapLeafMarkerUpdater.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapLeafMarkerUpdater.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/18/24. 6 | // 7 | 8 | #import "FnUtil.h" 9 | #import "ImageUtil.h" 10 | #import "RNCNaverMapClusterKey.h" 11 | #import 12 | #import 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface RNCNaverMapLeafMarkerUpdater : NMCDefaultLeafMarkerUpdater 17 | @property(nonatomic, weak, nullable) NMCClusterer* clusterer; 18 | 19 | - init:(std::unordered_map*)markerImageRequestCanceler; 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /ios/Overlay/Cluster/RNCNaverMapLeafMarkerUpdater.mm: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapLeafMarkerUpdater.m 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/18/24. 6 | // 7 | 8 | #import "RNCNaverMapLeafMarkerUpdater.h" 9 | #import 10 | #import 11 | 12 | @implementation RNCNaverMapLeafMarkerUpdater { 13 | std::unordered_map* _imgRequests; 14 | } 15 | 16 | - (id)init:(std::unordered_map*)markerImageRequestCanceler { 17 | if (self = [super init]) { 18 | _imgRequests = markerImageRequestCanceler; 19 | } 20 | return self; 21 | } 22 | 23 | #pragma clang diagnostic push 24 | #pragma clang diagnostic ignored "-Wmissing-selector-name" 25 | - (void)updateLeafMarker:(NMCLeafMarkerInfo* _Nonnull)info:(NMFMarker* _Nonnull)marker { 26 | [super updateLeafMarker:info:marker]; 27 | 28 | RNCNaverMapClusterKey* key = (RNCNaverMapClusterKey*)info.key; 29 | 30 | NSString* identifier = key.identifier; 31 | facebook::react::RNCNaverMapViewClustersClustersMarkersImageStruct image = key.image; 32 | 33 | __weak NMFMarker* weakMarker = marker; 34 | 35 | if (key.width > 0 && isValidNumber(key.width)) { 36 | marker.width = key.width; 37 | } else { 38 | marker.width = NMF_MARKER_SIZE_AUTO; 39 | } 40 | if (key.height > 0 && isValidNumber(key.height)) { 41 | marker.height = key.height; 42 | } else { 43 | marker.height = NMF_MARKER_SIZE_AUTO; 44 | } 45 | 46 | std::string idStr = [identifier UTF8String]; 47 | 48 | RCTBridge* bridge = [RCTBridge currentBridge]; 49 | if (bridge) { 50 | marker.alpha = 0; 51 | if (_imgRequests->find(idStr) != _imgRequests->end()) { 52 | (*_imgRequests)[idStr](); 53 | _imgRequests->erase(idStr); 54 | } 55 | (*_imgRequests)[idStr] = 56 | nmap::getImage(bridge, image, ^(NMFOverlayImage* _Nullable overlayImage) { 57 | dispatch_async(dispatch_get_main_queue(), ^{ 58 | if (weakMarker) { 59 | weakMarker.alpha = 1; 60 | weakMarker.iconImage = !overlayImage ? NMF_MARKER_IMAGE_GREEN : overlayImage; 61 | } 62 | self->_imgRequests->erase(idStr); 63 | }); 64 | }); 65 | } 66 | 67 | [marker setTouchHandler:^BOOL(NMFOverlay* __weak overlay) { 68 | if (key.onTapLeafMarker) { 69 | key.onTapLeafMarker(); 70 | return YES; 71 | } 72 | return NO; 73 | }]; 74 | } 75 | #pragma clang diagnostic pop 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /ios/Overlay/Ground/RNCNaverMapGround.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapGround.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 5/1/24. 6 | // 7 | 8 | #import "FnUtil.h" 9 | #import "ImageUtil.h" 10 | #import "MacroUtil.h" 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | 18 | #import "RCTFabricComponentsPlugins.h" 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | @interface RNCNaverMapGround : RCTViewComponentView 25 | @property(nonatomic, strong, nullable) NMFGroundOverlay* inner; 26 | @end 27 | -------------------------------------------------------------------------------- /ios/Overlay/Marker/RNCNaverMapMarker.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapMarker.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/6/24. 6 | // 7 | 8 | #import "ColorUtil.h" 9 | #import "FnUtil.h" 10 | #import "ImageUtil.h" 11 | #import "MacroUtil.h" 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | 21 | #import "RCTFabricComponentsPlugins.h" 22 | #import 23 | #import 24 | #import 25 | #import 26 | #import 27 | #import 28 | @interface RNCNaverMapMarker : RCTViewComponentView 29 | @property(nonatomic, strong) NMFMarker* inner; 30 | @property(nonatomic, assign) facebook::react::RNCNaverMapMarkerImageStruct image; 31 | @end 32 | -------------------------------------------------------------------------------- /ios/Overlay/Path/RNCNaverMapPath.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapPath.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/6/24. 6 | // 7 | 8 | #import "ColorUtil.h" 9 | #import "FnUtil.h" 10 | #import "ImageUtil.h" 11 | #import "MacroUtil.h" 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | 21 | #import "RCTFabricComponentsPlugins.h" 22 | #import 23 | #import 24 | #import 25 | #import 26 | #import 27 | @interface RNCNaverMapPath : RCTViewComponentView 28 | @property(nonatomic, strong) NMFPath* inner; 29 | @end 30 | -------------------------------------------------------------------------------- /ios/Overlay/Polygon/RNCNaverMapPolygon.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapPolygon.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/6/24. 6 | // 7 | 8 | #import "ColorUtil.h" 9 | #import "FnUtil.h" 10 | #import "MacroUtil.h" 11 | #import "Utils.h" 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | 19 | #import "RCTFabricComponentsPlugins.h" 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | @interface RNCNaverMapPolygon : RCTViewComponentView 26 | @property(nonatomic, strong) NMFPolygonOverlay* inner; 27 | @end 28 | -------------------------------------------------------------------------------- /ios/Overlay/Polyline/RNCNaverMapPolyline.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapPolyline.h 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/6/24. 6 | // 7 | 8 | #import "ColorUtil.h" 9 | #import "FnUtil.h" 10 | #import "MacroUtil.h" 11 | #import "Utils.h" 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | 19 | #import "RCTFabricComponentsPlugins.h" 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | @interface RNCNaverMapPolyline : RCTViewComponentView 26 | @property(nonatomic, strong) NMFPolylineOverlay* inner; 27 | @end 28 | -------------------------------------------------------------------------------- /ios/RNCNaverMapView.h: -------------------------------------------------------------------------------- 1 | #ifndef NaverMapViewNativeComponent_h 2 | #define NaverMapViewNativeComponent_h 3 | 4 | #import 5 | #import 6 | #import 7 | #import 8 | #import 9 | #import 10 | #import 11 | 12 | #import "EasingAnimationUtil.h" 13 | #import "FnUtil.h" 14 | #import "RCTFabricComponentsPlugins.h" 15 | #import "RNCNaverMapViewImpl.h" 16 | #import "Utils.h" 17 | 18 | @interface RNCNaverMapView : RCTViewComponentView 19 | 20 | - (std::shared_ptr)emitter; 21 | 22 | @end 23 | 24 | #endif /* NaverMapViewNativeComponent_h */ 25 | -------------------------------------------------------------------------------- /ios/RNCNaverMapViewImpl.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNCNaverMapViewImpl.m 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 4/3/24. 6 | // 7 | 8 | #ifndef RNCNaverMapViewImpl_h 9 | #define RNCNaverMapViewImpl_h 10 | 11 | #import "FnUtil.h" 12 | #import "MacroUtil.h" 13 | #import "RNCNaverMapArrowheadPath.h" 14 | #import "RNCNaverMapCircle.h" 15 | #import "RNCNaverMapClusterKey.h" 16 | #import "RNCNaverMapClusterMarkerUpdater.h" 17 | #import "RNCNaverMapGround.h" 18 | #import "RNCNaverMapLeafMarkerUpdater.h" 19 | #import "RNCNaverMapMarker.h" 20 | #import "RNCNaverMapPath.h" 21 | #import "RNCNaverMapPolygon.h" 22 | #import "RNCNaverMapPolyline.h" 23 | #import "Utils.h" 24 | #import 25 | #import 26 | #import 27 | #import 28 | #import 29 | #import 30 | #import 31 | #import 32 | #import 33 | #import 34 | using namespace facebook::react; 35 | 36 | @class RNCNaverMapView; 37 | 38 | @interface RNCNaverMapViewImpl 39 | : NMFNaverMapView 40 | 41 | @property(nonatomic, weak) RNCNaverMapView* rncParent; 42 | @property(nonatomic, copy) NSDictionary* camera; 43 | @property(nonatomic, copy) NSDictionary* initialCamera; 44 | @property(nonatomic, copy) NMGLatLngBounds* region; 45 | @property(nonatomic, copy) NMGLatLngBounds* initialRegion; 46 | @property(nonatomic, assign) NSInteger animationDuration; 47 | @property(nonatomic, assign) NSInteger animationEasing; 48 | 49 | @end 50 | 51 | #endif /* ifndef RNCNaverMapViewImpl_h */ 52 | -------------------------------------------------------------------------------- /ios/Util/ColorUtil.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | namespace nmap { 5 | static inline UIColor* hexToColor(NSString* stringToConvert) { 6 | NSString* noHashString = [stringToConvert stringByReplacingOccurrencesOfString:@"#" 7 | withString:@""]; 8 | NSScanner* stringScanner = [NSScanner scannerWithString:noHashString]; 9 | 10 | unsigned hex; 11 | 12 | if (![stringScanner scanHexInt:&hex]) { 13 | [UIColor blackColor]; 14 | } 15 | 16 | int a = (hex >> 24) & 0xFF; 17 | int r = (hex >> 16) & 0xFF; 18 | int g = (hex >> 8) & 0xFF; 19 | int b = (hex >> 0) & 0xFF; 20 | 21 | return [UIColor colorWithRed:r / 255.0f green:g / 255.0f blue:b / 255.0f alpha:a / 255.0f]; 22 | } 23 | 24 | static inline UIColor* intToColor(NSInteger intToConvert) { 25 | float alpha = ((intToConvert & 0xFF000000) >> 24) / 255.0; 26 | float red = ((intToConvert & 0xFF0000) >> 16) / 255.0; 27 | float green = ((intToConvert & 0x00FF00) >> 8) / 255.0; 28 | float blue = (intToConvert & 0x0000FF) / 255.0; 29 | return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 30 | } 31 | 32 | } // namespace nmap 33 | -------------------------------------------------------------------------------- /ios/Util/EasingAnimationUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // EasingAnimationUtil.m 3 | // mj-studio-react-native-naver-map 4 | // 5 | // Created by mj on 5/12/24. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | static inline NMFCameraUpdateAnimation getEasingAnimation(int easing) { 12 | if (easing == 1) { 13 | return NMFCameraUpdateAnimationNone; 14 | } 15 | 16 | if (easing == 2) { 17 | return NMFCameraUpdateAnimationLinear; 18 | } 19 | 20 | if (easing == 3) { 21 | return NMFCameraUpdateAnimationFly; 22 | } 23 | 24 | if (easing == 4) { 25 | return NMFCameraUpdateAnimationEaseOut; 26 | } 27 | 28 | return NMFCameraUpdateAnimationEaseIn; 29 | } 30 | -------------------------------------------------------------------------------- /ios/Util/MacroUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // MacroUtil.h 3 | // Pods 4 | // 5 | // Created by mj on 4/7/24. 6 | // 7 | #import "FnUtil.h" 8 | #import 9 | 10 | #ifndef MacroUtil_h 11 | #define MacroUtil_h 12 | 13 | #define NMAP_SETTER(upper, lower, rest, view_prop, type) \ 14 | -(void)set##upper##rest : (type)lower##rest { \ 15 | _##lower##rest = lower##rest; \ 16 | self.view_prop = lower##rest; \ 17 | } 18 | #define NMAP_INNER_SETTER(upper, lower, rest, type) \ 19 | NMAP_SETTER(upper, lower, rest, inner.lower##rest, type) 20 | #define NMAP_MAP_SETTER(upper, lower, rest, type) \ 21 | NMAP_SETTER(upper, lower, rest, mapView.lower##rest, type) 22 | 23 | #define NMAP_REMAP_PROP(name) \ 24 | if (prev.name != next.name) { \ 25 | _view.name = next.name; \ 26 | } 27 | 28 | #define NMAP_REMAP_STR_PROP(name) \ 29 | if (prev.name != next.name) { \ 30 | _view.name = [NSString stringWithUTF8String:next.name.c_str()]; \ 31 | } 32 | 33 | #define NMAP_REMAP_SELF_PROP(name) \ 34 | if (prev.name != next.name) { \ 35 | self.name = next.name; \ 36 | } 37 | 38 | #define NMAP_REMAP_SELF_STR_PROP(name) \ 39 | if (prev.name != next.name) { \ 40 | self.name = [NSString stringWithUTF8String:next.name.c_str()]; \ 41 | } 42 | 43 | #define NMAP_REMAP_RECT_PROP(name) \ 44 | if (prev.name.top != next.name.top || prev.name.right != next.name.right || \ 45 | prev.name.bottom != next.name.bottom || prev.name.left != next.name.left) { \ 46 | _view.name = \ 47 | RNCNaverMapRectMake(next.name.top, next.name.right, next.name.bottom, next.name.left); \ 48 | } 49 | 50 | #endif /* MacroUtil_h */ 51 | -------------------------------------------------------------------------------- /lefthook.yml: -------------------------------------------------------------------------------- 1 | pre-commit: 2 | parallel: true 3 | commands: 4 | lint:js: 5 | glob: "*.{js,ts,jsx,tsx}" 6 | run: yarn eslint --cache --max-warnings=0 {staged_files} 7 | lint:objc: 8 | glob: "*.{h,mm,m,hpp,cpp,c}" 9 | run: bash ./script/clang-lint.sh {staged_files} 10 | lint:kotlin: 11 | glob: "*.kt" 12 | run: bash ./script/ktlint-lint.sh {staged_files} 13 | typecheck: 14 | glob: "*.{ts,tsx}" 15 | run: yarn tsc --noEmit 16 | 17 | format: 18 | parallel: true 19 | commands: 20 | format:objc: 21 | glob: "*.{h,mm,m,hpp,cpp,c}" 22 | run: bash ./script/clang-format.sh {all_files} 23 | format:kotlin: 24 | glob: "*.kt" 25 | run: bash ./script/ktlint-format.sh {all_files} 26 | 27 | check: 28 | parallel: true 29 | commands: 30 | lint:js: 31 | glob: "*.{js,ts,jsx,tsx}" 32 | run: yarn eslint --cache --max-warnings=0 {all_files} 33 | lint:objc: 34 | glob: "*.{h,mm,m,hpp,cpp,c}" 35 | run: bash ./script/clang-lint.sh {all_files} 36 | lint:kotlin: 37 | glob: "*.kt" 38 | run: bash ./script/ktlint-lint.sh {all_files} 39 | typecheck: 40 | glob: "*.{ts,tsx}" 41 | run: yarn tsc --noEmit 42 | build: 43 | run: yarn prepack 44 | 45 | 46 | commit-msg: 47 | commands: 48 | commitlint: 49 | run: npx --no-install commitlint --edit 50 | -------------------------------------------------------------------------------- /mj-studio-react-native-naver-map.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' 5 | 6 | Pod::Spec.new do |s| 7 | s.name = "mj-studio-react-native-naver-map" 8 | s.version = package["version"] 9 | s.summary = package["description"] 10 | s.homepage = package["homepage"] 11 | s.license = package["license"] 12 | s.authors = package["author"] 13 | 14 | s.platforms = { :ios => min_ios_version_supported } 15 | s.source = { :git => "https://github.com/mym0404/react-native-naver-map.git", :tag => "#{s.version}" } 16 | 17 | s.source_files = "ios/**/*.{h,m,mm}" 18 | 19 | # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. 20 | # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. 21 | if respond_to?(:install_modules_dependencies, true) 22 | install_modules_dependencies(s) 23 | else 24 | s.dependency "React-Core" 25 | 26 | # Don't install the dependencies when we run `pod install` in the old architecture. 27 | if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then 28 | s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" 29 | s.pod_target_xcconfig = { 30 | "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", 31 | "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", 32 | "CLANG_CXX_LANGUAGE_STANDARD" => "c++20" 33 | } 34 | s.dependency "React-RCTFabric" 35 | s.dependency "React-Codegen" 36 | s.dependency "RCT-Folly" 37 | s.dependency "RCTRequired" 38 | s.dependency "RCTTypeSafety" 39 | s.dependency "ReactCommon/turbomodule/core" 40 | end 41 | end 42 | 43 | s.dependency "NMapsMap", "3.21.0" 44 | end 45 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mym0404/react-native-naver-map/f62e41f574dc5b3bc5caf05dca913c3bbb3604fa/public/favicon.png -------------------------------------------------------------------------------- /script/clang-format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | for file in "$@"; do 4 | # echo "🦋 clang-format ${file}" 5 | clang-format -i "${file}" 6 | done 7 | -------------------------------------------------------------------------------- /script/clang-lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | for file in "$@"; do 4 | # echo "🦋 clang-lint ${file}" 5 | clang-format --dry-run -Werror "${file}" 6 | if [[ $? = 1 ]]; then 7 | echo "❌ clang lint failed on '$file'" 8 | exit 1 9 | fi 10 | done 11 | -------------------------------------------------------------------------------- /script/ktlint-format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | #echo "🌊 ktlint android $file" 4 | ktlint --color --format --relative --editorconfig=example/android/.editorconfig "$@" 5 | -------------------------------------------------------------------------------- /script/ktlint-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | #echo "🌊 ktlint android $file" 5 | ktlint --color --relative --editorconfig=example/android/.editorconfig "$@" 6 | -------------------------------------------------------------------------------- /script/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | yarn t 4 | #yarn codegen 5 | yarn prepack 6 | export $(grep -v '^#' .env | xargs) && release-it $1 $2 7 | -------------------------------------------------------------------------------- /src/__tests__/index.test.tsx: -------------------------------------------------------------------------------- 1 | it.todo('write a test'); 2 | -------------------------------------------------------------------------------- /src/component/NaverMapArrowheadPathOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { default as NativeNaverMapArrowheadPath } from '../spec/RNCNaverMapArrowheadPathNativeComponent'; 2 | import type { BaseOverlayProps } from '../types/BaseOverlayProps'; 3 | import { type ColorValue, processColor } from 'react-native'; 4 | import { Const } from '../internal/util/Const'; 5 | import type { Coord } from '@mj-studio/react-native-naver-map'; 6 | import { nAssert } from '../internal/util/Assert'; 7 | import React from 'react'; 8 | 9 | export interface NaverMapArrowheadPathOverlayProps extends BaseOverlayProps { 10 | /** 11 | * 좌표열을 지정할 수 있습니다. 12 | * 좌표열은 필수적인 속성으로, 좌표열을 지정하지 않은 경로선 오버레이는 지도에 추가되지 않습니다. 13 | * 또한 좌표열의 크기가 2 미만이거나 null인 원소가 있을 경우에도 지도에 추가되지 않습니다. 14 | */ 15 | coords: Coord[]; 16 | /** 17 | * 두께를 지정할 수 있습니다. 18 | * 19 | * dp, pt단위입니다. 20 | * 21 | * @default 1 22 | */ 23 | width?: number; 24 | /** 25 | * 테두리의 두께를 지정할 수 있습니다. 0으로 지정하면 테두리가 그려지지 않습니다. 26 | * 27 | * @default 0 28 | */ 29 | outlineWidth?: number; 30 | /** 31 | * color와 passedColor 속성을 사용해 각각 지나갈, 지나온 경로선의 색상을 지정할 수 있습니다. 32 | * 33 | * @default black 34 | */ 35 | color?: ColorValue; 36 | /** 37 | * 외곽선 색상입니다. 38 | * 39 | * @default black 40 | */ 41 | outlineColor?: ColorValue; 42 | /** 43 | * 머리 크기의 배율을 지정할 수 있습니다. 두께에 배율을 곱한 값이 머리의 크기가 됩니다. 44 | * 45 | * @default 2.5 46 | */ 47 | headSizeRatio?: number; 48 | } 49 | 50 | export const NaverMapArrowheadPathOverlay = ({ 51 | zIndex = 0, 52 | globalZIndex = Const.NULL_NUMBER, 53 | isHidden = false, 54 | minZoom = Const.MIN_ZOOM, 55 | maxZoom = Const.MAX_ZOOM, 56 | isMinZoomInclusive = true, 57 | isMaxZoomInclusive = true, 58 | 59 | coords = [], 60 | width = 1, 61 | color = 'black', 62 | outlineColor = 'black', 63 | outlineWidth = 0, 64 | headSizeRatio = 2.5, 65 | onTap, 66 | }: NaverMapArrowheadPathOverlayProps) => { 67 | if (coords) { 68 | nAssert( 69 | coords.length >= 2, 70 | `[NaverMapArrowheadPathOverlay] coords length should be equal or greater than 2, is ${coords.length}.` 71 | ); 72 | if (coords.length < 2) return null; 73 | } 74 | return ( 75 | 91 | ); 92 | }; 93 | -------------------------------------------------------------------------------- /src/component/NaverMapCircleOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { default as NativeNaverMapCircle } from '../spec/RNCNaverMapCircleNativeComponent'; 2 | import type { BaseOverlayProps } from '../types/BaseOverlayProps'; 3 | import { type ColorValue, processColor } from 'react-native'; 4 | import { Const } from '../internal/util/Const'; 5 | import type { Coord } from '../types/Coord'; 6 | import React from 'react'; 7 | 8 | export interface NaverMapCircleOverlayProps extends BaseOverlayProps, Coord { 9 | /** 지도에 원의 반지름을 미터 단위로 표시합니다. */ 10 | radius?: number; 11 | /** 12 | * 원의 색상입니다. 13 | * 14 | * @default black 15 | */ 16 | color?: ColorValue; 17 | /** 18 | * 외곽선의 굵기입니다. dp(android), pt(ios) 19 | * 20 | * @default 0 21 | */ 22 | outlineWidth?: number; 23 | /** 24 | * 외곽선의 색상입니다. 25 | * 26 | * @default black 27 | */ 28 | outlineColor?: ColorValue; 29 | } 30 | 31 | export const NaverMapCircleOverlay = ({ 32 | latitude, 33 | longitude, 34 | zIndex = 0, 35 | globalZIndex = Const.NULL_NUMBER, 36 | isHidden = false, 37 | minZoom = Const.MIN_ZOOM, 38 | maxZoom = Const.MAX_ZOOM, 39 | isMinZoomInclusive = true, 40 | isMaxZoomInclusive = true, 41 | 42 | radius = 0, 43 | color = 'black', 44 | outlineWidth = 0, 45 | outlineColor = 'black', 46 | onTap, 47 | }: NaverMapCircleOverlayProps) => { 48 | return ( 49 | 67 | ); 68 | }; 69 | -------------------------------------------------------------------------------- /src/component/NaverMapGroundOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { default as NativeNaverMapGround } from '../spec/RNCNaverMapGroundNativeComponent'; 2 | import type { BaseOverlayProps } from '../types/BaseOverlayProps'; 3 | import { Const } from '../internal/util/Const'; 4 | import type { 5 | MarkerImageProp, 6 | Region, 7 | } from '@mj-studio/react-native-naver-map'; 8 | import { convertJsImagePropToNativeProp } from '../internal/Util'; 9 | import React from 'react'; 10 | 11 | export interface NaverMapGroundOverlayProps extends BaseOverlayProps { 12 | /** 13 | * 지상 오버레이의 이미지를 지정할 수 있습니다. 14 | * 15 | * 이미지는 필수적인 속성으로, 이미지를 지정하지 않은 지상 오버레이는 지도에 추가되지 않습니다. 16 | */ 17 | image: MarkerImageProp; 18 | /** 19 | * 지상 오버레이의 영역을 지정할 수 있습니다. 20 | * 21 | * 영역은 필수적인 속성으로, 영역을 지정하지 않은 지상 오버레이는 지도에 추가되지 않습니다. 22 | */ 23 | region: Region; 24 | } 25 | 26 | export const NaverMapGroundOverlay = ({ 27 | zIndex = 0, 28 | globalZIndex = Const.NULL_NUMBER, 29 | isHidden = false, 30 | minZoom = Const.MIN_ZOOM, 31 | maxZoom = Const.MAX_ZOOM, 32 | isMinZoomInclusive = true, 33 | isMaxZoomInclusive = true, 34 | image, 35 | region, 36 | onTap, 37 | }: NaverMapGroundOverlayProps) => { 38 | return ( 39 | 51 | ); 52 | }; 53 | -------------------------------------------------------------------------------- /src/component/NaverMapPolygonOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { default as NativeNaverMapPolygon } from '../spec/RNCNaverMapPolygonNativeComponent'; 2 | import type { BaseOverlayProps } from '../types/BaseOverlayProps'; 3 | import { type ColorValue, processColor } from 'react-native'; 4 | import { Const } from '../internal/util/Const'; 5 | import type { Coord } from '@mj-studio/react-native-naver-map'; 6 | import { nAssert } from '../internal/util/Assert'; 7 | import React from 'react'; 8 | 9 | export interface NaverMapPolygonOverlayProps extends BaseOverlayProps { 10 | /** 11 | * 폴리곤 오버레이는 좌표열 혹은 좌표열 정보가 입력된 객체를 사용하여 생성할 수 있습니다. 12 | * 이때, 좌표열의 첫 좌표와 끝 좌표가 정확히 같아야 합니다. 13 | * 14 | * coords는 필수적인 속성으로, 시계 방향으로 감겨 있어야 하며, 그렇지 않을 경우 비정상적으로 그려지거나 이벤트를 받지 못할 수 있습니다. 15 | * 폴리곤을 지정하지 않은 폴리곤 오버레이는 지도에 추가되지 않습니다. 16 | * 또한 폴리곤의 coords의 크기가 3 미만이거나 nil인 원소가 있을 경우에도 지도에 추가되지 않습니다. 17 | */ 18 | coords: Coord[]; 19 | /** 20 | * polygon의 holes 속성이 있을 경우 폴리곤 오버레이에 홀을 만들 수 있습니다. 21 | * 폴리곤에는 여러 개의 내부 홀을 지정할 수 있으며, 홀에 해당하는 부분은 색상이 칠해지지 않고 이벤트도 받지 못합니다. 22 | * 각 홀의 좌표열은 시계 반대 방향으로 감겨 있어야 하며, 그렇지 않을 경우 비정상적으로 그려지거나 이벤트를 받지 못할 수 있습니다. 23 | * 또한 각 홀의 좌표열의 크기가 3 미만이거나 nil인 원소가 있을 경우 지도에 추가되지 않습니다. 24 | */ 25 | holes?: Coord[][]; 26 | /** 27 | * color속성을 사용해 선의 색상을 지정할 수 있습니다. 28 | * 29 | * @default black 30 | */ 31 | color?: ColorValue; 32 | /** 33 | * 테두리의 두께를 지정할 수 있습니다. 0으로 지정하면 테두리가 그려지지 않습니다. 34 | * 35 | * @default 0 36 | */ 37 | outlineWidth?: number; 38 | /** 39 | * 외곽선 색상입니다. 40 | * 41 | * @default black 42 | */ 43 | outlineColor?: ColorValue; 44 | } 45 | 46 | export const NaverMapPolygonOverlay = ({ 47 | zIndex = 0, 48 | globalZIndex = Const.NULL_NUMBER, 49 | isHidden = false, 50 | minZoom = Const.MIN_ZOOM, 51 | maxZoom = Const.MAX_ZOOM, 52 | isMinZoomInclusive = true, 53 | isMaxZoomInclusive = true, 54 | 55 | coords = [], 56 | holes = [], 57 | color = 'black', 58 | outlineWidth = 0, 59 | outlineColor = 'black', 60 | onTap, 61 | }: NaverMapPolygonOverlayProps) => { 62 | if (coords) { 63 | nAssert( 64 | coords.length >= 3, 65 | `[NaverMapPolygonOverlay] coords length should be equal or greater than 3, is ${coords.length}.` 66 | ); 67 | } 68 | if (holes) { 69 | for (const hole of holes) { 70 | nAssert( 71 | hole.length >= 3, 72 | `[NaverMapPolygonOverlay] hole length should be equal or greater than 3, is ${hole.length}.` 73 | ); 74 | } 75 | } 76 | return ( 77 | 94 | ); 95 | }; 96 | -------------------------------------------------------------------------------- /src/component/NaverMapPolylineOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { default as NativeNaverMapPolyline } from '../spec/RNCNaverMapPolylineNativeComponent'; 2 | import type { BaseOverlayProps } from '../types/BaseOverlayProps'; 3 | import { type ColorValue, processColor } from 'react-native'; 4 | import { Const } from '../internal/util/Const'; 5 | import type { 6 | Coord, 7 | CapType, 8 | JoinType, 9 | } from '@mj-studio/react-native-naver-map'; 10 | import { nAssert } from '../internal/util/Assert'; 11 | import React from 'react'; 12 | 13 | export interface NaverMapPolylineOverlayProps extends BaseOverlayProps { 14 | coords: Coord[]; 15 | /** 16 | * 두께를 지정할 수 있습니다. 17 | * 18 | * dp, pt단위입니다. 19 | * 20 | * @default 1 21 | */ 22 | width?: number; 23 | /** 24 | * color속성을 사용해 선의 색상을 지정할 수 있습니다. 25 | * 26 | * @default black 27 | */ 28 | color?: ColorValue; 29 | pattern?: number[]; 30 | /** 31 | * capType 속성을 사용해 끝 지점의 모양을 지정할 수 있습니다. 32 | * 33 | * 다음 그림은 위에서부터 차례대로 Round, Butt, Square 모양을 나타냅니다. 34 | * 35 | * @description 36 | * 37 | * preview 38 | * 39 | * @see {@link CapType} 40 | * @default Round 41 | */ 42 | capType?: CapType; 43 | /** 44 | * joinType 속성을 사용해 연결점의 모양을 지정할 수 있습니다. 45 | * 46 | * 다음 그림은 위에서부터 차례대로 Round, Butt, Square 모양을 나타냅니다. 47 | * 48 | * @description 49 | * 50 | * preview 51 | * preview 52 | * preview 53 | * 54 | * @see {@link JoinType} 55 | * @default Round 56 | */ 57 | joinType?: JoinType; 58 | } 59 | 60 | export const NaverMapPolylineOverlay = ({ 61 | zIndex = 0, 62 | globalZIndex = Const.NULL_NUMBER, 63 | isHidden = false, 64 | minZoom = Const.MIN_ZOOM, 65 | maxZoom = Const.MAX_ZOOM, 66 | isMinZoomInclusive = true, 67 | isMaxZoomInclusive = true, 68 | 69 | coords = [], 70 | width = 1, 71 | capType = 'Round', 72 | joinType = 'Round', 73 | color = 'black', 74 | onTap, 75 | }: NaverMapPolylineOverlayProps) => { 76 | if (coords) { 77 | nAssert( 78 | coords.length >= 2, 79 | `[NaverMapPolylineOverlay] coords length should be equal or greater than 2, is ${coords.length}.` 80 | ); 81 | } 82 | return ( 83 | 98 | ); 99 | }; 100 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import { NaverMapUtil } from './util/NaverMapUtil'; 2 | 3 | export { 4 | NaverMapView, 5 | type NaverMapViewProps, 6 | type NaverMapViewRef, 7 | } from './component/NaverMapView'; 8 | export { 9 | NaverMapMarkerOverlay, 10 | type NaverMapMarkerOverlayProps, 11 | type CaptionType, 12 | type SubCaptionType, 13 | } from './component/NaverMapMarkerOverlay'; 14 | export { 15 | NaverMapCircleOverlay, 16 | type NaverMapCircleOverlayProps, 17 | } from './component/NaverMapCircleOverlay'; 18 | export { 19 | NaverMapPolygonOverlay, 20 | type NaverMapPolygonOverlayProps, 21 | } from './component/NaverMapPolygonOverlay'; 22 | export { 23 | NaverMapPolylineOverlay, 24 | type NaverMapPolylineOverlayProps, 25 | } from './component/NaverMapPolylineOverlay'; 26 | export { 27 | NaverMapPathOverlay, 28 | type NaverMapPathOverlayProps, 29 | } from './component/NaverMapPathOverlay'; 30 | export { 31 | NaverMapArrowheadPathOverlay, 32 | type NaverMapArrowheadPathOverlayProps, 33 | } from './component/NaverMapArrowheadPathOverlay'; 34 | export { 35 | NaverMapGroundOverlay, 36 | type NaverMapGroundOverlayProps, 37 | } from './component/NaverMapGroundOverlay'; 38 | 39 | export * from './spec/RNCNaverMapViewNativeComponent'; 40 | export * from './types/BaseOverlayProps'; 41 | export * from './types/Coord'; 42 | export * from './types/Rect'; 43 | export * from './types/Region'; 44 | export * from './types/MapType'; 45 | export * from './types/Align'; 46 | export * from './types/LogoAlign'; 47 | export * from './types/Camera'; 48 | export * from './types/CameraAnimationEasing'; 49 | export * from './types/CameraChangeReason'; 50 | export * from './types/MarkerSymbol'; 51 | export * from './types/MarkerImageProp'; 52 | export * from './types/CapType'; 53 | export * from './types/JoinType'; 54 | export * from './types/LocationTrackingMode'; 55 | export * from './types/CameraMoveBaseParams'; 56 | export * from './types/Point'; 57 | export * from './types/ClusterMarkerProp'; 58 | 59 | export { NaverMapUtil }; 60 | -------------------------------------------------------------------------------- /src/internal/Util.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | CameraAnimationEasing, 3 | CameraChangeReason, 4 | Align, 5 | Camera, 6 | MarkerImageProp, 7 | } from '@mj-studio/react-native-naver-map'; 8 | import { Const } from './util/Const'; 9 | import { Image } from 'react-native'; 10 | 11 | export function cameraEasingToNumber( 12 | value: CameraAnimationEasing = 'EaseIn' 13 | ): number { 14 | switch (value) { 15 | case 'None': 16 | return 1; 17 | case 'Linear': 18 | return 2; 19 | case 'Fly': 20 | return 3; 21 | case 'EaseOut': 22 | return 4; 23 | default: 24 | case 'EaseIn': 25 | return 0; 26 | } 27 | } 28 | 29 | export function cameraChangeReasonFromNumber( 30 | value: number 31 | ): CameraChangeReason { 32 | switch (value) { 33 | case 0: 34 | return 'Developer'; 35 | case 1: 36 | return 'Gesture'; 37 | case 2: 38 | return 'Control'; 39 | case 3: 40 | return 'Location'; 41 | default: 42 | return 'Developer'; 43 | } 44 | } 45 | 46 | export function getAlignIntValue(value?: Align) { 47 | switch (value) { 48 | case 'Center': 49 | return 0; 50 | case 'Left': 51 | return 1; 52 | case 'Right': 53 | return 2; 54 | case 'Top': 55 | return 3; 56 | case 'TopLeft': 57 | return 5; 58 | case 'TopRight': 59 | return 6; 60 | case 'BottomRight': 61 | return 7; 62 | case 'BottomLeft': 63 | return 8; 64 | default: 65 | case 'Bottom': 66 | return 4; 67 | } 68 | } 69 | 70 | export function createCameraInstance({ 71 | bearing, 72 | latitude, 73 | longitude, 74 | tilt, 75 | zoom, 76 | }: Camera): Camera { 77 | return { 78 | latitude, 79 | longitude, 80 | zoom: zoom ?? Const.DEFAULT_ZOOM, 81 | tilt: tilt ?? Const.DEFAULT_TILT, 82 | bearing: bearing ?? Const.DEFAULT_BEARING, 83 | }; 84 | } 85 | 86 | export const convertJsImagePropToNativeProp = (image: MarkerImageProp) => { 87 | if (typeof image === 'number') { 88 | const rnAssetUri = Image.resolveAssetSource(image)?.uri; 89 | if (rnAssetUri) { 90 | return { rnAssetUri }; 91 | } else { 92 | return; 93 | } 94 | } 95 | const { assetName, httpUri, reuseIdentifier, symbol } = image as Exclude< 96 | MarkerImageProp, 97 | number 98 | >; 99 | if (assetName) { 100 | return { assetName, reuseIdentifier }; 101 | } 102 | if (httpUri) { 103 | return { httpUri, reuseIdentifier }; 104 | } 105 | if (symbol) { 106 | return { symbol, reuseIdentifier }; 107 | } 108 | return; 109 | }; 110 | -------------------------------------------------------------------------------- /src/internal/util/Assert.ts: -------------------------------------------------------------------------------- 1 | class NaverMapJSError extends Error { 2 | constructor(message: string) { 3 | super(message); 4 | 5 | this.name = 'NaverMapJSError'; 6 | } 7 | } 8 | export function nAssert( 9 | condition: boolean | null | undefined, 10 | message: string 11 | ) { 12 | if (!condition) { 13 | throw new NaverMapJSError(message); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/internal/util/Const.ts: -------------------------------------------------------------------------------- 1 | import type { CameraAnimationEasing } from '../../types/CameraAnimationEasing'; 2 | 3 | export const Const = { 4 | /** 5 | * ios: codegen generate struct number fields with default value zero. 6 | * in some cases, we should check it is invalid value instead of checking is zero. 7 | */ 8 | NULL_NUMBER: -123123123, 9 | DEFAULT_ANIM_DURATION: 700, 10 | DEFAULT_EASING: 'EaseOut', 11 | DEFAULT_ZOOM: 10, 12 | DEFAULT_TILT: 0, 13 | DEFAULT_BEARING: 0, 14 | MIN_ZOOM: 0, 15 | MAX_ZOOM: 21, 16 | DEFAULT_SCREEN_DISTANCE: 70, 17 | } satisfies (Record & {}) & { 18 | DEFAULT_EASING: CameraAnimationEasing; 19 | }; 20 | -------------------------------------------------------------------------------- /src/internal/util/useStableCallback.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns a stabilized callback reference which delegates to the most recent unstable callback 3 | * 4 | * This is similar to useCallback, but allows unstableCallback to access the most recent values from the closure. 5 | * This can be useful if the callback is being stored long term, such as in the Transition Hook registry. 6 | * 7 | * Example: 8 | * ```jsx 9 | * const latestValueFromProps = props.value 10 | * const transitionHook = useStableCallback(() => console.log(latestValueFromProps)); 11 | * useEffect(() => { 12 | * const deregister = transitionService.onBefore({ exiting: 'someState' }, transitionHook); 13 | * return () => deregister(); 14 | * }, []); 15 | * ``` 16 | */ 17 | import { useCallback, useRef } from 'react'; 18 | 19 | export function useStableCallback(unstableCallback: T): T { 20 | const ref = useRef(unstableCallback); 21 | ref.current = unstableCallback; 22 | const callback = useCallback(function () { 23 | // @ts-ignore 24 | return ref.current && ref.current.apply(this, arguments); 25 | }, []); 26 | return callback as unknown as T; 27 | } 28 | -------------------------------------------------------------------------------- /src/spec/NativeRNCNaverMapUtil.ts: -------------------------------------------------------------------------------- 1 | import { TurboModuleRegistry, type TurboModule } from 'react-native'; 2 | import type { Double } from 'react-native/Libraries/Types/CodegenTypes'; 3 | 4 | export interface Spec extends TurboModule { 5 | setGlobalZIndex(type: string, zIndex: Double): void; 6 | } 7 | 8 | export default TurboModuleRegistry.getEnforcing('RNCNaverMapUtil'); 9 | -------------------------------------------------------------------------------- /src/spec/RNCNaverMapArrowheadPathNativeComponent.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Double, 3 | Int32, 4 | DirectEventHandler, 5 | } from 'react-native/Libraries/Types/CodegenTypes'; 6 | import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; 7 | import type { ViewProps } from 'react-native'; 8 | 9 | /* Type should be redeclared because of codegen ts parser doesn't allow imported type 10 | * [comments](https://github.com/reactwg/react-native-new-architecture/discussions/91#discussioncomment-4282452) 11 | */ 12 | 13 | interface BaseOverlay { 14 | zIndexValue: Int32; 15 | globalZIndexValue: Int32; 16 | isHidden: boolean; 17 | minZoom: Double; 18 | maxZoom: Double; 19 | isMinZoomInclusive: boolean; 20 | isMaxZoomInclusive: boolean; 21 | } 22 | 23 | type Coord = { 24 | latitude: Double; 25 | longitude: Double; 26 | }; 27 | //////////////////// 28 | 29 | interface Props extends BaseOverlay, ViewProps { 30 | onTapOverlay?: DirectEventHandler>; 31 | coords: ReadonlyArray; 32 | width?: Double; 33 | 34 | outlineWidth?: Double; 35 | color?: Int32; 36 | outlineColor?: Int32; 37 | headSizeRatio?: Double; 38 | } 39 | 40 | export default codegenNativeComponent('RNCNaverMapArrowheadPath'); 41 | -------------------------------------------------------------------------------- /src/spec/RNCNaverMapCircleNativeComponent.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Double, 3 | Int32, 4 | DirectEventHandler, 5 | } from 'react-native/Libraries/Types/CodegenTypes'; 6 | import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; 7 | import type { ViewProps } from 'react-native'; 8 | 9 | /* Type should be redeclared because of codegen ts parser doesn't allow imported type 10 | * [comments](https://github.com/reactwg/react-native-new-architecture/discussions/91#discussioncomment-4282452) 11 | */ 12 | 13 | interface BaseOverlay { 14 | zIndexValue: Int32; 15 | globalZIndexValue: Int32; 16 | isHidden: boolean; 17 | minZoom: Double; 18 | maxZoom: Double; 19 | isMinZoomInclusive: boolean; 20 | isMaxZoomInclusive: boolean; 21 | } 22 | 23 | //////////////////// 24 | 25 | interface Props extends BaseOverlay, ViewProps { 26 | coord: Readonly<{ latitude: Double; longitude: Double }>; 27 | onTapOverlay?: DirectEventHandler>; 28 | radius?: Double; 29 | color?: Int32; 30 | outlineColor?: Int32; 31 | outlineWidth?: Double; 32 | } 33 | 34 | export default codegenNativeComponent('RNCNaverMapCircle'); 35 | -------------------------------------------------------------------------------- /src/spec/RNCNaverMapGroundNativeComponent.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Double, 3 | Int32, 4 | DirectEventHandler, 5 | } from 'react-native/Libraries/Types/CodegenTypes'; 6 | import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; 7 | import type { ViewProps } from 'react-native'; 8 | 9 | /* Type should be redeclared because of codegen ts parser doesn't allow imported type 10 | * [comments](https://github.com/reactwg/react-native-new-architecture/discussions/91#discussioncomment-4282452) 11 | */ 12 | 13 | interface BaseOverlay { 14 | zIndexValue: Int32; 15 | globalZIndexValue: Int32; 16 | isHidden: boolean; 17 | minZoom: Double; 18 | maxZoom: Double; 19 | isMinZoomInclusive: boolean; 20 | isMaxZoomInclusive: boolean; 21 | } 22 | 23 | export type NativeImageProp = 24 | | undefined 25 | | Readonly<{ 26 | symbol?: string; 27 | rnAssetUri?: string; 28 | httpUri?: string; 29 | assetName?: string; 30 | reuseIdentifier?: string; 31 | }>; 32 | type Region = { 33 | latitude: Double; 34 | longitude: Double; 35 | latitudeDelta: Double; 36 | longitudeDelta: Double; 37 | }; 38 | 39 | //////////////////// 40 | 41 | interface Props extends BaseOverlay, ViewProps { 42 | onTapOverlay?: DirectEventHandler>; 43 | image: NativeImageProp; 44 | region: Region; 45 | } 46 | 47 | export default codegenNativeComponent('RNCNaverMapGround'); 48 | -------------------------------------------------------------------------------- /src/spec/RNCNaverMapMarkerNativeComponent.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Double, 3 | Int32, 4 | DirectEventHandler, 5 | } from 'react-native/Libraries/Types/CodegenTypes'; 6 | import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; 7 | import type { ViewProps } from 'react-native'; 8 | 9 | /* Type should be redeclared because of codegen ts parser doesn't allow imported type 10 | * [comments](https://github.com/reactwg/react-native-new-architecture/discussions/91#discussioncomment-4282452) 11 | */ 12 | 13 | interface BaseOverlay { 14 | zIndexValue: Int32; 15 | globalZIndexValue: Int32; 16 | isHidden: boolean; 17 | minZoom: Double; 18 | maxZoom: Double; 19 | isMinZoomInclusive: boolean; 20 | isMaxZoomInclusive: boolean; 21 | } 22 | 23 | export type NativeCaptionProp = { 24 | key: string; 25 | text: string; 26 | requestedWidth?: Double; 27 | align?: Int32; 28 | offset?: Double; 29 | color?: Int32; 30 | haloColor?: Int32; 31 | textSize?: Double; 32 | minZoom?: Double; 33 | maxZoom?: Double; 34 | }; 35 | 36 | export type NativeSubCaptionProp = { 37 | key: string; 38 | text: string; 39 | color?: Int32; 40 | haloColor?: Int32; 41 | textSize?: Double; 42 | requestedWidth?: Double; 43 | minZoom?: Double; 44 | maxZoom?: Double; 45 | }; 46 | 47 | export type NativeImageProp = Readonly<{ 48 | symbol?: string; 49 | rnAssetUri?: string; 50 | httpUri?: string; 51 | assetName?: string; 52 | reuseIdentifier?: string; 53 | }>; 54 | 55 | //////////////////// 56 | 57 | interface Props extends BaseOverlay, ViewProps { 58 | coord: Readonly<{ latitude: Double; longitude: Double }>; 59 | onTapOverlay?: DirectEventHandler>; 60 | width?: Double; 61 | height?: Double; 62 | anchor?: Readonly<{ x: Double; y: Double }>; 63 | angle?: Double; 64 | isFlatEnabled?: boolean; 65 | isIconPerspectiveEnabled?: boolean; 66 | alpha?: Double; 67 | isHideCollidedSymbols?: boolean; 68 | isHideCollidedMarkers?: boolean; 69 | isHideCollidedCaptions?: boolean; 70 | isForceShowIcon?: boolean; 71 | tintColor?: Int32; 72 | image?: Readonly; 73 | caption?: Readonly; 74 | subCaption?: Readonly; 75 | } 76 | 77 | export default codegenNativeComponent('RNCNaverMapMarker'); 78 | -------------------------------------------------------------------------------- /src/spec/RNCNaverMapPathNativeComponent.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Double, 3 | Int32, 4 | DirectEventHandler, 5 | } from 'react-native/Libraries/Types/CodegenTypes'; 6 | import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; 7 | import type { ViewProps } from 'react-native'; 8 | 9 | /* Type should be redeclared because of codegen ts parser doesn't allow imported type 10 | * [comments](https://github.com/reactwg/react-native-new-architecture/discussions/91#discussioncomment-4282452) 11 | */ 12 | 13 | interface BaseOverlay { 14 | zIndexValue: Int32; 15 | globalZIndexValue: Int32; 16 | isHidden: boolean; 17 | minZoom: Double; 18 | maxZoom: Double; 19 | isMinZoomInclusive: boolean; 20 | isMaxZoomInclusive: boolean; 21 | } 22 | 23 | type Coord = { 24 | latitude: Double; 25 | longitude: Double; 26 | }; 27 | type NativeImageProp = 28 | | undefined 29 | | Readonly<{ 30 | symbol?: string; 31 | rnAssetUri?: string; 32 | httpUri?: string; 33 | assetName?: string; 34 | reuseIdentifier?: string; 35 | }>; 36 | 37 | //////////////////// 38 | 39 | interface Props extends BaseOverlay, ViewProps { 40 | onTapOverlay?: DirectEventHandler>; 41 | coords: ReadonlyArray; 42 | width?: Double; 43 | outlineWidth?: Double; 44 | patternInterval?: Int32; 45 | patternImage?: NativeImageProp; 46 | progress?: Double; 47 | color?: Int32; 48 | passedColor?: Int32; 49 | outlineColor?: Int32; 50 | passedOutlineColor?: Int32; 51 | isHideCollidedSymbols?: boolean; 52 | isHideCollidedMarkers?: boolean; 53 | isHideCollidedCaptions?: boolean; 54 | } 55 | 56 | export default codegenNativeComponent('RNCNaverMapPath'); 57 | -------------------------------------------------------------------------------- /src/spec/RNCNaverMapPolygonNativeComponent.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Double, 3 | Int32, 4 | DirectEventHandler, 5 | } from 'react-native/Libraries/Types/CodegenTypes'; 6 | import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; 7 | import type { ViewProps } from 'react-native'; 8 | 9 | /* Type should be redeclared because of codegen ts parser doesn't allow imported type 10 | * [comments](https://github.com/reactwg/react-native-new-architecture/discussions/91#discussioncomment-4282452) 11 | */ 12 | 13 | interface BaseOverlay { 14 | zIndexValue: Int32; 15 | globalZIndexValue: Int32; 16 | isHidden: boolean; 17 | minZoom: Double; 18 | maxZoom: Double; 19 | isMinZoomInclusive: boolean; 20 | isMaxZoomInclusive: boolean; 21 | } 22 | 23 | type Coord = { 24 | latitude: Double; 25 | longitude: Double; 26 | }; 27 | //////////////////// 28 | 29 | interface Props extends BaseOverlay, ViewProps { 30 | onTapOverlay?: DirectEventHandler>; 31 | geometries: Readonly<{ 32 | coords: ReadonlyArray; 33 | holes: ReadonlyArray>; 34 | }>; 35 | color?: Int32; 36 | outlineColor?: Int32; 37 | outlineWidth?: Double; 38 | } 39 | 40 | export default codegenNativeComponent('RNCNaverMapPolygon'); 41 | -------------------------------------------------------------------------------- /src/spec/RNCNaverMapPolylineNativeComponent.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Double, 3 | Int32, 4 | DirectEventHandler, 5 | WithDefault, 6 | } from 'react-native/Libraries/Types/CodegenTypes'; 7 | import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; 8 | import type { ViewProps } from 'react-native'; 9 | 10 | /* Type should be redeclared because of codegen ts parser doesn't allow imported type 11 | * [comments](https://github.com/reactwg/react-native-new-architecture/discussions/91#discussioncomment-4282452) 12 | */ 13 | 14 | interface BaseOverlay { 15 | zIndexValue: Int32; 16 | globalZIndexValue: Int32; 17 | isHidden: boolean; 18 | minZoom: Double; 19 | maxZoom: Double; 20 | isMinZoomInclusive: boolean; 21 | isMaxZoomInclusive: boolean; 22 | } 23 | 24 | type Coord = { 25 | latitude: Double; 26 | longitude: Double; 27 | }; 28 | //////////////////// 29 | 30 | interface Props extends BaseOverlay, ViewProps { 31 | onTapOverlay?: DirectEventHandler>; 32 | coords: ReadonlyArray; 33 | width?: Double; 34 | color?: Int32; 35 | pattern?: ReadonlyArray; 36 | capType?: WithDefault<'Round' | 'Butt' | 'Square', 'Round'>; 37 | joinType?: WithDefault<'Bevel' | 'Miter' | 'Round', 'Round'>; 38 | } 39 | 40 | export default codegenNativeComponent('RNCNaverMapPolyline'); 41 | -------------------------------------------------------------------------------- /src/types/Align.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 정렬 위치입니다. 3 | */ 4 | export type Align = 5 | | 'Center' 6 | | 'Left' 7 | | 'Right' 8 | | 'Top' 9 | | 'Bottom' 10 | | 'TopLeft' 11 | | 'TopRight' 12 | | 'BottomRight' 13 | | 'BottomLeft'; 14 | -------------------------------------------------------------------------------- /src/types/BaseOverlayProps.ts: -------------------------------------------------------------------------------- 1 | export interface BaseOverlayProps { 2 | /** z index의 위치입니다. 기본값은 0입니다. 3 | * 4 | * 주의해야 할 점은 이 zIndex가 높다고 항상 위에 보이는 것이 아니라는 점입니다. 5 | * 6 | * global zIndex와 보조 zIndex가 존재하며 이 값은 보조 zIndex입니다. 7 | * 8 | * 보조 zIndex는 global zIndex가 같은 오버레이들 중 겹침 우선순위를 조절하는 옵션입니다. 9 | * 10 | * @see {@link globalZIndex} 11 | * @default 0 12 | * */ 13 | zIndex?: number; 14 | /** 지도에서 global z index의 위치입니다. 기본값은 오버레이의 타입에 따라 다릅니다. 15 | * 16 | * 전역 Z 인덱스. 여러 오버레이가 화면에서 겹쳐지면 전역 Z 인덱스가 큰 오버레이가 작은 오버레이를 덮습니다. 17 | * 18 | * 또한 값이 0 이상이면 오버레이가 심벌 위에, 0 미만이면 심벌 아래에 그려집니다. 19 | * 20 | * 다음은 global zIndex의 값들입니다. 21 | * 22 | * - 정보 창: 400000 23 | * - 위치 오버레이: 300000 24 | * - 마커: 200000 25 | * - 화살표 오버레이: 100000 26 | * - (지도 심벌) 27 | * - 경로선 오버레이: -100000 28 | * - 셰이프(폴리곤, 폴리라인, 서클): -200000 29 | * - 지상 오버레이: -300000 30 | * - (지도 배경) 31 | * 32 | * @see {@link zIndex} 33 | * @default null 34 | * */ 35 | globalZIndex?: number; 36 | /** 감춰진 여부입니다. */ 37 | isHidden?: boolean; 38 | /** 39 | * 지도에 보이는 최소 줌 레벨입니다. 40 | * 41 | * @default 0 42 | */ 43 | minZoom?: number; 44 | /** 45 | * 지도에 보이는 최대 줌 레벨입니다. 46 | * 47 | * @default 21 48 | */ 49 | maxZoom?: number; 50 | /** 최소 줌 레벨이 포함될 때도 보이는 지 여부입니다. */ 51 | isMinZoomInclusive?: boolean; 52 | /** 최대 줌 레벨이 포함될 때도 보이는 지 여부입니다. */ 53 | isMaxZoomInclusive?: boolean; 54 | /** 55 | * 오버레이를 클릭했을 때의 이벤트입니다. 56 | * @group Events 57 | */ 58 | onTap?: () => void; 59 | } 60 | -------------------------------------------------------------------------------- /src/types/Camera.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 카메라의 상태를 나타내는 객체입니다. 3 | */ 4 | export interface Camera { 5 | /** 위도 */ 6 | latitude: number; 7 | /** 경도 */ 8 | longitude: number; 9 | /** 10 | * 카메라의 줌 레벨을 나타내는 속성입니다.
줌 레벨은 지도의 축척을 나타냅니다. 11 | * 즉, 줌 레벨이 작을수록 지도가 축소되고 클수록 확대됩니다. 12 | * 줌 레벨이 커지면 지도에 나타나는 정보도 더욱 세밀해집니다. 13 | * 14 | * @default 10 15 | */ 16 | zoom?: number; 17 | /** 18 | * 카메라의 기울임 각도를 나타내는 속성입니다. 19 | * 카메라는 기울임 각도만큼 지면을 비스듬하게 내려다봅니다. 20 | * 기울임 각도가 0도이면 카메라가 지면을 수직으로 내려다보며, 각도가 증가하면 카메라의 시선도 점점 수평에 가깝게 기울어집니다. 21 | * 따라서 기울임 각도가 클수록 더 먼 곳을 볼 수 있게 됩니다. 22 | * 카메라가 기울어지면 화면에 보이는 지도에 원근감이 적용됩니다. 23 | * 즉, 화면의 중심을 기준으로 먼 곳은 더 작게 보이고 가까운 곳은 더 크게 보입니다. 24 | * 25 | * @default 0 26 | */ 27 | tilt?: number; 28 | /** 29 | * 카메라의 헤딩 각도를 나타내는 속성입니다. 30 | * 헤딩은 카메라가 바라보는 방위를 의미합니다. 31 | * 카메라가 정북 방향을 바라볼 때 헤딩 각도는 0도이며, 시계 방향으로 값이 증가합니다. 32 | * 즉, 동쪽을 바라볼 때 90도, 남쪽을 바라볼 때 180도가 됩니다. 33 | * 34 | * @default 0 35 | */ 36 | bearing?: number; 37 | } 38 | -------------------------------------------------------------------------------- /src/types/CameraAnimationEasing.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 카메라 애니메이션의 Easing입니다. 3 | * 4 | * - EaseIn: 부드럽게 가속하며 이동합니다. 가까운 거리를 이동할 때 적합합니다. 5 | * - EaseOut: 부드럽게 감속하며 이동합니다. 가까운 거리를 이동할 때 적합합니다. 6 | * - None: 애니메이션 없이 이동합니다. 7 | * - Linear: 일정한 속도로 이동합니다. 8 | * - Fly: 부드럽게 축소됐다가 확대되며 이동합니다. 먼 거리를 이동할 때 적합합니다. 9 | */ 10 | export type CameraAnimationEasing = 11 | | 'EaseIn' 12 | | 'EaseOut' 13 | | 'None' 14 | | 'Linear' 15 | | 'Fly'; 16 | -------------------------------------------------------------------------------- /src/types/CameraChangeReason.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 카메라의 위치가 변한 이유입니다. 3 | * 4 | * - Developer: 개발자가 API를 호출해 카메라가 움직였음을 나타냅니다. 기본값입니다. 5 | * - Gesture: 사용자의 제스처로 인해 카메라가 움직였음을 나타냅니다. 6 | * - Control: 사용자의 버튼 선택으로 인해 카메라가 움직였음을 나타냅니다. 7 | * - Location: 위치 트래킹 기능으로 인해 카메라가 움직였음을 나타냅니다. 8 | */ 9 | export type CameraChangeReason = 10 | | 'Developer' 11 | | 'Gesture' 12 | | 'Control' 13 | | 'Location'; 14 | -------------------------------------------------------------------------------- /src/types/CameraMoveBaseParams.ts: -------------------------------------------------------------------------------- 1 | import type { CameraAnimationEasing } from './CameraAnimationEasing'; 2 | 3 | export interface CameraMoveBaseParams { 4 | /** 5 | * 지속시간, milliseconds 6 | * 7 | * @default 700 8 | */ 9 | duration?: number; 10 | /** 11 | * 카메라 애니메이션 Easing 12 | * 13 | * @default EaseOut 14 | */ 15 | easing?: CameraAnimationEasing; 16 | /** 17 | * 카메라의 중심은 두 좌표의 중심이며 `pivot`으로 조절할 수 있습니다. 18 | * `pivot`은 기본 0.5(중앙)이며 0 ~ 1 값으로 설정할 수 있습니다. 19 | * 20 | * @default {x: 0.5, y: 0.5} 21 | */ 22 | pivot?: { 23 | x: number; 24 | y: number; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/types/CapType.ts: -------------------------------------------------------------------------------- 1 | export type CapType = 'Round' | 'Butt' | 'Square'; 2 | -------------------------------------------------------------------------------- /src/types/ClusterMarkerProp.ts: -------------------------------------------------------------------------------- 1 | import type { Coord } from './Coord'; 2 | import type { MarkerImageProp } from './MarkerImageProp'; 3 | 4 | export interface ClusterMarkerProp extends Coord { 5 | identifier: string; 6 | image?: MarkerImageProp; 7 | width?: number; 8 | height?: number; 9 | } 10 | -------------------------------------------------------------------------------- /src/types/Coord.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Coord는 하나의 위경도 좌표를 나타내는 객체입니다. 3 | * latitude 속성이 위도를, longitude 속성이 경도를 나타냅니다. 4 | */ 5 | export interface Coord { 6 | /** 위도 */ 7 | latitude: number; 8 | /** 경도 */ 9 | longitude: number; 10 | } 11 | -------------------------------------------------------------------------------- /src/types/JoinType.ts: -------------------------------------------------------------------------------- 1 | export type JoinType = 'Bevel' | 'Miter' | 'Round'; 2 | -------------------------------------------------------------------------------- /src/types/LocationTrackingMode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 사용자의 위치를 추적하는 모드입니다. 3 | * 4 | * - None: 위치를 추적하지 않습니다. 5 | * - NoFollow: 위치 추적이 활성화되고, 현위치 오버레이가 사용자의 위치를 따라 움직입니다. 그러나 지도는 움직이지 않습니다. 6 | * - Follow: 위치 추적이 활성화되고, 현위치 오버레이와 카메라의 좌표가 사용자의 위치를 따라 움직입니다. 7 | * API나 제스처를 사용해 임의로 카메라를 움직일 경우 모드가 NoFollow로 바뀝니다. 8 | * - Face:위치 추적이 활성화되고, 현위치 오버레이, 카메라의 좌표, 베어링이 사용자의 위치 및 방향을 따라 움직입니다. 9 | * API나 제스처를 사용해 임의로 카메라를 움직일 경우 모드가 NoFollow로 바뀝니다. 10 | */ 11 | export type LocationTrackingMode = 'None' | 'NoFollow' | 'Follow' | 'Face'; 12 | -------------------------------------------------------------------------------- /src/types/LogoAlign.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 네이버 로고의 정렬 위치입니다. 3 | */ 4 | export type LogoAlign = 'TopLeft' | 'TopRight' | 'BottomLeft' | 'BottomRight'; 5 | -------------------------------------------------------------------------------- /src/types/MapType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 지도의 유형을 변경하면 가장 바닥에 나타나는 배경 지도의 스타일이 변경됩니다. 3 | * 4 | * - Basic: 일반 지도입니다. 하천, 녹지, 도로, 심벌 등 다양한 정보를 노출합니다. 5 | * - Navi: 차량용 내비게이션에 특화된 지도입니다. 6 | * - Satellite: 위성 지도입니다. 심벌, 도로 등 위성 사진을 제외한 요소는 노출되지 않습니다. 7 | * - Hybrid: 위성 사진과 도로, 심벌을 함께 노출하는 하이브리드 지도입니다. 8 | * - NaviHybrid: 위성 사진과 내비게이션용 도로, 심벌을 함께 노출하는 하이브리드 지도입니다. 9 | * - Terrain: 지형도입니다. 산악 지형을 실제 지형과 유사하게 입체적으로 표현합니다. 10 | * - None: 지도를 나타내지 않습니다. 단, 오버레이는 여전히 나타납니다. 11 | */ 12 | export type MapType = 13 | | 'Basic' 14 | | 'Navi' 15 | | 'Satellite' 16 | | 'Hybrid' 17 | | 'Terrain' 18 | | 'NaviHybrid' 19 | | 'None'; 20 | -------------------------------------------------------------------------------- /src/types/MarkerImageProp.ts: -------------------------------------------------------------------------------- 1 | import type { MarkerSymbol } from './MarkerSymbol'; 2 | import type { ImageRequireSource } from 'react-native/Libraries/Image/ImageSource'; 3 | 4 | /** 5 | * 마커의 이미지 Prop 타입입니다. 6 | */ 7 | export type MarkerImageProp = 8 | | ImageRequireSource 9 | | { 10 | symbol?: MarkerSymbol; 11 | httpUri?: string; 12 | assetName?: string; 13 | reuseIdentifier?: string; 14 | }; 15 | -------------------------------------------------------------------------------- /src/types/MarkerSymbol.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 마커의 기본적인 `symbol` 종류입니다. 3 | * 4 | * @see {@link MarkerImageProp} 5 | */ 6 | export type MarkerSymbol = 7 | | 'blue' 8 | | 'gray' 9 | | 'green' 10 | | 'lightblue' 11 | | 'pink' 12 | | 'red' 13 | | 'yellow' 14 | | 'black' 15 | | 'lowDensityCluster' 16 | | 'mediumDensityCluster' 17 | | 'highDensityCluster'; 18 | -------------------------------------------------------------------------------- /src/types/Point.ts: -------------------------------------------------------------------------------- 1 | export interface Point { 2 | x: number; 3 | y: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/types/Rect.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 사각형을 의미합니다. 3 | */ 4 | export interface Rect { 5 | left: number; 6 | top: number; 7 | right: number; 8 | bottom: number; 9 | } 10 | -------------------------------------------------------------------------------- /src/types/Region.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 지도에 보이는 위치의 상태를 의미하는 객체입니다. 3 | */ 4 | export interface Region { 5 | /** 위도, 대개 더 작은 위도 값이며 정확히는 south-west 지점의 latitude 입니다. */ 6 | latitude: number; 7 | /** 경도, 대개 더 작은 경도 값이며 정확히는 south-west 지점의 longitude 입니다. */ 8 | longitude: number; 9 | /** north-east 지점의 latitude와 latitude와의 위도차이 입니다. */ 10 | latitudeDelta: number; 11 | /** north-east 지점의 longitude와 longitude와의 경도차이 입니다. */ 12 | longitudeDelta: number; 13 | } 14 | -------------------------------------------------------------------------------- /src/util/NaverMapUtil.ts: -------------------------------------------------------------------------------- 1 | // import { Platform, NativeModules } from 'react-native'; 2 | // import type { Spec } from '../spec/NativeRNCNaverMapUtil'; 3 | // 4 | // const LINKING_ERROR = 5 | // "The package '@mj-studio/react-native-naver-map' doesn't seem to be linked. Make sure: \n\n" + 6 | // Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + 7 | // '- You rebuilt the app after installing the package\n' + 8 | // '- You are not using Expo Go\n'; 9 | // 10 | // // @ts-ignore 11 | // const isTurboModuleEnabled = global.__turboModuleProxy != null; 12 | // 13 | // const Module = isTurboModuleEnabled 14 | // ? require('../spec/NativeRNCNaverMapUtil').default 15 | // : NativeModules.NativeRNCNaverMapUtil; 16 | // 17 | // const Native: Spec = Module 18 | // ? Module 19 | // : new Proxy( 20 | // {}, 21 | // { 22 | // get() { 23 | // throw new Error(LINKING_ERROR); 24 | // }, 25 | // } 26 | // ); 27 | 28 | export const NaverMapUtil = {}; 29 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "exclude": ["example", "./expo-config-plugin", "./docs"] 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": ".", 4 | "paths": { 5 | "@mj-studio/react-native-naver-map": ["./src/index"] 6 | }, 7 | "allowUnreachableCode": false, 8 | "allowUnusedLabels": false, 9 | "esModuleInterop": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "jsx": "react", 12 | "lib": ["esnext"], 13 | "module": "esnext", 14 | "moduleResolution": "node", 15 | "noFallthroughCasesInSwitch": true, 16 | "noImplicitReturns": true, 17 | "noImplicitUseStrict": false, 18 | "noStrictGenericChecks": false, 19 | "noUncheckedIndexedAccess": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "resolveJsonModule": true, 23 | "skipLibCheck": true, 24 | "strict": true, 25 | "target": "esnext", 26 | "verbatimModuleSyntax": true 27 | }, 28 | "exclude": ["./expo-config-plugin", "./docs"] 29 | } 30 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasks": { 3 | "ci:android": { 4 | "inputs": [ 5 | "package.json", 6 | "android/**", 7 | "!android/.gradle", 8 | "!android/.idea", 9 | "!android/**/*.{jar,bat}", 10 | "!android/gradlew", 11 | "!android/build", 12 | "src/**/*.ts", 13 | "src/**/*.tsx", 14 | "example/package.json", 15 | "example/android", 16 | "!example/android/.gradle", 17 | "!example/android/build", 18 | "!example/android/app/.cxx", 19 | "!example/android/app/build" 20 | ], 21 | "outputs": [] 22 | }, 23 | "ci:ios": { 24 | "inputs": [ 25 | "package.json", 26 | "*.podspec", 27 | "ios/**", 28 | "!**/*.{DS_Store}", 29 | "src/**/*.ts", 30 | "src/**/*.tsx", 31 | "example/package.json", 32 | "example/ios", 33 | "!example/ios/build", 34 | "!example/ios/Pods" 35 | ], 36 | "outputs": [] 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "React Native Naver Map | MJ Studio", 3 | "entryPoints": ["src/index.tsx"], 4 | "entryPointStrategy": "resolve", 5 | "out": "docs", 6 | "kindSortOrder": ["Function"], 7 | "readme": "README.md", 8 | "tsconfig": "tsconfig.json", 9 | "commentStyle": "all", 10 | "exclude": ["src/spec/**/*", "src/internal/**/*"], 11 | "searchInComments": true, 12 | "sort": ["kind", "static-first", "alphabetical"], 13 | "plugin": ["typedoc-plugin-extras", "typedoc-theme-hierarchy", "@8hobbies/typedoc-plugin-404"], 14 | "theme": "hierarchy", 15 | "customTitle": "React Native Naver Map", 16 | "customDescription": "\uD83D\uDCCD Naver Map Component for React Native Supporting Fabric and Bridge and Expo", 17 | "footerLastModified": true, 18 | "footerTypedocVersion": true, 19 | "categorizeByGroup": true, 20 | "groupOrder": ["Events","*", "Properties"], 21 | "visibilityFilters": { 22 | "protected": false, 23 | "private": false, 24 | "inherited": true, 25 | "external": false, 26 | "@alpha": true, 27 | "@beta": true 28 | }, 29 | "favicon": "public/favicon.png", 30 | "navigationLinks": { 31 | "Github": "https://github.com/mym0404/react-native-naver-map" 32 | }, 33 | "customCss": "./public/doc.css" 34 | } 35 | --------------------------------------------------------------------------------