From a898253089fecde589f4eab965b3e02ac868b04f Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Thu, 8 Oct 2026 17:48:04 +0200 Subject: [PATCH] fix(tiles): a keyboard focus brings the Tiles hover card back after a click Found live: a click on Tiles hides the card and keeps it hidden while the pointer rests on the button, until the pointer leaves. With the pointer left there, tabbing away and back onto the button showed no card either, so a keyboard user whose mouse happened to sit on the button never got the Shift+F10 hint. Leaving the button (blur) now ends that suppression as well: a keyboard focus that comes back later is a new arrival. A click that opens the grid or a right-click that opens the menu still shows nothing, since no pointerenter or focus follows while the pointer stays. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/web/public/tile-grid.js | 7 ++++++- test/tile-grid-hint.test.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/web/public/tile-grid.js b/src/web/public/tile-grid.js index f965462c..076e642c 100644 --- a/src/web/public/tile-grid.js +++ b/src/web/public/tile-grid.js @@ -605,7 +605,12 @@ Object.assign(CodemanApp.prototype, { } if (btn.matches?.(':focus-visible')) this._scheduleTileHint({ keyboard: true }); }); - btn.addEventListener('blur', () => this._hideTileHint()); + // Leaving the button ends a click's suppression too: a keyboard focus that + // comes back later is a new arrival, even with the pointer still on it. + btn.addEventListener('blur', () => { + hint.suppressed = false; + this._hideTileHint(); + }); // Capture: these run before the button's own handlers, so the card is gone // before a right-click opens the count menu or a click opens the grid; and // it stays gone while the pointer rests there. diff --git a/test/tile-grid-hint.test.ts b/test/tile-grid-hint.test.ts index 5de151e4..d002ae28 100644 --- a/test/tile-grid-hint.test.ts +++ b/test/tile-grid-hint.test.ts @@ -281,6 +281,18 @@ describe('hiding', () => { } }); + it('a keyboard focus coming back after a click shows it, the pointer still resting there', () => { + shown(); + btn.dispatch('click', {}); + expect(card()!.hidden).toBe(true); + // Tab away and back, the mouse never moved. + btn.dispatch('blur', {}); + (btn as unknown as { matches: (s: string) => boolean }).matches = (s) => s === ':focus-visible'; + btn.dispatch('focus', {}); + vi.advanceTimersByTime(300); + expect(card()!.hidden).toBe(false); + }); + it('the count menu never opens beside it: openTileCountMenu hides it first', () => { const app = shown(); app.openTileCountMenu({ preventDefault: vi.fn() });