From f6a80e38f9a884d35edf24e0941de844336ee469 Mon Sep 17 00:00:00 2001 From: Faisal Misbah Date: Fri, 20 Feb 2026 08:36:34 +0500 Subject: [PATCH] Sidebar auto-scroll when dragging relation members near top/bottom (fixes #11897) --- CHANGELOG.md | 3 +++ modules/ui/sections/raw_member_editor.js | 24 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7700091fa3b..d1e7f007d75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ _Breaking developer changes, which may affect downstream projects or sites that ##### 2026-03-02 #### :sparkles: Usability & Accessibility +* Sidebar auto-scrolls when dragging relation members near top or bottom edge (fixes [#11897], thanks [@FaisalMisbah23]) * Show warning when attempting to paste but nothing has been copied ([#9401], thanks [@omsaraykar]) * Don't suggest values from Taginfo for `addr:*` tags ([#11733], thanks [@k-yle]) * Don't suggest values from Taginfo for tags with less than 100 uses, even if they're documented on the wiki ([#11794], thanks [@Kaushik4141]) @@ -162,6 +163,8 @@ _Breaking developer changes, which may affect downstream projects or sites that [be0a20e59]: https://github.com/openstreetmap/iD/commit/be0a20e59 [b06496780]: https://github.com/openstreetmap/iD/commit/b06496780 [#id-tagging-schema/pull/1507]: https://github.com/openstreetmap/id-tagging-schema/pull/1507 +[#11897]: https://github.com/openstreetmap/iD/issues/11897 +[@FaisalMisbah23]: https://github.com/FaisalMisbah23 [@ilias52730]: https://github.com/ilias52730 [@Razen04]: https://github.com/Razen04 [@homersimpsons]: https://github.com/homersimpsons diff --git a/modules/ui/sections/raw_member_editor.js b/modules/ui/sections/raw_member_editor.js index d5a16c0cee4..61d9b1e59c2 100644 --- a/modules/ui/sections/raw_member_editor.js +++ b/modules/ui/sections/raw_member_editor.js @@ -305,7 +305,9 @@ export function uiSectionRawMemberEditor(context) { items.select('button.member-delete') .on('click', deleteMember); - var dragOrigin, targetIndex; + var dragOrigin, targetIndex, scrollContainer; + var scrollEdgeThreshold = 40; + var scrollSpeed = 10; items.call(d3_drag() .on('start', function(d3_event) { @@ -314,6 +316,7 @@ export function uiSectionRawMemberEditor(context) { y: d3_event.y }; targetIndex = null; + scrollContainer = selection.node().closest('.inspector-body'); }) .on('drag', function(d3_event) { var x = d3_event.x - dragOrigin.x, @@ -330,6 +333,23 @@ export function uiSectionRawMemberEditor(context) { targetIndex = null; + // Auto-scroll sidebar when dragging near top or bottom edge (fixes #11897) + if (scrollContainer) { + var se = d3_event.sourceEvent; + var clientY = (se && (se.touches && se.touches[0] ? se.touches[0].clientY : se.clientY)) ?? d3_event.clientY; + if (typeof clientY === 'number') { + var rect = scrollContainer.getBoundingClientRect(); + if (clientY - rect.top < scrollEdgeThreshold) { + scrollContainer.scrollTop = Math.max(0, scrollContainer.scrollTop - scrollSpeed); + } else if (rect.bottom - clientY < scrollEdgeThreshold) { + var maxScroll = scrollContainer.scrollHeight - scrollContainer.clientHeight; + if (maxScroll > 0) { + scrollContainer.scrollTop = Math.min(maxScroll, scrollContainer.scrollTop + scrollSpeed); + } + } + } + } + selection.selectAll('li.member-row') .style('transform', function(d2, index2) { var node = d3_select(this).node(); @@ -353,6 +373,8 @@ export function uiSectionRawMemberEditor(context) { if (!d3_select(this).classed('dragging')) return; + scrollContainer = null; + var index = items.nodes().indexOf(this); d3_select(this)