{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "fab",
  "title": "Fab",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-angular/components/fab/fab.component.ts",
      "content": "import { Component, ElementRef, Input, booleanAttribute, inject, ChangeDetectionStrategy } from '@angular/core'\nimport { cn } from '@/lib/utils'\nimport { fabVariants, type FabVariants } from './fab.variants'\n\nexport type FabVariant = NonNullable<FabVariants['variant']>\nexport type FabSize = NonNullable<FabVariants['size']>\nexport type FabPosition = NonNullable<FabVariants['position']>\n\n/**\n * Angular port of UIPKGE Fab (React `Fab`): a floating action <button>. Put it on a native\n * element — `<button ui-fab>` (React default) or `<a ui-fab>` (React `asChild` with a link).\n * Click with the native `(click)`; while `disabled` clicks are swallowed (the <button> also gets\n * the native disabled attribute). Class strings identical to React via shared `fabVariants`.\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'button[ui-fab], a[ui-fab]',\n  standalone: true,\n  host: {\n    '[attr.data-uipkge]': '\"\"',\n    '[attr.data-slot]': '\"fab\"',\n    '[attr.data-variant]': 'variant ?? null',\n    '[attr.data-size]': 'resolvedSize ?? null',\n    '[attr.data-position]': 'position ?? null',\n    '[attr.disabled]': 'disabled && isButton ? \"\" : null',\n    '[attr.aria-label]': 'ariaLabelAttr || ariaLabel || label || \"Floating action\"',\n    '[class]': 'hostClass',\n  },\n  template: `<ng-content />\n    @if (label) {\n      <span class=\"pr-1\">{{ label }}</span>\n    }`,\n})\nexport class UiFabComponent {\n  private readonly el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement\n  /** Label text: renders an extended FAB. Project the icon as content. */\n  @Input() label?: string\n  @Input() variant?: FabVariant\n  @Input() size?: FabSize\n  @Input() position?: FabPosition\n  /** Absolute instead of fixed positioning (for contained FABs). */\n  @Input({ transform: booleanAttribute }) absolute = false\n  @Input({ transform: booleanAttribute }) disabled = false\n  /** Accessible label. Defaults to `label`, then 'Floating action'. */\n  @Input() ariaLabel?: string\n  /** A plain `aria-label=\"…\"` attribute wins over `ariaLabel`, like React. */\n  @Input('aria-label') ariaLabelAttr?: string\n  @Input('class') className?: string\n\n  constructor() {\n    // Capture phase so it runs before consumer (click) handlers: disabled <a> FABs must not fire.\n    this.el.addEventListener(\n      'click',\n      (e) => {\n        if (!this.disabled) return\n        e.preventDefault()\n        e.stopImmediatePropagation()\n      },\n      true,\n    )\n  }\n\n  get isButton(): boolean {\n    return this.el.tagName === 'BUTTON'\n  }\n\n  get resolvedSize(): FabSize | undefined {\n    return this.label ? 'extended' : this.size\n  }\n\n  get hostClass(): string {\n    return cn(\n      fabVariants({ variant: this.variant, size: this.resolvedSize, position: this.position }),\n      this.absolute && this.position !== 'inline' && 'absolute',\n      this.className,\n    )\n  }\n}\n\nexport { fabVariants, type FabVariants }\n",
      "type": "registry:ui",
      "target": "~/src/app/components/ui/fab/fab.component.ts"
    },
    {
      "path": "packages/registry-angular/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/app/components/ui/fab/fab.variants.ts"
    },
    {
      "path": "packages/registry-angular/components/fab/index.ts",
      "content": "export {\n  UiFabComponent,\n  fabVariants,\n  type FabVariants,\n  type FabVariant,\n  type FabSize,\n  type FabPosition,\n} from './fab.component'\n",
      "type": "registry:ui",
      "target": "~/src/app/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"
  ]
}