-
-
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
fix: deduplicate children prop from default slot #10800
Conversation
🦋 Changeset detectedLatest commit: 1bdf919 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
I'm still 👎 on exposing this publicly, at least until there's evidence of significant demand. I think it just encourages bad API design. |
This looks good to me, but I don't have the full context, so will defer to @Rich-Harris |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having spent time understanding this, this looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to hold off on this until we have some clarity around #10678 (comment)
How does this relate to this PR? What would need to change? In general, programmatic slots (now snippets) are one of the most requested features, and have been the source of many "hacking into internals" workarounds, so a solution for it would be great |
If we had an API for programmatically creating snippets, then either we need to design that API in such a way that the symbol is still present, or we need to come up with some other approach. In a client-side context the ideal API is something close to this: mount(App, {
target,
props: {
mySnippet: (firstname, lastname) {
const element = document.createElement('h1');
$effect.pre(() => {
element.textContent = `Hello ${firstname()} ${lastname()}!`;
});
return element;
}
}
}); In an SSR context that doesn't work, but perhaps that's just something the user needs to deal with: render(App, {
props: {
mySnippet: (firstname, lastname) {
return `<h1>Hello ${firstname()} ${lastname()}!</h1>`;
}
}
}); |
This sounds like we should expose a |
Brought this up to date and changed the approach so that we don't need the symbol anymore. Instead, we pass |
It's rare, but some components may have a
children
attribute and receive a default slot content. We previously had undefined behavior in this case, with this PR we're now putting the implicit default content into$$slots.default
if we detect there's also achildren
prop - fixes #10790.In order to do we need to detect at runtime whether or not a given value is a snippet at runtime, so I moved the "apply snippet symbol" function out of dev and am applying it everytime now.
As a consequence, we can also provide a user-facing function,update: removed for now.isSnippet
, which will help people detect this - part of #9774This is mostly done, the reason this is in draft mode is because
dts-buddy
is not creating the correct types. It's inlining theSnippet
type on the return of theisSnippet
function, but that's wrong because of the unique symbol, meaning the return type ofisSnippet
and theSnippet
type are separate. This will throw a wrong type error:The snippet type is also inlined in
svelte/legacy
, and it would be better if it instead would do something likeimport('svelte').Snippet
. I'm not sure if this is really fixable indts-buddy
(unless you have a good idea @Rich-Harris), so my idea for tomorrow is to have some pre and postprocessing applied on thed.ts
file generation to get the desired end result.Update: No longer relevant when not exposing the type, but it will get relevant at some point. I think this requires some dts-buddy hackery, I actually think that TypeScript's doing something wrong here, because it inlines a type that cannot be inlined.
Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.Tests and linting
pnpm test
and lint the project withpnpm lint