diff --git a/packages/app/src/components/search/SearchModal.tsx b/packages/app/src/components/search/SearchModal.tsx index ea5a156c55..fea80f9952 100644 --- a/packages/app/src/components/search/SearchModal.tsx +++ b/packages/app/src/components/search/SearchModal.tsx @@ -186,7 +186,7 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => { - + } /> } /> } /> diff --git a/plugins/search/src/components/SearchModal/SearchModal.tsx b/plugins/search/src/components/SearchModal/SearchModal.tsx index c32c9a5cc3..8035484333 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.tsx @@ -92,7 +92,7 @@ const useStyles = makeStyles(theme => ({ viewResultsLink: { verticalAlign: '0.5em' }, })); -export const Modal = ({ toggleModal }: SearchModalProps) => { +export const Modal = () => { const classes = useStyles(); const navigate = useNavigate(); const { transitions } = useTheme(); @@ -107,9 +107,8 @@ export const Modal = ({ toggleModal }: SearchModalProps) => { }); const handleSearchResultClick = useCallback(() => { - toggleModal(); setTimeout(focusContent, transitions.duration.leavingScreen); - }, [toggleModal, focusContent, transitions]); + }, [focusContent, transitions]); const handleSearchBarKeyDown = useCallback( (e: KeyboardEvent) => { @@ -188,7 +187,7 @@ export const SearchModal = (props: SearchModalProps) => { {open && ( {(children && children({ toggleModal })) ?? ( - + )} )} diff --git a/plugins/search/src/components/SearchModal/useSearchModal.tsx b/plugins/search/src/components/SearchModal/useSearchModal.tsx index db01765f0e..91a2c38bfa 100644 --- a/plugins/search/src/components/SearchModal/useSearchModal.tsx +++ b/plugins/search/src/components/SearchModal/useSearchModal.tsx @@ -14,7 +14,14 @@ * limitations under the License. */ -import React, { ReactNode, useCallback, useContext, useState } from 'react'; +import React, { + ReactNode, + useCallback, + useContext, + useState, + useEffect, +} from 'react'; +import { useLocation } from 'react-router-dom'; import { createVersionedContext, createVersionedValueMap, @@ -96,7 +103,8 @@ export const SearchModalProvider = (props: SearchModalProviderProps) => { /** * Use this hook to manage the state of {@link SearchModal} - * and change its visibility. + * and change its visibility. Monitors route changes setting the hidden state + * to avoid having to call toggleModal on every result click. * * @public * @@ -105,10 +113,6 @@ export const SearchModalProvider = (props: SearchModalProviderProps) => { * functions for changing the visibility of the modal. */ export function useSearchModal(initialState = false) { - // Check for any existing parent context. - const parentContext = useContext(SearchModalContext); - const parentContextValue = parentContext?.atVersion(1); - const [state, setState] = useState({ hidden: !initialState, open: initialState, @@ -132,8 +136,32 @@ export function useSearchModal(initialState = false) { [], ); + // Check for any existing parent context. + const parentContext = useContext(SearchModalContext); + const parentContextValue = parentContext?.atVersion(1); + const isParentContextPresent = !!parentContextValue?.state; + + // Monitor route pathname changes to automatically hide the modal. + const { pathname } = useLocation(); + const [openedPathname, setOpenedPathname] = useState(null); + const { open, hidden } = state; + const isModalOpened = !isParentContextPresent && open && !hidden; + useEffect(() => { + if (isModalOpened) { + setOpenedPathname(pathname); + } + }, [isModalOpened, pathname]); + useEffect(() => { + if (isModalOpened && openedPathname && openedPathname !== pathname) { + setState(prevState => ({ + open: prevState.open, + hidden: true, + })); + } + }, [isModalOpened, openedPathname, pathname]); + // Inherit from parent context, if set. - return parentContextValue?.state + return isParentContextPresent ? parentContextValue : { state, toggleModal, setOpen }; }