One direction to drop in, and a new note that stays on top
Every new note pulled the arrangement apart. A note was made with no position and left to the tie-break, which put it near the top by age -- which is not the same thing. A separator's position counts the rows above it, so a row appearing without a renumber left every line one row too high. placeOnTop builds the order from the list *without* the new note and puts it in front: measuring the room after the furniture has moved would write the misreading back as the truth. A drop now lands the row under the one it was released on, and only there. Dropping above a row and dropping below the row before it are the same move described twice, so every gap could be aimed at from two sides. The strip above the first row is the one place a drop under something cannot reach. A chapter could only be dropped into, never dragged past: taking the whole row as a place quietly took reordering away. The bottom edge of its header is the gap now, the rest of the row is still the chapter. A link showed the sheet of paper whatever it pointed at. The @ menu dropped the mark on the way into the link, and the refresh that keeps a link current ran once, while the editor was still empty -- content is poured in afterwards without an update event, so nothing ever looked again. The mark in the title bar and the box in a task list were each centred on a line box rather than on the letters in it, which is not the same as being on one line. The mark shares the title's baseline; the box is centred on the capitals and sized in em. Move to... is divided under headings that are deliberately not shaped like entries, and each row carries the mark its chapter or notebook wears. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2ffa357dfc
commit
a9391cdcf2
15 files changed
+724
-189
No files matched your search
@@ -106,10 +106,27 @@ export function useReorderDrag(
|
||||
const row = el?.closest?.("[data-reorder-id]") as HTMLElement | null;
|
||||
const target = row?.dataset.reorderId ?? null;
|
||||
const next = target && target !== d.id ? target : null;
|
||||
/* A chapter takes what is dropped on it rather than standing beside it,
|
||||
* which is what "drag it into the chapter" means. Filing is only offered
|
||||
* when there is somewhere to file *to*. */
|
||||
const into = next && row?.dataset.reorderInto !== undefined && fileInto ? next : null;
|
||||
/* A chapter is both a place and a neighbour, so which one it is depends on
|
||||
* where in the row the pointer is.
|
||||
*
|
||||
* Anywhere on the row meant "into", and that quietly took reordering away:
|
||||
* a chapter could no longer be moved among its neighbours, and nothing —
|
||||
* note or line — could be put in the gap under one. The bottom edge is
|
||||
* that gap; the body of the row is the chapter itself and takes what is
|
||||
* carried in. The indicator says which: a line in the gap, the whole row
|
||||
* lit up when it is about to take something. */
|
||||
let into: string | null = null;
|
||||
if (next && row && row.dataset.reorderInto !== undefined && fileInto) {
|
||||
// The header, not the row: an open chapter's row includes the notes
|
||||
// inside it, and an edge measured on *that* would be half a notebook.
|
||||
const head = (row.querySelector("[data-reorder-head]") as HTMLElement | null) || row;
|
||||
const rect = head.getBoundingClientRect();
|
||||
const edge = Math.min(10, rect.height / 3);
|
||||
// Only that band is the gap. Below it lie the chapter's own notes, and
|
||||
// holding over them plainly means the chapter.
|
||||
const inGap = e.clientY >= rect.bottom - edge && e.clientY <= rect.bottom;
|
||||
if (!inGap) into = next;
|
||||
}
|
||||
if (into !== intoRef.current) {
|
||||
intoRef.current = into;
|
||||
setIntoId(into);
|
||||
|
||||
Reference in new issue
Block a user