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)