@biodiv-platform/naksha-maplibre-layers 5.0.3 → 5.0.5

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.
package/dist/esm/index.js CHANGED
@@ -149,7 +149,10 @@ var locales_default = { en: en_default, fr: fr_default, hi: hi_default };
149
149
  // src/components/map/index.tsx
150
150
  import { defaultViewState as defaultViewState2 } from "@biodiv-platform/naksha-commons";
151
151
  import { useMemo as useMemo7, useState as useState10 } from "react";
152
- import MapGL, { NavigationControl } from "react-map-gl/maplibre";
152
+ import MapGL, {
153
+ FullscreenControl,
154
+ NavigationControl
155
+ } from "react-map-gl/maplibre";
153
156
  import { tw as tw20 } from "twind";
154
157
 
155
158
  // src/hooks/use-layers.tsx
@@ -251,27 +254,27 @@ var processRectangles = function(data, level) {
251
254
  counts.forEach((count, hash) => {
252
255
  const bboxStart = GeoHash.decodeGeoHash(hash);
253
256
  const bboxEnd = GeoHash.decodeGeoHash(bins.get(hash));
254
- const feature = new BoundingBox({
257
+ const feature2 = new BoundingBox({
255
258
  minlat: bboxStart.latitude[0],
256
259
  minlon: bboxStart.longitude[0],
257
260
  maxlat: bboxEnd.latitude[1],
258
261
  maxlon: bboxEnd.longitude[1]
259
262
  }).toGeoJSON();
260
- features.push(__spreadProps(__spreadValues({}, feature), { properties: { count, [PROPERTY_ID]: hash } }));
263
+ features.push(__spreadProps(__spreadValues({}, feature2), { properties: { count, [PROPERTY_ID]: hash } }));
261
264
  });
262
265
  return features;
263
266
  };
264
267
  var processSquares = (data) => {
265
268
  const features = [];
266
269
  for (const [hash, count] of Object.entries(data)) {
267
- const bbox = GeoHash.decodeGeoHash(hash);
268
- const feature = new BoundingBox({
269
- minlat: bbox.latitude[0],
270
- minlon: bbox.longitude[0],
271
- maxlat: bbox.latitude[1],
272
- maxlon: bbox.longitude[1]
270
+ const bbox2 = GeoHash.decodeGeoHash(hash);
271
+ const feature2 = new BoundingBox({
272
+ minlat: bbox2.latitude[0],
273
+ minlon: bbox2.longitude[0],
274
+ maxlat: bbox2.latitude[1],
275
+ maxlon: bbox2.longitude[1]
273
276
  }).toGeoJSON();
274
- features.push(__spreadProps(__spreadValues({}, feature), { properties: { count, [PROPERTY_ID]: hash } }));
277
+ features.push(__spreadProps(__spreadValues({}, feature2), { properties: { count, [PROPERTY_ID]: hash } }));
275
278
  }
276
279
  return features;
277
280
  };
@@ -488,8 +491,12 @@ var LayersProvider = ({ mp: _mp, children }) => {
488
491
  const [queryTerm, setQueryTerm] = useState("");
489
492
  const queryTermDebounced = useDebounce(queryTerm, 500);
490
493
  const styles = mp.mapStyles && mp.mapStyles.length > 0 ? mp.mapStyles : defaultMapStyles;
491
- const [mapStyle, setMapStyle] = useState((_a = styles[(mp == null ? void 0 : mp.mapStyle) || 0]) == null ? void 0 : _a.style);
492
- const [maxZoom, setMaxZoom] = useState((_b = styles[(mp == null ? void 0 : mp.mapStyle) || 0]) == null ? void 0 : _b.maxZoom);
494
+ const [mapStyle, setMapStyle] = useState(
495
+ (_a = styles[(mp == null ? void 0 : mp.mapStyle) || 0]) == null ? void 0 : _a.style
496
+ );
497
+ const [maxZoom, setMaxZoom] = useState(
498
+ (_b = styles[(mp == null ? void 0 : mp.mapStyle) || 0]) == null ? void 0 : _b.maxZoom
499
+ );
493
500
  const [selectionStyle, setSelectionStyle] = useState(
494
501
  SELECTION_STYLE.TOP
495
502
  );
@@ -587,7 +594,7 @@ var LayersProvider = ({ mp: _mp, children }) => {
587
594
  styleIndex = 0,
588
595
  focus = true
589
596
  }) {
590
- var _a2;
597
+ var _a2, _b2;
591
598
  if (!add) {
592
599
  setSelectedLayerIds(
593
600
  selectedLayerIds.filter((_lyrId) => layerId !== _lyrId)
@@ -596,11 +603,26 @@ var LayersProvider = ({ mp: _mp, children }) => {
596
603
  }
597
604
  const layerIndex = getLayerIndexById(layerId);
598
605
  const sourceType = (_a2 = layers[layerIndex]) == null ? void 0 : _a2.source.type;
599
- yield toggleVectorLayer(layerIndex, styleIndex, focus);
600
- setSelectedLayerIds((_slIds) => [
601
- layerId,
602
- ..._slIds.filter((lid) => lid !== layerId)
603
- ]);
606
+ if (sourceType === "grid") {
607
+ setSelectedLayerIds((_slIds) => [
608
+ layerId,
609
+ ..._slIds.filter((lid) => lid !== layerId)
610
+ ]);
611
+ if (focus && ((_b2 = layers[layerIndex]) == null ? void 0 : _b2.bbox)) {
612
+ setTimeout(() => {
613
+ mapl == null ? void 0 : mapl.fitBounds(layers[layerIndex].bbox, {
614
+ padding: 40,
615
+ duration: 1e3
616
+ });
617
+ }, 100);
618
+ }
619
+ } else {
620
+ yield toggleVectorLayer(layerIndex, styleIndex, focus);
621
+ setSelectedLayerIds((_slIds) => [
622
+ layerId,
623
+ ..._slIds.filter((lid) => lid !== layerId)
624
+ ]);
625
+ }
604
626
  });
605
627
  const clearAllLayers = () => __async(void 0, null, function* () {
606
628
  return setSelectedLayerIds([]);
@@ -1378,7 +1400,6 @@ import { tw as tw13 } from "twind";
1378
1400
  // src/components/sidebar/common/layer-item.tsx
1379
1401
  import { useT as useT6 } from "@biodiv-platform/naksha-commons";
1380
1402
  import { useMemo as useMemo3, useState as useState6 } from "react";
1381
- import { SortableHandle } from "react-sortable-hoc";
1382
1403
  import { RWebShare } from "react-web-share";
1383
1404
  import { tw as tw12 } from "twind";
1384
1405
 
@@ -1687,13 +1708,29 @@ function LayerItemStyle({ item }) {
1687
1708
 
1688
1709
  // src/components/sidebar/common/layer-item.tsx
1689
1710
  import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
1690
- var DragHandle = SortableHandle(() => /* @__PURE__ */ jsx16("div", {
1691
- className: tw12`mt-1 w-6 text-center cursor-move`,
1692
- children: /* @__PURE__ */ jsx16(GrabberIcon, {})
1693
- }));
1694
- function LayerItem({ item, extended }) {
1711
+ function DragHandle({
1712
+ dragHandleProps
1713
+ }) {
1714
+ return /* @__PURE__ */ jsx16("div", __spreadProps(__spreadValues({
1715
+ className: tw12`mt-1 w-6 text-center cursor-move`,
1716
+ style: { touchAction: "none" }
1717
+ }, dragHandleProps), {
1718
+ children: /* @__PURE__ */ jsx16(GrabberIcon, {})
1719
+ }));
1720
+ }
1721
+ function LayerItem({
1722
+ item,
1723
+ extended,
1724
+ dragHandleProps
1725
+ }) {
1695
1726
  const { t } = useT6();
1696
- const { layer, query, mp, query: { setClickedLngLat }, setIsInfoBarOpen } = useLayers();
1727
+ const {
1728
+ layer,
1729
+ query,
1730
+ mp,
1731
+ query: { setClickedLngLat },
1732
+ setIsInfoBarOpen
1733
+ } = useLayers();
1697
1734
  const [isAdded, setIsAdded] = useState6(layer.selectedIds.includes(item.id));
1698
1735
  const [isLoading, setIsLoading] = useState6(false);
1699
1736
  const shareData = useMemo3(
@@ -1738,7 +1775,9 @@ function LayerItem({ item, extended }) {
1738
1775
  onChange: onToggleLayer,
1739
1776
  isLoading
1740
1777
  }),
1741
- extended && /* @__PURE__ */ jsx16(DragHandle, {})
1778
+ extended && /* @__PURE__ */ jsx16(DragHandle, {
1779
+ dragHandleProps
1780
+ })
1742
1781
  ]
1743
1782
  }),
1744
1783
  /* @__PURE__ */ jsx16("img", {
@@ -1902,19 +1941,63 @@ function arrayMoveImmutable(array, fromIndex, toIndex) {
1902
1941
  }
1903
1942
 
1904
1943
  // src/components/sidebar/selected/selected-item-list.tsx
1905
- import { SortableContainer, SortableElement } from "react-sortable-hoc";
1944
+ import {
1945
+ closestCenter,
1946
+ DndContext,
1947
+ PointerSensor,
1948
+ useSensor,
1949
+ useSensors
1950
+ } from "@dnd-kit/core";
1951
+ import { SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
1952
+ import { CSS } from "@dnd-kit/utilities";
1906
1953
  import { jsx as jsx20 } from "react/jsx-runtime";
1907
- var SelectedItem = SortableElement(({ item, extended }) => /* @__PURE__ */ jsx20(LayerItem, {
1908
- item,
1909
- extended
1910
- }));
1911
- var SelectedItemList = SortableContainer(({ layerList }) => /* @__PURE__ */ jsx20("div", {
1912
- children: layerList.map((item, index) => /* @__PURE__ */ jsx20(SelectedItem, {
1913
- index,
1914
- item,
1915
- extended: true
1916
- }, item.id))
1917
- }));
1954
+ function SortableSelectedItem({ item, extended }) {
1955
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
1956
+ id: item.id
1957
+ });
1958
+ const style = {
1959
+ transform: CSS.Transform.toString(transform),
1960
+ transition,
1961
+ opacity: isDragging ? 0.5 : 1
1962
+ };
1963
+ return /* @__PURE__ */ jsx20("div", {
1964
+ ref: setNodeRef,
1965
+ style,
1966
+ children: /* @__PURE__ */ jsx20(LayerItem, {
1967
+ item,
1968
+ extended,
1969
+ dragHandleProps: __spreadValues(__spreadValues({}, attributes), listeners)
1970
+ })
1971
+ });
1972
+ }
1973
+ var SelectedItemList = ({ layerList, onSortEnd }) => {
1974
+ const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));
1975
+ const handleDragEnd = (event) => {
1976
+ const { active, over } = event;
1977
+ if (over && active.id !== over.id) {
1978
+ const oldIndex = layerList.findIndex((item) => item.id === active.id);
1979
+ const newIndex = layerList.findIndex((item) => item.id === over.id);
1980
+ if (oldIndex !== -1 && newIndex !== -1) {
1981
+ onSortEnd({ oldIndex, newIndex });
1982
+ }
1983
+ }
1984
+ };
1985
+ return /* @__PURE__ */ jsx20(DndContext, {
1986
+ sensors,
1987
+ collisionDetection: closestCenter,
1988
+ onDragEnd: handleDragEnd,
1989
+ children: /* @__PURE__ */ jsx20(SortableContext, {
1990
+ items: layerList.map((item) => item.id),
1991
+ strategy: verticalListSortingStrategy,
1992
+ children: /* @__PURE__ */ jsx20("div", {
1993
+ children: layerList.map((item) => /* @__PURE__ */ jsx20(SortableSelectedItem, {
1994
+ item,
1995
+ extended: true
1996
+ }, item.id))
1997
+ })
1998
+ })
1999
+ });
2000
+ };
1918
2001
 
1919
2002
  // src/components/sidebar/selected/index.tsx
1920
2003
  import { useT as useT8 } from "@biodiv-platform/naksha-commons";
@@ -2066,6 +2149,170 @@ function Sidebar() {
2066
2149
  // src/components/map/layers/index.tsx
2067
2150
  import { useMap as useMap4 } from "react-map-gl/maplibre";
2068
2151
 
2152
+ // ../../node_modules/@turf/helpers/dist/es/index.js
2153
+ var earthRadius = 63710088e-1;
2154
+ var factors = {
2155
+ centimeters: earthRadius * 100,
2156
+ centimetres: earthRadius * 100,
2157
+ degrees: earthRadius / 111325,
2158
+ feet: earthRadius * 3.28084,
2159
+ inches: earthRadius * 39.37,
2160
+ kilometers: earthRadius / 1e3,
2161
+ kilometres: earthRadius / 1e3,
2162
+ meters: earthRadius,
2163
+ metres: earthRadius,
2164
+ miles: earthRadius / 1609.344,
2165
+ millimeters: earthRadius * 1e3,
2166
+ millimetres: earthRadius * 1e3,
2167
+ nauticalmiles: earthRadius / 1852,
2168
+ radians: 1,
2169
+ yards: earthRadius * 1.0936
2170
+ };
2171
+ var unitsFactors = {
2172
+ centimeters: 100,
2173
+ centimetres: 100,
2174
+ degrees: 1 / 111325,
2175
+ feet: 3.28084,
2176
+ inches: 39.37,
2177
+ kilometers: 1 / 1e3,
2178
+ kilometres: 1 / 1e3,
2179
+ meters: 1,
2180
+ metres: 1,
2181
+ miles: 1 / 1609.344,
2182
+ millimeters: 1e3,
2183
+ millimetres: 1e3,
2184
+ nauticalmiles: 1 / 1852,
2185
+ radians: 1 / earthRadius,
2186
+ yards: 1.0936133
2187
+ };
2188
+
2189
+ // ../../node_modules/@turf/meta/dist/es/index.js
2190
+ function coordEach(geojson, callback, excludeWrapCoord) {
2191
+ if (geojson === null)
2192
+ return;
2193
+ var j, k, l, geometry, stopG, coords, geometryMaybeCollection, wrapShrink = 0, coordIndex = 0, isGeometryCollection, type = geojson.type, isFeatureCollection = type === "FeatureCollection", isFeature = type === "Feature", stop = isFeatureCollection ? geojson.features.length : 1;
2194
+ for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
2195
+ geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
2196
+ isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
2197
+ stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
2198
+ for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
2199
+ var multiFeatureIndex = 0;
2200
+ var geometryIndex = 0;
2201
+ geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
2202
+ if (geometry === null)
2203
+ continue;
2204
+ coords = geometry.coordinates;
2205
+ var geomType = geometry.type;
2206
+ wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
2207
+ switch (geomType) {
2208
+ case null:
2209
+ break;
2210
+ case "Point":
2211
+ if (callback(
2212
+ coords,
2213
+ coordIndex,
2214
+ featureIndex,
2215
+ multiFeatureIndex,
2216
+ geometryIndex
2217
+ ) === false)
2218
+ return false;
2219
+ coordIndex++;
2220
+ multiFeatureIndex++;
2221
+ break;
2222
+ case "LineString":
2223
+ case "MultiPoint":
2224
+ for (j = 0; j < coords.length; j++) {
2225
+ if (callback(
2226
+ coords[j],
2227
+ coordIndex,
2228
+ featureIndex,
2229
+ multiFeatureIndex,
2230
+ geometryIndex
2231
+ ) === false)
2232
+ return false;
2233
+ coordIndex++;
2234
+ if (geomType === "MultiPoint")
2235
+ multiFeatureIndex++;
2236
+ }
2237
+ if (geomType === "LineString")
2238
+ multiFeatureIndex++;
2239
+ break;
2240
+ case "Polygon":
2241
+ case "MultiLineString":
2242
+ for (j = 0; j < coords.length; j++) {
2243
+ for (k = 0; k < coords[j].length - wrapShrink; k++) {
2244
+ if (callback(
2245
+ coords[j][k],
2246
+ coordIndex,
2247
+ featureIndex,
2248
+ multiFeatureIndex,
2249
+ geometryIndex
2250
+ ) === false)
2251
+ return false;
2252
+ coordIndex++;
2253
+ }
2254
+ if (geomType === "MultiLineString")
2255
+ multiFeatureIndex++;
2256
+ if (geomType === "Polygon")
2257
+ geometryIndex++;
2258
+ }
2259
+ if (geomType === "Polygon")
2260
+ multiFeatureIndex++;
2261
+ break;
2262
+ case "MultiPolygon":
2263
+ for (j = 0; j < coords.length; j++) {
2264
+ geometryIndex = 0;
2265
+ for (k = 0; k < coords[j].length; k++) {
2266
+ for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
2267
+ if (callback(
2268
+ coords[j][k][l],
2269
+ coordIndex,
2270
+ featureIndex,
2271
+ multiFeatureIndex,
2272
+ geometryIndex
2273
+ ) === false)
2274
+ return false;
2275
+ coordIndex++;
2276
+ }
2277
+ geometryIndex++;
2278
+ }
2279
+ multiFeatureIndex++;
2280
+ }
2281
+ break;
2282
+ case "GeometryCollection":
2283
+ for (j = 0; j < geometry.geometries.length; j++)
2284
+ if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
2285
+ return false;
2286
+ break;
2287
+ default:
2288
+ throw new Error("Unknown Geometry Type");
2289
+ }
2290
+ }
2291
+ }
2292
+ }
2293
+
2294
+ // ../../node_modules/@turf/bbox/dist/es/index.js
2295
+ function bbox(geojson) {
2296
+ var result = [Infinity, Infinity, -Infinity, -Infinity];
2297
+ coordEach(geojson, function(coord) {
2298
+ if (result[0] > coord[0]) {
2299
+ result[0] = coord[0];
2300
+ }
2301
+ if (result[1] > coord[1]) {
2302
+ result[1] = coord[1];
2303
+ }
2304
+ if (result[2] < coord[0]) {
2305
+ result[2] = coord[0];
2306
+ }
2307
+ if (result[3] < coord[1]) {
2308
+ result[3] = coord[1];
2309
+ }
2310
+ });
2311
+ return result;
2312
+ }
2313
+ bbox["default"] = bbox;
2314
+ var es_default = bbox;
2315
+
2069
2316
  // src/components/map/layers/grid/index.tsx
2070
2317
  import { useEffect as useEffect4, useState as useState9 } from "react";
2071
2318
  import { Layer, Source, useMap as useMap3 } from "react-map-gl/maplibre";
@@ -2077,7 +2324,9 @@ function GridLayer({
2077
2324
  const { layer } = useLayers();
2078
2325
  const { mapl } = useMap3();
2079
2326
  const [layerData, setLayerData] = useState9({ geojson: {}, paint: {} });
2080
- const fetchGridData = () => __async(this, null, function* () {
2327
+ const isSelected = layer.selectedIds.includes(data.id);
2328
+ const isLastSelected = layer.selectedIds[0] === data.id;
2329
+ const fetchGridData = (shouldFitBounds = false) => __async(this, null, function* () {
2081
2330
  const { success, geojson, paint: paint2, stops, squareSize } = yield getGridLayerData(
2082
2331
  data.source.fetcher,
2083
2332
  mapl == null ? void 0 : mapl.getBounds(),
@@ -2085,14 +2334,50 @@ function GridLayer({
2085
2334
  );
2086
2335
  if (success) {
2087
2336
  setLayerData({ geojson, paint: paint2 });
2337
+ if (shouldFitBounds && isLastSelected && data.zoomToFit) {
2338
+ try {
2339
+ const [minLon, minLat, maxLon, maxLat] = es_default(geojson);
2340
+ mapl == null ? void 0 : mapl.fitBounds(
2341
+ [
2342
+ [minLon, minLat],
2343
+ [maxLon, maxLat]
2344
+ ],
2345
+ { padding: 40, animate: true }
2346
+ );
2347
+ } catch (e) {
2348
+ console.warn("Failed to compute bbox", e);
2349
+ }
2350
+ }
2088
2351
  layer.setGridLegends({
2089
2352
  [data.id]: { stops, squareSize }
2090
2353
  });
2091
2354
  }
2092
2355
  });
2093
2356
  useEffect4(() => {
2094
- mapl == null ? void 0 : mapl.on("idle", fetchGridData);
2095
- }, []);
2357
+ if (isSelected && isLastSelected) {
2358
+ fetchGridData(true);
2359
+ } else if (isSelected) {
2360
+ fetchGridData(false);
2361
+ }
2362
+ }, [isSelected, isLastSelected]);
2363
+ useEffect4(() => {
2364
+ if (!isSelected || !mapl)
2365
+ return;
2366
+ const handleIdle = () => fetchGridData(false);
2367
+ mapl.on("idle", handleIdle);
2368
+ return () => {
2369
+ mapl.off("idle", handleIdle);
2370
+ };
2371
+ }, [isSelected, mapl]);
2372
+ useEffect4(() => {
2373
+ return () => {
2374
+ layer.setGridLegends((prev) => {
2375
+ const newLegends = __spreadValues({}, prev);
2376
+ delete newLegends[data.id];
2377
+ return newLegends;
2378
+ });
2379
+ };
2380
+ }, [data.id]);
2096
2381
  return /* @__PURE__ */ jsx25(Source, {
2097
2382
  id: data.id,
2098
2383
  type: "geojson",
@@ -2296,7 +2581,6 @@ function Map2() {
2296
2581
  setCoordinates(event.lngLat);
2297
2582
  hover.onHover(event);
2298
2583
  };
2299
- console.info("NakshaMaplibreLayers props");
2300
2584
  return /* @__PURE__ */ jsxs18("div", {
2301
2585
  className: tw20`h-full w-full relative bg-gray-100`,
2302
2586
  children: [
@@ -2317,6 +2601,9 @@ function Map2() {
2317
2601
  showZoom: true,
2318
2602
  showCompass: true
2319
2603
  }),
2604
+ mp.showFullscreenControl && /* @__PURE__ */ jsx31(FullscreenControl, {
2605
+ position: "bottom-right"
2606
+ }),
2320
2607
  /* @__PURE__ */ jsx31(markers_list_default, {}),
2321
2608
  layer.selectedLayers.map((_l, index) => {
2322
2609
  const beforeId = index > 0 ? layer.selectedIds[index - 1] : void 0;
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ interface NakshaMaplibreLayersProps {
11
11
  defaultViewState?: Partial<ViewState>;
12
12
  loadToC?: boolean;
13
13
  showToC?: boolean;
14
+ showFullscreenControl?: boolean;
14
15
  managePublishing?: boolean;
15
16
  nakshaEndpointToken?: string;
16
17
  nakshaApiEndpoint?: string;
@@ -60,6 +61,7 @@ interface GeoserverLayer {
60
61
  createdDate?: string;
61
62
  isDownloadable?: boolean;
62
63
  bbox?: any[];
64
+ zoomToFit?: boolean;
63
65
  isAdded?: boolean;
64
66
  ats?: any;
65
67
  source: {
package/dist/index.js CHANGED
@@ -272,27 +272,27 @@ var processRectangles = function(data, level) {
272
272
  counts.forEach((count, hash) => {
273
273
  const bboxStart = import_geohash.GeoHash.decodeGeoHash(hash);
274
274
  const bboxEnd = import_geohash.GeoHash.decodeGeoHash(bins.get(hash));
275
- const feature = new import_boundingbox.default({
275
+ const feature2 = new import_boundingbox.default({
276
276
  minlat: bboxStart.latitude[0],
277
277
  minlon: bboxStart.longitude[0],
278
278
  maxlat: bboxEnd.latitude[1],
279
279
  maxlon: bboxEnd.longitude[1]
280
280
  }).toGeoJSON();
281
- features.push(__spreadProps(__spreadValues({}, feature), { properties: { count, [PROPERTY_ID]: hash } }));
281
+ features.push(__spreadProps(__spreadValues({}, feature2), { properties: { count, [PROPERTY_ID]: hash } }));
282
282
  });
283
283
  return features;
284
284
  };
285
285
  var processSquares = (data) => {
286
286
  const features = [];
287
287
  for (const [hash, count] of Object.entries(data)) {
288
- const bbox = import_geohash.GeoHash.decodeGeoHash(hash);
289
- const feature = new import_boundingbox.default({
290
- minlat: bbox.latitude[0],
291
- minlon: bbox.longitude[0],
292
- maxlat: bbox.latitude[1],
293
- maxlon: bbox.longitude[1]
288
+ const bbox2 = import_geohash.GeoHash.decodeGeoHash(hash);
289
+ const feature2 = new import_boundingbox.default({
290
+ minlat: bbox2.latitude[0],
291
+ minlon: bbox2.longitude[0],
292
+ maxlat: bbox2.latitude[1],
293
+ maxlon: bbox2.longitude[1]
294
294
  }).toGeoJSON();
295
- features.push(__spreadProps(__spreadValues({}, feature), { properties: { count, [PROPERTY_ID]: hash } }));
295
+ features.push(__spreadProps(__spreadValues({}, feature2), { properties: { count, [PROPERTY_ID]: hash } }));
296
296
  }
297
297
  return features;
298
298
  };
@@ -509,8 +509,12 @@ var LayersProvider = ({ mp: _mp, children }) => {
509
509
  const [queryTerm, setQueryTerm] = (0, import_react.useState)("");
510
510
  const queryTermDebounced = (0, import_naksha_commons2.useDebounce)(queryTerm, 500);
511
511
  const styles = mp.mapStyles && mp.mapStyles.length > 0 ? mp.mapStyles : import_naksha_commons2.defaultMapStyles;
512
- const [mapStyle, setMapStyle] = (0, import_react.useState)((_a = styles[(mp == null ? void 0 : mp.mapStyle) || 0]) == null ? void 0 : _a.style);
513
- const [maxZoom, setMaxZoom] = (0, import_react.useState)((_b = styles[(mp == null ? void 0 : mp.mapStyle) || 0]) == null ? void 0 : _b.maxZoom);
512
+ const [mapStyle, setMapStyle] = (0, import_react.useState)(
513
+ (_a = styles[(mp == null ? void 0 : mp.mapStyle) || 0]) == null ? void 0 : _a.style
514
+ );
515
+ const [maxZoom, setMaxZoom] = (0, import_react.useState)(
516
+ (_b = styles[(mp == null ? void 0 : mp.mapStyle) || 0]) == null ? void 0 : _b.maxZoom
517
+ );
514
518
  const [selectionStyle, setSelectionStyle] = (0, import_react.useState)(
515
519
  SELECTION_STYLE.TOP
516
520
  );
@@ -608,7 +612,7 @@ var LayersProvider = ({ mp: _mp, children }) => {
608
612
  styleIndex = 0,
609
613
  focus = true
610
614
  }) {
611
- var _a2;
615
+ var _a2, _b2;
612
616
  if (!add) {
613
617
  setSelectedLayerIds(
614
618
  selectedLayerIds.filter((_lyrId) => layerId !== _lyrId)
@@ -617,11 +621,26 @@ var LayersProvider = ({ mp: _mp, children }) => {
617
621
  }
618
622
  const layerIndex = getLayerIndexById(layerId);
619
623
  const sourceType = (_a2 = layers[layerIndex]) == null ? void 0 : _a2.source.type;
620
- yield toggleVectorLayer(layerIndex, styleIndex, focus);
621
- setSelectedLayerIds((_slIds) => [
622
- layerId,
623
- ..._slIds.filter((lid) => lid !== layerId)
624
- ]);
624
+ if (sourceType === "grid") {
625
+ setSelectedLayerIds((_slIds) => [
626
+ layerId,
627
+ ..._slIds.filter((lid) => lid !== layerId)
628
+ ]);
629
+ if (focus && ((_b2 = layers[layerIndex]) == null ? void 0 : _b2.bbox)) {
630
+ setTimeout(() => {
631
+ mapl == null ? void 0 : mapl.fitBounds(layers[layerIndex].bbox, {
632
+ padding: 40,
633
+ duration: 1e3
634
+ });
635
+ }, 100);
636
+ }
637
+ } else {
638
+ yield toggleVectorLayer(layerIndex, styleIndex, focus);
639
+ setSelectedLayerIds((_slIds) => [
640
+ layerId,
641
+ ..._slIds.filter((lid) => lid !== layerId)
642
+ ]);
643
+ }
625
644
  });
626
645
  const clearAllLayers = () => __async(void 0, null, function* () {
627
646
  return setSelectedLayerIds([]);
@@ -1399,7 +1418,6 @@ var import_twind13 = require("twind");
1399
1418
  // src/components/sidebar/common/layer-item.tsx
1400
1419
  var import_naksha_commons8 = require("@biodiv-platform/naksha-commons");
1401
1420
  var import_react7 = require("react");
1402
- var import_react_sortable_hoc = require("react-sortable-hoc");
1403
1421
  var import_react_web_share = require("react-web-share");
1404
1422
  var import_twind12 = require("twind");
1405
1423
 
@@ -1708,13 +1726,29 @@ function LayerItemStyle({ item }) {
1708
1726
 
1709
1727
  // src/components/sidebar/common/layer-item.tsx
1710
1728
  var import_jsx_runtime16 = require("react/jsx-runtime");
1711
- var DragHandle = (0, import_react_sortable_hoc.SortableHandle)(() => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", {
1712
- className: import_twind12.tw`mt-1 w-6 text-center cursor-move`,
1713
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(GrabberIcon, {})
1714
- }));
1715
- function LayerItem({ item, extended }) {
1729
+ function DragHandle({
1730
+ dragHandleProps
1731
+ }) {
1732
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", __spreadProps(__spreadValues({
1733
+ className: import_twind12.tw`mt-1 w-6 text-center cursor-move`,
1734
+ style: { touchAction: "none" }
1735
+ }, dragHandleProps), {
1736
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(GrabberIcon, {})
1737
+ }));
1738
+ }
1739
+ function LayerItem({
1740
+ item,
1741
+ extended,
1742
+ dragHandleProps
1743
+ }) {
1716
1744
  const { t } = (0, import_naksha_commons8.useT)();
1717
- const { layer, query, mp, query: { setClickedLngLat }, setIsInfoBarOpen } = useLayers();
1745
+ const {
1746
+ layer,
1747
+ query,
1748
+ mp,
1749
+ query: { setClickedLngLat },
1750
+ setIsInfoBarOpen
1751
+ } = useLayers();
1718
1752
  const [isAdded, setIsAdded] = (0, import_react7.useState)(layer.selectedIds.includes(item.id));
1719
1753
  const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
1720
1754
  const shareData = (0, import_react7.useMemo)(
@@ -1759,7 +1793,9 @@ function LayerItem({ item, extended }) {
1759
1793
  onChange: onToggleLayer,
1760
1794
  isLoading
1761
1795
  }),
1762
- extended && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DragHandle, {})
1796
+ extended && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DragHandle, {
1797
+ dragHandleProps
1798
+ })
1763
1799
  ]
1764
1800
  }),
1765
1801
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("img", {
@@ -1923,19 +1959,57 @@ function arrayMoveImmutable(array, fromIndex, toIndex) {
1923
1959
  }
1924
1960
 
1925
1961
  // src/components/sidebar/selected/selected-item-list.tsx
1926
- var import_react_sortable_hoc2 = require("react-sortable-hoc");
1962
+ var import_core9 = require("@dnd-kit/core");
1963
+ var import_sortable = require("@dnd-kit/sortable");
1964
+ var import_utilities = require("@dnd-kit/utilities");
1927
1965
  var import_jsx_runtime20 = require("react/jsx-runtime");
1928
- var SelectedItem = (0, import_react_sortable_hoc2.SortableElement)(({ item, extended }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LayerItem, {
1929
- item,
1930
- extended
1931
- }));
1932
- var SelectedItemList = (0, import_react_sortable_hoc2.SortableContainer)(({ layerList }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", {
1933
- children: layerList.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SelectedItem, {
1934
- index,
1935
- item,
1936
- extended: true
1937
- }, item.id))
1938
- }));
1966
+ function SortableSelectedItem({ item, extended }) {
1967
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = (0, import_sortable.useSortable)({
1968
+ id: item.id
1969
+ });
1970
+ const style = {
1971
+ transform: import_utilities.CSS.Transform.toString(transform),
1972
+ transition,
1973
+ opacity: isDragging ? 0.5 : 1
1974
+ };
1975
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", {
1976
+ ref: setNodeRef,
1977
+ style,
1978
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LayerItem, {
1979
+ item,
1980
+ extended,
1981
+ dragHandleProps: __spreadValues(__spreadValues({}, attributes), listeners)
1982
+ })
1983
+ });
1984
+ }
1985
+ var SelectedItemList = ({ layerList, onSortEnd }) => {
1986
+ const sensors = (0, import_core9.useSensors)((0, import_core9.useSensor)(import_core9.PointerSensor, { activationConstraint: { distance: 4 } }));
1987
+ const handleDragEnd = (event) => {
1988
+ const { active, over } = event;
1989
+ if (over && active.id !== over.id) {
1990
+ const oldIndex = layerList.findIndex((item) => item.id === active.id);
1991
+ const newIndex = layerList.findIndex((item) => item.id === over.id);
1992
+ if (oldIndex !== -1 && newIndex !== -1) {
1993
+ onSortEnd({ oldIndex, newIndex });
1994
+ }
1995
+ }
1996
+ };
1997
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core9.DndContext, {
1998
+ sensors,
1999
+ collisionDetection: import_core9.closestCenter,
2000
+ onDragEnd: handleDragEnd,
2001
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_sortable.SortableContext, {
2002
+ items: layerList.map((item) => item.id),
2003
+ strategy: import_sortable.verticalListSortingStrategy,
2004
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", {
2005
+ children: layerList.map((item) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SortableSelectedItem, {
2006
+ item,
2007
+ extended: true
2008
+ }, item.id))
2009
+ })
2010
+ })
2011
+ });
2012
+ };
1939
2013
 
1940
2014
  // src/components/sidebar/selected/index.tsx
1941
2015
  var import_naksha_commons10 = require("@biodiv-platform/naksha-commons");
@@ -2087,6 +2161,170 @@ function Sidebar() {
2087
2161
  // src/components/map/layers/index.tsx
2088
2162
  var import_maplibre6 = require("react-map-gl/maplibre");
2089
2163
 
2164
+ // ../../node_modules/@turf/helpers/dist/es/index.js
2165
+ var earthRadius = 63710088e-1;
2166
+ var factors = {
2167
+ centimeters: earthRadius * 100,
2168
+ centimetres: earthRadius * 100,
2169
+ degrees: earthRadius / 111325,
2170
+ feet: earthRadius * 3.28084,
2171
+ inches: earthRadius * 39.37,
2172
+ kilometers: earthRadius / 1e3,
2173
+ kilometres: earthRadius / 1e3,
2174
+ meters: earthRadius,
2175
+ metres: earthRadius,
2176
+ miles: earthRadius / 1609.344,
2177
+ millimeters: earthRadius * 1e3,
2178
+ millimetres: earthRadius * 1e3,
2179
+ nauticalmiles: earthRadius / 1852,
2180
+ radians: 1,
2181
+ yards: earthRadius * 1.0936
2182
+ };
2183
+ var unitsFactors = {
2184
+ centimeters: 100,
2185
+ centimetres: 100,
2186
+ degrees: 1 / 111325,
2187
+ feet: 3.28084,
2188
+ inches: 39.37,
2189
+ kilometers: 1 / 1e3,
2190
+ kilometres: 1 / 1e3,
2191
+ meters: 1,
2192
+ metres: 1,
2193
+ miles: 1 / 1609.344,
2194
+ millimeters: 1e3,
2195
+ millimetres: 1e3,
2196
+ nauticalmiles: 1 / 1852,
2197
+ radians: 1 / earthRadius,
2198
+ yards: 1.0936133
2199
+ };
2200
+
2201
+ // ../../node_modules/@turf/meta/dist/es/index.js
2202
+ function coordEach(geojson, callback, excludeWrapCoord) {
2203
+ if (geojson === null)
2204
+ return;
2205
+ var j, k, l, geometry, stopG, coords, geometryMaybeCollection, wrapShrink = 0, coordIndex = 0, isGeometryCollection, type = geojson.type, isFeatureCollection = type === "FeatureCollection", isFeature = type === "Feature", stop = isFeatureCollection ? geojson.features.length : 1;
2206
+ for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
2207
+ geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
2208
+ isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
2209
+ stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
2210
+ for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
2211
+ var multiFeatureIndex = 0;
2212
+ var geometryIndex = 0;
2213
+ geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
2214
+ if (geometry === null)
2215
+ continue;
2216
+ coords = geometry.coordinates;
2217
+ var geomType = geometry.type;
2218
+ wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
2219
+ switch (geomType) {
2220
+ case null:
2221
+ break;
2222
+ case "Point":
2223
+ if (callback(
2224
+ coords,
2225
+ coordIndex,
2226
+ featureIndex,
2227
+ multiFeatureIndex,
2228
+ geometryIndex
2229
+ ) === false)
2230
+ return false;
2231
+ coordIndex++;
2232
+ multiFeatureIndex++;
2233
+ break;
2234
+ case "LineString":
2235
+ case "MultiPoint":
2236
+ for (j = 0; j < coords.length; j++) {
2237
+ if (callback(
2238
+ coords[j],
2239
+ coordIndex,
2240
+ featureIndex,
2241
+ multiFeatureIndex,
2242
+ geometryIndex
2243
+ ) === false)
2244
+ return false;
2245
+ coordIndex++;
2246
+ if (geomType === "MultiPoint")
2247
+ multiFeatureIndex++;
2248
+ }
2249
+ if (geomType === "LineString")
2250
+ multiFeatureIndex++;
2251
+ break;
2252
+ case "Polygon":
2253
+ case "MultiLineString":
2254
+ for (j = 0; j < coords.length; j++) {
2255
+ for (k = 0; k < coords[j].length - wrapShrink; k++) {
2256
+ if (callback(
2257
+ coords[j][k],
2258
+ coordIndex,
2259
+ featureIndex,
2260
+ multiFeatureIndex,
2261
+ geometryIndex
2262
+ ) === false)
2263
+ return false;
2264
+ coordIndex++;
2265
+ }
2266
+ if (geomType === "MultiLineString")
2267
+ multiFeatureIndex++;
2268
+ if (geomType === "Polygon")
2269
+ geometryIndex++;
2270
+ }
2271
+ if (geomType === "Polygon")
2272
+ multiFeatureIndex++;
2273
+ break;
2274
+ case "MultiPolygon":
2275
+ for (j = 0; j < coords.length; j++) {
2276
+ geometryIndex = 0;
2277
+ for (k = 0; k < coords[j].length; k++) {
2278
+ for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
2279
+ if (callback(
2280
+ coords[j][k][l],
2281
+ coordIndex,
2282
+ featureIndex,
2283
+ multiFeatureIndex,
2284
+ geometryIndex
2285
+ ) === false)
2286
+ return false;
2287
+ coordIndex++;
2288
+ }
2289
+ geometryIndex++;
2290
+ }
2291
+ multiFeatureIndex++;
2292
+ }
2293
+ break;
2294
+ case "GeometryCollection":
2295
+ for (j = 0; j < geometry.geometries.length; j++)
2296
+ if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false)
2297
+ return false;
2298
+ break;
2299
+ default:
2300
+ throw new Error("Unknown Geometry Type");
2301
+ }
2302
+ }
2303
+ }
2304
+ }
2305
+
2306
+ // ../../node_modules/@turf/bbox/dist/es/index.js
2307
+ function bbox(geojson) {
2308
+ var result = [Infinity, Infinity, -Infinity, -Infinity];
2309
+ coordEach(geojson, function(coord) {
2310
+ if (result[0] > coord[0]) {
2311
+ result[0] = coord[0];
2312
+ }
2313
+ if (result[1] > coord[1]) {
2314
+ result[1] = coord[1];
2315
+ }
2316
+ if (result[2] < coord[0]) {
2317
+ result[2] = coord[0];
2318
+ }
2319
+ if (result[3] < coord[1]) {
2320
+ result[3] = coord[1];
2321
+ }
2322
+ });
2323
+ return result;
2324
+ }
2325
+ bbox["default"] = bbox;
2326
+ var es_default = bbox;
2327
+
2090
2328
  // src/components/map/layers/grid/index.tsx
2091
2329
  var import_react10 = require("react");
2092
2330
  var import_maplibre3 = require("react-map-gl/maplibre");
@@ -2098,7 +2336,9 @@ function GridLayer({
2098
2336
  const { layer } = useLayers();
2099
2337
  const { mapl } = (0, import_maplibre3.useMap)();
2100
2338
  const [layerData, setLayerData] = (0, import_react10.useState)({ geojson: {}, paint: {} });
2101
- const fetchGridData = () => __async(this, null, function* () {
2339
+ const isSelected = layer.selectedIds.includes(data.id);
2340
+ const isLastSelected = layer.selectedIds[0] === data.id;
2341
+ const fetchGridData = (shouldFitBounds = false) => __async(this, null, function* () {
2102
2342
  const { success, geojson, paint: paint2, stops, squareSize } = yield getGridLayerData(
2103
2343
  data.source.fetcher,
2104
2344
  mapl == null ? void 0 : mapl.getBounds(),
@@ -2106,14 +2346,50 @@ function GridLayer({
2106
2346
  );
2107
2347
  if (success) {
2108
2348
  setLayerData({ geojson, paint: paint2 });
2349
+ if (shouldFitBounds && isLastSelected && data.zoomToFit) {
2350
+ try {
2351
+ const [minLon, minLat, maxLon, maxLat] = es_default(geojson);
2352
+ mapl == null ? void 0 : mapl.fitBounds(
2353
+ [
2354
+ [minLon, minLat],
2355
+ [maxLon, maxLat]
2356
+ ],
2357
+ { padding: 40, animate: true }
2358
+ );
2359
+ } catch (e) {
2360
+ console.warn("Failed to compute bbox", e);
2361
+ }
2362
+ }
2109
2363
  layer.setGridLegends({
2110
2364
  [data.id]: { stops, squareSize }
2111
2365
  });
2112
2366
  }
2113
2367
  });
2114
2368
  (0, import_react10.useEffect)(() => {
2115
- mapl == null ? void 0 : mapl.on("idle", fetchGridData);
2116
- }, []);
2369
+ if (isSelected && isLastSelected) {
2370
+ fetchGridData(true);
2371
+ } else if (isSelected) {
2372
+ fetchGridData(false);
2373
+ }
2374
+ }, [isSelected, isLastSelected]);
2375
+ (0, import_react10.useEffect)(() => {
2376
+ if (!isSelected || !mapl)
2377
+ return;
2378
+ const handleIdle = () => fetchGridData(false);
2379
+ mapl.on("idle", handleIdle);
2380
+ return () => {
2381
+ mapl.off("idle", handleIdle);
2382
+ };
2383
+ }, [isSelected, mapl]);
2384
+ (0, import_react10.useEffect)(() => {
2385
+ return () => {
2386
+ layer.setGridLegends((prev) => {
2387
+ const newLegends = __spreadValues({}, prev);
2388
+ delete newLegends[data.id];
2389
+ return newLegends;
2390
+ });
2391
+ };
2392
+ }, [data.id]);
2117
2393
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_maplibre3.Source, {
2118
2394
  id: data.id,
2119
2395
  type: "geojson",
@@ -2317,7 +2593,6 @@ function Map2() {
2317
2593
  setCoordinates(event.lngLat);
2318
2594
  hover.onHover(event);
2319
2595
  };
2320
- console.info("NakshaMaplibreLayers props");
2321
2596
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", {
2322
2597
  className: import_twind20.tw`h-full w-full relative bg-gray-100`,
2323
2598
  children: [
@@ -2338,6 +2613,9 @@ function Map2() {
2338
2613
  showZoom: true,
2339
2614
  showCompass: true
2340
2615
  }),
2616
+ mp.showFullscreenControl && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_maplibre9.FullscreenControl, {
2617
+ position: "bottom-right"
2618
+ }),
2341
2619
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(markers_list_default, {}),
2342
2620
  layer.selectedLayers.map((_l, index) => {
2343
2621
  const beforeId = index > 0 ? layer.selectedIds[index - 1] : void 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biodiv-platform/naksha-maplibre-layers",
3
- "version": "5.0.3",
3
+ "version": "5.0.5",
4
4
  "author": "harshzalavadiya",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -20,7 +20,10 @@
20
20
  "peerDependencies": {
21
21
  "react": ">=18",
22
22
  "maplibre-gl": "^5.6.2",
23
- "react-map-gl": "^8.0.4"
23
+ "react-map-gl": "^8.0.4",
24
+ "@dnd-kit/core": "^6.3.1",
25
+ "@dnd-kit/sortable": "^10.0.0",
26
+ "@dnd-kit/utilities": "^3.2.2"
24
27
  },
25
28
  "devDependencies": {
26
29
  "@biodiv-platform/eslint-preset": "*",
@@ -31,7 +34,10 @@
31
34
  "maplibre-gl": "^5.6.2",
32
35
  "react-map-gl": "^8.0.4",
33
36
  "tsup": "^6.1.2",
34
- "typescript": "^4.7.3"
37
+ "typescript": "^4.7.3",
38
+ "@dnd-kit/core": "^6.3.1",
39
+ "@dnd-kit/sortable": "^10.0.0",
40
+ "@dnd-kit/utilities": "^3.2.2"
35
41
  },
36
42
  "dependencies": {
37
43
  "@bumaga/tabs": "^0.2.0",
@@ -42,7 +48,6 @@
42
48
  "geohash": "^0.0.1",
43
49
  "highlight-search-result": "^1.0.4",
44
50
  "immer": "^9.0.15",
45
- "react-sortable-hoc": "^2.0.0",
46
51
  "react-tiny-popover": "^7.0.1",
47
52
  "react-virtual": "^2.10.4",
48
53
  "react-virtualized-auto-sizer": "^1.0.6",