@xyo-network/react-map 3.0.15 → 3.0.16

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.
@@ -2,7 +2,7 @@ import type { WithChildren } from '@xylabs/react-shared'
2
2
  import { useInterval } from '@xylabs/react-shared'
3
3
  import type { Map } from 'mapbox-gl'
4
4
  import React, {
5
- useCallback, useEffect, useRef, useState,
5
+ useCallback, useEffect, useMemo, useRef,
6
6
  } from 'react'
7
7
 
8
8
  import type { MapLayer } from '../Layers/index.ts'
@@ -21,9 +21,21 @@ const animatedLayerCount = 3
21
21
  export const LayerAnimator: React.FC<WithChildren<LayerAnimatorProps>> = ({
22
22
  animateLayers, children, layers, layersInitialized, map,
23
23
  }) => {
24
- const [fillLayers, setFillLayers] = useState<MapLayer[]>([])
25
24
  const layerIndexQueue = useRef<number[]>([])
26
25
 
26
+ const fillLayers: MapLayer[] = useMemo(() => {
27
+ if (layers?.length && map && layersInitialized) {
28
+ return layers.filter((layer) => {
29
+ const fillLayer = layer.id.startsWith('location-fill')
30
+ if (fillLayer) {
31
+ map.setPaintProperty(layer.id, 'fill-opacity-transition', { delay: 0, duration: 4000 })
32
+ }
33
+ return fillLayer
34
+ })
35
+ }
36
+ return []
37
+ }, [layers, layersInitialized, map])
38
+
27
39
  const incrementQueue = useCallback(
28
40
  (index: number) => {
29
41
  if (fillLayers[index]) {
@@ -71,21 +83,6 @@ export const LayerAnimator: React.FC<WithChildren<LayerAnimatorProps>> = ({
71
83
  [map, unshiftQueue],
72
84
  )
73
85
 
74
- useEffect(() => {
75
- if (layers?.length && map && layersInitialized) {
76
- // Only animate fill layers for now
77
- setFillLayers(
78
- layers.filter((layer) => {
79
- const fillLayer = layer.id.startsWith('location-fill')
80
- if (fillLayer) {
81
- map.setPaintProperty(layer.id, 'fill-opacity-transition', { delay: 0, duration: 4000 })
82
- }
83
- return fillLayer
84
- }),
85
- )
86
- }
87
- }, [layers, layersInitialized, map])
88
-
89
86
  //
90
87
  const queueLayerAnimation = useCallback(() => {
91
88
  const animatedLayers: MapLayer[] = []
@@ -50,6 +50,7 @@ export const MapBox: React.FC<MapBoxProps> = ({
50
50
 
51
51
  // Allow external components to control the map
52
52
  setMapBoxInstance?.(map)
53
+ // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
53
54
  setMap(map)
54
55
 
55
56
  // save the map canvas ref to help with resizing
@@ -3,7 +3,7 @@ import { FlexCol } from '@xylabs/react-flexbox'
3
3
  import type { Feature, Point } from 'geojson'
4
4
  import type { MapOptions } from 'mapbox-gl'
5
5
  import React, {
6
- useCallback, useEffect, useState,
6
+ useCallback, useEffect, useMemo,
7
7
  } from 'react'
8
8
 
9
9
  import { useMapBoxInstance, useMapSettings } from '../Contexts/index.ts'
@@ -25,7 +25,6 @@ export const MapboxPointsFlexBox: React.FC<MapboxPointsFlexBoxProps> = ({
25
25
  zoom,
26
26
  ...props
27
27
  }) => {
28
- const [mapPoints, setMapPoints] = useState<MapPoints>()
29
28
  const { mapSettings } = useMapSettings()
30
29
  const { map, mapInitialized } = useMapBoxInstance()
31
30
 
@@ -40,6 +39,14 @@ export const MapboxPointsFlexBox: React.FC<MapboxPointsFlexBoxProps> = ({
40
39
  return {}
41
40
  }
42
41
 
42
+ const mapPoints = useMemo(() => {
43
+ return (map && features?.length)
44
+ ? new MapPoints({
45
+ features, map, zoom,
46
+ })
47
+ : undefined
48
+ }, [map, features, zoom])
49
+
43
50
  const updateFeatures = useCallback(() => {
44
51
  if (mapPoints?.isMapReady && features?.length && layers)
45
52
  for (const layer of layers) {
@@ -70,14 +77,6 @@ export const MapboxPointsFlexBox: React.FC<MapboxPointsFlexBoxProps> = ({
70
77
  updateFeatures()
71
78
  }, [mapPoints, fitToPointsPadding, updateFeatures, zoom])
72
79
 
73
- useEffect(() => {
74
- if (map && features?.length) {
75
- setMapPoints(new MapPoints({
76
- features, map, zoom,
77
- }))
78
- }
79
- }, [map, features, zoom])
80
-
81
80
  useEffect(() => {
82
81
  if (mapInitialized) {
83
82
  updateMapSetup()
@@ -1,9 +1,7 @@
1
1
  import { forget } from '@xylabs/forget'
2
2
  import type { WithChildren } from '@xylabs/react-shared'
3
3
  import type { Feature, Polygon } from 'geojson'
4
- import React, {
5
- useEffect, useMemo, useState,
6
- } from 'react'
4
+ import React, { useEffect, useMemo } from 'react'
7
5
 
8
6
  import type { AnimatedHeatMapColorProps, HeatMapColorProps } from '../../Colors/index.ts'
9
7
  import { useDynamicPositioning } from '../../hooks/index.ts'
@@ -34,11 +32,18 @@ export const HeatMapInitializerProvider: React.FC<WithChildren<MapInitializerPro
34
32
  layers,
35
33
  zoom,
36
34
  }) => {
37
- const [mapHeat, setMapHeat] = useState<MapHeat>()
38
35
  const { options } = useDynamicPositioning()
39
36
  const { mapSettings } = useMapSettings()
40
37
  const { map, mapInitialized } = useMapBoxInstance()
41
38
 
39
+ const mapHeat = useMemo(() => {
40
+ return (map && features?.length)
41
+ ? new MapHeat({
42
+ features, map, zoom,
43
+ })
44
+ : undefined
45
+ }, [map, features, zoom])
46
+
42
47
  const value: HeatMapInitializerState = useMemo(() => ({
43
48
  MapHeat: mapHeat,
44
49
  heatMapColorProps,
@@ -76,7 +81,7 @@ export const HeatMapInitializerProvider: React.FC<WithChildren<MapInitializerPro
76
81
  map,
77
82
  features,
78
83
  )
79
- } else if (options.zoom && options.center) {
84
+ } else if (options?.zoom && options.center) {
80
85
  map.setZoom(options.zoom)
81
86
  map.setCenter(options.center)
82
87
  }
@@ -84,14 +89,5 @@ export const HeatMapInitializerProvider: React.FC<WithChildren<MapInitializerPro
84
89
  }
85
90
  }, [mapHeat, map, mapSettings, fitToPadding, options, mapInitialized, features])
86
91
 
87
- useEffect(() => {
88
- if (map && features?.length) {
89
- // Every time we get a new map or features, we make a new class
90
- setMapHeat(new MapHeat({
91
- features, map, zoom,
92
- }))
93
- }
94
- }, [map, features, zoom])
95
-
96
92
  return <HeatMapInitializerContext.Provider value={value}>{children}</HeatMapInitializerContext.Provider>
97
93
  }
@@ -1,8 +1,6 @@
1
1
  import type { Map } from 'mapbox-gl'
2
2
  import type { MutableRefObject } from 'react'
3
- import {
4
- useEffect, useMemo, useState,
5
- } from 'react'
3
+ import { useEffect, useMemo } from 'react'
6
4
 
7
5
  /**
8
6
  * Inspired by - https://bl.ocks.org/danswick/fc56f37c10d40be62e4feac5984250d2
@@ -13,8 +11,6 @@ export const useDynamicMapResize = (
13
11
  mapInstance?: Map,
14
12
  active = true,
15
13
  ) => {
16
- const [dependenciesReady, setDependenciesReady] = useState(false)
17
-
18
14
  const resizer = useMemo(
19
15
  () =>
20
16
  new ResizeObserver(() => {
@@ -29,9 +25,8 @@ export const useDynamicMapResize = (
29
25
  [mapCanvasRef, mapContainerRef, mapInstance],
30
26
  )
31
27
 
32
- useEffect(() => {
33
- const dependenciesReady = !!(active && mapInstance && mapContainerRef?.current && mapCanvasRef.current)
34
- setDependenciesReady(dependenciesReady)
28
+ const dependenciesReady = useMemo(() => {
29
+ return !!(active && mapInstance && mapContainerRef?.current && mapCanvasRef.current)
35
30
  }, [active, mapCanvasRef, mapContainerRef, mapInstance])
36
31
 
37
32
  useEffect(() => {
@@ -1,6 +1,6 @@
1
1
  import { useWindowSize } from '@xylabs/react-shared'
2
2
  import type { MapOptions } from 'mapbox-gl'
3
- import { useEffect, useState } from 'react'
3
+ import { useMemo } from 'react'
4
4
 
5
5
  /**
6
6
  * Zoom level for the map
@@ -49,17 +49,16 @@ const linearInterpolate = (aspectRatio: number, degreeRange: number[], aspectRat
49
49
  }
50
50
 
51
51
  const useDynamicPositioning = () => {
52
- const [options, setOptions] = useState<Partial<MapOptions>>({})
53
52
  const { width, height } = useWindowSize()
54
53
 
55
- useEffect(() => {
54
+ const options = useMemo(() => {
56
55
  if (width && height) {
57
56
  const aspectRatio = width / height
58
57
 
59
- setOptions({
58
+ return {
60
59
  center: [linearInterpolate(aspectRatio, lngRange), linearInterpolate(aspectRatio, latRange)],
61
60
  zoom: defaultZoom,
62
- })
61
+ } as Partial<MapOptions>
63
62
  }
64
63
  }, [height, width])
65
64
 
@@ -1,7 +1,7 @@
1
1
  import { exists } from '@xylabs/exists'
2
2
  import { GeoJson } from '@xyo-network/sdk-geo'
3
3
  import type { Feature, Geometry } from 'geojson'
4
- import { useEffect, useState } from 'react'
4
+ import { useMemo, useState } from 'react'
5
5
 
6
6
  import type { NetworkLocationHeatmapQuadkeyAnswerPayload } from '../types/index.ts'
7
7
 
@@ -26,7 +26,7 @@ const useQuadKeyPayloadsToFeatures = (payloads?: NetworkLocationHeatmapQuadkeyAn
26
26
  const [features, setFeatures] = useState<Feature<Geometry>[]>([])
27
27
  const [error, setError] = useState<Error>()
28
28
 
29
- useEffect(() => {
29
+ useMemo(() => {
30
30
  // Convert Multiple Payloads from Quadkey to GeoJson
31
31
  if (Array.isArray(payloads)) {
32
32
  if ((payloads)?.filter(exists).length > 0) {