@map-colonies/react-components 3.12.0 → 3.12.2

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 (375) hide show
  1. package/.eslintignore +1 -1
  2. package/.storybook/main.js +13 -13
  3. package/.storybook/manager.js +6 -6
  4. package/.storybook/preview-head.html +21 -21
  5. package/.storybook/preview.js +18 -18
  6. package/.storybook/theme.js +9 -9
  7. package/CHANGELOG.md +559 -538
  8. package/README.md +53 -53
  9. package/dist/autocomplete/autocomplete.css +25 -25
  10. package/dist/autocomplete/autocomplete.d.ts +33 -33
  11. package/dist/autocomplete/autocomplete.js +478 -478
  12. package/dist/autocomplete/index.d.ts +1 -1
  13. package/dist/autocomplete/index.js +5 -5
  14. package/dist/box/box.d.ts +3 -3
  15. package/dist/box/box.js +35 -35
  16. package/dist/box/index.d.ts +1 -1
  17. package/dist/box/index.js +5 -5
  18. package/dist/cesium-map/data-sources/custom.data-source.d.ts +5 -5
  19. package/dist/cesium-map/data-sources/custom.data-source.js +23 -23
  20. package/dist/cesium-map/data-sources/drawings.data-source.d.ts +34 -34
  21. package/dist/cesium-map/data-sources/drawings.data-source.js +187 -187
  22. package/dist/cesium-map/data-sources/index.d.ts +2 -2
  23. package/dist/cesium-map/data-sources/index.js +14 -14
  24. package/dist/cesium-map/entities/entity.d.ts +5 -5
  25. package/dist/cesium-map/entities/entity.description.d.ts +6 -6
  26. package/dist/cesium-map/entities/entity.description.js +27 -27
  27. package/dist/cesium-map/entities/entity.js +23 -23
  28. package/dist/cesium-map/entities/graphics/polygon.graphics.d.ts +5 -5
  29. package/dist/cesium-map/entities/graphics/polygon.graphics.js +23 -23
  30. package/dist/cesium-map/entities/graphics/polyline.graphics.d.ts +5 -5
  31. package/dist/cesium-map/entities/graphics/polyline.graphics.js +23 -23
  32. package/dist/cesium-map/entities/graphics/rectangle.graphics.d.ts +5 -5
  33. package/dist/cesium-map/entities/graphics/rectangle.graphics.js +23 -23
  34. package/dist/cesium-map/entities/index.d.ts +4 -4
  35. package/dist/cesium-map/entities/index.js +16 -16
  36. package/dist/cesium-map/index.d.ts +8 -7
  37. package/dist/cesium-map/index.js +20 -19
  38. package/dist/cesium-map/layers/3d.tileset.d.ts +7 -7
  39. package/dist/cesium-map/layers/3d.tileset.js +43 -43
  40. package/dist/cesium-map/layers/3d.tileset.with.update.d.ts +6 -6
  41. package/dist/cesium-map/layers/3d.tileset.with.update.js +115 -115
  42. package/dist/cesium-map/layers/geojson.layer.d.ts +5 -5
  43. package/dist/cesium-map/layers/geojson.layer.js +23 -23
  44. package/dist/cesium-map/layers/imagery.layer.d.ts +6 -6
  45. package/dist/cesium-map/layers/imagery.layer.js +68 -68
  46. package/dist/cesium-map/layers/index.d.ts +7 -7
  47. package/dist/cesium-map/layers/index.js +19 -19
  48. package/dist/cesium-map/layers/osm.layer.d.ts +9 -9
  49. package/dist/cesium-map/layers/osm.layer.js +36 -36
  50. package/dist/cesium-map/layers/wms.layer.d.ts +9 -9
  51. package/dist/cesium-map/layers/wms.layer.js +36 -36
  52. package/dist/cesium-map/layers/wmts.layer.d.ts +9 -9
  53. package/dist/cesium-map/layers/wmts.layer.js +36 -36
  54. package/dist/cesium-map/layers/xyz.layer.d.ts +9 -9
  55. package/dist/cesium-map/layers/xyz.layer.js +36 -36
  56. package/dist/cesium-map/layers-manager.d.ts +55 -55
  57. package/dist/cesium-map/layers-manager.js +246 -246
  58. package/dist/cesium-map/map-legend/MapLegend.css +135 -135
  59. package/dist/cesium-map/map-legend/MapLegend.d.ts +15 -15
  60. package/dist/cesium-map/map-legend/MapLegend.js +57 -57
  61. package/dist/cesium-map/map-legend/MapLegendList.d.ts +13 -13
  62. package/dist/cesium-map/map-legend/MapLegendList.js +43 -43
  63. package/dist/cesium-map/map-legend/MapLegendSidebar.d.ts +16 -16
  64. package/dist/cesium-map/map-legend/MapLegendSidebar.js +20 -20
  65. package/dist/cesium-map/map-legend/MapLegendToggle.d.ts +7 -7
  66. package/dist/cesium-map/map-legend/MapLegendToggle.js +20 -20
  67. package/dist/cesium-map/map-legend/index.d.ts +3 -3
  68. package/dist/cesium-map/map-legend/index.js +14 -14
  69. package/dist/cesium-map/map.css +59 -59
  70. package/dist/cesium-map/map.d.ts +59 -61
  71. package/dist/cesium-map/map.js +305 -303
  72. package/dist/cesium-map/map.types.d.ts +8 -8
  73. package/dist/cesium-map/map.types.js +12 -12
  74. package/dist/cesium-map/proxied.types.d.ts +30 -22
  75. package/dist/cesium-map/proxied.types.js +132 -100
  76. package/dist/cesium-map/settings/base-maps.css +37 -37
  77. package/dist/cesium-map/settings/base-maps.d.ts +7 -7
  78. package/dist/cesium-map/settings/base-maps.js +78 -78
  79. package/dist/cesium-map/settings/scene-modes.css +19 -19
  80. package/dist/cesium-map/settings/scene-modes.d.ts +7 -7
  81. package/dist/cesium-map/settings/scene-modes.js +65 -65
  82. package/dist/cesium-map/settings/settings.css +52 -52
  83. package/dist/cesium-map/settings/settings.d.ts +23 -23
  84. package/dist/cesium-map/settings/settings.js +79 -79
  85. package/dist/cesium-map/terrain-providers/custom/dummy-quantized-mesh-tile.d.ts +3 -3
  86. package/dist/cesium-map/terrain-providers/custom/dummy-quantized-mesh-tile.js +245 -245
  87. package/dist/cesium-map/terrain-providers/custom/quantized-mesh-decoder.d.ts +9 -9
  88. package/dist/cesium-map/terrain-providers/custom/quantized-mesh-decoder.js +202 -202
  89. package/dist/cesium-map/terrain-providers/custom/quantized-mesh-terrain-provider.d.ts +50 -50
  90. package/dist/cesium-map/terrain-providers/custom/quantized-mesh-terrain-provider.js +136 -136
  91. package/dist/cesium-map/tools/cesium/primitives-conversions.cesium.d.ts +2 -2
  92. package/dist/cesium-map/tools/cesium/primitives-conversions.cesium.js +38 -38
  93. package/dist/cesium-map/tools/coordinates-tracker.tool.css +11 -11
  94. package/dist/cesium-map/tools/coordinates-tracker.tool.d.ts +7 -7
  95. package/dist/cesium-map/tools/coordinates-tracker.tool.js +78 -78
  96. package/dist/cesium-map/tools/draw/drawHelper.css +101 -101
  97. package/dist/cesium-map/tools/draw/drawHelper.d.ts +28 -28
  98. package/dist/cesium-map/tools/draw/drawHelper.js +1694 -1694
  99. package/dist/cesium-map/tools/geojson/geojson-to-primitive.d.ts +4 -4
  100. package/dist/cesium-map/tools/geojson/geojson-to-primitive.js +41 -41
  101. package/dist/cesium-map/tools/geojson/index.d.ts +2 -2
  102. package/dist/cesium-map/tools/geojson/index.js +14 -14
  103. package/dist/cesium-map/tools/geojson/point.geojson.d.ts +3 -3
  104. package/dist/cesium-map/tools/geojson/point.geojson.js +21 -21
  105. package/dist/cesium-map/tools/geojson/polygon.geojson.d.ts +3 -3
  106. package/dist/cesium-map/tools/geojson/polygon.geojson.js +24 -24
  107. package/dist/cesium-map/tools/geojson/rectangle.geojson.d.ts +3 -3
  108. package/dist/cesium-map/tools/geojson/rectangle.geojson.js +44 -44
  109. package/dist/cesium-map/tools/inspector.tool.d.ts +4 -4
  110. package/dist/cesium-map/tools/inspector.tool.js +33 -33
  111. package/dist/cesium-map/tools/scale-tracker.tool.css +16 -16
  112. package/dist/cesium-map/tools/scale-tracker.tool.d.ts +8 -8
  113. package/dist/cesium-map/tools/scale-tracker.tool.js +158 -158
  114. package/dist/cesium-map/tools/terranian-height.tool.d.ts +4 -4
  115. package/dist/cesium-map/tools/terranian-height.tool.js +114 -114
  116. package/dist/cssbaseline/cssbaseline.d.ts +5 -5
  117. package/dist/cssbaseline/cssbaseline.js +41 -41
  118. package/dist/cssbaseline/index.d.ts +1 -1
  119. package/dist/cssbaseline/index.js +6 -6
  120. package/dist/date-picker/date-picker.css +9 -9
  121. package/dist/date-picker/date-picker.d.ts +14 -14
  122. package/dist/date-picker/date-picker.js +78 -78
  123. package/dist/date-picker/index.d.ts +1 -1
  124. package/dist/date-picker/index.js +13 -13
  125. package/dist/date-range-picker/date-range-picker.css +9 -9
  126. package/dist/date-range-picker/date-range-picker.d.ts +26 -26
  127. package/dist/date-range-picker/date-range-picker.form-control.css +3 -3
  128. package/dist/date-range-picker/date-range-picker.form-control.d.ts +28 -28
  129. package/dist/date-range-picker/date-range-picker.form-control.js +95 -95
  130. package/dist/date-range-picker/date-range-picker.js +104 -104
  131. package/dist/date-range-picker/index.d.ts +2 -2
  132. package/dist/date-range-picker/index.js +14 -14
  133. package/dist/file-picker/file-picker.css +63 -63
  134. package/dist/file-picker/file-picker.d.ts +276 -276
  135. package/dist/file-picker/file-picker.js +151 -151
  136. package/dist/file-picker/fs-map.json +1556 -1556
  137. package/dist/file-picker/index.d.ts +2 -2
  138. package/dist/file-picker/index.js +14 -14
  139. package/dist/file-picker/localization.d.ts +11 -11
  140. package/dist/file-picker/localization.js +124 -124
  141. package/dist/index.d.ts +13 -13
  142. package/dist/index.js +25 -25
  143. package/dist/map-filter-container/container-map.css +5 -5
  144. package/dist/map-filter-container/container-map.d.ts +11 -11
  145. package/dist/map-filter-container/container-map.js +31 -31
  146. package/dist/map-filter-container/index.d.ts +1 -1
  147. package/dist/map-filter-container/index.js +13 -13
  148. package/dist/map-filter-container/map-filter-container.d.ts +9 -9
  149. package/dist/map-filter-container/map-filter-container.js +78 -78
  150. package/dist/map-filter-container/polygon-selection-ui.d.ts +12 -12
  151. package/dist/map-filter-container/polygon-selection-ui.js +62 -62
  152. package/dist/models/defaults.d.ts +28 -28
  153. package/dist/models/defaults.js +32 -32
  154. package/dist/models/enums.d.ts +14 -14
  155. package/dist/models/enums.js +20 -20
  156. package/dist/models/index.d.ts +1 -1
  157. package/dist/models/index.js +13 -13
  158. package/dist/ol-map/feature.d.ts +6 -6
  159. package/dist/ol-map/feature.js +20 -20
  160. package/dist/ol-map/index.d.ts +6 -6
  161. package/dist/ol-map/index.js +18 -18
  162. package/dist/ol-map/interactions/draw.d.ts +8 -8
  163. package/dist/ol-map/interactions/draw.js +44 -44
  164. package/dist/ol-map/interactions/index.d.ts +1 -1
  165. package/dist/ol-map/interactions/index.js +13 -13
  166. package/dist/ol-map/layers/index.d.ts +3 -3
  167. package/dist/ol-map/layers/index.js +15 -15
  168. package/dist/ol-map/layers/tile-layer.d.ts +9 -9
  169. package/dist/ol-map/layers/tile-layer.js +48 -48
  170. package/dist/ol-map/layers/vector-layer.d.ts +4 -4
  171. package/dist/ol-map/layers/vector-layer.js +48 -48
  172. package/dist/ol-map/layers/vector-tile-layer.d.ts +10 -10
  173. package/dist/ol-map/layers/vector-tile-layer.js +66 -66
  174. package/dist/ol-map/map.css +17 -17
  175. package/dist/ol-map/map.d.ts +14 -14
  176. package/dist/ol-map/map.js +117 -117
  177. package/dist/ol-map/source/index.d.ts +6 -6
  178. package/dist/ol-map/source/index.js +18 -18
  179. package/dist/ol-map/source/mvt.d.ts +11 -11
  180. package/dist/ol-map/source/mvt.js +37 -37
  181. package/dist/ol-map/source/osm.d.ts +2 -2
  182. package/dist/ol-map/source/osm.js +14 -14
  183. package/dist/ol-map/source/vector-source.d.ts +4 -4
  184. package/dist/ol-map/source/vector-source.js +45 -45
  185. package/dist/ol-map/source/wms.d.ts +17 -17
  186. package/dist/ol-map/source/wms.js +30 -30
  187. package/dist/ol-map/source/wmts.d.ts +21 -21
  188. package/dist/ol-map/source/wmts.js +59 -59
  189. package/dist/ol-map/source/xyz.d.ts +12 -12
  190. package/dist/ol-map/source/xyz.js +27 -27
  191. package/dist/ol-map/style.d.ts +4 -4
  192. package/dist/ol-map/style.js +22 -22
  193. package/dist/popover/index.d.ts +1 -1
  194. package/dist/popover/index.js +5 -5
  195. package/dist/popover/popover.d.ts +3 -3
  196. package/dist/popover/popover.js +35 -35
  197. package/dist/smart-table/__mock-data__/smartTableMocks.d.ts +7 -7
  198. package/dist/smart-table/__mock-data__/smartTableMocks.js +17 -17
  199. package/dist/smart-table/index.d.ts +2 -2
  200. package/dist/smart-table/index.js +14 -14
  201. package/dist/smart-table/smart-table-head.d.ts +11 -11
  202. package/dist/smart-table/smart-table-head.js +22 -22
  203. package/dist/smart-table/smart-table-row.d.ts +12 -12
  204. package/dist/smart-table/smart-table-row.js +46 -46
  205. package/dist/smart-table/smart-table-types.d.ts +9 -9
  206. package/dist/smart-table/smart-table-types.js +2 -2
  207. package/dist/smart-table/smart-table.d.ts +17 -17
  208. package/dist/smart-table/smart-table.js +51 -51
  209. package/dist/theme/index.d.ts +1 -1
  210. package/dist/theme/index.js +13 -13
  211. package/dist/theme/theme.d.ts +8 -8
  212. package/dist/theme/theme.js +124 -124
  213. package/dist/utils/map.d.ts +3 -3
  214. package/dist/utils/map.js +21 -21
  215. package/dist/utils/projections.d.ts +6 -6
  216. package/dist/utils/projections.js +10 -10
  217. package/dist/utils/story.d.ts +12 -12
  218. package/dist/utils/story.js +2 -2
  219. package/package.json +2 -2
  220. package/public/index.html +43 -43
  221. package/public/manifest.json +25 -25
  222. package/public/robots.txt +3 -3
  223. package/src/index.tsx +9 -9
  224. package/src/lib/autocomplete/autocomplete.css +25 -25
  225. package/src/lib/autocomplete/autocomplete.stories.tsx +101 -101
  226. package/src/lib/autocomplete/autocomplete.tsx +681 -681
  227. package/src/lib/autocomplete/index.ts +1 -1
  228. package/src/lib/box/box.tsx +7 -7
  229. package/src/lib/box/index.ts +1 -1
  230. package/src/lib/cesium-map/context-menu.stories.tsx +444 -444
  231. package/src/lib/cesium-map/data-sources/custom.data-source.tsx +12 -12
  232. package/src/lib/cesium-map/data-sources/drawings.data-source.stories.tsx +161 -161
  233. package/src/lib/cesium-map/data-sources/drawings.data-source.tsx +204 -205
  234. package/src/lib/cesium-map/data-sources/index.ts +2 -2
  235. package/src/lib/cesium-map/entities/entity.description.tsx +19 -19
  236. package/src/lib/cesium-map/entities/entity.graphics.stories.tsx +48 -48
  237. package/src/lib/cesium-map/entities/entity.stories.tsx +146 -146
  238. package/src/lib/cesium-map/entities/entity.tsx +10 -10
  239. package/src/lib/cesium-map/entities/graphics/polygon.graphics.tsx +12 -12
  240. package/src/lib/cesium-map/entities/graphics/polyline.graphics.tsx +12 -12
  241. package/src/lib/cesium-map/entities/graphics/rectangle.graphics.tsx +12 -12
  242. package/src/lib/cesium-map/entities/index.ts +4 -4
  243. package/src/lib/cesium-map/index.ts +8 -7
  244. package/src/lib/cesium-map/layers/3d.tileset.stories.tsx +164 -164
  245. package/src/lib/cesium-map/layers/3d.tileset.tsx +51 -51
  246. package/src/lib/cesium-map/layers/3d.tileset.with.update.tsx +120 -120
  247. package/src/lib/cesium-map/layers/geojson.layer.stories.tsx +119 -119
  248. package/src/lib/cesium-map/layers/geojson.layer.tsx +12 -12
  249. package/src/lib/cesium-map/layers/imagery.layer.stories.tsx +39 -39
  250. package/src/lib/cesium-map/layers/imagery.layer.tsx +37 -37
  251. package/src/lib/cesium-map/layers/index.ts +7 -7
  252. package/src/lib/cesium-map/layers/layers.rect.stories.tsx +171 -171
  253. package/src/lib/cesium-map/layers/osm.layer.stories.tsx +40 -40
  254. package/src/lib/cesium-map/layers/osm.layer.tsx +22 -22
  255. package/src/lib/cesium-map/layers/wms.layer.stories.tsx +38 -38
  256. package/src/lib/cesium-map/layers/wms.layer.tsx +22 -22
  257. package/src/lib/cesium-map/layers/wmts.layer.stories.tsx +53 -53
  258. package/src/lib/cesium-map/layers/wmts.layer.tsx +22 -22
  259. package/src/lib/cesium-map/layers/xyz.layer.stories.tsx +37 -37
  260. package/src/lib/cesium-map/layers/xyz.layer.tsx +22 -22
  261. package/src/lib/cesium-map/layers-manager.stories.tsx +286 -286
  262. package/src/lib/cesium-map/layers-manager.ts +354 -358
  263. package/src/lib/cesium-map/map-legend/MapLegend.css +135 -135
  264. package/src/lib/cesium-map/map-legend/MapLegend.tsx +92 -91
  265. package/src/lib/cesium-map/map-legend/MapLegendList.tsx +47 -46
  266. package/src/lib/cesium-map/map-legend/MapLegendSidebar.tsx +55 -55
  267. package/src/lib/cesium-map/map-legend/MapLegendToggle.tsx +31 -31
  268. package/src/lib/cesium-map/map-legend/index.tsx +3 -3
  269. package/src/lib/cesium-map/map-legend/legends-sidebar.stories.tsx +201 -201
  270. package/src/lib/cesium-map/map.css +59 -59
  271. package/src/lib/cesium-map/map.stories.tsx +143 -143
  272. package/src/lib/cesium-map/map.tsx +446 -447
  273. package/src/lib/cesium-map/map.types.ts +11 -11
  274. package/src/lib/cesium-map/proxied.types.ts +54 -42
  275. package/src/lib/cesium-map/settings/base-maps.css +37 -37
  276. package/src/lib/cesium-map/settings/base-maps.tsx +94 -94
  277. package/src/lib/cesium-map/settings/scene-modes.css +19 -19
  278. package/src/lib/cesium-map/settings/scene-modes.tsx +100 -100
  279. package/src/lib/cesium-map/settings/settings.css +52 -52
  280. package/src/lib/cesium-map/settings/settings.stories.tsx +182 -182
  281. package/src/lib/cesium-map/settings/settings.tsx +141 -141
  282. package/src/lib/cesium-map/terrain-providers/custom/dummy-quantized-mesh-tile.ts +243 -243
  283. package/src/lib/cesium-map/terrain-providers/custom/quantized-mesh-decoder.ts +321 -321
  284. package/src/lib/cesium-map/terrain-providers/custom/quantized-mesh-terrain-provider.ts +237 -237
  285. package/src/lib/cesium-map/terrain-providers/terrain-provider-heights-tool.stories.tsx +170 -170
  286. package/src/lib/cesium-map/terrain-providers/terrain-provider.stories.tsx +187 -187
  287. package/src/lib/cesium-map/tools/cesium/primitives-conversions.cesium.ts +15 -15
  288. package/src/lib/cesium-map/tools/coordinates-tracker.tool.css +11 -11
  289. package/src/lib/cesium-map/tools/coordinates-tracker.tool.tsx +79 -79
  290. package/src/lib/cesium-map/tools/draw/drawHelper.css +101 -101
  291. package/src/lib/cesium-map/tools/draw/drawHelper.ts +2116 -2116
  292. package/src/lib/cesium-map/tools/geojson/geojson-to-primitive.ts +54 -54
  293. package/src/lib/cesium-map/tools/geojson/index.ts +2 -2
  294. package/src/lib/cesium-map/tools/geojson/point.geojson.ts +29 -29
  295. package/src/lib/cesium-map/tools/geojson/polygon.geojson.ts +24 -24
  296. package/src/lib/cesium-map/tools/geojson/rectangle.geojson.ts +21 -21
  297. package/src/lib/cesium-map/tools/inspector.tool.tsx +15 -15
  298. package/src/lib/cesium-map/tools/scale-tracker.tool.css +16 -16
  299. package/src/lib/cesium-map/tools/scale-tracker.tool.tsx +192 -192
  300. package/src/lib/cesium-map/tools/terranian-height.tool.tsx +171 -171
  301. package/src/lib/cssbaseline/cssbaseline.tsx +19 -19
  302. package/src/lib/cssbaseline/index.ts +4 -4
  303. package/src/lib/date-picker/date-picker.css +9 -9
  304. package/src/lib/date-picker/date-picker.stories.tsx +130 -130
  305. package/src/lib/date-picker/date-picker.tsx +90 -90
  306. package/src/lib/date-picker/index.ts +1 -1
  307. package/src/lib/date-range-picker/date-range-picker.css +9 -9
  308. package/src/lib/date-range-picker/date-range-picker.form-control.css +3 -3
  309. package/src/lib/date-range-picker/date-range-picker.form-control.spec.tsx +58 -58
  310. package/src/lib/date-range-picker/date-range-picker.form-control.tsx +150 -150
  311. package/src/lib/date-range-picker/date-range-picker.stories.tsx +207 -207
  312. package/src/lib/date-range-picker/date-range-picker.tsx +156 -156
  313. package/src/lib/date-range-picker/index.ts +2 -2
  314. package/src/lib/file-picker/file-picker.css +63 -63
  315. package/src/lib/file-picker/file-picker.stories.tsx +447 -447
  316. package/src/lib/file-picker/file-picker.tsx +180 -180
  317. package/src/lib/file-picker/fs-map.json +1556 -1556
  318. package/src/lib/file-picker/index.ts +2 -2
  319. package/src/lib/file-picker/localization.ts +164 -164
  320. package/src/lib/index.ts +13 -13
  321. package/src/lib/map-filter-container/container-map.css +5 -5
  322. package/src/lib/map-filter-container/container-map.tsx +48 -48
  323. package/src/lib/map-filter-container/index.ts +1 -1
  324. package/src/lib/map-filter-container/map-filter-container.tsx +91 -91
  325. package/src/lib/map-filter-container/polygon-selection-ui.spec.tsx +119 -119
  326. package/src/lib/map-filter-container/polygon-selection-ui.tsx +111 -111
  327. package/src/lib/map-filter-container/stories/Map.stories.tsx +76 -76
  328. package/src/lib/models/defaults.ts +32 -32
  329. package/src/lib/models/enums.ts +16 -16
  330. package/src/lib/models/index.ts +1 -1
  331. package/src/lib/ol-map/feature.tsx +23 -23
  332. package/src/lib/ol-map/index.ts +6 -6
  333. package/src/lib/ol-map/interactions/draw.tsx +56 -56
  334. package/src/lib/ol-map/interactions/index.ts +1 -1
  335. package/src/lib/ol-map/layers/index.ts +3 -3
  336. package/src/lib/ol-map/layers/tile-layer.tsx +36 -36
  337. package/src/lib/ol-map/layers/vector-layer.tsx +32 -32
  338. package/src/lib/ol-map/layers/vector-tile-layer.tsx +56 -56
  339. package/src/lib/ol-map/map.css +17 -17
  340. package/src/lib/ol-map/map.tsx +137 -137
  341. package/src/lib/ol-map/source/index.ts +6 -6
  342. package/src/lib/ol-map/source/mvt.tsx +46 -46
  343. package/src/lib/ol-map/source/osm.tsx +13 -13
  344. package/src/lib/ol-map/source/stories/mvt.stories.tsx +68 -68
  345. package/src/lib/ol-map/source/stories/vector-source.stories.tsx +78 -78
  346. package/src/lib/ol-map/source/stories/wms.stories.tsx +51 -51
  347. package/src/lib/ol-map/source/stories/wmts.stories.tsx +72 -72
  348. package/src/lib/ol-map/source/stories/xyz.stories.tsx +53 -53
  349. package/src/lib/ol-map/source/vector-source.tsx +30 -30
  350. package/src/lib/ol-map/source/wms.tsx +40 -40
  351. package/src/lib/ol-map/source/wmts.tsx +82 -82
  352. package/src/lib/ol-map/source/xyz.tsx +33 -33
  353. package/src/lib/ol-map/stories/map.stories.tsx +60 -60
  354. package/src/lib/ol-map/style.ts +24 -24
  355. package/src/lib/popover/index.ts +1 -1
  356. package/src/lib/popover/popover.tsx +7 -7
  357. package/src/lib/smart-table/__mock-data__/smartTableMocks.ts +22 -22
  358. package/src/lib/smart-table/index.ts +2 -2
  359. package/src/lib/smart-table/smart-table-head.spec.tsx +116 -116
  360. package/src/lib/smart-table/smart-table-head.tsx +47 -47
  361. package/src/lib/smart-table/smart-table-row.spec.tsx +109 -109
  362. package/src/lib/smart-table/smart-table-row.tsx +78 -78
  363. package/src/lib/smart-table/smart-table-types.ts +10 -10
  364. package/src/lib/smart-table/smart-table.spec.tsx +116 -116
  365. package/src/lib/smart-table/smart-table.tsx +115 -115
  366. package/src/lib/smart-table/stories/SmartTable.stories.tsx +114 -114
  367. package/src/lib/theme/index.ts +1 -1
  368. package/src/lib/theme/theme.ts +123 -123
  369. package/src/lib/utils/map.ts +19 -19
  370. package/src/lib/utils/projections.ts +7 -7
  371. package/src/lib/utils/story.ts +11 -11
  372. package/src/react-app-env.d.ts +1 -1
  373. package/src/setupTests.ts +14 -14
  374. package/tsbuildconfig.json +37 -37
  375. package/tsconfig.json +26 -26
@@ -1,681 +1,681 @@
1
- /* eslint-disable */
2
- import React, {
3
- useState,
4
- useRef,
5
- useEffect,
6
- ChangeEvent,
7
- KeyboardEvent,
8
- } from 'react';
9
- import getCaretCoordinates from 'textarea-caret';
10
- import getInputSelection, { setCaretPosition } from 'get-input-selection';
11
-
12
- import './autocomplete.css';
13
-
14
- const KEY_UP = 38;
15
- const KEY_DOWN = 40;
16
- const KEY_RETURN = 13;
17
- const KEY_ENTER = 14;
18
- const KEY_ESCAPE = 27;
19
- const KEY_TAB = 9;
20
-
21
- const OPTION_LIST_Y_OFFSET = 10;
22
- const OPTION_LIST_MIN_WIDTH = 100;
23
-
24
- export interface IAutocompleteProps {
25
- Component: React.ReactElement;
26
- ComponentProps: Record<string, unknown>;
27
- defaultValue: string | undefined;
28
- disabled: boolean;
29
- maxOptions: number;
30
- onBlur: (evt: any) => void;
31
- onChange: (val: string) => void;
32
- onKeyDown: (evt: any) => void;
33
- onRequestOptions: (val: string) => void;
34
- onSelect: (val: string) => void;
35
- changeOnSelect: (trigger: string, slug: string) => string;
36
- options: string[];
37
- regex: string;
38
- matchAny: boolean;
39
- minChars: number;
40
- requestOnlyIfNoOptions: boolean;
41
- spaceRemovers: string[];
42
- spacer: string;
43
- trigger: string | string[];
44
- value: string | undefined;
45
- offsetX: number;
46
- offsetY: number;
47
- passThroughEnter: boolean;
48
- mode: 'autocomplete' | 'assist';
49
- direction: 'ltr' | 'rtl';
50
- }
51
-
52
- const Autocomplete: React.FC<IAutocompleteProps> = (props) => {
53
- const [recentValue, setRecentValue] = useState(props.defaultValue ?? '');
54
- const [enableSpaceRemovers, setEnableSpaceRemovers] = useState(false);
55
-
56
- const [state, setState] = useState({
57
- helperVisible: false,
58
- left: 0,
59
- right: 0,
60
- trigger: '',
61
- matchLength: 0,
62
- matchStart: 0,
63
- options: [],
64
- selection: 0,
65
- top: 0,
66
- value: '',
67
- caret: 0,
68
- width: 'unset',
69
- });
70
- const refInput = useRef(null);
71
-
72
- useEffect(() => {
73
- window.addEventListener('resize', handleResize);
74
- return (): void => {
75
- try {
76
- window.removeEventListener('resize', handleResize);
77
- } catch (e) {
78
- console.log('WINDOW "resize" remove listener failed', e);
79
- }
80
- };
81
- }, []);
82
-
83
- useEffect(() => {
84
- if (typeof props.value !== 'undefined') {
85
- setRecentValue(props.value);
86
- }
87
-
88
- if (typeof props.defaultValue !== 'undefined') {
89
- setRecentValue(props.defaultValue);
90
- }
91
- }, [props.value, props.defaultValue]);
92
-
93
- useEffect(() => {
94
- const { options } = props;
95
- const { caret } = state;
96
-
97
- // if (options.length !== prevProps.options.length) {
98
- updateHelper(recentValue, caret, options);
99
- // }
100
- }, [props]);
101
-
102
- const getMatch = (
103
- str: string,
104
- caret: number,
105
- providedOptions: string[]
106
- ): Record<string, unknown> => {
107
- const { trigger, matchAny, regex } = props;
108
- const re = new RegExp(regex);
109
-
110
- let triggers = trigger;
111
- if (!Array.isArray(triggers)) {
112
- triggers = new Array(trigger) as string[];
113
- }
114
- triggers.sort();
115
-
116
- const providedOptionsObject: Record<string, unknown> = {};
117
- if (Array.isArray(providedOptions)) {
118
- triggers.forEach((triggerStr) => {
119
- providedOptionsObject[triggerStr] = providedOptions;
120
- });
121
- }
122
-
123
- const triggersMatch = arrayTriggerMatch(triggers, re);
124
- let slugData: Record<string, unknown> = {};
125
-
126
- for (
127
- let triggersIndex = 0;
128
- triggersIndex < triggersMatch.length;
129
- triggersIndex++
130
- ) {
131
- const { triggerStr, triggerMatch, triggerLength } = triggersMatch[
132
- triggersIndex
133
- ];
134
-
135
- for (let i = caret - 1; i >= 0; --i) {
136
- const substr = str.substring(i, caret);
137
- const match = substr.match(re);
138
- let matchStart = -1;
139
-
140
- if (triggerLength > 0) {
141
- const triggerIdx = triggerMatch ? i : i - triggerLength + 1;
142
-
143
- if (triggerIdx < 0) {
144
- // out of input
145
- break;
146
- }
147
-
148
- if (isTrigger(triggerStr, str, triggerIdx)) {
149
- matchStart = triggerIdx + triggerLength;
150
- }
151
-
152
- if (!match && matchStart < 0) {
153
- break;
154
- }
155
- } else {
156
- if (match && i > 0) {
157
- // find first non-matching character or begin of input
158
- continue;
159
- }
160
- matchStart = i === 0 && match ? 0 : i + 1;
161
-
162
- if (caret - matchStart === 0) {
163
- // matched slug is empty
164
- break;
165
- }
166
- }
167
-
168
- if (matchStart >= 0) {
169
- const triggerOptions = providedOptionsObject[triggerStr] as string[];
170
- if (!Array.isArray(triggerOptions)) {
171
- continue;
172
- }
173
-
174
- const matchedSlug = str.substring(matchStart, caret);
175
-
176
- const options = triggerOptions.filter((slug) => {
177
- const idx = slug.toLowerCase().indexOf(matchedSlug.toLowerCase());
178
- return idx !== -1 && (matchAny || idx === 0);
179
- });
180
-
181
- const currTrigger = triggerStr;
182
- const matchLength = matchedSlug.length;
183
-
184
- if (slugData === {}) {
185
- slugData = {
186
- trigger: currTrigger,
187
- matchStart,
188
- matchLength,
189
- options,
190
- };
191
- } else {
192
- slugData = {
193
- ...slugData,
194
- trigger: currTrigger,
195
- matchStart,
196
- matchLength,
197
- options,
198
- };
199
- }
200
- }
201
- }
202
- }
203
-
204
- return slugData;
205
- };
206
-
207
- const arrayTriggerMatch = (triggers: string[], re: RegExp) => {
208
- const triggersMatch = triggers.map((trigger) => ({
209
- triggerStr: trigger,
210
- triggerMatch: trigger.match(re),
211
- triggerLength: trigger.length,
212
- }));
213
-
214
- return triggersMatch;
215
- };
216
-
217
- const isTrigger = (trigger: string, str: string, i: number): boolean => {
218
- if (!trigger || !trigger.length) {
219
- return true;
220
- }
221
-
222
- if (str.substr(i, trigger.length) === trigger) {
223
- return true;
224
- }
225
-
226
- return false;
227
- };
228
-
229
- const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
230
- const { onChange, options, spaceRemovers, spacer, value } = props;
231
-
232
- const old = recentValue;
233
- const str = e.target.value;
234
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
235
- const caret = (getInputSelection(getInputElement(e.target)) as {
236
- start: number;
237
- end: number;
238
- }).end;
239
-
240
- if (!str.length) {
241
- updateState({
242
- ...state,
243
- helperVisible: false,
244
- });
245
- }
246
-
247
- setRecentValue(str);
248
-
249
- updateState({
250
- ...state,
251
- caret,
252
- value: e.target.value,
253
- });
254
-
255
- if (!str.length || !caret) {
256
- return onChange(e.target.value);
257
- }
258
-
259
- // '@wonderjenny ,|' -> '@wonderjenny, |'
260
- if (
261
- enableSpaceRemovers &&
262
- spaceRemovers.length &&
263
- str.length > 2 &&
264
- spacer.length
265
- ) {
266
- for (let i = 0; i < Math.max(old.length, str.length); ++i) {
267
- if (old[i] !== str[i]) {
268
- if (
269
- i >= 2 &&
270
- str[i - 1] === spacer &&
271
- spaceRemovers.indexOf(str[i - 2]) === -1 &&
272
- spaceRemovers.indexOf(str[i]) !== -1 &&
273
- getMatch(str.substring(0, i - 2), caret - 3, options) !== {}
274
- ) {
275
- const newValue = `${str.slice(0, i - 1)}${str.slice(
276
- i,
277
- i + 1
278
- )}${str.slice(i - 1, i)}${str.slice(i + 1)}`;
279
-
280
- updateCaretPosition(i + 1);
281
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
282
- if (refInput.current !== null) {
283
- ((refInput.current as unknown) as Record<
284
- string,
285
- unknown
286
- >).value = newValue;
287
- }
288
-
289
- if (!value) {
290
- updateState({
291
- ...state,
292
- value: newValue,
293
- });
294
- }
295
-
296
- return onChange(newValue);
297
- }
298
-
299
- break;
300
- }
301
- }
302
-
303
- setEnableSpaceRemovers(false);
304
- }
305
-
306
- updateHelper(str, caret, options);
307
-
308
- // if (!value) {
309
- // updateState({
310
- // ...state,
311
- // value: e.target.value
312
- // });
313
- // }
314
-
315
- return onChange(e.target.value);
316
- };
317
-
318
- const getInputElement = (
319
- parent: HTMLElement | undefined
320
- ): HTMLElement | undefined => {
321
- if (parent !== undefined) {
322
- if (parent.children.length > 0) {
323
- const innerTextAreas = parent.getElementsByTagName('textarea');
324
- if (innerTextAreas.length > 0) {
325
- return innerTextAreas[0];
326
- }
327
-
328
- const innerInputs = parent.getElementsByTagName('input');
329
- if (innerInputs.length > 0) {
330
- return innerInputs[0];
331
- }
332
- } else {
333
- return parent;
334
- }
335
- }
336
-
337
- return undefined;
338
- };
339
-
340
- const handleKeyDown = (event: KeyboardEvent) => {
341
- const { helperVisible, options, selection } = state;
342
- const { onKeyDown, passThroughEnter } = props;
343
-
344
- if (helperVisible) {
345
- switch (event.keyCode) {
346
- case KEY_ESCAPE:
347
- event.preventDefault();
348
- resetHelper();
349
- break;
350
- case KEY_UP:
351
- event.preventDefault();
352
- updateState({
353
- ...state,
354
- selection: (options.length + selection - 1) % options.length,
355
- });
356
- break;
357
- case KEY_DOWN:
358
- event.preventDefault();
359
- updateState({
360
- ...state,
361
- selection: (selection + 1) % options.length,
362
- });
363
- break;
364
- case KEY_ENTER:
365
- case KEY_RETURN:
366
- if (!passThroughEnter) {
367
- event.preventDefault();
368
- }
369
- handleSelection(selection);
370
- break;
371
- case KEY_TAB:
372
- handleSelection(selection);
373
- break;
374
- default:
375
- onKeyDown(event);
376
- break;
377
- }
378
- } else {
379
- onKeyDown(event);
380
- }
381
- };
382
-
383
- const handleResize = () => {
384
- updateState({
385
- ...state,
386
- helperVisible: false,
387
- });
388
- };
389
-
390
- const handleSelection = (idx: number) => {
391
- const { spacer, onSelect, changeOnSelect } = props;
392
- const { matchStart, matchLength, options, trigger } = state;
393
-
394
- const slug = options[idx];
395
- const value = recentValue;
396
- const part1 = value.substring(0, matchStart - trigger.length);
397
- const part2 = value.substring(matchStart + matchLength);
398
-
399
- const event = { target: refInput.current };
400
- const changedStr = changeOnSelect(trigger, slug);
401
-
402
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
403
- if (event.target !== null) {
404
- ((event.target as unknown) as Record<
405
- string,
406
- unknown
407
- >).value = `${part1}${changedStr}${spacer}${part2}`;
408
- }
409
- handleChange(event as any);
410
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
411
- if (event.target !== null) {
412
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
413
- onSelect((event.target as any).value);
414
- }
415
-
416
- resetHelper();
417
-
418
- updateCaretPosition(part1.length + changedStr.length + 1);
419
-
420
- setEnableSpaceRemovers(true);
421
- };
422
-
423
- const updateCaretPosition = (caret: number) => {
424
- updateState({
425
- ...state,
426
- caret,
427
- });
428
-
429
- const input = getInputElement((refInput.current as unknown) as HTMLElement);
430
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
431
- setCaretPosition(input, caret);
432
- };
433
-
434
- const updateState = (val: any) => {
435
- setTimeout(() => {
436
- setState({
437
- ...val,
438
- });
439
- }, 0);
440
- };
441
-
442
- const updateHelper = (str: string, caret: number, options: string[]) => {
443
- const parent = (refInput.current as unknown) as HTMLElement;
444
- if (refInput.current === null) {
445
- return;
446
- }
447
-
448
- const input = getInputElement(parent);
449
- if (input === undefined) {
450
- return;
451
- }
452
- const parentRect = parent.getBoundingClientRect();
453
-
454
- const slug = getMatch(str, caret, options) as any;
455
-
456
- if (Object.keys(slug).length > 0 && input !== null) {
457
- const caretPos = getCaretCoordinates(input, caret);
458
- const rect = input.getBoundingClientRect();
459
- const {
460
- minChars,
461
- onRequestOptions,
462
- requestOnlyIfNoOptions,
463
- mode,
464
- } = props;
465
-
466
- let top,
467
- left,
468
- right,
469
- width = 'unset';
470
- if (mode === 'assist') {
471
- top =
472
- parent === input
473
- ? caretPos.top + input.offsetTop
474
- : caretPos.top + parentRect.top;
475
- left = Math.min(
476
- caretPos.left + input.offsetLeft - OPTION_LIST_Y_OFFSET,
477
- input.offsetLeft + rect.width - OPTION_LIST_MIN_WIDTH
478
- );
479
- } else {
480
- top = parentRect.top + parent.offsetHeight;
481
- left = parent.offsetLeft;
482
- right = parent.offsetLeft - parent.offsetWidth;
483
- width = `${parentRect.width}px`;
484
- }
485
-
486
- if (
487
- slug.matchLength >= minChars &&
488
- (slug.options.length > 1 ||
489
- (slug.options.length === 1 &&
490
- slug.options[0].length !== slug.matchLength))
491
- ) {
492
- updateState({
493
- ...state,
494
- value: str,
495
- helperVisible: true,
496
- top,
497
- left,
498
- right,
499
- width,
500
- ...slug,
501
- });
502
- } else {
503
- if (!requestOnlyIfNoOptions || !slug.options.length) {
504
- onRequestOptions(str.substr(slug.matchStart, slug.matchLength));
505
- }
506
-
507
- resetHelper();
508
- }
509
- } else {
510
- resetHelper();
511
- }
512
- };
513
-
514
- const resetHelper = () => {
515
- const timeDelay = 100;
516
- setTimeout(() => {
517
- updateState({
518
- ...state,
519
- helperVisible: false,
520
- selection: 0,
521
- });
522
- }, timeDelay);
523
- };
524
-
525
- const renderAutocompleteList = () => {
526
- const {
527
- helperVisible,
528
- left,
529
- right,
530
- matchStart,
531
- matchLength,
532
- options,
533
- selection,
534
- top,
535
- value,
536
- width,
537
- } = state;
538
-
539
- if (!helperVisible) {
540
- return null;
541
- }
542
-
543
- const { maxOptions, offsetX, offsetY, direction } = props;
544
-
545
- if (options.length === 0) {
546
- return null;
547
- }
548
-
549
- if (selection >= options.length) {
550
- updateState({
551
- ...state,
552
- selection: 0,
553
- });
554
-
555
- return null;
556
- }
557
-
558
- const optionNumber = maxOptions === 0 ? options.length : maxOptions;
559
-
560
- const helperOptions = options
561
- .slice(0, optionNumber)
562
- .map((val: string, idx) => {
563
- const highlightStart = val
564
- .toLowerCase()
565
- .indexOf(value.substr(matchStart, matchLength).toLowerCase());
566
-
567
- return (
568
- <li
569
- className={idx === selection ? 'active' : undefined}
570
- key={val}
571
- onClick={() => {
572
- handleSelection(idx);
573
- }}
574
- onMouseEnter={() => {
575
- updateState({
576
- ...state,
577
- selection: idx,
578
- });
579
- }}
580
- >
581
- {val.slice(0, highlightStart)}
582
- <strong>{val.substr(highlightStart, matchLength)}</strong>
583
- {val.slice(highlightStart + matchLength)}
584
- </li>
585
- );
586
- });
587
-
588
- const horizontalPosition =
589
- direction === 'ltr'
590
- ? { left: left + offsetX }
591
- : { right: right + offsetX };
592
- return (
593
- <ul
594
- className="react-autocomplete-input"
595
- style={{ ...horizontalPosition, top: top + offsetY, width }}
596
- >
597
- {helperOptions}
598
- </ul>
599
- );
600
- };
601
-
602
- const {
603
- Component,
604
- ComponentProps,
605
- defaultValue,
606
- disabled,
607
- onBlur,
608
- value,
609
- ...rest
610
- } = props;
611
-
612
- const propagated: any = Object.assign({}, rest);
613
- Object.keys(props).forEach((k) => {
614
- delete (propagated as Record<string, unknown>)[k];
615
- });
616
-
617
- return (
618
- <>
619
- {React.cloneElement(Component, {
620
- disabled: disabled,
621
- onBlur: onBlur,
622
- onChange: handleChange,
623
- onKeyDown: handleKeyDown,
624
- ref: refInput,
625
- value: recentValue,
626
- ...propagated,
627
- ...ComponentProps,
628
- })}
629
- {renderAutocompleteList()}
630
- </>
631
- );
632
- };
633
-
634
- const defaultProps: IAutocompleteProps = {
635
- Component: <textarea />,
636
- ComponentProps: {},
637
- defaultValue: undefined,
638
- disabled: false,
639
- maxOptions: 6,
640
- onBlur: (evt: any) => {},
641
- onChange: (val: string) => {},
642
- onKeyDown: (evt: any) => {},
643
- onRequestOptions: (val: string) => {},
644
- onSelect: (val: string) => {},
645
- changeOnSelect: (trigger: string, slug: string): string =>
646
- `${trigger}${slug}`,
647
- options: [],
648
- regex: '^[A-Za-z0-9\\-_]+$',
649
- matchAny: false,
650
- minChars: 0,
651
- requestOnlyIfNoOptions: true,
652
- spaceRemovers: [',', '.', '!', '?'],
653
- spacer: ' ',
654
- trigger: '@',
655
- offsetX: 0,
656
- offsetY: 0,
657
- value: undefined,
658
- passThroughEnter: false,
659
- mode: 'assist',
660
- direction: 'ltr',
661
- };
662
-
663
- interface IAutocompleteOptionalProps extends Partial<IAutocompleteProps> {}
664
- export const AutocompleteWithDefauls: React.FC<IAutocompleteOptionalProps> = (
665
- props
666
- ) => {
667
- let compProps = {
668
- ...defaultProps,
669
- ...props,
670
- };
671
- if (props.mode === 'autocomplete') {
672
- compProps = {
673
- ...compProps,
674
- trigger: '',
675
- regex: '.',
676
- spacer: '',
677
- };
678
- }
679
- return <Autocomplete {...compProps} />;
680
- };
681
- export default AutocompleteWithDefauls;
1
+ /* eslint-disable */
2
+ import React, {
3
+ useState,
4
+ useRef,
5
+ useEffect,
6
+ ChangeEvent,
7
+ KeyboardEvent,
8
+ } from 'react';
9
+ import getCaretCoordinates from 'textarea-caret';
10
+ import getInputSelection, { setCaretPosition } from 'get-input-selection';
11
+
12
+ import './autocomplete.css';
13
+
14
+ const KEY_UP = 38;
15
+ const KEY_DOWN = 40;
16
+ const KEY_RETURN = 13;
17
+ const KEY_ENTER = 14;
18
+ const KEY_ESCAPE = 27;
19
+ const KEY_TAB = 9;
20
+
21
+ const OPTION_LIST_Y_OFFSET = 10;
22
+ const OPTION_LIST_MIN_WIDTH = 100;
23
+
24
+ export interface IAutocompleteProps {
25
+ Component: React.ReactElement;
26
+ ComponentProps: Record<string, unknown>;
27
+ defaultValue: string | undefined;
28
+ disabled: boolean;
29
+ maxOptions: number;
30
+ onBlur: (evt: any) => void;
31
+ onChange: (val: string) => void;
32
+ onKeyDown: (evt: any) => void;
33
+ onRequestOptions: (val: string) => void;
34
+ onSelect: (val: string) => void;
35
+ changeOnSelect: (trigger: string, slug: string) => string;
36
+ options: string[];
37
+ regex: string;
38
+ matchAny: boolean;
39
+ minChars: number;
40
+ requestOnlyIfNoOptions: boolean;
41
+ spaceRemovers: string[];
42
+ spacer: string;
43
+ trigger: string | string[];
44
+ value: string | undefined;
45
+ offsetX: number;
46
+ offsetY: number;
47
+ passThroughEnter: boolean;
48
+ mode: 'autocomplete' | 'assist';
49
+ direction: 'ltr' | 'rtl';
50
+ }
51
+
52
+ const Autocomplete: React.FC<IAutocompleteProps> = (props) => {
53
+ const [recentValue, setRecentValue] = useState(props.defaultValue ?? '');
54
+ const [enableSpaceRemovers, setEnableSpaceRemovers] = useState(false);
55
+
56
+ const [state, setState] = useState({
57
+ helperVisible: false,
58
+ left: 0,
59
+ right: 0,
60
+ trigger: '',
61
+ matchLength: 0,
62
+ matchStart: 0,
63
+ options: [],
64
+ selection: 0,
65
+ top: 0,
66
+ value: '',
67
+ caret: 0,
68
+ width: 'unset',
69
+ });
70
+ const refInput = useRef(null);
71
+
72
+ useEffect(() => {
73
+ window.addEventListener('resize', handleResize);
74
+ return (): void => {
75
+ try {
76
+ window.removeEventListener('resize', handleResize);
77
+ } catch (e) {
78
+ console.log('WINDOW "resize" remove listener failed', e);
79
+ }
80
+ };
81
+ }, []);
82
+
83
+ useEffect(() => {
84
+ if (typeof props.value !== 'undefined') {
85
+ setRecentValue(props.value);
86
+ }
87
+
88
+ if (typeof props.defaultValue !== 'undefined') {
89
+ setRecentValue(props.defaultValue);
90
+ }
91
+ }, [props.value, props.defaultValue]);
92
+
93
+ useEffect(() => {
94
+ const { options } = props;
95
+ const { caret } = state;
96
+
97
+ // if (options.length !== prevProps.options.length) {
98
+ updateHelper(recentValue, caret, options);
99
+ // }
100
+ }, [props]);
101
+
102
+ const getMatch = (
103
+ str: string,
104
+ caret: number,
105
+ providedOptions: string[]
106
+ ): Record<string, unknown> => {
107
+ const { trigger, matchAny, regex } = props;
108
+ const re = new RegExp(regex);
109
+
110
+ let triggers = trigger;
111
+ if (!Array.isArray(triggers)) {
112
+ triggers = new Array(trigger) as string[];
113
+ }
114
+ triggers.sort();
115
+
116
+ const providedOptionsObject: Record<string, unknown> = {};
117
+ if (Array.isArray(providedOptions)) {
118
+ triggers.forEach((triggerStr) => {
119
+ providedOptionsObject[triggerStr] = providedOptions;
120
+ });
121
+ }
122
+
123
+ const triggersMatch = arrayTriggerMatch(triggers, re);
124
+ let slugData: Record<string, unknown> = {};
125
+
126
+ for (
127
+ let triggersIndex = 0;
128
+ triggersIndex < triggersMatch.length;
129
+ triggersIndex++
130
+ ) {
131
+ const { triggerStr, triggerMatch, triggerLength } = triggersMatch[
132
+ triggersIndex
133
+ ];
134
+
135
+ for (let i = caret - 1; i >= 0; --i) {
136
+ const substr = str.substring(i, caret);
137
+ const match = substr.match(re);
138
+ let matchStart = -1;
139
+
140
+ if (triggerLength > 0) {
141
+ const triggerIdx = triggerMatch ? i : i - triggerLength + 1;
142
+
143
+ if (triggerIdx < 0) {
144
+ // out of input
145
+ break;
146
+ }
147
+
148
+ if (isTrigger(triggerStr, str, triggerIdx)) {
149
+ matchStart = triggerIdx + triggerLength;
150
+ }
151
+
152
+ if (!match && matchStart < 0) {
153
+ break;
154
+ }
155
+ } else {
156
+ if (match && i > 0) {
157
+ // find first non-matching character or begin of input
158
+ continue;
159
+ }
160
+ matchStart = i === 0 && match ? 0 : i + 1;
161
+
162
+ if (caret - matchStart === 0) {
163
+ // matched slug is empty
164
+ break;
165
+ }
166
+ }
167
+
168
+ if (matchStart >= 0) {
169
+ const triggerOptions = providedOptionsObject[triggerStr] as string[];
170
+ if (!Array.isArray(triggerOptions)) {
171
+ continue;
172
+ }
173
+
174
+ const matchedSlug = str.substring(matchStart, caret);
175
+
176
+ const options = triggerOptions.filter((slug) => {
177
+ const idx = slug.toLowerCase().indexOf(matchedSlug.toLowerCase());
178
+ return idx !== -1 && (matchAny || idx === 0);
179
+ });
180
+
181
+ const currTrigger = triggerStr;
182
+ const matchLength = matchedSlug.length;
183
+
184
+ if (slugData === {}) {
185
+ slugData = {
186
+ trigger: currTrigger,
187
+ matchStart,
188
+ matchLength,
189
+ options,
190
+ };
191
+ } else {
192
+ slugData = {
193
+ ...slugData,
194
+ trigger: currTrigger,
195
+ matchStart,
196
+ matchLength,
197
+ options,
198
+ };
199
+ }
200
+ }
201
+ }
202
+ }
203
+
204
+ return slugData;
205
+ };
206
+
207
+ const arrayTriggerMatch = (triggers: string[], re: RegExp) => {
208
+ const triggersMatch = triggers.map((trigger) => ({
209
+ triggerStr: trigger,
210
+ triggerMatch: trigger.match(re),
211
+ triggerLength: trigger.length,
212
+ }));
213
+
214
+ return triggersMatch;
215
+ };
216
+
217
+ const isTrigger = (trigger: string, str: string, i: number): boolean => {
218
+ if (!trigger || !trigger.length) {
219
+ return true;
220
+ }
221
+
222
+ if (str.substr(i, trigger.length) === trigger) {
223
+ return true;
224
+ }
225
+
226
+ return false;
227
+ };
228
+
229
+ const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
230
+ const { onChange, options, spaceRemovers, spacer, value } = props;
231
+
232
+ const old = recentValue;
233
+ const str = e.target.value;
234
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
235
+ const caret = (getInputSelection(getInputElement(e.target)) as {
236
+ start: number;
237
+ end: number;
238
+ }).end;
239
+
240
+ if (!str.length) {
241
+ updateState({
242
+ ...state,
243
+ helperVisible: false,
244
+ });
245
+ }
246
+
247
+ setRecentValue(str);
248
+
249
+ updateState({
250
+ ...state,
251
+ caret,
252
+ value: e.target.value,
253
+ });
254
+
255
+ if (!str.length || !caret) {
256
+ return onChange(e.target.value);
257
+ }
258
+
259
+ // '@wonderjenny ,|' -> '@wonderjenny, |'
260
+ if (
261
+ enableSpaceRemovers &&
262
+ spaceRemovers.length &&
263
+ str.length > 2 &&
264
+ spacer.length
265
+ ) {
266
+ for (let i = 0; i < Math.max(old.length, str.length); ++i) {
267
+ if (old[i] !== str[i]) {
268
+ if (
269
+ i >= 2 &&
270
+ str[i - 1] === spacer &&
271
+ spaceRemovers.indexOf(str[i - 2]) === -1 &&
272
+ spaceRemovers.indexOf(str[i]) !== -1 &&
273
+ getMatch(str.substring(0, i - 2), caret - 3, options) !== {}
274
+ ) {
275
+ const newValue = `${str.slice(0, i - 1)}${str.slice(
276
+ i,
277
+ i + 1
278
+ )}${str.slice(i - 1, i)}${str.slice(i + 1)}`;
279
+
280
+ updateCaretPosition(i + 1);
281
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
282
+ if (refInput.current !== null) {
283
+ ((refInput.current as unknown) as Record<
284
+ string,
285
+ unknown
286
+ >).value = newValue;
287
+ }
288
+
289
+ if (!value) {
290
+ updateState({
291
+ ...state,
292
+ value: newValue,
293
+ });
294
+ }
295
+
296
+ return onChange(newValue);
297
+ }
298
+
299
+ break;
300
+ }
301
+ }
302
+
303
+ setEnableSpaceRemovers(false);
304
+ }
305
+
306
+ updateHelper(str, caret, options);
307
+
308
+ // if (!value) {
309
+ // updateState({
310
+ // ...state,
311
+ // value: e.target.value
312
+ // });
313
+ // }
314
+
315
+ return onChange(e.target.value);
316
+ };
317
+
318
+ const getInputElement = (
319
+ parent: HTMLElement | undefined
320
+ ): HTMLElement | undefined => {
321
+ if (parent !== undefined) {
322
+ if (parent.children.length > 0) {
323
+ const innerTextAreas = parent.getElementsByTagName('textarea');
324
+ if (innerTextAreas.length > 0) {
325
+ return innerTextAreas[0];
326
+ }
327
+
328
+ const innerInputs = parent.getElementsByTagName('input');
329
+ if (innerInputs.length > 0) {
330
+ return innerInputs[0];
331
+ }
332
+ } else {
333
+ return parent;
334
+ }
335
+ }
336
+
337
+ return undefined;
338
+ };
339
+
340
+ const handleKeyDown = (event: KeyboardEvent) => {
341
+ const { helperVisible, options, selection } = state;
342
+ const { onKeyDown, passThroughEnter } = props;
343
+
344
+ if (helperVisible) {
345
+ switch (event.keyCode) {
346
+ case KEY_ESCAPE:
347
+ event.preventDefault();
348
+ resetHelper();
349
+ break;
350
+ case KEY_UP:
351
+ event.preventDefault();
352
+ updateState({
353
+ ...state,
354
+ selection: (options.length + selection - 1) % options.length,
355
+ });
356
+ break;
357
+ case KEY_DOWN:
358
+ event.preventDefault();
359
+ updateState({
360
+ ...state,
361
+ selection: (selection + 1) % options.length,
362
+ });
363
+ break;
364
+ case KEY_ENTER:
365
+ case KEY_RETURN:
366
+ if (!passThroughEnter) {
367
+ event.preventDefault();
368
+ }
369
+ handleSelection(selection);
370
+ break;
371
+ case KEY_TAB:
372
+ handleSelection(selection);
373
+ break;
374
+ default:
375
+ onKeyDown(event);
376
+ break;
377
+ }
378
+ } else {
379
+ onKeyDown(event);
380
+ }
381
+ };
382
+
383
+ const handleResize = () => {
384
+ updateState({
385
+ ...state,
386
+ helperVisible: false,
387
+ });
388
+ };
389
+
390
+ const handleSelection = (idx: number) => {
391
+ const { spacer, onSelect, changeOnSelect } = props;
392
+ const { matchStart, matchLength, options, trigger } = state;
393
+
394
+ const slug = options[idx];
395
+ const value = recentValue;
396
+ const part1 = value.substring(0, matchStart - trigger.length);
397
+ const part2 = value.substring(matchStart + matchLength);
398
+
399
+ const event = { target: refInput.current };
400
+ const changedStr = changeOnSelect(trigger, slug);
401
+
402
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
403
+ if (event.target !== null) {
404
+ ((event.target as unknown) as Record<
405
+ string,
406
+ unknown
407
+ >).value = `${part1}${changedStr}${spacer}${part2}`;
408
+ }
409
+ handleChange(event as any);
410
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
411
+ if (event.target !== null) {
412
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
413
+ onSelect((event.target as any).value);
414
+ }
415
+
416
+ resetHelper();
417
+
418
+ updateCaretPosition(part1.length + changedStr.length + 1);
419
+
420
+ setEnableSpaceRemovers(true);
421
+ };
422
+
423
+ const updateCaretPosition = (caret: number) => {
424
+ updateState({
425
+ ...state,
426
+ caret,
427
+ });
428
+
429
+ const input = getInputElement((refInput.current as unknown) as HTMLElement);
430
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
431
+ setCaretPosition(input, caret);
432
+ };
433
+
434
+ const updateState = (val: any) => {
435
+ setTimeout(() => {
436
+ setState({
437
+ ...val,
438
+ });
439
+ }, 0);
440
+ };
441
+
442
+ const updateHelper = (str: string, caret: number, options: string[]) => {
443
+ const parent = (refInput.current as unknown) as HTMLElement;
444
+ if (refInput.current === null) {
445
+ return;
446
+ }
447
+
448
+ const input = getInputElement(parent);
449
+ if (input === undefined) {
450
+ return;
451
+ }
452
+ const parentRect = parent.getBoundingClientRect();
453
+
454
+ const slug = getMatch(str, caret, options) as any;
455
+
456
+ if (Object.keys(slug).length > 0 && input !== null) {
457
+ const caretPos = getCaretCoordinates(input, caret);
458
+ const rect = input.getBoundingClientRect();
459
+ const {
460
+ minChars,
461
+ onRequestOptions,
462
+ requestOnlyIfNoOptions,
463
+ mode,
464
+ } = props;
465
+
466
+ let top,
467
+ left,
468
+ right,
469
+ width = 'unset';
470
+ if (mode === 'assist') {
471
+ top =
472
+ parent === input
473
+ ? caretPos.top + input.offsetTop
474
+ : caretPos.top + parentRect.top;
475
+ left = Math.min(
476
+ caretPos.left + input.offsetLeft - OPTION_LIST_Y_OFFSET,
477
+ input.offsetLeft + rect.width - OPTION_LIST_MIN_WIDTH
478
+ );
479
+ } else {
480
+ top = parentRect.top + parent.offsetHeight;
481
+ left = parent.offsetLeft;
482
+ right = parent.offsetLeft - parent.offsetWidth;
483
+ width = `${parentRect.width}px`;
484
+ }
485
+
486
+ if (
487
+ slug.matchLength >= minChars &&
488
+ (slug.options.length > 1 ||
489
+ (slug.options.length === 1 &&
490
+ slug.options[0].length !== slug.matchLength))
491
+ ) {
492
+ updateState({
493
+ ...state,
494
+ value: str,
495
+ helperVisible: true,
496
+ top,
497
+ left,
498
+ right,
499
+ width,
500
+ ...slug,
501
+ });
502
+ } else {
503
+ if (!requestOnlyIfNoOptions || !slug.options.length) {
504
+ onRequestOptions(str.substr(slug.matchStart, slug.matchLength));
505
+ }
506
+
507
+ resetHelper();
508
+ }
509
+ } else {
510
+ resetHelper();
511
+ }
512
+ };
513
+
514
+ const resetHelper = () => {
515
+ const timeDelay = 100;
516
+ setTimeout(() => {
517
+ updateState({
518
+ ...state,
519
+ helperVisible: false,
520
+ selection: 0,
521
+ });
522
+ }, timeDelay);
523
+ };
524
+
525
+ const renderAutocompleteList = () => {
526
+ const {
527
+ helperVisible,
528
+ left,
529
+ right,
530
+ matchStart,
531
+ matchLength,
532
+ options,
533
+ selection,
534
+ top,
535
+ value,
536
+ width,
537
+ } = state;
538
+
539
+ if (!helperVisible) {
540
+ return null;
541
+ }
542
+
543
+ const { maxOptions, offsetX, offsetY, direction } = props;
544
+
545
+ if (options.length === 0) {
546
+ return null;
547
+ }
548
+
549
+ if (selection >= options.length) {
550
+ updateState({
551
+ ...state,
552
+ selection: 0,
553
+ });
554
+
555
+ return null;
556
+ }
557
+
558
+ const optionNumber = maxOptions === 0 ? options.length : maxOptions;
559
+
560
+ const helperOptions = options
561
+ .slice(0, optionNumber)
562
+ .map((val: string, idx) => {
563
+ const highlightStart = val
564
+ .toLowerCase()
565
+ .indexOf(value.substr(matchStart, matchLength).toLowerCase());
566
+
567
+ return (
568
+ <li
569
+ className={idx === selection ? 'active' : undefined}
570
+ key={val}
571
+ onClick={() => {
572
+ handleSelection(idx);
573
+ }}
574
+ onMouseEnter={() => {
575
+ updateState({
576
+ ...state,
577
+ selection: idx,
578
+ });
579
+ }}
580
+ >
581
+ {val.slice(0, highlightStart)}
582
+ <strong>{val.substr(highlightStart, matchLength)}</strong>
583
+ {val.slice(highlightStart + matchLength)}
584
+ </li>
585
+ );
586
+ });
587
+
588
+ const horizontalPosition =
589
+ direction === 'ltr'
590
+ ? { left: left + offsetX }
591
+ : { right: right + offsetX };
592
+ return (
593
+ <ul
594
+ className="react-autocomplete-input"
595
+ style={{ ...horizontalPosition, top: top + offsetY, width }}
596
+ >
597
+ {helperOptions}
598
+ </ul>
599
+ );
600
+ };
601
+
602
+ const {
603
+ Component,
604
+ ComponentProps,
605
+ defaultValue,
606
+ disabled,
607
+ onBlur,
608
+ value,
609
+ ...rest
610
+ } = props;
611
+
612
+ const propagated: any = Object.assign({}, rest);
613
+ Object.keys(props).forEach((k) => {
614
+ delete (propagated as Record<string, unknown>)[k];
615
+ });
616
+
617
+ return (
618
+ <>
619
+ {React.cloneElement(Component, {
620
+ disabled: disabled,
621
+ onBlur: onBlur,
622
+ onChange: handleChange,
623
+ onKeyDown: handleKeyDown,
624
+ ref: refInput,
625
+ value: recentValue,
626
+ ...propagated,
627
+ ...ComponentProps,
628
+ })}
629
+ {renderAutocompleteList()}
630
+ </>
631
+ );
632
+ };
633
+
634
+ const defaultProps: IAutocompleteProps = {
635
+ Component: <textarea />,
636
+ ComponentProps: {},
637
+ defaultValue: undefined,
638
+ disabled: false,
639
+ maxOptions: 6,
640
+ onBlur: (evt: any) => {},
641
+ onChange: (val: string) => {},
642
+ onKeyDown: (evt: any) => {},
643
+ onRequestOptions: (val: string) => {},
644
+ onSelect: (val: string) => {},
645
+ changeOnSelect: (trigger: string, slug: string): string =>
646
+ `${trigger}${slug}`,
647
+ options: [],
648
+ regex: '^[A-Za-z0-9\\-_]+$',
649
+ matchAny: false,
650
+ minChars: 0,
651
+ requestOnlyIfNoOptions: true,
652
+ spaceRemovers: [',', '.', '!', '?'],
653
+ spacer: ' ',
654
+ trigger: '@',
655
+ offsetX: 0,
656
+ offsetY: 0,
657
+ value: undefined,
658
+ passThroughEnter: false,
659
+ mode: 'assist',
660
+ direction: 'ltr',
661
+ };
662
+
663
+ interface IAutocompleteOptionalProps extends Partial<IAutocompleteProps> {}
664
+ export const AutocompleteWithDefauls: React.FC<IAutocompleteOptionalProps> = (
665
+ props
666
+ ) => {
667
+ let compProps = {
668
+ ...defaultProps,
669
+ ...props,
670
+ };
671
+ if (props.mode === 'autocomplete') {
672
+ compProps = {
673
+ ...compProps,
674
+ trigger: '',
675
+ regex: '.',
676
+ spacer: '',
677
+ };
678
+ }
679
+ return <Autocomplete {...compProps} />;
680
+ };
681
+ export default AutocompleteWithDefauls;