{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "popover",
  "title": "Popover",
  "description": "Anchored floating panel that enters from its trigger with a small placement-aware offset.",
  "dependencies": [
    "motion",
    "@base-ui/react"
  ],
  "registryDependencies": [
    "utils",
    "springs"
  ],
  "files": [
    {
      "path": "src/components/ui/popover.tsx",
      "content": "\"use client\";\n\nimport type { ComponentProps } from \"react\";\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\";\nimport { motion, useReducedMotion } from \"motion/react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { spring } from \"@/lib/springs\";\n\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\n  return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n}\n\nfunction PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {\n  return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\n\n/**\n * Anchored, non-modal — no backdrop, unlike Dialog. It enters from a small\n * trigger-facing offset on its resolved side, so collision handling never\n * breaks the connection between the trigger and its floating surface.\n */\nfunction PopoverContent({\n  className,\n  align = \"center\",\n  alignOffset = 0,\n  side = \"bottom\",\n  sideOffset = 8,\n  ...props\n}: PopoverPrimitive.Popup.Props &\n  Pick<PopoverPrimitive.Positioner.Props, \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\">) {\n  const reduceMotion = useReducedMotion();\n\n  return (\n    <PopoverPrimitive.Portal>\n      <PopoverPrimitive.Positioner\n        data-slot=\"popover-positioner\"\n        align={align}\n        alignOffset={alignOffset}\n        side={side}\n        sideOffset={sideOffset}\n        className=\"z-50\"\n      >\n        <PopoverPrimitive.Popup\n          data-slot=\"popover-content\"\n          render={(popupProps, state) => {\n            const exiting = state.transitionStatus === \"ending\";\n            const triggerOffset = reduceMotion\n              ? { x: 0, y: 0 }\n              : {\n                  x: state.side === \"right\" ? -4 : state.side === \"left\" ? 4 : 0,\n                  y: state.side === \"bottom\" ? -4 : state.side === \"top\" ? 4 : 0,\n                };\n            return (\n              <motion.div\n                {...(popupProps as Record<string, unknown>)}\n                {...(props as Record<string, unknown>)}\n                className={cn(\n                  \"w-72 rounded-lg bg-popover p-3 text-body text-popover-foreground shadow-popover outline-none\",\n                  className,\n                )}\n                initial={{ opacity: 0, ...triggerOffset }}\n                animate={{\n                  opacity: exiting ? 0 : 1,\n                  x: exiting ? triggerOffset.x : 0,\n                  y: exiting ? triggerOffset.y : 0,\n                }}\n                transition={exiting ? spring.moderate.exit : spring.moderate.enter}\n              />\n            );\n          }}\n        />\n      </PopoverPrimitive.Positioner>\n    </PopoverPrimitive.Portal>\n  );\n}\n\nfunction PopoverHeader({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div data-slot=\"popover-header\" className={cn(\"flex flex-col gap-1\", className)} {...props} />\n  );\n}\n\nfunction PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {\n  return (\n    <PopoverPrimitive.Title\n      data-slot=\"popover-title\"\n      className={cn(\"text-control font-medium text-foreground\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction PopoverDescription({ className, ...props }: PopoverPrimitive.Description.Props) {\n  return (\n    <PopoverPrimitive.Description\n      data-slot=\"popover-description\"\n      className={cn(\"text-caption text-muted-foreground\", className)}\n      {...props}\n    />\n  );\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverHeader, PopoverTitle, PopoverDescription };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}