dotfiles/app/lib/prymn_web/components/button.ex
2023-11-25 16:49:51 +02:00

105 lines
2.9 KiB
Elixir

defmodule PrymnWeb.Button do
use Phoenix.Component
@doc """
Render a primary variant button.
## Examples
<.primary>Click me</.primary>
<.primary href="/a/path" size="sm">Link button</.primary>
"""
attr :size, :string, default: "md", values: ~w(sm md lg)
attr :class, :string, default: nil
attr :rest, :global, include: ~w(href navigate patch)
slot :inner_block, required: true
def primary(assigns), do: button(assign(assigns, :variant, "primary"))
@doc """
Render a secondary variant button.
## Examples
<.secondary>Click me</.secondary>
<.secondary href="/a/path" size="sm">Link button</.secondary>
"""
attr :size, :string, default: "md", values: ~w(sm md lg)
attr :class, :string, default: nil
attr :rest, :global, include: ~w(href navigate patch)
slot :inner_block, required: true
def secondary(assigns), do: button(assign(assigns, :variant, "secondary"))
@doc """
Render a tertiary variant button.
## Examples
<.tertiary>Click me</.tertiary>
<.tertiary href="/a/path" size="sm">Link button</.tertiary>
"""
def tertiary(assigns), do: button(assign(assigns, :variant, "tertiary"))
@doc """
Render a button.
"""
attr :variant, :string, default: "primary"
attr :size, :string, default: "md", values: ~w(sm md lg)
attr :class, :string, default: nil
attr :rest, :global, include: ~w(href navigate patch)
slot :inner_block, required: true
def button(%{rest: %{href: _}} = assigns), do: link_button(assigns)
def button(%{rest: %{navigate: _}} = assigns), do: link_button(assigns)
def button(%{rest: %{patch: _}} = assigns), do: link_button(assigns)
def button(assigns) do
assigns = button_assigns(assigns)
~H"""
<button class={@style} {@rest}>
<%= render_slot(@inner_block) %>
</button>
"""
end
defp button_assigns(assigns) do
assign(
assigns,
:style,
[
"inline-flex justify-center items-center rounded-2xl transition-colors",
by_variant(assigns.variant),
by_size(assigns.size),
assigns[:class]
]
)
end
defp link_button(assigns) do
assigns = button_assigns(assigns)
~H"""
<Phoenix.Component.link class={@style} {@rest}>
<%= render_slot(@inner_block) %>
</Phoenix.Component.link>
"""
end
defp by_size("sm"), do: "text-sm px-3 py-1"
defp by_size("md"), do: "text-base px-5 py-2"
defp by_size("lg"), do: "text-lg px-7 py-3"
defp by_variant("primary"),
do:
"font-medium bg-black text-white shadow active:shadow-sm hover:bg-slate-800 active:text-white/80"
defp by_variant("secondary"),
do:
"font-medium bg-transparent border shadow active:shadow-sm border-slate-800 text-slate-800 hover:bg-slate-800 hover:text-white active:text-white/80"
defp by_variant("tertiary"),
do:
"font-medium border-none text-black hover:bg-slate-50 focus:bg-slate-50 active:text-black/80"
end