c16942777d
F1: extract the navbar-visibility crux (width/height 0 or right<=0 -> hidden) from getNavbarRect into a pure isNavbarRectVisible in dock-helpers.ts + 3 tests; getNavbarRect calls it (identical null cases). F2: base the dock/undock button's label/icon/title on the effective useDock state (docked && dockRect present) rather than the raw docked flag, so a docked window that fell back to floating (collapsed sidebar) doesn't show 'Undock'. Toggle action unchanged; no remount. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
49 lines
1.6 KiB
TypeScript
49 lines
1.6 KiB
TypeScript
// Pure geometry helper for the AI chat window dock/undock decision (#276). Kept
|
|
// free of React and the DOM so it can be unit-tested in isolation (see
|
|
// dock-helpers.test.ts). The DOM-reading getNavbarRect() lives in the window
|
|
// component; this is only the point-in-rect math that decides dock-on-drop and
|
|
// undock-on-drag-out from the measured navbar rect.
|
|
|
|
export type NavbarRect = {
|
|
left: number;
|
|
top: number;
|
|
width: number;
|
|
height: number;
|
|
};
|
|
|
|
/**
|
|
* Whether a viewport point (x, y) falls within `rect`. Edges are inclusive so a
|
|
* drop exactly on the navbar boundary counts as "over the navbar". Returns false
|
|
* when the rect is null (navbar absent/collapsed) so the caller falls back to the
|
|
* floating behavior.
|
|
*/
|
|
export function isPointWithinRect(
|
|
x: number,
|
|
y: number,
|
|
rect: NavbarRect | null,
|
|
): boolean {
|
|
if (!rect) return false;
|
|
return (
|
|
x >= rect.left &&
|
|
x <= rect.left + rect.width &&
|
|
y >= rect.top &&
|
|
y <= rect.top + rect.height
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Whether a measured navbar rect represents a VISIBLE navbar. Mantine collapses
|
|
* the navbar by translating it off-screen (its right edge lands at or left of the
|
|
* viewport) without changing its width/border-box, so a zero-size or off-screen
|
|
* rect means "no navbar" — the docked window then falls back to floating instead
|
|
* of pinning to an invisible box. Pure (no DOM) so it can be unit-tested; the
|
|
* DOM-reading getNavbarRect() in the window component supplies the rect.
|
|
*/
|
|
export function isNavbarRectVisible(r: {
|
|
width: number;
|
|
height: number;
|
|
right: number;
|
|
}): boolean {
|
|
return !(r.width === 0 || r.height === 0 || r.right <= 0);
|
|
}
|