From f85687ef87c07f1e8b7844df2257c1b0b213dec7 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Mon, 3 Jul 2023 15:10:43 +0200 Subject: [PATCH] fix: reflect all custom element prop updates back to attribute 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 000000000000..777d26db3fa0 --- /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 b0e82da26767..4733b1d74594 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 0e36f0143ce1..a662227a133d 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

hi

- + +