// @ts-check
import { html } from 'dhtml'
import { createRoot, invalidate } from 'dhtml/client'
function transition(cb) {
if ('startViewTransition' in document) {
document.startViewTransition(cb)
} else {
cb()
}
}
function classes(...args) {
const classes = args.flatMap(a => (a ? a.split(' ') : []))
return node => {
node.classList.add(...classes)
return () => {
node.classList.remove(...classes)
}
}
}
const autofocus = node => node.focus()
const autoselect = node => node.setSelectionRange(0, node.value.length)
class TodoItem {
id = crypto.randomUUID()
completed = false
editing = false
constructor(app, title) {
this.app = app
this.title = title
}
render() {
return html`
{
transition(async () => {
for (const todo of this.todos) todo.completed = e.target.checked
await invalidate(this)
})
}}
/>
${this.todos.filter(todo => {
switch (this.filter) {
case 'Active':
return !todo.completed
case 'Completed':
return todo.completed
case 'All':
return true
}
})}
`
: null}
`
}
}
const app = new App()
globalThis.app = app
document.body.addEventListener('keypress', e => {
if (e.ctrlKey && e.key === 'i') invalidate(app)
})
app.todos.push(new TodoItem(app, 'hello'))
app.todos.push(new TodoItem(app, 'world'))
const rootEl = document.getElementById('root')
if (!rootEl) throw new Error('Root element not found')
createRoot(rootEl).render(app)