From 59ffa8753544f6f0574518da8afdf47a2375bf99 Mon Sep 17 00:00:00 2001 From: Manjunath Paparaju Date: Fri, 13 Nov 2026 10:44:45 +0530 Subject: [PATCH] Keep the left rail's order when its open item is lifted out Co-authored-by: Sameh Khamis --- src/ui/railEdgeScroll.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/ui/railEdgeScroll.js b/src/ui/railEdgeScroll.js index 57d94a998..4dfd56df6 100644 --- a/src/ui/railEdgeScroll.js +++ b/src/ui/railEdgeScroll.js @@ -61,9 +61,25 @@ export function installRailEdgeScroll(doc = globalThis.document) { // Vue rewrites a rail's class list when it folds its labels, so whether the // highlight is showing is kept here, and the classes are put back each time. const gliding = new WeakSet(); + + // Where a rail lifts its open item out to sit beside the panel's title, the + // items left in the rail follow on from it in turn, so the next one in line + // is the one directly under it and a step brings that one up. A rail that + // keeps its open item in place keeps its own order. + function reorder(rail, on) { + const slots = [...rail.children].filter((slot) => slot.querySelector?.('.ui-rail__item')); + const at = on ? slots.findIndex((slot) => slot.contains(on)) : -1; + const lifted = at >= 0 && win.getComputedStyle(slots[at]).position === 'absolute'; + slots.forEach((slot, index) => { + const order = lifted ? String((index - at + slots.length) % slots.length) : ''; + if (slot.style.order !== order) slot.style.order = order; + }); + } + function glide(rail) { rail.classList.toggle('ui-rail--edge-hot', rail === hot); const on = rail.querySelector('.ui-rail__item[aria-pressed="true"]'); + reorder(rail, on); if (!on?.offsetWidth) { gliding.delete(rail); rail.classList.remove('ui-rail--glide'); @@ -245,8 +261,9 @@ export function installRailEdgeScroll(doc = globalThis.document) { doc.removeEventListener('pointerout', onLeave); win.removeEventListener('wheel', onWheel, { capture: true }); win.removeEventListener('resize', onResize); - doc.querySelectorAll('.ui-rail').forEach((rail) => - rail.classList.remove('ui-rail--glide', 'ui-rail--glide-jump', 'ui-rail--edge-hot'), - ); + doc.querySelectorAll('.ui-rail').forEach((rail) => { + rail.classList.remove('ui-rail--glide', 'ui-rail--glide-jump', 'ui-rail--edge-hot'); + reorder(rail, null); + }); }; }