Skip to content

Commit e8e4290

Browse files
committed
fix: allow runelike writable as prop
1 parent d856c50 commit e8e4290

File tree

7 files changed

+59
-1
lines changed

7 files changed

+59
-1
lines changed

.changeset/chilly-pans-raise.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
fix: allow runelike writable as prop

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,9 @@ export function analyze_component(root, source, options) {
285285
!Runes.includes(/** @type {any} */ (name)) ||
286286
(declaration !== null &&
287287
// const state = $state(0) is valid
288-
get_rune(declaration.initial, instance.scope) === null &&
288+
(get_rune(declaration.initial, instance.scope) === null ||
289+
// rune-line names received as props are valid too (but we have to protect against $props as store)
290+
(store_name !== 'props' && get_rune(declaration.initial, instance.scope) === '$props')) &&
289291
// allow `import { derived } from 'svelte/store'` in the same file as `const x = $derived(..)` because one is not a subscription to the other
290292
!(
291293
name === '$derived' &&
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
test({ assert, target, ok }) {
6+
const button = target.querySelector('button');
7+
8+
flushSync(() => {
9+
button?.click();
10+
});
11+
assert.htmlEqual(
12+
target.innerHTML,
13+
`
14+
<button>1</button>
15+
`
16+
);
17+
}
18+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let { state } = $props();
3+
</script>
4+
5+
<button onclick={()=> $state++}>{$state}</button>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<svelte:options runes />
2+
<script>
3+
import { writable } from "svelte/store";
4+
import Child from "./child.svelte";
5+
const state = writable(0);
6+
</script>
7+
8+
<Child {state} />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
let { state } = $props();
3+
let x = $state();
4+
</script>
5+
6+
{$state}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"code": "store_rune_conflict",
4+
"message": "It looks like you're using the `$state` rune, but there is a local binding called `state`. Referencing a local variable with a `$` prefix will create a store subscription. Please rename `state` to avoid the ambiguity",
5+
"start": {
6+
"line": 3,
7+
"column": 9
8+
},
9+
"end": {
10+
"line": 3,
11+
"column": 15
12+
}
13+
}
14+
]

0 commit comments

Comments
 (0)