Button

Interactive button component with various styles

Preview

Props Editor

✅ JSON is valid - Click "Preview Update" to see changes

Source Code

defmodule FeenixUiWeb.Components.ButtonComponent do
  use Phoenix.Component

  def render(assigns) do
    assigns = assign_new(assigns, :variant, fn -> "primary" end)
    assigns = assign_new(assigns, :size, fn -> "md" end)
    assigns = assign_new(assigns, :disabled, fn -> false end)
    assigns = assign_new(assigns, :text, fn -> "Button" end)

    assigns = assign(assigns, :button_classes, get_button_classes(assigns.variant, assigns.size, assigns.disabled))

    ~H"""
    <button class={@button_classes} disabled={@disabled}>
      <%= @text %>
    </button>
    """
  end

  defp get_button_classes(variant, size, disabled) do
    base_classes = "inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2"

    variant_classes = case variant do
      "primary" -> "bg-primary-600 text-white hover:bg-primary-700 focus:ring-primary-500"
      "secondary" -> "bg-secondary-600 text-white hover:bg-secondary-700 focus:ring-secondary-500"
      "success" -> "bg-success-600 text-white hover:bg-success-700 focus:ring-success-500"
      "warning" -> "bg-warning-600 text-white hover:bg-warning-700 focus:ring-warning-500"
      "danger" -> "bg-danger-600 text-white hover:bg-danger-700 focus:ring-danger-500"
      "info" -> "bg-info-600 text-white hover:bg-info-700 focus:ring-info-500"
      "outline" -> "border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-primary-500"
      "ghost" -> "text-gray-700 hover:bg-gray-100 focus:ring-gray-500"
      _ -> "bg-primary-600 text-white hover:bg-primary-700 focus:ring-primary-500"
    end

    size_classes = case size do
      "xs" -> "px-2.5 py-1.5 text-xs"
      "sm" -> "px-3 py-2 text-sm"
      "md" -> "px-4 py-2 text-sm"
      "lg" -> "px-6 py-3 text-base"
      "xl" -> "px-8 py-4 text-lg"
      _ -> "px-4 py-2 text-sm"
    end

    disabled_classes = if disabled, do: "opacity-50 cursor-not-allowed", else: ""

    [base_classes, variant_classes, size_classes, disabled_classes]
    |> Enum.filter(&(&1 != ""))
    |> Enum.join(" ")
  end
end