Feat: Add insert variable icon in the header of prompt editor. #4764 (#5142)

### What problem does this PR solve?

Feat: Add insert variable icon in the header of prompt editor. #4764

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-02-19 19:20:00 +08:00 committed by GitHub
parent c5b32b2211
commit c432ce6be5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 4 deletions

View File

@ -9,14 +9,19 @@ import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
import { HeadingNode, QuoteNode } from '@lexical/rich-text'; import { HeadingNode, QuoteNode } from '@lexical/rich-text';
import { import {
$getRoot, $getRoot,
$getSelection,
$nodesOfType, $nodesOfType,
EditorState, EditorState,
Klass, Klass,
LexicalNode, LexicalNode,
} from 'lexical'; } from 'lexical';
import { useCallback } from 'react'; import { cn } from '@/lib/utils';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { Variable } from 'lucide-react';
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
import theme from './theme'; import theme from './theme';
import { VariableNode } from './variable-node'; import { VariableNode } from './variable-node';
import { VariableOnChangePlugin } from './variable-on-change-plugin'; import { VariableOnChangePlugin } from './variable-on-change-plugin';
@ -42,6 +47,58 @@ type IProps = {
onChange?: (value?: string) => void; onChange?: (value?: string) => void;
}; };
function PromptContent() {
const [editor] = useLexicalComposerContext();
const [isBlur, setIsBlur] = useState(false);
const { t } = useTranslation();
const insertTextAtCursor = useCallback(() => {
editor.update(() => {
const selection = $getSelection();
if (selection !== null) {
selection.insertText(' /');
}
});
}, [editor]);
const handleVariableIconClick = useCallback(() => {
insertTextAtCursor();
}, [insertTextAtCursor]);
const handleBlur = useCallback(() => {
setIsBlur(true);
}, []);
const handleFocus = useCallback(() => {
setIsBlur(false);
}, []);
return (
<section
className={cn('border rounded-sm ', { 'border-blue-400': !isBlur })}
>
<div className="border-b px-2 py-2 justify-end flex">
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-block cursor-pointer cursor p-0.5 hover:bg-gray-100 dark:hover:bg-slate-800 rounded-sm">
<Variable size={16} onClick={handleVariableIconClick} />
</span>
</TooltipTrigger>
<TooltipContent>
<p>{t('flow.insertVariableTip')}</p>
</TooltipContent>
</Tooltip>
</div>
<ContentEditable
className="min-h-40 relative px-2 py-1 focus-visible:outline-none"
onBlur={handleBlur}
onFocus={handleFocus}
/>
</section>
);
}
export function PromptEditor({ value, onChange }: IProps) { export function PromptEditor({ value, onChange }: IProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const initialConfig: InitialConfigType = { const initialConfig: InitialConfigType = {
@ -69,9 +126,7 @@ export function PromptEditor({ value, onChange }: IProps) {
return ( return (
<LexicalComposer initialConfig={initialConfig}> <LexicalComposer initialConfig={initialConfig}>
<RichTextPlugin <RichTextPlugin
contentEditable={ contentEditable={<PromptContent></PromptContent>}
<ContentEditable className="min-h-40 relative px-2 py-1 border" />
}
placeholder={ placeholder={
<div className="absolute top-2 left-2">{t('common.pleaseInput')}</div> <div className="absolute top-2 left-2">{t('common.pleaseInput')}</div>
} }

View File

@ -1179,6 +1179,7 @@ This delimiter is used to split the input text into several text pieces echo of
addCategory: 'Add category', addCategory: 'Add category',
categoryName: 'Category name', categoryName: 'Category name',
nextStep: 'Next step', nextStep: 'Next step',
insertVariableTip: `Enter / Insert variables`,
}, },
footer: { footer: {
profile: 'All rights reserved @ React', profile: 'All rights reserved @ React',

View File

@ -1111,6 +1111,7 @@ export default {
addCategory: '新增分類', addCategory: '新增分類',
categoryName: '分類名稱', categoryName: '分類名稱',
nextStep: '下一步', nextStep: '下一步',
insertVariableTip: `輸入 / 插入變數`,
}, },
footer: { footer: {
profile: '“保留所有權利 @ react”', profile: '“保留所有權利 @ react”',

View File

@ -1152,6 +1152,7 @@ General实体和关系提取提示来自 GitHub - microsoft/graphrag基于
addCategory: '新增分类', addCategory: '新增分类',
categoryName: '分类名称', categoryName: '分类名称',
nextStep: '下一步', nextStep: '下一步',
insertVariableTip: `输入 / 插入变量`,
}, },
footer: { footer: {
profile: 'All rights reserved @ React', profile: 'All rights reserved @ React',