fix: eliminate double scrollbar in script editor and extend page scroll area

ScriptBodyEditor: overlay now has overflow-hidden and syncs scroll
position from the textarea via onScroll, so only one scrollbar appears.
ScriptManagePage: outer scroll container is now full-width so scrolling
works even when hovering outside the max-w content area.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-03-14 15:32:59 -04:00
parent 0b01692bbd
commit 5768e04804
2 changed files with 24 additions and 13 deletions

View File

@@ -9,6 +9,14 @@ interface Props {
export function ScriptBodyEditor({ value, onChange, disabled }: Props) {
const textareaRef = useRef<HTMLTextAreaElement>(null)
const overlayRef = useRef<HTMLDivElement>(null)
const handleScroll = useCallback(() => {
if (textareaRef.current && overlayRef.current) {
overlayRef.current.scrollTop = textareaRef.current.scrollTop
overlayRef.current.scrollLeft = textareaRef.current.scrollLeft
}
}, [])
const handleTab = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Tab') {
@@ -26,9 +34,9 @@ export function ScriptBodyEditor({ value, onChange, disabled }: Props) {
}, [value, onChange])
return (
<div className="relative rounded-xl border border-border">
{/* Highlighted overlay (read-only visual layer) */}
<div className="absolute inset-0 pointer-events-none overflow-auto p-4">
<div className="relative rounded-xl border border-border overflow-hidden">
{/* Highlighted overlay (read-only visual layer) — scroll synced to textarea */}
<div ref={overlayRef} className="absolute inset-0 pointer-events-none overflow-hidden p-4">
<PowerShellHighlighter script={value || ' '} />
</div>
@@ -37,6 +45,7 @@ export function ScriptBodyEditor({ value, onChange, disabled }: Props) {
ref={textareaRef}
value={value}
onChange={e => onChange(e.target.value)}
onScroll={handleScroll}
onKeyDown={handleTab}
disabled={disabled}
spellCheck={false}

View File

@@ -27,16 +27,18 @@ export default function ScriptManagePage() {
}
return (
<div className="p-6 max-w-5xl mx-auto h-full overflow-y-auto">
{mode === 'list' ? (
<ScriptTemplateListView onEdit={handleEdit} onCreate={handleCreate} />
) : (
<ScriptTemplateEditor
templateId={editingId}
onBack={handleBack}
onSaved={handleSaved}
/>
)}
<div className="h-full overflow-y-auto">
<div className="p-6 max-w-5xl mx-auto">
{mode === 'list' ? (
<ScriptTemplateListView onEdit={handleEdit} onCreate={handleCreate} />
) : (
<ScriptTemplateEditor
templateId={editingId}
onBack={handleBack}
onSaved={handleSaved}
/>
)}
</div>
</div>
)
}