From af3dc018c7bec4ab8770ab6467419cbd13651da3 Mon Sep 17 00:00:00 2001 From: Pouzor Date: Sat, 18 Jul 2026 01:51:57 +0200 Subject: [PATCH] feat(properties): drag to reorder node properties Add native HTML5 drag-and-drop reorder to the property list in the detail panel. A grip handle appears when more than one property exists; dragging updates property order (persisted with canvas save) and is undoable via history snapshot. Closes #292 ha-relevant: yes --- .../src/components/panels/DetailPanel.tsx | 53 +++++++++++++++++-- .../panels/__tests__/DetailPanel.test.tsx | 38 +++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/panels/DetailPanel.tsx b/frontend/src/components/panels/DetailPanel.tsx index b75ff31..2a65e19 100644 --- a/frontend/src/components/panels/DetailPanel.tsx +++ b/frontend/src/components/panels/DetailPanel.tsx @@ -1,5 +1,5 @@ import { createElement, useRef, useState } from 'react' -import { X, Edit, Trash2, ExternalLink, Plus, Pencil, Layers, Ungroup, Eye, EyeOff } from 'lucide-react' +import { X, Edit, Trash2, ExternalLink, Plus, Pencil, Layers, Ungroup, Eye, EyeOff, GripVertical } from 'lucide-react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' @@ -37,6 +37,8 @@ export function DetailPanel({ onEdit }: DetailPanelProps) { const [newProp, setNewProp] = useState(EMPTY_PROP) const [editingPropIndex, setEditingPropIndex] = useState(null) const [editProp, setEditProp] = useState(EMPTY_PROP) + const [dragPropIndex, setDragPropIndex] = useState(null) + const [dragOverPropIndex, setDragOverPropIndex] = useState(null) // Multi-select panel const multiSelected = (selectedNodeIds ?? []).filter((id) => nodes.some((n) => n.id === id)) @@ -202,6 +204,15 @@ export function DetailPanel({ onEdit }: DetailPanelProps) { setEditingPropIndex(null) } + const handleReorderProp = (from: number, to: number) => { + if (from === to || from < 0 || to < 0 || from >= properties.length || to >= properties.length) return + snapshotHistory() + const reordered = [...properties] + const [moved] = reordered.splice(from, 1) + reordered.splice(to, 0, moved) + updateNode(node.id, { properties: reordered }) + } + return (