mirror of https://github.com/sveltejs/svelte
fix: error when using `let:` directives on a component with a `children` snippet (#18873)
Closes #13864 A `let:` directive on a component only applies to the default slot content. If the content is an explicit `{#snippet children()}` block, the value is never provided, so code like this compiles but fails at runtime with "value is not defined": ```svelte <Child let:value> {#snippet children()}Value is: {value}{/snippet} </Child> ``` This adds a compile error on the directive that points to snippet parameters instead (`{#snippet children({ value })}`, or `{ item: x }` for `let:item={x}`). Components with a `slot` attribute are not affected, since there the directive applies to the component itself. An unused `let:` next to a `children` snippet is also flagged now, but it never had any effect. ### Before submitting the PR, please make sure you do the following - [x] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs - [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`. - [x] This message body should clearly illustrate what problems it solves. - [x] Ideally, include a test that fails without this PR but passes with it. - [x] If this PR changes code within `packages/svelte/src`, add a changeset (`npx changeset`). ### Tests and linting - [x] Run the tests with `pnpm test` and lint the project with `pnpm lint` Co-authored-by: waltu <182410443+waltuov@users.noreply.github.com>pull/18871/merge
parent
75aa6ba38d
commit
a956c2bd1f
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: error when using `let:` directives on a component with a `children` snippet
|
||||
@ -0,0 +1,10 @@
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
error: {
|
||||
code: 'let_directive_snippet_conflict',
|
||||
message:
|
||||
'Cannot use `let:` directives on a component that has a `children` snippet. Use snippet parameters instead (e.g. `{#snippet children({ item: x })}`)',
|
||||
position: [62, 74]
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,7 @@
|
||||
<script>
|
||||
import Child from './irrelevant';
|
||||
</script>
|
||||
|
||||
<Child let:item={x}>
|
||||
{#snippet children()}{x}{/snippet}
|
||||
</Child>
|
||||
@ -0,0 +1,10 @@
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
error: {
|
||||
code: 'let_directive_snippet_conflict',
|
||||
message:
|
||||
'Cannot use `let:` directives on a component that has a `children` snippet. Use snippet parameters instead (e.g. `{#snippet children({ value })}`)',
|
||||
position: [359, 368]
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,23 @@
|
||||
<script>
|
||||
import Child from './irrelevant';
|
||||
import Parent from './irrelevant';
|
||||
</script>
|
||||
|
||||
<!-- ok -->
|
||||
<Child let:value>
|
||||
{value}
|
||||
{#snippet foo()}x{/snippet}
|
||||
</Child>
|
||||
<Child>
|
||||
{#snippet children({ value })}{value}{/snippet}
|
||||
</Child>
|
||||
<Parent>
|
||||
<Child slot="foo" let:value>
|
||||
{#snippet children()}{value}{/snippet}
|
||||
</Child>
|
||||
</Parent>
|
||||
|
||||
<!-- invalid -->
|
||||
<Child let:value>
|
||||
{#snippet children()}Value is: {value}{/snippet}
|
||||
</Child>
|
||||
Loading…
Reference in new issue