Skip to content

Commit

Permalink
feat: 增加html生成处理
Browse files Browse the repository at this point in the history
  • Loading branch information
LsyWeb committed Dec 27, 2024
1 parent 80db021 commit 12b08c9
Show file tree
Hide file tree
Showing 39 changed files with 1,756 additions and 333 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@
"@udecode/plate-heading": "^40.2.6",
"@udecode/plate-highlight": "^40.0.0",
"@udecode/plate-horizontal-rule": "^40.0.0",
"@udecode/plate-html": "^40.0.0",
"@udecode/plate-indent": "^40.0.0",
"@udecode/plate-indent-list": "^40.0.0",
"@udecode/plate-juice": "^40.0.0",
"@udecode/plate-kbd": "^40.0.0",
"@udecode/plate-layout": "^40.0.0",
"@udecode/plate-line-height": "^40.0.0",
"@udecode/plate-link": "^40.0.0",
"@udecode/plate-list": "^40.0.0",
"@udecode/plate-markdown": "40.2.2",
"@udecode/plate-math": "^40.0.0",
"@udecode/plate-media": "40.2.7",
Expand Down
30 changes: 30 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/app/editor/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { PlateEditor } from '@/components/editor/plate-editor';
import { SettingsProvider } from '@/components/editor/settings';

export default function Page() {
const isFullScreen = true;
const isFullScreen = false;
const AreaClass =
'w-[800px] h-[800px] mt-[100px] m-auto border-[#eee] border-solid border rounded-md';
'w-[800px] h-[800px] mt-[100px] border-[#eee] border-solid border rounded-md';
return (
<div
className={
Expand Down
1 change: 1 addition & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@ body {
@apply bg-background text-foreground;
}
}

14 changes: 14 additions & 0 deletions src/components/common/divider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
type DividerProps = {
direction?: 'horizontal' | 'vertical';
} & React.HTMLAttributes<HTMLDivElement>;

const Divider = ({ direction = 'horizontal', ...props }: DividerProps) => {
if (direction === 'vertical') {
return (
<div className="w-[1px] h-auto bg-border mx-1 my-1" {...props}></div>
);
}
return <div className="w-auto h-[1px] bg-border mx-1 my-1" {...props}></div>;
};

export default Divider;
208 changes: 179 additions & 29 deletions src/components/editor/plate-editor.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import React from 'react';
import React, { useRef } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

Expand All @@ -10,38 +10,188 @@ import { useCreateEditor } from '@/components/editor/use-create-editor';
import { SettingsDialog } from '@/components/editor/settings';
import { Editor, EditorContainer } from '@/components/plate-ui/editor';
import { slateToHtml, slateToHtmlConfig } from '@slate-serializers/html';
import {Element} from 'domhandler'
import { Element, Text } from 'domhandler';
import { toggleElementTransform } from '@/utils/transform-html/toggle-transform';
import { pElementTransform } from '@/utils/transform-html/p-transform';
import { videoElementTramsform } from '@/utils/transform-html/video-transform';
import { imageElementTramsform } from '@/utils/transform-html/image-transform';
import { audioElementTramsform } from '@/utils/transform-html/audio-transform';
import { fileElementTramsform } from '@/utils/transform-html/file-transform';
import {
columnElementTransform,
columnGroupElementTransform,
} from '@/utils/transform-html/column-transform';
import { dateElementTransform } from '@/utils/transform-html/date-transform';
import {
tableCellElementTransform,
tableElementTransform,
tableHeaderCellElementTransform,
tableRowElementTransform,
} from '@/utils/transform-html/table-transform';
import { hrElementTransform } from '@/utils/transform-html/hr-transform';
import {
codeBlockElementTransform,
codeLineElementTransform,
} from '@/utils/transform-html/code-block.transform';
export function PlateEditor() {
const editor = useCreateEditor();
// const getHtml = () => {
// console.log(editor.children[0].children);
// const nodes = editor.children;
// const html = editor.api.htmlReact.serialize({
// nodes: nodes,
// plateProps: { readOnly: true },
// // if you use @udecode/plate-dnd
// dndWrapper: (props) => <DndProvider backend={HTML5Backend} {...props} />,
// });
// console.log(html);
// };

return (
<DndProvider backend={HTML5Backend}>
<Plate
editor={editor}
onChange={({ editor, value }) => {
console.log(editor, value);
const html = slateToHtml(value, {
...slateToHtmlConfig,
elementTransforms: {
...slateToHtmlConfig.elementTransforms,
img: ({ node }) => {
console.log(node);
const src = node.url;
return new Element('img', {
src: src,
}, []);
},
},
const htmlRef = useRef<any>();

const getHtml = () => {
const nodes = editor.children;
const html = slateToHtml(nodes, {
...slateToHtmlConfig,
markTransforms: {
...slateToHtmlConfig.markTransforms,
code: () => {
return new Element('code', {
class:
'whitespace-pre-wrap rounded-md bg-muted px-[0.3em] py-[0.2em] font-mono text-sm m-0.5 slate-code',
});
console.log(html);
}}
>
<EditorContainer>
<Editor variant="default" />
</EditorContainer>
},
kbd: () => {
return new Element('kbd', {
class:
'rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-sm slate-kbd',
});
},
superscript: () => {
return new Element('sup', {
class: 'slate-sup',
});
},
subscript: () => {
return new Element('sub', {
class: 'slate-sub',
});
},
color: ({ node }) => {
return new Element('span', {
style: `color: ${node.color}`,
});
},
backgroundColor: ({ node }) => {
return new Element('span', {
style: `background-color: ${node.backgroundColor}`,
});
},
highlight: () => {
return new Element('mark', {
class: 'bg-highlight/30 text-inherit slate-highlight',
});
},
text: ({ node, attribs }) => {
return new Element(
'span',
{
class: 'slate-text',
},
[new Text(node.text)]
);
},
},
elementTransforms: {
...slateToHtmlConfig.elementTransforms,
a: ({ node, children }) => {
return new Element(
'a',
{
class: 'slate-a underline cursor-pointer',
src: node.url,
},
children
);
},
h1: ({ children }) => {
return new Element(
'h1',
{
class:
'relative mb-1 mt-[1.6em] pb-1 font-heading text-4xl font-bold slate-h1 slate-h1',
},
children
);
},
h2: ({ children }) => {
return new Element(
'h2',
{
class:
'relative mb-1 mt-[1.4em] pb-1 font-heading text-3xl font-bold slate-h2',
},
children
);
},
h3: ({ children }) => {
return new Element(
'h3',
{
class:
'relative mb-1 mt-[1.2em] pb-1 font-heading text-2xl font-bold slate-h3',
},
children
);
},
code_block: codeBlockElementTransform,
code_line: codeLineElementTransform,
hr: hrElementTransform,
img: imageElementTramsform,
video: videoElementTramsform,
audio: audioElementTramsform,
file: fileElementTramsform,
column_group: columnGroupElementTransform,
column: columnElementTransform,
date: dateElementTransform,
p: pElementTransform,
toggle: toggleElementTransform,
table: tableElementTransform,
tr: tableRowElementTransform,
td: tableCellElementTransform,
th: tableHeaderCellElementTransform,
},
});
console.log(html);
htmlRef.current!.innerHTML = html;
};
return (
<>
<DndProvider backend={HTML5Backend}>
<Plate
editor={editor}
onChange={({ editor, value }) => {
console.log(value);
getHtml();
}}
>
<EditorContainer>
<Editor variant="default" />
</EditorContainer>

<SettingsDialog />
</Plate>
</DndProvider>
<SettingsDialog />
</Plate>
</DndProvider>
{/* <button
className="fixed right-40 top-40 p-4 rounded-full border"
onClick={getHtml}
>
Get HTML
</button> */}
<div
ref={htmlRef}
className="border rounded fixed right-0 max-w-[700px] h-[800px] overflow-auto top-[100px] p-4 bg-white"
></div>
</>
);
}
6 changes: 5 additions & 1 deletion src/components/editor/plugins/editor-plugins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ export const editorPlugins = [

// Deserialization
DocxPlugin,
MarkdownPlugin.configure({ options: { indentList: true } }),
MarkdownPlugin.configure({
options: {
indentList: true
},
}),
JuicePlugin,

// UI
Expand Down
2 changes: 2 additions & 0 deletions src/components/editor/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
} from '@udecode/plate-media/react';
import { TablePlugin, insertTable } from '@udecode/plate-table/react';
import { Path } from 'slate';
import { ListPlugin } from '@udecode/plate-list/react';

const ACTION_THREE_COLUMNS = 'action_three_columns';

Expand Down Expand Up @@ -167,6 +168,7 @@ export const setBlockType = (
if (node[IndentListPlugin.key]) {
unsetNodes(editor, [IndentListPlugin.key, 'indent'], { at: path });
}

if (type in setBlockMap) {
return setBlockMap[type](editor, type, entry);
}
Expand Down
Loading

0 comments on commit 12b08c9

Please sign in to comment.