@page-speed/maps 0.1.8 → 0.2.0
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/components/geo-map.cjs +161 -32
- package/dist/components/geo-map.cjs.map +1 -1
- package/dist/components/geo-map.d.cts +5 -1
- package/dist/components/geo-map.d.ts +5 -1
- package/dist/components/geo-map.js +162 -33
- package/dist/components/geo-map.js.map +1 -1
- package/dist/components/index.cjs +161 -32
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +162 -33
- package/dist/components/index.js.map +1 -1
- package/dist/index.cjs +93 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +93 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -658,6 +658,74 @@ function MapLibre({
|
|
|
658
658
|
}
|
|
659
659
|
);
|
|
660
660
|
}
|
|
661
|
+
var TILE_SIZE = 512;
|
|
662
|
+
function latToMercatorY(lat) {
|
|
663
|
+
const latRad = lat * Math.PI / 180;
|
|
664
|
+
const mercN = Math.log(Math.tan(Math.PI / 4 + latRad / 2));
|
|
665
|
+
return TILE_SIZE / (2 * Math.PI) * (Math.PI - mercN);
|
|
666
|
+
}
|
|
667
|
+
function lngToMercatorX(lng) {
|
|
668
|
+
return TILE_SIZE / (2 * Math.PI) * ((lng + 180) / 360 * 2 * Math.PI);
|
|
669
|
+
}
|
|
670
|
+
function computeDefaultZoom(options) {
|
|
671
|
+
const {
|
|
672
|
+
coordinates,
|
|
673
|
+
mapWidth,
|
|
674
|
+
mapHeight,
|
|
675
|
+
padding = 50,
|
|
676
|
+
maxZoom = 18,
|
|
677
|
+
minZoom = 1
|
|
678
|
+
} = options;
|
|
679
|
+
if (coordinates.length === 0) return null;
|
|
680
|
+
if (coordinates.length === 1) return maxZoom;
|
|
681
|
+
if (mapWidth <= 0 || mapHeight <= 0) return null;
|
|
682
|
+
let minLat = Infinity;
|
|
683
|
+
let maxLat = -Infinity;
|
|
684
|
+
let minLng = Infinity;
|
|
685
|
+
let maxLng = -Infinity;
|
|
686
|
+
for (const coord of coordinates) {
|
|
687
|
+
if (coord.lat < minLat) minLat = coord.lat;
|
|
688
|
+
if (coord.lat > maxLat) maxLat = coord.lat;
|
|
689
|
+
if (coord.lng < minLng) minLng = coord.lng;
|
|
690
|
+
if (coord.lng > maxLng) maxLng = coord.lng;
|
|
691
|
+
}
|
|
692
|
+
const pixelXMin = lngToMercatorX(minLng);
|
|
693
|
+
const pixelXMax = lngToMercatorX(maxLng);
|
|
694
|
+
const pixelYMin = latToMercatorY(maxLat);
|
|
695
|
+
const pixelYMax = latToMercatorY(minLat);
|
|
696
|
+
const dx = Math.abs(pixelXMax - pixelXMin);
|
|
697
|
+
const dy = Math.abs(pixelYMax - pixelYMin);
|
|
698
|
+
const availableWidth = mapWidth - padding * 2;
|
|
699
|
+
const availableHeight = mapHeight - padding * 2;
|
|
700
|
+
if (availableWidth <= 0 || availableHeight <= 0) return minZoom;
|
|
701
|
+
let zoom;
|
|
702
|
+
if (dx === 0 && dy === 0) {
|
|
703
|
+
return maxZoom;
|
|
704
|
+
} else if (dx === 0) {
|
|
705
|
+
zoom = Math.log2(availableHeight / dy);
|
|
706
|
+
} else if (dy === 0) {
|
|
707
|
+
zoom = Math.log2(availableWidth / dx);
|
|
708
|
+
} else {
|
|
709
|
+
const zoomX = Math.log2(availableWidth / dx);
|
|
710
|
+
const zoomY = Math.log2(availableHeight / dy);
|
|
711
|
+
zoom = Math.min(zoomX, zoomY);
|
|
712
|
+
}
|
|
713
|
+
return Math.max(minZoom, Math.min(maxZoom, Math.floor(zoom * 100) / 100));
|
|
714
|
+
}
|
|
715
|
+
function useDefaultZoom(options) {
|
|
716
|
+
const { coordinates, mapWidth, mapHeight, padding, maxZoom, minZoom } = options;
|
|
717
|
+
return React3.useMemo(
|
|
718
|
+
() => computeDefaultZoom({
|
|
719
|
+
coordinates,
|
|
720
|
+
mapWidth,
|
|
721
|
+
mapHeight,
|
|
722
|
+
padding,
|
|
723
|
+
maxZoom,
|
|
724
|
+
minZoom
|
|
725
|
+
}),
|
|
726
|
+
[coordinates, mapWidth, mapHeight, padding, maxZoom, minZoom]
|
|
727
|
+
);
|
|
728
|
+
}
|
|
661
729
|
var PANEL_POSITION_CLASS = {
|
|
662
730
|
"top-left": "left-4 top-4",
|
|
663
731
|
"top-right": "right-4 top-4",
|
|
@@ -902,9 +970,50 @@ function GeoMap({
|
|
|
902
970
|
clearSelectionOnMapClick = true,
|
|
903
971
|
mapChildren,
|
|
904
972
|
optixFlowConfig,
|
|
973
|
+
mapSize,
|
|
905
974
|
IconComponent = FallbackIcon,
|
|
906
975
|
ImgComponent = FallbackImg
|
|
907
976
|
}) {
|
|
977
|
+
const containerRef = React3__namespace.useRef(null);
|
|
978
|
+
const [containerDimensions, setContainerDimensions] = React3__namespace.useState({
|
|
979
|
+
width: 800,
|
|
980
|
+
// Default width
|
|
981
|
+
height: 520
|
|
982
|
+
// Default height
|
|
983
|
+
});
|
|
984
|
+
const [isMobile, setIsMobile] = React3__namespace.useState(false);
|
|
985
|
+
React3__namespace.useEffect(() => {
|
|
986
|
+
const checkMobile = () => {
|
|
987
|
+
setIsMobile(window.innerWidth < 768);
|
|
988
|
+
};
|
|
989
|
+
checkMobile();
|
|
990
|
+
window.addEventListener("resize", checkMobile);
|
|
991
|
+
return () => window.removeEventListener("resize", checkMobile);
|
|
992
|
+
}, []);
|
|
993
|
+
const calculatedHeight = React3__namespace.useMemo(() => {
|
|
994
|
+
if (mapSize) {
|
|
995
|
+
return isMobile ? mapSize.mobile : mapSize.desktop;
|
|
996
|
+
}
|
|
997
|
+
return isMobile ? 420 : 520;
|
|
998
|
+
}, [mapSize, isMobile]);
|
|
999
|
+
React3__namespace.useEffect(() => {
|
|
1000
|
+
if (!containerRef.current) return;
|
|
1001
|
+
const updateDimensions = () => {
|
|
1002
|
+
if (containerRef.current) {
|
|
1003
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
1004
|
+
setContainerDimensions({
|
|
1005
|
+
width: rect.width || 800,
|
|
1006
|
+
height: rect.height || calculatedHeight
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
updateDimensions();
|
|
1011
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
1012
|
+
const resizeObserver = new ResizeObserver(updateDimensions);
|
|
1013
|
+
resizeObserver.observe(containerRef.current);
|
|
1014
|
+
return () => resizeObserver.disconnect();
|
|
1015
|
+
}
|
|
1016
|
+
}, [calculatedHeight]);
|
|
908
1017
|
const normalizedStandaloneMarkers = React3__namespace.useMemo(
|
|
909
1018
|
() => markers.map((marker, index) => ({
|
|
910
1019
|
...marker,
|
|
@@ -988,39 +1097,41 @@ function GeoMap({
|
|
|
988
1097
|
longitude: DEFAULT_VIEW_STATE.longitude
|
|
989
1098
|
};
|
|
990
1099
|
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
return markerFocusZoom;
|
|
994
|
-
}
|
|
995
|
-
const allCoords = [];
|
|
1100
|
+
const zoomCoordinates = React3__namespace.useMemo(() => {
|
|
1101
|
+
const coords = [];
|
|
996
1102
|
normalizedStandaloneMarkers.forEach((marker) => {
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1103
|
+
coords.push({
|
|
1104
|
+
lat: marker.latitude,
|
|
1105
|
+
lng: marker.longitude
|
|
1000
1106
|
});
|
|
1001
1107
|
});
|
|
1002
1108
|
normalizedClusters.forEach((cluster) => {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1109
|
+
coords.push({
|
|
1110
|
+
lat: cluster.latitude,
|
|
1111
|
+
lng: cluster.longitude
|
|
1006
1112
|
});
|
|
1007
1113
|
});
|
|
1008
|
-
|
|
1114
|
+
return coords;
|
|
1115
|
+
}, [normalizedStandaloneMarkers, normalizedClusters]);
|
|
1116
|
+
const properZoom = useDefaultZoom({
|
|
1117
|
+
coordinates: zoomCoordinates,
|
|
1118
|
+
mapWidth: containerDimensions.width,
|
|
1119
|
+
mapHeight: containerDimensions.height,
|
|
1120
|
+
padding: 80,
|
|
1121
|
+
// Increased padding for better framing
|
|
1122
|
+
maxZoom: 18,
|
|
1123
|
+
minZoom: 1
|
|
1124
|
+
});
|
|
1125
|
+
const calculatedZoom = React3__namespace.useMemo(() => {
|
|
1126
|
+
if (zoomCoordinates.length === 1) {
|
|
1127
|
+
return markerFocusZoom;
|
|
1128
|
+
}
|
|
1129
|
+
if (zoomCoordinates.length === 0) {
|
|
1009
1130
|
return DEFAULT_VIEW_STATE.zoom;
|
|
1010
1131
|
}
|
|
1011
|
-
const
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
const lngDiff = Math.max(...lngs) - Math.min(...lngs);
|
|
1015
|
-
const maxDiff = Math.max(latDiff, lngDiff);
|
|
1016
|
-
if (maxDiff > 10) return 3;
|
|
1017
|
-
if (maxDiff > 5) return 5;
|
|
1018
|
-
if (maxDiff > 2) return 7;
|
|
1019
|
-
if (maxDiff > 1) return 9;
|
|
1020
|
-
if (maxDiff > 0.5) return 10;
|
|
1021
|
-
if (maxDiff > 0.1) return 12;
|
|
1022
|
-
return 13;
|
|
1023
|
-
}, [normalizedClusters, normalizedStandaloneMarkers, markerFocusZoom]);
|
|
1132
|
+
const adjustedZoom = properZoom ? properZoom - 0.5 : DEFAULT_VIEW_STATE.zoom;
|
|
1133
|
+
return Math.min(adjustedZoom, 15);
|
|
1134
|
+
}, [properZoom, zoomCoordinates.length, markerFocusZoom]);
|
|
1024
1135
|
const [uncontrolledViewState, setUncontrolledViewState] = React3__namespace.useState({
|
|
1025
1136
|
latitude: defaultViewState?.latitude ?? firstCoordinate.latitude,
|
|
1026
1137
|
longitude: defaultViewState?.longitude ?? firstCoordinate.longitude,
|
|
@@ -1346,25 +1457,35 @@ function GeoMap({
|
|
|
1346
1457
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1347
1458
|
"div",
|
|
1348
1459
|
{
|
|
1460
|
+
ref: containerRef,
|
|
1349
1461
|
className: cn(
|
|
1350
|
-
"relative
|
|
1462
|
+
"relative rounded-2xl border border-border bg-background",
|
|
1463
|
+
// Remove overflow-hidden from outer container to allow panel to overflow
|
|
1351
1464
|
className
|
|
1352
1465
|
),
|
|
1466
|
+
style: {
|
|
1467
|
+
// If className includes height settings, they'll override via CSS specificity
|
|
1468
|
+
height: className?.includes("h-[") || className?.includes("min-h-[") || className?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`,
|
|
1469
|
+
// Explicitly allow overflow for marker panels
|
|
1470
|
+
overflow: "visible"
|
|
1471
|
+
},
|
|
1353
1472
|
children: [
|
|
1354
1473
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1355
1474
|
"div",
|
|
1356
1475
|
{
|
|
1357
1476
|
className: cn(
|
|
1358
|
-
"w-full",
|
|
1359
|
-
//
|
|
1360
|
-
mapWrapperClassName
|
|
1477
|
+
"w-full rounded-2xl",
|
|
1478
|
+
// Only apply default height class if mapWrapperClassName not provided
|
|
1479
|
+
!mapWrapperClassName && `h-[${calculatedHeight}px]`,
|
|
1480
|
+
mapWrapperClassName
|
|
1361
1481
|
),
|
|
1362
1482
|
style: {
|
|
1363
|
-
//
|
|
1364
|
-
height: mapWrapperClassName ? void 0 :
|
|
1483
|
+
// If mapWrapperClassName includes height, let it handle the height
|
|
1484
|
+
height: mapWrapperClassName?.includes("h-[") || mapWrapperClassName?.includes("min-h-[") || mapWrapperClassName?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`,
|
|
1365
1485
|
maxHeight: "100vh",
|
|
1366
1486
|
// Prevent excessive growth
|
|
1367
1487
|
position: "relative",
|
|
1488
|
+
// Keep overflow hidden only on the map wrapper to contain the canvas
|
|
1368
1489
|
overflow: "hidden"
|
|
1369
1490
|
},
|
|
1370
1491
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1390,6 +1511,10 @@ function GeoMap({
|
|
|
1390
1511
|
geolocateControlPosition,
|
|
1391
1512
|
flyToOptions,
|
|
1392
1513
|
className: cn("h-full w-full", mapClassName),
|
|
1514
|
+
style: {
|
|
1515
|
+
// Pass the calculated height to MapLibre for better zoom calculations
|
|
1516
|
+
height: mapClassName?.includes("h-[") || mapClassName?.includes("min-h-[") || mapClassName?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`
|
|
1517
|
+
},
|
|
1393
1518
|
children: mapChildren
|
|
1394
1519
|
}
|
|
1395
1520
|
)
|
|
@@ -1399,9 +1524,13 @@ function GeoMap({
|
|
|
1399
1524
|
"div",
|
|
1400
1525
|
{
|
|
1401
1526
|
className: cn(
|
|
1402
|
-
"pointer-events-none absolute z-
|
|
1527
|
+
"pointer-events-none absolute z-30",
|
|
1403
1528
|
PANEL_POSITION_CLASS[panelPosition]
|
|
1404
1529
|
),
|
|
1530
|
+
style: {
|
|
1531
|
+
// Ensure panel can overflow and has higher z-index
|
|
1532
|
+
zIndex: 30
|
|
1533
|
+
},
|
|
1405
1534
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-auto", children: renderMarkerPanel() })
|
|
1406
1535
|
}
|
|
1407
1536
|
) : null
|