Skip to content

Instantly share code, notes, and snippets.

@nexpr
Created August 6, 2022 17:04
Show Gist options
  • Save nexpr/3891df4d8d4de274cfd1dbccf8ced241 to your computer and use it in GitHub Desktop.
Save nexpr/3891df4d8d4de274cfd1dbccf8ced241 to your computer and use it in GitHub Desktop.
lit-html でルートごとにイベントを伝える
<!DOCTYPE html>
<meta charset="utf-8" />
<script type="module">
import { html, render } from "https://cdn.skypack.dev/lit-html"
const lit = (root, template, init, actions) => {
let state = init
const update = async (fn, ...args) => {
state = await fn(state, ...args)
rerender()
}
const action = (fn, ...values) => event => {
if (typeof fn === "function") {
update(fn, values, event)
} else if (typeof fn === "string") {
action[fn](...values)(event)
} else {
action.action(fn)(event)
}
}
if (actions) {
const methods = actions((fn) => (...values) => event => {
update(fn, values, event)
})
Object.assign(action, methods)
}
const rerender = () => render(template(state, action), root)
return { render: rerender, action }
}
{ // example1
lit(
root1,
(state, action) => html`
<div>
<h1>root1</h1>
<p>count: ${state.num}</p>
<button @click=${action.up(1)}>up 1</button>
<button @click=${action("up", 2)}>up 2</button>
</div>
`,
{ num: 0 },
(action) => {
const up = action((state, values, event) => {
state.num += values[0]
return state
})
return { up }
}
).render()
}
{ // example2
const up = (state, values, event) => {
state += values[0]
return state
}
const tpl = (state, action) => {
return html`
<h1>root2</h1>
<button @click=${action(up, 1)}>${state}</button>
`
}
const app = lit(root2, tpl, 100)
setInterval(() => {
const reset = (state) => 100
app.action(reset)()
}, 5000)
app.render()
}
{ // example3
const tpl = (state, action, ref) => html`
<div>
<button @click=${action({ type: "up", value: 1, ref })}>+</button>
<span>${state}</span>
<button @click=${action({ type: "down", value: 1, ref })}>-</button>
</div>
`
lit(
root3,
(state, action) => html`
<div>
<h1>root3</h1>
${state.map((s, i) => tpl(s, action, i))}
</div>
`,
[0, 1, 2],
(action) => {
return {
action: action((state, [{ type, value, ref }], event) => {
if (type === "up") {
state[ref] += value
} else {
state[ref] -= value
}
return state
})
}
}
).render()
}
</script>
<div id="root1"></div>
<div id="root2"></div>
<div id="root3"></div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment