feat: Add improved html editor using CodeMirror
This commit is contained in:
@@ -10,6 +10,7 @@ import {Variable} from './VariableExtension';
|
||||
import {setAvailableVariables, VariableMention} from './VariableMention';
|
||||
import {Toolbar} from './Toolbar';
|
||||
import {ResizableImage} from './ResizableImage';
|
||||
import {HtmlEditor} from './HtmlEditor';
|
||||
import {useContactFields, useContacts} from '../../lib/hooks/useContacts';
|
||||
import {useConfig} from '../../lib/hooks/useConfig';
|
||||
import {useEffect, useRef, useState} from 'react';
|
||||
@@ -556,12 +557,11 @@ export function EmailEditor({value, onChange, placeholder, subject, from, replyT
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="min-h-[400px] max-h-[600px] overflow-y-auto">
|
||||
<textarea
|
||||
<div className="min-h-[400px] max-h-[600px] overflow-hidden">
|
||||
<HtmlEditor
|
||||
value={htmlContent}
|
||||
onChange={e => handleHtmlChange(e.target.value)}
|
||||
onChange={handleHtmlChange}
|
||||
placeholder={placeholder || 'Your next email starts here!'}
|
||||
className="w-full h-full px-4 py-3 text-sm font-mono resize-none min-h-[400px] focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
{selectedContactId && (
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
import CodeMirror from '@uiw/react-codemirror';
|
||||
import {html} from '@codemirror/lang-html';
|
||||
import {EditorView} from '@codemirror/view';
|
||||
import {useMemo} from 'react';
|
||||
|
||||
interface HtmlEditorProps {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
export function HtmlEditor({value, onChange, placeholder}: HtmlEditorProps) {
|
||||
// Custom theme configuration for better integration with the app
|
||||
const theme = EditorView.theme({
|
||||
'&': {
|
||||
fontSize: '14px',
|
||||
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
|
||||
height: '100%',
|
||||
},
|
||||
'.cm-content': {
|
||||
minHeight: '400px',
|
||||
padding: '12px 16px',
|
||||
caretColor: '#1f2937',
|
||||
},
|
||||
'.cm-line': {
|
||||
padding: '0',
|
||||
lineHeight: '1.6',
|
||||
},
|
||||
'.cm-gutters': {
|
||||
backgroundColor: '#f9fafb',
|
||||
color: '#9ca3af',
|
||||
border: 'none',
|
||||
borderRight: '1px solid #e5e7eb',
|
||||
paddingRight: '8px',
|
||||
paddingLeft: '8px',
|
||||
},
|
||||
'.cm-activeLineGutter': {
|
||||
backgroundColor: '#f3f4f6',
|
||||
color: '#374151',
|
||||
},
|
||||
'.cm-activeLine': {
|
||||
backgroundColor: '#f9fafb',
|
||||
},
|
||||
'.cm-selectionBackground, ::selection': {
|
||||
backgroundColor: '#dbeafe !important',
|
||||
},
|
||||
'.cm-focused .cm-selectionBackground, .cm-focused ::selection': {
|
||||
backgroundColor: '#bfdbfe !important',
|
||||
},
|
||||
'.cm-cursor': {
|
||||
borderLeftColor: '#1f2937',
|
||||
},
|
||||
'&.cm-focused': {
|
||||
outline: 'none',
|
||||
},
|
||||
'.cm-scroller': {
|
||||
overflow: 'auto',
|
||||
maxHeight: '600px',
|
||||
},
|
||||
});
|
||||
|
||||
// Extensions with HTML support and line numbers
|
||||
const extensions = useMemo(
|
||||
() => [
|
||||
html(),
|
||||
theme,
|
||||
EditorView.lineWrapping, // Enable line wrapping for long lines
|
||||
],
|
||||
[theme]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="html-editor-container">
|
||||
<CodeMirror
|
||||
value={value}
|
||||
height="100%"
|
||||
extensions={extensions}
|
||||
onChange={onChange}
|
||||
placeholder={placeholder}
|
||||
basicSetup={{
|
||||
lineNumbers: true,
|
||||
highlightActiveLineGutter: true,
|
||||
highlightActiveLine: true,
|
||||
foldGutter: true,
|
||||
dropCursor: true,
|
||||
allowMultipleSelections: true,
|
||||
indentOnInput: true,
|
||||
bracketMatching: true,
|
||||
closeBrackets: true,
|
||||
autocompletion: true,
|
||||
rectangularSelection: true,
|
||||
crosshairCursor: true,
|
||||
highlightSelectionMatches: true,
|
||||
closeBracketsKeymap: true,
|
||||
searchKeymap: true,
|
||||
foldKeymap: true,
|
||||
completionKeymap: true,
|
||||
lintKeymap: true,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user