{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "cookie-consent-banner",
  "title": "Cookie Consent Banner",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/cookie-consent-banner/CookieConsentBanner.vue",
      "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { Cookie } from 'lucide-vue-next'\nimport { Button } from '@/components/ui/button'\nimport { Separator } from '@/components/ui/separator'\nimport { Switch } from '@/components/ui/switch'\n\ninterface Props {\n  variant?: 'bottom-bar' | 'card'\n}\n\nwithDefaults(defineProps<Props>(), {\n  variant: 'bottom-bar',\n})\n\nconst visible = ref(true)\nconst showPreferences = ref(false)\nconst analytics = ref(true)\nconst marketing = ref(false)\n\nfunction dismiss() {\n  visible.value = false\n}\n</script>\n\n<template>\n  <Transition\n    enter-active-class=\"transition-opacity duration-150 ease-out\"\n    enter-from-class=\"opacity-0\"\n    leave-active-class=\"transition-opacity duration-150 ease-in\"\n    leave-to-class=\"opacity-0\"\n  >\n    <div v-if=\"visible\" data-slot=\"cookie-consent-banner\" role=\"dialog\" aria-label=\"Cookie consent\">\n      <div v-if=\"variant === 'bottom-bar'\" 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                <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 variant=\"ghost\" size=\"sm\" @click=\"showPreferences = !showPreferences\">\n                {{ showPreferences ? 'Hide preferences' : 'Customize' }}\n              </Button>\n              <Button variant=\"outline\" size=\"sm\" @click=\"dismiss\">Reject</Button>\n              <Button size=\"sm\" @click=\"dismiss\">Accept all</Button>\n            </div>\n          </div>\n\n          <div v-if=\"showPreferences\" class=\"flex flex-col gap-3\">\n            <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              <Switch :model-value=\"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              <Switch v-model=\"analytics\" aria-label=\"Analytics cookies\" />\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              <Switch v-model=\"marketing\" aria-label=\"Marketing cookies\" />\n            </div>\n            <div class=\"mt-1 flex justify-end\">\n              <Button size=\"sm\" @click=\"dismiss\">Save preferences</Button>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div v-else 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              <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          <template v-if=\"showPreferences\">\n            <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              <Switch :model-value=\"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              <Switch v-model=\"analytics\" aria-label=\"Analytics cookies\" />\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              <Switch v-model=\"marketing\" aria-label=\"Marketing cookies\" />\n            </div>\n          </template>\n\n          <div class=\"flex flex-wrap items-center gap-2\">\n            <Button variant=\"ghost\" size=\"sm\" @click=\"showPreferences = !showPreferences\">\n              {{ showPreferences ? 'Hide preferences' : 'Customize' }}\n            </Button>\n            <div class=\"ml-auto flex items-center gap-2\">\n              <Button variant=\"outline\" size=\"sm\" @click=\"dismiss\">Reject</Button>\n              <Button size=\"sm\" @click=\"dismiss\">\n                {{ showPreferences ? 'Save preferences' : 'Accept all' }}\n              </Button>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </Transition>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/CookieConsentBanner.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/switch.json",
    "https://uipkge.dev/r/vue/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"
}