hyperHTML だと順番が意味がある
select で option が hyperHTML の機能で生成される場合に value 属性で選択中の値を指定ができないように hyperHTML の ${} は順番に実行される
JavaScript で順に処理されるものなので書く順番で結果が変わる場合もある

bind(document.body)`
<e-lem mode=${"foo"} values=${{x: 1}}>${"bar"}</e-lem>
`

これは

elem.mode = "foo"
elem.values = {x: 1}
elem.textContent= "bar"

と同じこと

HTML みたいな定義型のものに見えるから 順番変えても問題なさそうに見えるけど mode と values の順番が変わると実行順も変わる
values が代入時に mode の値を使って shadowDOM 内を書き換えるのなら 順番によって結果も変わる

コンポーネント側でどんな順番でも同じ結果になるようにしてれば対処は可能
values を内部的に保存しておいて mode 変えると再度 values を設定して shadowDOM 内の更新をするとか

無駄な処理が増えて mode と values 両方変えると更新も 2 回必要になる
けど hyperHTML での定義順に依存したくないならそうするしかない
e-lem コンポーネント自体も hyperHTML で作っていれば setter は常に render して再描画する作りになってることが多いと思うのでそこまで気持ち的に無駄なことしてる感はなくなる
hyperHTML でカスタムイベントをリッスンする
on から始まると以降をイベント名としてリスナ扱いになる
「-」 や 「_」 があっても気にせず on*** にすればいい

customElements.define("x-elem", class extends HTMLElement {
constructor(){
super()
this.attachShadow({mode: "open"})
this.render()
}

render(){
bind(this.shadowRoot)`
<div
onxxx=${eve => console.log("event xxx")}
onx-x=${eve => console.log("event x-x")}
onx_x=${eve => console.log("event x_x")}
>
<button onclick=${
eve => {
eve.target.dispatchEvent(new Event("xxx", {bubbles: true}))
eve.target.dispatchEvent(new Event("x-x", {bubbles: true}))
eve.target.dispatchEvent(new Event("x_x", {bubbles: true}))
}
}>event</button>
</div>
`
}
})

on が最初の区切りまでとくっついて見づらいので 区切り文字は使わず全部小文字にしたほうがいいのかも

注意するところは大文字小文字を同一視したときに同じ名前は別々に設定できないこと

<div
onxxx=${eve => console.log("event xxx")}
onxXx=${eve => console.log("event xXx")}
></div>

これは無効
hyperHTML 内部でエラーが起きる

原因は

document.body.innerHTML = `<div a="1" A="2" b="3"></div>`
document.body.innerHTML
// "<div a="1" b="3"></div>"

HTML 自体が大文字小文字を区別しないで 同じ属性をふたつ作れないから

後のほうは消される
消された結果 属性と埋め込み値の数が合わなくてエラーになる