From 46b3618bd482f9313de708981fdebcb29b253214 Mon Sep 17 00:00:00 2001 From: ShobhitPatra Date: Thu, 5 Mar 2026 16:14:46 +0530 Subject: [PATCH] feat(docs): style playground chord selector as custom dropdown --- .../components/playground/chord-selector.tsx | 146 +++++++++++++++--- 1 file changed, 124 insertions(+), 22 deletions(-) diff --git a/apps/docs/components/playground/chord-selector.tsx b/apps/docs/components/playground/chord-selector.tsx index 92db60a..f26612f 100644 --- a/apps/docs/components/playground/chord-selector.tsx +++ b/apps/docs/components/playground/chord-selector.tsx @@ -1,7 +1,9 @@ "use client"; +import { useState, useRef, useEffect } from "react"; import type { ChordId } from "@/lib/playground/types"; import { + chordRegistry, majorChords, minorChords, } from "@/lib/playground/chord-registry"; @@ -13,35 +15,135 @@ export function ChordSelector({ chordId: ChordId; onChange: (id: ChordId) => void; }) { + const [open, setOpen] = useState(false); + const containerRef = useRef(null); + const selected = chordRegistry[chordId]; + + useEffect(() => { + function handleClickOutside(e: MouseEvent) { + if ( + containerRef.current && + !containerRef.current.contains(e.target as Node) + ) { + setOpen(false); + } + } + if (open) { + document.addEventListener("mousedown", handleClickOutside); + return () => + document.removeEventListener("mousedown", handleClickOutside); + } + }, [open]); + return (
- +
+ + + {open && ( +
+ { + onChange(id); + setOpen(false); + }} + /> +
+ { + onChange(id); + setOpen(false); + }} + /> +
+ )} +

- {majorChords.find((c) => c.id === chordId)?.description ?? - minorChords.find((c) => c.id === chordId)?.description} + {selected.description}

); } + +function ChordGroup({ + label, + chords, + activeId, + onSelect, +}: { + label: string; + chords: { id: ChordId; name: string }[]; + activeId: ChordId; + onSelect: (id: ChordId) => void; +}) { + return ( +
+
+ {label} +
+ {chords.map((c) => ( + + ))} +
+ ); +}