diff --git a/.changeset/green-trees-wait.md b/.changeset/green-trees-wait.md
new file mode 100644
index 0000000000..388298ef59
--- /dev/null
+++ b/.changeset/green-trees-wait.md
@@ -0,0 +1,22 @@
+---
+'@backstage/create-app': patch
+---
+
+imports `useSearch` hook from new `@backstage/plugin-search-react` package.
+
+To upgrade existing Apps:
+
+1. Change the import to the following:
+
+`packages/app/src/components/search/SearchPage.tsx`
+
+```diff
+import {
+...
+SearchType,
+- useSearch,
+} from '@backstage/plugin-search';
++import { useSearch } from '@backstage/plugin-search-react';
+```
+
+2. Add `@backstage/plugin-search-react` as a dependency to the app.
diff --git a/.changeset/strong-lions-film.md b/.changeset/strong-lions-film.md
new file mode 100644
index 0000000000..5efd765e83
--- /dev/null
+++ b/.changeset/strong-lions-film.md
@@ -0,0 +1,12 @@
+---
+'@backstage/plugin-search': minor
+---
+
+The following exports has now been fully deleted from this package and can be import from `@backstage/plugin-search-react` instead.
+
+`SearchApi` interface.
+`searchApiRef`
+`SearchContextProvider`
+`useSearch`
+
+`SearchContext` has now been fully deleted from this package and is no longer exported publicly. Use `SearchContextProvider` when access to the context is needed.
diff --git a/packages/app/src/components/search/SearchModal.tsx b/packages/app/src/components/search/SearchModal.tsx
index 2e18a289c9..f75017a4dd 100644
--- a/packages/app/src/components/search/SearchModal.tsx
+++ b/packages/app/src/components/search/SearchModal.tsx
@@ -41,8 +41,8 @@ import {
SearchResult,
SearchResultPager,
SearchType,
- useSearch,
} from '@backstage/plugin-search';
+import { useSearch } from '@backstage/plugin-search-react';
import { TechDocsSearchResultListItem } from '@backstage/plugin-techdocs';
const useStyles = makeStyles(theme => ({
diff --git a/packages/app/src/components/search/SearchPage.tsx b/packages/app/src/components/search/SearchPage.tsx
index 65da72d91c..fd9c80686c 100644
--- a/packages/app/src/components/search/SearchPage.tsx
+++ b/packages/app/src/components/search/SearchPage.tsx
@@ -36,8 +36,8 @@ import {
SearchResult,
SearchResultPager,
SearchType,
- useSearch,
} from '@backstage/plugin-search';
+import { useSearch } from '@backstage/plugin-search-react';
import { TechDocsSearchResultListItem } from '@backstage/plugin-techdocs';
import { Grid, List, makeStyles, Paper, Theme } from '@material-ui/core';
import React, { useContext } from 'react';
diff --git a/packages/create-app/package.json b/packages/create-app/package.json
index 06b39867fa..6f2aef14eb 100644
--- a/packages/create-app/package.json
+++ b/packages/create-app/package.json
@@ -85,6 +85,7 @@
"@backstage/plugin-scaffolder": "",
"@backstage/plugin-scaffolder-backend": "",
"@backstage/plugin-search": "",
+ "@backstage/plugin-search-react": "",
"@backstage/plugin-search-backend": "",
"@backstage/plugin-search-backend-module-pg": "",
"@backstage/plugin-search-backend-node": "",
diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts
index 963c04afdf..b6c93a38b3 100644
--- a/packages/create-app/src/lib/versions.ts
+++ b/packages/create-app/src/lib/versions.ts
@@ -69,6 +69,7 @@ import { version as pluginRollbarBackend } from '../../../../plugins/rollbar-bac
import { version as pluginScaffolder } from '../../../../plugins/scaffolder/package.json';
import { version as pluginScaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json';
import { version as pluginSearch } from '../../../../plugins/search/package.json';
+import { version as pluginSearchReact } from '../../../../plugins/search-react/package.json';
import { version as pluginSearchBackend } from '../../../../plugins/search-backend/package.json';
import { version as pluginSearchBackendModulePg } from '../../../../plugins/search-backend-module-pg/package.json';
import { version as pluginSearchBackendNode } from '../../../../plugins/search-backend-node/package.json';
@@ -113,6 +114,7 @@ export const packageVersions = {
'@backstage/plugin-scaffolder': pluginScaffolder,
'@backstage/plugin-scaffolder-backend': pluginScaffolderBackend,
'@backstage/plugin-search': pluginSearch,
+ '@backstage/plugin-search-react': pluginSearchReact,
'@backstage/plugin-search-backend': pluginSearchBackend,
'@backstage/plugin-search-backend-module-pg': pluginSearchBackendModulePg,
'@backstage/plugin-search-backend-node': pluginSearchBackendNode,
diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs
index 2ad394c68e..87a8060594 100644
--- a/packages/create-app/templates/default-app/packages/app/package.json.hbs
+++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs
@@ -25,6 +25,7 @@
"@backstage/plugin-permission-react": "^{{version '@backstage/plugin-permission-react'}}",
"@backstage/plugin-scaffolder": "^{{version '@backstage/plugin-scaffolder'}}",
"@backstage/plugin-search": "^{{version '@backstage/plugin-search'}}",
+ "@backstage/plugin-search-react": "^{{version '@backstage/plugin-search-react'}}",
"@backstage/plugin-tech-radar": "^{{version '@backstage/plugin-tech-radar'}}",
"@backstage/plugin-techdocs": "^{{version '@backstage/plugin-techdocs'}}",
"@backstage/plugin-user-settings": "^{{version '@backstage/plugin-user-settings'}}",
diff --git a/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx
index cd4603ecd3..0595e4ece8 100644
--- a/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx
+++ b/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx
@@ -14,8 +14,8 @@ import {
SearchResult,
SearchType,
DefaultResultListItem,
- useSearch,
} from '@backstage/plugin-search';
+import { useSearch } from '@backstage/plugin-search-react';
import {
CatalogIcon,
Content,
diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md
index 2f9a8fbb77..31d357f10c 100644
--- a/plugins/search/api-report.md
+++ b/plugins/search/api-report.md
@@ -5,20 +5,14 @@
```ts
///
-import { ApiRef } from '@backstage/core-plugin-api';
-import { AsyncState } from 'react-use/lib/useAsync';
import { BackstagePlugin } from '@backstage/core-plugin-api';
import { IconComponent } from '@backstage/core-plugin-api';
import { InputBaseProps } from '@material-ui/core';
-import { JsonObject } from '@backstage/types';
-import { default as React_2 } from 'react';
import { ReactElement } from 'react';
import { ReactNode } from 'react';
import { RouteRef } from '@backstage/core-plugin-api';
import { SearchDocument } from '@backstage/plugin-search-common';
-import { SearchQuery } from '@backstage/plugin-search-common';
import { SearchResult as SearchResult_2 } from '@backstage/plugin-search-common';
-import { SearchResultSet } from '@backstage/plugin-search-common';
// Warning: (ae-missing-release-tag) "DefaultResultListItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -81,19 +75,6 @@ export type HomePageSearchBarProps = Partial<
// @public (undocumented)
export const Router: () => JSX.Element;
-// Warning: (ae-missing-release-tag) "SearchApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public @deprecated (undocumented)
-export interface SearchApi {
- // (undocumented)
- query(query: SearchQuery): Promise;
-}
-
-// Warning: (ae-missing-release-tag) "searchApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public @deprecated (undocumented)
-export const searchApiRef: ApiRef;
-
// @public (undocumented)
export type SearchAutocompleteFilterProps = SearchFilterComponentProps & {
filterSelectedOptions?: boolean;
@@ -138,24 +119,6 @@ export const SearchBarNext: ({
// @public
export type SearchBarProps = Partial;
-// Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public @deprecated (undocumented)
-export const SearchContextProvider: ({
- initialState,
- children,
-}: React_2.PropsWithChildren<{
- initialState?: SearchContextState | undefined;
-}>) => JSX.Element;
-
-// @public
-export type SearchContextState = {
- term: string;
- types: string[];
- filters: JsonObject;
- pageCursor?: string;
-};
-
// Warning: (ae-missing-release-tag) "SearchFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -330,13 +293,6 @@ export type SidebarSearchProps = {
icon?: IconComponent;
};
-// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it
-// Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "useSearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public @deprecated (undocumented)
-export const useSearch: () => SearchContextValue;
-
// @public
export function useSearchModal(initialState?: boolean): {
state: {
diff --git a/plugins/search/src/apis.ts b/plugins/search/src/apis.ts
index 096b11bb5e..208ad98b0a 100644
--- a/plugins/search/src/apis.ts
+++ b/plugins/search/src/apis.ts
@@ -14,30 +14,13 @@
* limitations under the License.
*/
-import {
- createApiRef,
- DiscoveryApi,
- IdentityApi,
-} from '@backstage/core-plugin-api';
+import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
import { ResponseError } from '@backstage/errors';
+import { SearchApi } from '@backstage/plugin-search-react';
import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';
import qs from 'qs';
-/**
- * @deprecated import from `@backstage/plugin-search-react` instead
- */
-export const searchApiRef = createApiRef({
- id: 'plugin.search.queryservice',
-});
-
-/**
- * @deprecated import from `@backstage/plugin-search-react` instead
- */
-export interface SearchApi {
- query(query: SearchQuery): Promise;
-}
-
export class SearchClient implements SearchApi {
private readonly discoveryApi: DiscoveryApi;
private readonly identityApi: IdentityApi;
diff --git a/plugins/search/src/components/HomePageComponent/HomePageSearchBar.stories.tsx b/plugins/search/src/components/HomePageComponent/HomePageSearchBar.stories.tsx
index 1a6c5fbf7b..4c20ddec39 100644
--- a/plugins/search/src/components/HomePageComponent/HomePageSearchBar.stories.tsx
+++ b/plugins/search/src/components/HomePageComponent/HomePageSearchBar.stories.tsx
@@ -15,7 +15,7 @@
*/
import { rootRouteRef, HomePageSearchBar } from '../../plugin';
-import { searchApiRef } from '../../apis';
+import { searchApiRef } from '@backstage/plugin-search-react';
import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils';
import { Grid, makeStyles } from '@material-ui/core';
import React, { ComponentType } from 'react';
diff --git a/plugins/search/src/components/HomePageComponent/HomePageSearchBar.tsx b/plugins/search/src/components/HomePageComponent/HomePageSearchBar.tsx
index bccf38ab1d..bc4b409d57 100644
--- a/plugins/search/src/components/HomePageComponent/HomePageSearchBar.tsx
+++ b/plugins/search/src/components/HomePageComponent/HomePageSearchBar.tsx
@@ -16,7 +16,6 @@
import React, { useCallback, useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
-
import { SearchBarBase, SearchBarBaseProps } from '../SearchBar';
import { useNavigateToQuery } from '../util';
diff --git a/plugins/search/src/components/SearchBar/SearchBar.test.tsx b/plugins/search/src/components/SearchBar/SearchBar.test.tsx
index 73afb44f12..c48c3d3ed2 100644
--- a/plugins/search/src/components/SearchBar/SearchBar.test.tsx
+++ b/plugins/search/src/components/SearchBar/SearchBar.test.tsx
@@ -17,13 +17,15 @@
import React from 'react';
import { screen, render, waitFor, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { SearchContextProvider } from '../SearchContext';
-
-import { SearchBar } from './SearchBar';
import { configApiRef, analyticsApiRef } from '@backstage/core-plugin-api';
import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
-import { searchApiRef } from '../../apis';
import { MockAnalyticsApi, TestApiRegistry } from '@backstage/test-utils';
+import {
+ SearchContextProvider,
+ searchApiRef,
+} from '@backstage/plugin-search-react';
+
+import { SearchBar } from './SearchBar';
jest.mock('@backstage/core-plugin-api', () => ({
...jest.requireActual('@backstage/core-plugin-api'),
diff --git a/plugins/search/src/components/SearchBar/SearchBar.tsx b/plugins/search/src/components/SearchBar/SearchBar.tsx
index a203d27c93..70038ecc82 100644
--- a/plugins/search/src/components/SearchBar/SearchBar.tsx
+++ b/plugins/search/src/components/SearchBar/SearchBar.tsx
@@ -20,7 +20,6 @@ import React, {
useState,
useEffect,
useCallback,
- useContext,
} from 'react';
import useDebounce from 'react-use/lib/useDebounce';
import { configApiRef, useApi } from '@backstage/core-plugin-api';
@@ -34,10 +33,9 @@ import SearchIcon from '@material-ui/icons/Search';
import ClearButton from '@material-ui/icons/Clear';
import {
- SearchContext,
SearchContextProvider,
useSearch,
-} from '../SearchContext';
+} from '@backstage/plugin-search-react';
import { TrackSearch } from '../SearchTracker';
/**
@@ -53,11 +51,6 @@ export type SearchBarBaseProps = Omit & {
onChange: (value: string) => void;
};
-const useSearchContextCheck = () => {
- const context = useContext(SearchContext);
- return context !== undefined;
-};
-
/**
* All search boxes exported by the search plugin are based on the ,
* and this one is based on the component from Material UI.
@@ -79,7 +72,7 @@ export const SearchBarBase = ({
}: SearchBarBaseProps) => {
const configApi = useApi(configApiRef);
const [value, setValue] = useState(defaultValue as string);
- const hasSearchContext = useSearchContextCheck();
+ const hasSearchContext = useSearch();
useEffect(() => {
setValue(prevValue =>
diff --git a/plugins/search/src/components/SearchContext/SearchContext.tsx b/plugins/search/src/components/SearchContext/SearchContext.tsx
deleted file mode 100644
index c87295ab99..0000000000
--- a/plugins/search/src/components/SearchContext/SearchContext.tsx
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2021 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 { JsonObject } from '@backstage/types';
-import { useApi, AnalyticsContext } from '@backstage/core-plugin-api';
-import { SearchResultSet } from '@backstage/plugin-search-common';
-import React, {
- createContext,
- PropsWithChildren,
- useCallback,
- useContext,
- useEffect,
- useState,
-} from 'react';
-import useAsync, { AsyncState } from 'react-use/lib/useAsync';
-import usePrevious from 'react-use/lib/usePrevious';
-import { searchApiRef } from '../../apis';
-
-type SearchContextValue = {
- result: AsyncState;
- setTerm: React.Dispatch>;
- setTypes: React.Dispatch>;
- setFilters: React.Dispatch>;
- setPageCursor: React.Dispatch>;
- fetchNextPage?: React.DispatchWithoutAction;
- fetchPreviousPage?: React.DispatchWithoutAction;
-} & SearchContextState;
-
-/**
- * The initial state of `SearchContextProvider`.
- *
- * @public
- */
-export type SearchContextState = {
- term: string;
- types: string[];
- filters: JsonObject;
- pageCursor?: string;
-};
-
-/**
- * @deprecated import from `@backstage/plugin-search-react` instead
- */
-export const SearchContext = createContext(
- undefined,
-);
-
-const searchInitialState: SearchContextState = {
- term: '',
- pageCursor: undefined,
- filters: {},
- types: [],
-};
-
-/**
- * @deprecated import from `@backstage/plugin-search-react` instead
- */
-export const SearchContextProvider = ({
- initialState = searchInitialState,
- children,
-}: PropsWithChildren<{ initialState?: SearchContextState }>) => {
- const searchApi = useApi(searchApiRef);
- const [pageCursor, setPageCursor] = useState(
- initialState.pageCursor,
- );
- const [filters, setFilters] = useState(initialState.filters);
- const [term, setTerm] = useState(initialState.term);
- const [types, setTypes] = useState(initialState.types);
-
- const prevTerm = usePrevious(term);
-
- const result = useAsync(
- () =>
- searchApi.query({
- term,
- filters,
- pageCursor,
- types,
- }),
- [term, filters, types, pageCursor],
- );
-
- const hasNextPage =
- !result.loading && !result.error && result.value?.nextPageCursor;
- const hasPreviousPage =
- !result.loading && !result.error && result.value?.previousPageCursor;
- const fetchNextPage = useCallback(() => {
- setPageCursor(result.value?.nextPageCursor);
- }, [result.value?.nextPageCursor]);
- const fetchPreviousPage = useCallback(() => {
- setPageCursor(result.value?.previousPageCursor);
- }, [result.value?.previousPageCursor]);
-
- useEffect(() => {
- // Any time a term is reset, we want to start from page 0.
- if (term && prevTerm && term !== prevTerm) {
- setPageCursor(undefined);
- }
- }, [term, prevTerm, initialState.pageCursor]);
-
- const value: SearchContextValue = {
- result,
- filters,
- setFilters,
- term,
- setTerm,
- types,
- setTypes,
- pageCursor,
- setPageCursor,
- fetchNextPage: hasNextPage ? fetchNextPage : undefined,
- fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined,
- };
-
- return (
-
-
-
- );
-};
-
-/**
- * @deprecated import from "@backstage/plugin-search-react" instead
- */
-export const useSearch = () => {
- const context = useContext(SearchContext);
- if (context === undefined) {
- throw new Error('useSearch must be used within a SearchContextProvider');
- }
- return context;
-};
diff --git a/plugins/search/src/components/SearchContext/index.tsx b/plugins/search/src/components/SearchContext/index.tsx
deleted file mode 100644
index 8651e661c1..0000000000
--- a/plugins/search/src/components/SearchContext/index.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2021 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 {
- SearchContextProvider,
- SearchContext,
- useSearch,
-} from './SearchContext';
-
-export type { SearchContextState } from './SearchContext';
diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx
index ae0eeb30be..15ad348bd4 100644
--- a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx
+++ b/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx
@@ -18,8 +18,11 @@ import { TestApiProvider } from '@backstage/test-utils';
import { screen, render, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
-import { searchApiRef } from '../../apis';
-import { SearchContextProvider, useSearch } from '../SearchContext';
+import {
+ SearchContextProvider,
+ useSearch,
+ searchApiRef,
+} from '@backstage/plugin-search-react';
import { SearchFilter } from './SearchFilter';
const SearchContextFilterSpy = ({ name }: { name: string }) => {
diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx
index 9a27f63565..03f4f28943 100644
--- a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx
+++ b/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx
@@ -21,7 +21,7 @@ import {
AutocompleteGetTagProps,
AutocompleteRenderInputParams,
} from '@material-ui/lab';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
import { useAsyncFilterValues, useDefaultFilterValue } from './hooks';
import { SearchFilterComponentProps } from './SearchFilter';
diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx
index ba7abe7023..2d652df483 100644
--- a/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx
+++ b/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx
@@ -19,7 +19,7 @@ import { screen, render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { SearchFilter } from './SearchFilter';
-import { SearchContextProvider } from '../SearchContext';
+import { SearchContextProvider } from '@backstage/plugin-search-react';
import { useApi } from '@backstage/core-plugin-api';
jest.mock('@backstage/core-plugin-api', () => ({
diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.tsx
index 1308333100..bfbab8531c 100644
--- a/plugins/search/src/components/SearchFilter/SearchFilter.tsx
+++ b/plugins/search/src/components/SearchFilter/SearchFilter.tsx
@@ -30,7 +30,7 @@ import {
AutocompleteFilter,
SearchAutocompleteFilterProps,
} from './SearchFilter.Autocomplete';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
import { useAsyncFilterValues, useDefaultFilterValue } from './hooks';
const useStyles = makeStyles({
diff --git a/plugins/search/src/components/SearchFilter/hooks.test.tsx b/plugins/search/src/components/SearchFilter/hooks.test.tsx
index d8fbe698ce..14346a29eb 100644
--- a/plugins/search/src/components/SearchFilter/hooks.test.tsx
+++ b/plugins/search/src/components/SearchFilter/hooks.test.tsx
@@ -17,9 +17,12 @@ import React from 'react';
import { ApiProvider } from '@backstage/core-app-api';
import { TestApiRegistry } from '@backstage/test-utils';
import { renderHook } from '@testing-library/react-hooks';
-import { SearchContextProvider, useSearch } from '../SearchContext';
+import {
+ SearchContextProvider,
+ useSearch,
+ searchApiRef,
+} from '@backstage/plugin-search-react';
import { useDefaultFilterValue, useAsyncFilterValues } from './hooks';
-import { searchApiRef } from '../../apis';
jest.useFakeTimers();
diff --git a/plugins/search/src/components/SearchFilter/hooks.ts b/plugins/search/src/components/SearchFilter/hooks.ts
index 217e65d1c0..da30466522 100644
--- a/plugins/search/src/components/SearchFilter/hooks.ts
+++ b/plugins/search/src/components/SearchFilter/hooks.ts
@@ -17,7 +17,7 @@
import { useEffect, useRef } from 'react';
import useAsyncFn from 'react-use/lib/useAsyncFn';
import useDebounce from 'react-use/lib/useDebounce';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
/**
* Utility hook for either asynchronously loading filter values from a given
diff --git a/plugins/search/src/components/SearchModal/SearchModal.test.tsx b/plugins/search/src/components/SearchModal/SearchModal.test.tsx
index c50d8af1eb..842f5fb401 100644
--- a/plugins/search/src/components/SearchModal/SearchModal.test.tsx
+++ b/plugins/search/src/components/SearchModal/SearchModal.test.tsx
@@ -21,7 +21,7 @@ import userEvent from '@testing-library/user-event';
import { configApiRef } from '@backstage/core-plugin-api';
import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { rootRouteRef } from '../../plugin';
-import { searchApiRef } from '../../apis';
+import { searchApiRef } from '@backstage/plugin-search-react';
import { SearchModal } from './SearchModal';
diff --git a/plugins/search/src/components/SearchModal/SearchModal.tsx b/plugins/search/src/components/SearchModal/SearchModal.tsx
index 67b99e0926..55fd0cb977 100644
--- a/plugins/search/src/components/SearchModal/SearchModal.tsx
+++ b/plugins/search/src/components/SearchModal/SearchModal.tsx
@@ -31,7 +31,10 @@ import { makeStyles } from '@material-ui/core/styles';
import { SearchBar } from '../SearchBar';
import { DefaultResultListItem } from '../DefaultResultListItem';
import { SearchResult } from '../SearchResult';
-import { SearchContextProvider, useSearch } from '../SearchContext';
+import {
+ SearchContextProvider,
+ useSearch,
+} from '@backstage/plugin-search-react';
import { SearchResultPager } from '../SearchResultPager';
import { useRouteRef } from '@backstage/core-plugin-api';
import { Link, useContent } from '@backstage/core-components';
diff --git a/plugins/search/src/components/SearchPage/SearchPage.test.tsx b/plugins/search/src/components/SearchPage/SearchPage.test.tsx
index 9486196584..59e6e99aaf 100644
--- a/plugins/search/src/components/SearchPage/SearchPage.test.tsx
+++ b/plugins/search/src/components/SearchPage/SearchPage.test.tsx
@@ -17,7 +17,7 @@
import { renderInTestApp } from '@backstage/test-utils';
import React from 'react';
import { useLocation, useOutlet } from 'react-router';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
import { SearchPage } from './SearchPage';
jest.mock('react-router', () => ({
@@ -33,8 +33,8 @@ const setTypesMock = jest.fn();
const setFiltersMock = jest.fn();
const setPageCursorMock = jest.fn();
-jest.mock('../SearchContext', () => ({
- ...jest.requireActual('../SearchContext'),
+jest.mock('@backstage/plugin-search-react', () => ({
+ ...jest.requireActual('@backstage/plugin-search-react'),
SearchContextProvider: jest
.fn()
.mockImplementation(({ children }) => children),
@@ -51,7 +51,7 @@ jest.mock('../SearchContext', () => ({
}));
jest.mock('../LegacySearchPage', () => ({
- ...jest.requireActual('../SearchContext'),
+ ...jest.requireActual('@backstage/plugin-search-react'),
LegacySearchPage: jest.fn().mockReturnValue('LegacySearchPageMock'),
}));
diff --git a/plugins/search/src/components/SearchPage/SearchPage.tsx b/plugins/search/src/components/SearchPage/SearchPage.tsx
index e4e1e49d57..29a22a6f5c 100644
--- a/plugins/search/src/components/SearchPage/SearchPage.tsx
+++ b/plugins/search/src/components/SearchPage/SearchPage.tsx
@@ -18,7 +18,10 @@ import React, { useEffect } from 'react';
import usePrevious from 'react-use/lib/usePrevious';
import qs from 'qs';
import { useLocation, useOutlet } from 'react-router';
-import { SearchContextProvider, useSearch } from '../SearchContext';
+import {
+ SearchContextProvider,
+ useSearch,
+} from '@backstage/plugin-search-react';
import { JsonObject } from '@backstage/types';
import { LegacySearchPage } from '../LegacySearchPage';
diff --git a/plugins/search/src/components/SearchResult/SearchResult.test.tsx b/plugins/search/src/components/SearchResult/SearchResult.test.tsx
index 43a9cdb022..d93eacaef0 100644
--- a/plugins/search/src/components/SearchResult/SearchResult.test.tsx
+++ b/plugins/search/src/components/SearchResult/SearchResult.test.tsx
@@ -17,11 +17,11 @@
import { renderInTestApp } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
import { SearchResult } from './SearchResult';
-jest.mock('../SearchContext', () => ({
- ...jest.requireActual('../SearchContext'),
+jest.mock('@backstage/plugin-search-react', () => ({
+ ...jest.requireActual('@backstage/plugin-search-react'),
useSearch: jest.fn().mockReturnValue({
result: {},
}),
diff --git a/plugins/search/src/components/SearchResult/SearchResult.tsx b/plugins/search/src/components/SearchResult/SearchResult.tsx
index d6ca9fd968..a62dddb924 100644
--- a/plugins/search/src/components/SearchResult/SearchResult.tsx
+++ b/plugins/search/src/components/SearchResult/SearchResult.tsx
@@ -21,7 +21,7 @@ import {
} from '@backstage/core-components';
import { SearchResult } from '@backstage/plugin-search-common';
import React from 'react';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
type Props = {
children: (results: { results: SearchResult[] }) => JSX.Element;
diff --git a/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx b/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx
index f24a73d63e..b1cad8d748 100644
--- a/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx
+++ b/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx
@@ -18,11 +18,11 @@ import { renderInTestApp } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
import { SearchResultPager } from './SearchResultPager';
-jest.mock('../SearchContext', () => ({
- ...jest.requireActual('../SearchContext'),
+jest.mock('@backstage/plugin-search-react', () => ({
+ ...jest.requireActual('@backstage/plugin-search-react'),
useSearch: jest.fn().mockReturnValue({
result: {},
}),
diff --git a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx
index 12f07530ef..6f4c8628a6 100644
--- a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx
+++ b/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx
@@ -18,7 +18,7 @@ import { Button, makeStyles } from '@material-ui/core';
import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';
import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';
import React from 'react';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
const useStyles = makeStyles(theme => ({
root: {
diff --git a/plugins/search/src/components/SearchTracker/SearchTracker.tsx b/plugins/search/src/components/SearchTracker/SearchTracker.tsx
index b9da9b5560..35cfa1ec38 100644
--- a/plugins/search/src/components/SearchTracker/SearchTracker.tsx
+++ b/plugins/search/src/components/SearchTracker/SearchTracker.tsx
@@ -16,7 +16,7 @@
import React, { useEffect } from 'react';
import { useAnalytics } from '@backstage/core-plugin-api';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
/**
* Capture search event on term change.
diff --git a/plugins/search/src/components/SearchType/SearchType.Accordion.test.tsx b/plugins/search/src/components/SearchType/SearchType.Accordion.test.tsx
index a62d061663..da1cae46b9 100644
--- a/plugins/search/src/components/SearchType/SearchType.Accordion.test.tsx
+++ b/plugins/search/src/components/SearchType/SearchType.Accordion.test.tsx
@@ -15,29 +15,30 @@
*/
import React from 'react';
-import { ApiProvider } from '@backstage/core-app-api';
-import { TestApiRegistry } from '@backstage/test-utils';
+import { TestApiProvider } from '@backstage/test-utils';
import { act, render } from '@testing-library/react';
import user from '@testing-library/user-event';
-
-import { searchApiRef } from '../../apis';
-import { SearchContext, SearchContextProvider } from '../SearchContext';
+import {
+ searchApiRef,
+ SearchContextProvider,
+} from '@backstage/plugin-search-react';
import { SearchType } from './SearchType';
+const setTypesMock = jest.fn();
+const setPageCursorMock = jest.fn();
+
+jest.mock('@backstage/plugin-search-react', () => ({
+ ...jest.requireActual('@backstage/plugin-search-react'),
+ useSearch: jest.fn().mockReturnValue({
+ types: [],
+ setTypes: (types: any) => setTypesMock(types),
+ pageCursor: '',
+ setPageCursor: (pageCursor: any) => setPageCursorMock(pageCursor),
+ }),
+}));
+
describe('SearchType.Accordion', () => {
const query = jest.fn();
- const mockApis = TestApiRegistry.from([searchApiRef, { query }]);
-
- const contextSpy = {
- result: { loading: false, value: { results: [] } },
- term: '',
- types: [],
- filters: {},
- setTerm: jest.fn(),
- setTypes: jest.fn(),
- setFilters: jest.fn(),
- setPageCursor: jest.fn(),
- };
const expectedLabel = 'Expected Label';
const expectedType = {
@@ -50,17 +51,19 @@ describe('SearchType.Accordion', () => {
query.mockResolvedValue({ results: [] });
});
- afterEach(() => {
- jest.resetAllMocks();
- });
+ const Wrapper = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+ {children}
+
+ );
+ };
it('should render as expected', async () => {
const { getByText } = render(
-
-
-
-
- ,
+
+
+ ,
);
// The given label should be rendered.
@@ -80,49 +83,49 @@ describe('SearchType.Accordion', () => {
it('should set entire types array when a type is selected', async () => {
const { getByText } = render(
-
+
- ,
+ ,
);
await user.click(getByText(expectedType.name));
- expect(contextSpy.setTypes).toHaveBeenCalledWith([expectedType.value]);
+ expect(setTypesMock).toHaveBeenCalledWith([expectedType.value]);
});
it('should reset types array when all is selected', async () => {
const { getByText } = render(
-
+
- ,
+ ,
);
await user.click(getByText('All'));
- expect(contextSpy.setTypes).toHaveBeenCalledWith([]);
+ expect(setTypesMock).toHaveBeenCalledWith([]);
});
it('should reset page cursor when a new type is selected', async () => {
const { getByText } = render(
-
+
- ,
+ ,
);
await user.click(getByText(expectedType.name));
- expect(contextSpy.setPageCursor).toHaveBeenCalledWith(undefined);
+ expect(setPageCursorMock).toHaveBeenCalledWith(undefined);
});
it('should collapse when a new type is selected', async () => {
const { getByText, queryByText } = render(
-
+
- ,
+ ,
);
await user.click(getByText(expectedType.name));
diff --git a/plugins/search/src/components/SearchType/SearchType.Accordion.tsx b/plugins/search/src/components/SearchType/SearchType.Accordion.tsx
index 57e6609bab..49f5cf74ca 100644
--- a/plugins/search/src/components/SearchType/SearchType.Accordion.tsx
+++ b/plugins/search/src/components/SearchType/SearchType.Accordion.tsx
@@ -15,7 +15,7 @@
*/
import React, { cloneElement, Fragment, useEffect, useState } from 'react';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
import {
Accordion,
AccordionSummary,
diff --git a/plugins/search/src/components/SearchType/SearchType.Tabs.test.tsx b/plugins/search/src/components/SearchType/SearchType.Tabs.test.tsx
index 2886b63ae7..16df3a8f65 100644
--- a/plugins/search/src/components/SearchType/SearchType.Tabs.test.tsx
+++ b/plugins/search/src/components/SearchType/SearchType.Tabs.test.tsx
@@ -15,50 +15,49 @@
*/
import React from 'react';
-import { ApiProvider } from '@backstage/core-app-api';
-import { TestApiRegistry } from '@backstage/test-utils';
+import { TestApiProvider } from '@backstage/test-utils';
import { act, render } from '@testing-library/react';
import user from '@testing-library/user-event';
-
-import { searchApiRef } from '../../apis';
-import { SearchContext, SearchContextProvider } from '../SearchContext';
+import {
+ SearchContextProvider,
+ searchApiRef,
+} from '@backstage/plugin-search-react';
import { SearchType } from './SearchType';
-describe('SearchType.Tabs', () => {
- const query = jest.fn();
- const mockApis = TestApiRegistry.from([searchApiRef, { query }]);
+const setTypesMock = jest.fn();
+const setPageCursorMock = jest.fn();
- const contextSpy = {
- result: { loading: false, value: { results: [] } },
- term: '',
+jest.mock('@backstage/plugin-search-react', () => ({
+ ...jest.requireActual('@backstage/plugin-search-react'),
+ useSearch: jest.fn().mockReturnValue({
types: [],
- filters: {},
- setTerm: jest.fn(),
- setTypes: jest.fn(),
- setFilters: jest.fn(),
- setPageCursor: jest.fn(),
- };
+ setTypes: (types: any) => setTypesMock(types),
+ pageCursor: '',
+ setPageCursor: (pageCursor: any) => setPageCursorMock(pageCursor),
+ }),
+}));
+
+describe('SearchType.Tabs', () => {
+ const query = jest.fn().mockResolvedValue({});
const expectedType = {
value: 'expected-type',
name: 'Expected Type',
};
- beforeEach(() => {
- query.mockResolvedValue({ results: [] });
- });
-
- afterEach(() => {
- jest.resetAllMocks();
- });
+ const Wrapper = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+ {children}
+
+ );
+ };
it('should render as expected', async () => {
const { getByText } = render(
-
-
-
-
- ,
+
+
+ ,
);
// The default "all" type should be rendered.
@@ -72,40 +71,40 @@ describe('SearchType.Tabs', () => {
it('should set entire types array when a type is selected', async () => {
const { getByText } = render(
-
+
- ,
+ ,
);
await user.click(getByText(expectedType.name));
- expect(contextSpy.setTypes).toHaveBeenCalledWith([expectedType.value]);
+ expect(setTypesMock).toHaveBeenCalledWith([expectedType.value]);
});
it('should reset types array when all is selected', async () => {
const { getByText } = render(
-
+
- ,
+ ,
);
await user.click(getByText('All'));
- expect(contextSpy.setTypes).toHaveBeenCalledWith([]);
+ expect(setTypesMock).toHaveBeenCalledWith([]);
});
it('should reset page cursor when a new type is selected', async () => {
const { getByText } = render(
-
+
- ,
+ ,
);
await user.click(getByText(expectedType.name));
- expect(contextSpy.setPageCursor).toHaveBeenCalledWith(undefined);
+ expect(setPageCursorMock).toHaveBeenCalledWith(undefined);
});
});
diff --git a/plugins/search/src/components/SearchType/SearchType.Tabs.tsx b/plugins/search/src/components/SearchType/SearchType.Tabs.tsx
index 09797ae8f5..fc0380e23a 100644
--- a/plugins/search/src/components/SearchType/SearchType.Tabs.tsx
+++ b/plugins/search/src/components/SearchType/SearchType.Tabs.tsx
@@ -15,7 +15,7 @@
*/
import React, { useEffect } from 'react';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
import { BackstageTheme } from '@backstage/theme';
import { makeStyles, Tab, Tabs } from '@material-ui/core';
diff --git a/plugins/search/src/components/SearchType/SearchType.test.tsx b/plugins/search/src/components/SearchType/SearchType.test.tsx
index 94f6cf716c..a80782921f 100644
--- a/plugins/search/src/components/SearchType/SearchType.test.tsx
+++ b/plugins/search/src/components/SearchType/SearchType.test.tsx
@@ -18,7 +18,7 @@ import { useApi } from '@backstage/core-plugin-api';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
-import { SearchContextProvider } from '../SearchContext';
+import { SearchContextProvider } from '@backstage/plugin-search-react';
import { SearchType } from './SearchType';
jest.mock('@backstage/core-plugin-api', () => ({
diff --git a/plugins/search/src/components/SearchType/SearchType.tsx b/plugins/search/src/components/SearchType/SearchType.tsx
index ba20e1db5d..79c3dda2b9 100644
--- a/plugins/search/src/components/SearchType/SearchType.tsx
+++ b/plugins/search/src/components/SearchType/SearchType.tsx
@@ -30,7 +30,7 @@ import {
SearchTypeAccordionProps,
} from './SearchType.Accordion';
import { SearchTypeTabs, SearchTypeTabsProps } from './SearchType.Tabs';
-import { useSearch } from '../SearchContext';
+import { useSearch } from '@backstage/plugin-search-react';
const useStyles = makeStyles(theme => ({
label: {
diff --git a/plugins/search/src/index.ts b/plugins/search/src/index.ts
index bfffb9e84c..dccb2ce835 100644
--- a/plugins/search/src/index.ts
+++ b/plugins/search/src/index.ts
@@ -20,9 +20,6 @@
* @packageDocumentation
*/
-export { searchApiRef } from './apis';
-export type { SearchApi } from './apis';
-
export { Filters, FiltersButton } from './components/Filters';
export type { FiltersState } from './components/Filters';
export type { HomePageSearchBarProps } from './components/HomePageComponent';
@@ -31,8 +28,6 @@ export type {
SearchBarBaseProps,
SearchBarProps,
} from './components/SearchBar';
-export { SearchContextProvider, useSearch } from './components/SearchContext';
-export type { SearchContextState } from './components/SearchContext';
export { SearchFilter, SearchFilterNext } from './components/SearchFilter';
export type {
SearchAutocompleteFilterProps,
diff --git a/plugins/search/src/plugin.ts b/plugins/search/src/plugin.ts
index 9dda2a84bb..96e7bc1eed 100644
--- a/plugins/search/src/plugin.ts
+++ b/plugins/search/src/plugin.ts
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-import { SearchClient, searchApiRef } from './apis';
+import { SearchClient } from './apis';
+import { searchApiRef } from '@backstage/plugin-search-react';
import {
createApiFactory,
createPlugin,