diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md
index 09dd3d77a8..5558fd3257 100644
--- a/plugins/search-react/api-report.md
+++ b/plugins/search-react/api-report.md
@@ -124,6 +124,9 @@ export type SearchFilterWrapperProps = SearchFilterComponentProps & {
// @public (undocumented)
export const SearchResult: ({ children }: SearchResultProps) => JSX.Element;
+// @public (undocumented)
+export const SearchResultPager: () => JSX.Element;
+
// @public (undocumented)
export type SearchResultProps = {
children: (results: { results: SearchResult_2[] }) => JSX.Element;
diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json
index 04932bd5ea..95507e64b7 100644
--- a/plugins/search-react/package.json
+++ b/plugins/search-react/package.json
@@ -38,6 +38,7 @@
"@backstage/version-bridge": "^1.0.1",
"@backstage/types": "^1.0.0",
"@material-ui/core": "^4.12.2",
+ "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
"react-router": "6.0.0-beta.0",
"react-use": "^17.3.2"
diff --git a/plugins/search-react/src/components/SearchResultPager/SearchResultPager.test.tsx b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.test.tsx
new file mode 100644
index 0000000000..24d9a76e51
--- /dev/null
+++ b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.test.tsx
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+
+import { renderInTestApp } from '@backstage/test-utils';
+import { waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+
+import { useSearch } from '../../context';
+import { SearchResultPager } from './SearchResultPager';
+
+jest.mock('../../context', () => ({
+ ...jest.requireActual('../../context'),
+ useSearch: jest.fn().mockReturnValue({
+ result: {},
+ }),
+}));
+
+describe('SearchResultPager', () => {
+ it('renders pager buttons', async () => {
+ const fetchNextPage = jest.fn();
+ const fetchPreviousPage = jest.fn();
+ (useSearch as jest.Mock).mockReturnValueOnce({
+ result: { loading: false, value: [] },
+ fetchNextPage,
+ fetchPreviousPage,
+ });
+
+ const { getByLabelText } = await renderInTestApp();
+
+ await waitFor(() => {
+ expect(getByLabelText('previous page')).toBeInTheDocument();
+ });
+ await userEvent.click(getByLabelText('previous page'));
+ expect(fetchPreviousPage).toBeCalled();
+
+ await waitFor(() => {
+ expect(getByLabelText('next page')).toBeInTheDocument();
+ });
+ await userEvent.click(getByLabelText('next page'));
+
+ expect(fetchNextPage).toBeCalled();
+ });
+});
diff --git a/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx
new file mode 100644
index 0000000000..68f8223ca0
--- /dev/null
+++ b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+
+import { Button, makeStyles } from '@material-ui/core';
+import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';
+import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';
+
+import { useSearch } from '../../context';
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ display: 'flex',
+ justifyContent: 'space-between',
+ gap: theme.spacing(2),
+ margin: theme.spacing(2, 0),
+ },
+}));
+
+/**
+ * @public
+ */
+export const SearchResultPager = () => {
+ const { fetchNextPage, fetchPreviousPage } = useSearch();
+ const classes = useStyles();
+
+ if (!fetchNextPage && !fetchPreviousPage) {
+ return <>>;
+ }
+
+ return (
+
+ );
+};
diff --git a/plugins/search-react/src/components/SearchResultPager/index.ts b/plugins/search-react/src/components/SearchResultPager/index.ts
new file mode 100644
index 0000000000..5ff203b15d
--- /dev/null
+++ b/plugins/search-react/src/components/SearchResultPager/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { SearchResultPager } from './SearchResultPager';
diff --git a/plugins/search-react/src/components/index.ts b/plugins/search-react/src/components/index.ts
index db9214d299..bfd65d471f 100644
--- a/plugins/search-react/src/components/index.ts
+++ b/plugins/search-react/src/components/index.ts
@@ -17,3 +17,4 @@
export * from './HighlightedSearchResultText';
export * from './SearchFilter';
export * from './SearchResult';
+export * from './SearchResultPager';
diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md
index ec60569af4..25a7f40394 100644
--- a/plugins/search/api-report.md
+++ b/plugins/search/api-report.md
@@ -237,7 +237,7 @@ export const SearchResult: ({
// Warning: (ae-missing-release-tag) "SearchResultPager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
-// @public (undocumented)
+// @public @deprecated (undocumented)
export const SearchResultPager: () => JSX.Element;
// Warning: (ae-missing-release-tag) "SearchType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
diff --git a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx
index 6f4c8628a6..0e8d59a694 100644
--- a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx
+++ b/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx
@@ -29,6 +29,9 @@ const useStyles = makeStyles(theme => ({
},
}));
+/**
+ * @deprecated Moved to `@backstage/plugin-search-react`.
+ */
export const SearchResultPager = () => {
const { fetchNextPage, fetchPreviousPage } = useSearch();
const classes = useStyles();