diff --git a/.changeset/mean-moles-relate.md b/.changeset/mean-moles-relate.md
new file mode 100644
index 0000000000..1b3d01dd96
--- /dev/null
+++ b/.changeset/mean-moles-relate.md
@@ -0,0 +1,31 @@
+---
+'@backstage/plugin-search-react': minor
+---
+
+Allow customizing empty state component through `noResultsComponent` property.
+
+Example:
+
+```jsx
+No results were found>}>
+ {({ results }) => (
+
+ {results.map(({ type, document }) => {
+ switch (type) {
+ case 'custom-result-item':
+ return (
+
+ );
+ default:
+ return (
+
+ );
+ }
+ })}
+
+ )}
+
+```
diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md
index ef3e8b19bd..3d1e4091ea 100644
--- a/plugins/search-react/api-report.md
+++ b/plugins/search-react/api-report.md
@@ -402,6 +402,7 @@ export const SearchResultPager: () => JSX.Element;
// @public
export type SearchResultProps = Pick & {
children: (resultSet: SearchResultSet) => JSX.Element;
+ noResultsComponent?: JSX.Element;
};
// @public
diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx
index 6f536510e8..ef9b0d6b5c 100644
--- a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx
+++ b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx
@@ -218,3 +218,32 @@ export const GroupLayout = () => {
);
};
+
+export const WithCustomNoResultsComponent = () => {
+ return (
+ No results were found>}>
+ {({ results }) => (
+
+ {results.map(({ type, document }) => {
+ switch (type) {
+ case 'custom-result-item':
+ return (
+
+ );
+ default:
+ return (
+
+ );
+ }
+ })}
+
+ )}
+
+ );
+};
diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.test.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.test.tsx
index 988d59d7cf..5972eaa891 100644
--- a/plugins/search-react/src/components/SearchResult/SearchResult.test.tsx
+++ b/plugins/search-react/src/components/SearchResult/SearchResult.test.tsx
@@ -93,6 +93,22 @@ describe('SearchResult', () => {
});
});
+ it('On empty result value state with custom component', async () => {
+ (useSearch as jest.Mock).mockReturnValueOnce({
+ result: { loading: false, error: '', value: { results: [] } },
+ });
+
+ const { getByText } = await renderInTestApp(
+ No results found>}>
+ {() => <>>}
+ ,
+ );
+
+ await waitFor(() => {
+ expect(getByText('No results found')).toBeInTheDocument();
+ });
+ });
+
it('Calls children with results set to result.value', async () => {
(useSearch as jest.Mock).mockReturnValueOnce({
result: {
diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.tsx
index dd11f42903..333156aab9 100644
--- a/plugins/search-react/src/components/SearchResult/SearchResult.tsx
+++ b/plugins/search-react/src/components/SearchResult/SearchResult.tsx
@@ -167,6 +167,7 @@ export const SearchResultState = (props: SearchResultStateProps) => {
*/
export type SearchResultProps = Pick & {
children: (resultSet: SearchResultSet) => JSX.Element;
+ noResultsComponent?: JSX.Element;
};
/**
@@ -176,7 +177,13 @@ export type SearchResultProps = Pick & {
* @public
*/
export const SearchResultComponent = (props: SearchResultProps) => {
- const { query, children } = props;
+ const {
+ query,
+ children,
+ noResultsComponent = (
+
+ ),
+ } = props;
return (
@@ -195,9 +202,7 @@ export const SearchResultComponent = (props: SearchResultProps) => {
}
if (!value?.results.length) {
- return (
-
- );
+ return noResultsComponent;
}
return children(value);