From 25db053a7b94b9a75411f48e4a461a17f357d0b1 Mon Sep 17 00:00:00 2001 From: Sebastian Seedorf Date: Wed, 3 Jun 2026 13:08:05 +0200 Subject: [PATCH] feat: draggable resizer between plot and legend in chart cards --- web/components/ChartCard/CardShell.tsx | 50 +++++++++++++++++++++----- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/web/components/ChartCard/CardShell.tsx b/web/components/ChartCard/CardShell.tsx index 79f38c7..f753c0a 100644 --- a/web/components/ChartCard/CardShell.tsx +++ b/web/components/ChartCard/CardShell.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useRef, useState, useCallback } from 'react'; interface HeaderProps { title: string; @@ -32,23 +32,55 @@ interface CardShellProps extends HeaderProps { } export function CardShell({ title, onEdit, onDelete, empty, children, legendContainerRef }: CardShellProps) { + const containerRef = useRef(null); + const [legendHeight, setLegendHeight] = useState(null); + const dragRef = useRef<{ startY: number; startH: number } | null>(null); + + const handleMouseDown = useCallback((e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + const el = legendContainerRef?.current; + if (!el) return; + dragRef.current = { startY: e.clientY, startH: el.offsetHeight }; + + function onMove(ev: MouseEvent) { + if (!dragRef.current) return; + const delta = dragRef.current.startY - ev.clientY; + const containerH = containerRef.current?.offsetHeight ?? 400; + const newH = Math.max(32, Math.min(containerH - 64, dragRef.current.startH + delta)); + setLegendHeight(newH); + } + function onUp() { + dragRef.current = null; + document.removeEventListener('mousemove', onMove); + document.removeEventListener('mouseup', onUp); + } + document.addEventListener('mousemove', onMove); + document.addEventListener('mouseup', onUp); + }, [legendContainerRef]); + return ( -
+
{empty ? ( ) : ( <> - {/* Plot fills remaining space */}
{children}
- {/* Legend scrolls independently, capped at 25% card height */} -
- + {legendContainerRef && <> +
+
+ + } )}