From 9397e46eecebdb46811fc16103f0fb292bc006bd Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Sat, 14 Mar 2026 01:47:16 -0400 Subject: [PATCH] feat: add ScriptBodyEditor with PowerShell syntax highlighting overlay Co-Authored-By: Claude Opus 4.6 --- .../script-editor/ScriptBodyEditor.tsx | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 frontend/src/components/script-editor/ScriptBodyEditor.tsx diff --git a/frontend/src/components/script-editor/ScriptBodyEditor.tsx b/frontend/src/components/script-editor/ScriptBodyEditor.tsx new file mode 100644 index 00000000..1a96dcf5 --- /dev/null +++ b/frontend/src/components/script-editor/ScriptBodyEditor.tsx @@ -0,0 +1,48 @@ +import { useRef, useCallback } from 'react' +import { PowerShellHighlighter } from '@/components/scripts/PowerShellHighlighter' + +interface Props { + value: string + onChange: (value: string) => void + disabled?: boolean +} + +export function ScriptBodyEditor({ value, onChange, disabled }: Props) { + const textareaRef = useRef(null) + + const handleTab = useCallback((e: React.KeyboardEvent) => { + if (e.key === 'Tab') { + e.preventDefault() + const ta = e.currentTarget + const start = ta.selectionStart + const end = ta.selectionEnd + const newValue = value.substring(0, start) + ' ' + value.substring(end) + onChange(newValue) + // Restore cursor position after React re-render + requestAnimationFrame(() => { + ta.selectionStart = ta.selectionEnd = start + 4 + }) + } + }, [value, onChange]) + + return ( +
+ {/* Highlighted overlay (read-only visual layer) */} +
+ +
+ + {/* Editable textarea (transparent text, visible caret) */} +