diff --git a/.changeset/poor-mugs-pay.md b/.changeset/poor-mugs-pay.md
new file mode 100644
index 0000000000..01f54e4604
--- /dev/null
+++ b/.changeset/poor-mugs-pay.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: propagate custom element component prop changes
diff --git a/packages/svelte/src/internal/client/dom/elements/custom-element.js b/packages/svelte/src/internal/client/dom/elements/custom-element.js
index 1c31d0a394..a0483e9ea5 100644
--- a/packages/svelte/src/internal/client/dom/elements/custom-element.js
+++ b/packages/svelte/src/internal/client/dom/elements/custom-element.js
@@ -1,7 +1,7 @@
import { createClassComponent } from '../../../../legacy/legacy-client.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.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
@@ -305,7 +305,18 @@ export function create_custom_element(
set(value) {
value = get_custom_element_value(prop, value, props_definition);
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 });
+ }
+ }
}
});
});
diff --git a/packages/svelte/tests/runtime-browser/custom-elements-samples/propagate-prop-changes/_config.js b/packages/svelte/tests/runtime-browser/custom-elements-samples/propagate-prop-changes/_config.js
new file mode 100644
index 0000000000..da451f6230
--- /dev/null
+++ b/packages/svelte/tests/runtime-browser/custom-elements-samples/propagate-prop-changes/_config.js
@@ -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 = '';
+ 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);
+ }
+});
diff --git a/packages/svelte/tests/runtime-browser/custom-elements-samples/propagate-prop-changes/main.svelte b/packages/svelte/tests/runtime-browser/custom-elements-samples/propagate-prop-changes/main.svelte
new file mode 100644
index 0000000000..5aafc8eecf
--- /dev/null
+++ b/packages/svelte/tests/runtime-browser/custom-elements-samples/propagate-prop-changes/main.svelte
@@ -0,0 +1,7 @@
+
+
+
+
+