diff --git a/.changeset/clever-boats-clap.md b/.changeset/clever-boats-clap.md new file mode 100644 index 0000000000..6b40f05a76 --- /dev/null +++ b/.changeset/clever-boats-clap.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-search-react': minor +'@backstage/plugin-techdocs': minor +'@backstage/plugin-catalog': minor +'@backstage/plugin-search': minor +--- + +Add support for customizable icons in `SearchResultListItemBlueprint` and related components diff --git a/plugins/catalog/report-alpha.api.md b/plugins/catalog/report-alpha.api.md index 4f581add67..fde928423f 100644 --- a/plugins/catalog/report-alpha.api.md +++ b/plugins/catalog/report-alpha.api.md @@ -1165,6 +1165,7 @@ const _default: OverridableFrontendPlugin< { predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; + icon?: JSX_2.Element; }, 'search.search-result-list-item.item', {} diff --git a/plugins/catalog/src/alpha/searchResultItems.tsx b/plugins/catalog/src/alpha/searchResultItems.tsx index db8d0bfc09..1381ea0c12 100644 --- a/plugins/catalog/src/alpha/searchResultItems.tsx +++ b/plugins/catalog/src/alpha/searchResultItems.tsx @@ -15,9 +15,11 @@ */ import { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha'; +import { CatalogIcon } from '@backstage/core-components'; export const catalogSearchResultListItem = SearchResultListItemBlueprint.make({ params: { + icon: , predicate: result => result.type === 'software-catalog', component: () => import('../components/CatalogSearchResultListItem').then( diff --git a/plugins/search-react/report-alpha.api.md b/plugins/search-react/report-alpha.api.md index 59d0ed17f9..3ddcde9076 100644 --- a/plugins/search-react/report-alpha.api.md +++ b/plugins/search-react/report-alpha.api.md @@ -6,6 +6,7 @@ import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; import { ExtensionDataRef } from '@backstage/frontend-plugin-api'; +import { JSX as JSX_2 } from 'react'; import { ListItemProps } from '@material-ui/core/ListItem'; import { SearchDocument } from '@backstage/plugin-search-common'; import { SearchResult } from '@backstage/plugin-search-common'; @@ -15,6 +16,7 @@ import { TranslationRef } from '@backstage/core-plugin-api/alpha'; export type BaseSearchResultListItemProps = T & { rank?: number; result?: SearchDocument; + icon?: JSX_2.Element; } & Omit; // @alpha (undocumented) @@ -51,7 +53,7 @@ export interface SearchFilterBlueprintParams { // @alpha (undocumented) export type SearchFilterExtensionComponent = ( props: SearchFilterExtensionComponentProps, -) => JSX.Element; +) => JSX_2.Element; // @alpha (undocumented) export type SearchFilterExtensionComponentProps = { @@ -66,7 +68,7 @@ export const SearchFilterResultTypeBlueprint: ExtensionBlueprint<{ { value: string; name: string; - icon: JSX.Element; + icon: JSX_2; }, 'search.filters.result-types.type', {} @@ -79,7 +81,7 @@ export const SearchFilterResultTypeBlueprint: ExtensionBlueprint<{ { value: string; name: string; - icon: JSX.Element; + icon: JSX_2; }, 'search.filters.result-types.type', {} @@ -117,7 +119,7 @@ export type SearchResultItemExtensionComponent = < P extends BaseSearchResultListItemProps, >( props: P, -) => JSX.Element | null; +) => JSX_2.Element | null; // @alpha (undocumented) export type SearchResultItemExtensionPredicate = ( @@ -132,6 +134,7 @@ export const SearchResultListItemBlueprint: ExtensionBlueprint<{ { predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; + icon?: JSX_2.Element; }, 'search.search-result-list-item.item', {} @@ -148,6 +151,7 @@ export const SearchResultListItemBlueprint: ExtensionBlueprint<{ { predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; + icon?: JSX_2.Element; }, 'search.search-result-list-item.item', {} @@ -162,6 +166,7 @@ export interface SearchResultListItemBlueprintParams { noTrack?: boolean; }; }) => Promise; + icon?: JSX_2.Element; predicate?: SearchResultItemExtensionPredicate; } diff --git a/plugins/search-react/src/alpha/blueprints/SearchResultListItemBlueprint.tsx b/plugins/search-react/src/alpha/blueprints/SearchResultListItemBlueprint.tsx index f551b3d60c..b442246199 100644 --- a/plugins/search-react/src/alpha/blueprints/SearchResultListItemBlueprint.tsx +++ b/plugins/search-react/src/alpha/blueprints/SearchResultListItemBlueprint.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { lazy } from 'react'; +import { lazy, JSX } from 'react'; import { createExtensionBlueprint, ExtensionBoundary, @@ -42,6 +42,11 @@ export interface SearchResultListItemBlueprintParams { * Defaults to a predicate that returns true, which means it renders all sorts of results. */ predicate?: SearchResultItemExtensionPredicate; + + /** + * The icon of the result item. + */ + icon?: JSX.Element; } /** @@ -77,7 +82,7 @@ export const SearchResultListItemBlueprint = createExtensionBlueprint({ result={props.result} noTrack={config.noTrack} > - + ), diff --git a/plugins/search-react/src/alpha/blueprints/types.ts b/plugins/search-react/src/alpha/blueprints/types.ts index 56306ba681..fc44b99ad3 100644 --- a/plugins/search-react/src/alpha/blueprints/types.ts +++ b/plugins/search-react/src/alpha/blueprints/types.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { JSX } from 'react'; import { ListItemProps } from '@material-ui/core/ListItem'; import { SearchDocument, SearchResult } from '@backstage/plugin-search-common'; import { createExtensionDataRef } from '@backstage/frontend-plugin-api'; @@ -22,6 +23,7 @@ import { createExtensionDataRef } from '@backstage/frontend-plugin-api'; export type BaseSearchResultListItemProps = T & { rank?: number; result?: SearchDocument; + icon?: JSX.Element; } & Omit; /** @alpha */ @@ -40,6 +42,7 @@ export type SearchResultItemExtensionPredicate = ( export const searchResultListItemDataRef = createExtensionDataRef<{ predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; + icon?: JSX.Element; }>().with({ id: 'search.search-result-list-item.item' }); /** @alpha */ diff --git a/plugins/search/report-alpha.api.md b/plugins/search/report-alpha.api.md index 773f6c21b7..9a385c6fae 100644 --- a/plugins/search/report-alpha.api.md +++ b/plugins/search/report-alpha.api.md @@ -90,6 +90,7 @@ const _default: OverridableFrontendPlugin< { predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; + icon?: JSX_2.Element; }, 'search.search-result-list-item.item', {} @@ -104,7 +105,7 @@ const _default: OverridableFrontendPlugin< { value: string; name: string; - icon: JSX.Element; + icon: JSX_2.Element; }, 'search.filters.result-types.type', {} @@ -209,6 +210,7 @@ export const searchPage: ExtensionDefinition<{ { predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; + icon?: JSX_2.Element; }, 'search.search-result-list-item.item', {} @@ -223,7 +225,7 @@ export const searchPage: ExtensionDefinition<{ { value: string; name: string; - icon: JSX.Element; + icon: JSX_2.Element; }, 'search.filters.result-types.type', {} diff --git a/plugins/techdocs/report-alpha.api.md b/plugins/techdocs/report-alpha.api.md index 7681810d6c..1bcb53a3c1 100644 --- a/plugins/techdocs/report-alpha.api.md +++ b/plugins/techdocs/report-alpha.api.md @@ -322,6 +322,7 @@ const _default: OverridableFrontendPlugin< { predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; + icon?: JSX_2.Element; }, 'search.search-result-list-item.item', {} @@ -365,6 +366,7 @@ export const techDocsSearchResultListItemExtension: ExtensionDefinition<{ { predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; + icon?: JSX_2.Element; }, 'search.search-result-list-item.item', {} diff --git a/plugins/techdocs/src/alpha/index.tsx b/plugins/techdocs/src/alpha/index.tsx index 5b1033876a..96454600d9 100644 --- a/plugins/techdocs/src/alpha/index.tsx +++ b/plugins/techdocs/src/alpha/index.tsx @@ -55,6 +55,7 @@ import { } from '@backstage/plugin-techdocs-react'; import { useTechdocsReaderIconLinkProps } from './hooks/useTechdocsReaderIconLinkProps'; +import { DocsIcon } from '@backstage/core-components'; /** @alpha */ const techdocsEntityIconLink = EntityIconLinkBlueprint.make({ @@ -116,6 +117,7 @@ export const techDocsSearchResultListItemExtension = }, factory(originalFactory, { config }) { return originalFactory({ + icon: , predicate: result => result.type === 'techdocs', component: async () => { const { TechDocsSearchResultListItem } = await import(