# `PhiaUi.Components.Button`
[🔗](https://github.com/charlenopires/PhiaUI/blob/v0.1.17/lib/phia_ui/components/buttons/button.ex#L1)

Stateless Button component with 6 variants and 7 sizes.

Follows the shadcn/ui Button anatomy adapted for Phoenix LiveView.
Classes are built via `PhiaUi.ClassMerger.cn/1` so callers can safely
override individual utilities using the `:class` attribute.

## Variants

| Variant       | Use case                              |
|---------------|---------------------------------------|
| `:default`    | Primary call-to-action                |
| `:destructive`| Dangerous or irreversible actions     |
| `:outline`    | Secondary actions, cancel             |
| `:secondary`  | Lower-emphasis actions                |
| `:ghost`      | Minimal emphasis, toolbar actions     |
| `:link`       | Inline navigation-like actions        |

## Sizes

| Size       | Dimensions              |
|------------|-------------------------|
| `:default` | h-10 px-4 py-2          |
| `:xs`      | h-7 px-2 text-xs        |
| `:sm`      | h-9 px-3                |
| `:lg`      | h-11 px-8               |
| `:icon`    | h-10 w-10 (square)      |
| `:icon_sm` | h-8 w-8 (small square)  |
| `:icon_lg` | h-12 w-12 (large square)|

## Examples

    <.button>Save changes</.button>

    <.button variant={:destructive}>Delete account</.button>

    <.button variant={:outline}>Cancel</.button>

    <.button variant={:secondary}>More options</.button>

    <.button variant={:ghost}>Settings</.button>

    <.button variant={:link}>View details</.button>

    <.button size={:sm}>Compact action</.button>

    <.button size={:lg}>Prominent action</.button>

    <.button size={:icon} aria-label="Add item">
      <.icon name="hero-plus" />
    </.button>

    <.button phx-click="save" phx-disable-with="Saving…">
      Save
    </.button>

    <.button disabled={true}>Unavailable</.button>

    <.button class="w-full">Full width</.button>

    <.button size={:xs}>Compact</.button>

    <.button size={:icon_sm} aria-label="Remove">✕</.button>

    <.button>
      <:left_icon><.icon name="hero-arrow-left" /></:left_icon>
      Back
    </.button>

    <.button loading={true}>Saving…</.button>

# `button`

Renders a `<button>` element with semantic PhiaUI theming.

**Icon slots and gap**: when either `left_icon` or `right_icon` is
provided, `gap-2` is automatically added to the button's class list so
the icon and label maintain consistent spacing — you do not need to add
margin classes inside the slots.

**Loading state**: when `loading={true}`, an animated SVG spinner
(`animate-spin h-4 w-4`) is prepended to the button content, `aria-busy`
is set to `"true"` (announcing the in-progress state to screen readers),
and `pointer-events-none opacity-50` is applied to prevent duplicate
submissions while the operation completes.

**Disabled + loading**: both `:disabled` and `:loading` independently
apply `pointer-events-none opacity-50`. When both are true the button is
non-interactive and visually dimmed — this is intentional and safe.

## Examples

    <%!-- Primary call-to-action --%>
    <.button>Save changes</.button>

    <%!-- Destructive action — use a confirmation dialog alongside --%>
    <.button variant={:destructive}>Delete account</.button>

    <%!-- Icon-only toolbar button with accessible label --%>
    <.button size={:icon} aria-label="Open menu">
      <.icon name="menu" />
    </.button>

    <%!-- Left icon adds gap-2 automatically --%>
    <.button>
      <:left_icon><.icon name="arrow-left" /></:left_icon>
      Back
    </.button>

    <%!-- Right icon with a destructive context --%>
    <.button variant={:destructive}>
      Delete
      <:right_icon><.icon name="trash-2" /></:right_icon>
    </.button>

    <%!-- Loading state while an async operation is in progress --%>
    <.button loading={@saving}>
      {if @saving, do: "Saving…", else: "Save"}
    </.button>

    <%!-- LiveView phx-disable-with alternative (server-driven) --%>
    <.button phx-click="save" phx-disable-with="Saving…">
      Save
    </.button>

    <%!-- Full-width block button --%>
    <.button class="w-full">Continue</.button>

## Attributes

* `variant` (`:atom`) - Visual style variant. Defaults to `:default`. Must be one of `:default`, `:destructive`, `:outline`, `:secondary`, `:ghost`, or `:link`.
* `size` (`:atom`) - Size variant. Defaults to `:default`. Must be one of `:default`, `:xs`, `:sm`, `:lg`, `:icon`, `:icon_sm`, or `:icon_lg`.
* `class` (`:string`) - Additional CSS classes (merged via cn/1, last wins). Defaults to `nil`.
* `disabled` (`:boolean`) - Disables the button and adds pointer-events-none opacity-50. Defaults to `false`.
* `loading` (`:boolean`) - Shows a spinner and prevents interaction while true. Defaults to `false`.
* Global attributes are accepted. HTML attributes forwarded to the <button> element (phx-click, data-*, aria-*, etc.).
## Slots

* `left_icon` - Optional icon rendered to the left of the label.
* `right_icon` - Optional icon rendered to the right of the label.
* `inner_block` (required) - Button label, text or icon content.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
