diff --git a/.changeset/fuzzy-taxis-hunt.md b/.changeset/fuzzy-taxis-hunt.md new file mode 100644 index 0000000000..5deda96ce5 --- /dev/null +++ b/.changeset/fuzzy-taxis-hunt.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: falsy attachments on components diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js index 57402c2b4a..3aa7f486ea 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js @@ -261,7 +261,10 @@ export function build_component(node, component_name, context, anchor = context. let expression = /** @type {Expression} */ (context.visit(attribute.expression)); if (attribute.metadata.expression.has_state) { - expression = b.arrow([b.id('$$node')], b.call(expression, b.id('$$node'))); + expression = b.arrow( + [b.id('$$node')], + b.call(b.call('$.safe_call', expression), b.id('$$node')) + ); } push_prop(b.prop('get', b.call('$.attachment'), expression, true)); diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index 71c06d7b1b..269dcfd17b 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -155,7 +155,7 @@ export { } from './dom/operations.js'; export { attr, clsx } from '../shared/attributes.js'; export { snapshot } from '../shared/clone.js'; -export { noop, fallback, to_array } from '../shared/utils.js'; +export { noop, fallback, safe_call, to_array } from '../shared/utils.js'; export { invalid_default_snippet, validate_dynamic_element_tag, diff --git a/packages/svelte/src/internal/shared/utils.js b/packages/svelte/src/internal/shared/utils.js index 10f8597520..59f9bbfd0e 100644 --- a/packages/svelte/src/internal/shared/utils.js +++ b/packages/svelte/src/internal/shared/utils.js @@ -82,6 +82,16 @@ export function fallback(value, fallback, lazy = false) { : value; } +/** + * @param {*} value + */ +export function safe_call(value) { + if (is_function(value)) { + return value; + } + return noop; +} + /** * When encountering a situation like `let [a, b, c] = $derived(blah())`, * we need to stash an intermediate value that `a`, `b`, and `c` derive diff --git a/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/Child.svelte b/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/Child.svelte new file mode 100644 index 0000000000..6760da61fa --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/Child.svelte @@ -0,0 +1,5 @@ + + +
diff --git a/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/_config.js b/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/_config.js new file mode 100644 index 0000000000..27f013d6d1 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +export default test({ + test() {} +}); diff --git a/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/main.svelte b/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/main.svelte new file mode 100644 index 0000000000..993bcdd6a5 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/attachment-component-falsy/main.svelte @@ -0,0 +1,13 @@ + + + + +