From 2e2b440954a783a836e803f7b2babc054a1a33ad Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:51:32 +0100 Subject: [PATCH] fix: apply `clsx` logic to custom element `class` attributes (#14907) Fixes #14902 --- .changeset/happy-candles-clean.md | 5 +++++ .../3-transform/client/visitors/RegularElement.js | 12 +++++++++++- .../tests/runtime-runes/samples/clsx/_config.js | 14 ++++++++++---- .../tests/runtime-runes/samples/clsx/main.svelte | 2 ++ 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 .changeset/happy-candles-clean.md diff --git a/.changeset/happy-candles-clean.md b/.changeset/happy-candles-clean.md new file mode 100644 index 0000000000..d08f97a247 --- /dev/null +++ b/.changeset/happy-candles-clean.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: apply `clsx` logic to custom element `class` attributes diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js index 59a6fafbc5..ffd06dfd86 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js @@ -571,7 +571,9 @@ function build_element_attribute_update_assignment( is_svg ? '$.set_svg_class' : is_mathml ? '$.set_mathml_class' : '$.set_class', node_id, value, - attribute.metadata.needs_clsx ? b.literal(context.state.analysis.css.hash) : undefined + attribute.metadata.needs_clsx && context.state.analysis.css.hash + ? b.literal(context.state.analysis.css.hash) + : undefined ) ); } else if (name === 'value') { @@ -648,6 +650,14 @@ function build_custom_element_attribute_update_assignment(node_id, attribute, co const name = attribute.name; // don't lowercase, as we set the element's property, which might be case sensitive let { has_call, value } = build_attribute_value(attribute.value, context); + // We assume that noone's going to redefine the semantics of the class attribute on custom elements, i.e. it's still used for CSS classes + if (name === 'class' && attribute.metadata.needs_clsx) { + if (context.state.analysis.css.hash) { + value = b.array([value, b.literal(context.state.analysis.css.hash)]); + } + value = b.call('$.clsx', value); + } + const update = b.stmt(b.call('$.set_custom_element_data', node_id, b.literal(name), value)); if (attribute.metadata.expression.has_state) { diff --git a/packages/svelte/tests/runtime-runes/samples/clsx/_config.js b/packages/svelte/tests/runtime-runes/samples/clsx/_config.js index e0813d0e6c..202a13b1cb 100644 --- a/packages/svelte/tests/runtime-runes/samples/clsx/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/clsx/_config.js @@ -1,3 +1,4 @@ +import { flushSync } from 'svelte'; import { test } from '../../test'; export default test({ @@ -14,27 +15,32 @@ export default test({
child
child
+ + `, test({ assert, target }) { const button = target.querySelector('button'); button?.click(); + flushSync(); assert.htmlEqual( target.innerHTML, `
-
-
+
+
child
child
+
child
+
child
child
-
child
-
child
+ + ` diff --git a/packages/svelte/tests/runtime-runes/samples/clsx/main.svelte b/packages/svelte/tests/runtime-runes/samples/clsx/main.svelte index bf68b42e11..ebc0697f97 100644 --- a/packages/svelte/tests/runtime-runes/samples/clsx/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/clsx/main.svelte @@ -18,6 +18,8 @@ + +