From 7aaa8f703e932b9f357a2e41295290f71a7839c1 Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Thu, 16 Jan 2025 10:27:38 +1030 Subject: [PATCH] fix: auto-focus the search keyword input when in search modal only so that library authoring navigate events don't change element focus. --- src/library-authoring/LibraryAuthoringPage.test.tsx | 4 ++++ src/search-manager/SearchKeywordsField.tsx | 8 ++++++-- src/search-modal/SearchModal.test.tsx | 10 ++++++++++ src/search-modal/SearchModal.tsx | 6 +++++- src/search-modal/SearchUI.tsx | 11 +++++++++-- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/library-authoring/LibraryAuthoringPage.test.tsx b/src/library-authoring/LibraryAuthoringPage.test.tsx index 2b55375fd2..ed02d68bd1 100644 --- a/src/library-authoring/LibraryAuthoringPage.test.tsx +++ b/src/library-authoring/LibraryAuthoringPage.test.tsx @@ -111,6 +111,10 @@ describe('', () => { expect(screen.getAllByText('Recently Modified').length).toEqual(1); expect((await screen.findAllByText('Introduction to Testing'))[0]).toBeInTheDocument(); + // Search box should not have focus on page load + const searchBox = screen.getByRole('searchbox'); + expect(searchBox).not.toHaveFocus(); + // Navigate to the components tab fireEvent.click(screen.getByRole('tab', { name: 'Components' })); // "Recently Modified" default sort shown diff --git a/src/search-manager/SearchKeywordsField.tsx b/src/search-manager/SearchKeywordsField.tsx index 14a6a06dc9..90c09fdd93 100644 --- a/src/search-manager/SearchKeywordsField.tsx +++ b/src/search-manager/SearchKeywordsField.tsx @@ -7,7 +7,11 @@ import { useSearchContext } from './SearchManager'; /** * The "main" input field where users type in search keywords. The search happens as they type (no need to press enter). */ -const SearchKeywordsField: React.FC<{ className?: string, placeholder?: string }> = (props) => { +const SearchKeywordsField: React.FC<{ + className?: string, + placeholder?: string, + autoFocus?: boolean, +}> = (props) => { const intl = useIntl(); const { searchKeywords, setSearchKeywords, usageKey } = useSearchContext(); const defaultPlaceholder = usageKey ? messages.clearUsageKeyToSearch : messages.inputPlaceholder; @@ -24,7 +28,7 @@ const SearchKeywordsField: React.FC<{ className?: string, placeholder?: string } > diff --git a/src/search-modal/SearchModal.test.tsx b/src/search-modal/SearchModal.test.tsx index ef35726395..9449a9efdc 100644 --- a/src/search-modal/SearchModal.test.tsx +++ b/src/search-modal/SearchModal.test.tsx @@ -73,4 +73,14 @@ describe('', () => { const { findByText } = render(); expect(await findByText('An error occurred. Unable to load search results.')).toBeInTheDocument(); }); + + it('should set focus on the search input box when loaded in the modal', async () => { + axiosMock.onGet(getContentSearchConfigUrl()).replyOnce(200, { + url: 'https://meilisearch.example.com', + index: 'test-index', + apiKey: 'test-api-key', + }); + const { getByRole } = render(); + expect(getByRole('searchbox')).toHaveFocus(); + }); }); diff --git a/src/search-modal/SearchModal.tsx b/src/search-modal/SearchModal.tsx index 2e552fb6e8..197ba6c708 100644 --- a/src/search-modal/SearchModal.tsx +++ b/src/search-modal/SearchModal.tsx @@ -21,7 +21,11 @@ const SearchModal: React.FC<{ courseId?: string, isOpen: boolean, onClose: () => isFullscreenOnMobile className="courseware-search-modal" > - + ); }; diff --git a/src/search-modal/SearchUI.tsx b/src/search-modal/SearchUI.tsx index 2df074111c..a70e1f69fe 100644 --- a/src/search-modal/SearchUI.tsx +++ b/src/search-modal/SearchUI.tsx @@ -19,7 +19,11 @@ import EmptyStates from './EmptyStates'; import SearchResults from './SearchResults'; import messages from './messages'; -const SearchUI: React.FC<{ courseId?: string, closeSearchModal?: () => void }> = (props) => { +const SearchUI: React.FC<{ + courseId?: string, + autoFocus?: boolean, + closeSearchModal?: () => void, +}> = (props) => { const hasCourseId = Boolean(props.courseId); const [searchThisCourseEnabled, setSearchThisCourse] = React.useState(hasCourseId); const switchToThisCourse = React.useCallback(() => setSearchThisCourse(true), []); @@ -39,7 +43,10 @@ const SearchUI: React.FC<{ courseId?: string, closeSearchModal?: () => void }> =
- +