Skip to content

Commit ba57a22

Browse files
chore: wip
1 parent 8c164a4 commit ba57a22

File tree

8 files changed

+925
-1
lines changed

8 files changed

+925
-1
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import type { MapOptions } from 'ts-maps'
2+
import { useEffect, useRef, useMemo } from 'react'
3+
import { VectorMap as TSVectorMap } from 'ts-maps'
4+
import brasilMap from 'ts-maps/maps/brasil'
5+
import './map-components.css'
6+
7+
export interface BrasilProps extends Omit<React.HTMLProps<HTMLDivElement>, 'ref'> {
8+
options: Omit<MapOptions, 'selector'>
9+
height?: string
10+
mapKey?: string | number // Optional key for forcing re-renders
11+
onRegionClick?: (event: MouseEvent, code: string) => void
12+
onMarkerClick?: (event: MouseEvent, index: string) => void
13+
onLoaded?: () => void
14+
onViewportChange?: (x: number, y: number, z: number) => void
15+
onRegionSelected?: (event: MouseEvent, code: string, isSelected: boolean, selectedRegions: string[]) => void
16+
onMarkerSelected?: (event: MouseEvent, index: string, isSelected: boolean, selectedMarkers: string[]) => void
17+
onRegionTooltipShow?: (event: Event, tooltip: any, code: string) => void
18+
onMarkerTooltipShow?: (event: Event, tooltip: any, index: string) => void
19+
}
20+
21+
export function Brasil({
22+
options,
23+
height = '500px',
24+
mapKey,
25+
onRegionClick,
26+
onMarkerClick,
27+
onLoaded,
28+
onViewportChange,
29+
onRegionSelected,
30+
onMarkerSelected,
31+
onRegionTooltipShow,
32+
onMarkerTooltipShow,
33+
style,
34+
...props
35+
}: BrasilProps) {
36+
const containerRef = useRef<HTMLDivElement>(null)
37+
const mapRef = useRef<TSVectorMap | null>(null)
38+
39+
// Generate a key based on options to force re-render when options change significantly
40+
const computedMapKey = useMemo(() => {
41+
if (mapKey !== undefined)
42+
return mapKey
43+
44+
const optionsHash = JSON.stringify({
45+
backgroundColor: options.backgroundColor,
46+
zoomOnScroll: options.zoomOnScroll,
47+
regionsSelectable: options.regionsSelectable,
48+
markersSelectable: options.markersSelectable,
49+
visualizeData: options.visualizeData,
50+
markers: options.markers?.length,
51+
})
52+
53+
return `brasil-map-${optionsHash.length}-${Date.now()}`
54+
}, [mapKey, options])
55+
56+
useEffect(() => {
57+
if (!containerRef.current)
58+
return
59+
60+
// Add Brasil map
61+
TSVectorMap.addMap('brasil', brasilMap)
62+
63+
const map = new TSVectorMap({
64+
selector: `#${containerRef.current.id}`,
65+
map: {
66+
name: 'brasil',
67+
...options.map,
68+
},
69+
...options,
70+
})
71+
72+
// Set up event listeners
73+
if (onRegionClick) {
74+
map.on('regionClick', onRegionClick)
75+
}
76+
if (onMarkerClick) {
77+
map.on('markerClick', onMarkerClick)
78+
}
79+
if (onLoaded) {
80+
map.on('loaded', onLoaded)
81+
}
82+
if (onViewportChange) {
83+
map.on('viewportChange', onViewportChange)
84+
}
85+
if (onRegionSelected) {
86+
map.on('regionSelected', onRegionSelected)
87+
}
88+
if (onMarkerSelected) {
89+
map.on('markerSelected', onMarkerSelected)
90+
}
91+
if (onRegionTooltipShow) {
92+
map.on('regionTooltipShow', onRegionTooltipShow)
93+
}
94+
if (onMarkerTooltipShow) {
95+
map.on('markerTooltipShow', onMarkerTooltipShow)
96+
}
97+
98+
mapRef.current = map
99+
100+
return () => {
101+
if (mapRef.current) {
102+
// Clean up event listeners
103+
if (onRegionClick) {
104+
mapRef.current.off('regionClick', onRegionClick)
105+
}
106+
if (onMarkerClick) {
107+
mapRef.current.off('markerClick', onMarkerClick)
108+
}
109+
if (onLoaded) {
110+
mapRef.current.off('loaded', onLoaded)
111+
}
112+
if (onViewportChange) {
113+
mapRef.current.off('viewportChange', onViewportChange)
114+
}
115+
if (onRegionSelected) {
116+
mapRef.current.off('regionSelected', onRegionSelected)
117+
}
118+
if (onMarkerSelected) {
119+
mapRef.current.off('markerSelected', onMarkerSelected)
120+
}
121+
if (onRegionTooltipShow) {
122+
mapRef.current.off('regionTooltipShow', onRegionTooltipShow)
123+
}
124+
if (onMarkerTooltipShow) {
125+
mapRef.current.off('markerTooltipShow', onMarkerTooltipShow)
126+
}
127+
128+
mapRef.current = null
129+
}
130+
}
131+
}, [computedMapKey, options, onRegionClick, onMarkerClick, onLoaded, onViewportChange, onRegionSelected, onMarkerSelected, onRegionTooltipShow, onMarkerTooltipShow])
132+
133+
const containerStyle: React.CSSProperties = {
134+
height,
135+
...style,
136+
}
137+
138+
return (
139+
<div
140+
{...props}
141+
ref={containerRef}
142+
id={`brasil-map-${Math.random().toString(36).slice(2, 11)}`}
143+
style={containerStyle}
144+
>
145+
<div className="brasil-map-loading">
146+
Loading Brasil map...
147+
</div>
148+
</div>
149+
)
150+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import type { MapOptions } from 'ts-maps'
2+
import { useEffect, useRef, useMemo } from 'react'
3+
import { VectorMap as TSVectorMap } from 'ts-maps'
4+
import iraqMap from 'ts-maps/maps/iraq'
5+
import './map-components.css'
6+
7+
export interface IraqProps extends Omit<React.HTMLProps<HTMLDivElement>, 'ref'> {
8+
options: Omit<MapOptions, 'selector'>
9+
height?: string
10+
mapKey?: string | number // Optional key for forcing re-renders
11+
onRegionClick?: (event: MouseEvent, code: string) => void
12+
onMarkerClick?: (event: MouseEvent, index: string) => void
13+
onLoaded?: () => void
14+
onViewportChange?: (x: number, y: number, z: number) => void
15+
onRegionSelected?: (event: MouseEvent, code: string, isSelected: boolean, selectedRegions: string[]) => void
16+
onMarkerSelected?: (event: MouseEvent, index: string, isSelected: boolean, selectedMarkers: string[]) => void
17+
onRegionTooltipShow?: (event: Event, tooltip: any, code: string) => void
18+
onMarkerTooltipShow?: (event: Event, tooltip: any, index: string) => void
19+
}
20+
21+
export function Iraq({
22+
options,
23+
height = '500px',
24+
mapKey,
25+
onRegionClick,
26+
onMarkerClick,
27+
onLoaded,
28+
onViewportChange,
29+
onRegionSelected,
30+
onMarkerSelected,
31+
onRegionTooltipShow,
32+
onMarkerTooltipShow,
33+
style,
34+
...props
35+
}: IraqProps) {
36+
const containerRef = useRef<HTMLDivElement>(null)
37+
const mapRef = useRef<TSVectorMap | null>(null)
38+
39+
// Generate a key based on options to force re-render when options change significantly
40+
const computedMapKey = useMemo(() => {
41+
if (mapKey !== undefined)
42+
return mapKey
43+
44+
const optionsHash = JSON.stringify({
45+
backgroundColor: options.backgroundColor,
46+
zoomOnScroll: options.zoomOnScroll,
47+
regionsSelectable: options.regionsSelectable,
48+
markersSelectable: options.markersSelectable,
49+
visualizeData: options.visualizeData,
50+
markers: options.markers?.length,
51+
})
52+
53+
return `iraq-map-${optionsHash.length}-${Date.now()}`
54+
}, [mapKey, options])
55+
56+
useEffect(() => {
57+
if (!containerRef.current)
58+
return
59+
60+
// Add Iraq map
61+
TSVectorMap.addMap('iraq', iraqMap)
62+
63+
const map = new TSVectorMap({
64+
selector: `#${containerRef.current.id}`,
65+
map: {
66+
name: 'iraq',
67+
...options.map,
68+
},
69+
...options,
70+
})
71+
72+
// Set up event listeners
73+
if (onRegionClick) {
74+
map.on('regionClick', onRegionClick)
75+
}
76+
if (onMarkerClick) {
77+
map.on('markerClick', onMarkerClick)
78+
}
79+
if (onLoaded) {
80+
map.on('loaded', onLoaded)
81+
}
82+
if (onViewportChange) {
83+
map.on('viewportChange', onViewportChange)
84+
}
85+
if (onRegionSelected) {
86+
map.on('regionSelected', onRegionSelected)
87+
}
88+
if (onMarkerSelected) {
89+
map.on('markerSelected', onMarkerSelected)
90+
}
91+
if (onRegionTooltipShow) {
92+
map.on('regionTooltipShow', onRegionTooltipShow)
93+
}
94+
if (onMarkerTooltipShow) {
95+
map.on('markerTooltipShow', onMarkerTooltipShow)
96+
}
97+
98+
mapRef.current = map
99+
100+
return () => {
101+
if (mapRef.current) {
102+
// Clean up event listeners
103+
if (onRegionClick) {
104+
mapRef.current.off('regionClick', onRegionClick)
105+
}
106+
if (onMarkerClick) {
107+
mapRef.current.off('markerClick', onMarkerClick)
108+
}
109+
if (onLoaded) {
110+
mapRef.current.off('loaded', onLoaded)
111+
}
112+
if (onViewportChange) {
113+
mapRef.current.off('viewportChange', onViewportChange)
114+
}
115+
if (onRegionSelected) {
116+
mapRef.current.off('regionSelected', onRegionSelected)
117+
}
118+
if (onMarkerSelected) {
119+
mapRef.current.off('markerSelected', onMarkerSelected)
120+
}
121+
if (onRegionTooltipShow) {
122+
mapRef.current.off('regionTooltipShow', onRegionTooltipShow)
123+
}
124+
if (onMarkerTooltipShow) {
125+
mapRef.current.off('markerTooltipShow', onMarkerTooltipShow)
126+
}
127+
128+
mapRef.current = null
129+
}
130+
}
131+
}, [computedMapKey, options, onRegionClick, onMarkerClick, onLoaded, onViewportChange, onRegionSelected, onMarkerSelected, onRegionTooltipShow, onMarkerTooltipShow])
132+
133+
const containerStyle: React.CSSProperties = {
134+
height,
135+
...style,
136+
}
137+
138+
return (
139+
<div
140+
{...props}
141+
ref={containerRef}
142+
id={`iraq-map-${Math.random().toString(36).slice(2, 11)}`}
143+
style={containerStyle}
144+
>
145+
<div className="iraq-map-loading">
146+
Loading Iraq map...
147+
</div>
148+
</div>
149+
)
150+
}

0 commit comments

Comments
 (0)