add them so that the TypeScript parser doesn't put the following content under the `@deprecated` tag, which messes with the JSON-type-generation script.
When the TypeScript plugin we provide isn't enabled, imports to `.svelte`-files fall back to an ambient module declaration. Said declaration was still only providing the deprecated class. This PR widens the type so that you can also invoke it like a function. After the transition period (Svelte 6 or 7) only the new type should be provided from the module declaration.
- give autocompletion for types and more precise event types for html elements
- allow to pass other kinds of event target nodes, like window
closes#12027fixes#12045
* import Component as Type
interfaces can only be used as a Type, that way it should be imported as type
* fix import type
* regenerate types
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
The current type narrows the binding type to `""` by default, which means "no bindings on this component". While this is the common case, it makes it very cumbersome to use the `Component` type because legacy components are of type `string` and as soon as you have bindings, the type is something like `"foo" | "bar"` which _also_ is not assignable to `""` which is semantically wrong, because you should be able to assign a component that can have bindings to a type that accepts none.
The pragmatic solution is to change the binding type to allow `string`, which means someone theoretically could use bindings with a component that doesn't have bindings:
```svelte
<script>
let component: Component<{ prop: boolean }> = IAcceptNoBindings;
</script>
<!-- allowed but should be a type error -->
<svelte:component this={component} bind:prop={foo} />
```
But this is a) rare anyway and b) can be caught at runtime
This came up in comments of #11775
In Svelte 3 and 4, components were classes under the hood, and the base class was `SvelteComponent`. This class was also used in language tools to properly type check the template code.
In Svelte 5, components are functions. To give people a way to extend them programmatically, it would be good to expose the actual shape of components. This is why this PR introduces a new `Component` type.
For backwards compatibility reasons, we can't just get rid of the old class-based types. We also need to ensure that language tools can work with both the new and old types: There are many libraries out there that provide `d.ts` files with type definitions written using the class types - these should not error.
That's why there's an accompagning language tools PR (https://github.com/sveltejs/language-tools/pull/2380) that's doing the heavy lifting: Instead of generating classes, it now generates a constant and an interfaces and uses Typescript's declaration merging feature to provide both so we can declare a component export as being both a class and a function. That ensures that people can still instantiate them with `new` (which they can do if they use the `legacy.componentApi` compiler option), and it also ensure we don't need to adjust any other code generation mechanisms in language tools yet - from a language tools perspective, classes are still the norm. But through exposing the default export as being _also_ callable as a function we can in a future Svelte version, where classes/the Svelte 4 syntax are removed completely, seamlessly switch over to using functions in the code generation, too, and the `d.ts` files generated up until that point will support it because of the dual shape. This way we have both backwards and forwards compatibility.
* feat: add rootDir option and set __svelte_meta.file like in svelte4
* Update packages/svelte/src/compiler/validate-options.js
* update tests
* centralise logic
* fix
* note to self
* Apply suggestions from code review
* lint
* one dollar towards the windows backslash bugfix foundation please
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* feat: add $state.is rune
* fix type
* tweak docs
* may as well update the test case to match the docs
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Instead of using types that declare whether or not a type is bindable directly as part of the property, we're introducing a new for-types-only field to `SvelteComponent`: `$$bindings`, which is typed as the keys of the properties that are bindable (string by default, i.e. everything's bindable; for backwards compat). language-tools can then produce code that assigns to this property which results in an error we can display if the binding is invalid
closes#11356
* feat: leave view transition pseudo selectors untouched
view transition pseude selectors are global-like, i.e. they shouldn't be scoped or treated as unused.
In the process of adding support for this, is_root and is_host were consolidated into is_global_like because their usage locations didn't need any differentiation between them (same for the new view transition treatment)
closes#9127
* regenerate types
Provides a migration function, exported as `migrate` from `svelte/compiler`, which tries its best to automatically migrate towards runes, render tags (instead of slots) and event attributes (instead of event handlers)
The preview REPL was updated with a migrate button so people can try it out in the playground.
closes#9239
* fix: mark `accessors` and `immutable` as deprecated
* add warnings for deprecated <svelte:options> attributes
* disable accessors in runes mode
* update tests
* tidy up
* the hell?
* regenerate types
* if I would get a dollar for every windows bug I fix I would be a millionaire by now
* return instance _and_ props in runes mode, move flushSync into shared code, don't set accessors in runes mode
* goddammit
* note breaking change
* fix
* regenerate messages
* Revert "return instance _and_ props in runes mode, move flushSync into shared code, don't set accessors in runes mode"
This reverts commit a47827e57d.
* pass instance to tests
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
This is a typings PR and the companion PR to sveltejs/language-tools#2336
It introduces two new types:
- Binding: Marks a property as being bound (i.e. you must do bind:x)
- Bindable: Marks a property as being able to be bound (i.e. you can do bind:x)
Language tools then uses this generate code accordingly which then generates type errors.
All the other type gymnastics are there to ensure that you don't interact with these bindable types when using mount or hydrate or ComponentProps<MyComponent>, i.e. these two types should be mostly opaque for day-to-day users.
For backwards-compatibility, all properties are automatically wrapped with Bindable, which means existing type definition files will continue to work from a types perspective. Language tools opts into strict bindability by providing its own constructor definition for all generated classes in runes mode which omits the "wrap everything with bindable" behavior.
* fix: fall back to component namespace when not statically determinable
In #10006 we added more elaborate mechanisms to determine which namespace a given element is in. For `<svelte:element>` we added a "can't know at compile time" case and introduced a limited heuristic into the runtime.
This doesn't work for a few reasons:
- we're checking the parent's namespace to determine the current namespace, but the element itself could be the one that _changes_ the namespace
- as mentioned in the previous comment already, on the first render we can't do any parent analysis
- it does not take into account the static component namespace
The last point is the crucial one: In Svelte 4, we're falling back to the component namespace if we can't know statically - e.g. if someone added `<svelte:options namespace="svg">` then `<svelte:element>` should fall back to that namespace instead.
We were not doing that up until now, which introduced a regression. Fixing this also means getting rid of the (flawed) "can't know statically" heuristic.
Fixes#10858, though for a complete solution we likely need some way to tell `<svelte:element>` the namespace at runtime through a special attribute. Maybe we can use `xmlns` for that like we do in the static case
* support dynamic svelte:element namespace through xmlns attribute
* fix
* feat: allow $inspect reactivity map, set, date
* feat: inspect map without adding new data source
* feat: add inspect
* feat: define inspect on dev mode only
* fix: lint error
The character adjustments in the existing warnings are because we remove some tabs from empty lines when initializing the Svelte 5 repo; the warnings were just not checked at that time yet.
- the `component` parameter expects a component constructor type, not an instance type
- use `import('svelte')` instead of relative paths to not inline all types that are already present in the sibiling module declaration