refactor(web): share member-dropdown keyboard navigation between LiveViews

This commit is contained in:
Moritz 2026-06-16 15:03:05 +02:00 committed by moritz
parent 164826d3aa
commit 561779e704
3 changed files with 89 additions and 119 deletions

View file

@ -23,6 +23,7 @@ defmodule MvWeb.GroupLive.Show do
alias Mv.Membership
alias MvWeb.Helpers.MemberHelpers, as: MemberHelpers
alias MvWeb.Live.MemberDropdownNav
@impl true
def mount(_params, _session, socket) do
@ -566,56 +567,8 @@ defmodule MvWeb.GroupLive.Show do
end
@impl true
def handle_event("member_dropdown_keydown", %{"key" => "ArrowDown"}, socket) do
return_if_dropdown_closed(socket, fn ->
max_index = length(socket.assigns.available_members) - 1
current = socket.assigns.focused_member_index
new_index =
case current do
nil -> 0
index when index < max_index -> index + 1
_ -> current
end
{:noreply, assign(socket, focused_member_index: new_index)}
end)
end
@impl true
def handle_event("member_dropdown_keydown", %{"key" => "ArrowUp"}, socket) do
return_if_dropdown_closed(socket, fn ->
current = socket.assigns.focused_member_index
new_index =
case current do
nil -> 0
0 -> 0
index -> index - 1
end
{:noreply, assign(socket, focused_member_index: new_index)}
end)
end
@impl true
def handle_event("member_dropdown_keydown", %{"key" => "Enter"}, socket) do
return_if_dropdown_closed(socket, fn ->
select_focused_member(socket)
end)
end
@impl true
def handle_event("member_dropdown_keydown", %{"key" => "Escape"}, socket) do
return_if_dropdown_closed(socket, fn ->
{:noreply, assign(socket, show_member_dropdown: false, focused_member_index: nil)}
end)
end
@impl true
def handle_event("member_dropdown_keydown", _params, socket) do
# Ignore other keys
{:noreply, socket}
def handle_event("member_dropdown_keydown", params, socket) do
MemberDropdownNav.handle_keydown(params, socket, fn -> select_focused_member(socket) end)
end
@impl true
@ -705,14 +658,6 @@ defmodule MvWeb.GroupLive.Show do
end
# Helper functions
defp return_if_dropdown_closed(socket, fun) do
if socket.assigns.show_member_dropdown do
fun.()
else
{:noreply, socket}
end
end
defp select_focused_member(socket) do
case socket.assigns.focused_member_index do
nil ->