|
5 | 5 | * Copyright (c) Sebastian Stehle. All rights reserved.
|
6 | 6 | */
|
7 | 7 |
|
8 |
| -// tslint:disable: quotemark |
9 |
| - |
| 8 | +import * as React from 'react'; |
10 | 9 | import Split from 'react-split';
|
11 | 10 | import { Alert } from 'reactstrap';
|
12 |
| -import { IFrame } from '@app/framework'; |
| 11 | +import { CodeEditor, CodeEditorProps, IFrame } from '@app/framework'; |
13 | 12 | import { MjmlSchema } from '@app/service';
|
14 |
| -import { EmailHtmlTextEditor } from './EmailHtmlTextEditor'; |
15 |
| -import { usePreview } from './helpers'; |
16 |
| - |
17 |
| -export interface EmailHtmlEditorProps { |
18 |
| - // The value. |
19 |
| - value: string; |
| 13 | +import { useErrors, usePreview } from './helpers'; |
| 14 | +import { completeAfter, completeIfAfterLt, completeIfInTag } from './helpers'; |
| 15 | +import 'codemirror/addon/dialog/dialog'; |
| 16 | +import 'codemirror/addon/edit/closetag'; |
| 17 | +import 'codemirror/addon/edit/matchtags'; |
| 18 | +import 'codemirror/addon/hint/show-hint'; |
| 19 | +import 'codemirror/addon/hint/xml-hint'; |
| 20 | +import 'codemirror/addon/lint/lint'; |
| 21 | +import 'codemirror/addon/scroll/annotatescrollbar'; |
| 22 | +import 'codemirror/addon/search/jump-to-line'; |
| 23 | +import 'codemirror/addon/search/match-highlighter'; |
| 24 | +import 'codemirror/addon/search/matchesonscrollbar'; |
| 25 | +import 'codemirror/addon/search/search'; |
| 26 | +import 'codemirror/addon/search/searchcursor'; |
| 27 | +import 'codemirror/addon/selection/active-line'; |
| 28 | +import 'codemirror/mode/xml/xml'; |
20 | 29 |
|
| 30 | +export interface EmailHtmlEditorProps extends CodeEditorProps { |
21 | 31 | // The app name.
|
22 | 32 | appId: string;
|
23 | 33 |
|
24 | 34 | // The schema.
|
25 | 35 | schema?: MjmlSchema;
|
26 |
| - |
27 |
| - // When the html has changed. |
28 |
| - onChange: (value: string) => void; |
29 |
| - |
30 |
| - // Called when the focus has been lost. |
31 |
| - onBlur: () => void; |
32 | 36 | }
|
33 | 37 |
|
34 | 38 | export const EmailHtmlEditor = (props: EmailHtmlEditorProps) => {
|
35 | 39 | const {
|
36 | 40 | appId,
|
37 |
| - onBlur, |
38 |
| - onChange, |
39 | 41 | schema,
|
40 | 42 | value,
|
| 43 | + ...other |
41 | 44 | } = props;
|
42 | 45 |
|
43 | 46 | const emailMarkup = value || '';
|
44 | 47 | const emailPreview = usePreview(appId, emailMarkup, 'Html');
|
45 | 48 |
|
46 |
| - const error = emailPreview.rendering.errors?.[0]; |
| 49 | + const initialOptions = React.useMemo(() => { |
| 50 | + const result: CodeEditorProps['options'] = { |
| 51 | + autoCloseTags: true, |
| 52 | + mode: 'xml', |
| 53 | + extraKeys: { |
| 54 | + Tab: (cm) => { |
| 55 | + if (cm.getMode().name === 'null') { |
| 56 | + cm.execCommand('insertTab'); |
| 57 | + } else if (cm.somethingSelected()) { |
| 58 | + cm.execCommand('indentMore'); |
| 59 | + } else { |
| 60 | + cm.execCommand('insertSoftTab'); |
| 61 | + } |
| 62 | + }, |
| 63 | + '\'<\'': completeAfter, |
| 64 | + '\'/\'': completeIfAfterLt, |
| 65 | + '\' \'': completeIfInTag, |
| 66 | + '\'=\'': completeIfInTag, |
| 67 | + 'Ctrl-Space': 'autocomplete', |
| 68 | + }, |
| 69 | + matchTags: true, |
| 70 | + }; |
| 71 | + |
| 72 | + return result; |
| 73 | + }, []); |
| 74 | + |
| 75 | + const { lint, error } = useErrors(emailPreview.rendering); |
| 76 | + |
| 77 | + const options = React.useMemo(() => { |
| 78 | + const result: CodeEditorProps['options'] = { |
| 79 | + hintOptions: schema ? { schemaInfo: schema } : undefined, |
| 80 | + lint, |
| 81 | + }; |
| 82 | + |
| 83 | + return result; |
| 84 | + }, [lint, schema]); |
47 | 85 |
|
48 | 86 | return (
|
49 |
| - <div className='email-editor'> |
| 87 | + <div className='email-editor white'> |
50 | 88 | <Split direction='horizontal'>
|
51 | 89 | <div className='left'>
|
52 |
| - <EmailHtmlTextEditor |
53 |
| - value={emailMarkup} |
54 |
| - errors={emailPreview.rendering?.errors} |
55 |
| - onBlur={onBlur} |
56 |
| - onChange={onChange} |
57 |
| - schema={schema} |
58 |
| - /> |
| 90 | + <CodeEditor initialOptions={initialOptions} options={options} value={emailMarkup} |
| 91 | + className='email-editor' {...other} /> |
59 | 92 | </div>
|
60 | 93 |
|
61 | 94 | <div className='right'>
|
|
0 commit comments