From c17dad6f1fafb8d76e105d4f4f78c9db868a01ed Mon Sep 17 00:00:00 2001 From: Aculix Technologies Date: Sun, 16 Aug 2026 18:57:59 +0530 Subject: [PATCH] fix: give editing its own button and hand the text back to dragging Making the task text clickable turned it into a button, and the drag handler skips anything inside a button. That quietly cost the row its best drag handle: press and move across the text and nothing picked the card up, so you got a text selection instead. Verified before changing anything, dragging from the text did nothing while dragging from the row's padding worked. Editing moves to a pencil next to the arrow and the bin, and the text goes back to being text. Rows also stop being selectable, since the row is a drag handle and highlighting words across one is never what you meant. The edit field keeps selection so text can still be copied out of it. A third button costs width on a phone, where all three stay visible because there is no hover. Grouping the actions so their gaps stop multiplying across the row, and drawing them at 26px, keeps most of it back: 199px of text becomes 187, 24 characters a line becomes 23. The 44px tap targets come from the overlay underneath, so a smaller drawn button does not shrink them. Also drops the click-after-drag guard, which only existed because the text was clickable. --- README.md | 2 +- src/App.svelte | 30 +++++++++++++++++------------- src/style.css | 39 +++++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index d9f4807..abe9ca4 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ The date, storage, rollover, task and undo logic lives in `src/lib/` as plain mo ### Managing Tasks - **Add a task**: Type in the input field and press Enter - **Complete a task**: Click the checkbox next to the task -- **Edit a task**: Click its text. Enter saves, Escape cancels, and clicking away saves too +- **Edit a task**: Click the pencil on the task. Enter saves, Escape cancels, and clicking away saves too - **Delete a task**: Click the delete icon on the task (it shows on hover, and is always visible on touch), or press `Delete` with the task focused - **Undo**: An Undo button appears for a few seconds after a task is deleted, cleared or moved to another day. `Cmd/Ctrl+Z` does the same. Either way the task returns to where it was - **Move a task to Tomorrow**: Click the arrow on the task, or press `Alt+→`. From Tomorrow, the arrow points back and `Alt+←` returns it to Today diff --git a/src/App.svelte b/src/App.svelte index ddf60e5..2f49ebd 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -94,12 +94,9 @@ let editingId = $state(null); let editingText = $state(''); - // A drag ends with a click event, which would otherwise drop the row you - // just moved straight into edit mode. - let suppressClick = false; function startEditing(task) { - if (suppressClick || draggedId) return; + if (draggedId) return; editingId = task.id; editingText = task.text; } @@ -478,10 +475,6 @@ if (!wasActive) return; - // Swallow the click the browser fires after this drag. - suppressClick = true; - setTimeout(() => { suppressClick = false; }, 0); - // Clearing the inline transform while the settling class supplies a // transition eases the card into its slot. Nothing else on the list moves, // because nothing else changed. @@ -769,10 +762,20 @@ aria-label="Edit {task.text}" /> {:else} - + {task.text} {/if} + +
+ + + +
{/each} diff --git a/src/style.css b/src/style.css index 230f89e..b81862c 100644 --- a/src/style.css +++ b/src/style.css @@ -280,6 +280,9 @@ html.dark .day-option.selected { .task-item { display: flex; + /* The row is a drag handle, so pressing and moving across it should carry + the card rather than highlight words. */ + user-select: none; align-items: flex-start; gap: 16px; padding: 16px 20px; @@ -385,16 +388,9 @@ html.dark .task-item.dragging { .task-text { flex: 1; min-width: 0; - text-align: left; - background: transparent; - border: none; - padding-inline: 0; /* Pads the 24px line box out to the 32px first-line band the row buttons - set, so the text centres against the checkbox. Declared as a longhand - because a `padding: 0` shorthand here would reset it. */ + set, so the text centres against the checkbox. */ padding-block: 4px; - font-family: inherit; - cursor: text; font-size: 16px; /* 24px line box, the same height as the checkbox, so the two align on the first line without nudging either. */ @@ -414,6 +410,8 @@ html.dark .task-item.dragging { .task-edit { flex: 1; min-width: 0; + /* The one place text stays selectable, so it can still be copied out. */ + user-select: text; font-family: inherit; font-size: 16px; line-height: 1.5; @@ -426,6 +424,15 @@ html.dark .task-item.dragging { outline: none; } +/* One group rather than three loose children, so the gaps between the actions + do not multiply across the row on a narrow screen. */ +.row-actions { + display: flex; + align-items: flex-start; + gap: 2px; + flex-shrink: 0; +} + .row-btn { width: 32px; height: 32px; @@ -443,6 +450,11 @@ html.dark .task-item.dragging { flex-shrink: 0; } +.edit-btn:hover { + background-color: var(--hover); + color: var(--accent); +} + .defer-btn:hover { background-color: var(--hover); color: var(--accent); @@ -617,9 +629,13 @@ html.dark .data-status.error { /* Smaller drawn box, same 44px target from the overlay below, and the margin keeps it in the 32px first-line band. */ .row-btn { - width: 28px; - height: 28px; - margin-block: 2px; + width: 26px; + height: 26px; + margin-block: 3px; + } + + .row-actions { + gap: 0; } .checkbox::after, @@ -777,7 +793,6 @@ html.dark .data-status.error { longer exists, while five newer controls had no focus ring at all. */ .checkbox:focus-visible, .row-btn:focus-visible, -.task-text:focus-visible, .task-edit:focus-visible, .theme-toggle:focus-visible, .day-option:focus-visible,