diff --git a/packages/morph/src/dom.js b/packages/morph/src/dom.js index a8fef1f99..77fd6bd0f 100644 --- a/packages/morph/src/dom.js +++ b/packages/morph/src/dom.js @@ -14,12 +14,18 @@ export let dom = { replace(children, old, replacement) { let index = children.indexOf(old) + let replacementIndex = children.indexOf(old) + if (index === -1) throw 'Cant find element in children' old.replaceWith(replacement) children[index] = replacement + if (replacementIndex) { + children.splice(replacementIndex, 1) + } + return children }, before(children, reference, subject) { diff --git a/packages/morph/src/morph.js b/packages/morph/src/morph.js index 23d5ea511..6ab20b504 100644 --- a/packages/morph/src/morph.js +++ b/packages/morph/src/morph.js @@ -132,7 +132,7 @@ export function morph(from, toHtml, options) { function patchChildren(fromChildren, toChildren, appendFn) { // I think I can get rid of this for now: - let fromKeyDomNodeMap = {} // keyToMap(fromChildren) + let fromKeyDomNodeMap = keyToMap(fromChildren) let fromKeyHoldovers = {} let currentTo = dom.first(toChildren) diff --git a/tests/cypress/integration/plugins/morph.spec.js b/tests/cypress/integration/plugins/morph.spec.js index f423c9688..0ef4c25f4 100644 --- a/tests/cypress/integration/plugins/morph.spec.js +++ b/tests/cypress/integration/plugins/morph.spec.js @@ -247,6 +247,35 @@ test('can morph using a custom key function', }, ) +test('can morph using keys with existing key to be moved up', + [html` + + `], + ({ get }, reload, window, document) => { + let toHtml = html` + + ` + + get('li:nth-of-type(1) input').type('foo') + get('li:nth-of-type(3) input').type('baz') + + get('ul').then(([el]) => window.Alpine.morph(el, toHtml)) + + get('li').should(haveLength(2)) + get('li:nth-of-type(1)').should(haveText('foo')) + get('li:nth-of-type(2)').should(haveText('baz')) + get('li:nth-of-type(1) input').should(haveValue('foo')) + get('li:nth-of-type(2) input').should(haveValue('baz')) + }, +) + test('can morph text nodes', [html`

Foo
Bar

`], ({ get }, reload, window, document) => {