mirror of https://github.com/fantasticit/think.git
feat: add defaultShowPicker for katex
parent
c9d4fd5127
commit
f89c1051db
|
@ -2,10 +2,15 @@ import { Node, mergeAttributes, nodeInputRule } from '@tiptap/core';
|
|||
import { ReactNodeViewRenderer } from '@tiptap/react';
|
||||
import { KatexWrapper } from '../wrappers/katex';
|
||||
|
||||
type IKatexAttrs = {
|
||||
text?: string;
|
||||
defaultShowPicker?: boolean;
|
||||
};
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
katex: {
|
||||
setKatex: () => ReturnType;
|
||||
setKatex: (arg?: IKatexAttrs) => ReturnType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +40,9 @@ export const Katex = Node.create({
|
|||
return element.getAttribute('data-text');
|
||||
},
|
||||
},
|
||||
defaultShowPicker: {
|
||||
default: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ export const Insert: React.FC<{ editor: Editor }> = ({ editor }) => {
|
|||
<IconMind /> 思维导图
|
||||
</Dropdown.Item>
|
||||
|
||||
<Dropdown.Item onClick={() => editor.chain().focus().setKatex().run()}>
|
||||
<Dropdown.Item onClick={() => editor.chain().focus().setKatex({ defaultShowPicker: true }).run()}>
|
||||
<IconMath /> 数学公式
|
||||
</Dropdown.Item>
|
||||
|
||||
|
|
|
@ -208,7 +208,14 @@ export const QUICK_INSERT_ITEMS = [
|
|||
数学公式
|
||||
</Space>
|
||||
),
|
||||
command: (editor: Editor) => editor.chain().focus().setKatex().run(),
|
||||
command: (editor: Editor) =>
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.setKatex({
|
||||
defaultShowPicker: true,
|
||||
})
|
||||
.run(),
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
.wrap {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
padding: 0 8px;
|
||||
transform: translateY(8px);
|
||||
transform: translateY(1px);
|
||||
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
height: 20px;
|
||||
padding: 2px 8px;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import { NodeViewWrapper, NodeViewContent } from '@tiptap/react';
|
||||
import { useMemo } from 'react';
|
||||
import { useMemo, useCallback, useEffect, useRef } from 'react';
|
||||
import cls from 'classnames';
|
||||
import { Popover, TextArea, Typography, Space } from '@douyinfe/semi-ui';
|
||||
import { IconHelpCircle } from '@douyinfe/semi-icons';
|
||||
import katex from 'katex';
|
||||
import { useToggle } from 'hooks/use-toggle';
|
||||
import styles from './index.module.scss';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
export const KatexWrapper = ({ editor, node, updateAttributes }) => {
|
||||
const isEditable = editor.isEditable;
|
||||
const { text } = node.attrs;
|
||||
const { text, defaultShowPicker } = node.attrs;
|
||||
const ref = useRef<HTMLTextAreaElement>();
|
||||
const [visible, toggleVisible] = useToggle(false);
|
||||
|
||||
const formatText = useMemo(() => {
|
||||
try {
|
||||
|
@ -20,22 +23,46 @@ export const KatexWrapper = ({ editor, node, updateAttributes }) => {
|
|||
}
|
||||
}, [text]);
|
||||
|
||||
const content = text.trim() ? (
|
||||
<span contentEditable={false} dangerouslySetInnerHTML={{ __html: formatText }}></span>
|
||||
) : (
|
||||
<span contentEditable={false}>点击输入公式</span>
|
||||
const content = useMemo(
|
||||
() =>
|
||||
text.trim() ? (
|
||||
<span contentEditable={false} dangerouslySetInnerHTML={{ __html: formatText }}></span>
|
||||
) : (
|
||||
<span contentEditable={false}>点击输入公式</span>
|
||||
),
|
||||
[text]
|
||||
);
|
||||
|
||||
const onVisibleChange = useCallback(
|
||||
(value) => {
|
||||
toggleVisible(value);
|
||||
if (defaultShowPicker) {
|
||||
updateAttributes({ defaultShowPicker: false });
|
||||
}
|
||||
},
|
||||
[defaultShowPicker, updateAttributes]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultShowPicker) {
|
||||
toggleVisible(true);
|
||||
setTimeout(() => ref.current?.focus(), 100);
|
||||
}
|
||||
}, [defaultShowPicker]);
|
||||
|
||||
return (
|
||||
<NodeViewWrapper as="span" className={cls(styles.wrap, 'render-wrapper')} contentEditable={false}>
|
||||
<NodeViewContent />
|
||||
{isEditable ? (
|
||||
<Popover
|
||||
showArrow
|
||||
position="bottomLeft"
|
||||
spacing={12}
|
||||
visible={visible}
|
||||
onVisibleChange={onVisibleChange}
|
||||
content={
|
||||
<div style={{ width: 320 }}>
|
||||
<TextArea
|
||||
ref={ref}
|
||||
autofocus
|
||||
placeholder="输入公式"
|
||||
autosize
|
||||
|
@ -59,7 +86,6 @@ export const KatexWrapper = ({ editor, node, updateAttributes }) => {
|
|||
) : (
|
||||
content
|
||||
)}
|
||||
<NodeViewContent />
|
||||
</NodeViewWrapper>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue