Skip to content

Commit 5324afa

Browse files
authored
responsive-iframe example (#1359)
* fix pager: null * responsive-iframe example * link to source * plain .md links
1 parent 95b1302 commit 5324afa

File tree

13 files changed

+168
-5
lines changed

13 files changed

+168
-5
lines changed

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
* [`hello-world`](https://observablehq.observablehq.cloud/framework-example-hello-world/) - A minimal Framework project
6767
* [`intersection-observer`](https://observablehq.observablehq.cloud/framework-example-intersection-observer/) - Scrollytelling with IntersectionObserver
6868
* [`penguin-classification`](https://observablehq.observablehq.cloud/framework-example-penguin-classification/) - Logistic regression in Python; validating models with Observable Plot
69+
* [`responsive-iframe`](https://observablehq.observablehq.cloud/framework-example-responsive-iframe/) - Adjust the height of an embedded iframe to fit its content
6970

7071
## About these examples
7172

examples/geotiff/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
View live: <https://observablehq.observablehq.cloud/framework-example-geotiff/>
66

7-
This Observable Framework example demonstrates how to use the [geotiff.js library](https://geotiffjs.github.io/) to read a GeoTIFF file, and then to display it as a raster plot using Observable Plot. The code is in [`src/index.md`](./src/index.md). The example data represents global surface temperatures.
7+
This Observable Framework example demonstrates how to use the [geotiff.js library](https://geotiffjs.github.io/) to read a GeoTIFF file, and then to display it as a raster plot using Observable Plot. The code is in [`src/index.md`](./src/index.md?plain=1). The example data represents global surface temperatures.

examples/google-analytics/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ The Google Analytics [API Quickstart](https://developers.google.com/analytics/de
2626

2727
## Charts
2828

29-
The dashboard displays a variety of charts, made with [Observable Plot](https://observablehq.com/plot/). With the key numbers at the top, a line chart or an area chart. Active users are displayed with a horizon chart faceted by channel. The “new vs. returning” chart is a Marimekko. Finally, the activity by day and hour is a punchcard chart. The code for each of these charts is available in [`src/index.md`](https://github.com/observablehq/framework/blob/main/examples/google-analytics/src/index.md).
29+
The dashboard displays a variety of charts, made with [Observable Plot](https://observablehq.com/plot/). With the key numbers at the top, a line chart or an area chart. Active users are displayed with a horizon chart faceted by channel. The “new vs. returning” chart is a Marimekko. Finally, the activity by day and hour is a punchcard chart. The code for each of these charts is available in [`src/index.md`](./src/index.md?plain=1).

examples/hello-world/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
View live: <https://observablehq.observablehq.cloud/framework-example-hello-world/>
66

7-
This is a minimal Observable Framework example. It contains a single page in [`src/index.md`](./src/index.md) and almost no configuration.
7+
This is a minimal Observable Framework example. It contains a single page in [`src/index.md`](./src/index.md?plain=1) and almost no configuration.

examples/netcdf/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
View live: <https://observablehq.observablehq.cloud/framework-example-netcdf/>
66

7-
This Observable Framework example demonstrates how to use the [`netcdfjs` library](https://github.com/cheminfo/netcdfjs) to read a NetCDF file, and then to display it as a raster plot using Observable Plot. The code is in [`src/index.md`](./src/index.md). The example data is global marine winds from NOAA’s Pacific Marine Environmental Laboratory.
7+
This Observable Framework example demonstrates how to use the [`netcdfjs` library](https://github.com/cheminfo/netcdfjs) to read a NetCDF file, and then to display it as a raster plot using Observable Plot. The code is in [`src/index.md`](./src/index.md?plain=1). The example data is global marine winds from NOAA’s Pacific Marine Environmental Laboratory.

examples/plot/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
View live: <https://observablehq.observablehq.cloud/framework-example-plot/>
66

7-
This is an example Observable Framework project that tracks several metrics about the development and usage of [Observable Plot](https://observablehq.com/plot/). It contains a single page in [`src/index.md`](./src/index.md), with no configuration file.
7+
This is an example Observable Framework project that tracks several metrics about the development and usage of [Observable Plot](https://observablehq.com/plot/). It contains a single page in [`src/index.md`](./src/index.md?plain=1), with no configuration file.
88

99
## Data loaders
1010

examples/responsive-iframe/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.DS_Store
2+
/dist/
3+
node_modules/
4+
yarn-error.log

examples/responsive-iframe/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[Framework examples →](../)
2+
3+
# Responsive iframe
4+
5+
View live: <https://observablehq.observablehq.cloud/framework-example-responsive-iframe/>
6+
7+
This Observable Framework example demonstrates how to implement a responsive iframe such that the height of the iframe automatically adjusts to show all of the content without scrolling. This example also demonstrates how to turn off Framework’s additional user interface elements (such as the sidebar) so that the embedded page contains only content. The main page is in [`src/index.md`](./src/index.md?plain=1) and the embedded page is in [`src/embed.md`](./src/embed.md?plain=1).
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
export default {
2+
root: "src",
3+
4+
// Shared Observable example configuration; feel free to remove this.
5+
title: "Observable Framework",
6+
toc: false,
7+
sidebar: false,
8+
head:
9+
process.env.CI &&
10+
`<script type="module" async src="https://events.observablehq.com/client.js?pageLoad"></script>
11+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9B88TP6PKQ"></script>
12+
<script>window.dataLayer=window.dataLayer||[];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js',new Date());\ngtag('config','G-9B88TP6PKQ');</script>`,
13+
header: `<style>
14+
15+
#observablehq-header a[href] {
16+
color: inherit;
17+
}
18+
19+
#observablehq-header a[target="_blank"] {
20+
display: flex;
21+
align-items: center;
22+
gap: 0.25rem;
23+
text-decoration: none;
24+
}
25+
26+
#observablehq-header a[target="_blank"]:hover span {
27+
text-decoration: underline;
28+
}
29+
30+
#observablehq-header a[target="_blank"]::after {
31+
content: "\\2197";
32+
}
33+
34+
#observablehq-header a[target="_blank"]:not(:hover, :focus)::after {
35+
color: var(--theme-foreground-muted);
36+
}
37+
38+
@container not (min-width: 640px) {
39+
.hide-if-small {
40+
display: none;
41+
}
42+
}
43+
44+
</style>
45+
<div style="display: flex; align-items: center; gap: 0.5rem; height: 2.2rem; margin: -1.5rem -2rem 2rem -2rem; padding: 0.5rem 2rem; border-bottom: solid 1px var(--theme-foreground-faintest); font: 500 16px var(--sans-serif);">
46+
<a href="https://observablehq.com/" target="_self" rel="" style="display: flex; align-items: center;">
47+
<svg width="22" height="22" viewBox="0 0 21.92930030822754 22.68549919128418" fill="currentColor">
48+
<path d="M10.9646 18.9046C9.95224 18.9046 9.07507 18.6853 8.33313 18.2467C7.59386 17.8098 7.0028 17.1909 6.62722 16.4604C6.22789 15.7003 5.93558 14.8965 5.75735 14.0684C5.56825 13.1704 5.47613 12.2574 5.48232 11.3427C5.48232 10.6185 5.52984 9.92616 5.62578 9.26408C5.7208 8.60284 5.89715 7.93067 6.15391 7.24843C6.41066 6.56618 6.74143 5.97468 7.14438 5.47308C7.56389 4.9592 8.1063 4.54092 8.72969 4.25059C9.38391 3.93719 10.1277 3.78091 10.9646 3.78091C11.977 3.78091 12.8542 4.00021 13.5962 4.43879C14.3354 4.87564 14.9265 5.49454 15.3021 6.22506C15.6986 6.97704 15.9883 7.7744 16.1719 8.61712C16.3547 9.459 16.447 10.3681 16.447 11.3427C16.447 12.067 16.3995 12.7593 16.3035 13.4214C16.2013 14.1088 16.0206 14.7844 15.7644 15.437C15.4994 16.1193 15.1705 16.7108 14.7739 17.2124C14.3774 17.714 13.8529 18.1215 13.1996 18.4349C12.5463 18.7483 11.8016 18.9046 10.9646 18.9046ZM12.8999 13.3447C13.4242 12.8211 13.7159 12.0966 13.7058 11.3427C13.7058 10.5639 13.4436 9.89654 12.92 9.34074C12.3955 8.78495 11.7441 8.50705 10.9646 8.50705C10.1852 8.50705 9.53376 8.78495 9.00928 9.34074C8.49569 9.87018 8.21207 10.5928 8.22348 11.3427C8.22348 12.1216 8.48572 12.7889 9.00928 13.3447C9.53376 13.9005 10.1852 14.1784 10.9646 14.1784C11.7441 14.1784 12.3891 13.9005 12.8999 13.3447ZM10.9646 22.6855C17.0199 22.6855 21.9293 17.6068 21.9293 11.3427C21.9293 5.07871 17.0199 0 10.9646 0C4.90942 0 0 5.07871 0 11.3427C0 17.6068 4.90942 22.6855 10.9646 22.6855Z"></path>
49+
</svg>
50+
</a>
51+
<div style="display: flex; flex-grow: 1; justify-content: space-between; align-items: baseline;">
52+
<a href="https://observablehq.com/framework/" target="_self" rel="">
53+
<span class="hide-if-small">Observable</span> Framework
54+
</a>
55+
<span style="display: flex; align-items: baseline; gap: 0.5rem; font-size: 14px;">
56+
<a target="_blank" href="https://github.com/observablehq/framework/tree/main/examples/responsive-iframe"><span>View source</span></a>
57+
</span>
58+
</div>
59+
</div>`
60+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"type": "module",
3+
"private": true,
4+
"scripts": {
5+
"clean": "rimraf src/.observablehq/cache",
6+
"build": "rimraf dist && observable build",
7+
"dev": "observable preview",
8+
"deploy": "observable deploy",
9+
"observable": "observable"
10+
},
11+
"dependencies": {
12+
"@observablehq/framework": "^1.7.1"
13+
},
14+
"devDependencies": {
15+
"rimraf": "^5.0.5"
16+
},
17+
"engines": {
18+
"node": ">=18"
19+
}
20+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/.observablehq/cache/
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
sidebar: false
3+
header: false
4+
footer: false
5+
pager: false
6+
---
7+
8+
I am a responsive iframe.
9+
10+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada ante orci, a sodales mi faucibus eu. Nunc leo nunc, cursus vitae blandit vestibulum, porttitor vel enim. Aenean sagittis ornare sapien, et dictum erat aliquet ac. Mauris vitae fringilla arcu. Mauris faucibus lorem laoreet diam tincidunt blandit.
11+
12+
Maecenas aliquet, nisi ac imperdiet molestie, libero neque tempor lacus, sit amet pellentesque lacus sapien in tellus. Fusce ex sem, scelerisque in massa sit amet, mollis pulvinar nibh. Integer rutrum sagittis mauris in pharetra. Maecenas accumsan est sit amet nunc scelerisque scelerisque. Nam rutrum nunc placerat lectus varius rutrum. Fusce viverra dolor felis, vitae aliquam velit viverra in.
13+
14+
```js
15+
const observer = new ResizeObserver(([entry]) => parent.postMessage({height: entry.target.offsetHeight}, "*"));
16+
observer.observe(document.documentElement);
17+
invalidation.then(() => observer.disconnect());
18+
```
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Responsive iframe
2+
3+
This example demonstrates how to implement a responsive iframe using Observable Framework such that the height of the iframe automatically adjusts to show all of the content without scrolling. This example also demonstrates how to turn off Framework’s additional user interface elements (such as the sidebar) so that the embedded page contains only content.
4+
5+
Try resizing the width of the iframe using the slider below; notice that the height adjusts automatically.
6+
7+
```js
8+
const iframeWidth = view(Inputs.range([200, 640], {step: 1, value: document.querySelector("#observablehq-main").offsetWidth, label: "Width"}));
9+
```
10+
11+
<iframe id="iframe" scrolling="no" src="./embed"></iframe>
12+
13+
```html run=false
14+
<iframe id="iframe" scrolling="no" src="./embed"></iframe>
15+
```
16+
17+
```js
18+
iframe.width = iframeWidth; // set the iframe width reactively
19+
```
20+
21+
On the embeded page (`src/embed.md`), the following code uses a [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) to observe the content height and posts a message to the parent frame reporting the new height.
22+
23+
```js run=false
24+
const observer = new ResizeObserver(([entry]) => parent.postMessage({height: entry.target.offsetHeight}, "*"));
25+
observer.observe(document.documentElement);
26+
invalidation.then(() => observer.disconnect());
27+
```
28+
29+
<div class="note">
30+
31+
The `invalidation` promise is used to remove the old observer if the code is re-run. This is only needed during development.
32+
33+
</div>
34+
35+
In the parent frame (on this page, `src/index.md`), there’s a corresponding listener that receives messages and adjusts the height of the iframe accordingly.
36+
37+
```js echo
38+
const messaged = (event) => iframe.height = event.data.height;
39+
addEventListener("message", messaged);
40+
invalidation.then(() => removeEventListener("message", messaged));
41+
```
42+
43+
Lastly, the embeded page uses front matter to turn off the sidebar, header, footer, and pager. If you prefer, you can disable these for the entire project by adding these same options to the `observablehq.config.js` file.
44+
45+
```yaml run=false
46+
---
47+
sidebar: false
48+
header: false
49+
footer: false
50+
pager: false
51+
---
52+
```

0 commit comments

Comments
 (0)