Sha256: 95a663a71521da7a26f7e7a5a98327177e42489e45b6f94bffa2325c1bfc2835
Contents?: true
Size: 1.63 KB
Versions: 46
Compression:
Stored size: 1.63 KB
Contents
import React, { useState, useRef, useEffect } from "react"; import { X } from "lucide-react"; interface PopoverProps { trigger: React.ReactElement; children: React.ReactNode; className?: string; } export function Popover({ trigger, children, className = "" }: PopoverProps) { const [isOpen, setIsOpen] = useState(false); const popoverRef = useRef<HTMLDivElement>(null); const triggerRef = useRef<HTMLDivElement>(null); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( popoverRef.current && !popoverRef.current.contains(event.target as Node) && !triggerRef.current?.contains(event.target as Node) ) { setIsOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, []); return ( <div className="relative"> <div ref={triggerRef} onClick={() => setIsOpen(!isOpen)}> {trigger} </div> {isOpen && ( <div ref={popoverRef} className={`absolute z-50 right-0 mt-2 bg-white rounded-lg shadow-lg border border-gray-200 ${className}`} > <div className="flex justify-between items-center p-3 border-b border-gray-200"> <h3 className="font-medium">Feature Configuration</h3> <button onClick={() => setIsOpen(false)} className="text-gray-400 hover:text-gray-600" > <X className="w-4 h-4" /> </button> </div> <div className="p-4">{children}</div> </div> )} </div> ); }
Version data entries
46 entries across 46 versions & 1 rubygems