Skip to content

Commit 76b787b

Browse files
committed
fix(#92): command palette — independent width on narrow viewports
When the viewport shrinks below md, the HeaderSearch row collapses to a 34px magnifying-glass compact button. The palette positioner was clamping its width to the search wrap, so on narrow viewports the slide-down panel became an unusable ~34px vertical strip with one-letter labels. Decouple palette width from the search wrap: width = clamp(360px, searchWrap.width, min(640px, viewport - 16)) Then re-anchor centered on the search input and clamp the resulting left position so the panel stays inside the viewport with an 8px gutter on each side. At vw=875 the panel is 360px wide (MIN_W) and left-aligned near the viewport edge; at vw=1500 it's its natural ~445px under the search box; at vw≥1880 it caps at 640px MAX_W. The list rows now read cleanly across the full responsive range. Refs #92
1 parent 7e4121e commit 76b787b

1 file changed

Lines changed: 21 additions & 6 deletions

File tree

gearbox/static/js/common/command-palette.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -390,13 +390,28 @@
390390
const wrap = document.getElementById('header-search');
391391
if (!p || !wrap) return;
392392
const rect = wrap.getBoundingClientRect();
393-
// Center the panel on the search input. Width tracks the search
394-
// box but is clamped to a 640px max so it remains readable on
395-
// wide monitors.
396-
const width = Math.min(rect.width, 640);
397-
p.style.left = (rect.left + rect.width / 2 - width / 2) + 'px';
393+
394+
// Width: at least MIN_W so the list stays readable, at most
395+
// MAX_W so it doesn't dominate wide monitors, and never wider
396+
// than the viewport. Decoupled from the search wrap's own
397+
// width, which on narrow viewports collapses to a 34px
398+
// magnifying-glass button (issue #92 follow-up: the palette
399+
// used to inherit that 34px and become an unusable strip).
400+
const MIN_W = 360;
401+
const MAX_W = 640;
402+
const margin = 16; // 8px gutter each side
403+
const available = window.innerWidth - margin;
404+
const width = Math.min(MAX_W, Math.max(MIN_W, rect.width), available);
405+
406+
// Anchor centered on the search input, then clamp so the panel
407+
// stays inside the viewport (relevant when the input is a tiny
408+
// compact button sitting near the right edge on a phone).
409+
let left = rect.left + rect.width / 2 - width / 2;
410+
left = Math.max(margin / 2, Math.min(left, window.innerWidth - width - margin / 2));
411+
412+
p.style.left = left + 'px';
398413
p.style.width = width + 'px';
399-
p.style.top = (rect.bottom + 6) + 'px';
414+
p.style.top = (rect.bottom + 6) + 'px';
400415
}
401416

402417
function isOpen() {

0 commit comments

Comments
 (0)