Packages
moon
2.87.2
2.90.5
retired
2.90.4
2.90.3
2.90.2
2.90.1
2.90.0
2.89.4
2.89.1
2.89.0
2.88.0
2.87.11
2.87.10
2.87.9
2.87.8
2.87.7
2.87.6
2.87.5
2.87.4
2.87.3
2.87.2
2.87.1
2.87.0
2.86.1
2.86.0
2.85.1
2.85.0
2.84.0
2.83.0
2.82.0
2.81.4
2.81.3
2.81.2
2.81.1
2.81.0
2.80.2
2.80.1
2.80.0
2.79.13
2.79.12
2.79.11
2.79.10
2.79.9
2.79.8
2.79.7
2.79.6
2.79.5
2.79.4
2.79.3
2.79.2
2.79.1
2.79.0
2.78.4
2.78.3
2.78.2
2.78.1
2.78.0
2.77.0
2.76.5
2.76.4
2.76.3
2.76.2
2.76.1
2.76.0
2.75.0
2.74.1
2.74.0
2.73.8
2.73.7
2.73.6
2.73.5
2.73.4
2.73.3
2.73.2
2.73.1
2.73.0
2.72.5
2.72.4
2.72.3
2.72.2
2.72.1
2.72.0
2.71.1
2.71.0
2.70.0
2.69.2
2.69.1
2.69.0
2.68.11
2.68.10
Components-based design system written in elixir
Current section
Files
Jump to
Current section
Files
lib/moon/design/button.ex
defmodule Moon.Design.Button do
@moduledoc false
use Moon.StatelessComponent
use Moon.Design.Button.Properties
alias Moon.Components.AsComponent
alias Moon.Design.Button.Utils
alias Moon.Icon
alias Moon.Design.Loader
def render(assigns) do
~F"""
<AsComponent
{=@as}
{=@href}
{=@id}
class={merge([
[
"flex row justify-center items-center relative overflow-hidden active:scale-90 transition-all duration-200 font-semibold group z-0",
"whitespace-nowrap select-none",
Utils.get_button_size_classes(@size),
Utils.variant_classes(assigns),
Utils.animation_classes(assigns),
"#{Utils.get_no_icon_padding(@size)}": !@right_icon && !@left_icon,
"#{Utils.get_right_icon_paddings(@size)}": @right_icon && !@full_width,
"#{Utils.get_left_icon_paddings(@size)}": @left_icon && !@full_width,
"#{Utils.get_full_width_padding(@size)}": @full_width,
"w-full": @full_width
],
@class
])}
on_click={@on_click}
testid={@testid}
{=@aria_label}
{=@values}
{=@value}
{=@target}
{=@rel}
attrs={[
disabled: @disabled,
type: @type,
form: @form,
"data-size": @size
] ++ @attrs}
>
{#if @animation}
{animation_content(assigns)}
<span class={"flex gap-2 items-center", "opacity-0": @animation in ["success", "progress"]}>
{content(assigns)}
</span>
{#else}
{content(assigns)}
{/if}
<span class={merge(Utils.hover_overlay_classes(assigns) ++ [@hover_bg_class])} />
</AsComponent>
"""
end
defp animation_content(assigns) do
~F"""
<span
:if={@animation in ["success", "progress"]}
class="flex absolute top-1/2 left-1/2 translate-y-[-50%] translate-x-[-50%] content-center justify-center"
>
{#if @animation == "progress"}
<Loader
color={if @variant in ["primary", "fill", "tertiary"], do: "gohan", else: "trunks"}
size={if @size == "xs", do: "2xs", else: "xs"}
/>
{#elseif @animation == "success"}
<Icon name="generic_check_alternative" color="currentColor" class={Utils.icon_class(@size)} />
{/if}
</span>
"""
end
defp content(assigns) do
~F"""
{#if slot_assigned?(:left_icon_slot)}
<#slot {@left_icon_slot} />
{#else}
<Icon
name={@left_icon}
class={
Utils.icon_class(@size),
"#{Utils.left_icon_horizontal_position(@size)}": @full_width
}
:if={@left_icon}
/>
{/if}
<#slot />
{#if slot_assigned?(:right_icon_slot)}
<#slot {@right_icon_slot} />
{#else}
<Icon
name={@right_icon}
class={
Utils.icon_class(@size),
"#{Utils.right_icon_horizontal_position(@size)}": @full_width
}
:if={@right_icon}
/>
{/if}
"""
end
end