fix: apply `clsx` logic to custom element `class` attributes (#14907)

Fixes #14902
pull/14908/head
Simon H 5 days ago committed by GitHub
parent c4e9faad52
commit 2e2b440954
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: apply `clsx` logic to custom element `class` attributes

@ -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) {

@ -1,3 +1,4 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
@ -14,27 +15,32 @@ export default test({
<div class="foo">child</div>
<div class="foo">child</div>
<applied-to-custom-element class="foo svelte-owbekl"></applied-to-custom-element>
<button>update</button>
`,
test({ assert, target }) {
const button = target.querySelector('button');
button?.click();
flushSync();
assert.htmlEqual(
target.innerHTML,
`
<div class="foo svelte-owbekl"></div>
<div class="foo svelte-owbekl"></div>
<div class="foo svelte-owbekl"></div>
<div class="foo svelte-owbekl"></div>
<div class="bar svelte-owbekl"></div>
<div class="bar svelte-owbekl"></div>
<div class="foo svelte-owbekl"></div>
<div class="foo">child</div>
<div class="foo">child</div>
<div class="bar">child</div>
<div class="bar">child</div>
<div class="foo">child</div>
<div class="foo">child</div>
<div class="foo">child</div>
<applied-to-custom-element class="bar svelte-owbekl"></applied-to-custom-element>
<button>update</button>
`

@ -18,6 +18,8 @@
<Child class={[ foo, bar ]} />
<Child {...spread} />
<applied-to-custom-element class={{ foo, bar }}></applied-to-custom-element>
<button onclick={() => {
foo = null;
bar = 'bar';

Loading…
Cancel
Save