feat(member): keep text selection in the overview table from opening the member

This commit is contained in:
Moritz 2026-06-08 12:43:40 +02:00
parent be57dcfce8
commit 24f67bea80
3 changed files with 36 additions and 0 deletions

View file

@ -103,6 +103,29 @@ Hooks.TableRowKeydown = {
}
}
// RowSelectionGuard: distinguish drag-to-select-text from a plain click on the members table.
// LiveView fires the row navigation push (select_row_and_navigate) on any click. When the user
// drags across a cell to select text (e.g. an email to copy) and releases, the mouseup produces a
// non-empty text selection; in that case we swallow the click in the capture phase so navigation is
// suppressed. A plain click leaves the selection collapsed and navigates as before.
Hooks.RowSelectionGuard = {
mounted() {
this.handleClickCapture = (e) => {
const selection = window.getSelection()
if (selection && !selection.isCollapsed && selection.toString().trim() !== "") {
e.preventDefault()
e.stopPropagation()
}
}
// Capture phase so this runs before LiveView's bubbling phx-click handler.
this.el.addEventListener("click", this.handleClickCapture, true)
},
destroyed() {
this.el.removeEventListener("click", this.handleClickCapture, true)
}
}
// FocusRestore hook: WCAG 2.4.3 — when a modal closes, focus returns to the trigger element (e.g. "Delete member" button)
Hooks.FocusRestore = {
mounted() {

View file

@ -82,6 +82,8 @@
<%!-- On desktop (lg:), only the table area scrolls; header and filters stay visible. On mobile, normal flow. --%>
<div
id="members-table-guard"
phx-hook="RowSelectionGuard"
class="lg:max-h-[calc(100vh-14rem)] lg:overflow-auto min-h-0"
data-testid="members-table-scroll"
role="region"

View file

@ -111,6 +111,17 @@ defmodule MvWeb.MemberLive.IndexTest do
end
end
describe "drag-select vs click guard (§3.3)" do
@describetag :ui
test "members table carries the row-selection guard hook", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, ~p"/members")
assert has_element?(view, "[phx-hook=RowSelectionGuard][id=members-table-guard]")
end
end
describe "translations" do
@describetag :ui