@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.
@@ -566,53 +566,50 @@ function MapLibre({
566
566
  }
567
567
  return getMapLibreStyleUrl("osm-bright", stadiaApiKey);
568
568
  }, [mapStyle, stadiaApiKey, styleUrl]);
569
- const isInIframe = React3__default.useMemo(() => {
570
- if (typeof window === "undefined") return false;
571
- try {
572
- return window.self !== window.top;
573
- } catch {
574
- return true;
575
- }
576
- }, []);
569
+ const containerRef = React3__default.useRef(null);
577
570
  React3__default.useEffect(() => {
578
- if (!isInIframe || !mapRef.current) return;
579
- let lastHeight = 0;
580
- let lastWidth = 0;
581
- let resizeTimeout;
582
- const handleResize = (entries) => {
583
- clearTimeout(resizeTimeout);
584
- const entry = entries[0];
585
- if (!entry) return;
586
- const { width, height } = entry.contentRect;
587
- const widthChanged = Math.abs(width - lastWidth) > 1;
588
- const heightChanged = Math.abs(height - lastHeight) > 1;
589
- if (widthChanged || heightChanged) {
590
- lastWidth = width;
591
- lastHeight = height;
592
- resizeTimeout = setTimeout(() => {
593
- mapRef.current?.resize();
594
- }, 250);
571
+ if (!mapRef.current || !containerRef.current) return;
572
+ const enforceContainerHeight = () => {
573
+ const container = containerRef.current;
574
+ const map = mapRef.current;
575
+ if (!container || !map) return;
576
+ const rect = container.getBoundingClientRect();
577
+ const maxHeight = Math.min(rect.height, window.innerHeight);
578
+ const canvas = map.getCanvas();
579
+ if (canvas && canvas.style.height) {
580
+ const canvasHeight = parseInt(canvas.style.height);
581
+ if (canvasHeight > maxHeight || canvasHeight > 2e3) {
582
+ map.resize();
583
+ }
595
584
  }
596
585
  };
597
- const parentElement = mapRef.current.getContainer().parentElement;
598
- if (parentElement) {
599
- const resizeObserver = new ResizeObserver(handleResize);
600
- resizeObserver.observe(parentElement);
601
- return () => {
602
- clearTimeout(resizeTimeout);
603
- resizeObserver.disconnect();
604
- };
586
+ const interval = setInterval(enforceContainerHeight, 1e3);
587
+ let resizeObserver = null;
588
+ if (typeof ResizeObserver !== "undefined") {
589
+ resizeObserver = new ResizeObserver(() => {
590
+ enforceContainerHeight();
591
+ });
592
+ resizeObserver.observe(containerRef.current);
605
593
  }
606
- }, [isInIframe]);
594
+ return () => {
595
+ clearInterval(interval);
596
+ if (resizeObserver) {
597
+ resizeObserver.disconnect();
598
+ }
599
+ };
600
+ }, []);
607
601
  return /* @__PURE__ */ jsx(
608
602
  "div",
609
603
  {
604
+ ref: containerRef,
610
605
  className: joinClassNames("relative w-full h-full", className),
611
606
  style: {
612
607
  width: "100%",
613
608
  height: "100%",
614
- // Prevent content from pushing container size in iframes
615
- ...isInIframe && { overflow: "hidden", position: "relative" },
609
+ maxHeight: "100vh",
610
+ // Prevent excessive height
611
+ overflow: "hidden",
612
+ position: "relative",
616
613
  ...style
617
614
  },
618
615
  children: /* @__PURE__ */ jsxs(
@@ -626,7 +623,7 @@ function MapLibre({
626
623
  onMoveEnd: handleMoveEnd,
627
624
  onClick: handleMapClick,
628
625
  attributionControl: false,
629
- trackResize: !isInIframe,
626
+ trackResize: true,
630
627
  dragRotate: false,
631
628
  touchZoomRotate: false,
632
629
  children: [
@@ -884,9 +881,25 @@ function GeoMap({
884
881
  clearSelectionOnMapClick = true,
885
882
  mapChildren,
886
883
  optixFlowConfig,
884
+ mapSize,
887
885
  IconComponent = FallbackIcon,
888
886
  ImgComponent = FallbackImg
889
887
  }) {
888
+ const [isMobile, setIsMobile] = React3.useState(false);
889
+ React3.useEffect(() => {
890
+ const checkMobile = () => {
891
+ setIsMobile(window.innerWidth < 768);
892
+ };
893
+ checkMobile();
894
+ window.addEventListener("resize", checkMobile);
895
+ return () => window.removeEventListener("resize", checkMobile);
896
+ }, []);
897
+ const calculatedHeight = React3.useMemo(() => {
898
+ if (mapSize) {
899
+ return isMobile ? mapSize.mobile : mapSize.desktop;
900
+ }
901
+ return isMobile ? 420 : 520;
902
+ }, [mapSize, isMobile]);
890
903
  const normalizedStandaloneMarkers = React3.useMemo(
891
904
  () => markers.map((marker, index) => ({
892
905
  ...marker,
@@ -995,14 +1008,17 @@ function GeoMap({
995
1008
  const latDiff = Math.max(...lats) - Math.min(...lats);
996
1009
  const lngDiff = Math.max(...lngs) - Math.min(...lngs);
997
1010
  const maxDiff = Math.max(latDiff, lngDiff);
998
- if (maxDiff > 10) return 3;
999
- if (maxDiff > 5) return 5;
1000
- if (maxDiff > 2) return 7;
1001
- if (maxDiff > 1) return 9;
1002
- if (maxDiff > 0.5) return 10;
1003
- if (maxDiff > 0.1) return 12;
1004
- return 13;
1005
- }, [normalizedClusters, normalizedStandaloneMarkers, markerFocusZoom]);
1011
+ const heightFactor = calculatedHeight / 520;
1012
+ const paddingFactor = 0.85;
1013
+ if (maxDiff > 10) return Math.max(2, 3 * heightFactor * paddingFactor);
1014
+ if (maxDiff > 5) return Math.max(4, 5 * heightFactor * paddingFactor);
1015
+ if (maxDiff > 2) return Math.max(6, 7 * heightFactor * paddingFactor);
1016
+ if (maxDiff > 1) return Math.max(8, 9 * heightFactor * paddingFactor);
1017
+ if (maxDiff > 0.5) return Math.max(9, 10 * heightFactor * paddingFactor);
1018
+ if (maxDiff > 0.1) return Math.max(11, 12 * heightFactor * paddingFactor);
1019
+ if (maxDiff > 0.01) return Math.max(12, 13 * heightFactor * paddingFactor);
1020
+ return Math.max(11, 12 * heightFactor * paddingFactor);
1021
+ }, [normalizedClusters, normalizedStandaloneMarkers, markerFocusZoom, calculatedHeight]);
1006
1022
  const [uncontrolledViewState, setUncontrolledViewState] = React3.useState({
1007
1023
  latitude: defaultViewState?.latitude ?? firstCoordinate.latitude,
1008
1024
  longitude: defaultViewState?.longitude ?? firstCoordinate.longitude,
@@ -1325,37 +1341,38 @@ function GeoMap({
1325
1341
  }
1326
1342
  return null;
1327
1343
  };
1328
- const isInIframe = React3.useMemo(() => {
1329
- if (typeof window === "undefined") return false;
1330
- try {
1331
- return window.self !== window.top;
1332
- } catch {
1333
- return true;
1334
- }
1335
- }, []);
1336
1344
  return /* @__PURE__ */ jsxs(
1337
1345
  "div",
1338
1346
  {
1339
1347
  className: cn(
1340
- "relative overflow-hidden rounded-2xl border border-border bg-background",
1348
+ "relative rounded-2xl border border-border bg-background",
1349
+ // Remove overflow-hidden from outer container to allow panel to overflow
1341
1350
  className
1342
1351
  ),
1343
1352
  style: {
1344
- // Use CSS containment to prevent layout shifts in iframes
1345
- ...isInIframe && { contain: "layout size" }
1353
+ // If className includes height settings, they'll override via CSS specificity
1354
+ height: className?.includes("h-[") || className?.includes("min-h-[") || className?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`,
1355
+ // Explicitly allow overflow for marker panels
1356
+ overflow: "visible"
1346
1357
  },
1347
1358
  children: [
1348
1359
  /* @__PURE__ */ jsx(
1349
1360
  "div",
1350
1361
  {
1351
1362
  className: cn(
1352
- "w-full",
1353
- // Default height, can be overridden by mapWrapperClassName
1354
- mapWrapperClassName || "h-[520px]"
1363
+ "w-full rounded-2xl",
1364
+ // Only apply default height class if mapWrapperClassName not provided
1365
+ !mapWrapperClassName && `h-[${calculatedHeight}px]`,
1366
+ mapWrapperClassName
1355
1367
  ),
1356
1368
  style: {
1357
- // Ensure proper height containment in iframes
1358
- ...isInIframe && !mapWrapperClassName && { height: "520px", minHeight: "420px" }
1369
+ // If mapWrapperClassName includes height, let it handle the height
1370
+ height: mapWrapperClassName?.includes("h-[") || mapWrapperClassName?.includes("min-h-[") || mapWrapperClassName?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`,
1371
+ maxHeight: "100vh",
1372
+ // Prevent excessive growth
1373
+ position: "relative",
1374
+ // Keep overflow hidden only on the map wrapper to contain the canvas
1375
+ overflow: "hidden"
1359
1376
  },
1360
1377
  children: /* @__PURE__ */ jsx(
1361
1378
  MapLibre,
@@ -1380,6 +1397,10 @@ function GeoMap({
1380
1397
  geolocateControlPosition,
1381
1398
  flyToOptions,
1382
1399
  className: cn("h-full w-full", mapClassName),
1400
+ style: {
1401
+ // Pass the calculated height to MapLibre for better zoom calculations
1402
+ height: mapClassName?.includes("h-[") || mapClassName?.includes("min-h-[") || mapClassName?.includes("max-h-[") ? void 0 : `${calculatedHeight}px`
1403
+ },
1383
1404
  children: mapChildren
1384
1405
  }
1385
1406
  )
@@ -1389,9 +1410,13 @@ function GeoMap({
1389
1410
  "div",
1390
1411
  {
1391
1412
  className: cn(
1392
- "pointer-events-none absolute z-20",
1413
+ "pointer-events-none absolute z-30",
1393
1414
  PANEL_POSITION_CLASS[panelPosition]
1394
1415
  ),
1416
+ style: {
1417
+ // Ensure panel can overflow and has higher z-index
1418
+ zIndex: 30
1419
+ },
1395
1420
  children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: renderMarkerPanel() })
1396
1421
  }
1397
1422
  ) : null