This repository has been archived on 2026-07-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
codespace/web/src/components/terminal/TerminalPanel.tsx
T
2026-07-02 18:35:17 +08:00

72 lines
1.9 KiB
TypeScript

import { FitAddon } from "@xterm/addon-fit";
import { Terminal } from "@xterm/xterm";
import { useEffect, useRef, useState } from "react";
export function TerminalPanel() {
const containerRef = useRef<HTMLDivElement>(null);
const [failed, setFailed] = useState(false);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
let terminal: Terminal | undefined;
let fitAddon: FitAddon | undefined;
try {
terminal = new Terminal({
cursorBlink: true,
convertEol: true,
fontFamily:
'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
fontSize: 12,
theme: {
background: "#171717",
foreground: "#e5e5e5",
},
});
fitAddon = new FitAddon();
terminal.loadAddon(fitAddon);
terminal.open(container);
terminal.writeln("codespace terminal");
terminal.writeln("Mock session initialized. No process is attached.");
terminal.writeln("");
terminal.writeln("$ pnpm test");
terminal.writeln("mock: 3 files checked, 0 failures");
terminal.write("$ ");
fitAddon.fit();
} catch {
setFailed(true);
terminal?.dispose();
fitAddon?.dispose();
return;
}
const handleResize = () => {
fitAddon?.fit();
};
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
terminal?.dispose();
fitAddon?.dispose();
};
}, []);
if (failed) {
return (
<section className="flex h-full w-full items-center justify-center bg-background text-sm text-muted-foreground">
Terminal failed to initialize
</section>
);
}
return (
<section className="h-full w-full overflow-hidden bg-[#171717] p-2">
<div ref={containerRef} className="h-full w-full" />
</section>
);
}