Fix structure tree drag feedback: stable ➕ rows, on-row child drops

Rework the site structure tree's drag-and-drop to match Sortable's native
model instead of mid-drag drop zones:

- Drop the dashed empty-list drop zones that appeared on drag start
  (flicker, space reservation, and mis-targeted drops: the last item's
  child zone sat exactly where 'end of parent list' was).
- Every non-empty list (and the root) ends with a non-draggable ➕ footer
  row (vuedraggable #footer slot): click to start a new page at that
  level, and while dragging it is the 'end of this list' drop target.
  It renders last even mid-drag via flex order, since Sortable appends
  end-of-list previews after it in the DOM.
- Dropping ON the lower part of a row makes the page that row's first
  child: the child list's container invisibly overlaps its own row's
  bottom (negative margin + equal padding, no layout effect) and becomes
  hit-testable only while dragging. A row's exposed top strip remains
  the 'sibling before' target. Leaf rows work too, creating a sublist.
- Indentation is structural (each nested list margin-indents itself), so
  a dragged row previews its whole subtree at the target list's depth.
  Rows get a little vertical padding to widen the drop zones.
This commit is contained in:
LeoVasanko committed 2026-08-16 18:05:33 +00:00
1 parent e38063a522
commit 3dc438f8df
5 files changed
+121 -61

No files matched your search

+11 -7
View File
@@ -167,14 +167,18 @@ evolves.
insert `![alt](/_/f/hash.ext)` at the cursor.
- The **structure panel** (vue-draggable tree of the whole site, in site
mode) covers page management: reorder any menu level, drag across
sections (empty child lists appear as drop zones while dragging), add,
delete (two clicks: the button arms, then deletes — no dialogs).
Every node is a real label — content-less category rows offer a
➕ to give them a landing page.
sections, add, delete (two clicks: the button arms, then deletes — no
dialogs). Every node is a real label — content-less category rows offer
a ➕ to give them a landing page.
Deleting a category removes only its landing page (the label and its
subpages stay). The ➕ in the panel header starts a new page as a
local-only tree row that can be dragged into place before its title and
slug are filled in; it is persisted only on commit. Rows are always
subpages stay). Every non-empty list ends with a ➕ row that starts a
new page as a local-only tree row at that level; the row can be dragged
into place before its title and slug are filled in and is persisted only
on commit. While dragging, these ➕ rows double as "end of this list"
drop targets; dropping ON the lower part of a row makes the page that
row's first child (even a leaf's, creating a sublist), while a row's
exposed top edge inserts a sibling before it. A dragged row's
indentation previews the target list's depth. Rows are always
editable: titles save while typing, slug edits commit on blur/Enter
since they rename the path (moving the whole subtree). The front page
is the root row with an empty slug — renaming it away leaves no front