Fix terminal textarea caret visibility

This commit is contained in:
Saoud Rizwan
2024-09-02 00:59:25 -04:00
parent 492ffeb5b1
commit b02692e2f7

View File

@@ -3,15 +3,15 @@ import DynamicTextArea from "react-textarea-autosize"
interface TerminalProps { interface TerminalProps {
output: string output: string
shouldAllowInput: boolean
handleSendStdin: (text: string) => void handleSendStdin: (text: string) => void
shouldAllowInput: boolean
} }
/* /*
Inspired by https://phuoc.ng/collection/mirror-a-text-area/create-your-own-custom-cursor-in-a-text-area/ Inspired by https://phuoc.ng/collection/mirror-a-text-area/create-your-own-custom-cursor-in-a-text-area/
*/ */
const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSendStdin }) => { const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin, shouldAllowInput }) => {
const [userInput, setUserInput] = useState("") const [userInput, setUserInput] = useState("")
const [isFocused, setIsFocused] = useState(false) // Initially not focused const [isFocused, setIsFocused] = useState(false) // Initially not focused
const textAreaRef = useRef<HTMLTextAreaElement>(null) const textAreaRef = useRef<HTMLTextAreaElement>(null)
@@ -27,7 +27,6 @@ const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSen
}, [output, lastProcessedOutput]) }, [output, lastProcessedOutput])
const handleKeyPress = (e: React.KeyboardEvent<HTMLTextAreaElement>) => { const handleKeyPress = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (!shouldAllowInput) return
if (e.key === "Enter") { if (e.key === "Enter") {
e.preventDefault() e.preventDefault()
handleSendStdin(userInput) handleSendStdin(userInput)
@@ -130,7 +129,7 @@ const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSen
const caretEle = document.createElement("span") const caretEle = document.createElement("span")
caretEle.classList.add("terminal-cursor") caretEle.classList.add("terminal-cursor")
if (isFocused && shouldAllowInput) { if (isFocused) {
caretEle.classList.add("terminal-cursor-focused") caretEle.classList.add("terminal-cursor-focused")
} }
if (!shouldAllowInput) { if (!shouldAllowInput) {
@@ -159,7 +158,7 @@ const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSen
const caretEle = document.createElement("span") const caretEle = document.createElement("span")
caretEle.classList.add("terminal-cursor") caretEle.classList.add("terminal-cursor")
if (isFocused && shouldAllowInput) { if (isFocused) {
caretEle.classList.add("terminal-cursor-focused") caretEle.classList.add("terminal-cursor-focused")
} }
if (!shouldAllowInput) { if (!shouldAllowInput) {
@@ -171,7 +170,6 @@ const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSen
}, [output, userInput, isFocused, shouldAllowInput]) }, [output, userInput, isFocused, shouldAllowInput])
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
if (!shouldAllowInput) return
const newValue = e.target.value const newValue = e.target.value
if (newValue.startsWith(output)) { if (newValue.startsWith(output)) {
setUserInput(newValue.slice(output.length)) setUserInput(newValue.slice(output.length))
@@ -190,7 +188,6 @@ const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSen
} }
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => { const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (!shouldAllowInput) return
const textarea = e.target as HTMLTextAreaElement const textarea = e.target as HTMLTextAreaElement
const cursorPosition = textarea.selectionStart const cursorPosition = textarea.selectionStart
@@ -213,6 +210,9 @@ const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSen
if (isFocused) { if (isFocused) {
caretEle.classList.add("terminal-cursor-focused") caretEle.classList.add("terminal-cursor-focused")
} }
if (!shouldAllowInput) {
caretEle.classList.add("terminal-cursor-hidden")
}
caretEle.innerHTML = "&nbsp;" caretEle.innerHTML = "&nbsp;"
mirrorRef.current!.appendChild(caretEle) mirrorRef.current!.appendChild(caretEle)
@@ -291,9 +291,7 @@ const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSen
color: "var(--vscode-terminal-foreground)", color: "var(--vscode-terminal-foreground)",
borderRadius: "3px", borderRadius: "3px",
...(textAreaStyle as any), ...(textAreaStyle as any),
//pointerEvents: shouldAllowInput ? "auto" : "none",
}} }}
readOnly={!shouldAllowInput}
minRows={1} minRows={1}
/> />
<div ref={mirrorRef} className="terminal-mirror"></div> <div ref={mirrorRef} className="terminal-mirror"></div>