Skip to content

Instantly share code, notes, and snippets.

@developit
Last active January 28, 2024 20:22
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save developit/3631edd9033df8df5975786b19f16bd8 to your computer and use it in GitHub Desktop.
Save developit/3631edd9033df8df5975786b19f16bd8 to your computer and use it in GitHub Desktop.

Preact, Without Build Tools

This is a demonstration of using Preact without any build tooling. The library is linked from the esm.sh CDN, however a standalone JS file exporting HTM + Preact + Hooks can also be downloaded here.

<!DOCTYPE html>
<html>
<head>
<title>Preact Without Tooling</title>
<style>
ul { list-style: none; padding: 0; }
label { padding: 5px; display: flex; gap: 5px; }
</style>
</head>
<body>
<script type="module" src="./main.js"></script>
</body>
</html>
import { render } from 'https://esm.sh/preact@10.7.2';
import { useState, useCallback } from 'https://esm.sh/preact@10.7.2/hooks';
import { html } from 'https://esm.sh/htm@3.0.4/preact';
const INITIAL_TODOS = [
{ text: 'add HTM imports', done: true },
{ text: 'remove bundler', done: true },
{ text: 'write code', done: false }
];
function App() {
const [todos, setTodos] = useState(INITIAL_TODOS);
console.log(todos);
const add = useCallback(e => {
const text = e.target.todo.value;
setTodos(todos => todos.concat({ text, done: false }));
}, []);
const updateTodo = useCallback(todo => {
// we update the todo in-place, so just invalidate the list to re-render:
setTodos(todos => todos.slice());
}, []);
return html`
<div class="app">
<form action="javascript:" onSubmit=${add}>
<input name="todo" placeholder="Add Todo [enter]" />
</form>
<ul>
${todos.map(todo => html`
<${Todo} todo=${todo} onChange=${updateTodo} />
`)}
</ul>
</div>
`;
}
function Todo({ todo, onChange }) {
const toggle = useCallback(e => {
todo.done = !todo.done;
onChange();
}, []);
return html`
<li>
<label>
<input type="checkbox" checked=${todo.done} onClick=${toggle} />
${todo.text}
</label>
</li>
`;
}
render(html`<${App} />`, document.body);
@fyodorio
Copy link

Looks neat 👍 what would be the best way to use css for components with such approach?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment