8000 fix: allow using typescript in `customElement.extend` option (#16001) · sveltejs/svelte@fbb6444 · GitHub
[go: up one dir, main page]

Skip to content

Commit fbb6444

Browse files
fix: allow using typescript in customElement.extend option (#16001)
Closes #15372 --------- Co-authored-by: Dominik G. <dominik.goepel@gmx.de>
1 parent add0c6a commit fbb6444

File tree

5 files changed

+45
-0
lines changed

5 files changed

+45
-0
lines changed

.changeset/olive-pandas-trade.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: allow using typescript in `customElement.extend` option

documentation/docs/07-misc/04-custom-elements.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ When constructing a custom element, you can tailor several aspects by defining `
114114
...
115115
```
116116

117+
> [!NOTE] While Typescript is supported in the `extend` function, it is subject to limitations: you need to set `lang="ts"` on one of the scripts AND you can only use [erasable syntax](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly) in it. They are not processed by script preprocessors.
118+
117119
## Caveats and limitations
118120

119121
Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:

packages/svelte/src/compiler/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ export function compile(source, options) {
4343
instance: parsed.instance && remove_typescript_nodes(parsed.instance),
4444
module: parsed.module && remove_typescript_nodes(parsed.module)
4545
};
46+
if (combined_options.customElementOptions?.extend) {
47+
combined_options.customElementOptions.extend = remove_typescript_nodes(
48+
combined_options.customElementOptions?.extend
49+
);
50+
}
4651
}
4752

4853
const analysis = analyze_component(parsed, source, combined_options);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { test } from '../../assert';
2+
const tick = () => Promise.resolve();
3+
4+
export default test({
5+
async test({ assert, target }) {
6+
target.innerHTML = '<custom-element name="world"></custom-element>';
7+
await tick();
8+
/** @type {any} */
9+
const el = target.querySelector('custom-element');
10+
11+
assert.htmlEqual(
12+
el.shadowRoot.innerHTML,
13+
`
14+
<p>name: world</p>
15+
`
16+
);
17+
assert.equal(el.test, `test`);
18+
}
19+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<svelte:options customElement={{
2+
tag: "custom-element",
3+
extend: (customClass)=>{
4+
return class extends customClass{
5+
public test: string = "test";
6+
}
7+
},
8+
}}/>
9+
10+
<script lang="ts">
11+
let { name } = $props();
12+
</script>
13+
14+
<p>name: {name}</p>

0 commit comments

Comments
 (0)
0