zporter
I have a LiveView page in which I would like to render a stream of items differently depending on viewport size. Currently, I use Tailwind classes like hidden and lg:inline-table to render a <table> on wider viewports and lg:hidden and block to render a list of cards on narrow viewports. In order to render both lists within the same DOM, I need to give each element a unique identifier. This requires me to setup two streams pointed to the same data source and configured to generate DOM identifiers differently: stream(:rows) and stream(:cards).
Using two streams in this way works well until I want to use the InfiniteScroll hook. On LiveView version 0.19.3, using the phx-viewport-bottom attribute on both of the stream elements results in triggering more rows to be added as soon as a scroll action is detected. This is due to the hidden list element’s last child being higher up in the viewport. A small change to the onScroll event handler in the InfiniteScroll hook to exit early if the element is hidden (if (this.el.offsetParent === null) { return };) fixes the scroll behavior for the page and items aren’t loaded until the last child of the visible element is on the screen.
Have others run into similar issues? Does the proposed solution make sense or should I be considering other options? I’m happy to open a Pull Request with the aforementioned change, but I wanted to solicit ideas here first. Thank you!
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #blog-post
- #ai
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 2- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
jason.o
I know this is an old post but I am implementing something very similar, and my solution is basically rendering the table or the card view depending on the screen size. (e.g., <table :if={@screen_layout == :desktop} />) It’s not perfect, but works decently.
byhemechi
Just for anyone landing on this thread from search i figured i’d put this here
Instead of using phx-viewport-bottom you could use an Intersection Observer positioned after the streamed elements.
What I usually do is create a custom element that “clicks” a child button once it is in view. Here’s an example of how that could be implemented
Alternatively, you could make a hook which you apply to a div or something.
I prefer the wrapper method as it makes loading state much simpler, you just use the built in phx attributes