Skip to content

Commit

Permalink
Merge pull request #7208 from QwikDev/v2-fix-moving-found-vnode
Browse files Browse the repository at this point in the history
fix: moving existing virtual node during vnode diffing
  • Loading branch information
wmertens authored Dec 31, 2024
2 parents c029c32 + 08cb7c4 commit 0bc9555
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/funny-apricots-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@qwik.dev/core': patch
---

fix: moving existing virtual node during vnode diffing
2 changes: 1 addition & 1 deletion packages/qwik/src/core/client/vnode-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ export const vnode_diff = (
vnode_insertBefore(
journal,
vParent as VirtualVNode,
(vNewNode = vnode_newVirtual()),
vNewNode,
vCurrent && getInsertBefore()
);
return;
Expand Down
176 changes: 176 additions & 0 deletions packages/qwik/src/core/tests/component.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1949,5 +1949,181 @@ describe.each([
</Component>
);
});

it('#7203 - should correctly move found vnode', async () => {
const Cmp = component$(() => {
const type = useSignal<'A' | 'B' | 'C'>('B');

return (
<>
<div>
<button
id="A"
type="button"
onClick$={$(() => {
type.value = 'A';
})}
>
Select A
</button>

<button
id="B"
type="button"
onClick$={$(() => {
type.value = 'B';
})}
>
Select B
</button>

<button
id="C"
type="button"
onClick$={$(() => {
type.value = 'C';
})}
>
Select C
</button>
</div>

{type.value === 'A' ? (
<>
<p>A</p>
</>
) : undefined}

{type.value === 'B' ? (
<>
<p>B</p>
</>
) : undefined}

{type.value === 'C' ? (
<>
<p>C</p>
</>
) : undefined}

{type.value !== 'C' ? (
<>
<p>A or B</p>
</>
) : undefined}
</>
);
});

const { vNode, document } = await render(<Cmp />, { debug });

expect(vNode).toMatchVDOM(
<Component ssr-required>
<Fragment ssr-required>
<div>
<button id="A" type="button">
Select A
</button>
<button id="B" type="button">
Select B
</button>
<button id="C" type="button">
Select C
</button>
</div>
{''}
<Fragment ssr-required>
<p>B</p>
</Fragment>
{''}
<Fragment ssr-required>
<p>A or B</p>
</Fragment>
</Fragment>
</Component>
);

await trigger(document.body, '#A', 'click');

expect(vNode).toMatchVDOM(
<Component ssr-required>
<Fragment ssr-required>
<div>
<button id="A" type="button">
Select A
</button>
<button id="B" type="button">
Select B
</button>
<button id="C" type="button">
Select C
</button>
</div>
<Fragment ssr-required>
<p>A</p>
</Fragment>
{''}
{''}
<Fragment ssr-required>
<p>A or B</p>
</Fragment>
</Fragment>
</Component>
);

await trigger(document.body, '#C', 'click');

expect(vNode).toMatchVDOM(
<Component ssr-required>
<Fragment ssr-required>
<div>
<button id="A" type="button">
Select A
</button>
<button id="B" type="button">
Select B
</button>
<button id="C" type="button">
Select C
</button>
</div>
{''}
{''}
<Fragment ssr-required>
<p>C</p>
</Fragment>
{''}
</Fragment>
</Component>
);

await trigger(document.body, '#B', 'click');

expect(vNode).toMatchVDOM(
<Component ssr-required>
<Fragment ssr-required>
<div>
<button id="A" type="button">
Select A
</button>
<button id="B" type="button">
Select B
</button>
<button id="C" type="button">
Select C
</button>
</div>
{''}
<Fragment ssr-required>
<p>B</p>
</Fragment>
{''}
<Fragment ssr-required>
<p>A or B</p>
</Fragment>
</Fragment>
</Component>
);
});
});
});

0 comments on commit 0bc9555

Please sign in to comment.