diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 513f3d935..ff9ea9421 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: - name: Setup | Node.js uses: actions/setup-node@v4 with: - node-version: "16.0.0" + node-version: "16.13.0" - name: Install dependencies and cache uses: bahmutov/npm-install@v1 diff --git a/sandpack-client/src/clients/node/inject-scripts/index.ts b/sandpack-client/src/clients/node/inject-scripts/index.ts index 83b7b8ac7..86bb62cc5 100644 --- a/sandpack-client/src/clients/node/inject-scripts/index.ts +++ b/sandpack-client/src/clients/node/inject-scripts/index.ts @@ -8,6 +8,7 @@ import { INJECT_MESSAGE_TYPE } from "@codesandbox/nodebox"; import consoleHook from "../../../inject-scripts/dist/consoleHook.js"; import { setupHistoryListeners } from "./historyListener"; +import { watchResize } from "./resize.js"; const scripts = [ { code: setupHistoryListeners.toString(), id: "historyListener" }, @@ -15,6 +16,7 @@ const scripts = [ code: "function consoleHook({ scope }) {" + consoleHook + "\n};", id: "consoleHook", }, + { code: watchResize.toString(), id: "watchResize" }, ]; export const injectScriptToIframe = ( diff --git a/sandpack-client/src/clients/node/inject-scripts/resize.ts b/sandpack-client/src/clients/node/inject-scripts/resize.ts new file mode 100644 index 000000000..c3d41f4ed --- /dev/null +++ b/sandpack-client/src/clients/node/inject-scripts/resize.ts @@ -0,0 +1,57 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export function watchResize({ scope }: { scope: { channelId: string } }) { + let lastHeight = 0; + + function getDocumentHeight(): number { + if (typeof window === "undefined") return 0; + + const { body } = document; + const html = document.documentElement; + + return Math.max(body.scrollHeight, body.offsetHeight, html.offsetHeight); + } + + function sendResizeEvent() { + const height = getDocumentHeight(); + + if (lastHeight !== height) { + window.parent.postMessage( + { + type: "resize", + height, + codesandbox: true, + channelId: scope.channelId, + }, + "*" + ); + } + + lastHeight = height; + } + + sendResizeEvent(); + + let throttle: any; + const observer = new MutationObserver(() => { + if (throttle === undefined) { + sendResizeEvent(); + + throttle = setTimeout(() => { + throttle = undefined; + }, 300); + } + }); + + observer.observe(document, { + attributes: true, + childList: true, + subtree: true, + }); + + /** + * Ideally we should only use a `MutationObserver` to trigger a resize event, + * however, we noted that it's not 100% reliable, so we went for polling strategy as well + */ + setInterval(sendResizeEvent, 300); +} diff --git a/sandpack-react/src/Playground.stories.tsx b/sandpack-react/src/Playground.stories.tsx index 47db10dba..331657111 100644 --- a/sandpack-react/src/Playground.stories.tsx +++ b/sandpack-react/src/Playground.stories.tsx @@ -4,14 +4,12 @@ import React from "react"; import { Sandpack } from "./"; +export default { + title: "Intro/Playground", +}; + export const Basic: React.FC = () => { - return ( - - ); + return ; }; export const EslintBasic = () => (