-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom Elements built with Svelte 4 do not work in Home Assistant #8954
Comments
In Svelte 4, the inner components are created after a tick when the custom element is mounted to the DOM. This should work: const element = document.createElement(tag)
mountTarget.appendChild(element);
await Promise.resolve();
element.setConfig(config); See #8457 for a more indepth explanation of the breaking change. Looking at the code, it doesn't seem that you have control over this part of the code though. A workaround for you would be to manually append the function to the created custom element component and forward it to a prop which will be saved for later use. Something like this: <svelte:options customElement="my-widget" />
<script context="module">
customElements.whenDefined('my-widget').then((element) => {
element.prototype.setConfig = function (config) {
this.config = config;
};
});
</script>
<script>
export let config;
</script> |
Thanks! The second snippet is getting executed (I see the added function on the element's prototype), but does not work for some reason, as I still get |
Ah that's unfortunate, I guess |
This should help everyone who has special needs and use cases around custom elements. Since Svelte components are wrapped and only run on connectedCallback, it makes sense to expose the custom element class for modification before that. - fixes #8954 - use extend to attach the function manually and save possible values to a prop - closes #8473 / closes #4168 - use extend to set the proper static attribute and then call attachInternals in the constructor closes #8472 - use extend to attach anything custom you need closes #3091 - pass `this` to a prop of your choice and use it inside your component
This should help everyone who has special needs and use cases around custom elements. Since Svelte components are wrapped and only run on connectedCallback, it makes sense to expose the custom element class for modification before that. - fixes #8954 / closes #8955 - use extend to attach the function manually and save possible values to a prop - closes #8473 / closes #4168 - use extend to set the proper static attribute and then call attachInternals in the constructor - closes #8472 - use extend to attach anything custom you need - closes #3091 - pass `this` to a prop of your choice and use it inside your component - add some doc for #8987
With the new <svelte:options
customElement={{
tag: 'custom-element',
extend: (customElementConstructor) => {
return class extends customElementConstructor {
// Add the function here, not below in the component so that
// it's always available, not just when the inner Svelte component
// is mounted
setConfig(config) {
this.config = config;
}
};
}
}}
/>
<script>
export let config;
</script>
... |
Excellent, thanks! |
Describe the bug
Context: Home Assistant's entire frontend is composed of custom elements. All the built-in ones are written in Lit. One can create a custom dashboard card by adding a new resource, which consists of a JS file containing a custom element. For the custom element card to render, it has to export
setConfig
function.When a custom element is rendered, Home Assistant calls
setConfig
on each such element in _createElement. Here's an extract:A custom element built with Svelte 3 works when added to Home Assistant, but Svelte 4's doesn't because of:
TypeError: element.setConfig is not a function
.Is the exported function not immediately available when the component is created?
Reproduction
Reproduction is a bit time-consuming, since you need to have a Home Assistant environment running.
npm init vite
)<svelte:options customElement="svelte-component" />
setConfig
to the componentnpm run build
.js
file as a new dashboard resource in Home AssistantHere is an example component with the exported
setConfig
:And here is
main.ts
:It starts to work if you downgrade Svelte from 4 to 3 and re-build.
Logs
No response
System Info
Severity
blocking an upgrade
The text was updated successfully, but these errors were encountered: