dropdown.tsx 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import React, { useState, useRef, useEffect } from 'react';
  2. interface DropdownProps {
  3. trigger: React.ReactNode;
  4. children: React.ReactNode;
  5. disabled?: boolean;
  6. }
  7. export default function Dropdown({ trigger, children, disabled = false }: DropdownProps) {
  8. const [isOpen, setIsOpen] = useState(false);
  9. const dropdownRef = useRef<HTMLDivElement>(null);
  10. useEffect(() => {
  11. const handleClickOutside = (event: MouseEvent) => {
  12. if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
  13. setIsOpen(false);
  14. }
  15. };
  16. document.addEventListener('mousedown', handleClickOutside);
  17. return () => {
  18. document.removeEventListener('mousedown', handleClickOutside);
  19. };
  20. }, []);
  21. const handleTriggerClick = () => {
  22. if (!disabled) {
  23. setIsOpen(!isOpen);
  24. }
  25. };
  26. return (
  27. <div className="relative" ref={dropdownRef}>
  28. <div
  29. onClick={handleTriggerClick}
  30. className={disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
  31. >
  32. {trigger}
  33. </div>
  34. {isOpen && !disabled && (
  35. <div className="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg border border-gray-200 z-50">
  36. <div className="py-1">
  37. {children}
  38. </div>
  39. </div>
  40. )}
  41. </div>
  42. );
  43. }