Skip to content

Commit 36ec44c

Browse files
authored
feat: update lib
feat: integrate FitBounds component for automatic map bounds adjustment and update dependencies
2 parents 9d062e3 + 9325f8e commit 36ec44c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1974
-1374
lines changed

.husky/pre-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
bun run lint

bun.lock

Lines changed: 155 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/App.tsx

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,30 @@
11
import { ThemeProvider } from "@tracktor/design-system";
2-
import { lotOfMarkers } from "example/Markers.tsx";
3-
import MarkerMap from "@/components/MarkerMap/MarkerMap";
4-
import MapProvider from "@/context/MapProvider.tsx";
2+
import FeaturesExample from "example/FeaturesExample.tsx";
3+
import LandingPage from "example/LandingPage.tsx";
4+
import MarkersExample from "example/MarkersExample";
5+
import RouteExample from "example/RoutesExample";
6+
import { useState } from "react";
7+
import { BrowserRouter, Route, Routes } from "react-router-dom";
8+
import MapProvider from "@/context/MapProvider";
59

10+
/**
11+
* This is the main app entry point.
12+
* It wraps all routes with providers and global components.
13+
*/
614
const App = () => {
7-
// console.warning if no .env found
8-
if (!import.meta.env.VITE_MUI_LICENSE_KEY || !import.meta.env.VITE_MAPBOX_ACCESS_TOKEN) {
9-
console.warn(
10-
"No .env file found. Please create a .env file with the following variables: VITE_MUI_LICENSE_KEY and VITE_MAPBOX_ACCESS_TOKEN",
11-
);
12-
}
13-
14-
const handleMapClick = (lng: number, lat: number): void => {
15-
console.log("Map clicked at:", { lat, lng });
16-
};
15+
const [themeMode, setThemeMode] = useState<"light" | "dark">("dark");
1716

1817
return (
19-
<ThemeProvider theme="dark">
18+
<ThemeProvider theme={themeMode}>
2019
<MapProvider licenseMuiX={import.meta.env.VITE_MUI_LICENSE_KEY} licenceMapbox={import.meta.env.VITE_MAPBOX_ACCESS_TOKEN}>
21-
<MarkerMap
22-
openPopup="1"
23-
markers={lotOfMarkers}
24-
height={600}
25-
width={600}
26-
onMapClick={handleMapClick}
27-
containerStyle={{
28-
marginLeft: 3,
29-
marginTop: 3,
30-
}}
31-
/>
20+
<BrowserRouter>
21+
<Routes>
22+
<Route path="/" element={<LandingPage />} />
23+
<Route path="/markers" element={<MarkersExample themeMode={themeMode} setThemeMode={setThemeMode} />} />
24+
<Route path="/features" element={<FeaturesExample themeMode={themeMode} setThemeMode={setThemeMode} />} />
25+
<Route path="/route" element={<RouteExample themeMode={themeMode} setThemeMode={setThemeMode} />} />
26+
</Routes>
27+
</BrowserRouter>
3228
</MapProvider>
3329
</ThemeProvider>
3430
);

example/FeaturesExample.tsx

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import { Box, Button, MenuItem, Select, Stack, Typography } from "@tracktor/design-system";
2+
import Navbar from "example/Navbar";
3+
import type { Feature, FeatureCollection, LineString, Point, Polygon } from "geojson";
4+
import { useCallback, useMemo, useState } from "react";
5+
import MarkerMap from "@/Features/MarkerMap/MarkerMap";
6+
7+
const randomCoordInFrance = () => [2 + (Math.random() - 0.5) * 6, 46 + (Math.random() - 0.5) * 6];
8+
9+
const createRandomPoint = (): Feature<Point> => ({
10+
geometry: {
11+
coordinates: randomCoordInFrance(),
12+
type: "Point",
13+
},
14+
properties: {
15+
color: "#F97316",
16+
},
17+
type: "Feature",
18+
});
19+
20+
const createRandomLine = (): Feature<LineString> => ({
21+
geometry: {
22+
coordinates: [randomCoordInFrance(), randomCoordInFrance()],
23+
type: "LineString",
24+
},
25+
properties: {
26+
color: "#3B82F6",
27+
},
28+
type: "Feature",
29+
});
30+
31+
const createRandomPolygon = (): Feature<Polygon> => {
32+
const [lng, lat] = randomCoordInFrance();
33+
const delta = 0.5;
34+
return {
35+
geometry: {
36+
coordinates: [
37+
[
38+
[lng - delta, lat - delta],
39+
[lng + delta, lat - delta],
40+
[lng + delta, lat + delta],
41+
[lng - delta, lat + delta],
42+
[lng - delta, lat - delta],
43+
],
44+
],
45+
type: "Polygon",
46+
},
47+
properties: {
48+
color: "#4ADE80",
49+
},
50+
type: "Feature",
51+
};
52+
};
53+
54+
interface FeaturesExampleProps {
55+
themeMode: "light" | "dark";
56+
setThemeMode: (mode: "light" | "dark") => void;
57+
}
58+
59+
const FeaturesExample = ({ themeMode, setThemeMode }: FeaturesExampleProps) => {
60+
const [featureList, setFeatureList] = useState<Feature[]>([]);
61+
const [baseMapView, setBaseMapView] = useState<"street" | "satellite">("street");
62+
63+
const markers = useMemo(
64+
() =>
65+
featureList
66+
.filter((f) => f.geometry.type === "Point")
67+
.map((f, index) => {
68+
const geom = f.geometry;
69+
if (geom.type === "Point") {
70+
return {
71+
id: `point-${index}`,
72+
lat: geom.coordinates[1],
73+
lng: geom.coordinates[0],
74+
};
75+
}
76+
return null;
77+
})
78+
.filter((m): m is { id: string; lat: number; lng: number } => m !== null),
79+
[featureList],
80+
);
81+
82+
const features: FeatureCollection = useMemo(
83+
() => ({
84+
features: featureList,
85+
type: "FeatureCollection",
86+
}),
87+
[featureList],
88+
);
89+
90+
const addFeature = useCallback((type: "point" | "line" | "polygon") => {
91+
setFeatureList((prev) => {
92+
if (type === "point") {
93+
return [...prev, createRandomPoint()];
94+
}
95+
if (type === "line") {
96+
return [...prev, createRandomLine()];
97+
}
98+
return [...prev, createRandomPolygon()];
99+
});
100+
}, []);
101+
102+
const clearFeatures = useCallback(() => setFeatureList([]), []);
103+
104+
return (
105+
<>
106+
<Navbar />
107+
<Stack direction="row" sx={{ height: "100vh", overflow: "hidden", width: "100vw" }}>
108+
<Box sx={{ flex: 1 }}>
109+
<MarkerMap markers={markers} features={features} fitBounds baseMapView={baseMapView} height="100%" width="100%" />
110+
</Box>
111+
112+
<Box
113+
sx={{
114+
backgroundColor: "background.paper",
115+
borderColor: "divider",
116+
borderLeft: "1px solid",
117+
color: "text.primary",
118+
display: "flex",
119+
flexDirection: "column",
120+
gap: 2,
121+
p: 2,
122+
width: 300,
123+
}}
124+
>
125+
<Typography variant="h6">🧭 Options</Typography>
126+
127+
<Typography variant="body2" color="text.secondary">
128+
Theme
129+
</Typography>
130+
<Button variant="outlined" onClick={() => setThemeMode(themeMode === "dark" ? "light" : "dark")}>
131+
{themeMode === "dark" ? "Light mode" : "Dark mode"}
132+
</Button>
133+
134+
<Typography variant="body2" color="text.secondary">
135+
Base Map View
136+
</Typography>
137+
<Select value={baseMapView} onChange={(e) => setBaseMapView(e.target.value)} size="small">
138+
<MenuItem value="street">Street</MenuItem>
139+
<MenuItem value="satellite">Satellite</MenuItem>
140+
</Select>
141+
142+
<Typography variant="h6" mt={2}>
143+
➕ Add Features
144+
</Typography>
145+
146+
<Stack spacing={1}>
147+
<Button variant="contained" onClick={() => addFeature("point")}>
148+
📍 Add Point
149+
</Button>
150+
<Button variant="contained" onClick={() => addFeature("line")}>
151+
➖ Add Line
152+
</Button>
153+
<Button variant="contained" onClick={() => addFeature("polygon")}>
154+
🟩 Add Polygon
155+
</Button>
156+
</Stack>
157+
158+
{featureList.length > 0 && (
159+
<Button variant="outlined" color="error" onClick={clearFeatures}>
160+
🗑 Clear all
161+
</Button>
162+
)}
163+
</Box>
164+
</Stack>
165+
</>
166+
);
167+
};
168+
169+
export default FeaturesExample;

0 commit comments

Comments
 (0)