-
Notifications
You must be signed in to change notification settings - Fork 949
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
proof of concept: phx-portal #3478
base: main
Are you sure you want to change the base?
Conversation
843df76
to
2e49ff4
Compare
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 |
2e49ff4
to
af851c4
Compare
If anyone wants to help out here: try building something with phx-portal, you can use this in your
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:
~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 😅 |
Thanks @SteffenDE. This will beautifully address the issues I had trying to implement a portal with dynamic hooks over here: #2563. Thanks for your hard work, this is extremely useful 👍 |
Will this in a sense address this issue #2586? |
Hey @SteffenDE, I've tested this today in my app, seems to be all working fine! |
Seconding this. |
Sadly, this solution doesn't allow us to teleport nested form tags without issues, as browsers see a nested tag and kill it before JS has a chance to unnest it. I still think the portals will be useful - you may render the child form separately and teleport some inputs back to the parent form. In a way this is another mechanism for component interaction without sending messages. |
@a3kov thank you very much for testing the form usecase! This is very helpful input. I think if we want to support something like this (portals), they should be able to solve those issues as well. I do have an idea to make it work, but this will require some more work. |
I think server-side portals would be a cleaner solution. We could have a |
@SteffenDE By the way has there been any discussion on implementing component communication without sending actual messages ? If I understand correctly, right now rendering with updates is not atomic, i.e. if I render a button that is interacting with a modal by sending an update to the modal component, there's a moment when client sees the button but not the modal. This is relevant to the idea of server-side portals, as if I were to implement such feature, I would not want the client to see the inconsistent state where content has entered the portal but hasn't exited yet. |
I tried to implement server-side portal in my own project, but then realized it would be very inefficient as I would need to copy the assigns to the portal exit. This feature should be implemented inside LiveView, as it has access to all component assigns and can simply render teleported content without copying assigns. @SteffenDE I think server side portals will be strictly superior to the client-side one, as server can do the same job efficiently without an additional load to the browser (hence why we are doing SSR in the first place), and browser will never see invalid initial state. You could even use the portals for dead views as content would be valid straight from the beginning, even search engines would see the content already teleported to new positions. |
This is a proof of concept commit 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 that `phx-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 commit only shows how it could be implemented.
f782342
to
6595457
Compare
6595457
to
87f39dd
Compare
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.