Skip to content

Commit

Permalink
fix: reflect all custom element prop updates back to attribute (#8898)
Browse files Browse the repository at this point in the history
fixes #8879
  • Loading branch information
dummdidumm committed Jul 3, 2023
1 parent 4b3eb72 commit 0aa03df
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/gold-tips-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: reflect all custom element prop updates back to attribute
40 changes: 25 additions & 15 deletions packages/svelte/src/runtime/internal/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
}
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
<svelte:options
customElement={{
tag: "custom-element",
props: { red: { reflect: true, type: "Boolean" } },
tag: 'custom-element',
props: { red: { reflect: true, type: 'Boolean' } }
}}
/>

<script>
import "./my-widget.svelte";
import './my-widget.svelte';
export let red;
red;
</script>

<div>hi</div>
<p>hi</p>
<my-widget red white />
<button on:click={() => (red = false)}>off</button>
<my-widget {red} white />

<style>
:host([red]) div {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default async function (target) {
const ceRoot = target.querySelector('custom-element').shadowRoot;
const div = ceRoot.querySelector('div');
const p = ceRoot.querySelector('p');
const button = ceRoot.querySelector('button');

assert.equal(getComputedStyle(div).color, 'rgb(255, 0, 0)');
assert.equal(getComputedStyle(p).color, 'rgb(255, 255, 255)');
Expand All @@ -19,4 +20,11 @@ export default async function (target) {

assert.equal(getComputedStyle(innerDiv).color, 'rgb(255, 0, 0)');
assert.equal(getComputedStyle(innerP).color, 'rgb(255, 255, 255)');

button.click();
await tick();
await tick();

assert.equal(getComputedStyle(div).color, 'rgb(0, 0, 0)');
assert.equal(getComputedStyle(innerDiv).color, 'rgb(0, 0, 0)');
}

0 comments on commit 0aa03df

Please sign in to comment.