diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/components/MentionsList/MentionsList.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/components/MentionsList/MentionsList.tsx index 69353e412261..341b114426c5 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/components/MentionsList/MentionsList.tsx +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/components/MentionsList/MentionsList.tsx @@ -1,11 +1,13 @@ import { SuggestionKeyDownProps } from "@tiptap/suggestion"; import { forwardRef } from "react"; +import { FaAngleDoubleDown } from "react-icons/fa"; import { AddBrainModal } from "@/lib/components/AddBrainModal"; import { AddNewPromptButton } from "./components/AddNewPromptButton"; import { MentionItem } from "./components/MentionItem/MentionItem"; import { useMentionList } from "./hooks/useMentionList"; +import { useSuggestionsOverflowHandler } from "./hooks/useSuggestionsOverflowHandler"; import { MentionListProps } from "./types"; export type MentionListRef = { @@ -19,19 +21,36 @@ export const MentionList = forwardRef( ref, }); + const { suggestionsRef, shouldShowScrollToBottomIcon, scrollToBottom } = + useSuggestionsOverflowHandler(); + return ( -
- {props.suggestionData.items.map((item, index) => ( - selectItem(index)} - type={props.suggestionData.type} - /> - ))} - {isBrain && } - {isPrompt && } +
+
+ {props.suggestionData.items.map((item, index) => ( + selectItem(index)} + type={props.suggestionData.type} + /> + ))} +
+
+ {shouldShowScrollToBottomIcon && ( + + )} + {isBrain && } + {isPrompt && } +
); } diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/components/MentionsList/hooks/useSuggestionsOverflowHandler.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/components/MentionsList/hooks/useSuggestionsOverflowHandler.ts new file mode 100644 index 000000000000..25aacbe89032 --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/components/MentionsList/hooks/useSuggestionsOverflowHandler.ts @@ -0,0 +1,46 @@ +import { useEffect, useRef, useState } from "react"; + +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export const useSuggestionsOverflowHandler = () => { + const [shouldShowScrollToBottomIcon, setShouldShowScrollToBottomIcon] = + useState(false); + + const suggestionsRef = useRef(null); + + useEffect(() => { + const scrollContainer = suggestionsRef.current; + const handleScroll = () => { + if (scrollContainer === null) { + return; + } + const SCROLL_POSITION_NOISE = 10; + const asReachedBottom = + scrollContainer.scrollHeight - + scrollContainer.scrollTop - + SCROLL_POSITION_NOISE <= + scrollContainer.clientHeight; + + setShouldShowScrollToBottomIcon(!asReachedBottom); + }; + scrollContainer?.addEventListener("scroll", handleScroll); + + return () => { + scrollContainer?.removeEventListener("scroll", handleScroll); + }; + }, []); + + const scrollToBottom = () => { + if (suggestionsRef.current) { + suggestionsRef.current.scrollTo({ + top: suggestionsRef.current.scrollHeight, + behavior: "smooth", + }); + } + }; + + return { + shouldShowScrollToBottomIcon, + scrollToBottom, + suggestionsRef, + }; +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/hooks/useMentionConfig.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/hooks/useMentionConfig.ts index b86545ec1cd8..12f211035b64 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/hooks/useMentionConfig.ts +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/ChatInput/components/ChatEditor/components/Editor/hooks/useMentionConfig.ts @@ -17,8 +17,6 @@ type UseMentionConfigProps = { suggestionData: SuggestionData; }; -const MAX_ITEMS_DISPLAYED = 15; - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const useMentionConfig = ({ char, @@ -35,11 +33,9 @@ export const useMentionConfig = ({ allowSpaces: true, pluginKey: new PluginKey(mentionKey), items: ({ query }) => - items - .filter((item) => - item.label.toLowerCase().startsWith(query.toLowerCase()) - ) - .slice(0, MAX_ITEMS_DISPLAYED), + items.filter((item) => + item.label.toLowerCase().startsWith(query.toLowerCase()) + ), render: () => { let reactRenderer: | ReactRenderer<