Implement custom CodeMirror themes and enhance CodeBlockEditor layout
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Added farmControlLight and farmControlDark themes for CodeMirror integration, improving syntax highlighting and overall editor aesthetics. - Updated CodeBlockEditor to utilize the new themes and introduced a layout theme for better responsiveness. - Enhanced styling in App.css for the code block editor, ensuring proper display and overflow handling. - Refactored CodeDiffViewer to support the new themes, maintaining visual consistency across code comparison components.
This commit is contained in:
parent
84adf58542
commit
6a4074674d
@ -47,7 +47,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ant-typography code,
|
.ant-typography code,
|
||||||
.ant-typography pre {
|
.ant-typography pre,
|
||||||
|
.ͼ1 .cm-scroller {
|
||||||
font-family: 'DM Mono';
|
font-family: 'DM Mono';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,6 +966,17 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.code-block-editor {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-block-editor > div {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.ant-splitter-panel:not(:first-child) .info-collapse .info-collapse-label {
|
.ant-splitter-panel:not(:first-child) .info-collapse .info-collapse-label {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
@ -1316,31 +1328,3 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
|||||||
background-color: #85858541;
|
background-color: #85858541;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ͼo {
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ͼu {
|
|
||||||
color: var(--color-warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ͼq {
|
|
||||||
color: var(--color-error);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ͼ13 {
|
|
||||||
color: var(--color-success);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ͼp {
|
|
||||||
color: var(--color-purple);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ͼv {
|
|
||||||
color: var(--color-cyan);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ͼt {
|
|
||||||
color: var(--color-magenta);
|
|
||||||
}
|
|
||||||
|
|||||||
230
src/codemirror/farmControlTheme.js
Normal file
230
src/codemirror/farmControlTheme.js
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
import { EditorView } from '@codemirror/view'
|
||||||
|
import { HighlightStyle, syntaxHighlighting } from '@codemirror/language'
|
||||||
|
import { tags } from '@lezer/highlight'
|
||||||
|
|
||||||
|
const editorFontFamily = "'DM Mono', monospace"
|
||||||
|
|
||||||
|
const farmControlHighlightStyle = HighlightStyle.define([
|
||||||
|
{ tag: tags.keyword, color: 'var(--color-purple)' },
|
||||||
|
{
|
||||||
|
tag: [
|
||||||
|
tags.function(tags.variableName),
|
||||||
|
tags.labelName,
|
||||||
|
tags.definition(tags.function(tags.variableName))
|
||||||
|
],
|
||||||
|
color: 'var(--color-magenta)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: [tags.string, tags.inserted, tags.special(tags.string)],
|
||||||
|
color: 'var(--color-success)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: [
|
||||||
|
tags.number,
|
||||||
|
tags.bool,
|
||||||
|
tags.atom,
|
||||||
|
tags.changed,
|
||||||
|
tags.typeName,
|
||||||
|
tags.className,
|
||||||
|
tags.annotation,
|
||||||
|
tags.modifier,
|
||||||
|
tags.self,
|
||||||
|
tags.namespace,
|
||||||
|
tags.color,
|
||||||
|
tags.constant(tags.name),
|
||||||
|
tags.standard(tags.name)
|
||||||
|
],
|
||||||
|
color: 'var(--color-warning)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: [
|
||||||
|
tags.operator,
|
||||||
|
tags.operatorKeyword,
|
||||||
|
tags.url,
|
||||||
|
tags.escape,
|
||||||
|
tags.regexp,
|
||||||
|
tags.link
|
||||||
|
],
|
||||||
|
color: 'var(--color-cyan)'
|
||||||
|
},
|
||||||
|
{ tag: tags.invalid, color: 'var(--color-error)' },
|
||||||
|
{
|
||||||
|
tag: [tags.meta, tags.comment],
|
||||||
|
color: 'color-mix(in srgb, var(--color-text) 55%, transparent)',
|
||||||
|
fontStyle: 'italic'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: [
|
||||||
|
tags.name,
|
||||||
|
tags.deleted,
|
||||||
|
tags.character,
|
||||||
|
tags.propertyName,
|
||||||
|
tags.macroName,
|
||||||
|
tags.definition(tags.name),
|
||||||
|
tags.separator,
|
||||||
|
tags.variableName
|
||||||
|
],
|
||||||
|
color: 'var(--color-text)'
|
||||||
|
},
|
||||||
|
{ tag: tags.heading, fontWeight: 'bold', color: 'var(--color-error)' },
|
||||||
|
{ tag: tags.strong, fontWeight: 'bold' },
|
||||||
|
{ tag: tags.emphasis, fontStyle: 'italic' },
|
||||||
|
{ tag: tags.strikethrough, textDecoration: 'line-through' },
|
||||||
|
{
|
||||||
|
tag: tags.link,
|
||||||
|
color: 'var(--color-link)',
|
||||||
|
textDecoration: 'underline'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: [tags.processingInstruction],
|
||||||
|
color: 'var(--color-info)'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const farmControlLightTheme = EditorView.theme(
|
||||||
|
{
|
||||||
|
'&': {
|
||||||
|
color: 'var(--color-text)',
|
||||||
|
backgroundColor: 'var(--layout-modal-bg)',
|
||||||
|
fontFamily: editorFontFamily,
|
||||||
|
fontSize: '14px'
|
||||||
|
},
|
||||||
|
'.cm-content': {
|
||||||
|
caretColor: 'var(--color-primary)'
|
||||||
|
},
|
||||||
|
'.cm-cursor, .cm-dropCursor': {
|
||||||
|
borderLeftColor: 'var(--color-primary)'
|
||||||
|
},
|
||||||
|
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection':
|
||||||
|
{
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-primary) 25%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-activeLine': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-primary) 8%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-selectionMatch': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-success) 15%, transparent)'
|
||||||
|
},
|
||||||
|
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-warning) 20%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-gutters': {
|
||||||
|
backgroundColor: 'var(--layout-modal-bg)',
|
||||||
|
color: 'color-mix(in srgb, var(--color-text) 45%, transparent)',
|
||||||
|
border: 'none'
|
||||||
|
},
|
||||||
|
'.cm-activeLineGutter': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-primary) 8%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-foldPlaceholder': {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
border: 'none',
|
||||||
|
color: 'color-mix(in srgb, var(--color-text) 55%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-tooltip': {
|
||||||
|
border: 'none',
|
||||||
|
backgroundColor: 'var(--layout-modal-bg)',
|
||||||
|
color: 'var(--color-text)'
|
||||||
|
},
|
||||||
|
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||||
|
borderTopColor: 'transparent',
|
||||||
|
borderBottomColor: 'transparent'
|
||||||
|
},
|
||||||
|
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||||
|
borderTopColor: 'var(--layout-modal-bg)',
|
||||||
|
borderBottomColor: 'var(--layout-modal-bg)'
|
||||||
|
},
|
||||||
|
'.cm-tooltip-autocomplete': {
|
||||||
|
'& > ul > li[aria-selected]': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-primary) 12%, transparent)',
|
||||||
|
color: 'var(--color-text)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ dark: false }
|
||||||
|
)
|
||||||
|
|
||||||
|
const farmControlDarkTheme = EditorView.theme(
|
||||||
|
{
|
||||||
|
'&': {
|
||||||
|
color: 'var(--color-text)',
|
||||||
|
backgroundColor: 'var(--layout-modal-bg)',
|
||||||
|
fontFamily: editorFontFamily,
|
||||||
|
fontSize: '14px'
|
||||||
|
},
|
||||||
|
'.cm-content': {
|
||||||
|
caretColor: 'var(--color-primary)'
|
||||||
|
},
|
||||||
|
'.cm-cursor, .cm-dropCursor': {
|
||||||
|
borderLeftColor: 'var(--color-primary)'
|
||||||
|
},
|
||||||
|
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection':
|
||||||
|
{
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-primary) 30%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-activeLine': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-primary) 10%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-selectionMatch': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-success) 18%, transparent)'
|
||||||
|
},
|
||||||
|
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-warning) 22%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-gutters': {
|
||||||
|
backgroundColor: 'var(--layout-modal-bg)',
|
||||||
|
color: 'color-mix(in srgb, var(--color-text) 45%, transparent)',
|
||||||
|
border: 'none'
|
||||||
|
},
|
||||||
|
'.cm-activeLineGutter': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-primary) 10%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-foldPlaceholder': {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
border: 'none',
|
||||||
|
color: 'color-mix(in srgb, var(--color-text) 55%, transparent)'
|
||||||
|
},
|
||||||
|
'.cm-tooltip': {
|
||||||
|
border: 'none',
|
||||||
|
backgroundColor: 'var(--layout-modal-bg)',
|
||||||
|
color: 'var(--color-text)'
|
||||||
|
},
|
||||||
|
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||||
|
borderTopColor: 'transparent',
|
||||||
|
borderBottomColor: 'transparent'
|
||||||
|
},
|
||||||
|
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||||
|
borderTopColor: 'var(--layout-modal-bg)',
|
||||||
|
borderBottomColor: 'var(--layout-modal-bg)'
|
||||||
|
},
|
||||||
|
'.cm-tooltip-autocomplete': {
|
||||||
|
'& > ul > li[aria-selected]': {
|
||||||
|
backgroundColor:
|
||||||
|
'color-mix(in srgb, var(--color-primary) 15%, transparent)',
|
||||||
|
color: 'var(--color-text)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ dark: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
export const farmControlLight = [
|
||||||
|
farmControlLightTheme,
|
||||||
|
syntaxHighlighting(farmControlHighlightStyle)
|
||||||
|
]
|
||||||
|
|
||||||
|
export const farmControlDark = [
|
||||||
|
farmControlDarkTheme,
|
||||||
|
syntaxHighlighting(farmControlHighlightStyle)
|
||||||
|
]
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { useMemo, useState } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import CodeMirror from '@uiw/react-codemirror'
|
import CodeMirror from '@uiw/react-codemirror'
|
||||||
import { EditorView, Decoration } from '@codemirror/view'
|
import { EditorView, Decoration, ViewPlugin } from '@codemirror/view'
|
||||||
import { StateField } from '@codemirror/state'
|
import { StateField } from '@codemirror/state'
|
||||||
import { javascript } from '@codemirror/lang-javascript'
|
import { javascript } from '@codemirror/lang-javascript'
|
||||||
import { python } from '@codemirror/lang-python'
|
import { python } from '@codemirror/lang-python'
|
||||||
@ -17,13 +17,88 @@ import { go } from '@codemirror/lang-go'
|
|||||||
import { php } from '@codemirror/lang-php'
|
import { php } from '@codemirror/lang-php'
|
||||||
import { yaml } from '@codemirror/lang-yaml'
|
import { yaml } from '@codemirror/lang-yaml'
|
||||||
import { xml } from '@codemirror/lang-xml'
|
import { xml } from '@codemirror/lang-xml'
|
||||||
import { oneDark } from '@codemirror/theme-one-dark'
|
import {
|
||||||
|
farmControlDark,
|
||||||
|
farmControlLight
|
||||||
|
} from '../../../codemirror/farmControlTheme'
|
||||||
import { fcTemplateLang } from '../../../codemirror/fcTemplateLang'
|
import { fcTemplateLang } from '../../../codemirror/fcTemplateLang'
|
||||||
import { useThemeContext } from '../context/ThemeContext'
|
import { useThemeContext } from '../context/ThemeContext'
|
||||||
import { Button, Modal, Typography } from 'antd'
|
import ScrollBox from './ScrollBox'
|
||||||
|
import { Button, Modal, Typography, Card } from 'antd'
|
||||||
|
|
||||||
const { Link } = Typography
|
const { Link } = Typography
|
||||||
|
|
||||||
|
const codeBlockEditorLayoutTheme = EditorView.theme({
|
||||||
|
'&': {
|
||||||
|
height: 'auto !important'
|
||||||
|
},
|
||||||
|
'.cm-scroller': {
|
||||||
|
overflow: 'visible !important'
|
||||||
|
},
|
||||||
|
'.cm-gutters': {
|
||||||
|
position: 'sticky',
|
||||||
|
left: '0',
|
||||||
|
zIndex: 2
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function createScrollBoxSyncExtension() {
|
||||||
|
return ViewPlugin.fromClass(
|
||||||
|
class {
|
||||||
|
constructor(view) {
|
||||||
|
this.view = view
|
||||||
|
this.scrollEl = view.dom.closest('.simplebar-content-wrapper')
|
||||||
|
this.syncing = false
|
||||||
|
this.onExternalScroll = this.onExternalScroll.bind(this)
|
||||||
|
this.onEditorScroll = this.onEditorScroll.bind(this)
|
||||||
|
|
||||||
|
if (this.scrollEl) {
|
||||||
|
this.scrollEl.addEventListener('scroll', this.onExternalScroll, {
|
||||||
|
passive: true
|
||||||
|
})
|
||||||
|
view.scrollDOM.addEventListener('scroll', this.onEditorScroll, {
|
||||||
|
passive: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncFromExternal() {
|
||||||
|
const { view, scrollEl } = this
|
||||||
|
if (this.syncing || !scrollEl) return
|
||||||
|
this.syncing = true
|
||||||
|
view.scrollDOM.scrollTop = scrollEl.scrollTop
|
||||||
|
view.scrollDOM.scrollLeft = scrollEl.scrollLeft
|
||||||
|
view.scrollDOM.dispatchEvent(new Event('scroll'))
|
||||||
|
this.syncing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
syncFromEditor() {
|
||||||
|
const { view, scrollEl } = this
|
||||||
|
if (this.syncing || !scrollEl) return
|
||||||
|
this.syncing = true
|
||||||
|
scrollEl.scrollTop = view.scrollDOM.scrollTop
|
||||||
|
scrollEl.scrollLeft = view.scrollDOM.scrollLeft
|
||||||
|
this.syncing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onExternalScroll() {
|
||||||
|
this.syncFromExternal()
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditorScroll() {
|
||||||
|
this.syncFromEditor()
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
if (this.scrollEl) {
|
||||||
|
this.scrollEl.removeEventListener('scroll', this.onExternalScroll)
|
||||||
|
this.view.scrollDOM.removeEventListener('scroll', this.onEditorScroll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function toEditorCode(code, language = 'javascript') {
|
export function toEditorCode(code, language = 'javascript') {
|
||||||
if (code == null) return ''
|
if (code == null) return ''
|
||||||
if (typeof code === 'object' && language === 'json') {
|
if (typeof code === 'object' && language === 'json') {
|
||||||
@ -148,6 +223,16 @@ export default function CodeBlockEditor({
|
|||||||
return [createErrorLineExtension(errorLines)]
|
return [createErrorLineExtension(errorLines)]
|
||||||
}, [errorLines])
|
}, [errorLines])
|
||||||
|
|
||||||
|
const editorExtensions = useMemo(
|
||||||
|
() => [
|
||||||
|
languageExtension,
|
||||||
|
...errorLineExtension,
|
||||||
|
codeBlockEditorLayoutTheme,
|
||||||
|
createScrollBoxSyncExtension()
|
||||||
|
],
|
||||||
|
[languageExtension, errorLineExtension]
|
||||||
|
)
|
||||||
|
|
||||||
const handleOnChange = (value) => {
|
const handleOnChange = (value) => {
|
||||||
if (typeof code == 'object' && language == 'json') {
|
if (typeof code == 'object' && language == 'json') {
|
||||||
onChange(JSON.parse(value))
|
onChange(JSON.parse(value))
|
||||||
@ -159,43 +244,56 @@ export default function CodeBlockEditor({
|
|||||||
const codeMirror = (
|
const codeMirror = (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border: '1px solid #85858541',
|
...(height !== 'auto' ? { height } : {}),
|
||||||
|
minHeight: 0,
|
||||||
|
overflow: 'visible',
|
||||||
...style
|
...style
|
||||||
}}
|
}}
|
||||||
className={className}
|
className={`code-block-editor h-100 ${className}`.trim()}
|
||||||
>
|
>
|
||||||
<CodeMirror
|
<Card
|
||||||
value={editorCode}
|
|
||||||
height={height}
|
|
||||||
theme={isDarkMode ? oneDark : 'light'}
|
|
||||||
extensions={[languageExtension, ...errorLineExtension]}
|
|
||||||
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={{
|
style={{
|
||||||
fontSize: '14px',
|
borderRadius: 0,
|
||||||
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace'
|
height: '100%',
|
||||||
|
overflow: 'visible',
|
||||||
|
backgroundColor: 'var(--layout-modal-bg)'
|
||||||
}}
|
}}
|
||||||
/>
|
styles={{ body: { padding: 0, height: '100%', overflow: 'visible' } }}
|
||||||
|
>
|
||||||
|
<ScrollBox>
|
||||||
|
<CodeMirror
|
||||||
|
value={editorCode}
|
||||||
|
height='auto'
|
||||||
|
theme={isDarkMode ? farmControlDark : farmControlLight}
|
||||||
|
extensions={editorExtensions}
|
||||||
|
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'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ScrollBox>
|
||||||
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,10 @@ import PropTypes from 'prop-types'
|
|||||||
import { MergeView } from '@codemirror/merge'
|
import { MergeView } from '@codemirror/merge'
|
||||||
import { EditorState } from '@codemirror/state'
|
import { EditorState } from '@codemirror/state'
|
||||||
import { EditorView } from '@codemirror/view'
|
import { EditorView } from '@codemirror/view'
|
||||||
import { oneDark } from '@codemirror/theme-one-dark'
|
import {
|
||||||
|
farmControlDark,
|
||||||
|
farmControlLight
|
||||||
|
} from '../../../codemirror/farmControlTheme'
|
||||||
import { basicSetup } from 'codemirror'
|
import { basicSetup } from 'codemirror'
|
||||||
import { useThemeContext } from '../context/ThemeContext'
|
import { useThemeContext } from '../context/ThemeContext'
|
||||||
import {
|
import {
|
||||||
@ -29,20 +32,12 @@ export default function CodeDiffViewer({
|
|||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!parentRef.current) return
|
if (!parentRef.current) return
|
||||||
|
|
||||||
const editorTheme = EditorView.theme({
|
|
||||||
'&': {
|
|
||||||
fontSize: '14px',
|
|
||||||
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const sharedExtensions = [
|
const sharedExtensions = [
|
||||||
basicSetup,
|
basicSetup,
|
||||||
languageExtension,
|
languageExtension,
|
||||||
editorTheme,
|
|
||||||
EditorView.editable.of(false),
|
EditorView.editable.of(false),
|
||||||
EditorState.readOnly.of(true),
|
EditorState.readOnly.of(true),
|
||||||
...(isDarkMode ? [oneDark] : [])
|
...(isDarkMode ? farmControlDark : farmControlLight)
|
||||||
]
|
]
|
||||||
|
|
||||||
const view = new MergeView({
|
const view = new MergeView({
|
||||||
|
|||||||
@ -913,6 +913,7 @@ const ObjectProperty = ({
|
|||||||
minimal={minimal}
|
minimal={minimal}
|
||||||
autoCompleteObject={autoCompleteObject}
|
autoCompleteObject={autoCompleteObject}
|
||||||
errorLines={errorLines}
|
errorLines={errorLines}
|
||||||
|
{...(onChange && !useFormItem ? { onChange } : {})}
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -240,17 +240,32 @@ const TemplateEditor = ({
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
overflowY: 'scroll',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
flex: '1 1 auto'
|
flex: '1 1 auto',
|
||||||
|
minHeight: 0
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ObjectProperty
|
<ObjectProperty
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
flex: '1 1 auto',
|
||||||
|
minHeight: 0
|
||||||
|
}}
|
||||||
|
useFormItem={false}
|
||||||
name={'content'}
|
name={'content'}
|
||||||
height='100%'
|
height='100%'
|
||||||
type='codeBlock'
|
type='codeBlock'
|
||||||
language={'fcTemplateLang'}
|
language={'fcTemplateLang'}
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
|
onChange={(value) => {
|
||||||
|
form?.setFieldValue?.('content', value)
|
||||||
|
setObjectData?.((prev) => ({
|
||||||
|
...prev,
|
||||||
|
content: value
|
||||||
|
}))
|
||||||
|
}}
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
autoCompleteObject={objectData?.testObject}
|
autoCompleteObject={objectData?.testObject}
|
||||||
errorLines={errorLines}
|
errorLines={errorLines}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user