@@ -429,46 +429,47 @@ class VDom extends Base {
429429 if ( vnode && vdom ) {
430430 // Sanity check: If the node types (tags) mismatch, we are likely looking at
431431 // a race condition where the VNode tree structure hasn't caught up with the VDOM yet.
432- // In this case, we must abort synchronization to prevent "Chimera" nodes (e.g. UL getting LI ID).
433- if ( vnode . nodeName && vdom . tag && vnode . nodeName . toLowerCase ( ) !== vdom . tag . toLowerCase ( ) ) {
434- return
435- }
432+ // In this case, we do not sync the node props, but we do want to check the children.
433+ // This is important for e.g. tag name changes (div => ul), where we want to keep the children stable.
434+ const tagMismatch = vnode . nodeName && vdom . tag && vnode . nodeName . toLowerCase ( ) !== vdom . tag . toLowerCase ( ) ;
436435
437436 vdom = VDom . getVdom ( vdom ) ;
438437
439438 let childNodes = vdom . cn ,
440439 cn , i , len ;
441440
442- if ( force ) {
443- if ( vnode . id && vdom . id !== vnode . id ) {
444- vdom . id = vnode . id
445- }
446- } else {
447- // We only want to add an ID if the vdom node does not already have one.
448- // This preserves developer-provided IDs while allowing the framework
449- // to assign IDs to nodes that need them for reconciliation.
450- // Also think of adding and removing nodes in parallel.
451- if ( vnode . id && ( ! vdom . id || vdom . id . startsWith ( 'neo-vnode-' ) ) ) {
452- vdom . id = vnode . id
441+ if ( ! tagMismatch ) {
442+ if ( force ) {
443+ if ( vnode . id && vdom . id !== vnode . id ) {
444+ vdom . id = vnode . id
445+ }
446+ } else {
447+ // We only want to add an ID if the vdom node does not already have one.
448+ // This preserves developer-provided IDs while allowing the framework
449+ // to assign IDs to nodes that need them for reconciliation.
450+ // Also think of adding and removing nodes in parallel.
451+ if ( vnode . id && ( ! vdom . id || vdom . id . startsWith ( 'neo-vnode-' ) ) ) {
452+ vdom . id = vnode . id
453+ }
453454 }
454- }
455455
456- // 1. Rehydration (vnode -> vdom)
457- // Used by Functional Components (vdom is new)
458- if ( Neo . isNumber ( vnode . scrollTop ) && ! Neo . isNumber ( vdom . scrollTop ) ) {
459- vdom . scrollTop = vnode . scrollTop
460- }
461- if ( Neo . isNumber ( vnode . scrollLeft ) && ! Neo . isNumber ( vdom . scrollLeft ) ) {
462- vdom . scrollLeft = vnode . scrollLeft
463- }
456+ // 1. Rehydration (vnode -> vdom)
457+ // Used by Functional Components (vdom is new)
458+ if ( Neo . isNumber ( vnode . scrollTop ) && ! Neo . isNumber ( vdom . scrollTop ) ) {
459+ vdom . scrollTop = vnode . scrollTop
460+ }
461+ if ( Neo . isNumber ( vnode . scrollLeft ) && ! Neo . isNumber ( vdom . scrollLeft ) ) {
462+ vdom . scrollLeft = vnode . scrollLeft
463+ }
464464
465- // 2. Preservation (vdom -> vnode)
466- // Used by Classic Components (vdom is source of truth via capture)
467- if ( Neo . isNumber ( vdom . scrollTop ) ) {
468- vnode . scrollTop = vdom . scrollTop
469- }
470- if ( Neo . isNumber ( vdom . scrollLeft ) ) {
471- vnode . scrollLeft = vdom . scrollLeft
465+ // 2. Preservation (vdom -> vnode)
466+ // Used by Classic Components (vdom is source of truth via capture)
467+ if ( Neo . isNumber ( vdom . scrollTop ) ) {
468+ vnode . scrollTop = vdom . scrollTop
469+ }
470+ if ( Neo . isNumber ( vdom . scrollLeft ) ) {
471+ vnode . scrollLeft = vdom . scrollLeft
472+ }
472473 }
473474
474475 if ( childNodes ) {
0 commit comments