mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
Reserve full height for imagery segmented controls
This commit is contained in:
1 parent
7df8b369e4
commit
4bfee31fdb
5 files changed
+45
-6
No files matched your search
@@ -1,4 +1,5 @@
|
|||||||
- Unify segmented selectors for model coverage, detection allocation, drawing
|
- Unify segmented selectors for model coverage, detection allocation, drawing
|
||||||
shape, Street View and imagery comparison while preserving their existing
|
shape, Street View and imagery comparison while preserving their existing
|
||||||
behavior. Keep compact labels such as FILL and FLAT on one line, and let
|
behavior. Keep compact labels such as FILL and FLAT on one line, and let
|
||||||
collapsed Weather release space to the open rail panel (mazy1998, #1301).
|
collapsed Weather release space to the open rail panel. Reserve the full mode
|
||||||
|
button height in Recent Imagery so keyboard focus is not clipped (mazy1998, #1301).
|
||||||
@@ -1237,6 +1237,8 @@ Pure value navigation is separate from DOM rendering for reuse by a future view.
|
|||||||
Segments keep their word minimum width: compact inline groups such as FIT/FILL
|
Segments keep their word minimum width: compact inline groups such as FIT/FILL
|
||||||
and ALL/360°/FLAT must not break short labels mid-word. Collapsed Weather follows
|
and ALL/360°/FLAT must not break short labels mid-word. Collapsed Weather follows
|
||||||
the same exclusive-rail hiding rule as the other readouts.
|
the same exclusive-rail hiding rule as the other readouts.
|
||||||
|
The imagery mode row reserves 26px for the 24px buttons and group borders so
|
||||||
|
the complete button and inset keyboard-focus outline remain visible.
|
||||||
Browser acceptance: `QA_BASE_URL=http://127.0.0.1:4173 node scripts/qa-segmented-controls.mjs`.
|
Browser acceptance: `QA_BASE_URL=http://127.0.0.1:4173 node scripts/qa-segmented-controls.mjs`.
|
||||||
|
|
||||||
## Application shortcuts and shader parameter controls
|
## Application shortcuts and shader parameter controls
|
||||||
|
|||||||
@@ -274,6 +274,42 @@ try {
|
|||||||
cyber.consistent,
|
cyber.consistent,
|
||||||
JSON.stringify(cyber),
|
JSON.stringify(cyber),
|
||||||
);
|
);
|
||||||
|
await page.evaluate(async () => {
|
||||||
|
const { dataManager, styleManager } = window.__godsEyeView;
|
||||||
|
await dataManager.setEnabled('recent-imagery', true);
|
||||||
|
styleManager.setPanelCollapsed('recent-imagery-panel', false, {
|
||||||
|
persist: false,
|
||||||
|
syncShare: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
for (const width of [1440, 620, 390]) {
|
||||||
|
await page.setViewport({ width, height: 900 });
|
||||||
|
await page.focus('.ri-mode-btn[aria-checked="true"]');
|
||||||
|
const modeLayout = await page.evaluate(() => {
|
||||||
|
const group = document.getElementById('ri-mode');
|
||||||
|
const bounds = group.getBoundingClientRect();
|
||||||
|
const style = getComputedStyle(group);
|
||||||
|
const top = bounds.top + parseFloat(style.borderTopWidth);
|
||||||
|
const bottom = bounds.bottom - parseFloat(style.borderBottomWidth);
|
||||||
|
const buttons = [...group.querySelectorAll('[role="radio"]')];
|
||||||
|
return {
|
||||||
|
visible: bounds.width > 0 && bounds.height > 0,
|
||||||
|
contained: buttons.every((button) => {
|
||||||
|
const rect = button.getBoundingClientRect();
|
||||||
|
return rect.top >= top - 0.5 && rect.bottom <= bottom + 0.5;
|
||||||
|
}),
|
||||||
|
groupHeight: bounds.height,
|
||||||
|
buttonHeights: buttons.map(
|
||||||
|
(button) => button.getBoundingClientRect().height,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
check(
|
||||||
|
`imagery mode buttons and focus outline fit their row at ${width}px`,
|
||||||
|
modeLayout.visible && modeLayout.contained,
|
||||||
|
JSON.stringify(modeLayout),
|
||||||
|
);
|
||||||
|
}
|
||||||
check('no uncaught browser errors', errors.length === 0, errors.join(' | '));
|
check('no uncaught browser errors', errors.length === 0, errors.join(' | '));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Browser errors:', errors);
|
console.error('Browser errors:', errors);
|
||||||
|
|||||||
@@ -412,7 +412,7 @@ test('the body is a fixed stack of seven blocks in a fixed order, each with a fi
|
|||||||
assert.match(rule('.recent-imagery-readout .ri-card'), /height: 112px/);
|
assert.match(rule('.recent-imagery-readout .ri-card'), /height: 112px/);
|
||||||
assert.match(
|
assert.match(
|
||||||
rule('.recent-imagery-readout .ri-selection'),
|
rule('.recent-imagery-readout .ri-selection'),
|
||||||
/grid-template-rows: 20px 20px 20px/,
|
/grid-template-rows: 26px 20px 20px/,
|
||||||
);
|
);
|
||||||
assert.match(rule('.recent-imagery-readout .ri-slot'), /height: 20px/);
|
assert.match(rule('.recent-imagery-readout .ri-slot'), /height: 20px/);
|
||||||
assert.match(rule('.recent-imagery-readout .ri-controls'), /height: 22px/);
|
assert.match(rule('.recent-imagery-readout .ri-controls'), /height: 22px/);
|
||||||
@@ -445,7 +445,7 @@ test('no control changes place in the tree, no block is hidden and every fixed-h
|
|||||||
/**
|
/**
|
||||||
* Every block that must keep its height: the node carrying the class, that
|
* Every block that must keep its height: the node carrying the class, that
|
||||||
* class, and the rule it gets its height from. The mode row is the first
|
* class, and the rule it gets its height from. The mode row is the first
|
||||||
* 20 px track of the selection grid. The details header has no height of
|
* 26 px track of the selection grid. The details header has no height of
|
||||||
* its own: it is the last block, so it moves nothing below it, and its
|
* its own: it is the last block, so it moves nothing below it, and its
|
||||||
* title is held to one line.
|
* title is held to one line.
|
||||||
*/
|
*/
|
||||||
@@ -491,7 +491,7 @@ test('no control changes place in the tree, no block is hidden and every fixed-h
|
|||||||
mode.parentNode.children[0] === mode ? mode.parentNode : null,
|
mode.parentNode.children[0] === mode ? mode.parentNode : null,
|
||||||
'ri-selection',
|
'ri-selection',
|
||||||
readout('.ri-selection'),
|
readout('.ri-selection'),
|
||||||
/grid-template-rows: 20px 20px 20px/,
|
/grid-template-rows: 26px 20px 20px/,
|
||||||
],
|
],
|
||||||
'ri-slot-a': [
|
'ri-slot-a': [
|
||||||
f.byId('ri-slot-a'),
|
f.byId('ri-slot-a'),
|
||||||
|
|||||||
@@ -309,10 +309,10 @@ html:not([lang='en'])
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 4. The selection bar: mode, then two rows that are always there. */
|
/* 4. The selection bar: 24px mode buttons plus borders, then two stable rows. */
|
||||||
.recent-imagery-readout .ri-selection {
|
.recent-imagery-readout .ri-selection {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 20px 20px 20px;
|
grid-template-rows: 26px 20px 20px;
|
||||||
row-gap: 4px;
|
row-gap: 4px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border: 1px solid var(--weather-card-border);
|
border: 1px solid var(--weather-card-border);
|
||||||
|
|||||||
Reference in new issue
Block a user