/// import { useEffect, useRef } from 'react'; import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; import 'monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution'; import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'; // Vite emits this worker locally; no AMD loader or CDN is involved. self.MonacoEnvironment = { getWorker: () => new EditorWorker() }; export interface ProfileEditorProps { value: string; onChange?: (value: string) => void; readOnly?: boolean; label?: string; } export function ProfileEditor({ value, onChange, readOnly = false, label = 'YAML 配置' }: ProfileEditorProps) { const host = useRef(null); const editor = useRef(null); const change = useRef(onChange); change.current = onChange; const initialValue = useRef(value); const updating = useRef(false); useEffect(() => { if (!host.current) return; const model = monaco.editor.createModel(initialValue.current, 'yaml'); const instance = monaco.editor.create(host.current, { model, automaticLayout: true, minimap: { enabled: false }, scrollBeyondLastLine: false, tabSize: 2, insertSpaces: true, wordWrap: 'on', ariaLabel: label, readOnly, }); editor.current = instance; const listener = instance.onDidChangeModelContent(() => { if (!updating.current) change.current?.(instance.getValue()); }); return () => { listener.dispose(); instance.dispose(); model.dispose(); editor.current = null; }; }, []); useEffect(() => { const instance = editor.current; if (instance && instance.getValue() !== value) { updating.current = true; instance.setValue(value); updating.current = false; } }, [value]); useEffect(() => { editor.current?.updateOptions({ readOnly, ariaLabel: label }); }, [readOnly, label]); return
; }