refactor: cleanup dropdown_menu component (required attr, remove redundant defaults, fix checkbox)

This commit is contained in:
Moritz 2025-12-03 18:42:49 +01:00
parent 6cf955b024
commit 6029920c3f
2 changed files with 10 additions and 51 deletions

View file

@ -124,7 +124,7 @@ defmodule MvWeb.CoreComponents do
## Examples
<.dropdown_menu items={@items} open={@open} phx-target={@myself} />
<.dropdown_menu items={@items} open={@open} phx_target={@myself} />
"""
attr :id, :string, default: "dropdown-menu"
attr :items, :list, required: true, doc: "List of %{label: string, value: any} maps"
@ -134,24 +134,9 @@ defmodule MvWeb.CoreComponents do
attr :selected, :map, default: %{}
attr :open, :boolean, default: false, doc: "Whether the dropdown is open"
attr :show_select_buttons, :boolean, default: false, doc: "Show select all/none buttons"
attr :phx_target, :any, default: nil
attr :phx_target, :any, required: true, doc: "The LiveView/LiveComponent target for events"
def dropdown_menu(assigns) do
unless Map.has_key?(assigns, :phx_target) do
raise ArgumentError, ":phx_target is required in dropdown_menu/1"
end
assigns =
assign_new(assigns, :items, fn -> [] end)
|> assign_new(:button_label, fn -> "Dropdown" end)
|> assign_new(:icon, fn -> nil end)
|> assign_new(:checkboxes, fn -> false end)
|> assign_new(:selected, fn -> %{} end)
|> assign_new(:open, fn -> false end)
|> assign_new(:show_select_buttons, fn -> false end)
|> assign(:phx_target, assigns.phx_target)
|> assign_new(:id, fn -> "dropdown-menu" end)
~H"""
<div
class="relative"
@ -229,18 +214,18 @@ defmodule MvWeb.CoreComponents do
class="flex items-center gap-2 px-2 py-1 rounded cursor-pointer hover:bg-base-200 w-full text-left"
phx-click="select_item"
phx-keydown="select_item"
phx-key="Enter Space"
phx-key="Enter"
phx-value-item={item.value}
phx-target={@phx_target}
>
<%= if @checkboxes do %>
<span
role="presentation"
<input
type="checkbox"
checked={Map.get(@selected, item.value, true)}
class="checkbox checkbox-sm checkbox-primary"
tabindex="-1"
aria-hidden="true"
class="checkbox checkbox-sm"
aria-checked={if Map.get(@selected, item.value, true), do: "true", else: "false"}
>
</span>
/>
<% end %>
<span>{item.label}</span>
</button>

View file

@ -420,7 +420,7 @@ defmodule MvWeb.MemberLive.IndexFieldVisibilityTest do
assert html =~ ~s(tabindex="0")
# Check that keyboard events are supported
assert html =~ ~s(phx-keydown="select_item")
assert html =~ ~s(phx-key="Enter Space")
assert html =~ ~s(phx-key="Enter")
end
test "keyboard activation with Enter key works", %{conn: conn} do
@ -448,31 +448,5 @@ defmodule MvWeb.MemberLive.IndexFieldVisibilityTest do
html = render(view)
refute html =~ "alice@example.com"
end
test "keyboard activation with Space key works", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# Verify email is visible initially
html = render(view)
assert html =~ "alice@example.com"
# Open dropdown
view
|> element("button[aria-controls='field-visibility-menu']")
|> render_click()
# Simulate Space key press on email field button
view
|> element("button[phx-click='select_item'][phx-value-item='email']")
|> render_keydown(%{key: " "})
# Wait for update
:timer.sleep(100)
# Email should no longer be visible
html = render(view)
refute html =~ "alice@example.com"
end
end
end