@page-speed/maps 0.1.7 → 0.1.9

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.
@@ -587,53 +587,50 @@ function MapLibre({
587
587
  }
588
588
  return getMapLibreStyleUrl("osm-bright", stadiaApiKey);
589
589
  }, [mapStyle, stadiaApiKey, styleUrl]);
590
- const isInIframe = React3__namespace.default.useMemo(() => {
591
- if (typeof window === "undefined") return false;
592
- try {
593
- return window.self !== window.top;
594
- } catch {
595
- return true;
596
- }
597
- }, []);
590
+ const containerRef = React3__namespace.default.useRef(null);
598
591
  React3__namespace.default.useEffect(() => {
599
- if (!isInIframe || !mapRef.current) return;
600
- let lastHeight = 0;
601
- let lastWidth = 0;
602
- let resizeTimeout;
603
- const handleResize = (entries) => {
604
- clearTimeout(resizeTimeout);
605
- const entry = entries[0];
606
- if (!entry) return;
607
- const { width, height } = entry.contentRect;
608
- const widthChanged = Math.abs(width - lastWidth) > 1;
609
- const heightChanged = Math.abs(height - lastHeight) > 1;
610
- if (widthChanged || heightChanged) {
611
- lastWidth = width;
612
- lastHeight = height;
613
- resizeTimeout = setTimeout(() => {
614
- mapRef.current?.resize();
615
- }, 250);
592
+ if (!mapRef.current || !containerRef.current) return;
593
+ const enforceContainerHeight = () => {
594
+ const container = containerRef.current;
595
+ const map = mapRef.current;
596
+ if (!container || !map) return;
597
+ const rect = container.getBoundingClientRect();
598
+ const maxHeight = Math.min(rect.height, window.innerHeight);
599
+ const canvas = map.getCanvas();
600
+ if (canvas && canvas.style.height) {
601
+ const canvasHeight = parseInt(canvas.style.height);
602
+ if (canvasHeight > maxHeight || canvasHeight > 2e3) {
603
+ map.resize();
604
+ }
616
605
  }
617
606
  };
618
- const parentElement = mapRef.current.getContainer().parentElement;
619
- if (parentElement) {
620
- const resizeObserver = new ResizeObserver(handleResize);
621
- resizeObserver.observe(parentElement);
622
- return () => {
623
- clearTimeout(resizeTimeout);
624
- resizeObserver.disconnect();
625
- };
607
+ const interval = setInterval(enforceContainerHeight, 1e3);
608
+ let resizeObserver = null;
609
+ if (typeof ResizeObserver !== "undefined") {
610
+ resizeObserver = new ResizeObserver(() => {
611
+ enforceContainerHeight();
612
+ });
613
+ resizeObserver.observe(containerRef.current);
626
614
  }
627
- }, [isInIframe]);
615
+ return () => {
616
+ clearInterval(interval);
617
+ if (resizeObserver) {
618
+ resizeObserver.disconnect();
619
+ }
620
+ };
621
+ }, []);
628
622
  return /* @__PURE__ */ jsxRuntime.jsx(
629
623
  "div",
630
624
  {
625
+ ref: containerRef,
631
626
  className: joinClassNames("relative w-full h-full", className),
632
627
  style: {
633
628
  width: "100%",
634
629
  height: "100%",
635
- // Prevent content from pushing container size in iframes
636
- ...isInIframe && { overflow: "hidden", position: "relative" },
630
+ maxHeight: "100vh",
631
+ // Prevent excessive height
632
+ overflow: "hidden",
633
+ position: "relative",
637
634
  ...style
638
635
  },
639
636
  children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -647,7 +644,7 @@ function MapLibre({
647
644
  onMoveEnd: handleMoveEnd,
648
645
  onClick: handleMapClick,
649
646
  attributionControl: false,
650
- trackResize: !isInIframe,
647
+ trackResize: true,
651
648
  dragRotate: false,
652
649
  touchZoomRotate: false,
653
650
  children: [
@@ -905,9 +902,25 @@ function GeoMap({
905
902
  clearSelectionOnMapClick = true,
906
903
  mapChildren,
907
904
  optixFlowConfig,
905
+ mapSize,
908
906
  IconComponent = FallbackIcon,
909
907
  ImgComponent = FallbackImg
910
908
  }) {
909
+ const [isMobile, setIsMobile] = React3__namespace.useState(false);
910
+ React3__namespace.useEffect(() => {
911
+ const checkMobile = () => {
912
+ setIsMobile(window.innerWidth < 768);
913
+ };
914
+ checkMobile();
915
+ window.addEventListener("resize", checkMobile);
916
+ return () => window.removeEventListener("resize", checkMobile);
917
+ }, []);
918
+ const calculatedHeight = React3__namespace.useMemo(() => {
919
+ if (mapSize) {
920
+ return isMobile ? mapSize.mobile : mapSize.desktop;
921
+ }
922
+ return isMobile ? 420 : 520;
923
+ }, [mapSize, isMobile]);
911
924
  const normalizedStandaloneMarkers = React3__namespace.useMemo(
912
925
  () => markers.map((marker, index) => ({
913
926
  ...marker,
@@ -1016,14 +1029,17 @@ function GeoMap({
1016
1029
  const latDiff = Math.max(...lats) - Math.min(...lats);
1017
1030
  const lngDiff = Math.max(...lngs) - Math.min(...lngs);
1018
1031
  const maxDiff = Math.max(latDiff, lngDiff);
1019
- if (maxDiff > 10) return 3;
1020
- if (maxDiff > 5) return 5;
1021
- if (maxDiff > 2) return 7;
1022
- if (maxDiff > 1) return 9;
1023
- if (maxDiff > 0.5) return 10;
1024
- if (maxDiff > 0.1) return 12;
1025
- return 13;
1026
- }, [normalizedClusters, normalizedStandaloneMarkers, markerFocusZoom]);
1032
+ const heightFactor = calculatedHeight / 520;
1033
+ const paddingFactor = 0.85;
1034
+ if (maxDiff > 10) return Math.max(2, 3 * heightFactor * paddingFactor);
1035
+ if (maxDiff > 5) return Math.max(4, 5 * heightFactor * paddingFactor);
1036
+ if (maxDiff > 2) return Math.max(6, 7 * heightFactor * paddingFactor);
1037
+ if (maxDiff > 1) return Math.max(8, 9 * heightFactor * paddingFactor);
1038
+ if (maxDiff > 0.5) return Math.max(9, 10 * heightFactor * paddingFactor);
1039
+ if (maxDiff > 0.1) return Math.max(11, 12 * heightFactor * paddingFactor);
1040
+ if (maxDiff > 0.01) return Math.max(12, 13 * heightFactor * paddingFactor);
1041
+ return Math.max(11, 12 * heightFactor * paddingFactor);
1042
+ }, [normalizedClusters, normalizedStandaloneMarkers, markerFocusZoom, calculatedHeight]);
1027
1043
  const [uncontrolledViewState, setUncontrolledViewState] = React3__namespace.useState({
1028
1044
  latitude: defaultViewState?.latitude ?? firstCoordinate.latitude,
1029
1045
  longitude: defaultViewState?.longitude ?? firstCoordinate.longitude,
@@ -1346,37 +1362,38 @@ function GeoMap({
1346
1362
  }
1347
1363
  return null;
1348
1364
  };
1349
- const isInIframe = React3__namespace.useMemo(() => {
1350
- if (typeof window === "undefined") return false;
1351
- try {
1352
- return window.self !== window.top;
1353
- } catch {
1354
- return true;
1355
- }
1356
- }, []);
1357
1365
  return /* @__PURE__ */ jsxRuntime.jsxs(
1358
1366
  "div",
1359
1367
  {
1360
1368
  className: cn(
1361
- "relative overflow-hidden rounded-2xl border border-border bg-background",
1369
+ "relative rounded-2xl border border-border bg-background",
1370
+ // Remove overflow-hidden from outer container to allow panel to overflow
1362
1371
  className
1363
1372
  ),
1364
1373
  style: {
1365
- // Use CSS containment to prevent layout shifts in iframes
1366
- ...isInIframe && { contain: "layout size" }
1374
+ // If className includes height settings, they'll override via CSS specificity
1375
+ height: className?.includes("h-[") || className?.includes("min-h-[") || className?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`,
1376
+ // Explicitly allow overflow for marker panels
1377
+ overflow: "visible"
1367
1378
  },
1368
1379
  children: [
1369
1380
  /* @__PURE__ */ jsxRuntime.jsx(
1370
1381
  "div",
1371
1382
  {
1372
1383
  className: cn(
1373
- "w-full",
1374
- // Default height, can be overridden by mapWrapperClassName
1375
- mapWrapperClassName || "h-[520px]"
1384
+ "w-full rounded-2xl",
1385
+ // Only apply default height class if mapWrapperClassName not provided
1386
+ !mapWrapperClassName && `h-[${calculatedHeight}px]`,
1387
+ mapWrapperClassName
1376
1388
  ),
1377
1389
  style: {
1378
- // Ensure proper height containment in iframes
1379
- ...isInIframe && !mapWrapperClassName && { height: "520px", minHeight: "420px" }
1390
+ // If mapWrapperClassName includes height, let it handle the height
1391
+ height: mapWrapperClassName?.includes("h-[") || mapWrapperClassName?.includes("min-h-[") || mapWrapperClassName?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`,
1392
+ maxHeight: "100vh",
1393
+ // Prevent excessive growth
1394
+ position: "relative",
1395
+ // Keep overflow hidden only on the map wrapper to contain the canvas
1396
+ overflow: "hidden"
1380
1397
  },
1381
1398
  children: /* @__PURE__ */ jsxRuntime.jsx(
1382
1399
  MapLibre,
@@ -1401,6 +1418,10 @@ function GeoMap({
1401
1418
  geolocateControlPosition,
1402
1419
  flyToOptions,
1403
1420
  className: cn("h-full w-full", mapClassName),
1421
+ style: {
1422
+ // Pass the calculated height to MapLibre for better zoom calculations
1423
+ height: mapClassName?.includes("h-[") || mapClassName?.includes("min-h-[") || mapClassName?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`
1424
+ },
1404
1425
  children: mapChildren
1405
1426
  }
1406
1427
  )
@@ -1410,9 +1431,13 @@ function GeoMap({
1410
1431
  "div",
1411
1432
  {
1412
1433
  className: cn(
1413
- "pointer-events-none absolute z-20",
1434
+ "pointer-events-none absolute z-30",
1414
1435
  PANEL_POSITION_CLASS[panelPosition]
1415
1436
  ),
1437
+ style: {
1438
+ // Ensure panel can overflow and has higher z-index
1439
+ zIndex: 30
1440
+ },
1416
1441
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-auto", children: renderMarkerPanel() })
1417
1442
  }
1418
1443
  ) : null