mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-14 23:32:20 +00:00
Keep rail icons in place and move only the highlight
The left rail no longer lifts its open icon out beside the panel title or reorders the rest behind it. Every icon keeps its place, open or not, and the rail's shared highlight slides to the open one, on both rails. The rail also holds one height whichever panel is open: its offset now allows for the stack rising by a different amount for a tall panel than at rest. Co-authored-by: Sameh Khamis <[email protected]>
This commit is contained in:
1 parent
59ffa87535
commit
b090937e5f
5 files changed
+30
-72
No files matched your search
@@ -283,13 +283,16 @@ export function layoutLeftPanelRail({
|
||||
getComputedStyle(stack)
|
||||
.getPropertyValue?.('--panel-stack-top-pinned')
|
||||
?.trim() === '1';
|
||||
const railOffset = `${(topPinned ? 0 : safeTop - layoutTop).toFixed(1)}px`;
|
||||
// The stack itself rises by the lift below, by a different amount for a
|
||||
// tall panel than at rest; the rail takes up the difference.
|
||||
const lift = (top) => Math.min(0, obstacleSafeTop - top);
|
||||
const railOffset = `${(topPinned ? 0 : safeTop + lift(safeTop) - layoutTop - lift(layoutTop)).toFixed(1)}px`;
|
||||
if (stack.style.getPropertyValue('--panel-rail-offset') !== railOffset) {
|
||||
stack.style.setProperty('--panel-rail-offset', railOffset);
|
||||
}
|
||||
// How far the column can rise before it meets the HUD readout, so the rail
|
||||
// and any open panel sit just under it, whether or not a panel is open.
|
||||
const railLift = `${(topPinned ? 0 : Math.min(0, obstacleSafeTop - layoutTop)).toFixed(1)}px`;
|
||||
const railLift = `${(topPinned ? 0 : lift(layoutTop)).toFixed(1)}px`;
|
||||
if (stack.style.getPropertyValue('--panel-rail-lift') !== railLift) {
|
||||
stack.style.setProperty('--panel-rail-lift', railLift);
|
||||
}
|
||||
|
||||
@@ -359,14 +359,23 @@ test('right rail aligns to the left rail buttons while the left stack is offset'
|
||||
assert.equal(f.stack.dataset.safeTop, '286.7');
|
||||
});
|
||||
|
||||
test('left rail buttons hold still while a tall panel moves the stack', () => {
|
||||
test('left rail buttons hold still whether the open panel is short or tall', () => {
|
||||
// Where the rail sits: the stack's top, the stack's rise, and the rail's
|
||||
// own offset inside the stack.
|
||||
const railTop = (stack) =>
|
||||
(parseFloat(stack.style.getPropertyValue('--left-stack-safe-top')) * 900) /
|
||||
100 +
|
||||
parseFloat(stack.style.getPropertyValue('--panel-rail-lift')) +
|
||||
parseFloat(stack.style.getPropertyValue('--panel-rail-offset'));
|
||||
const short = fixture('left');
|
||||
short.expand(short.first, 250);
|
||||
short.run();
|
||||
const f = fixture('left');
|
||||
f.expand(f.first, 900);
|
||||
f.run();
|
||||
assert.equal(f.stack.dataset.layoutMode, 'focus');
|
||||
assert.ok(
|
||||
parseFloat(f.stack.style.getPropertyValue('--panel-rail-offset')) > 0,
|
||||
);
|
||||
assert.notEqual(short.stack.dataset.layoutMode, 'focus');
|
||||
assert.ok(Math.abs(railTop(f.stack) - railTop(short.stack)) < 0.2);
|
||||
|
||||
// A theme that pins the stack's top (Cyber) leaves nothing to offset.
|
||||
f.stack.computed.getPropertyValue = (name) =>
|
||||
|
||||
@@ -62,24 +62,9 @@ export function installRailEdgeScroll(doc = globalThis.document) {
|
||||
// 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');
|
||||
@@ -263,7 +248,6 @@ export function installRailEdgeScroll(doc = globalThis.document) {
|
||||
win.removeEventListener('resize', onResize);
|
||||
doc.querySelectorAll('.ui-rail').forEach((rail) => {
|
||||
rail.classList.remove('ui-rail--glide', 'ui-rail--glide-jump', 'ui-rail--edge-hot');
|
||||
reorder(rail, null);
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -71,16 +71,6 @@ body.panels-edge-right:not(.context-docked) .gev-panel-rail--right .ui-rail--col
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
/* The open panel's icon joins the row instead of floating above it. */
|
||||
body.panels-edge-left .gev-panel-rail--left .ui-rail--collapsible:not(.ui-rail--expanded) .ui-tooltip {
|
||||
position: static !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
background: none !important;
|
||||
backdrop-filter: none !important;
|
||||
-webkit-backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
body.panels-edge-left #left-panel-stack > :not(.gev-panel-rail):not(.collapsed) {
|
||||
transform: translate(calc(-1 * var(--panel-rail-clearance, 48px)), var(--edge-rail-row));
|
||||
max-height: calc(100% - var(--edge-rail-row)) !important;
|
||||
|
||||
@@ -1,37 +1,5 @@
|
||||
/* Experiment: with a left panel open, its rail icon leaves the rail and sits
|
||||
level with the panel's title, as the panel's own tab. The other icons stay
|
||||
in the rail underneath it and close the gap. With nothing open the rail keeps its
|
||||
labelled pills. */
|
||||
.gev-panel-rail--left:has(.ui-rail--collapsible:not(.ui-rail--expanded) .ui-rail__item--on) {
|
||||
/* The lifted chip (42px) centres on the panel title (26px into the
|
||||
stack); the rail starts 6px below the chip. */
|
||||
top: 53px;
|
||||
}
|
||||
|
||||
.gev-panel-rail--left .ui-rail--collapsible:not(.ui-rail--expanded) {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gev-panel-rail--left
|
||||
.ui-rail--collapsible:not(.ui-rail--expanded)
|
||||
.ui-tooltip:has(> .ui-rail__item--on) {
|
||||
position: absolute;
|
||||
bottom: calc(100% + 6px);
|
||||
left: -1px;
|
||||
padding: 4px;
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: calc(var(--btn-radius) + 4px);
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.gev-panel-rail--left
|
||||
.ui-rail--collapsible:not(.ui-rail--expanded)
|
||||
.ui-tooltip:has(> .ui-rail__item--on)
|
||||
.ui-rail__item {
|
||||
width: 32px;
|
||||
}
|
||||
/* The left rail's icons keep their places whether or not a panel is open;
|
||||
only the highlight moves to the open one. */
|
||||
|
||||
/* With nothing open, the icons and their names split into two glass panels
|
||||
side by side: the plain icon rail, and a name panel beside it with one row
|
||||
@@ -179,14 +147,18 @@
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* The open item's highlight sits on the button itself, so it shows wherever
|
||||
the button is (the lifted chip, the edge row). */
|
||||
/* The open item takes the accent colour; its highlight is the rail's shared
|
||||
one, which slides to it. Without that highlight the button carries its own. */
|
||||
:is(.gev-panel-rail--left, .gev-panel-rail--right) .ui-rail__item.ui-rail__item--on {
|
||||
color: #00d4ff !important;
|
||||
background: rgba(0, 212, 255, 0.15) !important;
|
||||
border-color: rgba(0, 212, 255, 0.15) !important;
|
||||
}
|
||||
|
||||
:is(.gev-panel-rail--left, .gev-panel-rail--right) .ui-rail.ui-rail--glide::before {
|
||||
display: none !important;
|
||||
:is(.gev-panel-rail--left, .gev-panel-rail--right) .ui-rail:not(.ui-rail--glide) .ui-rail__item.ui-rail__item--on {
|
||||
background: rgba(0, 212, 255, 0.15);
|
||||
border-color: rgba(0, 212, 255, 0.15);
|
||||
}
|
||||
|
||||
:is(.gev-panel-rail--left, .gev-panel-rail--right) .ui-rail::before {
|
||||
background: rgba(0, 212, 255, 0.15);
|
||||
border-color: rgba(0, 212, 255, 0.28);
|
||||
}
|
||||
Reference in new issue
Block a user