Skip to content

Commit ab743bc

Browse files
authored
🐛 Cleans teleported clone (#4328)
* 🧪 Adds failing test for teleport cleanup * 🐛 Cleans up Teleport clones
1 parent 1539ee9 commit ab743bc

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

packages/alpinejs/src/directives/x-teleport.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { skipDuringClone } from "../clone"
22
import { directive } from "../directives"
3-
import { initTree } from "../lifecycle"
3+
import { initTree, destroyTree } from "../lifecycle"
44
import { mutateDom } from "../mutation"
55
import { addScopeToNode } from "../scope"
66
import { warn } from "../utils/warn"
@@ -64,7 +64,12 @@ directive('teleport', (el, { modifiers, expression }, { cleanup }) => {
6464
})
6565
}
6666

67-
cleanup(() => clone.remove())
67+
cleanup(() =>
68+
mutateDom(() => {
69+
clone.remove()
70+
destroyTree(clone)
71+
})
72+
)
6873
})
6974

7075
let teleportContainerDuringClone = document.createElement('div')

tests/cypress/integration/directives/x-teleport.spec.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,37 @@ test('removing teleport source removes teleported target',
122122
},
123123
)
124124

125+
test(
126+
'immediately cleans up the clone when the original template is removed',
127+
[
128+
html`
129+
<div x-data="{ show: true, shown: 'original' }">
130+
<span x-text="shown"></span>
131+
<template x-if="show">
132+
<div>
133+
<template x-teleport="#target">
134+
<button x-data="{
135+
init() { this.shown = 'cloned' },
136+
destroy() { this.shown = 'destroyed' }
137+
}" @click="show = false">remove</button>
138+
</template>
139+
</div>
140+
</template>
141+
<section id="target"></section>
142+
</div>
143+
`,
144+
],
145+
({ get }) => {
146+
get('section').should(haveText('remove'));
147+
get("button").should(exist());
148+
get('span').should(haveText('cloned'));
149+
get('button').click();
150+
get('section').should(haveText(''));
151+
get('button').should(notExist());
152+
get('span').should(haveText('destroyed'));
153+
}
154+
);
155+
125156
test('$refs inside teleport can be accessed outside',
126157
[html`
127158
<div x-data="{ count: 1 }" id="a">

0 commit comments

Comments
 (0)