Skip to content

Commit a1b6cc6

Browse files
authored
fix: handle is attribute on elements with spread (#12056)
The `is` attribute is special and always needs to be part of the static template string, or else it wouldn't be taken into account on initialization fixes #12052
1 parent c3da6a4 commit a1b6cc6

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

.changeset/large-waves-join.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: handle `is` attribute on elements with spread

packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,15 @@ function serialize_element_spread_attributes(
278278
// TODO: handle contains_call_expression
279279
const [, value] = serialize_attribute_value(attribute.value, context);
280280

281+
if (
282+
name === 'is' &&
283+
value.type === 'Literal' &&
284+
context.state.metadata.namespace === 'html'
285+
) {
286+
context.state.template.push(` is="${escape_html(value.value, true)}"`);
287+
continue;
288+
}
289+
281290
if (
282291
is_event_attribute(attribute) &&
283292
(attribute.value[0].expression.type === 'ArrowFunctionExpression' ||
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
mode: ['client'],
6+
test({ assert, target, logs }) {
7+
const [b1, b2] = target.querySelectorAll('button');
8+
9+
b1.click();
10+
flushSync();
11+
assert.deepEqual(logs, ['works']);
12+
13+
b2.click();
14+
flushSync();
15+
assert.deepEqual(logs, ['works', 'works']);
16+
}
17+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script lang="ts" context="module">
2+
if (!customElements.get('x-button')) {
3+
class XButton extends HTMLButtonElement {
4+
connectedCallback() {
5+
this.addEventListener('click', () => console.log('works'));
6+
}
7+
}
8+
9+
customElements.define('x-button', XButton, { extends: 'button' });
10+
}
11+
</script>
12+
13+
<script lang="ts">
14+
let { ...props } = $props();
15+
</script>
16+
17+
<button is="x-button">click me</button>
18+
<button {...props} is="x-button">click me</button>

0 commit comments

Comments
 (0)