Skip to content

Commit d8954d7

Browse files
trueadmRich-Harris
andauthored
fix: ensure custom elements do not sync flush on mount (#12787)
* fix: ensure Svelte4Components do not sync flush * fix: ensure Svelte4Components do not sync flush * lint * feedback * simplify test, remove redundant comments * prettier * fix test --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 057316c commit d8954d7

File tree

5 files changed

+37
-1
lines changed

5 files changed

+37
-1
lines changed

.changeset/cool-turtles-travel.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ensure custom elements do not sync flush on mount

packages/svelte/src/legacy/legacy-client.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,10 @@ class Svelte4Component {
110110
recover: options.recover
111111
});
112112

113-
flush_sync();
113+
// We don't flush_sync for custom element wrappers
114+
if (!options?.props?.$$host) {
115+
flush_sync();
116+
}
114117

115118
this.#events = props.$$events;
116119

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { test } from '../../assert';
2+
const tick = () => Promise.resolve();
3+
4+
export default test({
5+
async test({ assert, target }) {
6+
let changed = false;
7+
8+
target.innerHTML = '<child-element></child-element>';
9+
10+
await tick(); // wait for element to upgrade
11+
12+
target.addEventListener('change', () => {
13+
changed = true;
14+
});
15+
16+
await tick(); // wait for effect
17+
18+
assert.equal(changed, true);
19+
}
20+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<svelte:options customElement="child-element" />
2+
3+
<script>
4+
$effect(() => {
5+
$host().dispatchEvent(new CustomEvent('change', { bubbles: true }));
6+
});
7+
</script>

packages/svelte/tests/runtime-browser/custom-elements-samples/escaped-css/_config.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default test({
55
async test({ assert, target }) {
66
target.innerHTML = '<custom-element></custom-element>';
77
await tick();
8+
await tick();
89
/** @type {any} */
910
const ce = target.querySelector('custom-element');
1011
const icon = ce.shadowRoot.querySelector('.icon');

0 commit comments

Comments
 (0)