diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx index 3e6be1abcf..3deeaa79ad 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx @@ -4,6 +4,12 @@ import { useState, } from 'react' import ReactDOM from 'react-dom' +import { + FloatingPortal, + flip, + shift, + useFloating, +} from '@floating-ui/react' import type { TextNode } from 'lexical' import type { MenuRenderFn } from '@lexical/react/LexicalTypeaheadMenuPlugin' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' @@ -47,6 +53,13 @@ const ComponentPicker = ({ workflowVariableBlock, }: ComponentPickerProps) => { const { eventEmitter } = useEventEmitterContextContext() + const { refs, floatingStyles, elements } = useFloating({ + placement: 'bottom-start', + middleware: [ + shift(), + flip(), + ], + }) const [editor] = useLexicalComposerContext() const checkForTriggerMatch = useBasicTypeaheadTriggerMatch(triggerString, { minLength: 0, @@ -113,106 +126,128 @@ const ComponentPicker = ({ { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }, ) => { if (anchorElementRef.current && (allOptions.length || workflowVariableOptions.length)) { - return ReactDOM.createPortal( -
+ return ( + <> { - !!promptOptions.length && ( - <> - { - if (option.disabled) - return - setHighlightedIndex(index) - selectOptionAndCleanUp(option) - }} - onMouseEnter={(index, option) => { - if (option.disabled) - return - setHighlightedIndex(index) - }} - /> - + ReactDOM.createPortal( +
, + anchorElementRef.current, ) } { - !!variableOptions.length && ( - <> - { - !!promptOptions.length && ( -
- ) - } - { - if (option.disabled) - return - setHighlightedIndex(index) - selectOptionAndCleanUp(option) + elements.reference && ( + +
{ - if (option.disabled) - return - setHighlightedIndex(index) - }} - queryString={queryString} - /> - + ref={refs.setFloating} + > + { + !!promptOptions.length && ( + <> + { + if (option.disabled) + return + setHighlightedIndex(index) + selectOptionAndCleanUp(option) + }} + onMouseEnter={(index, option) => { + if (option.disabled) + return + setHighlightedIndex(index) + }} + /> + + ) + } + { + !!variableOptions.length && ( + <> + { + !!promptOptions.length && ( +
+ ) + } + { + if (option.disabled) + return + setHighlightedIndex(index) + selectOptionAndCleanUp(option) + }} + onMouseEnter={(index, option) => { + if (option.disabled) + return + setHighlightedIndex(index) + }} + queryString={queryString} + /> + + ) + } + { + !!externalToolOptions.length && ( + <> + { + (!!promptOptions.length || !!variableOptions.length) && ( +
+ ) + } + { + if (option.disabled) + return + setHighlightedIndex(index) + selectOptionAndCleanUp(option) + }} + onMouseEnter={(index, option) => { + if (option.disabled) + return + setHighlightedIndex(index) + }} + queryString={queryString} + /> + + ) + } + { + !!workflowVariableOptions.length && ( + <> + { + (!!promptOptions.length || !!variableOptions.length || !!externalToolOptions.length) && ( +
+ ) + } +
+ { + handleSelectWorkflowVariable(variables) + }} + /> +
+ + ) + } +
+
) } - { - !!externalToolOptions.length && ( - <> - { - (!!promptOptions.length || !!variableOptions.length) && ( -
- ) - } - { - if (option.disabled) - return - setHighlightedIndex(index) - selectOptionAndCleanUp(option) - }} - onMouseEnter={(index, option) => { - if (option.disabled) - return - setHighlightedIndex(index) - }} - queryString={queryString} - /> - - ) - } - { - !!workflowVariableOptions.length && ( - <> - { - (!!promptOptions.length || !!variableOptions.length || !!externalToolOptions.length) && ( -
- ) - } - { - handleSelectWorkflowVariable(variables) - }} - /> - - ) - } -
, - anchorElementRef.current, + ) } @@ -225,6 +260,9 @@ const ComponentPicker = ({ workflowVariableOptions, queryString, handleSelectWorkflowVariable, + elements, + floatingStyles, + refs, ]) return ( diff --git a/web/app/components/workflow/nodes/_base/panel.tsx b/web/app/components/workflow/nodes/_base/panel.tsx index 84262a8c3b..f622d5a994 100644 --- a/web/app/components/workflow/nodes/_base/panel.tsx +++ b/web/app/components/workflow/nodes/_base/panel.tsx @@ -82,7 +82,9 @@ const BasePanel: FC = ({
+ className='absolute top-1/2 -translate-y-1/2 -left-2 w-3 h-6 cursor-col-resize resize-x'> +
+