portal-vue
portal-vue copied to clipboard
Can't portal content from svg
https://codesandbox.io/s/strange-keldysh-7pwk1
I expect to window appears, but it's not.
If I move <component :is="Second"></component>
outside the svg tag, everything is ok then.
Well, the portal content is moved to the portal-target:
As I'm not familiar with that window library that you are using, someone would have to guide me about why the dom is there but the window is not showing.
If that info can be provided we can judge wether/how this is related to portal-vue
Edit: this seems to be related: #287
Hello! Thank you for your time. I make it simpler and it doesn't work either, so as I see you've mentioned that #287 issue, guess that problem is the same as mine.
https://codesandbox.io/s/beautiful-bogdan-gucj4
https://codesandbox.io/s/ecstatic-mclaren-u45lb
Even more simpler: with no component tag.
I've got another interesting stuff. If I add anything in body tag using Chrome devtools, then ported content shows up.
https://youtu.be/TxL5olpWqT4
Okay, this is getting weirder by the minute 🧐
Maybe a Chrome bug? Need to test other browsers...
I've already tested in Firefox. The same result.
Weird. Just - weird.
May it be a Vue bug?
I remove portal-vue and just leave div inside svg in vue applcation. Div is invisible. https://codesandbox.io/s/prod-violet-4f5be
Dynamically create the same html with no Vue using. Div is visible. https://codesandbox.io/s/jovial-violet-qbok9
Getting this issue as well. Static content in the SVG portaled outside of it works fine. Static content inside a transition-group
(?) causes the :not(svg)
CSS condition to be permanently applied to the element. Dynamic content shows up in the devtools but isn't visible unless I "Edit HTML", then it shows up but isn't bound to the VM anymore (presumably because it's a new/different Element object).
It seems that Vue's h()
is aware that it's curently in an SVG element and thus creates the HTML elements differently before they are portaled to outside of the SVG. There, the browser gets a hickup as the element looks like it belongs inside of an SVG,but it isn't - and after being nudged to update the page, the browser "realizes" that it's actually a normal HTML element.
I can't tell wether this is a browser bug, Vue bug or portal-vue issue, and have no idea how it could be fixed.
Will rate this a wontfix caveat.
Although this issue is already closed, I'd like to add another finding:
This code works perfectly fine. It even works if the portal is nested into several <g>
-elements
<div>
<portal-target
multiple
name="tooltips"
/>
<svg>
<portal
to="tooltips"
>
<div>ported</div>
</portal>
</svg>
</div>
But as soon as I put the portal inside a component, the teleported content exists in the DOM but is not shown anymore.
<div>
<portal-target
multiple
name="tooltips"
/>
<svg>
<PortalSource />
</svg>
</div>
// PortalSource.vue
<template>
<portal
to="tooltips"
>
<div>ported</div>
</portal>
</tempate>
I suggest it to be a portal-vue or vue issue
I have the same problem. I am trying to port several things out of an SVG into HTML. The problem is, that the ported element is in the SVG namespace and not HTML namespace. Since div-tags are not SVG elements, it doesn't know how to handle these.
This is an issue with portal-vue which has to make sure that the namespace of its members is fixed depending on where the portal is mounted. That means, that porting SVG elements into HTML needs to fix the namespace to HTML EXCEPT for the <svg>
tag itself which is recognized by browsers as SVG and establishes a new namespace by itself. Fixing it would do no harm tho. HTML ported from SVG to HTML needs to be fixed the other way round.
The hack I tried and worked is:
<svg>
...
<Portal to="target">
<svg width="100%" height="100%">
<foreignObject width="100%" height="100%">
...html content
</foreignObject>
</svg>
</Portal>
</svg>
@LinusBorg it turned out that vue 3 with Teleport can handle that in case the Teleport component is wrapped into a foreignObject-tag. Unfortunately, this does not work in portal-vue. However, if Teleport can do it, Portal should also be able to do it. Do you think this could be fixed?
I may find some time to look into it but my impression so far is that this would require a change in Vue 2 core.