Repository: svelte
Issue: enhancement(custom element): svelte 5 should automatically set converters based on types
Labels: feature request,custom element

### Describe the problem

## Motivation

We maintain custom element libraries at work, some using vue.js, some using svelte.js.
To be honest, this is not really a pleasant experience in **either** of framework.
While vue.js has tremendous issues with correctly outputting css for nested components, svelte technically works as expected, but the process to get there is very clunky and un-svelte-like.

## Clunkiness in Svelte

To me, the biggest issue with building custom elements in svelte 4 is the `<svelte:options/>` api.
Since `customElement` must be a statically analyzable object literal, it cannot be dynamically generated using javascript.
This means that if you have to set a very large amount of properties, the config alone takes away a lot of valuable space. 
```svelte
<svelte:options customElement={{
  tag: "my-foo",
  props: {
    // if not manually converted the attribute is: `mymultiwordprop`, which is bad dx at best and a trap at worst
    myMultiwordProp: {
      attribute: "my-multiword-prop"
    },
    obj: {
      type: "Object"
    },
   num: {
     type: "Number"
   }
  }
}} />

<script lang="ts">
  export let myMultiwordProp: string;
  export let obj: {a: string};
  export let num: number;
</script>
```
for decent sized components, this can become so bad, that I ended up writing a vite plugin that injects the `<svelte:options customElement/>` config, just so that the amount of code inside the SFC stayed manageable.

## Custom Elements in Svelte 5

svelte 5 already relieves part of this clunkiness, since props can now be declared as "attribute" kebab-case from the start:
```svelte
<script lang="ts">
let {'my-multiword-prop': myMultiwordProp} = $props<{
  ['my-multiword-prop']: string;
}>();
</script>
<p>{myMultiwordProp}</p>
```

However, most web components take props other than just strings, which in the case of a complex component still requires a lot of clunky configuration.

### Describe the proposed solution

## The Vue Approach

vue 3 leverages the information it gets from its `defineProps()` macro to automatically convert attributes from strings into the correct type. (vue does this only for basic types: String, Number, Boolean)

I've created two stackblitz reproductions, so you can compare what vue does differently here than svelte:

- [vue custom element (implicit type conversion)](https://stackblitz.com/edit/vitejs-vite-tpc83e?file=src/App.vue,src/components/Foo.vue)
- [svelte custom element (no implicit type conversion)](https://stackblitz.com/edit/vitejs-vite-fnywzv?file=index.html,src/lib/Foo.svelte,src/App.svelte)

## Proposal for Svelte 5: Implicit Conversion Leveraging Types

While svelte does not collect "type" information for non-typescript props like vue does, it should still be possible to make the process easier for typescript users (and with more and more users choosing typescript, that would be most users).

I know next to nothing about compilers, but I thought since svelte 5 now uses acorn-typescript for parsing the necessary type information might already be there, ready to be statically analized (assuming the script content is parsed)

While implicit type conversion would be a great first step, this idea could even be expanded to 
1. use the [`$bindable()`](https://svelte-5-preview.vercel.app/docs/breaking-changes#breaking-changes-in-runes-mode-bindings-need-to-be-explicitly-defined-using-$bindable) rune to show that an attribute should be reflected back to the host element
2. use an attribute on the style tag to signify that styles should be encapsuled into the shadow dom

I don't know if implementing this proposal is feasible, but it would remove a lot of the "boilerplate" associated with the `<svelte:options customElement={{...}}/>` clutter configuration of today.

### Importance

would make my life easier