This is an overhaul of custom elements in Svelte. Instead of compiling to a custom element class, the Svelte component class is mostly preserved as-is. Instead a wrapper is introduced which wraps a Svelte component constructor and returns a HTML element constructor. This has a couple of advantages:
- component can be used both as a custom element as well as a regular component. This allows creating one wrapper custom element and using regular Svelte components inside. Fixes#3594, fixes#3128, fixes#4274, fixes#5486, fixes#3422, fixes#2969, helps with https://github.com/sveltejs/kit/issues/4502
- all components are compiled with injected styles (inlined through Javascript), fixes#4274
- the wrapper instantiates the component in `connectedCallback` and disconnects it in `disconnectedCallback` (but only after one tick, because this could be a element move). Mount/destroy works as expected inside, fixes#5989, fixes#8191
- the wrapper forwards `addEventListener` calls to `component.$on`, which allows to listen to custom events, fixes#3119, closes#4142
- some things are hard to auto-configure, like attribute hyphen preferences or whether or not setting a property should reflect back to the attribute. This is why `<svelte:options customElement={..}>` can also take an object to modify such aspects. This option allows to specify whether setting a prop should be reflected back to the attribute (default `false`), what to use when converting the property to the attribute value and vice versa (through `type`, default `String`, or when `export let prop = false` then `Boolean`), and what the corresponding attribute for the property is (`attribute`, default lowercased prop name). These options are heavily inspired by lit: https://lit.dev/docs/components/properties. Closes#7638, fixes#5705
- adds a `shadowdom` option to control whether or not encapsulate the custom element. Closes#4330, closes#1748
Breaking changes:
- Wrapped Svelte component now stays as a regular Svelte component (invokeing it like before with `new Component({ target: ..})` won't create a custom element). Its custom element constructor is now a static property named `element` on the class (`Component.element`) and should be regularly invoked through setting it in the html.
- The timing of mount/destroy/update is different. Mount/destroy/updating a prop all happen after a tick, so `shadowRoot.innerHTML` won't immediately reflect the change (Lit does this too). If you rely on it, you need to await a promise
Closes#3310
---------
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Move @html tutorial to end
* move debug and html tag into one section
* rename
---------
Co-authored-by: Rémi Marche <35939574+Marr11317@users.noreply.github.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
Co-authored-by: Tan Li Hau <tanhauhau@users.noreply.github.com>
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Gabor Szabo <gabor@szabgab.com>
Co-authored-by: gtmnayan <50981692+gtm-nayan@users.noreply.github.com>
* add more examples on the spring store API docs
* Update site/content/docs/03-run-time.md
Co-authored-by: Ignatius Bagus <ignatius.mbs@gmail.com>
* Update site/content/docs/03-run-time.md
Co-authored-by: Ignatius Bagus <ignatius.mbs@gmail.com>
Co-authored-by: Ignatius Bagus <ignatius.mbs@gmail.com>