Skip to content

Commit

Permalink
Docs: Add proper playground
Browse files Browse the repository at this point in the history
  • Loading branch information
nmn committed Nov 29, 2023
1 parent 6c12794 commit 08789a7
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 27 deletions.
101 changes: 101 additions & 0 deletions apps/docs/components/Playground.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

import * as React from 'react';
import {useEffect, useState, useRef} from 'react';
import * as stylex from '@stylexjs/stylex';
import {WebContainer} from '@webcontainer/api';
import {files} from './playground-utils/files';

async function wcSpawn(instance, ...args) {
console.log('Running:', args.join(' '));
const process = await instance.spawn(...args);
process.output.pipeTo(
new WritableStream({
write(data) {
console.log(data);
},
}),
);
const exitCode = await process.exit;
if (exitCode !== 0) {
console.log('Command Failed:', args.join(' '), 'with exit code', exitCode);
throw new Error('Command Failed', args.join(' '));
}

console.log('Command Successful:', args.join(' '));
return process;
}

async function makeWebcontainer() {
console.log('Booting WebContainer...');
const instance = await WebContainer.boot();
console.log('Boot successful!');

console.log('Mounting files...');
await instance.mount(files);
console.log('Mounted files!');

console.log('Installing dependencies...');
await wcSpawn(instance, 'npm', ['install']);
console.log('Installed dependencies!');

return instance;
}

export default function Playground() {
const instance = useRef(null);
const [output, setOutput] = useState('');

const build = async () => {
const containerInstance = instance.current;
if (!containerInstance) return;

await wcSpawn(containerInstance, 'npm', ['run', 'build']);
const output = await containerInstance.fs.readFile('output.js', 'utf-8');
setOutput(output);
};

useEffect(() => {
makeWebcontainer().then((i) => {
instance.current = i;
build();
});
() => {
instance.current.unmount();
};
}, []);

return (
<div {...stylex.props(styles.container)}>
<pre {...stylex.props(styles.textarea)}>
{files['input.js'].file.contents}
</pre>
<pre {...stylex.props(styles.textarea)}>{output}</pre>
</div>
);
}

const styles = stylex.create({
container: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: stylex.firstThatWorks('calc(100dvh - 60px)', 'calc(100vh - 60px)'),
borderBottomWidth: 2,
borderBottomStyle: 'solid',
borderBottomColor: 'var(--cyan)',
},
textarea: {
width: '50%',
height: '100%',
borderWidth: 0,
borderStyle: 'none',
},
});
98 changes: 98 additions & 0 deletions apps/docs/components/playground-utils/files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

export const files = {
'.babelrc.js': {
file: {
contents: `
const tsSyntaxPlugin = require('@babel/plugin-syntax-typescript');
const jsxSyntaxPlugin = require('@babel/plugin-syntax-jsx');
module.exports = {
plugins: [
tsSyntaxPlugin,
jsxSyntaxPlugin,
[
"@stylexjs/babel-plugin",
{
dev: true,
stylexSheetName: "<>",
genConditionalClasses: true,
unstable_moduleResolution: {
type: "commonJS",
rootDir: '/',
},
},
],
],
};
`,
},
},
'package.json': {
file: {
contents: `
{
"name": "stylex-playground",
"version": "1.0.0",
"description": "Playground using WebContainers",
"main": "index.js",
"scripts": {
"build": "babel ./input.js -o ./output.js"
},
"dependencies": {
"@stylexjs/stylex": "0.2.0-beta.27",
"@stylexjs/babel-plugin": "0.2.0-beta.27",
"@babel/cli": "latest",
"@babel/core": "latest",
"@babel/plugin-syntax-typescript": "latest",
"@babel/plugin-syntax-jsx": "latest"
}
}
`,
},
},
'input.js': {
file: {
contents: `
import * as React from 'react';
import * as stylex from "@stylexjs/stylex";
export default function Card({ onClick, children, theme, variant, em = false }) {
const props = stylex.props(theme, styles.base, em && styles.emphasise, variantStyles[variant]);
}
const styles = stylex.create({
base: {
appearance: "none",
borderStyle: "none",
backgroundColor: "blue",
color: "white",
borderRadius: 4,
paddingBlock: 4,
paddingInline: 8,
},
emphasise: {
transform: "scale(1.1)",
}
});
const variantStyles = stylex.create({
danger: {
backgroundColor: "red",
color: "white",
},
primary: {
fontWeight: "bold",
},
});
`,
},
},
};
1 change: 1 addition & 0 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@mdx-js/react": "^1.6.22",
"@orama/plugin-docusaurus": "^1.2.4",
"@stylexjs/stylex": "0.2.0-beta.27",
"@webcontainer/api": "^1.1.8",
"clsx": "^1.2.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand Down
30 changes: 3 additions & 27 deletions apps/docs/src/pages/playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,13 @@
*/

import * as React from 'react';
import * as stylex from '@stylexjs/stylex';
import Layout from '@theme/Layout';
import Playground from '../../components/Playground';

export default function Playground() {
export default function PlaygroundPage() {
return (
<Layout>
<div {...stylex.props(styles.container)}>
<iframe
{...stylex.props(styles.iframe)}
src="https://stackblitz.com/edit/stylex-next?embed=1&file=README.md"
/>
</div>
<Playground />
</Layout>
);
}

const styles = stylex.create({
container: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: stylex.firstThatWorks('calc(100dvh - 60px)', 'calc(100vh - 60px)'),
borderBottomWidth: 2,
borderBottomStyle: 'solid',
borderBottomColor: 'var(--cyan)',
},
iframe: {
width: '100%',
height: '100%',
borderWidth: 0,
borderStyle: 'none',
},
});
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 08789a7

Please sign in to comment.