193 lines
4.9 KiB
JavaScript
193 lines
4.9 KiB
JavaScript
import { useMemo, useState } from 'react'
|
|
import PropTypes from 'prop-types'
|
|
import CodeMirror from '@uiw/react-codemirror'
|
|
import { javascript } from '@codemirror/lang-javascript'
|
|
import { python } from '@codemirror/lang-python'
|
|
import { json } from '@codemirror/lang-json'
|
|
import { css } from '@codemirror/lang-css'
|
|
import { html } from '@codemirror/lang-html'
|
|
import { markdown } from '@codemirror/lang-markdown'
|
|
import { sql } from '@codemirror/lang-sql'
|
|
import { java } from '@codemirror/lang-java'
|
|
import { cpp } from '@codemirror/lang-cpp'
|
|
import { rust } from '@codemirror/lang-rust'
|
|
import { go } from '@codemirror/lang-go'
|
|
import { php } from '@codemirror/lang-php'
|
|
import { yaml } from '@codemirror/lang-yaml'
|
|
import { xml } from '@codemirror/lang-xml'
|
|
import { oneDark } from '@codemirror/theme-one-dark'
|
|
import { useThemeContext } from '../context/ThemeContext'
|
|
import { Button, Modal, Typography } from 'antd'
|
|
|
|
const { Link } = Typography
|
|
|
|
export default function CodeBlockEditor({
|
|
code = '',
|
|
language = 'javascript',
|
|
style = {},
|
|
className = '',
|
|
readOnly = false,
|
|
onChange = null,
|
|
height = 'auto',
|
|
showLineNumbers = true,
|
|
disabled = false,
|
|
minimal = false
|
|
}) {
|
|
const { isDarkMode } = useThemeContext()
|
|
const [codeMirrorOpen, setCodeMirrorOpen] = useState(false)
|
|
var editorCode = code
|
|
|
|
if (typeof code == 'object' && language == 'json') {
|
|
editorCode = JSON.stringify(code, null, 2)
|
|
}
|
|
|
|
console.log(editorCode)
|
|
|
|
// Map language to CodeMirror extension
|
|
const languageExtension = useMemo(() => {
|
|
switch (language.toLowerCase()) {
|
|
case 'javascript':
|
|
case 'js':
|
|
return javascript()
|
|
case 'python':
|
|
case 'py':
|
|
return python()
|
|
case 'json':
|
|
return json()
|
|
case 'xml':
|
|
return xml()
|
|
case 'ejs':
|
|
return xml()
|
|
case 'html':
|
|
return html()
|
|
case 'css':
|
|
return css()
|
|
case 'markdown':
|
|
case 'md':
|
|
return markdown()
|
|
case 'sql':
|
|
return sql()
|
|
case 'java':
|
|
return java()
|
|
case 'cpp':
|
|
case 'c++':
|
|
case 'c':
|
|
return cpp()
|
|
case 'rust':
|
|
case 'rs':
|
|
return rust()
|
|
case 'go':
|
|
return go()
|
|
case 'php':
|
|
return php()
|
|
case 'yaml':
|
|
case 'yml':
|
|
return yaml()
|
|
default:
|
|
return javascript() // Default fallback
|
|
}
|
|
}, [language])
|
|
|
|
const handleOnChange = (value) => {
|
|
if (typeof code == 'object' && language == 'json') {
|
|
console.log('Parsing object', JSON.parse(value))
|
|
onChange(JSON.parse(value))
|
|
} else {
|
|
onChange(value)
|
|
}
|
|
}
|
|
|
|
const codeMirror = (
|
|
<div
|
|
style={{
|
|
border: '1px solid #85858541',
|
|
...style
|
|
}}
|
|
className={className}
|
|
>
|
|
<CodeMirror
|
|
value={editorCode}
|
|
height={height}
|
|
theme={isDarkMode ? oneDark : 'light'}
|
|
extensions={[languageExtension]}
|
|
readOnly={readOnly || disabled}
|
|
onChange={handleOnChange}
|
|
basicSetup={{
|
|
lineNumbers: showLineNumbers,
|
|
foldGutter: true,
|
|
dropCursor: false,
|
|
allowMultipleSelections: false,
|
|
indentOnInput: false,
|
|
syntaxHighlighting: true,
|
|
bracketMatching: true,
|
|
closeBrackets: true,
|
|
autocompletion: !readOnly,
|
|
rectangularSelection: false,
|
|
crosshairCursor: false,
|
|
highlightActiveLine: !readOnly,
|
|
highlightSelectionMatches: false,
|
|
closeBracketsKeymap: false,
|
|
searchKeymap: false,
|
|
foldKeymap: false,
|
|
completionKeymap: !readOnly,
|
|
lintKeymap: false
|
|
}}
|
|
style={{
|
|
fontSize: '14px',
|
|
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace'
|
|
}}
|
|
/>
|
|
</div>
|
|
)
|
|
|
|
return (
|
|
<>
|
|
{minimal ? (
|
|
<div style={{ maxWidth: '300px' }}>
|
|
<Link
|
|
onClick={() => {
|
|
setCodeMirrorOpen(true)
|
|
}}
|
|
>
|
|
<pre>{editorCode.slice(-64).trim()}...</pre>
|
|
</Link>
|
|
<Modal
|
|
closeIcon={false}
|
|
open={codeMirrorOpen}
|
|
width={800}
|
|
footer={
|
|
<Button
|
|
onClick={() => {
|
|
setCodeMirrorOpen(false)
|
|
}}
|
|
>
|
|
Close
|
|
</Button>
|
|
}
|
|
>
|
|
{codeMirror}
|
|
</Modal>
|
|
</div>
|
|
) : (
|
|
codeMirror
|
|
)}
|
|
</>
|
|
)
|
|
}
|
|
|
|
CodeBlockEditor.propTypes = {
|
|
code: PropTypes.string.isRequired,
|
|
language: PropTypes.oneOfType([
|
|
PropTypes.string,
|
|
PropTypes.arrayOf(PropTypes.string)
|
|
]),
|
|
style: PropTypes.object,
|
|
className: PropTypes.string,
|
|
readOnly: PropTypes.bool,
|
|
onChange: PropTypes.func,
|
|
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
showLineNumbers: PropTypes.bool,
|
|
disabled: PropTypes.bool,
|
|
minimal: PropTypes.bool
|
|
}
|