defmodule <%= @module_name %>.Components.UI.Button do @moduledoc """ Stateless Button component with 6 variants and 4 sizes. Ejected from PhiaUI — owns this copy of the source. Customise freely. ## 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 | | `:sm` | h-9 px-3 | | `:lg` | h-11 px-8 | | `:icon` | h-10 w-10 (square) | ## Examples <.button>Save changes <.button variant={:destructive}>Delete <.button variant={:outline}>Cancel <.button variant={:secondary}>More <.button variant={:ghost}>Settings <.button variant={:link}>View details <.button size={:sm}>Small <.button size={:lg}>Large <.button size={:icon} aria-label="Add"><.icon name="hero-plus" /> <.button phx-click="save" phx-disable-with="Saving…">Save <.button disabled={true}>Unavailable <.button class="w-full">Full width """ use Phoenix.Component # Replace with your app's class merger or remove if unused. import <%= @module_name %>.ClassMerger, only: [cn: 1] attr :variant, :atom, values: [:default, :destructive, :outline, :secondary, :ghost, :link], default: :default, doc: "Visual style variant" attr :size, :atom, values: [:default, :sm, :lg, :icon], default: :default, doc: "Size variant" attr :class, :string, default: nil, doc: "Additional CSS classes (merged via cn/1, last wins)" attr :disabled, :boolean, default: false, doc: "Disables the button and adds pointer-events-none opacity-50" attr :rest, :global, doc: "HTML attributes forwarded to the """ end defp base_class do "inline-flex items-center justify-center whitespace-nowrap rounded-md " <> "text-sm font-medium ring-offset-background transition-colors " <> "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring " <> "focus-visible:ring-offset-2" end defp variant_class(:default), do: "bg-primary text-primary-foreground shadow hover:bg-primary/90" defp variant_class(:destructive), do: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90" defp variant_class(:outline), do: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground" defp variant_class(:secondary), do: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80" defp variant_class(:ghost), do: "hover:bg-accent hover:text-accent-foreground" defp variant_class(:link), do: "text-primary underline-offset-4 hover:underline" defp size_class(:default), do: "h-10 px-4 py-2" defp size_class(:sm), do: "h-9 rounded-md px-3" defp size_class(:lg), do: "h-11 rounded-md px-8" defp size_class(:icon), do: "h-10 w-10" end