mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-27 08:25:07 +00:00
fix: editor focus & picker highlight & ui (#2166)
* fix ui * fix editor focus & picker highlight
This commit is contained in:
@@ -86,7 +86,7 @@ export default function Editor({
|
|||||||
useDeepCompareEffect(() => {
|
useDeepCompareEffect(() => {
|
||||||
if (focus) return;
|
if (focus) return;
|
||||||
setKey(getNanoid(6));
|
setKey(getNanoid(6));
|
||||||
}, [value, variables]);
|
}, [value, variables, variableLabels]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box position={'relative'} width={'full'} h={`${height}px`} cursor={'text'}>
|
<Box position={'relative'} width={'full'} h={`${height}px`} cursor={'text'}>
|
||||||
|
@@ -2,7 +2,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
|
|||||||
import { LexicalTypeaheadMenuPlugin } from '@lexical/react/LexicalTypeaheadMenuPlugin';
|
import { LexicalTypeaheadMenuPlugin } from '@lexical/react/LexicalTypeaheadMenuPlugin';
|
||||||
import { $createTextNode, $getSelection, $isRangeSelection, TextNode } from 'lexical';
|
import { $createTextNode, $getSelection, $isRangeSelection, TextNode } from 'lexical';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState, useEffect, useRef } from 'react';
|
||||||
import * as ReactDOM from 'react-dom';
|
import * as ReactDOM from 'react-dom';
|
||||||
import { Box, Flex } from '@chakra-ui/react';
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
import { useBasicTypeaheadTriggerMatch } from '../../utils';
|
import { useBasicTypeaheadTriggerMatch } from '../../utils';
|
||||||
@@ -37,8 +37,7 @@ export default function VariableLabelPickerPlugin({
|
|||||||
const [editor] = useLexicalComposerContext();
|
const [editor] = useLexicalComposerContext();
|
||||||
const [queryString, setQueryString] = useState<string | null>(null);
|
const [queryString, setQueryString] = useState<string | null>(null);
|
||||||
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
||||||
const [highlightIndex, setHighlightIndex] = useState<number | null>(null);
|
const highlightedItemRef = useRef<any>(null);
|
||||||
const highlightedItemRef = React.useRef<any>(null);
|
|
||||||
|
|
||||||
const checkForTriggerMatch = useBasicTypeaheadTriggerMatch('/', {
|
const checkForTriggerMatch = useBasicTypeaheadTriggerMatch('/', {
|
||||||
minLength: 0
|
minLength: 0
|
||||||
@@ -63,7 +62,7 @@ export default function VariableLabelPickerPlugin({
|
|||||||
[editor]
|
[editor]
|
||||||
);
|
);
|
||||||
|
|
||||||
React.useEffect(() => {
|
useEffect(() => {
|
||||||
if (highlightedItemRef.current) {
|
if (highlightedItemRef.current) {
|
||||||
highlightedItemRef.current.scrollIntoView({
|
highlightedItemRef.current.scrollIntoView({
|
||||||
behavior: 'auto',
|
behavior: 'auto',
|
||||||
@@ -87,7 +86,6 @@ export default function VariableLabelPickerPlugin({
|
|||||||
}
|
}
|
||||||
if (currentIndex !== selectedIndex) {
|
if (currentIndex !== selectedIndex) {
|
||||||
setCurrentIndex(selectedIndex || 0);
|
setCurrentIndex(selectedIndex || 0);
|
||||||
setHighlightIndex(selectedIndex || 0);
|
|
||||||
}
|
}
|
||||||
return anchorElementRef.current && variables.length && isFocus
|
return anchorElementRef.current && variables.length && isFocus
|
||||||
? ReactDOM.createPortal(
|
? ReactDOM.createPortal(
|
||||||
@@ -95,7 +93,7 @@ export default function VariableLabelPickerPlugin({
|
|||||||
bg={'white'}
|
bg={'white'}
|
||||||
boxShadow={'lg'}
|
boxShadow={'lg'}
|
||||||
border={'base'}
|
border={'base'}
|
||||||
p={2}
|
p={1.5}
|
||||||
borderRadius={'md'}
|
borderRadius={'md'}
|
||||||
position={'absolute'}
|
position={'absolute'}
|
||||||
w={'auto'}
|
w={'auto'}
|
||||||
@@ -105,9 +103,7 @@ export default function VariableLabelPickerPlugin({
|
|||||||
zIndex={99999}
|
zIndex={99999}
|
||||||
>
|
>
|
||||||
{variableFilter(variables, queryString || '').length === variables.length && (
|
{variableFilter(variables, queryString || '').length === variables.length && (
|
||||||
<Box fontSize={'xs'} ml={4}>
|
<Box fontSize={'xs'}>{t('workflow:variable_picker_tips')}</Box>
|
||||||
{t('workflow:variable_picker_tips')}
|
|
||||||
</Box>
|
|
||||||
)}
|
)}
|
||||||
{variableFilter(variables, queryString || '').length > 0 ? (
|
{variableFilter(variables, queryString || '').length > 0 ? (
|
||||||
transformVariables(variableFilter(variables, queryString || '')).map((item) => {
|
transformVariables(variableFilter(variables, queryString || '')).map((item) => {
|
||||||
@@ -115,8 +111,7 @@ export default function VariableLabelPickerPlugin({
|
|||||||
<Flex
|
<Flex
|
||||||
key={item.id}
|
key={item.id}
|
||||||
flexDirection={'column'}
|
flexDirection={'column'}
|
||||||
px={4}
|
pt={2}
|
||||||
py={2}
|
|
||||||
_notLast={{
|
_notLast={{
|
||||||
borderBottom: '1px solid',
|
borderBottom: '1px solid',
|
||||||
borderColor: 'myGray.200'
|
borderColor: 'myGray.200'
|
||||||
@@ -145,16 +140,16 @@ export default function VariableLabelPickerPlugin({
|
|||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
as={'li'}
|
as={'li'}
|
||||||
key={child.key}
|
key={child.key}
|
||||||
px={4}
|
px={2}
|
||||||
py={1.5}
|
py={1}
|
||||||
rounded={'md'}
|
rounded={'4px'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
overflow={'auto'}
|
overflow={'auto'}
|
||||||
_notLast={{
|
_notLast={{
|
||||||
mb: 1
|
mb: 1
|
||||||
}}
|
}}
|
||||||
ref={selectedIndex === child.index ? highlightedItemRef : null}
|
ref={selectedIndex === child.index ? highlightedItemRef : null}
|
||||||
{...(highlightIndex === child.index
|
{...(selectedIndex === child.index
|
||||||
? {
|
? {
|
||||||
bg: '#1118240D',
|
bg: '#1118240D',
|
||||||
color: 'primary.700'
|
color: 'primary.700'
|
||||||
@@ -163,12 +158,13 @@ export default function VariableLabelPickerPlugin({
|
|||||||
bg: 'white',
|
bg: 'white',
|
||||||
color: 'myGray.600'
|
color: 'myGray.600'
|
||||||
})}
|
})}
|
||||||
|
_hover={{
|
||||||
|
bg: '#1118240D',
|
||||||
|
color: 'primary.700'
|
||||||
|
}}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
selectOptionAndCleanUp({ ...child, parent: item });
|
selectOptionAndCleanUp({ ...child, parent: item });
|
||||||
}}
|
}}
|
||||||
onMouseEnter={() => {
|
|
||||||
setHighlightIndex(child.index);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Box ml={2} fontSize={'sm'} whiteSpace={'nowrap'}>
|
<Box ml={2} fontSize={'sm'} whiteSpace={'nowrap'}>
|
||||||
{child.label}
|
{child.label}
|
||||||
|
@@ -20,18 +20,15 @@ export default function VariableLabelPlugin({
|
|||||||
throw new Error('VariableLabelPlugin: VariableLabelPlugin not registered on editor');
|
throw new Error('VariableLabelPlugin: VariableLabelPlugin not registered on editor');
|
||||||
}, [editor]);
|
}, [editor]);
|
||||||
|
|
||||||
const createVariableLabelPlugin = useCallback(
|
const createVariableLabelPlugin = useCallback((textNode: TextNode): VariableLabelNode => {
|
||||||
(textNode: TextNode): VariableLabelNode => {
|
|
||||||
const [parentKey, childrenKey] = textNode.getTextContent().slice(3, -3).split('.');
|
const [parentKey, childrenKey] = textNode.getTextContent().slice(3, -3).split('.');
|
||||||
const currentVariable = variables.find(
|
const currentVariable = variables.find(
|
||||||
(item) => item.parent?.id === parentKey && item.key === childrenKey
|
(item) => item.parent.id === parentKey && item.key === childrenKey
|
||||||
);
|
);
|
||||||
const variableLabel = `${currentVariable && currentVariable.parent?.label}.${currentVariable?.label}`;
|
const variableLabel = `${currentVariable && currentVariable.parent?.label}.${currentVariable?.label}`;
|
||||||
const nodeAvatar = currentVariable?.parent?.avatar || '';
|
const nodeAvatar = currentVariable?.parent?.avatar || '';
|
||||||
return $createVariableLabelNode(textNode.getTextContent(), variableLabel, nodeAvatar);
|
return $createVariableLabelNode(textNode.getTextContent(), variableLabel, nodeAvatar);
|
||||||
},
|
}, []);
|
||||||
[variables]
|
|
||||||
);
|
|
||||||
|
|
||||||
const getVariableMatch = useCallback((text: string) => {
|
const getVariableMatch = useCallback((text: string) => {
|
||||||
const matches = REGEX.exec(text);
|
const matches = REGEX.exec(text);
|
||||||
@@ -55,7 +52,7 @@ export default function VariableLabelPlugin({
|
|||||||
createVariableLabelPlugin
|
createVariableLabelPlugin
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}, [createVariableLabelPlugin, editor, getVariableMatch, variables]);
|
}, [createVariableLabelPlugin, editor, getVariableMatch]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user