refactor(app): fix type-aware lint errors in UI components (#710)

This commit is contained in:
Mohamed Boudra
2026-05-05 19:58:55 +07:00
parent 8d3946c36c
commit fd30eafafc
5 changed files with 190 additions and 155 deletions
@@ -3,6 +3,7 @@
import {
useCallback,
useEffect,
useImperativeHandle,
useMemo,
useRef,
useState,
@@ -142,6 +143,16 @@ function clamp(value: number, min: number, max: number): number {
return Math.min(max, Math.max(min, value));
}
function isTerminalState(value: unknown): value is TerminalState {
return (
typeof value === "object" &&
value !== null &&
"rows" in value &&
"cols" in value &&
"grid" in value
);
}
function ensureTerminalScrollbarStyle(): void {
if (typeof document === "undefined") {
return;
@@ -229,20 +240,41 @@ export default function TerminalEmulator({
const [isScrollVisible, setIsScrollVisible] = useState(false);
const [isScrollActive, setIsScrollActive] = useState(false);
const domBridgeRef = useRef<DOMImperativeFactory | null>(null);
useDOMImperativeHandle(
ref as Ref<DOMImperativeFactory>,
() =>
({
writeOutput: (text: string) => {
runtimeRef.current?.write({ text });
},
renderSnapshot: (state: TerminalState | null) => {
domBridgeRef,
(): DOMImperativeFactory => ({
writeOutput: (...args) => {
const text = args[0];
if (typeof text === "string") runtimeRef.current?.write({ text });
},
renderSnapshot: (...args) => {
const state = args[0];
if (state === null) {
runtimeRef.current?.renderSnapshot({ state: null });
} else if (isTerminalState(state)) {
runtimeRef.current?.renderSnapshot({ state });
},
clear: () => {
runtimeRef.current?.clear();
},
}) as unknown as DOMImperativeFactory,
}
},
clear: () => {
runtimeRef.current?.clear();
},
}),
[],
);
useImperativeHandle(
ref,
(): TerminalEmulatorHandle => ({
writeOutput: (text: string) => {
runtimeRef.current?.write({ text });
},
renderSnapshot: (state: TerminalState | null) => {
runtimeRef.current?.renderSnapshot({ state });
},
clear: () => {
runtimeRef.current?.clear();
},
}),
[],
);
@@ -259,7 +291,7 @@ export default function TerminalEmulator({
useEffect(() => {
const root = rootRef.current;
if (!root || !swipeGesturesEnabled) {
return;
return () => {};
}
const SWIPE_MIN_PX = 22;
@@ -376,7 +408,7 @@ export default function TerminalEmulator({
const host = hostRef.current;
const root = rootRef.current;
if (!host || !root) {
return;
return () => {};
}
const runtime = new TerminalEmulatorRuntime();
@@ -423,7 +455,7 @@ export default function TerminalEmulator({
useEffect(() => {
if (focusRequestToken <= 0) {
return;
return () => {};
}
runtimeRef.current?.resize({ force: true });
return focusWithRetries({
@@ -451,14 +483,14 @@ export default function TerminalEmulator({
useEffect(() => {
const host = hostRef.current;
if (!host) {
return;
return () => {};
}
const viewportElement = host.querySelector<HTMLElement>(".xterm-viewport");
if (!viewportElement) {
viewportRef.current = null;
setViewportMetrics({ offset: 0, viewportSize: 0, contentSize: 0 });
return;
return () => {};
}
viewportRef.current = viewportElement;
@@ -566,7 +598,7 @@ export default function TerminalEmulator({
useEffect(() => {
if (!isDraggingScrollbar) {
return;
return () => {};
}
const handlePointerMove = (event: PointerEvent) => {