fix(member-live): stop infinite scroll from cascading into loading every page

This commit is contained in:
Simon 2026-07-16 09:39:14 +02:00
parent f847ae10af
commit f2312c24a1
3 changed files with 14 additions and 12 deletions

View file

@ -1024,10 +1024,10 @@ defmodule MvWeb.CoreComponents do
doc:
"when true, first header/body column gets sticky left positioning to keep selection controls visible"
attr :viewport_bottom, :any,
default: nil,
attr :infinite_scroll, :boolean,
default: false,
doc:
"optional phx-viewport-bottom event (string) rendered on the streamed tbody so the built-in InfiniteScroll hook appends the next page without shifting the scroll position; nil omits the binding"
"when true, renders the :footer slot as a full-width infinite-scroll sentinel row (typically only while more pages remain). The caller wires the actual load trigger via a hook in the slot (e.g. an IntersectionObserver sentinel). This component deliberately adds NO phx-viewport-bottom binding: LiveView's built-in InfiniteScroll scrolls the last child of that element into view after each load, which — on a sentinel/loading row — keeps it in view and cascades into loading every page. An IntersectionObserver sentinel has no such side effect."
slot :col, required: true do
attr :label, :string
@ -1265,13 +1265,15 @@ defmodule MvWeb.CoreComponents do
</tr>
</tbody>
<%!-- After-rows footer in its own, non-streamed tbody so it stays put
outside the phx-update="stream" container. When viewport_bottom is set it
doubles as the infinite-scroll sentinel: rendered only while more pages
exist, so once the last page loads it disappears and stops firing. --%>
outside the phx-update="stream" container. When infinite_scroll is set it
holds the load sentinel (a hook lives in the :footer slot): rendered only
while more pages remain, so once the last page loads it disappears and the
sentinel stops firing. No phx-viewport-bottom here on purpose LiveView's
built-in InfiniteScroll would scroll this row into view after each load and
cascade into loading everything. --%>
<tbody
:if={@footer != [] && @viewport_bottom}
:if={@footer != [] && @infinite_scroll}
id={"#{@id}-footer"}
phx-viewport-bottom={@viewport_bottom}
>
<tr>
<td colspan={@col_count}>