diff --git a/components/canvas/nodes/compare-node.tsx b/components/canvas/nodes/compare-node.tsx index 30c5132..c533477 100644 --- a/components/canvas/nodes/compare-node.tsx +++ b/components/canvas/nodes/compare-node.tsx @@ -153,17 +153,41 @@ export default function CompareNode({ id, data, selected, width }: NodeProps) { manualDisplayMode ?? (shouldDefaultToPreview ? "preview" : "render"); const previewNodeWidth = Math.max(240, Math.min(640, Math.round(width ?? 500))); + const setSliderPercent = useCallback((value: number) => { + setSliderX(Math.max(0, Math.min(100, value))); + }, []); + + const handleSliderKeyDown = useCallback((event: React.KeyboardEvent) => { + let nextValue: number | null = null; + const step = event.shiftKey ? 10 : 2; + + if (event.key === "ArrowLeft" || event.key === "ArrowDown") { + nextValue = sliderX - step; + } else if (event.key === "ArrowRight" || event.key === "ArrowUp") { + nextValue = sliderX + step; + } else if (event.key === "Home") { + nextValue = 0; + } else if (event.key === "End") { + nextValue = 100; + } + + if (nextValue === null) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + setSliderPercent(nextValue); + }, [setSliderPercent, sliderX]); + const handleMouseDown = useCallback((event: React.MouseEvent) => { event.stopPropagation(); const move = (moveEvent: MouseEvent) => { if (!containerRef.current) return; const rect = containerRef.current.getBoundingClientRect(); - const x = Math.max( - 0, - Math.min(1, (moveEvent.clientX - rect.left) / rect.width), - ); - setSliderX(x * 100); + const x = Math.max(0, Math.min(1, (moveEvent.clientX - rect.left) / rect.width)); + setSliderPercent(x * 100); }; const up = () => { @@ -173,7 +197,7 @@ export default function CompareNode({ id, data, selected, width }: NodeProps) { window.addEventListener("mousemove", move); window.addEventListener("mouseup", up); - }, []); + }, [setSliderPercent]); const handleTouchStart = useCallback((event: React.TouchEvent) => { event.stopPropagation(); @@ -183,7 +207,7 @@ export default function CompareNode({ id, data, selected, width }: NodeProps) { const rect = containerRef.current.getBoundingClientRect(); const touch = moveEvent.touches[0]; const x = Math.max(0, Math.min(1, (touch.clientX - rect.left) / rect.width)); - setSliderX(x * 100); + setSliderPercent(x * 100); }; const end = () => { @@ -193,7 +217,7 @@ export default function CompareNode({ id, data, selected, width }: NodeProps) { window.addEventListener("touchmove", move); window.addEventListener("touchend", end); - }, []); + }, [setSliderPercent]); return ( @@ -289,9 +313,18 @@ export default function CompareNode({ id, data, selected, width }: NodeProps) { className="pointer-events-none absolute bottom-0 top-0 z-10 w-0.5 bg-white shadow-md" style={{ left: `${sliderX}%` }} /> -
@@ -304,7 +337,7 @@ export default function CompareNode({ id, data, selected, width }: NodeProps) { />
-
+ )} diff --git a/components/dashboard/canvas-card.tsx b/components/dashboard/canvas-card.tsx index 886fc86..ef435fb 100644 --- a/components/dashboard/canvas-card.tsx +++ b/components/dashboard/canvas-card.tsx @@ -14,7 +14,6 @@ import { DialogFooter, DialogHeader, DialogTitle, - DialogTrigger, } from "@/components/ui/dialog"; import { DropdownMenu, @@ -128,36 +127,48 @@ export default function CanvasCard({ canvas, onNavigate }: CanvasCardProps) { <>
- {/* Avatar */} -
- {canvas.name.slice(0, 1).toUpperCase()} -
+ {isEditing ? ( +
+
+ {canvas.name.slice(0, 1).toUpperCase()} +
+
+ setEditName(e.target.value)} + onKeyDown={handleKeyDown} + onBlur={handleBlur} + disabled={isSaving} + autoFocus + className="h-auto border bg-transparent px-1.5 py-0.5 text-sm font-medium focus-visible:ring-1" + /> +

Canvas

+
+
+ ) : ( + + )} {/* Actions - positioned to not overlap with content */} {!isEditing && ( @@ -169,21 +180,14 @@ export default function CanvasCard({ canvas, onNavigate }: CanvasCardProps) { - e.stopPropagation()} - > - e.stopPropagation()} - > + + Umbenennen @@ -193,7 +197,6 @@ export default function CanvasCard({ canvas, onNavigate }: CanvasCardProps) { onSelect={() => { setDeleteOpen(true); }} - onClick={(e) => e.stopPropagation()} > Löschen