{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "popover",
  "title": "Popover",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-vue/components/popover/Popover.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PopoverRootEmits, PopoverRootProps } from 'reka-ui'\nimport { PopoverRoot, useForwardPropsEmits } from 'reka-ui'\nimport { computed, onMounted, provide, ref, toRef, useId, watch } from 'vue'\nimport { POPOVER_INJECTION_KEY, type PopoverCloseBehavior } from './context'\n\nconst props = withDefaults(\n  defineProps<\n    PopoverRootProps & {\n      persist?: string | boolean\n      closeBehavior?: PopoverCloseBehavior\n    }\n  >(),\n  {\n    persist: false,\n    closeBehavior: 'auto',\n  },\n)\n\nconst emits = defineEmits<PopoverRootEmits>()\n\nprovide(POPOVER_INJECTION_KEY, {\n  closeBehavior: toRef(props, 'closeBehavior'),\n})\n\nconst autoId = useId()\nconst storageKey = computed(() => {\n  if (props.persist === false) return null\n  if (props.persist === true) return `uipkge-popover-${autoId}`\n  return props.persist\n})\n\nconst localOpen = ref<boolean>(props.defaultOpen ?? false)\n\nonMounted(() => {\n  if (!storageKey.value || typeof localStorage === 'undefined') return\n  if (localStorage.getItem(storageKey.value) === '1') {\n    localOpen.value = true\n    if (props.open === undefined) {\n      emits('update:open', true)\n    }\n  }\n})\n\nwatch(\n  () => (props.open === undefined ? localOpen.value : props.open),\n  (v) => {\n    if (!storageKey.value || typeof localStorage === 'undefined') return\n    if (v) localStorage.setItem(storageKey.value, '1')\n    else localStorage.removeItem(storageKey.value)\n  },\n)\n\nconst forwarded = useForwardPropsEmits(\n  computed(() => ({\n    open: props.open,\n    defaultOpen: props.defaultOpen,\n    modal: props.modal,\n  })),\n  emits,\n)\n\nfunction onUpdateOpen(value: boolean) {\n  localOpen.value = value\n  emits('update:open', value)\n}\n</script>\n\n<template>\n  <PopoverRoot v-slot=\"slotProps\" data-uipkge data-slot=\"popover\" v-bind=\"forwarded\" @update:open=\"onUpdateOpen\">\n    <slot v-bind=\"slotProps\" />\n  </PopoverRoot>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/popover/Popover.vue"
    },
    {
      "path": "packages/registry-vue/components/popover/PopoverAnchor.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PopoverAnchorProps } from 'reka-ui'\nimport { PopoverAnchor } from 'reka-ui'\n\nconst props = defineProps<PopoverAnchorProps>()\n</script>\n\n<template>\n  <PopoverAnchor data-uipkge data-slot=\"popover-anchor\" v-bind=\"props\">\n    <slot />\n  </PopoverAnchor>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/popover/PopoverAnchor.vue"
    },
    {
      "path": "packages/registry-vue/components/popover/PopoverContent.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PopoverContentEmits, PopoverContentProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { reactiveOmit } from '@vueuse/core'\nimport { PopoverContent, PopoverPortal, useForwardPropsEmits } from 'reka-ui'\nimport { inject } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { POPOVER_INJECTION_KEY } from './context'\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<PopoverContentProps & { class?: HTMLAttributes['class'] }>(), {\n  align: 'center',\n  sideOffset: 4,\n})\nconst emits = defineEmits<PopoverContentEmits>()\n\nconst ctx = inject(POPOVER_INJECTION_KEY, null)\n\nconst delegatedProps = reactiveOmit(props, 'class')\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n\nfunction onPointerDownOutside(e: Event) {\n  const mode = ctx?.closeBehavior.value ?? 'auto'\n  if (mode === 'esc' || mode === 'manual' || mode === 'none') {\n    e.preventDefault()\n  }\n}\n\nfunction onEscapeKeyDown(e: KeyboardEvent) {\n  const mode = ctx?.closeBehavior.value ?? 'auto'\n  if (mode === 'click-outside' || mode === 'manual' || mode === 'none') {\n    e.preventDefault()\n  }\n}\n</script>\n\n<template>\n  <PopoverPortal>\n    <PopoverContent\n      data-uipkge\n      data-slot=\"popover-content\"\n      v-bind=\"{ ...$attrs, ...forwarded }\"\n      :class=\"\n        cn(\n          'bg-popover text-popover-foreground motion-safe:data-[state=open]:animate-in motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=open]:fade-in-0 motion-safe:data-[state=closed]:zoom-out-95 motion-safe:data-[state=open]:zoom-in-95 motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[side=left]:slide-in-from-right-2 motion-safe:data-[side=right]:slide-in-from-left-2 motion-safe:data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--reka-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden',\n          props.class,\n        )\n      \"\n      @pointer-down-outside=\"onPointerDownOutside\"\n      @escape-key-down=\"onEscapeKeyDown\"\n    >\n      <slot />\n    </PopoverContent>\n  </PopoverPortal>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/popover/PopoverContent.vue"
    },
    {
      "path": "packages/registry-vue/components/popover/PopoverTrigger.vue",
      "content": "<script setup lang=\"ts\">\nimport type { PopoverTriggerProps } from 'reka-ui'\nimport { PopoverTrigger } from 'reka-ui'\n\nconst props = defineProps<PopoverTriggerProps>()\n</script>\n\n<template>\n  <PopoverTrigger data-uipkge data-slot=\"popover-trigger\" v-bind=\"props\">\n    <slot />\n  </PopoverTrigger>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/popover/PopoverTrigger.vue"
    },
    {
      "path": "packages/registry-vue/components/popover/context.ts",
      "content": "import type { InjectionKey, Ref } from 'vue'\n\nexport type PopoverCloseBehavior = 'auto' | 'click-outside' | 'esc' | 'manual' | 'none'\n\nexport interface PopoverContext {\n  closeBehavior: Ref<PopoverCloseBehavior>\n}\n\nexport const POPOVER_INJECTION_KEY: InjectionKey<PopoverContext> = Symbol('uipkge-popover')\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/popover/context.ts"
    },
    {
      "path": "packages/registry-vue/components/popover/index.ts",
      "content": "export { default as Popover } from './Popover.vue'\nexport { default as PopoverAnchor } from './PopoverAnchor.vue'\nexport { default as PopoverContent } from './PopoverContent.vue'\nexport { default as PopoverTrigger } from './PopoverTrigger.vue'\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/popover/index.ts"
    }
  ],
  "dependencies": [
    "@vueuse/core",
    "reka-ui"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Click-triggered floating panel anchored to a trigger element. Supports optional localStorage persistence and configurable dismissal (click-outside, escape, manual). Built on reka-ui with collision detection.",
  "categories": [
    "overlay"
  ]
}