Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default tseslint.config(
".netlify/",
"public/",
"scripts/",
"src/playgrounds/",
],
},
{
Expand Down
1 change: 1 addition & 0 deletions osmium/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions osmium/src/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"));

Expand Down
52 changes: 52 additions & 0 deletions osmium/src/ui/playground.tsx
Original file line number Diff line number Diff line change
@@ -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<string, string>;
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 (
<figure class="my-6">
<iframe
src={src()}
title={props.title ?? "Solid playground"}
loading="lazy"
class="w-full rounded-lg border border-slate-300 dark:border-slate-700"
style={{ height: props.height ?? "560px" }}
/>
<figcaption class="mt-2 text-sm">
<a href={src()} target="_blank" rel="noopener">
Open in the Solid Playground
</a>
</figcaption>
</figure>
);
};
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

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

22 changes: 22 additions & 0 deletions src/playgrounds/line-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createSignal } from "solid-js";
import { render } from "@solidjs/web";

export function LineItem() {
const [quantity, setQuantity] = createSignal(1);
const price = 12;

return (
<div>
<button type="button" onClick={() => setQuantity(quantity() - 1)}>
−
</button>
<span>{quantity()}</span>
<button type="button" onClick={() => setQuantity(quantity() + 1)}>
+
</button>
<p>Subtotal: ${quantity() * price}</p>
</div>
);
}

render(() => <LineItem />, document.getElementById("app")!);
4 changes: 4 additions & 0 deletions src/routes/(2)concepts/(0)reactivity.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ version: "2.0"
description: "Signals, memos, and effects: how Solid tracks reads, why a component runs once, and how to tell when a value will update."
---

import lineItem from "~/playgrounds/line-item.tsx?raw";

In the [Quick start](/getting-started/quick-start) you saw two versions of the same counter.
One read `count()` inside the JSX and updated on every click.
The other read `count()` in the component body, and the button froze at zero while the console warned that the read "will not update".
Expand Down Expand Up @@ -344,6 +346,8 @@ Show the shipping cost, the total, and a line that reads either "Free shipping"

Before you look at the solution, decide for each value whether it should be a plain function or a memo, and where each read has to happen.

<Playground code={lineItem} title="LineItem starter" />

:::solution[A shipping estimate]

```tsx
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
},
"types": ["vite/client"]
},
"exclude": ["node_modules"]
"exclude": ["node_modules", "src/playgrounds"]
}
Loading