fix: issue with markdown(Vditor) (#5176)

* fix: markdown(Vditor)

* fix: bug

* fix: bug

* fix: bug
This commit is contained in:
Katherine 2024-09-04 10:32:40 +08:00 committed by GitHub
parent 703350884d
commit b8acdc1477
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 43 deletions

View File

@ -2,9 +2,7 @@
"version": "1.3.14-beta", "version": "1.3.14-beta",
"npmClient": "yarn", "npmClient": "yarn",
"useWorkspaces": true, "useWorkspaces": true,
"npmClientArgs": [ "npmClientArgs": ["--ignore-engines"],
"--ignore-engines"
],
"command": { "command": {
"version": { "version": {
"forcePublish": true, "forcePublish": true,

View File

@ -35,13 +35,12 @@ const getContentWidth = (element) => {
}; };
function DisplayInner(props: { value: string; style?: CSSProperties }) { function DisplayInner(props: { value: string; style?: CSSProperties }) {
const containerRef = useRef<HTMLDivElement>(); const containerRef = useRef<HTMLDivElement>(null);
const { wrapSSR, componentCls, hashId } = useStyle(); const { wrapSSR, componentCls, hashId } = useStyle();
const cdn = useCDN(); const cdn = useCDN();
useEffect(() => { useEffect(() => {
if (!props.value) return; Vditor.preview(containerRef.current, props.value ?? '', {
Vditor.preview(containerRef.current, props.value, {
mode: 'light', mode: 'light',
cdn, cdn,
}); });
@ -67,7 +66,6 @@ export const Display = withDynamicSchemaProps((props) => {
const [text, setText] = useState(''); const [text, setText] = useState('');
const elRef = useRef<HTMLDivElement>(); const elRef = useRef<HTMLDivElement>();
useEffect(() => { useEffect(() => {
if (!props.value || !field.value) return; if (!props.value || !field.value) return;
if (props.ellipsis) { if (props.ellipsis) {
@ -125,6 +123,5 @@ export const Display = withDynamicSchemaProps((props) => {
</Popover> </Popover>
); );
} }
return <DisplayInner value={value} />; return <DisplayInner value={value} />;
}); });

View File

@ -8,7 +8,7 @@
*/ */
import { useAPIClient, useApp, withDynamicSchemaProps } from '@nocobase/client'; import { useAPIClient, useApp, withDynamicSchemaProps } from '@nocobase/client';
import React, { useEffect, useLayoutEffect, useMemo, useRef } from 'react'; import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import Vditor from 'vditor'; import Vditor from 'vditor';
import { defaultToolbar } from '../interfaces/markdown-vditor'; import { defaultToolbar } from '../interfaces/markdown-vditor';
import { useCDN } from './const'; import { useCDN } from './const';
@ -19,10 +19,11 @@ const locales = ['en_US', 'fr_FR', 'pt_BR', 'ja_JP', 'ko_KR', 'ru_RU', 'sv_SE',
export const Edit = withDynamicSchemaProps((props) => { export const Edit = withDynamicSchemaProps((props) => {
const { disabled, onChange, value, fileCollection, toolbar } = props; const { disabled, onChange, value, fileCollection, toolbar } = props;
const [editorReady, setEditorReady] = useState(false);
const vdRef = useRef<Vditor>(); const vdRef = useRef<Vditor>();
const vdFullscreen = useRef(false); const vdFullscreen = useRef(false);
const containerRef = useRef<HTMLDivElement>(); const containerRef = useRef<HTMLDivElement>(null);
const containerParentRef = useRef<HTMLDivElement>(); const containerParentRef = useRef<HTMLDivElement>(null);
const app = useApp(); const app = useApp();
const apiClient = useAPIClient(); const apiClient = useAPIClient();
const cdn = useCDN(); const cdn = useCDN();
@ -38,28 +39,24 @@ export const Edit = withDynamicSchemaProps((props) => {
}, [locale]); }, [locale]);
useEffect(() => { useEffect(() => {
if (!containerRef.current) return;
const uploadFileCollection = fileCollection || 'attachments'; const uploadFileCollection = fileCollection || 'attachments';
const toolbarConfig = toolbar ?? defaultToolbar; const toolbarConfig = toolbar ?? defaultToolbar;
const vditor = new Vditor(containerRef.current, { const vditor = new Vditor(containerRef.current, {
value: value ?? '', value: value ?? '',
lang, lang,
cache: { cache: { enable: false },
enable: false,
},
undoDelay: 0, undoDelay: 0,
preview: { preview: { math: { engine: 'KaTeX' } },
math: {
engine: 'KaTeX',
},
},
toolbar: toolbarConfig, toolbar: toolbarConfig,
fullscreen: { fullscreen: { index: 1200 },
index: 1200,
},
cdn, cdn,
minHeight: 200, minHeight: 200,
after: () => { after: () => {
vdRef.current = vditor; vdRef.current = vditor;
setEditorReady(true); // Notify that the editor is ready
vditor.setValue(value ?? ''); vditor.setValue(value ?? '');
if (disabled) { if (disabled) {
vditor.disabled(); vditor.disabled();
@ -92,6 +89,7 @@ export const Edit = withDynamicSchemaProps((props) => {
}, },
}, },
}); });
return () => { return () => {
vdRef.current?.destroy(); vdRef.current?.destroy();
vdRef.current = undefined; vdRef.current = undefined;
@ -99,34 +97,42 @@ export const Edit = withDynamicSchemaProps((props) => {
}, [fileCollection, toolbar?.join(',')]); }, [fileCollection, toolbar?.join(',')]);
useEffect(() => { useEffect(() => {
if (value === vdRef?.current?.getValue()) { if (editorReady && vdRef.current) {
return; const editor = vdRef.current;
} if (value !== editor.getValue()) {
vdRef.current?.setValue(value); editor.setValue(value ?? '');
vdRef.current?.focus(); // editor.focus();
// 移动光标到末尾
const preArea = containerRef.current.querySelector('div.vditor-content > div.vditor-ir > pre') as HTMLPreElement; const preArea = containerRef.current?.querySelector(
if (preArea) { 'div.vditor-content > div.vditor-ir > pre',
const range = document.createRange(); ) as HTMLPreElement;
const selection = window.getSelection(); if (preArea) {
if (selection) { const range = document.createRange();
range.selectNodeContents(preArea); const selection = window.getSelection();
range.collapse(false); // 将光标移动到内容末尾 if (selection) {
selection.removeAllRanges(); range.selectNodeContents(preArea);
selection.addRange(range); range.collapse(false); // Move cursor to the end
selection.removeAllRanges();
selection.addRange(range);
}
}
} }
} }
}, [value]); }, [value, editorReady]);
useEffect(() => { useEffect(() => {
if (disabled) { if (editorReady && vdRef.current) {
vdRef.current?.disabled(); if (disabled) {
} else { vdRef.current.disabled();
vdRef.current?.enable(); } else {
vdRef.current.enable();
}
} }
}, [disabled]); }, [disabled, editorReady]);
useLayoutEffect(() => { useLayoutEffect(() => {
if (!containerRef.current) return;
const observer = new ResizeObserver((entries) => { const observer = new ResizeObserver((entries) => {
for (const entry of entries) { for (const entry of entries) {
const target = entry.target; const target = entry.target;