Skip to main content

priv/registry/button.json

{
  "files": [
    {
      "content": "defmodule Shadix.Components.Button do\n  @moduledoc \"\"\"\n  A button styled with the shadcn variant/size system.\n\n  Renders a `<button>` carrying `data-slot=\"button\"` plus `data-variant` and\n  `data-size` for stable styling/targeting. Caller-supplied `class` is appended\n  last; Tailwind cascade layers ensure it wins over the defaults.\n  \"\"\"\n  use Phoenix.Component\n\n  import Shadix.Cn\n\n  @base \"inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none active:not-aria-[haspopup]:translate-y-px focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n\n  @variants %{\n    \"default\" => \"bg-primary text-primary-foreground hover:bg-primary/90\",\n    \"destructive\" =>\n      \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n    \"outline\" =>\n      \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n    \"secondary\" => \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n    \"ghost\" => \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n    \"link\" => \"text-primary underline-offset-4 hover:underline\"\n  }\n\n  @sizes %{\n    \"default\" => \"h-9 px-4 py-2 has-[>svg]:px-3\",\n    \"sm\" => \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n    \"lg\" => \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n    \"icon\" => \"size-9\"\n  }\n\n  attr(:variant, :string,\n    default: \"default\",\n    values: ~w(default secondary destructive outline ghost link)\n  )\n\n  attr(:size, :string, default: \"default\", values: ~w(default sm lg icon))\n  attr(:type, :string, default: \"button\")\n  attr(:class, :string, default: nil)\n  attr(:rest, :global, include: ~w(disabled form name value autofocus))\n  slot(:inner_block, required: true)\n\n  def button(assigns) do\n    class =\n      cn([\n        @base,\n        Map.fetch!(@variants, assigns.variant),\n        Map.fetch!(@sizes, assigns.size),\n        assigns.class\n      ])\n\n    assigns = assign(assigns, :computed_class, class)\n\n    ~H\"\"\"\n    <button\n      type={@type}\n      data-slot=\"button\"\n      data-variant={@variant}\n      data-size={@size}\n      class={@computed_class}\n      {@rest}\n    >\n      {render_slot(@inner_block)}\n    </button>\n    \"\"\"\n  end\nend\n",
      "path": "button.ex"
    }
  ],
  "hooks": [],
  "name": "button",
  "npm_deps": [],
  "registry_deps": [
    "cn"
  ]
}