infopop-place: the placement rule moves onto placeInfopop
commit cbbd2a4a9712ba833c9063a13b9c852869fa5276 · parent f791bafcc9
· browse this tree
Ximianth, 2026-10-18 10:47:17 UTC
The rule bullets move onto placeInfopop; the shared constant comment splits into one doc per constant. The header keeps the purpose line. Wording is unchanged apart from the name-first prefix; lines break at clauses.
diff --git a/packages/yukey/src/infopop-place.ts b/packages/yukey/src/infopop-place.ts index f8b3880..23bbc54 100644 --- a/packages/yukey/src/infopop-place.ts +++ b/packages/yukey/src/infopop-place.ts @@ -1,15 +1,5 @@ // The infopop placement rule: pure geometry, no DOM types, no measurement. -// Given the anchor's rectangle, the popup's size, and the viewport size, decide -// where the popup goes. yk-infopop.ts feeds it measured values and applies the result. -// -// The rule (deterministic on purpose; simple beats clever for a transient surface): -// -// - Preferred: below the anchor, horizontally centered on it. -// - If below would clip the viewport bottom: flip above. -// - If both sides clip (the popup is taller than either side's room): take the -// roomier side. Only in this degenerate case may the popup overlap the anchor, -// because then there is nowhere it fits at all. -// - X is clamped so the popup stays inside the viewport (with a small margin). +// yk-infopop feeds it measured values and applies the result. export interface Rect { x: number; @@ -29,11 +19,23 @@ export interface Placement { side: "below" | "above"; } -// Gap between the anchor and the popup, and the minimum clearance kept to the -// viewport edges. Exported for the component's stylesheet-independent tests. +/** ANCHOR_GAP is the gap between the anchor and the popup. Exported for the component's stylesheet-independent tests. */ export const ANCHOR_GAP = 6; + +/** VIEWPORT_MARGIN is the minimum clearance kept to the viewport edges. Exported for the component's stylesheet-independent tests. */ export const VIEWPORT_MARGIN = 4; +/** + * placeInfopop decides where the popup goes, + * given the anchor's rectangle, the popup's size, and the viewport size. + * + * The rule (deterministic on purpose; simple beats clever for a transient surface): + * - Preferred: below the anchor, horizontally centered on it. + * - If below would clip the viewport bottom: flip above. + * - If both sides clip (the popup is taller than either side's room): take the roomier side. + * Only in this degenerate case may the popup overlap the anchor, because then there is nowhere it fits at all. + * - X is clamped so the popup stays inside the viewport (with a small margin). + */ export function placeInfopop(anchor: Rect, popup: Size, viewport: Size): Placement { const x = clamp( anchor.x + anchor.w / 2 - popup.w / 2,