Open SteffenDE opened 1 month ago
Hey @SteffenDE,
I think this is a worthy addition, even with the upcoming Dialog API. Even though the Dialog API usage is already at 95%, there are use cases where a portal is needed outside of a dialog usage, anything that we need to break out of its container layout.
Now, my only doubt is if this should be user-land, but I would be perfectly happy to have it built-in. :)
I would love this to simplify "forms within forms". Say for instance you have a multi-select component in a form and you want to be able to create options from within the component using another predeclared form (which is our use case). Would this work for that? That's at least how we used Vue Teleport before migrating to Live View.
will be great to have this in 1.0 release. This is very necessary feature with which modals can finally will be live! :)
Don't expect to see this in the upcoming 1.0 - maybe we can add it in a later release, but that's up to @chrismccord.
@SteffenDE it is a very useful feature which is exists in most of SPA frameworks. That why i want to see it here. But anyway i want to see 1.0 with or without it :) So many years without a release. Let it be as is but quicker :)
I think given that container-queries are becoming more popular (https://github.com/tailwindlabs/tailwindcss-container-queries), and will be shipped with Tailwind 4 (https://tailwindcss.com/blog/tailwindcss-v4-alpha#designed-for-the-modern-web), this is something that will become increasingly useful.
Also, imagine you have a dropdown menu in a header with a fix height. It's non-trivial to make it work without changing a lot of CSS positioning on the dropdown (that you might not want to just for this particular cases) without a portal.
I actually implemented a Portal like solution in a project of mine, but it's not DOM patch aware. :P
@chrismccord please push it :) any problems can be fixed in 1.0.1 :) Anyway 1.0 we don't know when will be released
If anyone wants to help out here: try building something with phx-portal, you can use this in your mix.exs
:
{:phoenix_live_view, github: "phoenixframework/phoenix_live_view", branch: "sd-phx-portal-assets", override: true}
and report any problems you find. This is very much a proof of concept and needs some exploration with real world and possibly complex use cases.
I wanted to add my 2 use-cases:
Rendering page navigation in root layout. If we do it (eg to optimize the payload on "navigate"), that part can't be updated other than by using JS. Having portals would allow to selectively update parts of the root layout without the need to send it as a whole.
I'm an author of LiveVue, a library bridging LiveView and Vue. There's one unsolved challenge related to slots. Currently we support passing slots from Phoenix LiveView to Vue, but it's a hack - I'm rendering slot content on a server and sending it over the wire. So it's not using optimized diffs, hooks are not evaluated etc. In particular, it makes it impossible to nest LiveVue component inside LiveVue component https://github.com/Valian/live_vue/issues/14 because LiveVue components are initialized using Hooks:
~H"""
<.vue v-component="Card">
<!-- this is a slot. It's rendered on the server side, but Vue won't be initialized in nested -->
<.vue v-component="Counter">
</.vue>
"""
I have a feeling having portals would make it possible - I could "teleport" each slot to a hidden element somewhere in DOM, and on update sync it with Vue slot content. The only alternative is to patch phoenix JS library to have more control when and how HTML diff is applied, but it would be tricky 😅
This is a proof of concept PR implementing a new phx binding called
phx-portal
. This binding allows to designate an element to be rendered at another location in the DOM, designated by the ID thatphx-portal
points to. This can be useful to render things like dialogs at the top layer, outside any containers that might affect their rendering (e.g. overflow: hidden).Nowadays there is also the Popover API and native
<dialog>
elements, so this might not be that important any more.Because of this, I also don't feel like this is something we really want to support. This PR only shows how it could be implemented.