diff --git a/.changeset/orange-friends-march.md b/.changeset/orange-friends-march.md new file mode 100644 index 0000000000..d3813063e2 --- /dev/null +++ b/.changeset/orange-friends-march.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search': patch +--- + +Fixed the `SearchModal` leaving the page in a broken state by not restoring body overflow and aria-hidden attributes when closing. diff --git a/plugins/search/src/components/SearchModal/SearchModal.test.tsx b/plugins/search/src/components/SearchModal/SearchModal.test.tsx index 9424599130..6235b5a511 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.test.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.test.tsx @@ -155,22 +155,6 @@ describe('SearchModal', () => { expect(toggleModal).toHaveBeenCalledTimes(1); }); - it('should render SearchModal hiding its content', async () => { - const { getByTestId } = await renderInTestApp( - - , - { - mountedRoutes: { - '/search': rootRouteRef, - }, - }, - ); - - expect(getByTestId('search-bar-next')).toBeInTheDocument(); - expect(getByTestId('search-bar-next')).not.toBeVisible(); - }); - it('should focus on its search bar when opened', async () => { await renderInTestApp( @@ -252,4 +236,36 @@ describe('SearchModal', () => { expect(navigate).toHaveBeenCalledWith('/search?query=term'); }); + + it('should completely unmount the Dialog from DOM when open prop is false', async () => { + await renderInTestApp( + + , + { + mountedRoutes: { + '/search': rootRouteRef, + }, + }, + ); + + // Dialog should not exist in the DOM at all (unmounted, not just hidden) + expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); + }); + + it('should completely unmount the Dialog from DOM when hidden prop is true', async () => { + await renderInTestApp( + + , + { + mountedRoutes: { + '/search': rootRouteRef, + }, + }, + ); + + // Dialog should not exist in the DOM at all (unmounted, not just hidden) + expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); + }); }); diff --git a/plugins/search/src/components/SearchModal/SearchModal.tsx b/plugins/search/src/components/SearchModal/SearchModal.tsx index af7e1c6e10..86fa4f1b73 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.tsx @@ -211,6 +211,8 @@ export const SearchModal = (props: SearchModalProps) => { const classes = useStyles(); + const isDialogOpen = open && !hidden; + return ( { aria-modal="true" fullWidth maxWidth="lg" - open={open} - hidden={hidden} + open={isDialogOpen} > - {open && ( + {isDialogOpen && ( {(children && children({