{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "popover",
  "type": "registry:ui",
  "title": "Popover",
  "description": "A slip of paper with a folded corner.",
  "categories": [
    "core"
  ],
  "files": [
    {
      "path": "ui/popover.tsx",
      "type": "registry:ui",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\n\n// Popups render in a layer on <body> that copies the paper type of the nearest [data-paper]\n// element (and follows it if it changes). That keeps their theme without trapping them inside the\n// container's stacking context, so sticky headers can't cover them.\nfunction usePaperContainer() {\n  const anchor = React.useRef<HTMLSpanElement>(null);\n  const [container, setContainer] = React.useState<HTMLElement | undefined>();\n  React.useEffect(() => {\n    const source = anchor.current?.closest<HTMLElement>(\"[data-paper]\");\n    if (!source || source === document.documentElement) return;\n    const layer = document.createElement(\"div\");\n    layer.setAttribute(\"data-paper-layer\", \"\");\n    const sync = () => layer.setAttribute(\"data-paper\", source.getAttribute(\"data-paper\") ?? \"\");\n    sync();\n    document.body.appendChild(layer);\n    const observer = new MutationObserver(sync);\n    observer.observe(source, { attributes: true, attributeFilter: [\"data-paper\"] });\n    setContainer(layer);\n    return () => {\n      observer.disconnect();\n      layer.remove();\n    };\n  }, []);\n  return [anchor, container] as const;\n}\n\n/** A slip of paper with a folded corner. */\nexport const Popover = PopoverPrimitive.Root;\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\nexport const PopoverAnchor = PopoverPrimitive.Anchor;\nexport const PopoverClose = PopoverPrimitive.Close;\n\nconst FOLD = 16;\n\nexport function PopoverContent({\n  className = \"\",\n  align = \"center\",\n  sideOffset = 8,\n  children,\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n  const [anchor, container] = usePaperContainer();\n  return (\n    <>\n      <span ref={anchor} hidden />\n      <PopoverPrimitive.Portal container={container}>\n        <PopoverPrimitive.Content\n          align={align}\n          sideOffset={sideOffset}\n          data-paper-motion\n          className=\"z-50 origin-(--radix-popover-content-transform-origin) outline-none drop-shadow-[0_12px_18px_rgb(0_0_0/.25)] data-[state=open]:animate-[paper-pop-in_.16s_ease-out]\"\n          {...props}\n        >\n          <div\n            className={`paper relative w-72 bg-(--paper-raised) p-5 text-(--ink) ${className}`}\n            style={{ clipPath: `polygon(0 0, calc(100% - ${FOLD}px) 0, 100% ${FOLD}px, 100% 100%, 0 100%)` }}\n          >\n            {/* the folded-down corner */}\n            <span\n              aria-hidden\n              className=\"absolute right-0 top-0\"\n              style={{\n                width: FOLD,\n                height: FOLD,\n                background: \"linear-gradient(225deg, transparent 50%, color-mix(in srgb, var(--paper-sunk) 80%, #000) 50%)\",\n              }}\n            />\n            {children}\n          </div>\n        </PopoverPrimitive.Content>\n      </PopoverPrimitive.Portal>\n    </>\n  );\n}\n"
    }
  ],
  "dependencies": [
    "radix-ui"
  ]
}