From 6826c0ed4308603a842ec589edc87b277d3c17fd Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 27 Apr 2025 15:13:19 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=99=8C=20a11y:=20Searchbar/Conversations?= =?UTF-8?q?=20List=20Focus=20(#7096)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: remove redundancy of useSetRecoilState and useRecoilValue with useRecoilState in SearchBar * refactor: remove unnecessary focus effect on text area in ChatForm * refactor: improve searchbar and clear search button accessibility * fix: add tabIndex to Conversations component for improved accessibility, moves focus directly conversation items * style: adjust margin in Header component for improved layout symmetry with Nav * chore: imports order --- client/src/components/Chat/Header.tsx | 2 +- client/src/components/Chat/Input/ChatForm.tsx | 6 ----- .../Conversations/Conversations.tsx | 1 + client/src/components/Nav/SearchBar.tsx | 24 ++++++++++++------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/client/src/components/Chat/Header.tsx b/client/src/components/Chat/Header.tsx index 4f491f4b0..0390eb428 100644 --- a/client/src/components/Chat/Header.tsx +++ b/client/src/components/Chat/Header.tsx @@ -36,7 +36,7 @@ export default function Header() { return (
-
+
{!navVisible && } {!navVisible && } {} diff --git a/client/src/components/Chat/Input/ChatForm.tsx b/client/src/components/Chat/Input/ChatForm.tsx index 3e4e4f698..7ac983099 100644 --- a/client/src/components/Chat/Input/ChatForm.tsx +++ b/client/src/components/Chat/Input/ChatForm.tsx @@ -151,12 +151,6 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => { const textValue = useWatch({ control: methods.control, name: 'text' }); - useEffect(() => { - if (!search.isSearching && textAreaRef.current && !disableInputs) { - textAreaRef.current.focus(); - } - }, [search.isSearching, disableInputs]); - useEffect(() => { if (textAreaRef.current) { const style = window.getComputedStyle(textAreaRef.current); diff --git a/client/src/components/Conversations/Conversations.tsx b/client/src/components/Conversations/Conversations.tsx index eea39eaed..a0bf03e49 100644 --- a/client/src/components/Conversations/Conversations.tsx +++ b/client/src/components/Conversations/Conversations.tsx @@ -220,6 +220,7 @@ const Conversations: FC = ({ role="list" aria-label="Conversations" onRowsRendered={handleRowsRendered} + tabIndex={-1} /> )} diff --git a/client/src/components/Nav/SearchBar.tsx b/client/src/components/Nav/SearchBar.tsx index 9e21b5266..9fc271577 100644 --- a/client/src/components/Nav/SearchBar.tsx +++ b/client/src/components/Nav/SearchBar.tsx @@ -1,7 +1,7 @@ -import { forwardRef, useState, useCallback, useMemo, useEffect, Ref } from 'react'; +import React, { forwardRef, useState, useCallback, useMemo, useEffect, useRef } from 'react'; import debounce from 'lodash/debounce'; +import { useRecoilState } from 'recoil'; import { Search, X } from 'lucide-react'; -import { useSetRecoilState, useRecoilValue } from 'recoil'; import { QueryKeys } from 'librechat-data-provider'; import { useQueryClient } from '@tanstack/react-query'; import { useLocation, useNavigate } from 'react-router-dom'; @@ -13,7 +13,7 @@ type SearchBarProps = { isSmallScreen?: boolean; }; -const SearchBar = forwardRef((props: SearchBarProps, ref: Ref) => { +const SearchBar = forwardRef((props: SearchBarProps, ref: React.Ref) => { const localize = useLocalize(); const location = useLocation(); const queryClient = useQueryClient(); @@ -21,11 +21,11 @@ const SearchBar = forwardRef((props: SearchBarProps, ref: Ref) = const { isSmallScreen } = props; const [text, setText] = useState(''); + const inputRef = useRef(null); const [showClearIcon, setShowClearIcon] = useState(false); const { newConversation } = useNewConvo(); - const setSearchState = useSetRecoilState(store.search); - const search = useRecoilValue(store.search); + const [search, setSearchState] = useRecoilState(store.search); const clearSearch = useCallback(() => { if (location.pathname.includes('/search')) { @@ -44,6 +44,7 @@ const SearchBar = forwardRef((props: SearchBarProps, ref: Ref) = isTyping: false, })); clearSearch(); + inputRef.current?.focus(); }, [setSearchState, clearSearch]); const handleKeyUp = (e: React.KeyboardEvent) => { @@ -108,6 +109,7 @@ const SearchBar = forwardRef((props: SearchBarProps, ref: Ref) = ) = autoComplete="off" dir="auto" /> - + tabIndex={showClearIcon ? 0 : -1} + disabled={!showClearIcon} + > + +
); });