Skip to content

Commit 39b6a82

Browse files
authored
Merge pull request #185 from code-hike/playground
Playground
2 parents b7d7da7 + 8939e5f commit 39b6a82

16 files changed

+757
-3
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"packages": [
55
"packages/mdx",
66
"examples/*",
7+
"playground",
78
"site"
89
]
910
},

packages/mdx/src/remark/transform.preview.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import fetch from "node-fetch"
21
import { visitAsync, toJSX } from "./unist-utils"
32
import { JsxNode, SuperNode } from "./nodes"
43

@@ -14,6 +13,7 @@ export async function getPresetConfig(
1413
const prefix = "https://codesandbox.io/s/"
1514
const csbid = url.slice(prefix.length)
1615
const configUrl = `https://codesandbox.io/api/v1/sandboxes/${csbid}/sandpack`
16+
const { default: fetch } = await import("node-fetch")
1717
const res = await fetch(configUrl)
1818
return await res.json()
1919
}

playground/.gitignore

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?
25+
26+
27+
# Contentlayer
28+
.contentlayer

playground/index.html

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/src/favicon.ico" />
6+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
7+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
8+
<meta
9+
property="description"
10+
content="Try Code Hike directly in your browser"
11+
/>
12+
<meta property="og:title" content="Code Hike Playground" />
13+
<meta
14+
property="og:description"
15+
content="Try Code Hike directly in your browser"
16+
/>
17+
<meta name="twitter:site" content="@codehike_" />
18+
<!-- <meta name="twitter:card" content="summary_large_image" />
19+
<meta name="image" content="{imageUrl}" />
20+
<meta itemprop="image" content="{imageUrl}" />
21+
<meta name="twitter:image" content="{imageUrl}" />
22+
<meta property="og:image" content="{imageUrl}" /> -->
23+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
24+
<title>Code Hike Playground</title>
25+
</head>
26+
<body>
27+
<div id="root"></div>
28+
<script type="module" src="/src/main.jsx"></script>
29+
</body>
30+
</html>

playground/package.json

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "playground",
3+
"private": true,
4+
"version": "0.0.0",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "vite build",
8+
"preview": "vite preview"
9+
},
10+
"dependencies": {
11+
"@code-hike/mdx": "^0.5.1",
12+
"@mdx-js/mdx": "^2.1.1",
13+
"@monaco-editor/react": "^4.4.5",
14+
"react": "^17.0.2",
15+
"react-dom": "^17.0.2",
16+
"react-error-boundary": "^3.1.4"
17+
},
18+
"devDependencies": {
19+
"@types/react": "^17.0.2",
20+
"@types/react-dom": "^17.0.2",
21+
"@vitejs/plugin-react": "^1.3.0",
22+
"vite": "^2.9.9"
23+
}
24+
}

playground/src/app.jsx

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { useState } from "react";
2+
import { Editor } from "./editor";
3+
import { Preview } from "./preview";
4+
5+
const defaultCode = `
6+
# Hello
7+
8+
Edit me.
9+
10+
~~~python hello.py
11+
# mark[16:24]
12+
print("This is Code Hike")
13+
~~~
14+
15+
`;
16+
17+
function App() {
18+
const [code, setCode] = useState(defaultCode);
19+
20+
return (
21+
<div className="app">
22+
<header>
23+
<a className="code-hike" href="https://codehike.org">
24+
<CodeHikeLogo />
25+
<h1>
26+
Code Hike
27+
<span>v0.5.1</span>
28+
</h1>
29+
</a>
30+
</header>
31+
<main>
32+
<Editor setCode={setCode} defaultCode={defaultCode} />
33+
<Preview code={code} />
34+
</main>
35+
</div>
36+
);
37+
}
38+
39+
function CodeHikeLogo(props) {
40+
return (
41+
<svg viewBox="-100 -100 200 200" fill="currentColor" {...props}>
42+
<path d="M 70 60 L 42 -27 L 72 -27 L 100 60 Z" />
43+
<path d="M 20.419540229885058 40.05357142857142 L 42 -27 L 72 -27 L 50.41954022988506 40.05357142857142 Z" />
44+
<path d="M 20.419540229885058 40.05357142857142 L -15 -70 L 15 -70 L 50.41954022988506 40.05357142857142 Z" />
45+
<path d="M -50.41954022988506 40.05357142857142 L -15 -70 L 15 -70 L -20.419540229885058 40.05357142857142 Z" />
46+
<path d="M -50.41954022988506 40.05357142857142 L -72 -27 L -42 -27 L -20.419540229885058 40.05357142857142 Z" />
47+
<path d="M -100 60 L -72 -27 L -42 -27 L -70 60 Z" />
48+
</svg>
49+
);
50+
}
51+
52+
export default App;

playground/src/editor.jsx

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import MonacoEditor from "@monaco-editor/react";
2+
import { useState } from "react";
3+
4+
export function Editor({ setCode, defaultCode }) {
5+
function handleEditorChange(value, event) {
6+
setCode(value);
7+
}
8+
9+
const [tab, setTab] = useState("mdx");
10+
return (
11+
<div className="editor-side">
12+
<nav>
13+
<span
14+
className="editor-tab"
15+
data-active={tab === "mdx"}
16+
onClick={() => setTab("mdx")}
17+
>
18+
MDX
19+
</span>
20+
<span
21+
className="editor-tab"
22+
data-active={tab === "css"}
23+
onClick={() => setTab("css")}
24+
>
25+
CSS
26+
</span>
27+
<span
28+
className="editor-tab"
29+
data-active={tab === "config"}
30+
onClick={() => setTab("config")}
31+
>
32+
Config
33+
</span>
34+
</nav>
35+
<MonacoEditor
36+
className="editor"
37+
onChange={handleEditorChange}
38+
defaultLanguage="markdown"
39+
theme="vs-dark"
40+
defaultValue={defaultCode}
41+
options={{
42+
// https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IEditorConstructionOptions.html
43+
minimap: {
44+
enabled: false,
45+
},
46+
lineNumbers: "off",
47+
scrollBeyondLastLine: false,
48+
hideCursorInOverviewRuler: true,
49+
matchBrackets: false,
50+
overviewRulerBorder: false,
51+
renderLineHighlight: "none",
52+
wordWrap: "on",
53+
tabSize: 2,
54+
}}
55+
/>
56+
</div>
57+
);
58+
}

playground/src/favicon-16x16.png

602 Bytes
Loading

playground/src/favicon-32x32.png

1.25 KB
Loading

playground/src/favicon.ico

15 KB
Binary file not shown.

playground/src/favicon.svg

+15
Loading

playground/src/index.css

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
body {
2+
margin: 0;
3+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4+
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5+
sans-serif;
6+
-webkit-font-smoothing: antialiased;
7+
-moz-osx-font-smoothing: grayscale;
8+
}
9+
10+
html,
11+
body,
12+
#root {
13+
height: 100%;
14+
}
15+
16+
.app {
17+
display: flex;
18+
flex-direction: column;
19+
width: 100%;
20+
height: 100%;
21+
}
22+
23+
header {
24+
display: flex;
25+
align-items: center;
26+
gap: 0.4rem;
27+
background-color: #111;
28+
color: #fafafa;
29+
height: 3.2rem;
30+
min-height: 3.2rem;
31+
border-bottom: 1px solid #444;
32+
}
33+
34+
header h1 {
35+
margin: 0;
36+
font-size: 1.5rem;
37+
line-height: 2rem;
38+
font-weight: 700;
39+
}
40+
41+
header h1 span {
42+
font-weight: 400;
43+
font-size: 0.875rem;
44+
line-height: 1.25rem;
45+
padding-left: 0.5rem;
46+
}
47+
48+
header a.code-hike {
49+
color: inherit;
50+
text-decoration: inherit;
51+
display: flex;
52+
margin-left: 1.5rem;
53+
gap: 0.5rem;
54+
}
55+
56+
header svg {
57+
width: 2rem;
58+
height: 2rem;
59+
display: block;
60+
color: rgb(96 165 250);
61+
}
62+
main {
63+
display: flex;
64+
flex: 1 1 auto;
65+
overflow: hidden;
66+
}
67+
68+
.editor-side {
69+
min-width: 400px;
70+
display: flex;
71+
flex-direction: column;
72+
flex: 1;
73+
/* background-color: #222;
74+
color: white; */
75+
}
76+
77+
.editor-side nav {
78+
background-color: #111;
79+
color: #fafafa;
80+
height: 2rem;
81+
min-height: 2rem;
82+
border-bottom: 1px solid #444;
83+
display: flex;
84+
align-items: center;
85+
padding: 0 0.6rem 0 1.5rem;
86+
gap: 1rem;
87+
font-weight: 600;
88+
}
89+
90+
.editor-tab {
91+
cursor: pointer;
92+
height: 100%;
93+
z-index: 1;
94+
box-sizing: border-box;
95+
padding-top: 3px;
96+
padding-bottom: 3px;
97+
}
98+
99+
.editor-tab[data-active="true"] {
100+
color: rgb(96 165 250);
101+
border-bottom: 3px solid;
102+
padding-bottom: 0px;
103+
}
104+
105+
.editor-tab:hover {
106+
color: rgb(179, 209, 245);
107+
}
108+
.preview {
109+
min-width: 600px;
110+
border-left: 2px solid cadetblue;
111+
padding: 1em;
112+
flex: 1;
113+
min-height: 0;
114+
overflow: auto;
115+
}
116+
117+
.preview-error {
118+
border: 1px solid red;
119+
}

playground/src/main.jsx

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from "react";
2+
import ReactDOM from "react-dom";
3+
import App from "./app";
4+
import "./index.css";
5+
6+
ReactDOM.render(
7+
<React.StrictMode>
8+
<App />
9+
</React.StrictMode>,
10+
document.getElementById("root")
11+
);

0 commit comments

Comments
 (0)