Tooltips after one second, and at once for the next button
From the development repository at b7ffe0e. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
bc3c9bb886
commit
fcd6117618
5 files changed
+64
-10
No files matched your search
+23
-6
@@ -11,7 +11,18 @@
|
||||
|
||||
import { trace } from './log.js';
|
||||
|
||||
const DELAY_MS = 2000;
|
||||
/**
|
||||
* How long the pointer must have been in a button before its tooltip
|
||||
* appears: the time in the button, movement inside it not counting
|
||||
* (Andy, 2026-10-11: one second; two until then, one until 2026-10-06).
|
||||
*/
|
||||
export const DELAY_MS = 1000;
|
||||
/**
|
||||
* The neighbour rule: within this long after a tooltip was shown, the
|
||||
* next button's tooltip appears at once, so that reading a row of
|
||||
* buttons costs one wait, not one per button. A press or a key ends it.
|
||||
*/
|
||||
export const WARM_MS = 1000;
|
||||
const GAP_PX = 6;
|
||||
|
||||
/** @type {HTMLElement | null} */
|
||||
@@ -20,6 +31,8 @@ let tooltip = null;
|
||||
let timer = null;
|
||||
/** @type {Element | null} */
|
||||
let shownFor = null;
|
||||
/** When a tooltip was last showing, for the neighbour rule. */
|
||||
let warmUntil = -Infinity;
|
||||
|
||||
/**
|
||||
* @param {EventTarget | null} target
|
||||
@@ -49,10 +62,13 @@ function show(element) {
|
||||
tooltip.style.top = `${box.bottom + GAP_PX}px`;
|
||||
}
|
||||
|
||||
function hide() {
|
||||
/** @param {boolean} [cold] Whether the neighbour rule ends here too. */
|
||||
function hide(cold = false) {
|
||||
if (timer !== null) clearTimeout(timer);
|
||||
timer = null;
|
||||
if (shownFor) warmUntil = performance.now() + WARM_MS;
|
||||
shownFor = null;
|
||||
if (cold) warmUntil = -Infinity;
|
||||
if (tooltip) tooltip.hidden = true;
|
||||
}
|
||||
|
||||
@@ -69,11 +85,12 @@ export function enableTooltips() {
|
||||
if (element === shownFor) return;
|
||||
hide();
|
||||
trace(`Hover: ${event.pointerType} over ${element.textContent?.trim() || element.id}`);
|
||||
const wait = performance.now() < warmUntil ? 0 : DELAY_MS;
|
||||
timer = setTimeout(() => {
|
||||
timer = null;
|
||||
trace(`Tooltip: ${element.textContent?.trim() || element.id}`);
|
||||
show(element);
|
||||
}, DELAY_MS);
|
||||
}, wait);
|
||||
});
|
||||
document.addEventListener('pointerleave', (event) => {
|
||||
if (timer !== null || shownFor) trace(`Hover: ${event.pointerType} left the document`);
|
||||
@@ -85,14 +102,14 @@ export function enableTooltips() {
|
||||
let pressedAt = -Infinity;
|
||||
document.addEventListener('pointerdown', () => {
|
||||
pressedAt = performance.now();
|
||||
hide();
|
||||
hide(true);
|
||||
});
|
||||
document.addEventListener('focusin', (event) => {
|
||||
if (performance.now() - pressedAt < 500) return;
|
||||
const element = helpElement(event.target);
|
||||
if (element) show(element);
|
||||
});
|
||||
document.addEventListener('focusout', hide);
|
||||
document.addEventListener('focusout', () => hide());
|
||||
// Typing means the user's attention is on the keys, not the tooltip.
|
||||
document.addEventListener('keydown', hide);
|
||||
document.addEventListener('keydown', () => hide(true));
|
||||
}
|
||||
Reference in new issue
Block a user