Skip to content

Commit 1a94b58

Browse files
committed
feat(website): add high-performance JSX playground with 10k todos and runtime reactivity
1 parent f37ba69 commit 1a94b58

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

website/public/playground.html

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Playground</title>
6+
<style>
7+
body {
8+
font-family: sans-serif;
9+
margin: 20px;
10+
}
11+
.todo {
12+
cursor: pointer;
13+
transition: background 0.1s ease-in-out;
14+
}
15+
.todo:hover {
16+
background: #f0f0f0;
17+
}
18+
#controls {
19+
display: flex;
20+
gap: 8px;
21+
margin-bottom: 16px;
22+
}
23+
</style>
24+
</head>
25+
<body>
26+
<div id="controls">
27+
<input id="input" placeholder="Add todo..." />
28+
<button id="add">Add</button>
29+
<button id="filter-all">All</button>
30+
<button id="filter-done">Done</button>
31+
<button id="filter-active">Active</button>
32+
</div>
33+
<div id="app"></div>
34+
<script type="module" src="/src/index.ts"></script>
35+
</body>
36+
</html>

website/public/src/index.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Direct JSX file, no framework — runs with your runtime
2+
import { signal, effect } from "../runtime/signals.js"
3+
import { insert, createElement } from "../runtime/dom.js"
4+
5+
// Core signals
6+
const todos = signal([])
7+
const filter = signal("all")
8+
const input = signal("")
9+
10+
// Add 10,000 todos initially
11+
for (let i = 0; i < 10000; i++) {
12+
todos.value.push({ id: i, text: `Task #${i}`, done: false })
13+
}
14+
15+
// Reactive rendering
16+
effect(() => {
17+
const root = document.getElementById("app")
18+
root.innerHTML = ""
19+
20+
const visible = todos.value.filter(todo => {
21+
if (filter.value === "done") return todo.done
22+
if (filter.value === "active") return !todo.done
23+
return true
24+
})
25+
26+
for (const todo of visible) {
27+
const div = createElement("div")
28+
div.className = "todo"
29+
div.style.padding = "2px"
30+
div.style.borderBottom = "1px solid #eee"
31+
div.onclick = () => {
32+
todo.done = !todo.done
33+
todos.value = [...todos.value] // trigger update
34+
}
35+
div.textContent = `${todo.done ? "✅" : "⬜️"} ${todo.text}`
36+
insert(root, div)
37+
}
38+
})
39+
40+
// Input UI
41+
window.onload = () => {
42+
const inputBox = document.getElementById("input") as HTMLInputElement
43+
const filterAll = document.getElementById("filter-all")
44+
const filterDone = document.getElementById("filter-done")
45+
const filterActive = document.getElementById("filter-active")
46+
const addButton = document.getElementById("add")
47+
48+
inputBox.oninput = (e) => input.value = (e.target as HTMLInputElement).value
49+
addButton.onclick = () => {
50+
if (!input.value.trim()) return
51+
todos.value = [
52+
...todos.value,
53+
{ id: todos.value.length, text: input.value, done: false }
54+
]
55+
input.value = ""
56+
inputBox.value = ""
57+
}
58+
59+
filterAll.onclick = () => filter.value = "all"
60+
filterDone.onclick = () => filter.value = "done"
61+
filterActive.onclick = () => filter.value = "active"
62+
}

website/public/src/vite.config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { defineConfig } from "vite"
2+
3+
export default defineConfig({
4+
root: ".",
5+
publicDir: "public",
6+
build: {
7+
outDir: "dist",
8+
rollupOptions: {
9+
input: "public/playground.html"
10+
}
11+
}
12+
})

0 commit comments

Comments
 (0)