{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "cookie-consent-preferences",
  "title": "Cookie Consent — Preferences",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/cookie-consent-preferences/CookieConsentPreferences.vue",
      "content": "<script setup lang=\"ts\">\nimport { reactive, ref } from 'vue'\nimport { Lock } from 'lucide-vue-next'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Separator } from '@/components/ui/separator'\nimport { Switch } from '@/components/ui/switch'\n\n// Strictly-necessary is listed and shown locked rather than hidden. Omitting it\n// implies there is nothing there, which is not true.\nconst categories = [\n  {\n    id: 'necessary',\n    label: 'Strictly necessary',\n    purpose: 'Session and sign-in state. Without these the app cannot keep you logged in.',\n    retention: 'Session',\n    locked: true,\n  },\n  {\n    id: 'analytics',\n    label: 'Product analytics',\n    purpose: 'Which pages are read and where people give up. Aggregated, never sold.',\n    retention: '13 months',\n    locked: false,\n  },\n  {\n    id: 'support',\n    label: 'Support chat',\n    purpose: 'Keeps a conversation open across page loads so you do not repeat yourself.',\n    retention: '30 days',\n    locked: false,\n  },\n]\n\nconst open = ref(true)\nconst choices = reactive<Record<string, boolean>>({ necessary: true, analytics: false, support: false })\n</script>\n\n<template>\n  <div data-slot=\"cookie-consent-preferences\">\n    <Dialog v-model:open=\"open\">\n      <DialogContent class=\"sm:max-w-lg\">\n        <DialogHeader>\n          <Badge variant=\"secondary\" class=\"w-fit\">Privacy</Badge>\n          <DialogTitle class=\"mt-3 text-xl\">Choose what we store</DialogTitle>\n          <DialogDescription>\n            Each category says what it is for and how long it is kept. Nothing here is advertising.\n          </DialogDescription>\n        </DialogHeader>\n\n        <Separator />\n\n        <ul class=\"space-y-4\">\n          <li v-for=\"category in categories\" :key=\"category.id\" class=\"flex items-start gap-4\">\n            <div class=\"min-w-0 flex-1\">\n              <div class=\"flex flex-wrap items-center gap-2\">\n                <p class=\"text-sm font-medium\">{{ category.label }}</p>\n                <Badge v-if=\"category.locked\" variant=\"outline\" class=\"gap-1\">\n                  <Lock class=\"size-2.5\" aria-hidden=\"true\" />\n                  Required\n                </Badge>\n              </div>\n              <p class=\"text-muted-foreground mt-1 text-xs leading-relaxed\">{{ category.purpose }}</p>\n              <p class=\"text-muted-foreground/80 mt-1 font-mono text-xs\">Kept {{ category.retention }}</p>\n            </div>\n            <Switch\n              v-model=\"choices[category.id]\"\n              :disabled=\"category.locked\"\n              :aria-label=\"`Allow ${category.label}`\"\n              class=\"mt-1 shrink-0\"\n            />\n          </li>\n        </ul>\n\n        <DialogFooter class=\"sm:justify-start\">\n          <Button @click=\"open = false\">Save choices</Button>\n          <Button variant=\"outline\" @click=\"open = false\">Reject optional</Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/CookieConsentPreferences.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/dialog.json",
    "https://uipkge.dev/r/vue/separator.json",
    "https://uipkge.dev/r/vue/switch.json"
  ],
  "description": "Granular consent dialog listing each cookie category with its purpose, retention, and a switch, with strictly-necessary shown as locked rather than hidden.",
  "categories": [
    "marketing"
  ],
  "deprecated": true,
  "replacedBy": "cookie-consent"
}