feat: disable email buttons instead hide them

This commit is contained in:
carla 2025-12-15 08:44:24 +01:00
parent 6c38d7455f
commit b0daf8f28c
3 changed files with 33 additions and 13 deletions

View file

@ -95,9 +95,11 @@ defmodule MvWeb.CoreComponents do
<.button>Send!</.button>
<.button phx-click="go" variant="primary">Send!</.button>
<.button navigate={~p"/"}>Home</.button>
<.button disabled={true}>Disabled</.button>
"""
attr :rest, :global, include: ~w(href navigate patch method)
attr :variant, :string, values: ~w(primary)
attr :disabled, :boolean, default: false, doc: "Whether the button is disabled"
slot :inner_block, required: true
def button(%{rest: rest} = assigns) do
@ -105,14 +107,34 @@ defmodule MvWeb.CoreComponents do
assigns = assign(assigns, :class, Map.fetch!(variants, assigns[:variant]))
if rest[:href] || rest[:navigate] || rest[:patch] do
# For links, we can't use disabled attribute, so we use btn-disabled class
# DaisyUI's btn-disabled provides the same styling as :disabled on buttons
link_class =
if assigns[:disabled],
do: ["btn", assigns.class, "btn-disabled"],
else: ["btn", assigns.class]
# Prevent interaction when disabled
link_attrs =
if assigns[:disabled] do
Map.merge(rest, %{tabindex: "-1", "aria-disabled": "true"})
else
rest
end
assigns =
assigns
|> assign(:link_class, link_class)
|> assign(:link_attrs, link_attrs)
~H"""
<.link class={["btn", @class]} {@rest}>
<.link class={@link_class} {@link_attrs}>
{render_slot(@inner_block)}
</.link>
"""
else
~H"""
<button class={["btn", @class]} {@rest}>
<button class={["btn", @class]} disabled={@disabled} {@rest}>
{render_slot(@inner_block)}
</button>
"""

View file

@ -3,23 +3,29 @@
{gettext("Members")}
<:actions>
<.button
:if={Enum.any?(@members, &MapSet.member?(@selected_members, &1.id))}
class="secondary"
id="copy-emails-btn"
phx-hook="CopyToClipboard"
phx-click="copy_emails"
disabled={not Enum.any?(@members, &MapSet.member?(@selected_members, &1.id))}
aria-label={gettext("Copy email addresses of selected members")}
>
<.icon name="hero-clipboard-document" />
{gettext("Copy emails")} ({Enum.count(@members, &MapSet.member?(@selected_members, &1.id))})
{gettext("Copy email addresses")} ({Enum.count(
@members,
&MapSet.member?(@selected_members, &1.id)
)})
</.button>
<.button
:if={Enum.any?(@members, &MapSet.member?(@selected_members, &1.id))}
class="secondary"
id="open-email-btn"
href={
"mailto:?bcc=" <>
(MvWeb.MemberLive.Index.format_selected_member_emails(@members, @selected_members)
|> Enum.join(", ")
|> URI.encode())
}
disabled={not Enum.any?(@members, &MapSet.member?(@selected_members, &1.id))}
aria-label={gettext("Open email program with BCC recipients")}
>
<.icon name="hero-envelope" />

View file

@ -410,14 +410,6 @@ defmodule MvWeb.MemberLive.IndexTest do
assert render(view) =~ "1"
end
test "copy button is not visible when no members are selected", %{conn: conn} do
conn = conn_with_oidc_user(conn)
{:ok, view, _html} = live(conn, "/members")
# Ensure no members are selected (default state)
refute has_element?(view, "#copy-emails-btn")
end
test "copy button is visible when members are selected", %{
conn: conn,
member1: member1