fix multiselect combobox

This commit is contained in:
2026-07-13 15:21:42 -04:00
parent d52151cc1a
commit 5230bd6702
11 changed files with 664 additions and 58 deletions

View File

@@ -163,7 +163,7 @@ func createDOM(n *vdom.VNode, ns string) js.Value {
el.Call("setAttribute", k, v)
}
for k, v := range n.Props {
el.Set(k, v)
setProp(el, k, v)
}
for name, h := range n.Events {
addListener(n, name, h)
@@ -316,12 +316,33 @@ func updateAttrs(o, x *vdom.VNode) {
func updateProps(o, x *vdom.VNode) {
dom := rt(x).dom
for k, v := range x.Props {
if o.Props[k] != v && dom.Get(k).String() != v {
dom.Set(k, v)
if o.Props[k] != v && !propEquals(dom, k, v) {
setProp(dom, k, v)
}
}
}
// setProp writes a live DOM property. Props travel as strings, but the property they
// land on may be a boolean — and JS reads the string "false" as TRUE, so writing
// el.checked = "false" ticks the box. Boolean props are converted before the write.
func setProp(el js.Value, k, v string) {
if vdom.IsBoolProp(k) {
el.Set(k, v == "true")
return
}
el.Set(k, v)
}
// propEquals compares against what the DOM currently holds, in the property's own
// type. It is what lets a re-render skip touching an <input> the user is typing in.
func propEquals(el js.Value, k, v string) bool {
cur := el.Get(k)
if vdom.IsBoolProp(k) {
return cur.Truthy() == (v == "true")
}
return cur.String() == v
}
func updateEvents(o, x *vdom.VNode) {
r := rt(x) // same nodeRT as o (adopted above)
for name, fn := range r.jsFuncs {
@@ -441,7 +462,7 @@ func hydrateNode(dom js.Value, n *vdom.VNode) {
}
}
for k, v := range n.Props {
dom.Set(k, v)
setProp(dom, k, v)
}
if n.HTML != "" {
return // trust server-rendered HTML