Skip to content

Commit ba116a1

Browse files
authored
fix: propagate custom element component prop changes (#12774)
* fix: propagate custom element component prop changes * add test
1 parent a0bbf2a commit ba116a1

File tree

4 files changed

+62
-2
lines changed

4 files changed

+62
-2
lines changed

.changeset/poor-mugs-pay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: propagate custom element component prop changes

packages/svelte/src/internal/client/dom/elements/custom-element.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createClassComponent } from '../../../../legacy/legacy-client.js';
22
import { destroy_effect, render_effect } from '../../reactivity/effects.js';
33
import { append } from '../template.js';
4-
import { define_property, object_keys } from '../../../shared/utils.js';
4+
import { define_property, get_descriptor, object_keys } from '../../../shared/utils.js';
55

66
/**
77
* @typedef {Object} CustomElementPropDefinition
@@ -305,7 +305,18 @@ export function create_custom_element(
305305
set(value) {
306306
value = get_custom_element_value(prop, value, props_definition);
307307
this.$$d[prop] = value;
308-
this.$$c?.$set({ [prop]: value });
308+
var component = this.$$c;
309+
310+
if (component) {
311+
// // If the instance has an accessor, use that instead
312+
var setter = get_descriptor(component, prop)?.get;
313+
314+
if (setter) {
315+
component[prop] = value;
316+
} else {
317+
component.$set({ [prop]: value });
318+
}
319+
}
309320
}
310321
});
311322
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../assert';
3+
const tick = () => Promise.resolve();
4+
5+
export default test({
6+
async test({ assert, target }) {
7+
target.innerHTML = '<custom-element></custom-element>';
8+
await tick();
9+
await tick();
10+
11+
/** @type {any} */
12+
const el = target.querySelector('custom-element');
13+
const button = el.shadowRoot.querySelector('button');
14+
15+
assert.equal(button.textContent, '0');
16+
assert.equal(el.count, 0);
17+
18+
button.click();
19+
20+
flushSync();
21+
22+
assert.equal(button.textContent, '1');
23+
assert.equal(el.count, 1);
24+
25+
el.count = 0;
26+
27+
assert.equal(button.textContent, '0');
28+
assert.equal(el.count, 0);
29+
30+
button.click();
31+
32+
flushSync();
33+
34+
assert.equal(button.textContent, '1');
35+
assert.equal(el.count, 1);
36+
}
37+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<svelte:options customElement="custom-element" />
2+
3+
<script>
4+
export let count = 0;
5+
</script>
6+
7+
<button onclick={() => count++}>{count}</button>

0 commit comments

Comments
 (0)