@defra/interactive-map 0.0.3-alpha → 0.0.5-alpha

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 (407) hide show
  1. package/README.md +16 -57
  2. package/dist/css/index.css +1 -1
  3. package/dist/esm/im-core.js +1 -1
  4. package/dist/esm/index.js +1 -1
  5. package/dist/umd/im-core.js +1 -1
  6. package/dist/umd/index.js +1 -1
  7. package/docs/api/button-definition.md +176 -0
  8. package/docs/api/context.md +124 -0
  9. package/docs/api/control-definition.md +72 -0
  10. package/docs/api/icon-definition.md +28 -0
  11. package/docs/api/map-style-config.md +76 -0
  12. package/docs/api/marker-config.md +51 -0
  13. package/docs/api/panel-definition.md +117 -0
  14. package/docs/api/slots.md +25 -0
  15. package/docs/api.md +721 -0
  16. package/docs/architecture.md +139 -0
  17. package/docs/building-a-plugin.md +149 -0
  18. package/docs/getting-started.md +46 -0
  19. package/docs/govuk-prototype.md +0 -0
  20. package/docs/plugins/interact.md +205 -0
  21. package/docs/plugins/map-styles.md +84 -0
  22. package/docs/plugins/plugin-context.md +67 -0
  23. package/docs/plugins/plugin-descriptor.md +71 -0
  24. package/docs/plugins/plugin-manifest.md +118 -0
  25. package/docs/plugins/scale-bar.md +62 -0
  26. package/docs/plugins/search.md +162 -0
  27. package/docs/plugins.md +116 -0
  28. package/govuk-prototype-kit.config.json +7 -7
  29. package/package.json +16 -2
  30. package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +2 -0
  31. package/plugins/beta/datasets/dist/esm/index.js +2 -0
  32. package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +2 -0
  33. package/plugins/beta/datasets/dist/umd/index.js +2 -0
  34. package/plugins/beta/datasets/src/datasets.js +113 -0
  35. package/plugins/beta/datasets/src/fetch/createDynamicSource.js +206 -0
  36. package/plugins/beta/datasets/src/fetch/fetchGeoJSON.js +38 -0
  37. package/plugins/{datasets → beta/datasets}/src/handleSetMapStyle.js +8 -1
  38. package/plugins/{datasets → beta/datasets}/src/manifest.js +1 -1
  39. package/plugins/{datasets → beta/datasets}/src/mapLayers.js +42 -4
  40. package/plugins/{datasets → beta/datasets}/src/panels/Key.jsx +1 -1
  41. package/plugins/beta/datasets/src/utils/bbox.js +115 -0
  42. package/plugins/beta/draw-ml/dist/css/index.css +1 -0
  43. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -0
  44. package/plugins/beta/draw-ml/dist/esm/index.js +2 -0
  45. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -0
  46. package/plugins/beta/draw-ml/dist/umd/index.js +2 -0
  47. package/plugins/beta/draw-ml/src/api/addFeature.js +27 -0
  48. package/plugins/{draw-ml → beta/draw-ml}/src/api/editFeature.js +17 -6
  49. package/plugins/beta/draw-ml/src/api/merge.js +9 -0
  50. package/plugins/beta/draw-ml/src/api/newLine.js +68 -0
  51. package/plugins/beta/draw-ml/src/api/newPolygon.js +68 -0
  52. package/plugins/beta/draw-ml/src/api/split.js +81 -0
  53. package/plugins/{draw-ml → beta/draw-ml}/src/defaults.js +3 -0
  54. package/plugins/beta/draw-ml/src/draw.scss +32 -0
  55. package/plugins/beta/draw-ml/src/events.js +171 -0
  56. package/plugins/beta/draw-ml/src/manifest.js +132 -0
  57. package/plugins/{draw-ml → beta/draw-ml}/src/mapboxDraw.js +51 -2
  58. package/plugins/{draw-ml → beta/draw-ml}/src/mapboxSnap.js +18 -12
  59. package/plugins/beta/draw-ml/src/modes/createDrawMode.js +497 -0
  60. package/plugins/beta/draw-ml/src/modes/drawLineMode.js +18 -0
  61. package/plugins/beta/draw-ml/src/modes/drawPolygonMode.js +16 -0
  62. package/plugins/beta/draw-ml/src/modes/editVertex/geometryHelpers.js +135 -0
  63. package/plugins/beta/draw-ml/src/modes/editVertex/helpers.js +2 -0
  64. package/plugins/beta/draw-ml/src/modes/editVertex/touchHandlers.js +134 -0
  65. package/plugins/beta/draw-ml/src/modes/editVertex/undoHandlers.js +133 -0
  66. package/plugins/beta/draw-ml/src/modes/editVertex/vertexOperations.js +141 -0
  67. package/plugins/beta/draw-ml/src/modes/editVertex/vertexQueries.js +121 -0
  68. package/plugins/beta/draw-ml/src/modes/editVertexMode.js +437 -0
  69. package/plugins/{draw-ml → beta/draw-ml}/src/reducer.js +30 -2
  70. package/plugins/{draw-ml → beta/draw-ml}/src/styles.js +66 -36
  71. package/plugins/beta/draw-ml/src/undoStack.js +50 -0
  72. package/plugins/beta/draw-ml/src/utils/debounce.js +16 -0
  73. package/plugins/beta/draw-ml/src/utils/flattenStyleProperties.js +49 -0
  74. package/plugins/beta/draw-ml/src/utils/spatial.js +258 -0
  75. package/plugins/beta/frame/dist/esm/im-frame-plugin.js +1 -0
  76. package/plugins/beta/frame/dist/esm/index.js +2 -0
  77. package/plugins/beta/frame/dist/umd/im-frame-plugin.js +1 -0
  78. package/plugins/beta/frame/dist/umd/index.js +2 -0
  79. package/plugins/{frame → beta/frame}/src/Frame.jsx +1 -1
  80. package/plugins/{map-styles → beta/map-styles}/dist/css/index.css +1 -1
  81. package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -0
  82. package/plugins/beta/map-styles/dist/esm/index.js +2 -0
  83. package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -0
  84. package/plugins/beta/map-styles/dist/umd/index.js +2 -0
  85. package/plugins/{map-styles → beta/map-styles}/src/MapStyles.jsx +1 -1
  86. package/plugins/{map-styles → beta/map-styles}/src/manifest.js +8 -10
  87. package/plugins/{map-styles → beta/map-styles}/src/mapStyles.scss +4 -1
  88. package/plugins/beta/scale-bar/dist/esm/im-scale-bar-plugin.js +1 -0
  89. package/plugins/beta/scale-bar/dist/esm/index.js +2 -0
  90. package/plugins/beta/scale-bar/dist/umd/im-scale-bar-plugin.js +1 -0
  91. package/plugins/beta/scale-bar/dist/umd/index.js +2 -0
  92. package/plugins/beta/use-location/dist/esm/im-use-location-plugin.js +1 -0
  93. package/plugins/beta/use-location/dist/esm/index.js +2 -0
  94. package/plugins/beta/use-location/dist/umd/im-use-location-plugin.js +1 -0
  95. package/plugins/beta/use-location/dist/umd/index.js +2 -0
  96. package/plugins/interact/dist/css/index.css +1 -1
  97. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  98. package/plugins/interact/dist/esm/index.js +1 -1
  99. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  100. package/plugins/interact/dist/umd/index.js +1 -1
  101. package/plugins/interact/src/InteractInit.jsx +1 -1
  102. package/plugins/interact/src/InteractInit.test.js +97 -0
  103. package/plugins/interact/src/api/clear.test.js +18 -0
  104. package/plugins/interact/src/api/disable.test.js +12 -0
  105. package/plugins/interact/src/api/enable.test.js +48 -0
  106. package/plugins/interact/src/api/selectFeature.test.js +33 -0
  107. package/plugins/interact/src/api/unselectFeature.test.js +33 -0
  108. package/plugins/interact/src/defaults.js +2 -0
  109. package/plugins/interact/src/events.js +37 -52
  110. package/plugins/interact/src/events.test.js +186 -0
  111. package/plugins/interact/src/hooks/useHighlightSync.js +1 -1
  112. package/plugins/interact/src/hooks/useHighlightSync.test.js +212 -0
  113. package/plugins/interact/src/hooks/useInteractionHandlers.js +80 -41
  114. package/plugins/interact/src/hooks/useInteractionHandlers.test.js +316 -0
  115. package/plugins/interact/src/index.test.js +22 -0
  116. package/plugins/interact/src/interact.scss +6 -0
  117. package/plugins/interact/src/manifest.js +1 -1
  118. package/plugins/interact/src/manifest.test.js +94 -0
  119. package/plugins/interact/src/reducer.js +28 -21
  120. package/plugins/interact/src/reducer.test.js +155 -0
  121. package/plugins/interact/src/utils/buildStylesMap.test.js +57 -0
  122. package/plugins/interact/src/utils/featureQueries.js +2 -2
  123. package/plugins/interact/src/utils/featureQueries.test.js +56 -0
  124. package/plugins/interact/src/utils/spatial.js +95 -0
  125. package/plugins/interact/src/utils/spatial.test.js +93 -0
  126. package/plugins/search/dist/css/index.css +1 -1
  127. package/plugins/search/dist/esm/im-search-plugin.js +1 -1
  128. package/plugins/search/dist/esm/index.js +1 -1
  129. package/plugins/search/dist/umd/im-search-plugin.js +1 -1
  130. package/plugins/search/dist/umd/index.js +1 -1
  131. package/plugins/search/src/Search.jsx +2 -2
  132. package/plugins/search/src/components/Form/Form.jsx +1 -1
  133. package/plugins/search/src/components/Suggestions/Suggestions.jsx +5 -5
  134. package/plugins/search/src/datasets.js +1 -1
  135. package/plugins/search/src/defaults.js +3 -0
  136. package/plugins/search/src/events/fetchSuggestions.js +48 -53
  137. package/plugins/search/src/events/formHandlers.js +3 -2
  138. package/plugins/search/src/events/index.js +1 -1
  139. package/plugins/search/src/events/inputHandlers.js +3 -1
  140. package/plugins/search/src/events/suggestionHandlers.js +12 -3
  141. package/plugins/search/src/search.scss +4 -1
  142. package/plugins/search/src/utils/parseOsNamesResults.js +15 -19
  143. package/providers/{esri → beta/esri}/src/esriProvider.js +1 -1
  144. package/providers/{esri → beta/esri}/src/index.js +1 -1
  145. package/providers/{esri → beta/esri}/src/mapEvents.js +2 -2
  146. package/providers/beta/open-names/dist/esm/im-reverse-geocode.js +2 -0
  147. package/providers/beta/open-names/dist/esm/index.js +2 -0
  148. package/providers/beta/open-names/dist/umd/im-reverse-geocode.js +2 -0
  149. package/providers/beta/open-names/dist/umd/im-reverse-geocode.js.LICENSE.txt +1 -0
  150. package/providers/beta/open-names/dist/umd/index.js +2 -0
  151. package/providers/beta/open-names/dist/umd/index.js.LICENSE.txt +1 -0
  152. package/providers/maplibre/dist/esm/im-maplibre-framework.js +1 -1
  153. package/providers/maplibre/dist/esm/im-maplibre-framework.js.LICENSE.txt +1 -1
  154. package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
  155. package/providers/maplibre/dist/esm/index.js +1 -1
  156. package/providers/maplibre/dist/umd/im-maplibre-framework.js +1 -1
  157. package/providers/maplibre/dist/umd/im-maplibre-framework.js.LICENSE.txt +1 -1
  158. package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
  159. package/providers/maplibre/dist/umd/index.js +1 -1
  160. package/providers/maplibre/src/defaults.js +3 -2
  161. package/providers/maplibre/src/index.js +36 -20
  162. package/providers/maplibre/src/maplibreProvider.js +140 -11
  163. package/providers/maplibre/src/utils/detectWebgl.js +1 -2
  164. package/providers/maplibre/src/utils/highlightFeatures.js +78 -67
  165. package/providers/maplibre/src/utils/labels.js +174 -120
  166. package/providers/maplibre/src/utils/maplibreFixes.js +2 -2
  167. package/providers/maplibre/src/utils/queryFeatures.js +146 -0
  168. package/providers/maplibre/src/utils/spatial.js +14 -17
  169. package/sonar-project.properties +40 -3
  170. package/src/App/components/Actions/Actions.jsx +2 -2
  171. package/src/App/components/Actions/Actions.module.scss +2 -2
  172. package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +3 -1
  173. package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +9 -0
  174. package/src/App/components/Logo/Logo.jsx +1 -1
  175. package/src/App/components/MapButton/MapButton.jsx +217 -41
  176. package/src/App/components/MapButton/MapButton.module.scss +32 -21
  177. package/src/App/components/MapButton/MapButton.test.jsx +128 -84
  178. package/src/App/components/Markers/Markers.jsx +1 -1
  179. package/src/App/components/Markers/Markers.module.scss +0 -5
  180. package/src/App/components/Panel/Panel.jsx +75 -45
  181. package/src/App/components/Panel/Panel.module.scss +18 -24
  182. package/src/App/components/Panel/Panel.test.jsx +18 -0
  183. package/src/App/components/PopupMenu/PopupMenu.jsx +246 -0
  184. package/src/App/components/PopupMenu/PopupMenu.module.scss +70 -0
  185. package/src/App/components/PopupMenu/PopupMenu.test.jsx +304 -0
  186. package/src/App/components/Tooltip/Tooltip.jsx +4 -2
  187. package/src/App/components/Tooltip/getTooltipPosition.js +1 -1
  188. package/src/App/components/Viewport/MapController.jsx +1 -1
  189. package/src/App/components/Viewport/MapStatus.jsx +1 -1
  190. package/src/App/components/Viewport/Viewport.jsx +2 -2
  191. package/src/App/components/Viewport/Viewport.module.scss +2 -2
  192. package/src/App/controls/keyboardActions.js +3 -2
  193. package/src/App/controls/keyboardShortcuts.js +4 -2
  194. package/src/App/hooks/useButtonStateEvaluator.js +58 -45
  195. package/src/App/hooks/useButtonStateEvaluator.test.js +36 -3
  196. package/src/App/hooks/useCrossHairAPI.js +49 -47
  197. package/src/App/hooks/useFocusVisible.js +2 -2
  198. package/src/App/hooks/useInterfaceAPI.js +36 -1
  199. package/src/App/hooks/useKeyboardHint.js +1 -1
  200. package/src/App/hooks/useKeyboardShortcuts.js +4 -2
  201. package/src/App/hooks/useMapAnnouncements.js +34 -32
  202. package/src/App/hooks/useMapEvents.js +12 -1
  203. package/src/App/hooks/useMapProviderOverrides.js +3 -3
  204. package/src/App/hooks/useMapStateSync.js +7 -1
  205. package/src/App/hooks/useMapURLSync.js +6 -1
  206. package/src/App/hooks/useMarkersAPI.js +88 -50
  207. package/src/App/hooks/useMediaQueryDispatch.test.js +48 -0
  208. package/src/App/hooks/useModalPanelBehaviour.js +46 -40
  209. package/src/App/hooks/useResizeObserver.js +2 -2
  210. package/src/App/initialiseApp.js +45 -38
  211. package/src/App/layout/Layout.jsx +6 -4
  212. package/src/App/layout/layout.module.scss +13 -17
  213. package/src/App/registry/keyboardShortcutRegistry.js +12 -2
  214. package/src/App/registry/keyboardShortcutRegistry.test.js +28 -0
  215. package/src/App/registry/mergeManifests.js +1 -1
  216. package/src/App/registry/panelRegistry.js +1 -1
  217. package/src/App/registry/panelRegistry.test.js +30 -1
  218. package/src/App/registry/pluginRegistry.js +14 -51
  219. package/src/App/registry/pluginRegistry.test.js +54 -6
  220. package/src/App/renderer/HtmlElementHost.jsx +186 -0
  221. package/src/App/renderer/HtmlElementHost.test.jsx +231 -0
  222. package/src/App/renderer/mapButtons.js +12 -9
  223. package/src/App/renderer/mapButtons.test.js +6 -4
  224. package/src/App/renderer/mapControls.js +6 -0
  225. package/src/App/renderer/mapControls.test.js +10 -2
  226. package/src/App/renderer/mapPanels.js +39 -26
  227. package/src/App/renderer/mapPanels.test.js +29 -0
  228. package/src/App/renderer/pluginWrapper.test.js +28 -0
  229. package/src/App/renderer/slotHelpers.js +60 -0
  230. package/src/App/renderer/slotHelpers.test.js +82 -0
  231. package/src/App/store/AppProvider.jsx +3 -0
  232. package/src/App/store/AppProvider.test.jsx +40 -0
  233. package/src/App/store/PluginProvider.jsx +7 -5
  234. package/src/App/store/appActionsMap.js +46 -1
  235. package/src/App/store/appActionsMap.test.js +21 -0
  236. package/src/App/store/appReducer.js +1 -0
  237. package/src/App/store/mapActionsMap.js +12 -24
  238. package/src/App/store/mapReducer.js +1 -1
  239. package/src/InteractiveMap/InteractiveMap.js +194 -13
  240. package/src/InteractiveMap/InteractiveMap.test.js +164 -2
  241. package/src/InteractiveMap/behaviourController.js +12 -2
  242. package/src/InteractiveMap/behaviourController.test.js +82 -1
  243. package/src/InteractiveMap/deviceChecker.js +1 -1
  244. package/src/InteractiveMap/deviceChecker.test.js +2 -2
  245. package/src/InteractiveMap/historyManager.js +41 -5
  246. package/src/InteractiveMap/historyManager.test.js +37 -6
  247. package/src/InteractiveMap/polyfills.js +39 -0
  248. package/src/InteractiveMap/polyfills.test.js +127 -0
  249. package/src/config/appConfig.js +5 -5
  250. package/src/config/appConfig.test.js +107 -42
  251. package/src/config/defaults.js +30 -20
  252. package/src/config/events.js +110 -4
  253. package/src/index.js +5 -2
  254. package/src/index.umd.js +1 -1
  255. package/src/scss/main.scss +1 -0
  256. package/src/scss/settings/_dimensions.scss +6 -2
  257. package/src/scss/tools/_border-focus.scss +20 -4
  258. package/src/services/eventBus.test.js +24 -1
  259. package/src/test-utils.js +1 -0
  260. package/src/types.js +590 -0
  261. package/src/utils/detectBreakpoint.js +78 -77
  262. package/src/utils/detectBreakpoint.test.js +50 -4
  263. package/src/utils/detectInterfaceType.js +4 -4
  264. package/src/utils/getIsFullscreen.js +3 -1
  265. package/src/utils/getSafeZoneInset.js +23 -7
  266. package/src/utils/getSafeZoneInset.test.js +18 -0
  267. package/src/utils/mapStateSync.js +3 -3
  268. package/src/utils/queryString.js +1 -1
  269. package/src/utils/stringToKebab.js +1 -1
  270. package/src/utils/toggleInertElements.js +37 -12
  271. package/webpack.dev.mjs +3 -4
  272. package/webpack.esm.mjs +8 -8
  273. package/webpack.umd.mjs +8 -8
  274. package/plugins/datasets/dist/esm/im-datasets-plugin.js +0 -1
  275. package/plugins/datasets/dist/esm/index.js +0 -2
  276. package/plugins/datasets/dist/umd/im-datasets-plugin.js +0 -1
  277. package/plugins/datasets/dist/umd/index.js +0 -2
  278. package/plugins/datasets/src/datasets.js +0 -60
  279. package/plugins/datasets/src/utils/bbox.js +0 -4
  280. package/plugins/draw-ml/dist/css/index.css +0 -1
  281. package/plugins/draw-ml/dist/esm/im-draw-ml-plugin.js +0 -1
  282. package/plugins/draw-ml/dist/esm/index.js +0 -2
  283. package/plugins/draw-ml/dist/umd/im-draw-ml-plugin.js +0 -1
  284. package/plugins/draw-ml/dist/umd/index.js +0 -2
  285. package/plugins/draw-ml/src/api/addFeature.js +0 -15
  286. package/plugins/draw-ml/src/api/newPolygon.js +0 -43
  287. package/plugins/draw-ml/src/draw.scss +0 -9
  288. package/plugins/draw-ml/src/events.js +0 -127
  289. package/plugins/draw-ml/src/manifest.js +0 -100
  290. package/plugins/draw-ml/src/modes/drawVertexMode.js +0 -275
  291. package/plugins/draw-ml/src/modes/editVertexMode.js +0 -426
  292. package/plugins/draw-ml/src/utils.js +0 -102
  293. package/plugins/frame/dist/esm/im-frame-plugin.js +0 -1
  294. package/plugins/frame/dist/esm/index.js +0 -2
  295. package/plugins/frame/dist/umd/im-frame-plugin.js +0 -1
  296. package/plugins/frame/dist/umd/index.js +0 -2
  297. package/plugins/map-styles/dist/esm/im-map-styles-plugin.js +0 -1
  298. package/plugins/map-styles/dist/esm/index.js +0 -2
  299. package/plugins/map-styles/dist/umd/im-map-styles-plugin.js +0 -1
  300. package/plugins/map-styles/dist/umd/index.js +0 -2
  301. package/plugins/scale-bar/dist/esm/im-scale-bar-plugin.js +0 -1
  302. package/plugins/scale-bar/dist/esm/index.js +0 -2
  303. package/plugins/scale-bar/dist/umd/im-scale-bar-plugin.js +0 -1
  304. package/plugins/scale-bar/dist/umd/index.js +0 -2
  305. package/plugins/search/src/utils/fetchDataset.js +0 -23
  306. package/plugins/use-location/dist/esm/im-use-location-plugin.js +0 -1
  307. package/plugins/use-location/dist/esm/index.js +0 -2
  308. package/plugins/use-location/dist/umd/im-use-location-plugin.js +0 -1
  309. package/plugins/use-location/dist/umd/index.js +0 -2
  310. package/providers/maplibre/dist/esm/im-maplibre-legacy-framework.js +0 -1
  311. package/providers/maplibre/dist/umd/im-maplibre-legacy-framework.js +0 -1
  312. package/providers/open-names/dist/esm/im-reverse-geocode.js +0 -2
  313. package/providers/open-names/dist/esm/index.js +0 -2
  314. package/providers/open-names/dist/umd/im-reverse-geocode.js +0 -2
  315. package/providers/open-names/dist/umd/index.js +0 -2
  316. /package/docs/architecture/{ARCHITECTURE_DIAGRAMS.md → architecture-diagrams.md} +0 -0
  317. /package/plugins/{datasets → beta/datasets}/dist/css/index.css +0 -0
  318. /package/plugins/{datasets/dist/esm/index.js.LICENSE.txt → beta/datasets/dist/esm/im-datasets-plugin.js.LICENSE.txt} +0 -0
  319. /package/plugins/{datasets/dist/umd → beta/datasets/dist/esm}/index.js.LICENSE.txt +0 -0
  320. /package/plugins/{draw-ml/dist/esm/index.js.LICENSE.txt → beta/datasets/dist/umd/im-datasets-plugin.js.LICENSE.txt} +0 -0
  321. /package/plugins/{draw-ml → beta/datasets}/dist/umd/index.js.LICENSE.txt +0 -0
  322. /package/plugins/{datasets → beta/datasets}/src/DatasetsInit.jsx +0 -0
  323. /package/plugins/{datasets → beta/datasets}/src/api/addDataset.js +0 -0
  324. /package/plugins/{datasets → beta/datasets}/src/api/hideDataset.js +0 -0
  325. /package/plugins/{datasets → beta/datasets}/src/api/hideFeatures.js +0 -0
  326. /package/plugins/{datasets → beta/datasets}/src/api/removeDataset.js +0 -0
  327. /package/plugins/{datasets → beta/datasets}/src/api/showDataset.js +0 -0
  328. /package/plugins/{datasets → beta/datasets}/src/api/showFeatures.js +0 -0
  329. /package/plugins/{datasets → beta/datasets}/src/datasets.scss +0 -0
  330. /package/plugins/{datasets → beta/datasets}/src/defaults.js +0 -0
  331. /package/plugins/{datasets → beta/datasets}/src/index.js +0 -0
  332. /package/plugins/{datasets → beta/datasets}/src/panels/Key.module.scss +0 -0
  333. /package/plugins/{datasets → beta/datasets}/src/panels/Layers.jsx +0 -0
  334. /package/plugins/{datasets → beta/datasets}/src/panels/Layers.module.scss +0 -0
  335. /package/plugins/{datasets → beta/datasets}/src/reducer.js +0 -0
  336. /package/plugins/{datasets → beta/datasets}/src/utils/debounce.js +0 -0
  337. /package/plugins/{datasets → beta/datasets}/src/utils/filters.js +0 -0
  338. /package/plugins/{draw-es → beta/draw-es}/src/DrawInit.jsx +0 -0
  339. /package/plugins/{draw-es → beta/draw-es}/src/api/addFeature.js +0 -0
  340. /package/plugins/{draw-es → beta/draw-es}/src/api/deleteFeature.js +0 -0
  341. /package/plugins/{draw-es → beta/draw-es}/src/api/editFeature.js +0 -0
  342. /package/plugins/{draw-es → beta/draw-es}/src/api/newPolygon.js +0 -0
  343. /package/plugins/{draw-es → beta/draw-es}/src/events.js +0 -0
  344. /package/plugins/{draw-es → beta/draw-es}/src/graphic.js +0 -0
  345. /package/plugins/{draw-es → beta/draw-es}/src/index.js +0 -0
  346. /package/plugins/{draw-es → beta/draw-es}/src/manifest.js +0 -0
  347. /package/plugins/{draw-es → beta/draw-es}/src/reducer.js +0 -0
  348. /package/plugins/{draw-es → beta/draw-es}/src/sketchViewModel.js +0 -0
  349. /package/plugins/{frame → beta/draw-ml}/dist/esm/index.js.LICENSE.txt +0 -0
  350. /package/plugins/{frame → beta/draw-ml}/dist/umd/index.js.LICENSE.txt +0 -0
  351. /package/plugins/{draw-ml → beta/draw-ml}/src/DrawInit.jsx +0 -0
  352. /package/plugins/{draw-ml → beta/draw-ml}/src/api/deleteFeature.js +0 -0
  353. /package/plugins/{draw-ml → beta/draw-ml}/src/index.js +0 -0
  354. /package/plugins/{draw-ml → beta/draw-ml}/src/modes/disabledMode.js +0 -0
  355. /package/plugins/{draw-ml/src → beta/draw-ml/src/utils}/snapHelpers.js +0 -0
  356. /package/plugins/{frame → beta/frame}/dist/css/index.css +0 -0
  357. /package/plugins/{map-styles → beta/frame}/dist/esm/index.js.LICENSE.txt +0 -0
  358. /package/plugins/{map-styles → beta/frame}/dist/umd/index.js.LICENSE.txt +0 -0
  359. /package/plugins/{frame → beta/frame}/package.json +0 -0
  360. /package/plugins/{frame → beta/frame}/src/FrameInit.jsx +0 -0
  361. /package/plugins/{frame → beta/frame}/src/api/addFrame.js +0 -0
  362. /package/plugins/{frame → beta/frame}/src/api/editFeature.js +0 -0
  363. /package/plugins/{frame → beta/frame}/src/config.js +0 -0
  364. /package/plugins/{frame → beta/frame}/src/frame.scss +0 -0
  365. /package/plugins/{frame → beta/frame}/src/index.js +0 -0
  366. /package/plugins/{frame → beta/frame}/src/manifest.js +0 -0
  367. /package/plugins/{frame → beta/frame}/src/reducer.js +0 -0
  368. /package/plugins/{frame → beta/frame}/src/utils.js +0 -0
  369. /package/plugins/{scale-bar → beta/map-styles}/dist/esm/index.js.LICENSE.txt +0 -0
  370. /package/plugins/{scale-bar → beta/map-styles}/dist/umd/index.js.LICENSE.txt +0 -0
  371. /package/plugins/{map-styles → beta/map-styles}/src/MapStylesInit.jsx +0 -0
  372. /package/plugins/{map-styles → beta/map-styles}/src/config.js +0 -0
  373. /package/plugins/{map-styles → beta/map-styles}/src/index.js +0 -0
  374. /package/plugins/{scale-bar → beta/scale-bar}/dist/css/index.css +0 -0
  375. /package/plugins/{use-location → beta/scale-bar}/dist/esm/index.js.LICENSE.txt +0 -0
  376. /package/plugins/{use-location → beta/scale-bar}/dist/umd/index.js.LICENSE.txt +0 -0
  377. /package/plugins/{scale-bar → beta/scale-bar}/package.json +0 -0
  378. /package/plugins/{scale-bar → beta/scale-bar}/src/ScaleBar.jsx +0 -0
  379. /package/plugins/{scale-bar → beta/scale-bar}/src/ScaleBar.test.jsx +0 -0
  380. /package/plugins/{scale-bar → beta/scale-bar}/src/index.js +0 -0
  381. /package/plugins/{scale-bar → beta/scale-bar}/src/index.test.js +0 -0
  382. /package/plugins/{scale-bar → beta/scale-bar}/src/manifest.js +0 -0
  383. /package/plugins/{scale-bar → beta/scale-bar}/src/scaleBar.scss +0 -0
  384. /package/plugins/{scale-bar → beta/scale-bar}/src/utils.js +0 -0
  385. /package/plugins/{scale-bar → beta/scale-bar}/src/utils.test.js +0 -0
  386. /package/{providers/open-names → plugins/beta/use-location}/dist/esm/index.js.LICENSE.txt +0 -0
  387. /package/{providers/open-names → plugins/beta/use-location}/dist/umd/index.js.LICENSE.txt +0 -0
  388. /package/plugins/{use-location → beta/use-location}/src/UseLocation.jsx +0 -0
  389. /package/plugins/{use-location → beta/use-location}/src/UseLocationInit.jsx +0 -0
  390. /package/plugins/{use-location → beta/use-location}/src/defaults.js +0 -0
  391. /package/plugins/{use-location → beta/use-location}/src/events.js +0 -0
  392. /package/plugins/{use-location → beta/use-location}/src/index.js +0 -0
  393. /package/plugins/{use-location → beta/use-location}/src/manifest.js +0 -0
  394. /package/plugins/{use-location → beta/use-location}/src/reducer.js +0 -0
  395. /package/providers/{esri → beta/esri}/src/appEvents.js +0 -0
  396. /package/providers/{esri → beta/esri}/src/defaults.js +0 -0
  397. /package/providers/{esri → beta/esri}/src/esriProvider.scss +0 -0
  398. /package/providers/{esri → beta/esri}/src/utils/coords.js +0 -0
  399. /package/providers/{esri → beta/esri}/src/utils/detectWebGL.js +0 -0
  400. /package/providers/{esri → beta/esri}/src/utils/esriFixes.js +0 -0
  401. /package/providers/{esri → beta/esri}/src/utils/query.js +0 -0
  402. /package/providers/{esri → beta/esri}/src/utils/spatial.js +0 -0
  403. /package/providers/{open-names → beta/open-names}/dist/esm/im-reverse-geocode.js.LICENSE.txt +0 -0
  404. /package/providers/{open-names/dist/umd/im-reverse-geocode.js.LICENSE.txt → beta/open-names/dist/esm/index.js.LICENSE.txt} +0 -0
  405. /package/providers/{open-names → beta/open-names}/src/index.js +0 -0
  406. /package/providers/{open-names → beta/open-names}/src/reverseGeocode.js +0 -0
  407. /package/providers/{open-names → beta/open-names}/src/utils/mapToLocationModel.js +0 -0
@@ -0,0 +1,437 @@
1
+ import DirectSelect from '../../../../../node_modules/@mapbox/mapbox-gl-draw/src/modes/direct_select.js'
2
+ import {
3
+ getSnapInstance, isSnapActive, isSnapEnabled, getSnapLngLat,
4
+ getSnapRadius, triggerSnapAtPoint, clearSnapIndicator, clearSnapState
5
+ } from '../utils/snapHelpers.js'
6
+ import { getCoords, coordPathToFlatIndex } from './editVertex/geometryHelpers.js'
7
+ import { scalePoint } from './editVertex/helpers.js'
8
+ import { undoHandlers } from './editVertex/undoHandlers.js'
9
+ import { touchHandlers } from './editVertex/touchHandlers.js'
10
+ import { vertexOperations } from './editVertex/vertexOperations.js'
11
+ import { vertexQueries } from './editVertex/vertexQueries.js'
12
+
13
+ const ARROW_KEYS = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'])
14
+ const ARROW_OFFSETS = { ArrowUp: [0, -1], ArrowDown: [0, 1], ArrowLeft: [-1, 0], ArrowRight: [1, 0] }
15
+
16
+ export const EditVertexMode = {
17
+ ...DirectSelect,
18
+ ...undoHandlers,
19
+ ...touchHandlers,
20
+ ...vertexOperations,
21
+ ...vertexQueries,
22
+
23
+ onSetup(options) {
24
+ const state = DirectSelect.onSetup.call(this, options)
25
+ Object.assign(state, {
26
+ container: options.container,
27
+ interfaceType: options.interfaceType,
28
+ deleteVertexButtonId: options.deleteVertexButtonId,
29
+ undoButtonId: options.undoButtonId,
30
+ isPanEnabled: options.isPanEnabled,
31
+ getSnapEnabled: options.getSnapEnabled,
32
+ featureId: state.featureId || options.featureId,
33
+ selectedVertexIndex: options.selectedVertexIndex ?? -1,
34
+ selectedVertexType: options.selectedVertexType,
35
+ coordPath: options.coordPath,
36
+ scale: options.scale ?? 1
37
+ })
38
+
39
+ // Get feature type for later reference
40
+ const feature = this.getFeature(state.featureId)
41
+ state.featureType = feature?.type
42
+
43
+ state.vertecies = this.getVerticies(state.featureId)
44
+ state.midpoints = this.getMidpoints(state.featureId)
45
+ this.setupEventListeners(state)
46
+
47
+ if (options.selectedVertexType === 'midpoint') {
48
+ // Clear any vertex selection when switching to midpoint
49
+ state.selectedCoordPaths = []
50
+ this.clearSelectedCoordinates()
51
+ // Force feature re-render to clear vertex highlights
52
+ if (state.feature) {
53
+ state.feature.changed()
54
+ }
55
+ this._ctx.store.render()
56
+ this.updateMidpoint(state.midpoints[options.selectedVertexIndex - state.vertecies.length])
57
+ } else if (options.selectedVertexIndex === -1) {
58
+ // Explicitly clear selection when re-entering with no vertex selected
59
+ state.selectedCoordPaths = []
60
+ this.clearSelectedCoordinates()
61
+ if (state.feature) {
62
+ state.feature.changed()
63
+ }
64
+ this._ctx.store.render()
65
+ }
66
+ this.addTouchVertexTarget(state)
67
+
68
+ // Clear any snap indicator when entering edit mode
69
+ const snap = getSnapInstance(this.map)
70
+ if (snap) {
71
+ clearSnapIndicator(snap, this.map)
72
+ }
73
+
74
+ // Show touch target if entering with a selected vertex on touch interface
75
+ if (state.interfaceType === 'touch' && state.selectedVertexIndex >= 0 && state.selectedVertexType === 'vertex') {
76
+ const vertex = state.vertecies[state.selectedVertexIndex]
77
+ if (vertex) {
78
+ setTimeout(() => {
79
+ this.updateTouchVertexTarget(state, scalePoint(this.map.project(vertex), state.scale))
80
+ }, 0)
81
+ }
82
+ }
83
+
84
+ // Ignore pointermove deselection briefly after setup to let Safari settle
85
+ state._ignorePointermoveDeselect = true
86
+ setTimeout(() => { state._ignorePointermoveDeselect = false }, 100)
87
+
88
+ return state
89
+ },
90
+
91
+ setupEventListeners(state) {
92
+ const bind = (fn) => (e) => fn.call(this, state, e)
93
+ const h = this.handlers = {
94
+ keydown: bind(this.onKeydown), keyup: bind(this.onKeyup),
95
+ pointerdown: bind(this.onPointerevent), pointermove: bind(this.onPointerevent), pointerup: bind(this.onPointerevent),
96
+ click: bind(this.onButtonClick),
97
+ touchstart: bind(this.onTouchstart), touchmove: bind(this.onTouchmove), touchend: bind(this.onTouchend),
98
+ selectionchange: bind(this.onSelectionChange), scalechange: bind(this.onScaleChange),
99
+ update: bind(this.onUpdate), move: bind(this.onMove)
100
+ }
101
+
102
+ window.addEventListener('keydown', h.keydown, { capture: true })
103
+ window.addEventListener('keyup', h.keyup, { capture: true })
104
+ window.addEventListener('click', h.click)
105
+ state.container.addEventListener('pointerdown', h.pointerdown)
106
+ state.container.addEventListener('pointermove', h.pointermove)
107
+ state.container.addEventListener('pointerup', h.pointerup)
108
+ state.container.addEventListener('touchstart', h.touchstart, { passive: false })
109
+ state.container.addEventListener('touchmove', h.touchmove, { passive: false })
110
+ state.container.addEventListener('touchend', h.touchend, { passive: false })
111
+ this.map.on('draw.selectionchange', h.selectionchange)
112
+ this.map.on('draw.scalechange', h.scalechange)
113
+ this.map.on('draw.update', h.update)
114
+ this.map.on('move', h.move)
115
+ },
116
+
117
+ onSelectionChange(state, e) {
118
+ const vertexCoord = e.points[e.points.length - 1]?.geometry.coordinates
119
+
120
+ // Only update selectedVertexIndex from event if not keyboard mode AND event has valid vertex
121
+ // For keyboard mode or when we have coordPath, trust the existing selectedVertexIndex
122
+ if (state.interfaceType !== 'keyboard' && vertexCoord && !state.coordPath) {
123
+ // No coordPath available - need to search for vertex by coordinates
124
+ const geom = e.features[0]?.geometry
125
+ const coords = getCoords(geom)
126
+ state.selectedVertexIndex = this.findVertexIndex(coords, vertexCoord, state.selectedVertexIndex)
127
+ }
128
+ // If we have coordPath, selectedVertexIndex is already correct from onTap/changeMode
129
+
130
+ state.selectedVertexType ??= state.selectedVertexIndex >= 0 ? 'vertex' : null
131
+
132
+ this.map.fire('draw.vertexselection', {
133
+ index: state.selectedVertexType === 'vertex' ? state.selectedVertexIndex : -1,
134
+ numVertecies: state.vertecies.length
135
+ })
136
+
137
+ // Use vertex from event if available, otherwise fall back to state
138
+ const vertex = vertexCoord || (state.selectedVertexIndex >= 0 ? state.vertecies[state.selectedVertexIndex] : null)
139
+ this.updateTouchVertexTarget(state, vertex ? scalePoint(this.map.project(vertex), state.scale) : null)
140
+ },
141
+
142
+ onScaleChange(state, e) {
143
+ state.scale = e.scale
144
+ },
145
+
146
+ onUpdate(state) {
147
+ const prev = new Set(state.vertecies.map(c => JSON.stringify(c)))
148
+ if (prev.size === state.vertecies.length) {
149
+ return
150
+ }
151
+ state.selectedVertexIndex = state.vertecies.findIndex(c => !prev.has(JSON.stringify(c)))
152
+ state.selectedVertexType ??= state.selectedVertexIndex >= 0 ? 'vertex' : null
153
+ },
154
+
155
+ onKeydown(state, e) {
156
+ state.interfaceType = 'keyboard'
157
+ this.hideTouchVertexIndicator(state)
158
+
159
+ if (e.key === ' ' && state.selectedVertexIndex < 0) {
160
+ // Clear snap indicator when starting keyboard selection
161
+ const snap = getSnapInstance(this.map)
162
+ if (snap) {
163
+ clearSnapIndicator(snap, this.map)
164
+ }
165
+
166
+ // Ensure we have vertices to select
167
+ if (!state.vertecies?.length) {
168
+ state.vertecies = this.getVerticies(state.featureId)
169
+ state.midpoints = this.getMidpoints(state.featureId)
170
+ }
171
+ if (!state.vertecies?.length) {
172
+ return
173
+ }
174
+ state.isPanEnabled = false
175
+ return this.updateVertex(state)
176
+ }
177
+
178
+ if (!e.altKey && ARROW_KEYS.has(e.key) && state.selectedVertexIndex >= 0) {
179
+ e.preventDefault()
180
+ e.stopPropagation()
181
+ if (state.selectedVertexType === 'midpoint') {
182
+ return this.insertVertex(state, e)
183
+ }
184
+
185
+ const snap = getSnapInstance(this.map)
186
+ const feature = this.getFeature(state.featureId)
187
+ if (!feature) {
188
+ return
189
+ }
190
+ const coords = getCoords(feature)
191
+ const currentCoord = coords?.[state.selectedVertexIndex]
192
+ if (!currentCoord) {
193
+ return
194
+ }
195
+
196
+ // Save starting position for undo (only on first move of sequence)
197
+ if (!state._keyboardMoveStartPosition) {
198
+ state._keyboardMoveStartPosition = [...currentCoord]
199
+ state._keyboardMoveStartIndex = state.selectedVertexIndex
200
+ }
201
+
202
+ // Break out of snap by moving outside snap radius
203
+ if (isSnapEnabled(state) && state._isSnapped && snap) {
204
+ const offset = getSnapRadius(snap) + 1
205
+ const pt = this.map.project(currentCoord)
206
+ const [dx, dy] = ARROW_OFFSETS[e.key].map(v => v * offset)
207
+ state._isSnapped = false
208
+ clearSnapIndicator(snap, this.map)
209
+ return this.moveVertex(state, this.map.unproject({ x: pt.x + dx, y: pt.y + dy }))
210
+ }
211
+
212
+ const newCoord = this.getNewCoord(state, e)
213
+ if (isSnapEnabled(state) && snap) {
214
+ triggerSnapAtPoint(snap, this.map, this.map.project(newCoord))
215
+ if (isSnapActive(snap)) {
216
+ state._isSnapped = true
217
+ return this.moveVertex(state, getSnapLngLat(snap))
218
+ }
219
+ }
220
+ state._isSnapped = false
221
+ return this.moveVertex(state, newCoord)
222
+ }
223
+
224
+ if (e.altKey && ARROW_KEYS.has(e.key) && state.selectedVertexIndex >= 0) {
225
+ e.preventDefault()
226
+ e.stopPropagation()
227
+ return this.updateVertex(state, e.key)
228
+ }
229
+
230
+ if (e.key === 'Escape') {
231
+ this.changeMode(state, { isPanEnabled: true, selectedVertexIndex: -1, selectedVertexType: null })
232
+ }
233
+
234
+ // Undo with Cmd/Ctrl+Z (works without viewport focus, but not in input fields)
235
+ if (e.key === 'z' && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
236
+ const tag = document.activeElement?.tagName
237
+ if (tag === 'INPUT' || tag === 'TEXTAREA') {
238
+ return
239
+ }
240
+ e.preventDefault()
241
+ e.stopPropagation()
242
+ return this.handleUndo(state)
243
+ }
244
+ },
245
+
246
+ onKeyup(state, e) {
247
+ state.interfaceType = 'keyboard'
248
+ if (ARROW_KEYS.has(e.key) && state.selectedVertexIndex >= 0) {
249
+ e.stopPropagation()
250
+
251
+ // Push undo for keyboard move sequence
252
+ if (state._keyboardMoveStartPosition && state._keyboardMoveStartIndex !== undefined) {
253
+ this.pushUndo({
254
+ type: 'move_vertex',
255
+ featureId: state.featureId,
256
+ vertexIndex: state._keyboardMoveStartIndex,
257
+ previousPosition: state._keyboardMoveStartPosition
258
+ })
259
+ state._keyboardMoveStartPosition = null
260
+ state._keyboardMoveStartIndex = undefined
261
+ }
262
+ }
263
+ if (e.key === 'Delete') {
264
+ this.deleteVertex(state)
265
+ }
266
+ },
267
+
268
+ onMouseDown(state, e) {
269
+ clearSnapState(getSnapInstance(this.map))
270
+ const meta = e.featureTarget?.properties.meta
271
+ const coordPath = e.featureTarget?.properties.coord_path
272
+
273
+ if (['vertex', 'midpoint'].includes(meta)) {
274
+ state.dragMoveLocation = e.lngLat
275
+ state.dragMoving = false
276
+ DirectSelect.onMouseDown.call(this, state, e)
277
+
278
+ // Update selection state for vertex clicks (so onSelectionChange has correct context)
279
+ if (meta === 'vertex' && coordPath) {
280
+ const feature = this.getFeature(state.featureId)
281
+ const vertexIndex = coordPathToFlatIndex(feature, coordPath)
282
+ state.selectedVertexIndex = vertexIndex
283
+ state.selectedVertexType = 'vertex'
284
+ state.coordPath = coordPath
285
+ const vertex = state.vertecies?.[vertexIndex]
286
+ if (vertex) {
287
+ state._moveStartPosition = [...vertex]
288
+ state._moveStartIndex = vertexIndex
289
+ }
290
+ }
291
+ }
292
+ if (meta === 'midpoint') {
293
+ // DirectSelect converts midpoint to vertex - track this as an insert
294
+ const feature = this.getFeature(state.featureId)
295
+ const insertedIndex = coordPathToFlatIndex(feature, coordPath)
296
+
297
+ // Track this insertion for undo (will be pushed on mouseUp if drag occurred)
298
+ state._insertedVertexIndex = insertedIndex
299
+ state._isInsertingVertex = true
300
+
301
+ state.selectedVertexIndex = this.getVertexIndexFromMidpoint(state, coordPath)
302
+ state.selectedVertexType = 'vertex'
303
+ state.coordPath = null // Clear coordPath for midpoints
304
+ this.map.fire('draw.vertexselection', { index: state.selectedVertexIndex, numVertecies: state.vertecies.length })
305
+ }
306
+ },
307
+
308
+ onMouseUp(state, e) {
309
+ clearSnapState(getSnapInstance(this.map))
310
+
311
+ // Check if vertex actually moved by comparing current position to start position
312
+ // This is more robust than relying on state.dragMoving which can be inconsistent
313
+ // IMPORTANT: Get current position from the feature, not state.vertecies (which is cached)
314
+ let vertexMoved = false
315
+ if (state._moveStartPosition && state._moveStartIndex !== undefined) {
316
+ const feature = this.getFeature(state.featureId)
317
+ if (feature) {
318
+ const currentVertex = getCoords(feature)?.[state._moveStartIndex]
319
+ if (currentVertex) {
320
+ vertexMoved = currentVertex[0] !== state._moveStartPosition[0] ||
321
+ currentVertex[1] !== state._moveStartPosition[1]
322
+ }
323
+ }
324
+ }
325
+
326
+ // Also check for insertions (dragMoving is reliable for midpoint drags)
327
+ const wasInsertion = state._isInsertingVertex && state._insertedVertexIndex !== undefined
328
+
329
+ if (state.dragMoving || vertexMoved || wasInsertion) {
330
+ this.syncVertices(state)
331
+
332
+ // Push undo for vertex insertion (from dragging midpoint)
333
+ if (wasInsertion) {
334
+ this.pushUndo({
335
+ type: 'insert_vertex',
336
+ featureId: state.featureId,
337
+ vertexIndex: state._insertedVertexIndex
338
+ })
339
+ state._isInsertingVertex = false
340
+ state._insertedVertexIndex = undefined
341
+ }
342
+ // Push undo for the move if vertex actually moved
343
+ else if (vertexMoved && state._moveStartPosition && state._moveStartIndex !== undefined) {
344
+ this.pushUndo({
345
+ type: 'move_vertex',
346
+ featureId: state.featureId,
347
+ vertexIndex: state._moveStartIndex,
348
+ previousPosition: state._moveStartPosition
349
+ })
350
+ }
351
+ }
352
+
353
+ // Clean up move state
354
+ state._moveStartPosition = null
355
+ state._moveStartIndex = null
356
+
357
+ DirectSelect.onMouseUp.call(this, state, e)
358
+ },
359
+
360
+ onDrag(state, e) {
361
+ if (state.interfaceType === 'touch') {
362
+ return
363
+ }
364
+
365
+ this.map.fire('draw.geometrychange', state.feature)
366
+
367
+ const snap = getSnapInstance(this.map)
368
+ if (snap) {
369
+ snap.snapStatus = false
370
+ snap.snapCoords = null
371
+ }
372
+
373
+ if (!isSnapEnabled(state) || !snap?.status) {
374
+ DirectSelect.onDrag.call(this, state, e)
375
+ return
376
+ }
377
+
378
+ if (!state.selectedCoordPaths?.length || !state.canDragMove) {
379
+ return
380
+ }
381
+
382
+ state.dragMoving = true
383
+ e.originalEvent.stopPropagation()
384
+ triggerSnapAtPoint(snap, this.map, e.point)
385
+
386
+ const finalLngLat = getSnapLngLat(snap) || e.lngLat
387
+ state.feature.updateCoordinate(state.selectedCoordPaths[0], finalLngLat.lng, finalLngLat.lat)
388
+ state.dragMoveLocation = e.lngLat
389
+ },
390
+
391
+ onMove(state) {
392
+ const vertex = state.vertecies[state.selectedVertexIndex]
393
+ if (vertex) {
394
+ this.updateTouchVertexTarget(state, scalePoint(this.map.project(vertex), state.scale))
395
+ }
396
+ },
397
+
398
+ onButtonClick(state, e) {
399
+ if (e.target.closest(`#${state.deleteVertexButtonId}`) && state.selectedVertexType === 'vertex') {
400
+ this.deleteVertex(state)
401
+ }
402
+ if (e.target.closest(`#${state.undoButtonId}`)) {
403
+ this.handleUndo(state)
404
+ }
405
+ },
406
+
407
+ clickNoTarget(state) {
408
+ this.changeMode(state, { selectedVertexIndex: -1, selectedVertexType: null, isPanEnabled: true })
409
+ },
410
+
411
+ // Prevent selecting other features
412
+ changeMode(state, updates) {
413
+ if (!state.featureId) {
414
+ return
415
+ }
416
+ this._ctx.api.changeMode('edit_vertex', { ...state, ...updates })
417
+ },
418
+
419
+ onStop(state) {
420
+ const h = this.handlers
421
+ state.container.removeEventListener('pointerdown', h.pointerdown)
422
+ state.container.removeEventListener('pointermove', h.pointermove)
423
+ state.container.removeEventListener('pointerup', h.pointerup)
424
+ state.container.removeEventListener('touchstart', h.touchstart)
425
+ state.container.removeEventListener('touchmove', h.touchmove)
426
+ state.container.removeEventListener('touchend', h.touchend)
427
+ this.map.off('draw.selectionchange', h.selectionchange)
428
+ this.map.off('draw.scalechange', h.scalechange)
429
+ this.map.off('draw.update', h.update)
430
+ this.map.off('move', h.move)
431
+ this.map.dragPan.enable()
432
+ window.removeEventListener('click', h.click)
433
+ window.removeEventListener('keydown', h.keydown, { capture: true })
434
+ window.removeEventListener('keyup', h.keyup, { capture: true })
435
+ this.hideTouchVertexIndicator(state)
436
+ }
437
+ }
@@ -1,11 +1,14 @@
1
1
  const initialState = {
2
2
  mode: null,
3
+ action: null, // 'split | merge'
4
+ actionValid: false, // eg. a valid split line for a target feature
3
5
  feature: null,
4
6
  tempFeature: null,
5
7
  selectedVertexIndex: -1,
6
8
  numVertecies: null,
7
9
  snap: false,
8
- hasSnapLayers: false
10
+ hasSnapLayers: false,
11
+ undoStackLength: 0
9
12
  }
10
13
 
11
14
  const setMode = (state, payload) => {
@@ -15,6 +18,14 @@ const setMode = (state, payload) => {
15
18
  }
16
19
  }
17
20
 
21
+ const setAction = (state, payload) => {
22
+ return {
23
+ ...state,
24
+ action: payload.name,
25
+ actionValid: payload.isValid
26
+ }
27
+ }
28
+
18
29
  const setSelectedVertexIndex = (state, payload) => {
19
30
  return {
20
31
  ...state,
@@ -38,6 +49,13 @@ const toggleSnap = (state) => {
38
49
  }
39
50
  }
40
51
 
52
+ const setSnap = (state, payload) => {
53
+ return {
54
+ ...state,
55
+ snap: !!payload
56
+ }
57
+ }
58
+
41
59
  const setHasSnapLayers = (state, payload) => {
42
60
  return {
43
61
  ...state,
@@ -45,12 +63,22 @@ const setHasSnapLayers = (state, payload) => {
45
63
  }
46
64
  }
47
65
 
66
+ const setUndoStackLength = (state, payload) => {
67
+ return {
68
+ ...state,
69
+ undoStackLength: payload
70
+ }
71
+ }
72
+
48
73
  const actions = {
49
74
  SET_MODE: setMode,
75
+ SET_ACTION: setAction,
50
76
  SET_FEATURE: setFeature,
51
77
  SET_SELECTED_VERTEX_INDEX: setSelectedVertexIndex,
52
78
  TOGGLE_SNAP: toggleSnap,
53
- SET_HAS_SNAP_LAYERS: setHasSnapLayers
79
+ SET_SNAP: setSnap,
80
+ SET_HAS_SNAP_LAYERS: setHasSnapLayers,
81
+ SET_UNDO_STACK_LENGTH: setUndoStackLength
54
82
  }
55
83
 
56
84
  export {
@@ -21,7 +21,7 @@ const fillInactive = (mapStyle) => ({
21
21
  const strokeInactive = (mapStyle) => ({
22
22
  id: 'stroke-inactive',
23
23
  type: 'line',
24
- filter: ['all', ['==', '$type', 'Polygon'], ['==', 'active', 'false']],
24
+ filter: ['all', ['any', ['==', '$type', 'Polygon'], ['==', '$type', 'LineString']], ['==', 'active', 'false'], ['!has', 'user_splitter']],
25
25
  layout: { 'line-cap': 'round', 'line-join': 'round' },
26
26
  paint: {
27
27
  'line-color': getUserProp(mapStyle, 'stroke'),
@@ -30,79 +30,105 @@ const strokeInactive = (mapStyle) => ({
30
30
  })
31
31
 
32
32
  // Active lines and fills
33
- const fillActive = (fgColor) => ({
33
+ const fillActive = (foregroundColor) => ({
34
34
  id: 'fill-active',
35
35
  type: 'fill',
36
36
  filter: ['all', ['==', '$type', 'Polygon'], ['==', 'active', 'true']],
37
- paint: { 'fill-color': fgColor, 'fill-opacity': 0.1 }
37
+ paint: { 'fill-color': foregroundColor, 'fill-opacity': 0.1 }
38
38
  })
39
39
 
40
- const strokeActive = (fgColor) => ({
40
+ const strokeActive = (foregroundColor) => ({
41
41
  id: 'stroke-active',
42
42
  type: 'line',
43
- filter: ['all', ['==', '$type', 'Polygon'], ['==', 'active', 'true']],
43
+ filter: ['all', ['any', ['==', '$type', 'Polygon'], ['==', '$type', 'LineString']], ['==', 'active', 'true'], ['!has', 'user_splitter']],
44
+ layout: { 'line-cap': 'round', 'line-join': 'round' },
45
+ paint: { 'line-color': foregroundColor, 'line-width': 2, 'line-opacity': 1 }
46
+ })
47
+
48
+ // Splitter line
49
+ const drawInvalidSplitter = (splitInvalidColor) => ({
50
+ id: 'stroke-invalid-splitter',
51
+ type: 'line',
52
+ filter: ['all', ['==', '$type', 'LineString'], ['==', 'active', 'true'], ['==', 'user_splitter', 'invalid']],
53
+ layout: { 'line-cap': 'round', 'line-join': 'round' },
54
+ paint: {
55
+ 'line-color': splitInvalidColor,
56
+ 'line-width': 2,
57
+ 'line-dasharray': [0.2, 2],
58
+ 'line-opacity': 1
59
+ }
60
+ })
61
+
62
+ const drawValidSplitter = (splitValidColor) => ({
63
+ id: 'stroke-valid-splitter',
64
+ type: 'line',
65
+ filter: ['all', ['==', '$type', 'LineString'], ['==', 'active', 'true'], ['==', 'user_splitter', 'valid']],
44
66
  layout: { 'line-cap': 'round', 'line-join': 'round' },
45
- paint: { 'line-color': fgColor, 'line-width': 2, 'line-opacity': 1 }
67
+ paint: {
68
+ 'line-color': splitValidColor,
69
+ 'line-width': 2,
70
+ 'line-opacity': 1
71
+ }
46
72
  })
47
73
 
48
74
  // Dashed preview line
49
- const drawPreviewLine = (fgColor) => ({
75
+ const drawPreviewLine = (foregroundColor) => ({
50
76
  id: 'stroke-preview-line',
51
77
  type: 'line',
52
- filter: ['all', ['==', '$type', 'LineString'], ['==', 'active', 'true']],
78
+ filter: ['all', ['==', '$type', 'LineString'], ['==', 'active', 'true'], ['!has', 'user_splitter']],
53
79
  layout: { 'line-cap': 'round', 'line-join': 'round' },
54
- paint: { 'line-color': fgColor, 'line-width': 2, 'line-dasharray': [0.2, 2], 'line-opacity': 1 }
80
+ paint: { 'line-color': foregroundColor, 'line-width': 2, 'line-dasharray': [0.2, 2], 'line-opacity': 1 }
55
81
  })
56
82
 
57
83
  // Vertex layers
58
- const vertex = (fgColor) => ({
84
+ const vertex = (foregroundColor) => ({
59
85
  id: 'vertex',
60
86
  type: 'circle',
61
87
  filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'vertex']],
62
- paint: { 'circle-radius': 6, 'circle-color': fgColor }
88
+ paint: { 'circle-radius': 6, 'circle-color': foregroundColor }
63
89
  })
64
90
 
65
- const vertexHalo = (bgColor, hColor) => ({
91
+ const vertexHalo = (backgroundColor, haloColor) => ({
66
92
  id: 'vertex-halo',
67
93
  type: 'circle',
68
94
  filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'vertex'], ['==', 'active', 'true']],
69
- paint: { 'circle-radius': 8, 'circle-stroke-width': 3, 'circle-color': bgColor, 'circle-stroke-color': hColor }
95
+ paint: { 'circle-radius': 8, 'circle-stroke-width': 3, 'circle-color': backgroundColor, 'circle-stroke-color': haloColor }
70
96
  })
71
97
 
72
- const vertexActive = (fgColor) => ({
98
+ const vertexActive = (foregroundColor) => ({
73
99
  id: 'vertex-active',
74
100
  type: 'circle',
75
101
  filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'vertex'], ['==', 'active', 'true']],
76
- paint: { 'circle-radius': 6, 'circle-color': fgColor }
102
+ paint: { 'circle-radius': 6, 'circle-color': foregroundColor }
77
103
  })
78
104
 
79
105
  // Midpoints
80
- const midpoint = (fgColor) => ({
106
+ const midpoint = (foregroundColor) => ({
81
107
  id: 'midpoint',
82
108
  type: 'circle',
83
109
  filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'midpoint']],
84
- paint: { 'circle-radius': 4, 'circle-color': fgColor }
110
+ paint: { 'circle-radius': 4, 'circle-color': foregroundColor }
85
111
  })
86
112
 
87
- const midpointHalo = (bgColor, hColor) => ({
113
+ const midpointHalo = (backgroundColor, haloColor) => ({
88
114
  id: 'midpoint-halo',
89
115
  type: 'circle',
90
116
  filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'midpoint'], ['==', 'active', 'true']],
91
- paint: { 'circle-radius': 6, 'circle-stroke-width': 3, 'circle-color': bgColor, 'circle-stroke-color': hColor }
117
+ paint: { 'circle-radius': 6, 'circle-stroke-width': 3, 'circle-color': backgroundColor, 'circle-stroke-color': haloColor }
92
118
  })
93
119
 
94
- const midpointActive = (fgColor) => ({
120
+ const midpointActive = (foregroundColor) => ({
95
121
  id: 'midpoint-active',
96
122
  type: 'circle',
97
123
  filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'midpoint'], ['==', 'active', 'true']],
98
- paint: { 'circle-radius': 4, 'circle-color': fgColor }
124
+ paint: { 'circle-radius': 4, 'circle-color': foregroundColor }
99
125
  })
100
126
 
101
- const circle = (fgColor) => ({
127
+ const circle = (foregroundColor) => ({
102
128
  id: 'circle',
103
129
  type: 'line',
104
130
  filter: ['==', 'id', 'circle'],
105
- paint: { 'line-color': fgColor, 'line-width': 2, 'line-opacity': 0.8 }
131
+ paint: { 'line-color': foregroundColor, 'line-width': 2, 'line-opacity': 0.8 }
106
132
  })
107
133
 
108
134
  const touchVertexIndicator = () => ({
@@ -113,23 +139,27 @@ const touchVertexIndicator = () => ({
113
139
  })
114
140
 
115
141
  const createDrawStyles = (mapStyle) => {
116
- const fgColor = DEFAULTS.editColorsForeground[getColorScheme(mapStyle)]
117
- const bgColor = DEFAULTS.editColorsBackground[getColorScheme(mapStyle)]
118
- const hColor = DEFAULTS.editColorsHalo[getColorScheme(mapStyle)]
142
+ const foregroundColor = DEFAULTS.editColorsForeground[getColorScheme(mapStyle)]
143
+ const backgroundColor = DEFAULTS.editColorsBackground[getColorScheme(mapStyle)]
144
+ const haloColor = DEFAULTS.editColorsHalo[getColorScheme(mapStyle)]
145
+ const splitInvalidColor = DEFAULTS.splitInvalidColors[getColorScheme(mapStyle)]
146
+ const splitValidColor = DEFAULTS.splitValidColors[getColorScheme(mapStyle)]
119
147
 
120
148
  return [
121
149
  fillInactive(mapStyle),
122
- fillActive(fgColor),
123
- strokeActive(fgColor),
150
+ fillActive(foregroundColor),
151
+ strokeActive(foregroundColor),
124
152
  strokeInactive(mapStyle),
125
- drawPreviewLine(fgColor),
126
- midpoint(fgColor),
127
- midpointHalo(bgColor, hColor),
128
- midpointActive(fgColor),
129
- vertex(fgColor),
130
- vertexHalo(bgColor, hColor),
131
- vertexActive(fgColor),
132
- circle(fgColor),
153
+ drawInvalidSplitter(splitInvalidColor),
154
+ drawValidSplitter(splitValidColor),
155
+ drawPreviewLine(foregroundColor),
156
+ midpoint(foregroundColor),
157
+ midpointHalo(backgroundColor, haloColor),
158
+ midpointActive(foregroundColor),
159
+ vertex(foregroundColor),
160
+ vertexHalo(backgroundColor, haloColor),
161
+ vertexActive(foregroundColor),
162
+ circle(foregroundColor),
133
163
  touchVertexIndicator()
134
164
  ]
135
165
  }