File size: 1,971 Bytes
7e3630c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | import { useMemo } from "react";
import type { Position } from "./usePosition.js";
export type Visibility = "full" | "partial" | "hidden";
export interface VisibilityInfo {
position: Position;
terminalWidth: number;
terminalHeight: number;
defaultVisibility: Visibility;
}
export type GetVisibility = (info: VisibilityInfo) => Visibility;
export function defaultVisibility(
position: Position,
terminalHeight: number,
terminalWidth: number,
): Visibility {
const viewportStartRow = terminalHeight - position.appHeight + position.row;
const viewportEndRow = viewportStartRow + position.height;
const inAppStartRow = position.row;
const inAppEndRow = inAppStartRow + position.height;
if (
viewportEndRow <= 0 ||
inAppEndRow <= 0 ||
viewportStartRow >= terminalHeight ||
inAppStartRow >= position.appHeight
) {
return "hidden";
}
const viewportEndCol = position.col + position.width;
if (
viewportEndCol <= 0 ||
position.col >= terminalWidth ||
position.col >= position.appWidth
) {
return "hidden";
}
if (
viewportStartRow < 0 ||
inAppStartRow < 0 ||
viewportEndRow > terminalHeight ||
inAppEndRow > position.appHeight ||
position.col < 0 ||
viewportEndCol > terminalWidth ||
viewportEndCol > position.appWidth
) {
return "partial";
}
return "full";
}
export function useVisibility(
position: Position | undefined,
terminalHeight: number,
terminalWidth: number,
getVisibility?: GetVisibility,
): Visibility {
return useMemo(() => {
if (!position) return "hidden";
const visibility = defaultVisibility(
position,
terminalHeight,
terminalWidth,
);
if (getVisibility) {
return getVisibility({
position,
terminalWidth,
terminalHeight,
defaultVisibility: visibility,
});
}
return visibility;
}, [position, terminalHeight, terminalWidth, getVisibility]);
}
|