'use client' import { useEffect, useRef } from 'react' import Editor from '@monaco-editor/react' import { useTheme } from 'next-themes' interface JsonEditorProps { value: string onChange: (value: string) => void disabled?: boolean height?: string onValidate?: (isValid: boolean, errors: string[]) => void isValid?: boolean stats?: { categories: number; items: number; size: number } } export function JsonEditor({ value, onChange, disabled = false, height = '500px', onValidate, isValid = true, stats }: JsonEditorProps) { const { theme } = useTheme() const editorRef = useRef(null) const handleEditorDidMount = (editor: any, monaco: any) => { editorRef.current = editor // 配置JSON语言特性 monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, allowComments: false, schemas: [], enableSchemaRequest: false, }) // 设置编辑器选项 editor.updateOptions({ fontSize: 14, fontFamily: 'JetBrains Mono, Consolas, Monaco, "Courier New", monospace', lineNumbers: 'on', minimap: { enabled: false }, scrollBeyondLastLine: false, wordWrap: 'on', automaticLayout: true, tabSize: 2, insertSpaces: true, formatOnPaste: true, formatOnType: true, folding: true, bracketPairColorization: { enabled: true }, guides: { bracketPairs: true, indentation: true, }, suggest: { showKeywords: true, showSnippets: true, }, quickSuggestions: { other: true, comments: false, strings: true, }, }) // 监听内容变化 editor.onDidChangeModelContent(() => { const currentValue = editor.getValue() onChange(currentValue) // 验证JSON格式 if (onValidate) { try { JSON.parse(currentValue) onValidate(true, []) } catch (error) { onValidate(false, [(error as Error).message]) } } }) // 添加键盘快捷键 editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => { // 触发保存事件 const event = new CustomEvent('monaco-save') window.dispatchEvent(event) }) editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyR, () => { // 触发刷新事件 const event = new CustomEvent('monaco-refresh') window.dispatchEvent(event) }) editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyD, () => { // 触发下载事件 const event = new CustomEvent('monaco-download') window.dispatchEvent(event) }) // 格式化快捷键 editor.addCommand(monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KeyF, () => { editor.getAction('editor.action.formatDocument').run() }) } // 格式化JSON const formatJson = () => { if (editorRef.current) { editorRef.current.getAction('editor.action.formatDocument').run() } } // 暴露格式化方法 useEffect(() => { const handleFormat = () => formatJson() window.addEventListener('monaco-format', handleFormat) return () => window.removeEventListener('monaco-format', handleFormat) }, []) return (
{/* 编辑器工具栏 */}
navigation.json {value && ( {value.split('\n').length} 行 · {value.length} 字符 )} {/* JSON状态显示 */}
{isValid ? ( <>
格式正确 {stats && ( · {stats.categories} 分类 · {stats.items} 站点 )} ) : ( <>
格式错误 )}
Ctrl+S 保存
Alt+Shift+F 格式化
Ctrl+F 查找
{/* Monaco Editor */}
加载编辑器...
} />
) }