From d627bc80651d3f9fef6b989a5291d1f6e2563e99 Mon Sep 17 00:00:00 2001 From: Pranav-IIITM Date: Sat, 23 May 2026 08:46:59 +0530 Subject: [PATCH] feat: add collapsible accordion sections to editor layout (#895) --- src/components/VideoEditor.tsx | 141 +++++++++++++++++++++++++++++---- 1 file changed, 126 insertions(+), 15 deletions(-) diff --git a/src/components/VideoEditor.tsx b/src/components/VideoEditor.tsx index 6e297539..d7a69231 100644 --- a/src/components/VideoEditor.tsx +++ b/src/components/VideoEditor.tsx @@ -48,6 +48,72 @@ function Section({ icon, title, children, delay = 0 }: SectionProps) { ); } +/** Accordion section with collapsible content. */ +function AccordionSection({ + id, + icon, + title, + children, + isOpen, + onToggle, + delay = 0, +}: { + id: string; + icon: React.ReactNode; + title: string; + children: React.ReactNode; + isOpen: boolean; + onToggle: () => void; + delay?: number; +}) { + const contentRef = useRef(null); + + useEffect(() => { + if (!contentRef.current) return; + if (isOpen) { + contentRef.current.style.maxHeight = `${contentRef.current.scrollHeight}px`; + } else { + contentRef.current.style.maxHeight = `0px`; + } + }, [isOpen]); + + return ( +
+ + +
+
{children}
+
+
+ ); +} + /** Inline keyboard hint badge. */ function Kbd({ children }: { children: React.ReactNode }) { return ( @@ -123,6 +189,16 @@ export default function VideoEditor() { } = useVideoEditor(); const [copied, setCopied] = useState(false); const [shareCopied, setShareCopied] = useState(false); + const [openSections, setOpenSections] = useState({ + resize: true, + trim: false, + rotation: false, + audio: false, + export: false, + }); + + const toggleSection = (key: keyof typeof openSections) => + setOpenSections((prev) => ({ ...prev, [key]: !prev[key] })); const downloadRef = useRef(null); const handleCopyLink = () => { @@ -229,22 +305,44 @@ export default function VideoEditor() { isProcessing && "pointer-events-none opacity-50" )}>
-
} title="Trim" delay={50}> + } + title="Trim" + isOpen={openSections.trim} + onToggle={() => toggleSection("trim")} + delay={50} + > -
-
} title="Rotate" delay={100}> + + + } + title="Rotation" + isOpen={openSections.rotation} + onToggle={() => toggleSection("rotation")} + delay={100} + > -
+
-
} title="Audio & Speed" delay={150}> + } + title="Audio & Speed" + isOpen={openSections.audio} + onToggle={() => toggleSection("audio")} + delay={150} + > -
+
} title="Adjustments" @@ -331,9 +429,16 @@ export default function VideoEditor() {
} title="Output format" delay={190}>
-
} title="Export quality" delay={200}> + } + title="Export" + isOpen={openSections.export} + onToggle={() => toggleSection("export")} + delay={200} + > -
+
} title="Image overlay" delay={120}>
-
} title="Output size"> + } + title="Resize & Aspect Ratio" + isOpen={openSections.resize} + onToggle={() => toggleSection("resize")} + delay={50} + > {recommendedPreset && (

@@ -406,11 +518,10 @@ export default function VideoEditor() {

)} -
- -
} title="Framing" delay={100}> - -
+
+ +
+