From 0aa03df086dce81083f23d254f660600331c0a69 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Mon, 3 Jul 2023 15:16:13 +0200
Subject: [PATCH] fix: reflect all custom element prop updates back to
attribute (#8898)
fixes #8879
---
.changeset/gold-tips-roll.md | 5 +++
.../svelte/src/runtime/internal/Component.js | 40 ++++++++++++-------
.../reflect-attributes/main.svelte | 9 +++--
.../reflect-attributes/test.js | 8 ++++
4 files changed, 43 insertions(+), 19 deletions(-)
create mode 100644 .changeset/gold-tips-roll.md
diff --git a/.changeset/gold-tips-roll.md b/.changeset/gold-tips-roll.md
new file mode 100644
index 0000000000..777d26db3f
--- /dev/null
+++ b/.changeset/gold-tips-roll.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: reflect all custom element prop updates back to attribute
diff --git a/packages/svelte/src/runtime/internal/Component.js b/packages/svelte/src/runtime/internal/Component.js
index b0e82da267..4733b1d745 100644
--- a/packages/svelte/src/runtime/internal/Component.js
+++ b/packages/svelte/src/runtime/internal/Component.js
@@ -269,6 +269,31 @@ if (typeof HTMLElement === 'function') {
}
}
});
+
+ // Reflect component props as attributes
+ const reflect_attributes = () => {
+ this.$$r = true;
+ for (const key in this.$$p_d) {
+ this.$$d[key] = this.$$c.$$.ctx[this.$$c.$$.props[key]];
+ if (this.$$p_d[key].reflect) {
+ const attribute_value = get_custom_element_value(
+ key,
+ this.$$d[key],
+ this.$$p_d,
+ 'toAttribute'
+ );
+ if (attribute_value == null) {
+ this.removeAttribute(key);
+ } else {
+ this.setAttribute(this.$$p_d[key].attribute || key, attribute_value);
+ }
+ }
+ }
+ this.$$r = false;
+ };
+ this.$$c.$$.after_update.push(reflect_attributes);
+ reflect_attributes(); // once initially because after_update is added too late for first render
+
for (const type in this.$$l) {
for (const listener of this.$$l[type]) {
const unsub = this.$$c.$on(type, listener);
@@ -386,21 +411,6 @@ export function create_custom_element(
value = get_custom_element_value(prop, value, props_definition);
this.$$d[prop] = value;
this.$$c?.$set({ [prop]: value });
- if (props_definition[prop].reflect) {
- this.$$r = true;
- const attribute_value = get_custom_element_value(
- prop,
- value,
- props_definition,
- 'toAttribute'
- );
- if (attribute_value == null) {
- this.removeAttribute(prop);
- } else {
- this.setAttribute(props_definition[prop].attribute || prop, attribute_value);
- }
- this.$$r = false;
- }
}
});
});
diff --git a/packages/svelte/test/runtime-browser/custom-elements-samples/reflect-attributes/main.svelte b/packages/svelte/test/runtime-browser/custom-elements-samples/reflect-attributes/main.svelte
index 0e36f0143c..a662227a13 100644
--- a/packages/svelte/test/runtime-browser/custom-elements-samples/reflect-attributes/main.svelte
+++ b/packages/svelte/test/runtime-browser/custom-elements-samples/reflect-attributes/main.svelte
@@ -1,19 +1,20 @@
hi
-