@exterio/react-native-yamap-lite 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +510 -0
  3. package/YamapLite.podspec +21 -0
  4. package/android/build.gradle +101 -0
  5. package/android/gradle.properties +14 -0
  6. package/android/settings.gradle +1 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/java/com/yamaplite/ClusteredYamapLiteViewManager.kt +181 -0
  9. package/android/src/main/java/com/yamaplite/Components/ClusteredYamapLiteView.kt +169 -0
  10. package/android/src/main/java/com/yamaplite/Components/YamapLiteCircleView.kt +145 -0
  11. package/android/src/main/java/com/yamaplite/Components/YamapLiteMarkerView.kt +214 -0
  12. package/android/src/main/java/com/yamaplite/Components/YamapLitePolygon.kt +149 -0
  13. package/android/src/main/java/com/yamaplite/Components/YamapLitePolyline.kt +171 -0
  14. package/android/src/main/java/com/yamaplite/Components/YamapLiteView.kt +678 -0
  15. package/android/src/main/java/com/yamaplite/Events/CameraPositionChangeEvent.kt +38 -0
  16. package/android/src/main/java/com/yamaplite/Events/MapLoadEvent.kt +34 -0
  17. package/android/src/main/java/com/yamaplite/Events/PressEvent.kt +24 -0
  18. package/android/src/main/java/com/yamaplite/Utils/ImageCache.kt +45 -0
  19. package/android/src/main/java/com/yamaplite/Utils/PointParser.kt +39 -0
  20. package/android/src/main/java/com/yamaplite/Utils/ResolveImageHelper.kt +122 -0
  21. package/android/src/main/java/com/yamaplite/Utils/YamapUtils.kt +169 -0
  22. package/android/src/main/java/com/yamaplite/YamapLiteCircleViewManager.kt +67 -0
  23. package/android/src/main/java/com/yamaplite/YamapLiteMarkerViewManager.kt +82 -0
  24. package/android/src/main/java/com/yamaplite/YamapLitePackage.kt +41 -0
  25. package/android/src/main/java/com/yamaplite/YamapLitePolygonViewManager.kt +61 -0
  26. package/android/src/main/java/com/yamaplite/YamapLitePolylineViewManager.kt +75 -0
  27. package/android/src/main/java/com/yamaplite/YamapLiteViewManager.kt +176 -0
  28. package/ios/ClusteredYamapLiteView.h +15 -0
  29. package/ios/ClusteredYamapLiteView.mm +325 -0
  30. package/ios/ClusteredYamapLiteViewManager.mm +17 -0
  31. package/ios/Components/Circle.swift +108 -0
  32. package/ios/Components/ClusteredYamap.swift +190 -0
  33. package/ios/Components/Marker.swift +187 -0
  34. package/ios/Components/Polygon.swift +108 -0
  35. package/ios/Components/Polyline.swift +125 -0
  36. package/ios/Components/Yamap.swift +585 -0
  37. package/ios/Listeners/CameraListener.swift +54 -0
  38. package/ios/Listeners/ClusterListener.swift +38 -0
  39. package/ios/Listeners/MapInputListener.swift +35 -0
  40. package/ios/Listeners/MapLoadListener.swift +35 -0
  41. package/ios/Listeners/MapObjectTap.swift +12 -0
  42. package/ios/Listeners/UserLocationObjectListener.swift +29 -0
  43. package/ios/Models/YamapModels.swift +77 -0
  44. package/ios/Utils/ImageCache.swift +20 -0
  45. package/ios/Utils/PointsEqual.h +45 -0
  46. package/ios/Utils/ResolveImageHelper.swift +142 -0
  47. package/ios/YamapLiteCircleView.h +15 -0
  48. package/ios/YamapLiteCircleView.mm +102 -0
  49. package/ios/YamapLiteMarkerView.h +15 -0
  50. package/ios/YamapLiteMarkerView.mm +102 -0
  51. package/ios/YamapLitePolygonView.h +15 -0
  52. package/ios/YamapLitePolygonView.mm +120 -0
  53. package/ios/YamapLitePolylineView.h +15 -0
  54. package/ios/YamapLitePolylineView.mm +115 -0
  55. package/ios/YamapLiteView.h +15 -0
  56. package/ios/YamapLiteView.mm +361 -0
  57. package/ios/YamapLiteViewManager.mm +17 -0
  58. package/ios/YamapUtils.h +5 -0
  59. package/ios/YamapUtils.mm +205 -0
  60. package/lib/module/@types/index.js +8 -0
  61. package/lib/module/@types/index.js.map +1 -0
  62. package/lib/module/ClusteredYamapLiteViewNativeComponent.ts +98 -0
  63. package/lib/module/Components/Circle.js +20 -0
  64. package/lib/module/Components/Circle.js.map +1 -0
  65. package/lib/module/Components/ClusteredYamap.js +133 -0
  66. package/lib/module/Components/ClusteredYamap.js.map +1 -0
  67. package/lib/module/Components/Marker.js +40 -0
  68. package/lib/module/Components/Marker.js.map +1 -0
  69. package/lib/module/Components/Polygon.js +25 -0
  70. package/lib/module/Components/Polygon.js.map +1 -0
  71. package/lib/module/Components/Polyline.js +25 -0
  72. package/lib/module/Components/Polyline.js.map +1 -0
  73. package/lib/module/Components/Yamap.js +124 -0
  74. package/lib/module/Components/Yamap.js.map +1 -0
  75. package/lib/module/Components/index.js +9 -0
  76. package/lib/module/Components/index.js.map +1 -0
  77. package/lib/module/NativeYamapUtils.js +5 -0
  78. package/lib/module/NativeYamapUtils.js.map +1 -0
  79. package/lib/module/Utils/YamapUtils.js +14 -0
  80. package/lib/module/Utils/YamapUtils.js.map +1 -0
  81. package/lib/module/YamapCircleViewNativeComponent.ts +28 -0
  82. package/lib/module/YamapLiteViewNativeComponent.ts +93 -0
  83. package/lib/module/YamapMarkerViewNativeComponent.ts +32 -0
  84. package/lib/module/YamapPolygonViewNativeComponent.ts +28 -0
  85. package/lib/module/YamapPolylineViewNativeComponent.ts +31 -0
  86. package/lib/module/index.js +7 -0
  87. package/lib/module/index.js.map +1 -0
  88. package/lib/module/package.json +1 -0
  89. package/lib/typescript/package.json +1 -0
  90. package/lib/typescript/src/@types/index.d.ts +257 -0
  91. package/lib/typescript/src/@types/index.d.ts.map +1 -0
  92. package/lib/typescript/src/ClusteredYamapLiteViewNativeComponent.d.ts +82 -0
  93. package/lib/typescript/src/ClusteredYamapLiteViewNativeComponent.d.ts.map +1 -0
  94. package/lib/typescript/src/Components/Circle.d.ts +4 -0
  95. package/lib/typescript/src/Components/Circle.d.ts.map +1 -0
  96. package/lib/typescript/src/Components/ClusteredYamap.d.ts +3 -0
  97. package/lib/typescript/src/Components/ClusteredYamap.d.ts.map +1 -0
  98. package/lib/typescript/src/Components/Marker.d.ts +3 -0
  99. package/lib/typescript/src/Components/Marker.d.ts.map +1 -0
  100. package/lib/typescript/src/Components/Polygon.d.ts +4 -0
  101. package/lib/typescript/src/Components/Polygon.d.ts.map +1 -0
  102. package/lib/typescript/src/Components/Polyline.d.ts +4 -0
  103. package/lib/typescript/src/Components/Polyline.d.ts.map +1 -0
  104. package/lib/typescript/src/Components/Yamap.d.ts +3 -0
  105. package/lib/typescript/src/Components/Yamap.d.ts.map +1 -0
  106. package/lib/typescript/src/Components/index.d.ts +7 -0
  107. package/lib/typescript/src/Components/index.d.ts.map +1 -0
  108. package/lib/typescript/src/NativeYamapUtils.d.ts +30 -0
  109. package/lib/typescript/src/NativeYamapUtils.d.ts.map +1 -0
  110. package/lib/typescript/src/Utils/YamapUtils.d.ts +27 -0
  111. package/lib/typescript/src/Utils/YamapUtils.d.ts.map +1 -0
  112. package/lib/typescript/src/YamapCircleViewNativeComponent.d.ts +20 -0
  113. package/lib/typescript/src/YamapCircleViewNativeComponent.d.ts.map +1 -0
  114. package/lib/typescript/src/YamapLiteViewNativeComponent.d.ts +80 -0
  115. package/lib/typescript/src/YamapLiteViewNativeComponent.d.ts.map +1 -0
  116. package/lib/typescript/src/YamapMarkerViewNativeComponent.d.ts +25 -0
  117. package/lib/typescript/src/YamapMarkerViewNativeComponent.d.ts.map +1 -0
  118. package/lib/typescript/src/YamapPolygonViewNativeComponent.d.ts +20 -0
  119. package/lib/typescript/src/YamapPolygonViewNativeComponent.d.ts.map +1 -0
  120. package/lib/typescript/src/YamapPolylineViewNativeComponent.d.ts +23 -0
  121. package/lib/typescript/src/YamapPolylineViewNativeComponent.d.ts.map +1 -0
  122. package/lib/typescript/src/index.d.ts +5 -0
  123. package/lib/typescript/src/index.d.ts.map +1 -0
  124. package/package.json +189 -0
  125. package/src/@types/index.ts +314 -0
  126. package/src/ClusteredYamapLiteViewNativeComponent.ts +98 -0
  127. package/src/Components/Circle.tsx +22 -0
  128. package/src/Components/ClusteredYamap.tsx +194 -0
  129. package/src/Components/Marker.tsx +50 -0
  130. package/src/Components/Polygon.tsx +27 -0
  131. package/src/Components/Polyline.tsx +27 -0
  132. package/src/Components/Yamap.tsx +176 -0
  133. package/src/Components/index.ts +6 -0
  134. package/src/NativeYamapUtils.ts +47 -0
  135. package/src/Utils/YamapUtils.ts +63 -0
  136. package/src/YamapCircleViewNativeComponent.ts +28 -0
  137. package/src/YamapLiteViewNativeComponent.ts +93 -0
  138. package/src/YamapMarkerViewNativeComponent.ts +32 -0
  139. package/src/YamapPolygonViewNativeComponent.ts +28 -0
  140. package/src/YamapPolylineViewNativeComponent.ts +31 -0
  141. package/src/index.tsx +5 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 hydromoll
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.
package/README.md ADDED
@@ -0,0 +1,510 @@
1
+ <div align="center">
2
+
3
+ <img src="./images/banner.png" alt="@exterio/react-native-yamap-lite" width="420" />
4
+
5
+ # @exterio/react-native-yamap-lite
6
+
7
+ **Легковесная библиотека для интеграции Yandex Maps (Яндекс Карт) в React Native.**
8
+
9
+ Yandex Maps · React Native · Fabric
10
+
11
+ [![npm](https://img.shields.io/npm/v/@exterio/react-native-yamap-lite.svg)](https://www.npmjs.com/package/@exterio/react-native-yamap-lite)
12
+ [![platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20Android-blue.svg)](#требования)
13
+ [![New Architecture](https://img.shields.io/badge/New%20Architecture-Fabric-success.svg)](#требования)
14
+ [![tests](https://img.shields.io/badge/tests-Jest%20%2B%20Harness-brightgreen.svg)](#тесты)
15
+ [![license](https://img.shields.io/npm/l/@exterio/react-native-yamap-lite.svg)](./LICENSE)
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ Lite-обёртка над [Yandex MapKit SDK](https://yandex.ru/dev/maps/mapkit/) — карты, маркеры,
22
+ круги, полигоны, полилинии и кластеризация без лишнего веса: в ней нет маршрутов,
23
+ геокодера и поиска, только то, что нужно для отображения карты в приложении.
24
+
25
+ Библиотека собрана целиком на **новой архитектуре React Native** (**Fabric** +
26
+ **TurboModules**), что даёт нативную скорость рендеринга на iOS и Android.
27
+
28
+ ## ✨ Возможности
29
+
30
+ - 🗺️ **Карты Yandex** — типы `map` / `satellite` / `hybrid`, ночной режим, кастомные стили MapKit.
31
+ - 📍 **Маркеры** — локальные (`require`) и удалённые (`{ uri }`) изображения, якорь, масштаб, z-index.
32
+ - ⭕ **Круги, полигоны, полилинии** — оверлеи с настраиваемыми цветами заливки и обводки.
33
+ - 🔗 **Кластеризация** — компонент `ClusteredYamap` для автоматической группировки маркеров.
34
+ - 📱 **Позиция пользователя** — отслеживание геолокации, кастомная иконка и зона точности.
35
+ - 🎯 **Управление камерой** — `setCenter`, `setZoom`, `fitAllMarkers`, чтение позиции и видимой области через `ref`.
36
+ - 🎨 **Жесты и UI** — гибкая настройка жестов, частоты кадров и позиции логотипа Яндекса.
37
+
38
+ > 💡 Знакомы с [`react-native-yamap`](https://github.com/volga-volga/react-native-yamap)?
39
+ > API близок по духу — миграция требует минимальных изменений.
40
+
41
+ ## Требования
42
+
43
+ Библиотека использует **Fabric (новую архитектуру React Native)** и требует:
44
+
45
+ - **React Native >= 0.70.0** с включенной новой архитектурой
46
+
47
+ ## Установка
48
+
49
+ ```sh
50
+ yarn add @exterio/react-native-yamap-lite
51
+ ```
52
+
53
+ или
54
+
55
+ ```sh
56
+ npm install @exterio/react-native-yamap-lite --save
57
+ ```
58
+
59
+ ### iOS
60
+
61
+ После установки выполните:
62
+
63
+ ```sh
64
+ cd ios && pod install && cd ..
65
+ ```
66
+
67
+ ## Инициализация карт
68
+
69
+ Инициализация выполняется **полностью из JavaScript** — не нужно править
70
+ `AppDelegate.swift` или `MainApplication`. Достаточно один раз вызвать
71
+ `YamapUtils.init(apiKey)` до того, как карта отрендерится (например, в `index.js`
72
+ или в корне `App.tsx`). Этот вызов сам устанавливает API-ключ и запускает MapKit
73
+ на обеих платформах.
74
+
75
+ ```js
76
+ // index.js
77
+ import { AppRegistry } from 'react-native';
78
+ import { YamapUtils } from '@exterio/react-native-yamap-lite';
79
+ import App from './App';
80
+ import { name as appName } from './app.json';
81
+
82
+ // Замените на ваш API-ключ от Yandex MapKit
83
+ YamapUtils.init('YOUR_API_KEY').catch((error) => {
84
+ console.warn('YamapUtils.init failed:', error);
85
+ });
86
+
87
+ // (необязательно) язык интерфейса карты
88
+ YamapUtils.setLocale('ru_RU');
89
+
90
+ AppRegistry.registerComponent(appName, () => App);
91
+ ```
92
+
93
+ > 💡 `init` возвращает `Promise` — карту можно рендерить сразу, она дождётся
94
+ > завершения инициализации. Метод идемпотентен: повторные вызовы безопасны.
95
+
96
+ > ℹ️ Android-зависимость MapKit (`com.yandex.android:maps.mobile`) уже входит в
97
+ > библиотеку — добавлять её в `android/app/build.gradle` вручную не нужно.
98
+
99
+ ## Миграция с react-native-yamap
100
+
101
+ Это **не форк** [`react-native-yamap`](https://github.com/volga-volga/react-native-yamap) (volga-volga) — нативная часть написана с нуля на Swift и Kotlin под Fabric. Но публичный JS-API я старался держать максимально совместимым, чтобы переезд был как можно ближе к «поменять импорт». Для большинства проектов, использующих карту, маркеры и оверлеи, миграция сводится к нескольким правкам.
102
+
103
+ ### Что совместимо
104
+
105
+ Компоненты и их основные пропсы совпадают по именам и форме данных:
106
+
107
+ | Сущность | react-native-yamap | react-native-yamap-lite |
108
+ |--|--|--|
109
+ | Карта | `YaMap` (default + named) | ✅ так же |
110
+ | Примитивы | `Marker`, `Circle`, `Polygon`, `Polyline` | ✅ так же |
111
+ | Кластеры | `ClusteredYamap` | ✅ так же |
112
+ | Координата | `{ lat, lon }` (`Point`) | ✅ так же |
113
+ | Управление камерой | `setCenter`, `setZoom`, `fitAllMarkers` (через `ref`) | ✅ так же |
114
+
115
+ ```diff
116
+ - import YaMap, { Marker, Circle } from 'react-native-yamap';
117
+ + import YaMap, { Marker, Circle } from '@exterio/react-native-yamap-lite';
118
+ ```
119
+
120
+ ### Что изменилось
121
+
122
+ - **Инициализация.** Вместо статического `YaMap.init(apiKey)` / `YaMap.setLocale(...)` используйте модуль `YamapUtils`:
123
+
124
+ ```diff
125
+ - import YaMap from 'react-native-yamap';
126
+ - YaMap.init('YOUR_API_KEY');
127
+ - YaMap.setLocale('ru_RU');
128
+ + import { YamapUtils } from '@exterio/react-native-yamap-lite';
129
+ + await YamapUtils.init('YOUR_API_KEY');
130
+ + YamapUtils.setLocale('ru_RU');
131
+ ```
132
+
133
+ - **`getCameraPosition` возвращает `Promise`**, а не принимает колбэк:
134
+
135
+ ```diff
136
+ - mapRef.current.getCameraPosition((pos) => console.log(pos));
137
+ + const pos = await mapRef.current.getCameraPosition();
138
+ ```
139
+
140
+ Аналогично промисы возвращают `getVisibleRegion`, `getScreenPoints`, `getWorldPoints`. Для совместимости со старым событийным стилем оставлены колбэк-пропсы `onCameraPositionReceived`, `onVisibleRegionReceived`, `onWorldToScreenPointsReceived`, `onScreenToWorldPointsReceived`.
141
+
142
+ - **Только новая архитектура.** Библиотека работает исключительно на Fabric + TurboModules. Если проект ещё на старой архитектуре — нужно сначала включить New Architecture.
143
+
144
+ ### Чего нет (ограничения lite SDK)
145
+
146
+ Библиотека построена на **MapKit Lite**, поэтому всё, что связано с сетевыми сервисами Яндекса, в неё не входит:
147
+
148
+ - ❌ **Маршруты** (`findRoutes` / `findMasstransitRoutes` / `findDrivingRoutes` и компоненты маршрутов)
149
+ - ❌ **Геокодер, поиск и подсказки** (`Suggest`, поиск по адресу)
150
+ - ❌ **Слой пробок** — `setTrafficVisible(visible)` оставлен как no-op для совместимости
151
+ - ⚠️ **`fitMarkers(markers)`** — это алиас для `fitAllMarkers()`: lite SDK не умеет нацеливаться на конкретные маркеры
152
+ - ⚠️ **`marker.animatedMoveTo()` / `animatedRotateTo()`** не поддерживаются — обновляйте проп `point` маркера вместо императивной анимации
153
+
154
+ Если проект использует маршрутизацию, геокодер или поиск — этот пакет их не заменит, тут нужен полноценный `react-native-yamap`.
155
+
156
+ ## Использование
157
+
158
+ ### Базовый пример
159
+
160
+ ```jsx
161
+ import React from 'react';
162
+ import { YaMap, Marker, Circle } from '@exterio/react-native-yamap-lite';
163
+
164
+ const Map = () => {
165
+ return (
166
+ <YaMap
167
+ initialRegion={{
168
+ lat: 55.751244,
169
+ lon: 37.618423,
170
+ zoom: 10
171
+ }}
172
+ style={{ flex: 1 }}
173
+ >
174
+ <Marker
175
+ point={{ lat: 55.751244, lon: 37.618423 }}
176
+ source={require('./marker.png')}
177
+ />
178
+ <Circle
179
+ center={{ lat: 55.751244, lon: 37.618423 }}
180
+ radius={1000}
181
+ fillColor="#0000ff"
182
+ strokeColor="#ff0000"
183
+ strokeWidth={2}
184
+ />
185
+ </YaMap>
186
+ );
187
+ };
188
+ ```
189
+
190
+ ## Типы
191
+
192
+ ```typescript
193
+ interface Point {
194
+ lat: number;
195
+ lon: number;
196
+ }
197
+
198
+ interface InitialRegion {
199
+ lat: number;
200
+ lon: number;
201
+ zoom?: number;
202
+ azimuth?: number;
203
+ tilt?: number;
204
+ }
205
+
206
+ interface CameraPosition {
207
+ nativeEvent: {
208
+ zoom: number;
209
+ tilt: number;
210
+ azimuth: number;
211
+ point: { lat: number; lon: number };
212
+ finished: boolean;
213
+ target: number;
214
+ reason: 'GESTURES' | 'APPLICATION';
215
+ };
216
+ }
217
+
218
+ interface MapLoaded {
219
+ nativeEvent: {
220
+ renderObjectCount: number;
221
+ curZoomModelsLoaded: number;
222
+ curZoomPlacemarksLoaded: number;
223
+ curZoomLabelsLoaded: number;
224
+ curZoomGeometryLoaded: number;
225
+ tileMemoryUsage: number;
226
+ delayedGeometryLoaded: number;
227
+ fullyAppeared: number;
228
+ fullyLoaded: number;
229
+ };
230
+ }
231
+
232
+ type YandexLogoPosition = {
233
+ horizontal?: 'left' | 'center' | 'right';
234
+ vertical?: 'top' | 'bottom';
235
+ };
236
+
237
+ type YandexLogoPadding = {
238
+ horizontal?: number;
239
+ vertical?: number;
240
+ };
241
+ ```
242
+
243
+ ## Компонент YaMap
244
+
245
+ ### Props
246
+
247
+ | Название | Тип | По умолчанию | Описание |
248
+ |--|--|--|--|
249
+ | `initialRegion` | `InitialRegion` | - | Изначальное местоположение карты при загрузке |
250
+ | `showUserPosition` | `boolean` | `false` | Отслеживание геоданных и отображение позиции пользователя |
251
+ | `followUser` | `boolean` | `false` | Слежение камеры за пользователем |
252
+ | `userLocationIcon` | `ImageSource` | - | Иконка для позиции пользователя |
253
+ | `userLocationIconScale` | `number` | `1` | Масштабирование иконки пользователя |
254
+ | `userLocationAccuracyFillColor` | `string` | `#00FF00` | Цвет фона зоны точности определения позиции пользователя |
255
+ | `userLocationAccuracyStrokeColor` | `string` | `#000000` | Цвет границы зоны точности определения позиции пользователя |
256
+ | `userLocationAccuracyStrokeWidth` | `number` | `2` | Толщина зоны точности определения позиции пользователя |
257
+ | `nightMode` | `boolean` | `false` | Использование ночного режима |
258
+ | `mapStyle` | `string` | - | Стили карты согласно [документации](https://yandex.ru/dev/maps/mapkit/doc/dg/concepts/style.html) |
259
+ | `mapType` | `'map' \| 'satellite' \| 'hybrid'` | `'map'` | Тип карты |
260
+ | `scrollGesturesEnabled` | `boolean` | `true` | Включены ли жесты скролла |
261
+ | `zoomGesturesEnabled` | `boolean` | `true` | Включены ли жесты зума |
262
+ | `tiltGesturesEnabled` | `boolean` | `true` | Включены ли жесты наклона камеры двумя пальцами |
263
+ | `rotateGesturesEnabled` | `boolean` | `true` | Включены ли жесты поворота камеры |
264
+ | `fastTapEnabled` | `boolean` | `true` | Убрана ли задержка в 300мс при клике/тапе |
265
+ | `maxFps` | `number` | `60` | Максимальная частота обновления карты |
266
+ | `logoPosition` | `YandexLogoPosition` | - | Позиция логотипа Яндекса на карте |
267
+ | `logoPadding` | `YandexLogoPadding` | - | Отступ логотипа Яндекса на карте |
268
+ | `onMapLoaded` | `(event: MapLoaded) => void` | - | Колбек на загрузку карты |
269
+ | `onCameraPositionChange` | `(event: CameraPosition) => void` | - | Колбек на изменение положения камеры |
270
+ | `onCameraPositionChangeEnd` | `(event: CameraPosition) => void` | - | Колбек при завершении изменения положения камеры |
271
+ | `onMapPress` | `(event: Point) => void` | - | Событие нажатия на карту |
272
+ | `onMapLongPress` | `(event: Point) => void` | - | Событие долгого нажатия на карту |
273
+
274
+ ### Методы (через ref)
275
+
276
+ ```typescript
277
+ interface YaMapRef {
278
+ getCameraPosition: () => Promise<{
279
+ lat: number;
280
+ lon: number;
281
+ zoom: number;
282
+ azimuth: number;
283
+ tilt: number;
284
+ }>;
285
+ setZoom: (
286
+ zoom: number,
287
+ duration?: number,
288
+ animation?: 'LINEAR' | 'SMOOTH'
289
+ ) => void;
290
+ setCenter: (
291
+ center: { lat: number; lon: number },
292
+ zoom?: number,
293
+ azimuth?: number,
294
+ tilt?: number,
295
+ duration?: number,
296
+ animation?: 'LINEAR' | 'SMOOTH'
297
+ ) => void;
298
+ fitAllMarkers: () => void;
299
+ getMapObjectCount: () => Promise<number>;
300
+ getVisibleRegion: () => Promise<VisibleRegion>;
301
+ getScreenPoints: (points: Point[]) => Promise<ScreenPoint[]>;
302
+ getWorldPoints: (points: ScreenPoint[]) => Promise<Point[]>;
303
+ }
304
+ ```
305
+
306
+ **Пример использования:**
307
+
308
+ ```jsx
309
+ import React, { useRef } from 'react';
310
+ import { YaMap } from '@exterio/react-native-yamap-lite';
311
+
312
+ const Map = () => {
313
+ const mapRef = useRef(null);
314
+
315
+ const handleSetCenter = () => {
316
+ mapRef.current?.setCenter(
317
+ { lat: 55.751244, lon: 37.618423 },
318
+ 15,
319
+ 0,
320
+ 0,
321
+ 1000,
322
+ 'SMOOTH'
323
+ );
324
+ };
325
+
326
+ const handleGetCameraPosition = async () => {
327
+ const position = await mapRef.current?.getCameraPosition();
328
+ console.log(position);
329
+ };
330
+
331
+ return (
332
+ <YaMap
333
+ ref={mapRef}
334
+ initialRegion={{
335
+ lat: 55.751244,
336
+ lon: 37.618423,
337
+ zoom: 10
338
+ }}
339
+ style={{ flex: 1 }}
340
+ />
341
+ );
342
+ };
343
+ ```
344
+
345
+ ## Примитивы
346
+
347
+ ### Marker
348
+
349
+ ```jsx
350
+ <YaMap>
351
+ <Marker
352
+ point={{ lat: 55.751244, lon: 37.618423 }}
353
+ source={require('./marker.png')}
354
+ scale={1.5}
355
+ anchor={{ x: 0.5, y: 0.5 }}
356
+ zInd={100}
357
+ visible={true}
358
+ onPress={(point) => console.log('Marker pressed', point)}
359
+ />
360
+ </YaMap>
361
+ ```
362
+
363
+ #### Props для Marker
364
+
365
+ | Название | Тип | Описание |
366
+ |--|--|--|
367
+ | `point` | `Point` | Координаты точки для отображения маркера |
368
+ | `source` | `ImageSource` | Данные для изображения маркера |
369
+ | `scale` | `number` | Масштабирование иконки маркера |
370
+ | `anchor` | `{ x: number, y: number }` | Якорь иконки маркера. Координаты принимают значения от 0 до 1 |
371
+ | `zInd` | `number` | Отображение элемента по оси Z |
372
+ | `visible` | `boolean` | Отображение маркера на карте |
373
+ | `rotated` | `boolean` | Вращение маркера при движении |
374
+ | `size` | `number` | Размер маркера в пикселях |
375
+ | `handled` | `boolean` | Включение(**false**)/отключение(**true**) всплытия события нажатия для родителя `default: true` |
376
+ | `onPress` | `(event: Point) => void` | Действие при нажатии/клике |
377
+
378
+ ### Circle
379
+
380
+ ```jsx
381
+ <YaMap>
382
+ <Circle
383
+ center={{ lat: 55.751244, lon: 37.618423 }}
384
+ radius={1000}
385
+ fillColor="#0000ff"
386
+ strokeColor="#ff0000"
387
+ strokeWidth={2}
388
+ zInd={100}
389
+ onPress={(point) => console.log('Circle pressed', point)}
390
+ />
391
+ </YaMap>
392
+ ```
393
+
394
+ #### Props для Circle
395
+
396
+ | Название | Тип | Описание |
397
+ |--|--|--|
398
+ | `center` | `Point` | Координаты центра круга |
399
+ | `radius` | `number` | Радиус круга в метрах |
400
+ | `fillColor` | `string` | Цвет заливки |
401
+ | `strokeColor` | `string` | Цвет границы |
402
+ | `strokeWidth` | `number` | Толщина границы |
403
+ | `zInd` | `number` | Отображение элемента по оси Z |
404
+ | `handled` | `boolean` | Включение(**false**)/отключение(**true**) всплытия события нажатия для родителя `default: true` |
405
+ | `onPress` | `(event: Point) => void` | Действие при нажатии/клике |
406
+
407
+ ## ClusteredYamap
408
+
409
+ Компонент для отображения кластеризованных маркеров:
410
+
411
+ ```jsx
412
+ import { ClusteredYamap, Marker } from '@exterio/react-native-yamap-lite';
413
+
414
+ <ClusteredYamap
415
+ clusterColor="#ff00ff"
416
+ clusteredMarkers={[
417
+ { point: { lat: 55.751244, lon: 37.618423 }, data: {} },
418
+ { point: { lat: 55.752244, lon: 37.619423 }, data: {} },
419
+ ]}
420
+ renderMarker={({ point, data }) => (
421
+ <Marker
422
+ point={point}
423
+ source={{ uri: data.source }}
424
+ size={data.size}
425
+ />
426
+ )}
427
+ style={{ flex: 1 }}
428
+ />
429
+ ```
430
+
431
+ #### Props для ClusteredYamap
432
+
433
+ Все props из `YaMap` плюс:
434
+
435
+ | Название | Тип | По умолчанию | Описание |
436
+ |--|--|--|--|
437
+ | `clusteredMarkers` | `Array<{ point: Point, data: any }>` | `[]` | Массив маркеров для кластеризации |
438
+ | `renderMarker` | `(info: { point: Point, data: any }, index: number) => ReactElement` | - | Функция для рендеринга каждого маркера |
439
+ | `clusterColor` | `string` | `#FF0000` | Цвет фона метки-кластера |
440
+
441
+ ## Запуск Example приложения
442
+
443
+ Перед запуском example приложения необходимо собрать нативный код для вашей платформы:
444
+
445
+ **Для iOS:**
446
+ ```sh
447
+ cd example
448
+ cd ios && pod install && cd ..
449
+ yarn ios
450
+ ```
451
+
452
+ **Для Android:**
453
+ ```sh
454
+ cd example
455
+ yarn build:android
456
+ yarn android
457
+ ```
458
+
459
+ После сборки можно запускать приложение как обычно используя `yarn ios` или `yarn android`.
460
+
461
+ **Примечание:** Все методы и примеры использования карты можно запустить и посмотреть в папке `example` проекта.
462
+
463
+ ## Тесты
464
+
465
+ Библиотека покрыта тестами на двух уровнях:
466
+
467
+ - **Jest** — модульные тесты JS-слоя (компоненты, парсинг пропсов, преобразование
468
+ координат, мосты к нативным модулям). Запускаются без устройства/эмулятора:
469
+
470
+ ```sh
471
+ yarn test
472
+ ```
473
+
474
+ - **Harness** — интеграционные тесты, которые гоняют реальные нативные Fabric-компоненты
475
+ на **iOS и Android** через [`react-native-harness`](https://github.com/callstack/react-native-harness).
476
+ Покрыты `YaMap`, `Marker`, `Circle`, `Polygon`, `Polyline`, `ClusteredYamap`,
477
+ события карты, методы `YamapUtils` и набор регрессионных сценариев
478
+ (см. `example/harness/tests`):
479
+
480
+ ```sh
481
+ # обе платформы
482
+ yarn test:harness
483
+
484
+ # по отдельности
485
+ yarn test:harness:ios
486
+ yarn test:harness:android
487
+ ```
488
+
489
+ Так нативный код проверяется на настоящих картах, а не на моках, — это покрывает баги,
490
+ которые JS-тесты увидеть не могут.
491
+
492
+ ## Важные замечания
493
+
494
+ 1. Компонент карт стилизуется, как и `View` из React Native. Если карта не отображается, после инициализации с валидным ключом API, вероятно необходимо прописать стиль, который опишет размеры компонента (`height + width` или `flex`).
495
+
496
+ 2. Для маркеров и иконки локации пользователя можно использовать как локальные изображения (через `require('./img.png')`), так и удаленные (через `{ uri: 'https://...' }`).
497
+
498
+ 3. Для отображения позиции пользователя на Android нужно запросить разрешение `android.permission.ACCESS_FINE_LOCATION`. На iOS нужно добавить `NSLocationWhenInUseUsageDescription` в `Info.plist`.
499
+
500
+ ## Contributing
501
+
502
+ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
503
+
504
+ ## License
505
+
506
+ MIT
507
+
508
+ ---
509
+
510
+ Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
@@ -0,0 +1,21 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "YamapLite"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported }
14
+ s.source = { :git => "https://github.com/hydromoll/react-native-yamap-lite.git", :tag => "#{s.version}" }
15
+
16
+ s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
17
+ s.private_header_files = "ios/**/*.h"
18
+ s.dependency 'YandexMapsMobile', '4.16.0-lite'
19
+
20
+ install_modules_dependencies(s)
21
+ end
@@ -0,0 +1,101 @@
1
+ buildscript {
2
+ ext.getExtOrDefault = { name ->
3
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['YamapLite_' + name]
4
+ }
5
+
6
+ ext {
7
+ minSdkVersion = 26
8
+ compileSdkVersion = 34
9
+ }
10
+
11
+ repositories {
12
+ google()
13
+ mavenCentral()
14
+ }
15
+
16
+ dependencies {
17
+ classpath "com.android.tools.build:gradle:8.7.2"
18
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
19
+ }
20
+ }
21
+
22
+ def isNewArchitectureEnabled() {
23
+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
24
+ }
25
+
26
+ apply plugin: "com.android.library"
27
+ apply plugin: "org.jetbrains.kotlin.android"
28
+
29
+ if (isNewArchitectureEnabled()) {
30
+ apply plugin: "com.facebook.react"
31
+ }
32
+
33
+ def getExtOrIntegerDefault(name) {
34
+ return rootProject.ext.has(name)
35
+ ? rootProject.ext.get(name)
36
+ : (project.properties["YamapLite_" + name]).toInteger()
37
+ }
38
+
39
+ android {
40
+ namespace = "com.yamaplite"
41
+ compileSdk = getExtOrIntegerDefault("compileSdkVersion")
42
+
43
+ defaultConfig {
44
+ minSdk = getExtOrIntegerDefault("minSdkVersion")
45
+ targetSdk = getExtOrIntegerDefault("targetSdkVersion")
46
+ }
47
+
48
+ buildFeatures {
49
+ buildConfig = true
50
+ }
51
+
52
+ buildTypes {
53
+ release {
54
+ minifyEnabled = false
55
+ }
56
+ }
57
+
58
+ lint {
59
+ disable 'GradleCompatible'
60
+ }
61
+
62
+ compileOptions {
63
+ sourceCompatibility = JavaVersion.VERSION_17
64
+ targetCompatibility = JavaVersion.VERSION_17
65
+ }
66
+
67
+ kotlinOptions {
68
+ jvmTarget = "17"
69
+ }
70
+
71
+ sourceSets {
72
+ main {
73
+ java.srcDirs += [
74
+ "build/generated/source/codegen/java",
75
+ "generated/java",
76
+ "generated/jni"
77
+ ]
78
+ }
79
+ }
80
+ }
81
+
82
+ repositories {
83
+ google()
84
+ mavenCentral()
85
+ }
86
+
87
+ def kotlin_version = getExtOrDefault("kotlinVersion")
88
+
89
+ dependencies {
90
+ implementation "com.facebook.react:react-android:0.79.2"
91
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
92
+ implementation 'com.yandex.android:maps.mobile:4.24.0-lite'
93
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
94
+ }
95
+
96
+ afterEvaluate {
97
+ def react = rootProject.ext.has("react") ? rootProject.ext.get("react") : null
98
+ if (react != null && react.hasProperty("registerReactNativeModule")) {
99
+ react.registerReactNativeModule(project)
100
+ }
101
+ }
@@ -0,0 +1,14 @@
1
+ YamapLite_kotlinVersion=2.0.21
2
+ YamapLite_minSdkVersion=24
3
+ YamapLite_targetSdkVersion=34
4
+ YamapLite_compileSdkVersion=35
5
+ YamapLite_ndkVersion=27.1.12297006
6
+
7
+ # AndroidX
8
+ android.useAndroidX=true
9
+ android.enableJetifier=true
10
+
11
+ # JVM settings
12
+ org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
13
+ org.gradle.parallel=true
14
+ org.gradle.caching=true
@@ -0,0 +1 @@
1
+ rootProject.name = 'react-native-yamap-lite'
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>