{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "button",
  "title": "Button",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-svelte/components/button/Button.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Snippet } from 'svelte'\n  import type { HTMLButtonAttributes } from 'svelte/elements'\n  import type { ButtonVariants } from './button.variants'\n\n  export interface ButtonProps extends HTMLButtonAttributes {\n    variant?: ButtonVariants['variant']\n    size?: ButtonVariants['size']\n    /** Render your own element with the button's props and styles instead of\n     *  emitting a <button> — the Svelte counterpart of React's `asChild`. Use it\n     *  to give an <a> full button styling: spread `props` onto your element. */\n    child?: Snippet<[{ props: Record<string, unknown> }]>\n    /** The rendered <button>, via `bind:ref`. Stays null in `child` mode — use\n     *  `bind:this` on your own element there. */\n    ref?: HTMLButtonElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n  import { buttonVariants } from './button.variants'\n\n  let {\n    class: className,\n    variant = 'default',\n    size = 'default',\n    type = 'button',\n    child,\n    children,\n    ref = $bindable(null),\n    ...restProps\n  }: ButtonProps = $props()\n\n  const mergedProps = $derived({\n    'data-uipkge': '',\n    'data-slot': 'button',\n    'data-variant': variant,\n    'data-size': size,\n    class: cn(buttonVariants({ variant, size }), className),\n    ...restProps,\n  })\n</script>\n\n{#if child}\n  <!-- Default type=\"button\" avoids accidental form submits. `child` leaves type\n       to the consumer's element (e.g. <a>) and must not receive it. -->\n  {@render child({ props: mergedProps })}\n{:else}\n  <button bind:this={ref} {type} {...mergedProps}>{@render children?.()}</button>\n{/if}\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/button/Button.svelte"
    },
    {
      "path": "packages/registry-svelte/components/button/ButtonGroup.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface ButtonGroupProps extends HTMLAttributes<HTMLDivElement> {\n    orientation?: 'horizontal' | 'vertical'\n    attached?: boolean\n    ref?: HTMLDivElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n\n  let {\n    class: className,\n    orientation = 'horizontal',\n    attached = true,\n    children,\n    ref = $bindable(null),\n    ...restProps\n  }: ButtonGroupProps = $props()\n</script>\n\n<div\n  bind:this={ref}\n  role=\"group\"\n  data-uipkge=\"\"\n  data-slot=\"button-group\"\n  data-orientation={orientation}\n  data-attached={attached ? '' : undefined}\n  class={cn(\n    'inline-flex items-center',\n    orientation === 'vertical' ? 'flex-col items-stretch' : 'flex-row',\n    attached && [\n      '[&>[data-slot=button]]:relative [&>[data-slot=button]:focus-visible]:z-20 [&>[data-slot=button]:hover]:z-10',\n      '[&>button]:relative [&>button:focus-visible]:z-20 [&>button:hover]:z-10',\n      orientation === 'horizontal' && [\n        '[&>[data-slot=button]]:rounded-none [&>button]:rounded-none',\n        '[&>[data-slot=button]:first-child]:rounded-l-md [&>button:first-child]:rounded-l-md',\n        '[&>[data-slot=button]:last-child]:rounded-r-md [&>button:last-child]:rounded-r-md',\n        '[&>[data-slot=button]:only-child]:rounded-md [&>button:only-child]:rounded-md',\n        '[&>[data-slot=button]:not(:first-child)]:-ml-px [&>button:not(:first-child)]:-ml-px',\n        '[&>[data-slot=button][data-variant=default]:not(:first-child)]:border-primary-foreground/20 [&>[data-slot=button][data-variant=default]:not(:first-child)]:border-l',\n        '[&>[data-slot=button]:not([data-variant]):not(:first-child)]:border-primary-foreground/20 [&>[data-slot=button]:not([data-variant]):not(:first-child)]:border-l',\n        '[&>[data-slot=button][data-variant=secondary]:not(:first-child)]:border-border [&>[data-slot=button][data-variant=secondary]:not(:first-child)]:border-l',\n        '[&>[data-slot=button][data-variant=destructive]:not(:first-child)]:border-l [&>[data-slot=button][data-variant=destructive]:not(:first-child)]:border-white/20',\n      ],\n      orientation === 'vertical' && [\n        '[&>[data-slot=button]]:rounded-none [&>button]:rounded-none',\n        '[&>[data-slot=button]:first-child]:rounded-t-md [&>button:first-child]:rounded-t-md',\n        '[&>[data-slot=button]:last-child]:rounded-b-md [&>button:last-child]:rounded-b-md',\n        '[&>[data-slot=button]:only-child]:rounded-md [&>button:only-child]:rounded-md',\n        '[&>[data-slot=button]:not(:first-child)]:-mt-px [&>button:not(:first-child)]:-mt-px',\n        '[&>[data-slot=button][data-variant=default]:not(:first-child)]:border-primary-foreground/20 [&>[data-slot=button][data-variant=default]:not(:first-child)]:border-t',\n        '[&>[data-slot=button]:not([data-variant]):not(:first-child)]:border-primary-foreground/20 [&>[data-slot=button]:not([data-variant]):not(:first-child)]:border-t',\n        '[&>[data-slot=button][data-variant=secondary]:not(:first-child)]:border-border [&>[data-slot=button][data-variant=secondary]:not(:first-child)]:border-t',\n        '[&>[data-slot=button][data-variant=destructive]:not(:first-child)]:border-t [&>[data-slot=button][data-variant=destructive]:not(:first-child)]:border-white/20',\n      ],\n    ],\n    !attached && (orientation === 'vertical' ? 'gap-1' : 'gap-1.5'),\n    className,\n  )}\n  {...restProps}\n>\n  {@render children?.()}\n</div>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/button/ButtonGroup.svelte"
    },
    {
      "path": "packages/registry-svelte/components/button/button.variants.ts",
      "content": "import type { VariantProps } from 'class-variance-authority'\nimport { cva } from 'class-variance-authority'\n\n/**\n * Variant definitions live in their own file (rather than the package\n * `index.ts`) so `Button.vue` can `import { buttonVariants } from\n * './button.variants'` without creating a circular dependency through the\n * index. See card.variants.ts for the same pattern + the SSR symptom that\n * motivated the split.\n */\nexport const buttonVariants = cva(\n  \"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,background-color,border-color,box-shadow,opacity,transform,scale] duration-150 active:scale-[0.97] active:duration-100 touch-manipulation disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',\n        destructive:\n          'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',\n        outline:\n          'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n        secondary: 'bg-secondary text-secondary-foreground shadow-xs 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      size: {\n        default: 'h-9 px-4 py-2 has-[>svg]:px-3',\n        sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',\n        lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',\n        xs: 'h-7 rounded-md gap-1 px-2 has-[>svg]:px-1.5 text-xs',\n        icon: 'size-9',\n        'icon-sm': 'size-8',\n        'icon-lg': 'size-10',\n        // Square counterpart of `xs` (h-7). Dense data toolbars run at 28px and\n        // had no icon-only tier to match, so icon controls sat 4px taller than\n        // the buttons beside them. Icons inside carry their own size class.\n        'icon-xs': 'size-7',\n        // Row-action tier: the hover-revealed copy control inside a two-line\n        // table cell. Anything taller than the 20px text line it sits on makes\n        // the row grow when the control appears.\n        'icon-2xs': 'size-5',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n    },\n  },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/button/button.variants.ts"
    },
    {
      "path": "packages/registry-svelte/components/button/index.ts",
      "content": "export { default as Button, type ButtonProps } from './Button.svelte'\nexport { default as ButtonGroup, type ButtonGroupProps } from './ButtonGroup.svelte'\nexport { buttonVariants, type ButtonVariants } from './button.variants'\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/button/index.ts"
    }
  ],
  "dependencies": [
    "class-variance-authority"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Interactive button component with variants (default, destructive, outline, secondary, ghost, link), sizes, and composite ButtonGroup container for segmented toolbars and split buttons.",
  "categories": [
    "control"
  ]
}