From 183efacc93c46f74e50c111cf7b3daa901251d25 Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Sat, 10 Oct 2026 04:10:05 +0200 Subject: [PATCH] fix(tabs): no drag while a rail search is active (#580) From the owner's review of #580 rather than the bot's report: "Drag while searching: I'd turn it off. A drop is saved for every device (session order or the tab layout), and where it lands relative to the rows the search is hiding is something you only see after clearing it." The PR head left drag on. Both rail drags now refuse while the search narrows the list: the grouped rail's pointer drag in _onTabLayoutPointerDown(), and the flat manual rail's HTML5 drag in its dragstart listener. The flat rail is refused in the listener, not by flipping `draggable`, because a keystroke in the box does not re-render the rows, so a cleared search drags again with the same rows. The sidebar filter box, the header strip and the keyboard moves (Ctrl+Shift+{ }, the row menu) are unchanged. Tests: a grouped-rail press during a search starts no drag and one after clearing does; a flat-rail dragstart during a search is refused and one after clearing goes through. CLAUDE.md and the Dashboard wiki row say so. Co-Authored-By: Claude Opus 5.5 (1M context) --- CLAUDE.md | 2 +- docs/wiki/The-Dashboard.md | 2 +- src/web/public/app.js | 11 ++++++++ test/tab-rail-search.test.ts | 55 ++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 28e10208..aa8536a8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -337,7 +337,7 @@ Frontend JS modules have `@fileoverview` with `@dependency`/`@loadorder` tags. L **Mobile tab strip scrolling** (issue #257): under 768px the tab strip scrolls horizontally, so the active tab must be kept reachable. `_updateActiveTabImmediate()` reveals it via `computeTabScrollLeft()` (constants.js, rect math on the strip's own `scrollLeft`, never `scrollIntoView()`, which scrolls the document under the fixed header); `_fullRenderSessionTabs()` must restore `scrollLeft` across rebuilds and re-reveal only when the active tab changed (`_lastRenderedActiveTabId`) or, grouped by state, the ACTIVE tab moved to another state band (`_noteActiveTabBand()`, both render paths, scrolling row only; another tab's move never scrolls). ⚠️ The phone-block `min-width` on `.session-tab.active .tab-name` keeps the tab's centre off the gear/close icons, sized for numberless tabs 10+ (floor 40px); do not shrink it. ⚠️ Never reintroduce hoisting the active session to the front of the strip. Tests: `test/mobile-tab-tap-zones.test.ts`, `test/tab-triage.test.ts`. → [architecture-invariants#mobile-tab-strip-scrolling](docs/architecture-invariants.md#mobile-tab-strip-scrolling) -**Session list layout: header strip or left sidebar** (`sessionListLayout`, default `header`; per-device via `displayKeys`, also in `SettingsUpdateSchema`): the list can move into a collapsible `