You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<script>import"my-lib/my-el"// import a native Custom Element definition (not made with Svelte)letfoo=[1,2,3]</script><my-elfoo={foo}/>
is resulting in the array getting stringified and passed in as a DOM attribute. It works (my custom elements handle array string values for example) but it is not good for performance.
A Svelte user that might be using my custom elements will see the custom elements work when they pass arrays as the type definitions allow, but it is not obvious that they are being converted into strings only to be converted back into arrays again.
The workaround is to escape out of the template using refs (bind:this) in order to set JS properties in JavaScript instead of in the template, which is not ideal for the developer experience (we want to stay in the template). The code becomes something like this:
<script>import"my-lib/my-el"// import a native Custom Element definition (not made with Svelte)letelletfoo=$state([1,2,3])$effect(()=>{el.foo=foo})</script><my-elbind:this={el}/>
Describe the proposed solution
In Vue we have <my-el foo.prop="..." foo.attr="...">. In Solid.js we have <my-el prop:foo={...} attr:foo={...}>.
In Vue, I can do the following and it will always set the prop instead of the attribute, so I can avoid the cost of string conversions:
We need a way to explicitly choose to set a prop, or to set an attribute.
Solid.js also has <my-el bool:foo={value} /> which forces boolean attribute treatment based on the truthiness of the given value. Lit.dev also has explicit boolean syntax: <my-el ?foo=${value} /> to use truthiness of value.
React 18 was sending all values as string too, but they semi-fixed this in React 19 which will now detect a JS property and use the JS property instead of an attribute (but the control is still not explicit, so if React chooses a JS property, there's no way for the user to choose an attribute).
Related to being able to choose an attribute vs a property, users need the choice to avoid broken styles similar to what is described here:
So, regardless if an element has a prop, and attribute, or both, the user still needs choice for ultimate control of the DOM (i.e. without the framework getting in the way).
Here's a custom-elements-everywhere proposal that will add a new test to ensure that all frameworks allow control, which Svelte will currently not pass (unless Svelte's feature wasn't documented and I missed it):
Describe the problem
In Svelte, this,
is resulting in the array getting stringified and passed in as a DOM attribute. It works (my custom elements handle array string values for example) but it is not good for performance.
A Svelte user that might be using my custom elements will see the custom elements work when they pass arrays as the type definitions allow, but it is not obvious that they are being converted into strings only to be converted back into arrays again.
The workaround is to escape out of the template using refs (
bind:this
) in order to set JS properties in JavaScript instead of in the template, which is not ideal for the developer experience (we want to stay in the template). The code becomes something like this:Describe the proposed solution
In Vue we have
<my-el foo.prop="..." foo.attr="...">
. In Solid.js we have<my-el prop:foo={...} attr:foo={...}>
.In Vue, I can do the following and it will always set the prop instead of the attribute, so I can avoid the cost of string conversions:
What about Svelte? There doesn't seem to be anything like this in Svelte unless the docs didn't mention it. I look here: https://svelte.dev/docs/svelte/basic-markup.
We need a way to explicitly choose to set a prop, or to set an attribute.
Solid.js also has
<my-el bool:foo={value} />
which forces boolean attribute treatment based on the truthiness of the givenvalue
. Lit.dev also has explicit boolean syntax:<my-el ?foo=${value} />
to use truthiness ofvalue
.React 18 was sending all values as string too, but they semi-fixed this in React 19 which will now detect a JS property and use the JS property instead of an attribute (but the control is still not explicit, so if React chooses a JS property, there's no way for the user to choose an attribute).
Related to being able to choose an attribute vs a property, users need the choice to avoid broken styles similar to what is described here:
So, regardless if an element has a prop, and attribute, or both, the user still needs choice for ultimate control of the DOM (i.e. without the framework getting in the way).
Here's a custom-elements-everywhere proposal that will add a new test to ensure that all frameworks allow control, which Svelte will currently not pass (unless Svelte's feature wasn't documented and I missed it):
Importance
would make my life easier
The text was updated successfully, but these errors were encountered: