Skip to content

Commit fe0b833

Browse files
author
Amelia Wattenberger
committed
un-sandbox MDX component
it will be sandboxed in the prototype
1 parent 2286299 commit fe0b833

File tree

5 files changed

+959
-1130
lines changed

5 files changed

+959
-1130
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@
157157
"id": "markdown-block",
158158
"title": "Markdown",
159159
"description": "View markdown files. You can also view live repo into, using Issues, Releases, and Commits custom components, as well as live code examples with CodeSandbox.",
160-
"sandbox": false,
160+
"sandbox": true,
161161
"entry": "/src/blocks/file-blocks/live-markdown/index.tsx",
162162
"extensions": [
163163
"md",
@@ -238,6 +238,7 @@
238238
"@githubnext/utils": "^0.15.4",
239239
"@githubocto/flat-ui": "^0.13.4",
240240
"@loadable/component": "^5.15.0",
241+
"@mdx-js/runtime": "^2.0.0-next.9",
241242
"@octokit/rest": "^18.12.0",
242243
"@primer/components": "^31.1.0",
243244
"@react-three/drei": "^7.20.5",
@@ -273,6 +274,7 @@
273274
"react-syntax-highlighter": "^15.4.5",
274275
"react-use": "^17.3.1",
275276
"recharts": "^2.1.6",
277+
"styled-components": "^5.3.3",
276278
"three": "^0.134.0"
277279
},
278280
"resolutions": {
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { ReactNode, useEffect, useState } from "react";
2+
import LZString from "lz-string"
3+
4+
const optionsDefaults = {
5+
fontsize: "14",
6+
hidenavigation: "1",
7+
codemirror: "1",
8+
hidedevtools: "1",
9+
}
10+
export const CodeSandbox = ({
11+
children,
12+
height = "20em",
13+
sandboxOptions = {},
14+
dependencies,
15+
}: {
16+
height: string | number;
17+
theme: string;
18+
sandboxOptions: Record<string, string>;
19+
children: ReactNode;
20+
dependencies?: string[];
21+
}) => {
22+
const [url, setUrl] = useState("");
23+
const parameters = getParameters({
24+
files: {
25+
"index.js": {
26+
// @ts-ignore
27+
content: children?.props?.children?.props?.children,
28+
isBinary: false,
29+
},
30+
"package.json": {
31+
content: JSON.stringify({
32+
// @ts-ignore
33+
dependencies: parseDependencies(dependencies),
34+
}),
35+
isBinary: false,
36+
},
37+
},
38+
});
39+
40+
const getSandboxUrl = async () => {
41+
const url = `https://codesandbox.io/api/v1/sandboxes/define?parameters=${parameters}&json=1`;
42+
const res = await fetch(url);
43+
const data = await res.json();
44+
const id = data?.sandbox_id;
45+
const params = new URLSearchParams({ ...optionsDefaults, ...sandboxOptions }).toString()
46+
const iframeUrl = `https://codesandbox.io/embed/${id}?${params}`;
47+
48+
setUrl(iframeUrl);
49+
};
50+
useEffect(() => {
51+
getSandboxUrl();
52+
}, []);
53+
54+
return (
55+
<div className="w-full h-full mt-3 mb-10">
56+
{!!url && (
57+
<iframe
58+
className="w-full outline-none"
59+
style={{
60+
height
61+
}}
62+
src={url}
63+
title="CodeSandbox"
64+
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
65+
/>
66+
)}
67+
</div>
68+
);
69+
};
70+
71+
const parseDependencies = (dependencies: string[]): Record<string, string> => {
72+
let res = {};
73+
dependencies.forEach((dep) => {
74+
const [name, version = "latest"] = dep.split("@");
75+
// @ts-ignore
76+
res[name] = version;
77+
});
78+
return res;
79+
};
80+
81+
// ported from "codesandbox/lib/api/define"
82+
function compress(input: string) {
83+
return LZString.compressToBase64(input)
84+
.replace(/\+/g, "-") // Convert '+' to '-'
85+
.replace(/\//g, "_") // Convert '/' to '_'
86+
.replace(/=+$/, ""); // Remove ending '='
87+
}
88+
function getParameters(parameters: any) {
89+
return compress(JSON.stringify(parameters));
90+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from "react";
2+
3+
export class ErrorBoundary extends React.Component {
4+
// @ts-ignore
5+
constructor(props) {
6+
super(props);
7+
this.state = { hasError: false, errorMessage: null };
8+
}
9+
10+
// @ts-ignore
11+
static getDerivedStateFromError(error) {
12+
return { hasError: true, errorMessage: error.message };
13+
}
14+
15+
// @ts-ignore
16+
componentDidCatch(error, errorInfo) {
17+
console.log(error, errorInfo);
18+
}
19+
20+
render() {
21+
// @ts-ignore
22+
if (this.state.hasError) {
23+
return (
24+
<div className="flex flex-col">
25+
26+
<h1>Something went wrong.</h1>
27+
<p>
28+
{/* @ts-ignore */}
29+
{this.state.errorMessage || ""}
30+
</p>
31+
</div>
32+
);
33+
}
34+
35+
return this.props.children;
36+
}
37+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy