{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "fab",
  "title": "Fab",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-svelte/components/fab/Fab.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Snippet } from 'svelte'\n  import type { HTMLButtonAttributes } from 'svelte/elements'\n  import type { FabVariants } from './fab.variants'\n\n  export interface FabProps extends HTMLButtonAttributes {\n    /** Label text — renders an extended FAB. Use children for an icon. */\n    label?: string\n    variant?: FabVariants['variant']\n    size?: FabVariants['size']\n    position?: FabVariants['position']\n    /** Use absolute instead of fixed positioning (for contained FABs). */\n    absolute?: boolean\n    /** Accessible label. Defaults to the label prop or 'Floating action'. */\n    ariaLabel?: string\n    /** Render your own element with the FAB's props and styles instead of\n     *  emitting a <button> — the Svelte counterpart of React's `asChild`. */\n    child?: Snippet<[{ props: Record<string, unknown> }]>\n    /** The rendered <button>, via `bind:ref`. Stays null in `child` mode. */\n    ref?: HTMLButtonElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n  import { fabVariants } from './fab.variants'\n\n  let {\n    class: className,\n    variant = 'default',\n    size = 'default',\n    position = 'bottom-right',\n    absolute = false,\n    label,\n    disabled,\n    ariaLabel,\n    child,\n    children,\n    ref = $bindable(null),\n    ...restProps\n  }: FabProps = $props()\n\n  const resolvedSize = $derived(label ? 'extended' : size)\n\n  const mergedProps = $derived({\n    'data-uipkge': '',\n    'data-slot': 'fab',\n    'data-variant': variant,\n    'data-size': resolvedSize,\n    'data-position': position,\n    disabled,\n    'aria-label': ariaLabel || label || 'Floating action',\n    class: cn(\n      fabVariants({ variant, size: resolvedSize, position }),\n      absolute && position !== 'inline' && 'absolute',\n      className,\n    ),\n    ...restProps,\n  })\n</script>\n\n{#if child}\n  {@render child({ props: mergedProps })}\n{:else}\n  <!-- Capture-phase guard mirrors the Vue twin's disabled click guard. -->\n  <button\n    bind:this={ref}\n    type=\"button\"\n    onclickcapture={(e) => {\n      if (disabled) {\n        e.preventDefault()\n        e.stopPropagation()\n      }\n    }}\n    {...mergedProps}\n  >\n    {@render children?.()}\n    {#if label}<span class=\"pr-1\">{label}</span>{/if}\n  </button>\n{/if}\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/fab/Fab.svelte"
    },
    {
      "path": "packages/registry-svelte/components/fab/fab.variants.ts",
      "content": "import type { VariantProps } from 'class-variance-authority'\nimport { cva } from 'class-variance-authority'\n\nexport const fabVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-full font-medium shadow-lg transition-[color,background-color,box-shadow,transform,scale] duration-200 outline-none focus-visible:ring-ring/50 focus-visible:ring-[3px] active:scale-95 touch-manipulation [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-6 disabled:pointer-events-none disabled:opacity-50\",\n  {\n    variants: {\n      variant: {\n        default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n        secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n        destructive: 'bg-destructive text-white hover:bg-destructive/90',\n        outline:\n          'border bg-background text-foreground hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n      },\n      size: {\n        mini: \"size-10 [&_svg:not([class*='size-'])]:size-4\",\n        default: 'size-14',\n        large: \"size-16 [&_svg:not([class*='size-'])]:size-7\",\n        extended: 'h-14 px-5',\n      },\n      position: {\n        'bottom-right': 'fixed bottom-6 right-6',\n        'bottom-left': 'fixed bottom-6 left-6',\n        'top-right': 'fixed top-6 right-6',\n        'top-left': 'fixed top-6 left-6',\n        'bottom-center': 'fixed bottom-6 left-1/2 -translate-x-1/2',\n        inline: '',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n      position: 'bottom-right',\n    },\n  },\n)\n\nexport type FabVariants = VariantProps<typeof fabVariants>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/fab/fab.variants.ts"
    },
    {
      "path": "packages/registry-svelte/components/fab/index.ts",
      "content": "export { default as Fab, type FabProps } from './Fab.svelte'\nexport { fabVariants, type FabVariants } from './fab.variants'\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/fab/index.ts"
    }
  ],
  "dependencies": [
    "class-variance-authority"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Floating action button — a fixed or absolute positioned circular button for the primary screen action. Supports an icon (default), an extended label variant, mini/large sizes, four color variants, six anchor positions, and a disabled state.",
  "categories": [
    "control",
    "navigation"
  ]
}