[nu-demo] Right click on a topic in hero voice and menu items are cutoff #155

Closed
opened 2026-04-24 01:54:32 +00:00 by scott · 1 comment
Member

image

![image](/attachments/a663d72a-f8bb-42fc-8445-f6d98c49e62a)
Owner

Fixed in hero_voice commit a113955 on development.

Reproduction — live on herodemo (1920×1080) via Hero Browser MCP:

  • right-click coords: (1870, 1030) (bottom-right corner)
  • 18-item topic menu (Record + 9 Transform + 3 Translate + Rename/Reset/Delete + headers/dividers) renders with right=2030, bottom=1707
  • Clipped: 110px on the right, 627px on the bottom (~60% of the menu invisible — only "🎤 R" peeks at the viewport edge)

Screenshot: /tmp/voice_menu_buggy.png

Root causeContextMenu.show(x, y, ...) in app.js:559-561:

this.menuEl.style.left = `${x}px`;
this.menuEl.style.top = `${y}px`;
this.menuEl.style.display = 'block';

Menu positioned at raw mouse coords with no boundary check. As soon as it overflows the viewport, items below the bottom edge are unreachable.

Fix — after rendering, measure with getBoundingClientRect() and clamp:

const margin = 8;
const rect = this.menuEl.getBoundingClientRect();
let adjX = x, adjY = y;
if (rect.right  > window.innerWidth  - margin) adjX = Math.max(margin, window.innerWidth  - rect.width  - margin);
if (rect.bottom > window.innerHeight - margin) adjY = Math.max(margin, window.innerHeight - rect.height - margin);
if (rect.height > window.innerHeight - 2 * margin) {
    this.menuEl.style.maxHeight = `${window.innerHeight - 2 * margin}px`;
    this.menuEl.style.overflowY = 'auto';
    adjY = margin;
}

The maxHeight + overflow-y branch handles the edge case where the menu itself is taller than the viewport (small laptop screens) — content remains scrollable instead of hidden.

Verification — same coordinates, post-fix:

  • right=1912 ≤ vw 1920
  • bottom=1072 ≤ vh 1080
  • All 18 items visible (Record, Transform-To: Spell Check / Summary / Specifications / Code Specs / Documentation / Technical / Meeting Notes / Business / Email, Translate-To: Dutch / French / Arabic, Rename, Reset, Delete)

Screenshot: /tmp/voice_menu_fixed.png — full menu inside viewport.

Meta-tracker: home#193.

Signed-off-by: mik-tf

Fixed in hero_voice commit `a113955` on `development`. **Reproduction** — live on herodemo (1920×1080) via Hero Browser MCP: - right-click coords: `(1870, 1030)` (bottom-right corner) - 18-item topic menu (Record + 9 Transform + 3 Translate + Rename/Reset/Delete + headers/dividers) renders with `right=2030, bottom=1707` - Clipped: 110px on the right, **627px on the bottom** (~60% of the menu invisible — only "🎤 R" peeks at the viewport edge) Screenshot: `/tmp/voice_menu_buggy.png` **Root cause** — `ContextMenu.show(x, y, ...)` in `app.js:559-561`: ```javascript this.menuEl.style.left = `${x}px`; this.menuEl.style.top = `${y}px`; this.menuEl.style.display = 'block'; ``` Menu positioned at raw mouse coords with no boundary check. As soon as it overflows the viewport, items below the bottom edge are unreachable. **Fix** — after rendering, measure with `getBoundingClientRect()` and clamp: ```javascript const margin = 8; const rect = this.menuEl.getBoundingClientRect(); let adjX = x, adjY = y; if (rect.right > window.innerWidth - margin) adjX = Math.max(margin, window.innerWidth - rect.width - margin); if (rect.bottom > window.innerHeight - margin) adjY = Math.max(margin, window.innerHeight - rect.height - margin); if (rect.height > window.innerHeight - 2 * margin) { this.menuEl.style.maxHeight = `${window.innerHeight - 2 * margin}px`; this.menuEl.style.overflowY = 'auto'; adjY = margin; } ``` The `maxHeight + overflow-y` branch handles the edge case where the menu itself is taller than the viewport (small laptop screens) — content remains scrollable instead of hidden. **Verification** — same coordinates, post-fix: - `right=1912 ≤ vw 1920` ✓ - `bottom=1072 ≤ vh 1080` ✓ - All 18 items visible (Record, Transform-To: Spell Check / Summary / Specifications / Code Specs / Documentation / Technical / Meeting Notes / Business / Email, Translate-To: Dutch / French / Arabic, Rename, Reset, Delete) Screenshot: `/tmp/voice_menu_fixed.png` — full menu inside viewport. Meta-tracker: home#193. Signed-off-by: mik-tf
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/home#155
No description provided.