Parse content to html
This commit is contained in:
parent
45c95c7f11
commit
392e7218de
@ -1,14 +1,8 @@
|
|||||||
import { LexicalComposer } from "@lexical/react/LexicalComposer";
|
|
||||||
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
||||||
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
|
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
|
||||||
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
|
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
|
||||||
import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
|
import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
|
||||||
import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
|
import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
|
||||||
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
|
|
||||||
import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
|
|
||||||
import { ListItemNode, ListNode } from "@lexical/list";
|
|
||||||
import { CodeHighlightNode, CodeNode } from "@lexical/code";
|
|
||||||
import { AutoLinkNode, LinkNode } from "@lexical/link";
|
|
||||||
import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
|
import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
|
||||||
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
|
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
|
||||||
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
|
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
|
||||||
@ -19,119 +13,29 @@ import ListMaxIndentLevelPlugin from "../plugins/ListMaxIndentLevelPlugin";
|
|||||||
import CodeHighlightPlugin from "../plugins/CodeHighlightPlugin";
|
import CodeHighlightPlugin from "../plugins/CodeHighlightPlugin";
|
||||||
import AutoLinkPlugin from "../plugins/AutoLinkPlugin";
|
import AutoLinkPlugin from "../plugins/AutoLinkPlugin";
|
||||||
|
|
||||||
const exampleTheme = {
|
|
||||||
ltr: "ltr",
|
|
||||||
rtl: "rtl",
|
|
||||||
placeholder: "editor-placeholder",
|
|
||||||
paragraph: "editor-paragraph",
|
|
||||||
quote: "editor-quote",
|
|
||||||
heading: {
|
|
||||||
h1: "editor-heading-h1",
|
|
||||||
h2: "editor-heading-h2",
|
|
||||||
h3: "editor-heading-h3",
|
|
||||||
h4: "editor-heading-h4",
|
|
||||||
h5: "editor-heading-h5",
|
|
||||||
},
|
|
||||||
list: {
|
|
||||||
nested: {
|
|
||||||
listitem: "editor-nested-listitem",
|
|
||||||
},
|
|
||||||
ol: "editor-list-ol",
|
|
||||||
ul: "editor-list-ul",
|
|
||||||
listitem: "editor-listitem",
|
|
||||||
},
|
|
||||||
image: "editor-image",
|
|
||||||
link: "editor-link",
|
|
||||||
text: {
|
|
||||||
bold: "editor-text-bold",
|
|
||||||
italic: "editor-text-italic",
|
|
||||||
overflowed: "editor-text-overflowed",
|
|
||||||
hashtag: "editor-text-hashtag",
|
|
||||||
underline: "editor-text-underline",
|
|
||||||
strikethrough: "editor-text-strikethrough",
|
|
||||||
underlineStrikethrough: "editor-text-underlineStrikethrough",
|
|
||||||
code: "editor-text-code",
|
|
||||||
},
|
|
||||||
code: "editor-code",
|
|
||||||
codeHighlight: {
|
|
||||||
atrule: "editor-tokenAttr",
|
|
||||||
attr: "editor-tokenAttr",
|
|
||||||
boolean: "editor-tokenProperty",
|
|
||||||
builtin: "editor-tokenSelector",
|
|
||||||
cdata: "editor-tokenComment",
|
|
||||||
char: "editor-tokenSelector",
|
|
||||||
class: "editor-tokenFunction",
|
|
||||||
"class-name": "editor-tokenFunction",
|
|
||||||
comment: "editor-tokenComment",
|
|
||||||
constant: "editor-tokenProperty",
|
|
||||||
deleted: "editor-tokenProperty",
|
|
||||||
doctype: "editor-tokenComment",
|
|
||||||
entity: "editor-tokenOperator",
|
|
||||||
function: "editor-tokenFunction",
|
|
||||||
important: "editor-tokenVariable",
|
|
||||||
inserted: "editor-tokenSelector",
|
|
||||||
keyword: "editor-tokenAttr",
|
|
||||||
namespace: "editor-tokenVariable",
|
|
||||||
number: "editor-tokenProperty",
|
|
||||||
operator: "editor-tokenOperator",
|
|
||||||
prolog: "editor-tokenComment",
|
|
||||||
property: "editor-tokenProperty",
|
|
||||||
punctuation: "editor-tokenPunctuation",
|
|
||||||
regex: "editor-tokenVariable",
|
|
||||||
selector: "editor-tokenSelector",
|
|
||||||
string: "editor-tokenSelector",
|
|
||||||
symbol: "editor-tokenProperty",
|
|
||||||
tag: "editor-tokenProperty",
|
|
||||||
url: "editor-tokenOperator",
|
|
||||||
variable: "editor-tokenVariable",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function Placeholder() {
|
function Placeholder() {
|
||||||
return <div className="editor-placeholder">Describe the bug</div>;
|
return <div className="editor-placeholder">Describe the bug</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const editorConfig = {
|
export default function RichEditor({ theme }) {
|
||||||
theme: exampleTheme,
|
|
||||||
onError(error) {
|
|
||||||
throw error;
|
|
||||||
},
|
|
||||||
nodes: [
|
|
||||||
HeadingNode,
|
|
||||||
ListNode,
|
|
||||||
ListItemNode,
|
|
||||||
QuoteNode,
|
|
||||||
CodeNode,
|
|
||||||
CodeHighlightNode,
|
|
||||||
TableNode,
|
|
||||||
TableCellNode,
|
|
||||||
TableRowNode,
|
|
||||||
AutoLinkNode,
|
|
||||||
LinkNode,
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function RichEditor(props) {
|
|
||||||
return (
|
return (
|
||||||
<LexicalComposer initialConfig={editorConfig}>
|
<div className="editor-container">
|
||||||
<div className="editor-container">
|
<ToolbarPlugin theme={theme} />
|
||||||
<ToolbarPlugin theme={props.theme} />
|
<div className="editor-inner">
|
||||||
<div className="editor-inner">
|
<RichTextPlugin
|
||||||
<RichTextPlugin
|
contentEditable={<ContentEditable className="editor-input" />}
|
||||||
contentEditable={<ContentEditable className="editor-input" />}
|
placeholder={<Placeholder />}
|
||||||
placeholder={<Placeholder />}
|
ErrorBoundary={LexicalErrorBoundary}
|
||||||
ErrorBoundary={LexicalErrorBoundary}
|
/>
|
||||||
/>
|
<HistoryPlugin />
|
||||||
<HistoryPlugin />
|
<AutoFocusPlugin />
|
||||||
<AutoFocusPlugin />
|
<CodeHighlightPlugin />
|
||||||
<CodeHighlightPlugin />
|
<ListPlugin />
|
||||||
<ListPlugin />
|
<LinkPlugin />
|
||||||
<LinkPlugin />
|
<AutoLinkPlugin />
|
||||||
<AutoLinkPlugin />
|
<ListMaxIndentLevelPlugin maxDepth={7} />
|
||||||
<ListMaxIndentLevelPlugin maxDepth={7} />
|
<MarkdownShortcutPlugin transformers={TRANSFORMERS} />
|
||||||
<MarkdownShortcutPlugin transformers={TRANSFORMERS} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</LexicalComposer>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
93
src/data/editor_config.js
Normal file
93
src/data/editor_config.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
|
||||||
|
import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
|
||||||
|
import { ListItemNode, ListNode } from "@lexical/list";
|
||||||
|
import { CodeHighlightNode, CodeNode } from "@lexical/code";
|
||||||
|
import { AutoLinkNode, LinkNode } from "@lexical/link";
|
||||||
|
|
||||||
|
const exampleTheme = {
|
||||||
|
ltr: "ltr",
|
||||||
|
rtl: "rtl",
|
||||||
|
placeholder: "editor-placeholder",
|
||||||
|
paragraph: "editor-paragraph",
|
||||||
|
quote: "editor-quote",
|
||||||
|
heading: {
|
||||||
|
h1: "editor-heading-h1",
|
||||||
|
h2: "editor-heading-h2",
|
||||||
|
h3: "editor-heading-h3",
|
||||||
|
h4: "editor-heading-h4",
|
||||||
|
h5: "editor-heading-h5",
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
nested: {
|
||||||
|
listitem: "editor-nested-listitem",
|
||||||
|
},
|
||||||
|
ol: "editor-list-ol",
|
||||||
|
ul: "editor-list-ul",
|
||||||
|
listitem: "editor-listitem",
|
||||||
|
},
|
||||||
|
image: "editor-image",
|
||||||
|
link: "editor-link",
|
||||||
|
text: {
|
||||||
|
bold: "editor-text-bold",
|
||||||
|
italic: "editor-text-italic",
|
||||||
|
overflowed: "editor-text-overflowed",
|
||||||
|
hashtag: "editor-text-hashtag",
|
||||||
|
underline: "editor-text-underline",
|
||||||
|
strikethrough: "editor-text-strikethrough",
|
||||||
|
underlineStrikethrough: "editor-text-underlineStrikethrough",
|
||||||
|
code: "editor-text-code",
|
||||||
|
},
|
||||||
|
code: "editor-code",
|
||||||
|
codeHighlight: {
|
||||||
|
atrule: "editor-tokenAttr",
|
||||||
|
attr: "editor-tokenAttr",
|
||||||
|
boolean: "editor-tokenProperty",
|
||||||
|
builtin: "editor-tokenSelector",
|
||||||
|
cdata: "editor-tokenComment",
|
||||||
|
char: "editor-tokenSelector",
|
||||||
|
class: "editor-tokenFunction",
|
||||||
|
"class-name": "editor-tokenFunction",
|
||||||
|
comment: "editor-tokenComment",
|
||||||
|
constant: "editor-tokenProperty",
|
||||||
|
deleted: "editor-tokenProperty",
|
||||||
|
doctype: "editor-tokenComment",
|
||||||
|
entity: "editor-tokenOperator",
|
||||||
|
function: "editor-tokenFunction",
|
||||||
|
important: "editor-tokenVariable",
|
||||||
|
inserted: "editor-tokenSelector",
|
||||||
|
keyword: "editor-tokenAttr",
|
||||||
|
namespace: "editor-tokenVariable",
|
||||||
|
number: "editor-tokenProperty",
|
||||||
|
operator: "editor-tokenOperator",
|
||||||
|
prolog: "editor-tokenComment",
|
||||||
|
property: "editor-tokenProperty",
|
||||||
|
punctuation: "editor-tokenPunctuation",
|
||||||
|
regex: "editor-tokenVariable",
|
||||||
|
selector: "editor-tokenSelector",
|
||||||
|
string: "editor-tokenSelector",
|
||||||
|
symbol: "editor-tokenProperty",
|
||||||
|
tag: "editor-tokenProperty",
|
||||||
|
url: "editor-tokenOperator",
|
||||||
|
variable: "editor-tokenVariable",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const editorConfig = {
|
||||||
|
theme: exampleTheme,
|
||||||
|
onError(error) {
|
||||||
|
throw error;
|
||||||
|
},
|
||||||
|
nodes: [
|
||||||
|
HeadingNode,
|
||||||
|
ListNode,
|
||||||
|
ListItemNode,
|
||||||
|
QuoteNode,
|
||||||
|
CodeNode,
|
||||||
|
CodeHighlightNode,
|
||||||
|
TableNode,
|
||||||
|
TableCellNode,
|
||||||
|
TableRowNode,
|
||||||
|
AutoLinkNode,
|
||||||
|
LinkNode,
|
||||||
|
],
|
||||||
|
};
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState, useCallback } from "react";
|
||||||
import logo_light from "../assets/logo_light_46.png";
|
import logo_light from "../assets/logo_light_46.png";
|
||||||
import logo_dark from "../assets/logo_dark_46.png";
|
import logo_dark from "../assets/logo_dark_46.png";
|
||||||
import { Banner, Button, Input, Upload } from "@douyinfe/semi-ui";
|
import { Banner, Button, Input, Upload } from "@douyinfe/semi-ui";
|
||||||
@ -9,6 +9,43 @@ import {
|
|||||||
IconPaperclip,
|
IconPaperclip,
|
||||||
} from "@douyinfe/semi-icons";
|
} from "@douyinfe/semi-icons";
|
||||||
import RichEditor from "../components/rich_editor";
|
import RichEditor from "../components/rich_editor";
|
||||||
|
import { LexicalComposer } from "@lexical/react/LexicalComposer";
|
||||||
|
import { editorConfig } from "../data/editor_config";
|
||||||
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
||||||
|
import { $generateHtmlFromNodes } from "@lexical/html";
|
||||||
|
|
||||||
|
function Form({ theme }) {
|
||||||
|
const [editor] = useLexicalComposerContext();
|
||||||
|
|
||||||
|
const onSubmit = useCallback(
|
||||||
|
(e) => {
|
||||||
|
editor.update(() => {
|
||||||
|
const tmp = $generateHtmlFromNodes(editor);
|
||||||
|
console.log(tmp);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[editor]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-5 mt-6 card-theme rounded-md">
|
||||||
|
<Input placeholder="Title" />
|
||||||
|
<RichEditor theme={theme} />
|
||||||
|
<Upload
|
||||||
|
action="#"
|
||||||
|
beforeUpload={({ file, fileList }) => {}}
|
||||||
|
draggable={true}
|
||||||
|
dragMainText="Click to upload the file or drag and drop the file here"
|
||||||
|
dragSubText="Support json"
|
||||||
|
accept="application/json,.ddb"
|
||||||
|
onRemove={() => {}}
|
||||||
|
onFileChange={() => {}}
|
||||||
|
limit={5}
|
||||||
|
></Upload>
|
||||||
|
<Button onClick={onSubmit}>Submit</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function BugReport() {
|
export default function BugReport() {
|
||||||
const [theme, setTheme] = useState("");
|
const [theme, setTheme] = useState("");
|
||||||
@ -159,21 +196,9 @@ export default function BugReport() {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<div className="p-5 mt-6 card-theme rounded-md">
|
<LexicalComposer initialConfig={editorConfig}>
|
||||||
<Input placeholder="Title" />
|
<Form theme={theme} />
|
||||||
<RichEditor theme={theme} />
|
</LexicalComposer>
|
||||||
<Upload
|
|
||||||
action="#"
|
|
||||||
beforeUpload={({ file, fileList }) => {}}
|
|
||||||
draggable={true}
|
|
||||||
dragMainText="Click to upload the file or drag and drop the file here"
|
|
||||||
dragSubText="Support json"
|
|
||||||
accept="application/json,.ddb"
|
|
||||||
onRemove={() => {}}
|
|
||||||
onFileChange={() => {}}
|
|
||||||
limit={5}
|
|
||||||
></Upload>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr
|
<hr
|
||||||
|
Loading…
Reference in New Issue
Block a user