Tiny web framework
- Tiny (only ~80 sloc)
- Component
- Context
- SSR and (partial) hydration
import { createHtml, createRef, renderToNode, rawHtml } from "srender";
const root = document.getElementById("root");
const TodoItem = (html, props, context) => html`
<li>
${props.item}_${context.name}
<button type="button" name="deleteButton">X</button>
</li>
`;
function TodoMVC(html, { items = [] }, context) {
const { createRef } = context;
const formRef = createRef();
const inputRef = createRef();
const listRef = createRef();
html`
<h1>Todo MVC</h1>
${rawHtml("<h2>srender example</h2>")}
<form id="${formRef}">
<input id="${inputRef}" />
<button>Add</button>
</form>
<ul id="${listRef}">
${() => {
const html = createHtml({
...context,
name: "second",
});
html(TodoItem, { item: "test" });
}}
${() => items.map(item => html(TodoItem, { item }))}
</ul>
`;
// component did mount
return () => {
const $form = formRef.get();
const $input = inputRef.get();
const $list = listRef.get();
$form.onsubmit = e => {
e.preventDefault();
renderToNode(
() => {
const html = createHtml({
...context,
name: "third",
});
html(TodoItem, { item: $input.value });
},
node => $list.appendChild(node),
);
$form.reset();
};
$list.onclick = ({ target }) => {
if (target.name === "deleteButton") {
target.closest("li").remove();
}
};
requestAnimationFrame(() => $input.focus());
};
}
renderToNode(
() => {
const context = {
createRef: createRef.bind({}), // initialize createRef
name: "root",
};
const html = createHtml(context);
html(TodoMVC, { items: ["foo", "bar"] });
},
node => root.appendChild(node)
);
const http = require("http");
const { render, createHtml } = require("srender");
const hostname = "127.0.0.1";
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/html; charset=utf-8");
render(
() => {
const html = createHtml();
html`
<!DOCTYPE html>
<html>
<head>
<title>srender demo</title>
</head>
<body>
Hello!
</body>
</html>
`;
},
{
onData: (data) => res.write(data),
}
);
res.end();
});
server.listen(port, hostname, () => {
console.log(`Server running at https://${hostname}:${port}/`);
});
Install lit-html IDE plugins to have syntax highlight.
MIT