-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
feat: allow dom elements as svelte:element
this
attribute
#15477
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
Conversation
🦋 Changeset detectedLatest commit: 7903a35 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 |
Some thoughts by @dominikg
And my answer As I've said in the pr (I think) it currently acts as It's more interesting the other cases: technically if it's from a different part of the dom It would move here, and then append to it which is an interesting but probably too confusing behavior. The same is true for something obtained through The name is an interesting question too although the above possible source of confusion make me question the feature all together We could however add runtime validation to only accept nodes that are not already connected. |
I think thats a very good idea, and if you really wanted to "move" something, you could pull it out of the DOM before targeting it.
Could also be named after mount's target option, like |
I've added the runtime validation...still a bit unsure about the feature however. But it could help integrating libraries with svelte which is something I like. |
Hi, I also think it would be better to have a distinct name : This would allow us to have something like this, which would be completely ignored during SSR (apart from any hydration marker) <svelte:attach this={createElement()} /> And it could event be better if he could accept promises, since some libraries need to be dynamically loaded only on client side to avoid errors on server : async function createElement() {
const lib = await import("...);
return lib.createElement();
} |
Technically you could do something like <svelte:element this={browser ? div : "div"} /> To have it SSR...dunno if there's a use case for that tho. I'm not super worried about the promise thing because you will likely load that in an effect/on mount and assign to a variable and this would be the first case where we await something for the user I think |
Looking at the original problem: <script>
let { ...rest } = $props();
const view = new EditorView({
doc: value,
});
let wrapper;
onMount(() => {
wrapper.appendChild(view.dom)
})
</script>
<!--
How can we reactively apply `...rest` attributes
to the `view.dom` parent and not this wrapper?
-->
<div class="wrapper" bind:this={wrapper} {...rest}></div> This is solvable in userland by using an $effect.pre(() => {
if (editorAttributes === undefined || editorAttributes === {}) return
const attributes = Object.entries(editorAttributes)
if (attributes.length === 0) return
Object.entries(editorAttributes).forEach(([key, val]) => {
view.dom.setAttribute(key, val)
})
}) Demo: https://svelte.dev/playground/236b091b6e0647bbab1ae9404526d145?version=5.22.6 I am also concerned about allowing I prefer using |
To be frank, no, this doesn't solve the issue. What the proposal suggests is currently impossible:
Your solution suffers from the same problem that prompted me to make proposal: You're forced to have a wrapper element, and potentially sync props, which has its own set of problems. From the issue:
So far we've mostly agreed that this feature could be pretty useful under the right circumstances and I'd be happy to expand on workarounds in the issue, but I'd keep the topic of this PR to issues with the proposal itself. I get your concerns about |
<svelte:element bind:this={node} class="foo" style="color:red"/> will override classes and styling set by the library, won't it? Having a node controlled by both Svelte and 3rd-party library at the same time doesn't sound good. This is why libraries accept a |
Mh yeah this is another drawback...I'm less and less inclined to consider this feature request...it has some niceties but it also has a bunch of quirks which would be difficult to document. |
I don't think it's a problem. Of course, if we use an external library, it should be used according to how it was designed. After all, this : <svelte:element bind:this={node} class="foo" style="color:red"/> is nothing but an equivalent to this code : node.className = "foo";
node.style.cssText = "color: red"; So, if you have a node, you can already do that... |
I agree. Without trying to strawman the argument, it's kinda similar to disallowing If CodeMirror did in fact expose a host option and I used that instead, I'd have to be aware of the exact same quirks, except the component would be much less readable (because |
I really don't think we should add this. Not only because of the SSR issue and the ambiguity over child content, but because the motivating use case is for a single element to be controlled by two separate systems, which is a recipe for unnecessary confusion. To me this seems like a perfect use case for attachments (or, in today's world, actions). It means you need a wrapper element but that's a good thing, because responsibilities are clearly delineated. |
I'm much more concerned about SSR and ambiguity...the reason today you need a wrapper element is because of code mirror not because of svelte: if code mirror accepted a host instead of a parent actions/attachments would suffer the same "problem" |
And I would bet good money that that's why CodeMirror doesn't accept a host element — because it's a bad idea! Marijn would spend half his time responding to bugs caused by declarative frameworks nuking stuff CodeMirror needs to control. Adding an API specifically to work around that healthy separation will only cause problems. In my view any of the three issues (SSR, child content, split control) would be a good reason not to add this API. |
Agree on this...I was surprised by the flexibility it allowed initially but this feels niche and risky enough so I'm in favor of closing it |
Closes #15475
I think overall is a reasonable request, and it could be useful to allow for even more integration with the JS ecosystem. I can't really think of a downside except that maybe could be a bit weird if you have children AND pass an html element with childrens.
It still needs
language-tools
to allow for the new type (i think)Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.packages/svelte/src
, add a changeset (npx changeset
).Tests and linting
pnpm test
and lint the project withpnpm lint