diff --git a/eslint.config.ts b/eslint.config.ts index 2a56d00b7..41c0f8354 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -18,6 +18,7 @@ export default tseslint.config( ".netlify/", "public/", "scripts/", + "src/playgrounds/", ], }, { diff --git a/osmium/package.json b/osmium/package.json index d4000e5db..e8614da38 100644 --- a/osmium/package.json +++ b/osmium/package.json @@ -28,6 +28,7 @@ }, "license": "MIT", "dependencies": { + "@amoutonbrady/lz-string": "0.2.0", "@fontsource-variable/geist": "^5.3.0", "@fontsource-variable/geist-mono": "^5.3.0", "@kobalte/core": "^0.13.12", diff --git a/osmium/src/mdx-components.tsx b/osmium/src/mdx-components.tsx index 94c03cace..2e374f460 100644 --- a/osmium/src/mdx-components.tsx +++ b/osmium/src/mdx-components.tsx @@ -26,6 +26,7 @@ export { Callout } from "./ui/callout"; export { DeepDive } from "./ui/deep-dive"; export { QuickLinks } from "./ui/quick-links"; export { ImageLink } from "./ui/image-link"; +export { Playground } from "./ui/playground"; const EraserLinkImpl = clientOnly(() => import("./ui/eraser-link")); diff --git a/osmium/src/ui/playground.tsx b/osmium/src/ui/playground.tsx new file mode 100644 index 000000000..439d44272 --- /dev/null +++ b/osmium/src/ui/playground.tsx @@ -0,0 +1,52 @@ +import { compressToURL } from "@amoutonbrady/lz-string"; +import { createMemo } from "solid-js"; + +const PLAYGROUND_URL = + import.meta.env.VITE_PLAYGROUND_URL ?? "https://playground.solidjs.com/"; +const DEFAULT_SOLID_VERSION = "2.0.0-rc.18"; + +export type PlaygroundProps = { + code?: string; + files?: Record; + solidVersion?: string; + title?: string; + height?: string; +}; + +export const Playground = (props: PlaygroundProps) => { + const src = createMemo(() => { + const files = props.files ?? { "main.tsx": props.code ?? "" }; + const version = props.solidVersion ?? DEFAULT_SOLID_VERSION; + const tabs = Object.entries(files).map(([name, source]) => ({ + name, + source, + })); + // The playground runs the Solid version that import_map.json pins for solid-js. + tabs.push({ + name: "import_map.json", + source: JSON.stringify( + { imports: { "solid-js": `https://esm.sh/solid-js@${version}` } }, + null, + 2 + ), + }); + return `${PLAYGROUND_URL}#${compressToURL(JSON.stringify(tabs))}`; + }); + + return ( +
+