| 17 | } |
| 18 | |
| 19 | export function ScaleDropdown({ activeScales, onToggleScale }: ScaleDropdownProps) { |
| 20 | const [isOpen, setIsOpen] = useState(false); |
| 21 | const containerRef = useRef<HTMLDivElement>(null); |
| 22 | |
| 23 | useEffect(() => { |
| 24 | function handleClickOutside(event: MouseEvent) { |
| 25 | if (containerRef.current && !containerRef.current.contains(event.target as Node)) { |
| 26 | setIsOpen(false); |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | document.addEventListener("click", handleClickOutside); |
| 31 | return () => document.removeEventListener("click", handleClickOutside); |
| 32 | }, []); |
| 33 | |
| 34 | const hasActive = activeScales.size > 0; |
| 35 | |
| 36 | return ( |
| 37 | <div className={cn("scale-dropdown", isOpen && "open")} ref={containerRef}> |
| 38 | <button |
| 39 | className={cn("control-btn", hasActive && "active")} |
| 40 | onClick={() => setIsOpen(!isOpen)} |
| 41 | aria-expanded={isOpen} |
| 42 | aria-haspopup="menu" |
| 43 | > |
| 44 | <Ruler size={14} weight="regular" aria-hidden="true" /> |
| 45 | Scale |
| 46 | </button> |
| 47 | <div className="scale-menu" role="menu" aria-label="Scale references"> |
| 48 | <div className="scale-menu-header">Scale References</div> |
| 49 | <div> |
| 50 | {scaleReferences.map((ref) => { |
| 51 | const Icon = iconMap[ref.icon] || Plant; |
| 52 | const isChecked = activeScales.has(ref.id); |
| 53 | |
| 54 | return ( |
| 55 | <button |
| 56 | key={ref.id} |
| 57 | className="scale-menu-item" |
| 58 | onClick={(e) => { |
| 59 | e.stopPropagation(); |
| 60 | onToggleScale(ref.id); |
| 61 | }} |
| 62 | role="menuitemcheckbox" |
| 63 | aria-checked={isChecked} |
| 64 | > |
| 65 | <div className={cn("scale-checkbox", isChecked && "checked")} aria-hidden="true" /> |
| 66 | <Icon size={18} weight="regular" aria-hidden="true" /> |
| 67 | <div className="scale-menu-item-info"> |
| 68 | <div className="scale-menu-item-name">{ref.name}</div> |
| 69 | <div className="scale-menu-item-desc">{ref.desc}</div> |
| 70 | </div> |
| 71 | </button> |
| 72 | ); |
| 73 | })} |
| 74 | </div> |
| 75 | </div> |
| 76 | </div> |