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 { ContentEditable } from "@lexical/react/LexicalContentEditable";
|
||||
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
|
||||
import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
|
||||
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 { ListPlugin } from "@lexical/react/LexicalListPlugin";
|
||||
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
|
||||
@ -19,119 +13,29 @@ import ListMaxIndentLevelPlugin from "../plugins/ListMaxIndentLevelPlugin";
|
||||
import CodeHighlightPlugin from "../plugins/CodeHighlightPlugin";
|
||||
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() {
|
||||
return <div className="editor-placeholder">Describe the bug</div>;
|
||||
}
|
||||
|
||||
const editorConfig = {
|
||||
theme: exampleTheme,
|
||||
onError(error) {
|
||||
throw error;
|
||||
},
|
||||
nodes: [
|
||||
HeadingNode,
|
||||
ListNode,
|
||||
ListItemNode,
|
||||
QuoteNode,
|
||||
CodeNode,
|
||||
CodeHighlightNode,
|
||||
TableNode,
|
||||
TableCellNode,
|
||||
TableRowNode,
|
||||
AutoLinkNode,
|
||||
LinkNode,
|
||||
],
|
||||
};
|
||||
|
||||
export default function RichEditor(props) {
|
||||
export default function RichEditor({ theme }) {
|
||||
return (
|
||||
<LexicalComposer initialConfig={editorConfig}>
|
||||
<div className="editor-container">
|
||||
<ToolbarPlugin theme={props.theme} />
|
||||
<div className="editor-inner">
|
||||
<RichTextPlugin
|
||||
contentEditable={<ContentEditable className="editor-input" />}
|
||||
placeholder={<Placeholder />}
|
||||
ErrorBoundary={LexicalErrorBoundary}
|
||||
/>
|
||||
<HistoryPlugin />
|
||||
<AutoFocusPlugin />
|
||||
<CodeHighlightPlugin />
|
||||
<ListPlugin />
|
||||
<LinkPlugin />
|
||||
<AutoLinkPlugin />
|
||||
<ListMaxIndentLevelPlugin maxDepth={7} />
|
||||
<MarkdownShortcutPlugin transformers={TRANSFORMERS} />
|
||||
</div>
|
||||
<div className="editor-container">
|
||||
<ToolbarPlugin theme={theme} />
|
||||
<div className="editor-inner">
|
||||
<RichTextPlugin
|
||||
contentEditable={<ContentEditable className="editor-input" />}
|
||||
placeholder={<Placeholder />}
|
||||
ErrorBoundary={LexicalErrorBoundary}
|
||||
/>
|
||||
<HistoryPlugin />
|
||||
<AutoFocusPlugin />
|
||||
<CodeHighlightPlugin />
|
||||
<ListPlugin />
|
||||
<LinkPlugin />
|
||||
<AutoLinkPlugin />
|
||||
<ListMaxIndentLevelPlugin maxDepth={7} />
|
||||
<MarkdownShortcutPlugin transformers={TRANSFORMERS} />
|
||||
</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_dark from "../assets/logo_dark_46.png";
|
||||
import { Banner, Button, Input, Upload } from "@douyinfe/semi-ui";
|
||||
@ -9,6 +9,43 @@ import {
|
||||
IconPaperclip,
|
||||
} from "@douyinfe/semi-icons";
|
||||
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() {
|
||||
const [theme, setTheme] = useState("");
|
||||
@ -159,21 +196,9 @@ export default function BugReport() {
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<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>
|
||||
</div>
|
||||
<LexicalComposer initialConfig={editorConfig}>
|
||||
<Form theme={theme} />
|
||||
</LexicalComposer>
|
||||
</div>
|
||||
</div>
|
||||
<hr
|
||||
|
Loading…
Reference in New Issue
Block a user