fix: propagate custom element component prop changes (#12774)

* fix: propagate custom element component prop changes

* add test
pull/12795/head
Dominic Gannaway 5 months ago committed by GitHub
parent a0bbf2ace0
commit ba116a1b43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: propagate custom element component prop changes

@ -1,7 +1,7 @@
import { createClassComponent } from '../../../../legacy/legacy-client.js'; import { createClassComponent } from '../../../../legacy/legacy-client.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.js'; import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { append } from '../template.js'; import { append } from '../template.js';
import { define_property, object_keys } from '../../../shared/utils.js'; import { define_property, get_descriptor, object_keys } from '../../../shared/utils.js';
/** /**
* @typedef {Object} CustomElementPropDefinition * @typedef {Object} CustomElementPropDefinition
@ -305,7 +305,18 @@ export function create_custom_element(
set(value) { set(value) {
value = get_custom_element_value(prop, value, props_definition); value = get_custom_element_value(prop, value, props_definition);
this.$$d[prop] = value; this.$$d[prop] = value;
this.$$c?.$set({ [prop]: value }); var component = this.$$c;
if (component) {
// // If the instance has an accessor, use that instead
var setter = get_descriptor(component, prop)?.get;
if (setter) {
component[prop] = value;
} else {
component.$set({ [prop]: value });
}
}
} }
}); });
}); });

@ -0,0 +1,37 @@
import { flushSync } from 'svelte';
import { test } from '../../assert';
const tick = () => Promise.resolve();
export default test({
async test({ assert, target }) {
target.innerHTML = '<custom-element></custom-element>';
await tick();
await tick();
/** @type {any} */
const el = target.querySelector('custom-element');
const button = el.shadowRoot.querySelector('button');
assert.equal(button.textContent, '0');
assert.equal(el.count, 0);
button.click();
flushSync();
assert.equal(button.textContent, '1');
assert.equal(el.count, 1);
el.count = 0;
assert.equal(button.textContent, '0');
assert.equal(el.count, 0);
button.click();
flushSync();
assert.equal(button.textContent, '1');
assert.equal(el.count, 1);
}
});

@ -0,0 +1,7 @@
<svelte:options customElement="custom-element" />
<script>
export let count = 0;
</script>
<button onclick={() => count++}>{count}</button>
Loading…
Cancel
Save