2026-06-23 12:24:11 -07:00
|
|
|
import Editor from "@monaco-editor/react"
|
|
|
|
|
import { useEffect, useState } from "react"
|
2026-06-09 15:46:29 -07:00
|
|
|
|
2026-06-23 12:24:11 -07:00
|
|
|
import { Textarea } from "@/components/ui/textarea"
|
2026-06-09 15:46:29 -07:00
|
|
|
|
|
|
|
|
interface InstructionsEditorProps {
|
2026-06-23 12:24:11 -07:00
|
|
|
value: string
|
|
|
|
|
onChange: (value: string) => void
|
|
|
|
|
disabled?: boolean
|
|
|
|
|
placeholder?: string
|
|
|
|
|
language?: string
|
2026-06-09 15:46:29 -07:00
|
|
|
}
|
|
|
|
|
|
2026-06-23 12:24:11 -07:00
|
|
|
/** Monaco-backed code editor that falls back to a textarea before mount (SSR-safe). */
|
2026-06-09 15:46:29 -07:00
|
|
|
export function InstructionsEditor({
|
|
|
|
|
value,
|
|
|
|
|
onChange,
|
|
|
|
|
disabled,
|
|
|
|
|
placeholder,
|
2026-06-23 12:24:11 -07:00
|
|
|
language = "markdown",
|
2026-06-09 15:46:29 -07:00
|
|
|
}: InstructionsEditorProps) {
|
2026-06-23 12:24:11 -07:00
|
|
|
const [mounted, setMounted] = useState(false)
|
2026-06-09 15:46:29 -07:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-06-23 12:24:11 -07:00
|
|
|
setMounted(true)
|
|
|
|
|
}, [])
|
2026-06-09 15:46:29 -07:00
|
|
|
|
|
|
|
|
if (!mounted) {
|
|
|
|
|
return (
|
|
|
|
|
<Textarea
|
|
|
|
|
className="min-h-[360px] w-full font-mono text-xs"
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={(e) => onChange(e.target.value)}
|
|
|
|
|
placeholder={placeholder}
|
|
|
|
|
disabled={disabled}
|
|
|
|
|
/>
|
2026-06-23 12:24:11 -07:00
|
|
|
)
|
2026-06-09 15:46:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="overflow-hidden rounded-md border border-border">
|
|
|
|
|
<Editor
|
|
|
|
|
height="360px"
|
2026-06-23 12:24:11 -07:00
|
|
|
language={language}
|
2026-06-09 15:46:29 -07:00
|
|
|
value={value}
|
|
|
|
|
onChange={(v) => onChange(v ?? "")}
|
|
|
|
|
options={{
|
|
|
|
|
readOnly: disabled,
|
|
|
|
|
minimap: { enabled: false },
|
|
|
|
|
wordWrap: "on",
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
lineNumbers: "on",
|
|
|
|
|
scrollBeyondLastLine: false,
|
|
|
|
|
padding: { top: 12, bottom: 12 },
|
|
|
|
|
renderLineHighlight: "none",
|
|
|
|
|
}}
|
|
|
|
|
theme="vs-dark"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2026-06-23 12:24:11 -07:00
|
|
|
)
|
2026-06-09 15:46:29 -07:00
|
|
|
}
|