From 4201f2b4a3b588f426b03384ce260567e7e982a6 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Mon, 18 Aug 2025 00:58:30 +0100 Subject: [PATCH] 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. --- .../Dashboard/common/CodeBlockEditor.jsx | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 src/components/Dashboard/common/CodeBlockEditor.jsx diff --git a/src/components/Dashboard/common/CodeBlockEditor.jsx b/src/components/Dashboard/common/CodeBlockEditor.jsx new file mode 100644 index 0000000..b3281bc --- /dev/null +++ b/src/components/Dashboard/common/CodeBlockEditor.jsx @@ -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 = ( +
+ +
+ ) + + return ( + <> + {minimal ? ( +
+ { + setCodeMirrorOpen(true) + }} + > +
{editorCode.slice(-64).trim()}...
+ + { + setCodeMirrorOpen(false) + }} + > + Close + + } + > + {codeMirror} + +
+ ) : ( + 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 +}