From fc693a995f5f51e451b1234cda266da67b17d660 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Mon, 10 Mar 2025 13:18:50 +0100 Subject: [PATCH] fix render nested fragment --- .changeset/early-needles-rush.md | 6 ++++++ packages/actions/src/morph.ts | 9 +++++++-- packages/react/src/actions-react-plugin.test.tsx | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 .changeset/early-needles-rush.md diff --git a/.changeset/early-needles-rush.md b/.changeset/early-needles-rush.md new file mode 100644 index 0000000..4d62866 --- /dev/null +++ b/.changeset/early-needles-rush.md @@ -0,0 +1,6 @@ +--- +'@coldwired/actions': patch +'@coldwired/react': patch +--- + +fix nested fragment render bug diff --git a/packages/actions/src/morph.ts b/packages/actions/src/morph.ts index 6c4f355..4970d9f 100644 --- a/packages/actions/src/morph.ts +++ b/packages/actions/src/morph.ts @@ -91,6 +91,7 @@ function morphToDocumentFragment( function morphToElement(fromElement: Element, toElement: Element, options?: MorphOptions): void { const forceAttribute = options?.forceAttribute; + const added = new WeakSet(); morphdom(fromElement, toElement, { childrenOnly: options?.childrenOnly, @@ -162,9 +163,13 @@ function morphToElement(fromElement: Element, toElement: Element, options?: Morp return true; }, onNodeAdded(node) { - if (isElement(node)) { - options?.plugins?.forEach((plugin) => plugin.onCreateElement?.(node)); + if (isElement(node) && node.parentElement) { + if (!added.has(node.parentElement)) { + options?.plugins?.forEach((plugin) => plugin.onCreateElement?.(node)); + } + added.add(node); } + return node; }, }); diff --git a/packages/react/src/actions-react-plugin.test.tsx b/packages/react/src/actions-react-plugin.test.tsx index 2592b5b..cd3de48 100644 --- a/packages/react/src/actions-react-plugin.test.tsx +++ b/packages/react/src/actions-react-plugin.test.tsx @@ -131,6 +131,20 @@ describe('@coldwired/react', () => { ); }); + actions.update({ + targets: '#main', + fragment: `<${DEFAULT_TAG_NAME} id="frag-1"><${REACT_COMPONENT_TAG} ${NAME_ATTRIBUTE}="Counter"><${DEFAULT_TAG_NAME} id="frag-2">Test
<${DEFAULT_TAG_NAME} id="frag-3">Encore un
`, + }); + await actions.ready(); + expect(root.getCache().size).toEqual(3); + await waitFor(() => { + expect(document.body.innerHTML).toEqual( + layout( + `<${DEFAULT_TAG_NAME} id="frag-1">

Count: 2

<${DEFAULT_TAG_NAME} id="frag-2">Test
<${DEFAULT_TAG_NAME} id="frag-3">Encore un
`, + ), + ); + }); + actions.update({ targets: '#main', fragment: `<${DEFAULT_TAG_NAME} id="frag-1"><${REACT_COMPONENT_TAG} ${NAME_ATTRIBUTE}="Counter"><${DEFAULT_TAG_NAME} id="frag-2">Test 23`,