Skip to content

Commit fc7e99e

Browse files
authored
fix $$props reactive for slots (#5125)
1 parent 8a8177b commit fc7e99e

File tree

5 files changed

+51
-14
lines changed

5 files changed

+51
-14
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Svelte changelog
22

3+
## Unreleased
4+
5+
* Fix reactivity when passing `$$props` to a `<slot>` ([#3364](https://github.com/sveltejs/svelte/issues/3364))
6+
37
## 3.24.0
48

59
* Support nullish coalescing (`??`) and optional chaining (`?.`) operators ([#1972](https://github.com/sveltejs/svelte/issues/1972))

src/compiler/compile/render_dom/wrappers/Slot.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { b, p, x } from 'code-red';
77
import { sanitize } from '../../../utils/names';
88
import add_to_set from '../../utils/add_to_set';
99
import get_slot_data from '../../utils/get_slot_data';
10+
import { is_reserved_keyword } from '../../utils/reserved_keywords';
1011
import Expression from '../../nodes/shared/Expression';
1112
import is_dynamic from './shared/is_dynamic';
1213
import { Identifier, ObjectExpression } from 'estree';
@@ -94,11 +95,7 @@ export default class SlotWrapper extends Wrapper {
9495
}
9596
});
9697

97-
const dynamic_dependencies = Array.from(attribute.dependencies).filter(name => {
98-
if (this.node.scope.is_let(name)) return true;
99-
const variable = renderer.component.var_lookup.get(name);
100-
return is_dynamic(variable);
101-
});
98+
const dynamic_dependencies = Array.from(attribute.dependencies).filter((name) => this.is_dependency_dynamic(name));
10299

103100
if (dynamic_dependencies.length > 0) {
104101
changes.properties.push(p`${attribute.name}: ${renderer.dirty(dynamic_dependencies)}`);
@@ -157,17 +154,10 @@ export default class SlotWrapper extends Wrapper {
157154
b`@transition_out(${slot_or_fallback}, #local);`
158155
);
159156

160-
const is_dependency_dynamic = name => {
161-
if (name === '$$scope') return true;
162-
if (this.node.scope.is_let(name)) return true;
163-
const variable = renderer.component.var_lookup.get(name);
164-
return is_dynamic(variable);
165-
};
166-
167-
const dynamic_dependencies = Array.from(this.dependencies).filter(is_dependency_dynamic);
157+
const dynamic_dependencies = Array.from(this.dependencies).filter((name) => this.is_dependency_dynamic(name));
168158

169159
const fallback_dynamic_dependencies = has_fallback
170-
? Array.from(this.fallback.dependencies).filter(is_dependency_dynamic)
160+
? Array.from(this.fallback.dependencies).filter((name) => this.is_dependency_dynamic(name))
171161
: [];
172162

173163
const slot_update = b`
@@ -201,4 +191,12 @@ export default class SlotWrapper extends Wrapper {
201191
b`if (${slot_or_fallback}) ${slot_or_fallback}.d(detaching);`
202192
);
203193
}
194+
195+
is_dependency_dynamic(name: string) {
196+
if (name === '$$scope') return true;
197+
if (this.node.scope.is_let(name)) return true;
198+
if (is_reserved_keyword(name)) return true;
199+
const variable = this.renderer.component.var_lookup.get(name);
200+
return is_dynamic(variable);
201+
}
204202
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<slot props={$$props}/>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export default {
2+
html: `
3+
<h1>hi</h1>
4+
<button>Change</button>
5+
`,
6+
7+
async test({ assert, component, target, window }) {
8+
const btn = target.querySelector("button");
9+
const clickEvent = new window.MouseEvent("click");
10+
11+
await btn.dispatchEvent(clickEvent);
12+
13+
assert.htmlEqual(
14+
target.innerHTML,
15+
`
16+
<h1>changed</h1>
17+
<button>Change</button>
18+
`
19+
);
20+
},
21+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
import Comp from './Comp.svelte'
3+
let p = "hi"
4+
</script>
5+
6+
<Comp someprop={p} let:props>
7+
<h1>
8+
{props.someprop}
9+
</h1>
10+
</Comp>
11+
12+
<button on:click={()=> p = "changed"}>Change
13+
</button>

0 commit comments

Comments
 (0)