@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.
@@ -468,11 +468,55 @@ function MapLibre({
468
468
  }
469
469
  return getMapLibreStyleUrl("osm-bright", stadiaApiKey);
470
470
  }, [mapStyle, stadiaApiKey, styleUrl]);
471
+ const isInIframe = React3__namespace.default.useMemo(() => {
472
+ if (typeof window === "undefined") return false;
473
+ try {
474
+ return window.self !== window.top;
475
+ } catch {
476
+ return true;
477
+ }
478
+ }, []);
479
+ React3__namespace.default.useEffect(() => {
480
+ if (!isInIframe || !mapRef.current) return;
481
+ let lastHeight = 0;
482
+ let lastWidth = 0;
483
+ let resizeTimeout;
484
+ const handleResize = (entries) => {
485
+ clearTimeout(resizeTimeout);
486
+ const entry = entries[0];
487
+ if (!entry) return;
488
+ const { width, height } = entry.contentRect;
489
+ const widthChanged = Math.abs(width - lastWidth) > 1;
490
+ const heightChanged = Math.abs(height - lastHeight) > 1;
491
+ if (widthChanged || heightChanged) {
492
+ lastWidth = width;
493
+ lastHeight = height;
494
+ resizeTimeout = setTimeout(() => {
495
+ mapRef.current?.resize();
496
+ }, 250);
497
+ }
498
+ };
499
+ const parentElement = mapRef.current.getContainer().parentElement;
500
+ if (parentElement) {
501
+ const resizeObserver = new ResizeObserver(handleResize);
502
+ resizeObserver.observe(parentElement);
503
+ return () => {
504
+ clearTimeout(resizeTimeout);
505
+ resizeObserver.disconnect();
506
+ };
507
+ }
508
+ }, [isInIframe]);
471
509
  return /* @__PURE__ */ jsxRuntime.jsx(
472
510
  "div",
473
511
  {
474
512
  className: joinClassNames("relative w-full h-full", className),
475
- style: { width: "100%", height: "100%", ...style },
513
+ style: {
514
+ width: "100%",
515
+ height: "100%",
516
+ // Prevent content from pushing container size in iframes
517
+ ...isInIframe && { overflow: "hidden", position: "relative" },
518
+ ...style
519
+ },
476
520
  children: /* @__PURE__ */ jsxRuntime.jsxs(
477
521
  maplibre.Map,
478
522
  {
@@ -484,7 +528,7 @@ function MapLibre({
484
528
  onMoveEnd: handleMoveEnd,
485
529
  onClick: handleMapClick,
486
530
  attributionControl: false,
487
- trackResize: true,
531
+ trackResize: !isInIframe,
488
532
  dragRotate: false,
489
533
  touchZoomRotate: false,
490
534
  children: [
@@ -1071,7 +1115,7 @@ function GeoMap({
1071
1115
  "div",
1072
1116
  {
1073
1117
  className: cn(
1074
- "relative w-[320px] overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
1118
+ "relative w-80 overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
1075
1119
  panelClassName
1076
1120
  ),
1077
1121
  children: [
@@ -1145,7 +1189,7 @@ function GeoMap({
1145
1189
  "div",
1146
1190
  {
1147
1191
  className: cn(
1148
- "relative w-[320px] overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
1192
+ "relative w-80 overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
1149
1193
  panelClassName
1150
1194
  ),
1151
1195
  children: [
@@ -1183,6 +1227,14 @@ function GeoMap({
1183
1227
  }
1184
1228
  return null;
1185
1229
  };
1230
+ const isInIframe = React3__namespace.useMemo(() => {
1231
+ if (typeof window === "undefined") return false;
1232
+ try {
1233
+ return window.self !== window.top;
1234
+ } catch {
1235
+ return true;
1236
+ }
1237
+ }, []);
1186
1238
  return /* @__PURE__ */ jsxRuntime.jsxs(
1187
1239
  "div",
1188
1240
  {
@@ -1190,33 +1242,51 @@ function GeoMap({
1190
1242
  "relative overflow-hidden rounded-2xl border border-border bg-background",
1191
1243
  className
1192
1244
  ),
1245
+ style: {
1246
+ // Use CSS containment to prevent layout shifts in iframes
1247
+ ...isInIframe && { contain: "layout size" }
1248
+ },
1193
1249
  children: [
1194
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("h-[520px] w-full", mapWrapperClassName), children: /* @__PURE__ */ jsxRuntime.jsx(
1195
- MapLibre,
1250
+ /* @__PURE__ */ jsxRuntime.jsx(
1251
+ "div",
1196
1252
  {
1197
- stadiaApiKey,
1198
- mapStyle,
1199
- styleUrl,
1200
- mapLibreCssHref,
1201
- viewState: resolvedViewState,
1202
- onViewStateChange: applyViewState,
1203
- markers: mapMarkers,
1204
- onClick: (coord) => {
1205
- onMapClick?.(coord);
1206
- if (clearSelectionOnMapClick) {
1207
- clearSelection();
1208
- }
1253
+ className: cn(
1254
+ "w-full",
1255
+ // Default height, can be overridden by mapWrapperClassName
1256
+ mapWrapperClassName || "h-[520px]"
1257
+ ),
1258
+ style: {
1259
+ // Ensure proper height containment in iframes
1260
+ ...isInIframe && !mapWrapperClassName && { height: "520px", minHeight: "420px" }
1209
1261
  },
1210
- onMarkerDrag,
1211
- showNavigationControl,
1212
- showGeolocateControl,
1213
- navigationControlPosition,
1214
- geolocateControlPosition,
1215
- flyToOptions,
1216
- className: cn("h-full w-full", mapClassName),
1217
- children: mapChildren
1262
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1263
+ MapLibre,
1264
+ {
1265
+ stadiaApiKey,
1266
+ mapStyle,
1267
+ styleUrl,
1268
+ mapLibreCssHref,
1269
+ viewState: resolvedViewState,
1270
+ onViewStateChange: applyViewState,
1271
+ markers: mapMarkers,
1272
+ onClick: (coord) => {
1273
+ onMapClick?.(coord);
1274
+ if (clearSelectionOnMapClick) {
1275
+ clearSelection();
1276
+ }
1277
+ },
1278
+ onMarkerDrag,
1279
+ showNavigationControl,
1280
+ showGeolocateControl,
1281
+ navigationControlPosition,
1282
+ geolocateControlPosition,
1283
+ flyToOptions,
1284
+ className: cn("h-full w-full", mapClassName),
1285
+ children: mapChildren
1286
+ }
1287
+ )
1218
1288
  }
1219
- ) }),
1289
+ ),
1220
1290
  selection.type !== "none" ? /* @__PURE__ */ jsxRuntime.jsx(
1221
1291
  "div",
1222
1292
  {