{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "popover-form",
  "type": "registry:ui",
  "description": "Form popover component with success states and animated transitions",
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "files": [
    {
      "path": "registry/default/ui/popover-form.tsx",
      "content": "\"use client\"\n\nimport { ReactNode, RefObject, useEffect, useRef } from \"react\"\nimport { ChevronUp, Loader } from \"lucide-react\"\nimport { AnimatePresence, motion } from \"motion/react\"\n\ntype PopoverFormProps = {\n  open: boolean\n  setOpen: (open: boolean) => void\n  openChild?: ReactNode\n  successChild?: ReactNode\n  showSuccess: boolean\n  width?: string\n  height?: string\n  showCloseButton?: boolean\n  title: string\n}\n\nexport function PopoverForm({\n  open,\n  setOpen,\n  openChild,\n  showSuccess,\n  successChild,\n  width = \"364px\",\n  height = \"192px\",\n  title = \"Feedback\",\n  showCloseButton = false,\n}: PopoverFormProps) {\n  const ref = useRef<HTMLDivElement>(null)\n  useClickOutside(ref, () => setOpen(false))\n\n  return (\n    <div\n      key={title}\n      className=\"flex min-h-[300px] w-full items-center justify-center\"\n    >\n      <motion.button\n        layoutId={`${title}-wrapper`}\n        onClick={() => setOpen(true)}\n        style={{ borderRadius: 8 }}\n        className=\"flex h-9 items-center border bg-white px-3 text-sm font-medium outline-none dark:bg-[#121212]\"\n      >\n        <motion.span layoutId={`${title}-title`}>{title}</motion.span>\n      </motion.button>\n      <AnimatePresence>\n        {open && (\n          <motion.div\n            layoutId={`${title}-wrapper`}\n            className=\"bg-muted absolute overflow-hidden p-1 shadow-[0_0_0_1px_rgba(0,0,0,0.08),0px_1px_2px_rgba(0,0,0,0.04)] outline-none\"\n            ref={ref}\n            style={{ borderRadius: 10, width, height }}\n          >\n            <motion.span\n              aria-hidden\n              className=\"text-muted-foreground absolute top-[17px] left-4 text-sm data-[success]:text-transparent\"\n              layoutId={`${title}-title`}\n              data-success={showSuccess}\n            >\n              {title}\n            </motion.span>\n\n            {showCloseButton && (\n              <div className=\"absolute -top-[5px] left-1/2 z-20 flex h-[26px] w-[12px] -translate-x-1/2 transform items-center justify-center\">\n                <button\n                  onClick={() => setOpen(false)}\n                  className=\"text-muted-foreground hover:text-foreground absolute z-10 -mt-1 flex h-[6px] w-[10px] items-center justify-center rounded-full focus:outline-none\"\n                  aria-label=\"Close\"\n                >\n                  <ChevronUp className=\"text-muted-foreground/80\" />\n                </button>\n\n                <PopoverFormCutOutTopIcon />\n              </div>\n            )}\n\n            <AnimatePresence mode=\"popLayout\">\n              {showSuccess ? (\n                <motion.div\n                  key=\"success\"\n                  initial={{ y: -32, opacity: 0, filter: \"blur(4px)\" }}\n                  animate={{ y: 0, opacity: 1, filter: \"blur(0px)\" }}\n                  transition={{\n                    type: \"spring\" as const,\n                    duration: 0.4,\n                    bounce: 0,\n                  }}\n                  className=\"flex h-full flex-col items-center justify-center\"\n                >\n                  {successChild || <PopoverFormSuccess />}\n                </motion.div>\n              ) : (\n                <motion.div\n                  exit={{ y: 8, opacity: 0, filter: \"blur(4px)\" }}\n                  transition={{\n                    type: \"spring\" as const,\n                    duration: 0.4,\n                    bounce: 0,\n                  }}\n                  key=\"open-child\"\n                  style={{ borderRadius: 10 }}\n                  className=\"z-20 h-full border bg-white dark:bg-[#121212]\"\n                >\n                  {openChild}\n                </motion.div>\n              )}\n            </AnimatePresence>\n          </motion.div>\n        )}\n      </AnimatePresence>\n    </div>\n  )\n}\n\nexport function PopoverFormButton({\n  loading,\n  text = \"submit\",\n}: {\n  loading: boolean\n  text: string\n}) {\n  return (\n    <button\n      type=\"submit\"\n      className=\"from-primary/90 to-primary text-primary-foreground ml-auto flex h-6 w-26 items-center justify-center overflow-hidden rounded-md bg-gradient-to-b px-3 text-xs font-semibold shadow-[0_0_1px_1px_rgba(255,255,255,0.08)_inset,0_1px_1.5px_0_rgba(0,0,0,0.32),0_0_0_0.5px_#1a94ff]\"\n    >\n      <AnimatePresence mode=\"popLayout\" initial={false}>\n        <motion.span\n          key={`${loading}`}\n          initial={{ opacity: 0, y: -25 }}\n          animate={{ opacity: 1, y: 0 }}\n          exit={{ opacity: 0, y: 25 }}\n          transition={{\n            type: \"spring\",\n            duration: 0.3,\n            bounce: 0,\n          }}\n          className=\"flex w-full items-center justify-center\"\n        >\n          {loading ? (\n            <Loader className=\"size-3 animate-spin\" />\n          ) : (\n            <span>{text}</span>\n          )}\n        </motion.span>\n      </AnimatePresence>\n    </button>\n  )\n}\n\nconst useClickOutside = (\n  ref: RefObject<HTMLElement | null>,\n  handleOnClickOutside: (event: MouseEvent | TouchEvent) => void\n) => {\n  useEffect(() => {\n    const listener = (event: MouseEvent | TouchEvent) => {\n      if (!ref.current || ref.current.contains(event.target as Node)) {\n        return\n      }\n      handleOnClickOutside(event)\n    }\n    document.addEventListener(\"mousedown\", listener)\n    document.addEventListener(\"touchstart\", listener)\n    return () => {\n      document.removeEventListener(\"mousedown\", listener)\n      document.removeEventListener(\"touchstart\", listener)\n    }\n  }, [ref, handleOnClickOutside])\n}\n\nexport function PopoverFormSuccess({\n  title = \"Success\",\n  description = \"Thank you for your submission\",\n}) {\n  return (\n    <>\n      <svg\n        width=\"32\"\n        height=\"32\"\n        viewBox=\"0 0 32 32\"\n        fill=\"none\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        className=\"-mt-1\"\n      >\n        <path\n          d=\"M27.6 16C27.6 17.5234 27.3 19.0318 26.717 20.4392C26.1341 21.8465 25.2796 23.1253 24.2025 24.2025C23.1253 25.2796 21.8465 26.1341 20.4392 26.717C19.0318 27.3 17.5234 27.6 16 27.6C14.4767 27.6 12.9683 27.3 11.5609 26.717C10.1535 26.1341 8.87475 25.2796 7.79759 24.2025C6.72043 23.1253 5.86598 21.8465 5.28302 20.4392C4.70007 19.0318 4.40002 17.5234 4.40002 16C4.40002 12.9235 5.62216 9.97301 7.79759 7.79759C9.97301 5.62216 12.9235 4.40002 16 4.40002C19.0765 4.40002 22.027 5.62216 24.2025 7.79759C26.3779 9.97301 27.6 12.9235 27.6 16Z\"\n          fill=\"#2090FF\"\n          fillOpacity=\"0.16\"\n        />\n        <path\n          d=\"M12.1334 16.9667L15.0334 19.8667L19.8667 13.1M27.6 16C27.6 17.5234 27.3 19.0318 26.717 20.4392C26.1341 21.8465 25.2796 23.1253 24.2025 24.2025C23.1253 25.2796 21.8465 26.1341 20.4392 26.717C19.0318 27.3 17.5234 27.6 16 27.6C14.4767 27.6 12.9683 27.3 11.5609 26.717C10.1535 26.1341 8.87475 25.2796 7.79759 24.2025C6.72043 23.1253 5.86598 21.8465 5.28302 20.4392C4.70007 19.0318 4.40002 17.5234 4.40002 16C4.40002 12.9235 5.62216 9.97301 7.79759 7.79759C9.97301 5.62216 12.9235 4.40002 16 4.40002C19.0765 4.40002 22.027 5.62216 24.2025 7.79759C26.3779 9.97301 27.6 12.9235 27.6 16Z\"\n          stroke=\"#2090FF\"\n          strokeWidth=\"2.4\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n        />\n      </svg>\n      <h3 className=\"text-primary mt-2 mb-1 text-sm font-medium\">{title}</h3>\n      <p className=\"text-muted-foreground mx-auto max-w-xs text-center text-sm text-pretty\">\n        {description}\n      </p>\n    </>\n  )\n}\n\nexport function PopoverFormSeparator({\n  width = 352,\n  height = 2,\n}: {\n  width?: number | string\n  height?: number\n}) {\n  return (\n    <svg\n      className=\"absolute top-[-1px] right-0 left-0\"\n      width={width}\n      height={height}\n      viewBox=\"0 0 352 2\"\n      fill=\"none\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n    >\n      <path d=\"M0 1H352\" className=\"stroke-border\" strokeDasharray=\"4 4\" />\n    </svg>\n  )\n}\n\nfunction PopoverFormCutOutTopIcon({\n  width = 44,\n  height = 30,\n}: {\n  width?: number\n  height?: number\n}) {\n  const aspectRatio = 6 / 12\n  const calculatedHeight = width * aspectRatio\n  const calculatedWidth = height / aspectRatio\n\n  const finalWidth = Math.min(width, calculatedWidth)\n  const finalHeight = Math.min(height, calculatedHeight)\n\n  return (\n    <svg\n      width={finalWidth}\n      height={finalHeight}\n      viewBox=\"0 0 6 12\"\n      fill=\"none\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      className=\"mt-[1px] rotate-90\"\n      preserveAspectRatio=\"none\"\n    >\n      <g clipPath=\"url(#clip0_2029_22)\">\n        <path\n          d=\"M0 2C0.656613 2 1.30679 2.10346 1.91341 2.30448C2.52005 2.5055 3.07124 2.80014 3.53554 3.17157C3.99982 3.54301 4.36812 3.98396 4.6194 4.46927C4.87067 4.95457 5 5.47471 5 6C5 6.52529 4.87067 7.04543 4.6194 7.53073C4.36812 8.01604 3.99982 8.45699 3.53554 8.82843C3.07124 9.19986 2.52005 9.4945 1.91341 9.69552C1.30679 9.89654 0.656613 10 0 10V6V2Z\"\n          className=\"fill-muted\"\n        />\n        <path\n          d=\"M1 12V10C2.06087 10 3.07828 9.57857 3.82843 8.82843C4.57857 8.07828 5 7.06087 5 6C5 4.93913 4.57857 3.92172 3.82843 3.17157C3.07828 2.42143 2.06087 2 1 2V0\"\n          className=\"stroke-border\"\n          strokeWidth={0.6}\n          strokeLinejoin=\"round\"\n        />\n      </g>\n      <defs>\n        <clipPath id=\"clip0_2029_22\">\n          <rect width={finalWidth} height={finalHeight} fill=\"white\" />\n        </clipPath>\n      </defs>\n    </svg>\n  )\n}\n\nexport function PopoverFormCutOutLeftIcon() {\n  return (\n    <svg\n      width=\"6\"\n      height=\"12\"\n      viewBox=\"0 0 6 12\"\n      fill=\"none\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n    >\n      <g clipPath=\"url(#clip0_2029_22)\">\n        <path\n          d=\"M0 2C0.656613 2 1.30679 2.10346 1.91341 2.30448C2.52005 2.5055 3.07124 2.80014 3.53554 3.17157C3.99982 3.54301 4.36812 3.98396 4.6194 4.46927C4.87067 4.95457 5 5.47471 5 6C5 6.52529 4.87067 7.04543 4.6194 7.53073C4.36812 8.01604 3.99982 8.45699 3.53554 8.82843C3.07124 9.19986 2.52005 9.4945 1.91341 9.69552C1.30679 9.89654 0.656613 10 0 10V6V2Z\"\n          className=\"fill-muted\"\n        />\n        <path\n          d=\"M1 12V10C2.06087 10 3.07828 9.57857 3.82843 8.82843C4.57857 8.07828 5 7.06087 5 6C5 4.93913 4.57857 3.92172 3.82843 3.17157C3.07828 2.42143 2.06087 2 1 2V0\"\n          className=\"stroke-border\"\n          strokeWidth=\"1\"\n          strokeLinejoin=\"round\"\n        />\n      </g>\n      <defs>\n        <clipPath id=\"clip0_2029_22\">\n          <rect width=\"6\" height=\"12\" fill=\"white\" />\n        </clipPath>\n      </defs>\n    </svg>\n  )\n}\n\nexport function PopoverFormCutOutRightIcon() {\n  return (\n    <svg\n      width=\"6\"\n      height=\"12\"\n      viewBox=\"0 0 6 12\"\n      fill=\"none\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n    >\n      <g clipPath=\"url(#clip0_2029_22)\">\n        <path\n          d=\"M0 2C0.656613 2 1.30679 2.10346 1.91341 2.30448C2.52005 2.5055 3.07124 2.80014 3.53554 3.17157C3.99982 3.54301 4.36812 3.98396 4.6194 4.46927C4.87067 4.95457 5 5.47471 5 6C5 6.52529 4.87067 7.04543 4.6194 7.53073C4.36812 8.01604 3.99982 8.45699 3.53554 8.82843C3.07124 9.19986 2.52005 9.4945 1.91341 9.69552C1.30679 9.89654 0.656613 10 0 10V6V2Z\"\n          className=\"fill-muted\"\n        />\n        <path\n          d=\"M1 12V10C2.06087 10 3.07828 9.57857 3.82843 8.82843C4.57857 8.07828 5 7.06087 5 6C5 4.93913 4.57857 3.92172 3.82843 3.17157C3.07828 2.42143 2.06087 2 1 2V0\"\n          className=\"stroke-border\"\n          strokeWidth=\"1\"\n          strokeLinejoin=\"round\"\n        />\n      </g>\n      <defs>\n        <clipPath id=\"clip0_2029_22\">\n          <rect width=\"6\" height=\"12\" fill=\"white\" />\n        </clipPath>\n      </defs>\n    </svg>\n  )\n}\n\nexport default PopoverForm\n",
      "type": "registry:ui"
    }
  ]
}