{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "cookie-consent-banner",
  "title": "Cookie Consent Banner",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/cookie-consent-banner/cookie-consent-banner.component.ts",
      "content": "// GDPR-style cookie consent banner with two variants: a full-width bottom bar and a compact\n// card. Customize expands inline preferences with Necessary (always on), Analytics, and\n// Marketing switches. Accept, Reject, and Save dismiss with a 150ms fade.\n// Port of the Vue/React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, signal } from '@angular/core'\nimport { Cookie, LucideAngularModule } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport { UiSwitchComponent } from '@/ui/switch/switch.component'\n\nexport type CookieConsentBannerVariant = 'bottom-bar' | 'card'\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-cookie-consent-banner, [ui-cookie-consent-banner]',\n  standalone: true,\n  // The block renders its own root <div>: keep this wrapper out of the layout.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [LucideAngularModule, UiButtonComponent, UiSeparatorComponent, UiSwitchComponent],\n  template: `\n    @if (visible()) {\n      <div data-slot=\"cookie-consent-banner\" role=\"dialog\" aria-label=\"Cookie consent\" [class]=\"rootClass\">\n        @if (variant === 'bottom-bar') {\n          <div class=\"bg-card border-border w-full border-t px-4 py-4 sm:px-6\">\n            <div class=\"mx-auto flex max-w-5xl flex-col gap-4\">\n              <div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\">\n                <div class=\"flex items-start gap-3\">\n                  <span\n                    class=\"bg-primary/10 text-primary mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full\"\n                  >\n                    <lucide-icon [img]=\"Cookie\" class=\"size-4\" aria-hidden=\"true\" />\n                  </span>\n                  <p class=\"text-muted-foreground max-w-xl text-sm leading-relaxed\">\n                    We use cookies to improve your experience and analyze traffic. Read our\n                    <a\n                      href=\"#\"\n                      class=\"text-foreground focus-visible:ring-ring rounded-sm font-medium underline underline-offset-4 outline-none focus-visible:ring-2\"\n                      >Cookie Policy</a\n                    >.\n                  </p>\n                </div>\n                <div class=\"flex shrink-0 flex-wrap items-center gap-2\">\n                  <button ui-button variant=\"ghost\" size=\"sm\" (click)=\"showPreferences.set(!showPreferences())\">\n                    {{ showPreferences() ? 'Hide preferences' : 'Customize' }}\n                  </button>\n                  <button ui-button variant=\"outline\" size=\"sm\" (click)=\"dismiss()\">Reject</button>\n                  <button ui-button size=\"sm\" (click)=\"dismiss()\">Accept all</button>\n                </div>\n              </div>\n\n              @if (showPreferences()) {\n                <div class=\"flex flex-col gap-3\">\n                  <ui-separator />\n                  <div class=\"flex items-center justify-between gap-4 py-1\">\n                    <div>\n                      <p class=\"text-sm font-medium\">Necessary</p>\n                      <p class=\"text-muted-foreground text-xs\">Required for the site to function.</p>\n                    </div>\n                    <ui-switch [checked]=\"true\" disabled aria-label=\"Necessary cookies\" />\n                  </div>\n                  <div class=\"flex items-center justify-between gap-4 py-1\">\n                    <div>\n                      <p class=\"text-sm font-medium\">Analytics</p>\n                      <p class=\"text-muted-foreground text-xs\">Helps us understand usage patterns.</p>\n                    </div>\n                    <ui-switch\n                      [checked]=\"analytics()\"\n                      (checkedChange)=\"analytics.set($event)\"\n                      aria-label=\"Analytics cookies\"\n                    />\n                  </div>\n                  <div class=\"flex items-center justify-between gap-4 py-1\">\n                    <div>\n                      <p class=\"text-sm font-medium\">Marketing</p>\n                      <p class=\"text-muted-foreground text-xs\">Used to personalize campaigns.</p>\n                    </div>\n                    <ui-switch\n                      [checked]=\"marketing()\"\n                      (checkedChange)=\"marketing.set($event)\"\n                      aria-label=\"Marketing cookies\"\n                    />\n                  </div>\n                  <div class=\"mt-1 flex justify-end\">\n                    <button ui-button size=\"sm\" (click)=\"dismiss()\">Save preferences</button>\n                  </div>\n                </div>\n              }\n            </div>\n          </div>\n        } @else {\n          <div class=\"bg-card border-border mx-auto max-w-md rounded-xl border p-6 shadow-xs\">\n            <div class=\"flex flex-col gap-4\">\n              <div class=\"flex items-start gap-3\">\n                <span class=\"bg-primary/10 text-primary flex size-9 shrink-0 items-center justify-center rounded-full\">\n                  <lucide-icon [img]=\"Cookie\" class=\"size-4\" aria-hidden=\"true\" />\n                </span>\n                <div>\n                  <h3 class=\"text-sm font-semibold\">We value your privacy</h3>\n                  <p class=\"text-muted-foreground mt-1 text-sm leading-relaxed\">\n                    We use cookies to improve your experience and analyze traffic. Read our\n                    <a\n                      href=\"#\"\n                      class=\"text-foreground focus-visible:ring-ring rounded-sm font-medium underline underline-offset-4 outline-none focus-visible:ring-2\"\n                      >Cookie Policy</a\n                    >.\n                  </p>\n                </div>\n              </div>\n\n              @if (showPreferences()) {\n                <ui-separator />\n                <div class=\"flex items-center justify-between gap-4 py-1\">\n                  <div>\n                    <p class=\"text-sm font-medium\">Necessary</p>\n                    <p class=\"text-muted-foreground text-xs\">Required for the site to function.</p>\n                  </div>\n                  <ui-switch [checked]=\"true\" disabled aria-label=\"Necessary cookies\" />\n                </div>\n                <div class=\"flex items-center justify-between gap-4 py-1\">\n                  <div>\n                    <p class=\"text-sm font-medium\">Analytics</p>\n                    <p class=\"text-muted-foreground text-xs\">Helps us understand usage patterns.</p>\n                  </div>\n                  <ui-switch\n                    [checked]=\"analytics()\"\n                    (checkedChange)=\"analytics.set($event)\"\n                    aria-label=\"Analytics cookies\"\n                  />\n                </div>\n                <div class=\"flex items-center justify-between gap-4 py-1\">\n                  <div>\n                    <p class=\"text-sm font-medium\">Marketing</p>\n                    <p class=\"text-muted-foreground text-xs\">Used to personalize campaigns.</p>\n                  </div>\n                  <ui-switch\n                    [checked]=\"marketing()\"\n                    (checkedChange)=\"marketing.set($event)\"\n                    aria-label=\"Marketing cookies\"\n                  />\n                </div>\n              }\n\n              <div class=\"flex flex-wrap items-center gap-2\">\n                <button ui-button variant=\"ghost\" size=\"sm\" (click)=\"showPreferences.set(!showPreferences())\">\n                  {{ showPreferences() ? 'Hide preferences' : 'Customize' }}\n                </button>\n                <div class=\"ml-auto flex items-center gap-2\">\n                  <button ui-button variant=\"outline\" size=\"sm\" (click)=\"dismiss()\">Reject</button>\n                  <button ui-button size=\"sm\" (click)=\"dismiss()\">\n                    {{ showPreferences() ? 'Save preferences' : 'Accept all' }}\n                  </button>\n                </div>\n              </div>\n            </div>\n          </div>\n        }\n      </div>\n    }\n  `,\n})\nexport class UiCookieConsentBannerComponent {\n  protected readonly Cookie = Cookie\n\n  @Input() variant: CookieConsentBannerVariant = 'bottom-bar'\n  @Input('class') className?: string\n\n  readonly visible = signal(true)\n  readonly showPreferences = signal(false)\n  readonly analytics = signal(true)\n  readonly marketing = signal(false)\n\n  get rootClass(): string {\n    return cn('animate-in fade-in duration-150', this.className)\n  }\n\n  dismiss(): void {\n    this.visible.set(false)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/cookie-consent-banner/cookie-consent-banner.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/cookie-consent-banner/index.ts",
      "content": "export { UiCookieConsentBannerComponent, type CookieConsentBannerVariant } from './cookie-consent-banner.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/cookie-consent-banner/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/switch.json",
    "https://uipkge.dev/r/angular/separator.json"
  ],
  "description": "GDPR-style cookie consent banner with two variants: a full-width bottom bar and a compact card. Customize expands inline preferences with Necessary (always on), Analytics, and Marketing switches. Accept, Reject, and Save dismiss with a 150ms fade.",
  "categories": [
    "legal",
    "marketing",
    "feedback"
  ],
  "deprecated": true,
  "replacedBy": "cookie-consent"
}