Add CodeBlockEditor component for enhanced code editing experience
- Introduced CodeBlockEditor component to support multiple programming languages with syntax highlighting using CodeMirror. - Implemented features such as customizable styles, read-only mode, and line number visibility. - Added support for JSON object parsing and modal display for minimal view. - Integrated theme context for dark mode support and improved user interaction with onChange handling. - Defined prop types for better type checking and documentation.
This commit is contained in:
parent
a9a2801e27
commit
4201f2b4a3
192
src/components/Dashboard/common/CodeBlockEditor.jsx
Normal file
192
src/components/Dashboard/common/CodeBlockEditor.jsx
Normal file
@ -0,0 +1,192 @@
|
||||
import React, { 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
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user