Skip to content

Commit

Permalink
un-sandbox MDX component
Browse files Browse the repository at this point in the history
it will be sandboxed in the prototype
  • Loading branch information
Wattenberger committed Mar 15, 2022
1 parent 2286299 commit fe0b833
Show file tree
Hide file tree
Showing 5 changed files with 959 additions and 1,130 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@
"id": "markdown-block",
"title": "Markdown",
"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.",
"sandbox": false,
"sandbox": true,
"entry": "/src/blocks/file-blocks/live-markdown/index.tsx",
"extensions": [
"md",
Expand Down Expand Up @@ -238,6 +238,7 @@
"@githubnext/utils": "^0.15.4",
"@githubocto/flat-ui": "^0.13.4",
"@loadable/component": "^5.15.0",
"@mdx-js/runtime": "^2.0.0-next.9",
"@octokit/rest": "^18.12.0",
"@primer/components": "^31.1.0",
"@react-three/drei": "^7.20.5",
Expand Down Expand Up @@ -273,6 +274,7 @@
"react-syntax-highlighter": "^15.4.5",
"react-use": "^17.3.1",
"recharts": "^2.1.6",
"styled-components": "^5.3.3",
"three": "^0.134.0"
},
"resolutions": {
Expand Down
90 changes: 90 additions & 0 deletions src/blocks/file-blocks/live-markdown/CodeSandbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { ReactNode, useEffect, useState } from "react";
import LZString from "lz-string"

const optionsDefaults = {
fontsize: "14",
hidenavigation: "1",
codemirror: "1",
hidedevtools: "1",
}
export const CodeSandbox = ({
children,
height = "20em",
sandboxOptions = {},
dependencies,
}: {
height: string | number;
theme: string;
sandboxOptions: Record<string, string>;
children: ReactNode;
dependencies?: string[];
}) => {
const [url, setUrl] = useState("");
const parameters = getParameters({
files: {
"index.js": {
// @ts-ignore
content: children?.props?.children?.props?.children,
isBinary: false,
},
"package.json": {
content: JSON.stringify({
// @ts-ignore
dependencies: parseDependencies(dependencies),
}),
isBinary: false,
},
},
});

const getSandboxUrl = async () => {
const url = `https://codesandbox.io/api/v1/sandboxes/define?parameters=${parameters}&json=1`;
const res = await fetch(url);
const data = await res.json();
const id = data?.sandbox_id;
const params = new URLSearchParams({ ...optionsDefaults, ...sandboxOptions }).toString()
const iframeUrl = `https://codesandbox.io/embed/${id}?${params}`;

setUrl(iframeUrl);
};
useEffect(() => {
getSandboxUrl();
}, []);

return (
<div className="w-full h-full mt-3 mb-10">
{!!url && (
<iframe
className="w-full outline-none"
style={{
height
}}
src={url}
title="CodeSandbox"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
/>
)}
</div>
);
};

const parseDependencies = (dependencies: string[]): Record<string, string> => {
let res = {};
dependencies.forEach((dep) => {
const [name, version = "latest"] = dep.split("@");
// @ts-ignore
res[name] = version;
});
return res;
};

// ported from "codesandbox/lib/api/define"
function compress(input: string) {
return LZString.compressToBase64(input)
.replace(/\+/g, "-") // Convert '+' to '-'
.replace(/\//g, "_") // Convert '/' to '_'
.replace(/=+$/, ""); // Remove ending '='
}
function getParameters(parameters: any) {
return compress(JSON.stringify(parameters));
}
37 changes: 37 additions & 0 deletions src/blocks/file-blocks/live-markdown/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react";

export class ErrorBoundary extends React.Component {
// @ts-ignore
constructor(props) {
super(props);
this.state = { hasError: false, errorMessage: null };
}

// @ts-ignore
static getDerivedStateFromError(error) {
return { hasError: true, errorMessage: error.message };
}

// @ts-ignore
componentDidCatch(error, errorInfo) {
console.log(error, errorInfo);
}

render() {
// @ts-ignore
if (this.state.hasError) {
return (
<div className="flex flex-col">

<h1>Something went wrong.</h1>
<p>
{/* @ts-ignore */}
{this.state.errorMessage || ""}
</p>
</div>
);
}

return this.props.children;
}
}
Loading

0 comments on commit fe0b833

Please sign in to comment.