diff --git a/apps/docs/components/MarkdownDoc.tsx b/apps/docs/components/MarkdownDoc.tsx
index 012b638..31ebe8a 100644
--- a/apps/docs/components/MarkdownDoc.tsx
+++ b/apps/docs/components/MarkdownDoc.tsx
@@ -10,6 +10,7 @@ import {
} from "@decadez/web-dev-ui/mdx";
import { MdxComponentGallery } from "./MdxComponentGallery";
import { getHeadingId } from "@/utils/headings";
+import { getSandboxAppFile } from "@/utils/sandbox";
type Token =
| { type: "heading"; depth: 2 | 3; text: string }
@@ -75,12 +76,13 @@ function renderToken(token: Token, index: number) {
return null;
case "code":
if (token.meta.includes("sandbox")) {
+ const appFile = getSandboxAppFile(token.language);
return (
diff --git a/apps/docs/next-env.d.ts b/apps/docs/next-env.d.ts
index 1970904..7996d35 100644
--- a/apps/docs/next-env.d.ts
+++ b/apps/docs/next-env.d.ts
@@ -1,6 +1,6 @@
///
///
-import "./.next/types/routes.d.ts";
+import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
diff --git a/apps/docs/utils/sandbox.ts b/apps/docs/utils/sandbox.ts
new file mode 100644
index 0000000..08d1dd9
--- /dev/null
+++ b/apps/docs/utils/sandbox.ts
@@ -0,0 +1,11 @@
+const sandboxLanguageExtensions: Record = {
+ js: "js",
+ jsx: "jsx",
+ ts: "ts",
+ tsx: "tsx",
+};
+
+export function getSandboxAppFile(language: string) {
+ const extension = sandboxLanguageExtensions[language.toLowerCase()] ?? "js";
+ return `/src/App.${extension}`;
+}
diff --git a/packages/web-dev-ui/package.json b/packages/web-dev-ui/package.json
index 71d6905..be145ea 100644
--- a/packages/web-dev-ui/package.json
+++ b/packages/web-dev-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "@decadez/web-dev-ui",
- "version": "0.3.1",
+ "version": "0.3.2",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
diff --git a/packages/web-dev-ui/src/mdx/sandpack/Preview.tsx b/packages/web-dev-ui/src/mdx/sandpack/Preview.tsx
index 2976f2f..0dfec23 100644
--- a/packages/web-dev-ui/src/mdx/sandpack/Preview.tsx
+++ b/packages/web-dev-ui/src/mdx/sandpack/Preview.tsx
@@ -24,6 +24,37 @@ type CustomPreviewProps = {
preview?: ReactNode;
};
+type SandpackPreviewError = {
+ title?: string;
+ message: string;
+} | null;
+
+export function shouldShowSandpackConsole(_error: SandpackPreviewError) {
+ return true;
+}
+
+export function shouldHideSandpackPreview({
+ bundlerIsReady,
+ currentError,
+ displayedError,
+ iframeComputedHeight,
+ previewIsSettled,
+}: {
+ bundlerIsReady: boolean;
+ currentError: SandpackPreviewError;
+ displayedError: SandpackPreviewError;
+ iframeComputedHeight: number | null;
+ previewIsSettled: boolean;
+}) {
+ return (
+ currentError !== null ||
+ displayedError !== null ||
+ iframeComputedHeight === null ||
+ !bundlerIsReady ||
+ !previewIsSettled
+ );
+}
+
function useDebounced(value: T): T {
const ref = useRef | null>(null);
const [saved, setSaved] = useState(value);
@@ -123,6 +154,12 @@ function LivePreview({
}
const error = useDebounced(rawError);
+ const previewCanBeShown =
+ rawError === null &&
+ error === null &&
+ iframeComputedHeight !== null &&
+ bundlerIsReady;
+ const previewIsSettled = useDebounced(previewCanBeShown);
const clientId = useId();
const iframeRef = useRef(null);
const sandpackIdle = sandpack.status === "idle";
@@ -173,7 +210,13 @@ function LivePreview({
[listen, clientId, sandpackIdle]
);
- const hideContent = error || !iframeComputedHeight || !bundlerIsReady;
+ const hideContent = shouldHideSandpackPreview({
+ bundlerIsReady,
+ currentError: rawError,
+ displayedError: error,
+ iframeComputedHeight,
+ previewIsSettled,
+ });
const iframeWrapperPosition = (): CSSProperties => {
if (hideContent) {
@@ -234,7 +277,7 @@ function LivePreview({
/>
-
+
>
);
}
diff --git a/packages/web-dev-ui/src/mdx/sandpack/template.ts b/packages/web-dev-ui/src/mdx/sandpack/template.ts
index 250be8c..da59426 100644
--- a/packages/web-dev-ui/src/mdx/sandpack/template.ts
+++ b/packages/web-dev-ui/src/mdx/sandpack/template.ts
@@ -29,9 +29,12 @@ root.render(
},
dependencies: {
"@decadez/web-dev-ui": "latest",
+ "@types/react": "^19.2.17",
+ "@types/react-dom": "^19.2.3",
react: "^19.2.7",
"react-dom": "^19.2.7",
"react-scripts": "^5.0.0",
+ typescript: "^4.9.5",
},
},
null,