docs: tighten the right rail follow-up comments and drop a one-use helper

Comments that still spoke of the strip scrolling or of a lifted max-height say what the code does now; the tab and column comments are shorter; the changelog bullet is wrapped. panelDisclosure.js is back to its reviewed shape: railTabFor had one caller left after the header click handoff was reverted.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Fable 5.1 committed 2026-10-28 12:53:17 +04:00
1 parent 5cc63fefb0
commit e05d6a29b4
5 files changed
+35 -42

No files matched your search

+10 -9
View File
@@ -2,12 +2,13 @@
Imagery while shown) is a vertical tab strip with sideways labels instead of
an accordion of collapsed launcher cards: at most one panel is open in every
desktop HUD layout, and the open tab and its panel share one surface and
outline, like a folder tab. On a short window the rail rises toward the HUD corner above it and the tabs share the room equally, clipping the longer labels, rather than scroll. A first-time visitor on a
desktop finds Display open; a stored choice still wins. The panels' own
collapse arrows are gone on desktop: the tab opens and closes a panel, and
Escape inside one closes it and returns focus to its tab; the strip is a
keyboard-navigable tablist. The compact Radio launcher moves from Context's
header to the bottom of the strip on desktop and always opens the compact
player, also while Context is open; the player's Details button leads to the
Radio section. Saved preferences, share links and the phone sheet shell are
unchanged (gekh, #1425).
outline, like a folder tab. On a short window the rail rises toward the HUD
corner above it, and the tabs then share the room equally rather than
scroll. A first-time visitor on a desktop finds Display open; a stored
choice still wins. The panels' own collapse arrows are gone on desktop: the
tab opens and closes a panel, Escape inside one closes it and returns focus
to its tab, and the strip is a keyboard-navigable tablist. The compact Radio
launcher moves from Context's header to the bottom of the strip on desktop
and always opens the compact player, also while Context is open; the
player's Details button leads to the Radio section. Saved preferences, share
links and the phone sheet shell are unchanged (gekh, #1425).
+7 -8
View File
@@ -1488,8 +1488,8 @@ unnecessary style writes.
The compact Radio player is independent of Context: its launcher toggles it
whether Context is collapsed or open, and only an outside pointer, Escape, its
close button or its Details button closes it, never a layout pass. The
expanded Enable's reveal of the directory and Play lands its smooth scroll
even when a rail layout pass, measuring the panels, cuts it short.
reveal after the expanded Enable lands its smooth scroll even when a rail
layout pass cuts it short.
The right rail skips panels hidden by other CSS (computed `display: none`), but
keeps the collapsed panels its own exclusive presentation hides, so the owner
rule can still give them back.
@@ -1510,12 +1510,11 @@ The strip is a vertical `role="tablist"`: Up/Down
wrap, Home/End jump, the open tab (else the first) is the tab stop, Escape
inside a panel returns focus to its tab, and the strip precedes the panels in
the DOM so Tab from the open tab reaches the tool slot and then the panel.
Labels are the panels' own translated header titles. The rail's lane shares
the left rail's top; when it is too short for the strip, the rail climbs toward
the HUD corner above as far as the strip needs (`src/ui/rightPanelRail.js`),
and a lane still shorter is shared equally between the tabs: a label short
enough keeps its height, the long ones end up the same height and clip at the
end; the strip never scrolls. Under the tabs the strip's
Labels are the panels' own translated header titles. The lane's top follows the
left rail's; a strip taller than the lane lifts the rail toward the HUD corner
above (`src/ui/rightPanelRail.js`), and a lane still shorter is shared equally
between the tabs, so the long labels end up one height and clip; the strip
never scrolls. Under the tabs the strip's
column keeps a tool slot (`#right-rail-tools`) that holds the compact Radio
launcher on desktop: `src/ui/radioPanelPlacement.js` moves it there from
Context's header, and back for the phone sheet, so the compact player stays one
+3 -8
View File
@@ -13,13 +13,6 @@ function listenerScope() {
};
}
/** The strip tab that controls a right-rail panel, if the panel has one. */
function railTabFor(panel) {
return panel.ownerDocument?.querySelector?.(
`[role="tab"][aria-controls="${panel.id}"]`,
);
}
/** Bind collapse buttons and bubbling Escape to an existing panel. */
export function bindPanelDisclosure({
panel,
@@ -70,7 +63,9 @@ export function collapsePanelOnEscape(
panel.querySelector(`[data-dock-toggle-target="${panel.id}"]`) ||
panel.querySelector(`[data-collapse-target="${panel.id}"]`);
// A right-rail panel collapses out of view; its tab stays and takes focus.
const tab = railTabFor(panel);
const tab = panel.ownerDocument?.querySelector?.(
`[role="tab"][aria-controls="${panel.id}"]`,
);
const escapedFromDisclosure =
event.target === disclosure || disclosure?.contains?.(event.target);
if (tab) tab.focus({ preventScroll: true });
+3 -3
View File
@@ -174,8 +174,8 @@ export function layoutRightPanelRail({
.map((node) => [node, node.scrollTop || 0])
.filter(([, top]) => top > 0);
const naturalHeights = new Map();
// The tab strip's column stands beside the panels at its own height; the
// measuring override lifts its lane clamp too.
// The tab strip's column stands beside the panels; the measuring override
// gives it its natural height.
const column = stack.querySelector?.(':scope > #right-rail-column');
let columnHeight = 0;
// Remove live height allocations through a synchronous CSS override. Keeping
@@ -222,7 +222,7 @@ export function layoutRightPanelRail({
if (!layout) return;
// A lane too short for the strip's column: the rail climbs toward the HUD
// above, as far as the strip needs and the obstacles allow. A lane still
// shorter scrolls the strip (rightRailTabs.js).
// shorter shrinks the tabs (styles/right-rail-tabs.css).
const shortfall = columnHeight - (layout.safeBottom - layout.safeTop);
if (shortfall > 0) layout = resolve(alignedTop - shortfall) || layout;
const { safeTop, safeBottom, maxHeight: availableHeight } = layout;
+12 -14
View File
@@ -57,10 +57,10 @@
}
}
/* The strip's column: the tablist, then a tool slot that holds the compact
Radio launcher on desktop (radioPanelPlacement.js). It stands the lane's
full height, which makes the strip's size definite so its tabs can share
it (see .right-rail-tab); only the strip and the slot take the pointer. */
/* The strip's column: the tablist, then a tool slot for the compact Radio
launcher (radioPanelPlacement.js). It stands the lane's full height, which
makes the strip's size definite for the tabs' share (.right-rail-tab); only
the strip and the slot take the pointer. */
#right-rail-column {
position: absolute;
top: 0;
@@ -90,8 +90,7 @@
min-height: 0;
/* Room for the open tab's bridge on the left. */
padding-left: var(--right-rail-tabs-gap);
/* The rail climbs above its baseline to fit the column (rightPanelRail.js);
a lane still shorter shrinks the tabs. The strip never scrolls. */
/* Never a scrollbar: a lane too short shrinks the tabs (.right-rail-tab). */
overflow: hidden;
pointer-events: auto;
}
@@ -168,17 +167,16 @@ body:not(.mobile-shell)
display: none;
}
/* The strip clips overflow, so the focus ring draws inside the tab. */
/* The tab's mask covers its own box only: the focus ring draws inside it. */
#right-rail-tabs > .right-rail-tab:focus-visible {
outline-offset: -3px;
}
/* A short strip is shared between the tabs: a zero basis hands the strip's
height out in equal parts, a tab's own length caps its part, and what a
short label leaves goes to the longer ones, which end up the same height. A
strip with room gives every tab its own length. The basis is 0%, not 0:
the strip's content size, which sizes the column, comes from the labels. A
tab clips its label at the end, faded over the bottom padding. */
/* A short strip is shared out equally: the zero basis hands every tab the
same part, a tab's own length caps it, and a short label's leftover goes
to the longer ones; with room each tab is its own length. The basis is
0%, not 0, so the strip still sizes to its labels. The label clips at the
end, faded over the bottom padding. */
.right-rail-tab {
position: relative;
display: flex;
@@ -231,7 +229,7 @@ body:not(.mobile-shell)
text-shadow: none;
}
/* Short windows: tighter tabs before the strip has to scroll. */
/* Short windows: tighter tabs, so fewer labels clip. */
@media (max-height: 720px) {
#right-rail-tabs {
gap: 3px;