@page-speed/maps 0.1.6 → 0.1.7

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,11 +587,55 @@ 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
+ }, []);
598
+ 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);
616
+ }
617
+ };
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
+ };
626
+ }
627
+ }, [isInIframe]);
590
628
  return /* @__PURE__ */ jsxRuntime.jsx(
591
629
  "div",
592
630
  {
593
631
  className: joinClassNames("relative w-full h-full", className),
594
- style: { width: "100%", height: "100%", ...style },
632
+ style: {
633
+ width: "100%",
634
+ height: "100%",
635
+ // Prevent content from pushing container size in iframes
636
+ ...isInIframe && { overflow: "hidden", position: "relative" },
637
+ ...style
638
+ },
595
639
  children: /* @__PURE__ */ jsxRuntime.jsxs(
596
640
  maplibre.Map,
597
641
  {
@@ -603,7 +647,7 @@ function MapLibre({
603
647
  onMoveEnd: handleMoveEnd,
604
648
  onClick: handleMapClick,
605
649
  attributionControl: false,
606
- trackResize: true,
650
+ trackResize: !isInIframe,
607
651
  dragRotate: false,
608
652
  touchZoomRotate: false,
609
653
  children: [
@@ -1190,7 +1234,7 @@ function GeoMap({
1190
1234
  "div",
1191
1235
  {
1192
1236
  className: cn(
1193
- "relative w-[320px] overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
1237
+ "relative w-80 overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
1194
1238
  panelClassName
1195
1239
  ),
1196
1240
  children: [
@@ -1264,7 +1308,7 @@ function GeoMap({
1264
1308
  "div",
1265
1309
  {
1266
1310
  className: cn(
1267
- "relative w-[320px] overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
1311
+ "relative w-80 overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
1268
1312
  panelClassName
1269
1313
  ),
1270
1314
  children: [
@@ -1302,6 +1346,14 @@ function GeoMap({
1302
1346
  }
1303
1347
  return null;
1304
1348
  };
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
+ }, []);
1305
1357
  return /* @__PURE__ */ jsxRuntime.jsxs(
1306
1358
  "div",
1307
1359
  {
@@ -1309,33 +1361,51 @@ function GeoMap({
1309
1361
  "relative overflow-hidden rounded-2xl border border-border bg-background",
1310
1362
  className
1311
1363
  ),
1364
+ style: {
1365
+ // Use CSS containment to prevent layout shifts in iframes
1366
+ ...isInIframe && { contain: "layout size" }
1367
+ },
1312
1368
  children: [
1313
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("h-[520px] w-full", mapWrapperClassName), children: /* @__PURE__ */ jsxRuntime.jsx(
1314
- MapLibre,
1369
+ /* @__PURE__ */ jsxRuntime.jsx(
1370
+ "div",
1315
1371
  {
1316
- stadiaApiKey,
1317
- mapStyle,
1318
- styleUrl,
1319
- mapLibreCssHref,
1320
- viewState: resolvedViewState,
1321
- onViewStateChange: applyViewState,
1322
- markers: mapMarkers,
1323
- onClick: (coord) => {
1324
- onMapClick?.(coord);
1325
- if (clearSelectionOnMapClick) {
1326
- clearSelection();
1327
- }
1372
+ className: cn(
1373
+ "w-full",
1374
+ // Default height, can be overridden by mapWrapperClassName
1375
+ mapWrapperClassName || "h-[520px]"
1376
+ ),
1377
+ style: {
1378
+ // Ensure proper height containment in iframes
1379
+ ...isInIframe && !mapWrapperClassName && { height: "520px", minHeight: "420px" }
1328
1380
  },
1329
- onMarkerDrag,
1330
- showNavigationControl,
1331
- showGeolocateControl,
1332
- navigationControlPosition,
1333
- geolocateControlPosition,
1334
- flyToOptions,
1335
- className: cn("h-full w-full", mapClassName),
1336
- children: mapChildren
1381
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1382
+ MapLibre,
1383
+ {
1384
+ stadiaApiKey,
1385
+ mapStyle,
1386
+ styleUrl,
1387
+ mapLibreCssHref,
1388
+ viewState: resolvedViewState,
1389
+ onViewStateChange: applyViewState,
1390
+ markers: mapMarkers,
1391
+ onClick: (coord) => {
1392
+ onMapClick?.(coord);
1393
+ if (clearSelectionOnMapClick) {
1394
+ clearSelection();
1395
+ }
1396
+ },
1397
+ onMarkerDrag,
1398
+ showNavigationControl,
1399
+ showGeolocateControl,
1400
+ navigationControlPosition,
1401
+ geolocateControlPosition,
1402
+ flyToOptions,
1403
+ className: cn("h-full w-full", mapClassName),
1404
+ children: mapChildren
1405
+ }
1406
+ )
1337
1407
  }
1338
- ) }),
1408
+ ),
1339
1409
  selection.type !== "none" ? /* @__PURE__ */ jsxRuntime.jsx(
1340
1410
  "div",
1341
1411
  {