defmodule PetalComponents.Button do use Phoenix.Component def button(assigns) do assigns = get_extra_attributes(assigns) ~H""" """ end def a(assigns) do assigns = get_extra_attributes(assigns) ~H""" <%= if assigns[:loading] do %> <% end %> <%= if assigns[:inner_block] do %> <%= render_slot(@inner_block) %> <% else %> <%= @label %> <% end %> """ end def patch(assigns) do assigns = get_extra_attributes(assigns) ~H""" <%= live_patch [ to: @href, class: button_classes(assigns), onclick: (if assigns[:disabled] || assigns[:loading], do: "return false;", else: nil) ] ++ Map.to_list(assigns.extra_attributes) do %> <%= if assigns[:loading] do %> <% end %> <%= if assigns[:inner_block] do %> <%= render_slot(@inner_block) %> <% else %> <%= @label %> <% end %> <% end %> """ end def redirect(assigns) do assigns = get_extra_attributes(assigns) ~H""" <%= live_redirect [ to: @href, class: button_classes(assigns), onclick: (if assigns[:disabled] || assigns[:loading], do: "return false;", else: nil) ] ++ Map.to_list(assigns.extra_attributes) do %> <%= if assigns[:loading] do %> <% end %> <%= if assigns[:inner_block] do %> <%= render_slot(@inner_block) %> <% else %> <%= @label %> <% end %> <% end %> """ end def button_classes(opts \\ %{}) do opts = %{ size: opts[:size] || "md", variant: opts[:variant] || "solid", color: opts[:color] || "primary", loading: opts[:loading] || false, disabled: opts[:disabled] || false, icon: opts[:icon] || false } color_css = get_color_classes(opts) size_css = case opts[:size] do "xs" -> "text-xs leading-4 px-2.5 py-1.5" "sm" -> "text-sm leading-4 px-3 py-2" "md" -> "text-sm leading-5 px-4 py-2" "lg" -> "text-base leading-6 px-4 py-2" "xl" -> "text-base leading-6 px-6 py-3" end loading_css = if opts[:loading] do "flex gap-2 items-center whitespace-nowrap disabled cursor-not-allowed" else "" end disabled_css = if opts[:disabled] do "disabled cursor-not-allowed opacity-50" else "" end icon_css = if opts[:icon] do "flex gap-2 items-center whitespace-nowrap" else "" end """ #{color_css} #{size_css} #{loading_css} #{disabled_css} #{icon_css} font-medium shadow-sm rounded-md inline-flex items-center justify-center border focus:outline-none transition duration-150 ease-in-out """ end def get_extra_attributes(assigns) do assign_new(assigns, :extra_attributes, fn -> Map.drop(assigns, [ :loading, :disabled, :inner_block, :size, :variant, :color, :icon ]) end) end def get_color_classes(%{color: "primary", variant: variant}) do case variant do "outline" -> "border-primary-400 hover:border-primary-600 text-primary-600 hover:text-primary-700 active:bg-primary-200 hover:bg-primary-50 focus:border-primary-700 focus:shadow-outline-primary" _ -> "border-transparent text-white bg-primary-600 active:bg-primary-700 hover:bg-primary-700 focus:bg-primary-700 active:bg-primary-800 focus:shadow-outline-primary" end end def get_color_classes(%{color: "secondary", variant: variant}) do case variant do "outline" -> "border-secondary-400 hover:border-secondary-600 text-secondary-600 hover:text-secondary-700 active:bg-secondary-200 hover:bg-secondary-50 focus:border-secondary-700 focus:shadow-outline-secondary" _ -> "border-transparent text-white bg-secondary-600 active:bg-secondary-700 hover:bg-secondary-700 focus:bg-secondary-700 active:bg-secondary-800 focus:shadow-outline-secondary" end end def get_color_classes(%{color: "white", variant: variant}) do case variant do "outline" -> "border-gray-400 hover:border-gray-500 text-gray-600 hover:text-gray-700 active:bg-gray-100 hover:bg-gray-50 focus:bg-gray-50 focus:border-gray-500 active:border-gray-600" _ -> "text-gray-700 border-gray-300 hover:text-gray-900 hover:text-gray-900 hover:border-gray-400 hover:bg-gray-50 focus:outline-none focus:border-gray-400 focus:bg-gray-100 focus:text-gray-900 active:border-gray-400 active:bg-gray-200 active:text-black" end end def get_color_classes(%{color: "success", variant: variant}) do case variant do "outline" -> "border-green-400 hover:border-green-500 text-green-500 hover:text-green-600 active:border-green-600 focus:text-green-600 active:text-green-700 active:bg-green-100 hover:bg-green-50 focus:border-green-500" _ -> "border-transparent text-white bg-green-500 active:bg-green-700 hover:bg-green-600 active:bg-green-700 focus:bg-green-600" end end def get_color_classes(%{color: "danger", variant: variant}) do case variant do "outline" -> "border-red-400 hover:border-red-600 text-red-600 hover:text-red-700 active:bg-red-200 active:border-red-700 hover:bg-red-50 focus:border-red-600" _ -> "border-transparent text-white bg-red-500 active:bg-red-700 hover:bg-red-600 active:bg-green-700 focus:bg-red-600" end end end