defmodule PineUi.Button do @moduledoc """ Provides button components with various styles and states. The Button module offers primary, secondary, and danger button variants with support for loading states, icons, and Phoenix LiveView integration. ## Examples Submit Cancel Delete ## Accessibility All button components provide proper focus states, ARIA attributes, and keyboard interaction support. """ use Phoenix.Component import Phoenix.HTML # This is needed for HTML markup import Phoenix.HTML.Form # This is needed for form elements @doc """ Renders a primary button component with optional loading state. ## Examples <.primary>Submit <.primary loading={true} phx_click="save" disabled={@form_invalid}> Save Changes <.primary icon="..."> With Icon ## Options * `:type` - Button type attribute (optional, defaults to "button") * `:class` - Additional CSS classes (optional) * `:disabled` - Whether the button is disabled (optional, defaults to false) * `:loading` - Whether to show loading state (optional, defaults to false) * `:icon` - HTML string for an icon to display before text (optional) * `:phx_click` - The LiveView click event to trigger (optional) * `:phx_value_id` - The id value to pass with the event (optional) * `:phx_target` - The LiveView target for the event (optional) """ def primary(assigns) do assigns = assigns |> assign_new(:type, fn -> "button" end) |> assign_new(:class, fn -> "" end) |> assign_new(:disabled, fn -> false end) |> assign_new(:loading, fn -> false end) |> assign_new(:phx_click, fn -> nil end) |> assign_new(:phx_value_id, fn -> nil end) |> assign_new(:phx_target, fn -> nil end) |> assign_new(:icon, fn -> nil end) ~H""" """ end @doc """ Renders a secondary button component with optional loading state. Secondary buttons are often used for secondary actions or alternative options. ## Examples <.secondary>Cancel <.secondary loading={@processing} phx_click="back"> Go Back ## Options * `:type` - Button type attribute (optional, defaults to "button") * `:class` - Additional CSS classes (optional) * `:disabled` - Whether the button is disabled (optional, defaults to false) * `:loading` - Whether to show loading state (optional, defaults to false) * `:icon` - HTML string for an icon to display before text (optional) * `:phx_click` - The LiveView click event to trigger (optional) * `:phx_value_id` - The id value to pass with the event (optional) * `:phx_target` - The LiveView target for the event (optional) """ def secondary(assigns) do assigns = assigns |> assign_new(:type, fn -> "button" end) |> assign_new(:class, fn -> "" end) |> assign_new(:disabled, fn -> false end) |> assign_new(:loading, fn -> false end) |> assign_new(:phx_click, fn -> nil end) |> assign_new(:phx_value_id, fn -> nil end) |> assign_new(:phx_target, fn -> nil end) |> assign_new(:icon, fn -> nil end) ~H""" """ end @doc """ Renders a danger button component with optional loading state. Danger buttons should be used for destructive actions such as delete or remove. ## Examples <.danger>Delete Account <.danger loading={@deleting} phx_click="delete" phx_value_id={@item.id}> Remove Item ## Options * `:type` - Button type attribute (optional, defaults to "button") * `:class` - Additional CSS classes (optional) * `:disabled` - Whether the button is disabled (optional, defaults to false) * `:loading` - Whether to show loading state (optional, defaults to false) * `:icon` - HTML string for an icon to display before text (optional) * `:phx_click` - The LiveView click event to trigger (optional) * `:phx_value_id` - The id value to pass with the event (optional) * `:phx_target` - The LiveView target for the event (optional) """ def danger(assigns) do assigns = assigns |> assign_new(:type, fn -> "button" end) |> assign_new(:class, fn -> "" end) |> assign_new(:disabled, fn -> false end) |> assign_new(:loading, fn -> false end) |> assign_new(:phx_click, fn -> nil end) |> assign_new(:phx_value_id, fn -> nil end) |> assign_new(:phx_target, fn -> nil end) |> assign_new(:icon, fn -> nil end) ~H""" """ end end