refactor: extract jinja render's form
This commit is contained in:
@@ -16,6 +16,7 @@ import InitialValuePlugin from './plugin/InitialValuePlugin';
|
||||
import CommandPlugin from './plugin/CommandPlugin';
|
||||
import Jinja2HighlightPlugin from './plugin/Jinja2HighlightPlugin';
|
||||
import LineNumberPlugin from './plugin/LineNumberPlugin';
|
||||
import BlurPlugin from './plugin/BlurPlugin';
|
||||
import { VariableNode } from './nodes/VariableNode'
|
||||
|
||||
interface LexicalEditorProps {
|
||||
@@ -113,8 +114,10 @@ const Editor: FC<LexicalEditorProps> =({
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.editor-content-with-numbers {
|
||||
.editor-content-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
.editor-content-with-numbers {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.editor-content-with-numbers p {
|
||||
@@ -174,18 +177,20 @@ const Editor: FC<LexicalEditorProps> =({
|
||||
<div className="line-numbers">
|
||||
<div>1</div>
|
||||
</div>
|
||||
<ContentEditable
|
||||
className="editor-content-with-numbers"
|
||||
style={{
|
||||
minHeight: minheight,
|
||||
padding: '4px 0',
|
||||
outline: 'none',
|
||||
resize: 'none',
|
||||
fontSize: fontSize,
|
||||
lineHeight: lineHeight,
|
||||
border: 'none',
|
||||
}}
|
||||
/>
|
||||
<div className="editor-content-wrapper">
|
||||
<ContentEditable
|
||||
className="editor-content-with-numbers"
|
||||
style={{
|
||||
minHeight: minheight,
|
||||
padding: '4px 0',
|
||||
outline: 'none',
|
||||
resize: 'none',
|
||||
fontSize: fontSize,
|
||||
lineHeight: lineHeight,
|
||||
border: 'none',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<ContentEditable
|
||||
@@ -207,8 +212,8 @@ const Editor: FC<LexicalEditorProps> =({
|
||||
style={{
|
||||
minHeight: placeHolderMinheight,
|
||||
position: 'absolute',
|
||||
top: variant === 'borderless' ? '0' : '6px',
|
||||
left: enableJinja2 ? '59px' : (variant === 'borderless' ? '0' : '11px'),
|
||||
top: enableJinja2 ? '4px' : variant === 'borderless' ? '0' : '6px',
|
||||
left: enableJinja2 ? '16px' : (variant === 'borderless' ? '0' : '11px'),
|
||||
color: '#A8A9AA',
|
||||
fontSize: fontSize,
|
||||
lineHeight: placeHolderMinheight,
|
||||
@@ -227,6 +232,7 @@ const Editor: FC<LexicalEditorProps> =({
|
||||
<AutocompletePlugin options={options} enableJinja2={enableJinja2} />
|
||||
<CharacterCountPlugin setCount={(count) => { setCount(count) }} onChange={onChange} />
|
||||
<InitialValuePlugin value={value} options={options} enableJinja2={enableJinja2} />
|
||||
{enableJinja2 && <BlurPlugin />}
|
||||
</div>
|
||||
</LexicalComposer>
|
||||
);
|
||||
|
||||
@@ -36,7 +36,7 @@ const VariableComponent: React.FC<{ nodeKey: NodeKey; data: Suggestion }> = ({
|
||||
return (
|
||||
<span
|
||||
onClick={handleClick}
|
||||
className={clsx('rb:border rb:rounded-md rb:bg-white rb:text-[12px] rb:inline-flex rb:items-center rb:py-0.5 rb:px-1.5 rb:mx-0.5 rb:cursor-pointer', {
|
||||
className={clsx('rb:border rb:rounded-md rb:bg-white rb:text-[10px] rb:inline-flex rb:items-center rb:py-0 rb:px-1.5 rb:mx-0.5 rb:cursor-pointer', {
|
||||
'rb:border-[#155EEF]': isSelected,
|
||||
'rb:border-[#DFE4ED]': !isSelected
|
||||
})}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState, type FC } from 'react';
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
import { $getSelection, $isRangeSelection } from 'lexical';
|
||||
import { $getSelection, $isRangeSelection, $isTextNode } from 'lexical';
|
||||
|
||||
import { INSERT_VARIABLE_COMMAND } from '../commands';
|
||||
import type { NodeProperties } from '../../../types'
|
||||
@@ -96,7 +96,9 @@ const AutocompletePlugin: FC<{ options: Suggestion[], enableJinja2?: boolean }>
|
||||
const textAfter = nodeText.substring(anchorOffset);
|
||||
const newText = textBefore + `{{${suggestion.value}}}` + textAfter;
|
||||
|
||||
anchorNode.setTextContent(newText);
|
||||
if ($isTextNode(anchorNode)) {
|
||||
anchorNode.setTextContent(newText);
|
||||
}
|
||||
|
||||
// 设置光标位置到插入文本之后
|
||||
const newOffset = textBefore.length + `{{${suggestion.value}}}`.length;
|
||||
@@ -129,6 +131,8 @@ const AutocompletePlugin: FC<{ options: Suggestion[], enableJinja2?: boolean }>
|
||||
}
|
||||
return (
|
||||
<div
|
||||
data-autocomplete-popup="true"
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
style={{
|
||||
position: 'fixed',
|
||||
top: popupPosition.top,
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
import { useEffect } from 'react';
|
||||
import { $setSelection } from 'lexical';
|
||||
|
||||
export default function BlurPlugin() {
|
||||
const [editor] = useLexicalComposerContext();
|
||||
|
||||
useEffect(() => {
|
||||
return editor.registerRootListener((rootElement) => {
|
||||
if (rootElement) {
|
||||
const handleBlur = (e: FocusEvent) => {
|
||||
// 检查是否点击了自动完成弹窗
|
||||
const target = e.target as HTMLElement;
|
||||
console.log('target', target)
|
||||
if (target?.closest('[data-autocomplete-popup="true"]')) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.update(() => {
|
||||
$setSelection(null);
|
||||
});
|
||||
};
|
||||
|
||||
rootElement.addEventListener('blur', handleBlur);
|
||||
return () => {
|
||||
rootElement.removeEventListener('blur', handleBlur);
|
||||
};
|
||||
}
|
||||
});
|
||||
}, [editor]);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user