Merge pull request #26060 from joshjung/jjung/custom-modal-search-items

Add ability to customize SearchResult children via SidebarSearchModal component
This commit is contained in:
Camila Belo
2024-09-11 11:51:48 +02:00
committed by GitHub
8 changed files with 107 additions and 22 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ This search plugin is primarily responsible for the following:
- Providing a `<SearchPage />` routable extension.
- Exposing various search-related components (like `<SearchModal />`,
`<SidebarSearch />`, etc), which can be composed by a Backstage App or by
`<SidebarSearch />`, etc.), which can be composed by a Backstage App or by
other Backstage Plugins to power search experiences of all kinds.
Don't forget, a lot of functionality is available in web libraries and backend plugins:
+10 -3
View File
@@ -12,6 +12,7 @@ import { default as React_2 } from 'react';
import { ReactNode } from 'react';
import { RouteRef } from '@backstage/core-plugin-api';
import { SearchBarBaseProps } from '@backstage/plugin-search-react';
import { SearchResultSet } from '@backstage/plugin-search-common';
// @public (undocumented)
export const HomePageSearchBar: (
@@ -31,6 +32,9 @@ export const SearchModal: (props: SearchModalProps) => React_2.JSX.Element;
// @public (undocumented)
export interface SearchModalChildrenProps {
resultItemComponents?:
| ReactNode
| ((resultSet: SearchResultSet) => JSX.Element);
toggleModal: () => void;
}
@@ -39,6 +43,7 @@ export interface SearchModalProps {
children?: (props: SearchModalChildrenProps) => JSX.Element;
hidden?: boolean;
open?: boolean;
resultItemComponents?: SearchModalChildrenProps['resultItemComponents'];
toggleModal: () => void;
}
@@ -118,12 +123,14 @@ export const SidebarSearch: (props: SidebarSearchProps) => React_2.JSX.Element;
// @public (undocumented)
export const SidebarSearchModal: (
props: SidebarSearchModalProps,
) => JSX_2.Element;
) => JSX.Element | null;
// @public
export type SidebarSearchModalProps = {
export type SidebarSearchModalProps = Pick<
SearchModalProps,
'children' | 'resultItemComponents'
> & {
icon?: IconComponent;
children?: (props: SearchModalChildrenProps) => JSX.Element;
};
// @public
@@ -34,10 +34,11 @@ import IconButton from '@material-ui/core/IconButton';
import { makeStyles } from '@material-ui/core/styles';
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
import CloseIcon from '@material-ui/icons/Close';
import React, { useCallback, useEffect, useRef } from 'react';
import React, { ReactNode, useCallback, useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { rootRouteRef } from '../../plugin';
import { SearchResultSet } from '@backstage/plugin-search-common';
/**
* @public
@@ -47,6 +48,13 @@ export interface SearchModalChildrenProps {
* A function that should be invoked when navigating away from the modal.
*/
toggleModal: () => void;
/**
* Ability to provide custom components to render the result items
*/
resultItemComponents?:
| ReactNode
| ((resultSet: SearchResultSet) => JSX.Element);
}
/**
@@ -74,6 +82,11 @@ export interface SearchModalProps {
* place of the default.
*/
children?: (props: SearchModalChildrenProps) => JSX.Element;
/**
* Optional ability to pass in result item component renderers.
*/
resultItemComponents?: SearchModalChildrenProps['resultItemComponents'];
}
const useStyles = makeStyles(theme => ({
@@ -100,7 +113,10 @@ const useStyles = makeStyles(theme => ({
viewResultsLink: { verticalAlign: '0.5em' },
}));
export const Modal = ({ toggleModal }: SearchModalChildrenProps) => {
export const Modal = ({
toggleModal,
resultItemComponents,
}: SearchModalChildrenProps) => {
const classes = useStyles();
const navigate = useNavigate();
const { transitions } = useTheme();
@@ -163,7 +179,9 @@ export const Modal = ({ toggleModal }: SearchModalChildrenProps) => {
<SearchResult
onClick={handleSearchResultClick}
onKeyDown={handleSearchResultClick}
/>
>
{resultItemComponents}
</SearchResult>
</DialogContent>
<DialogActions className={classes.dialogActionsContainer}>
<Grid container direction="row">
@@ -180,7 +198,13 @@ export const Modal = ({ toggleModal }: SearchModalChildrenProps) => {
* @public
*/
export const SearchModal = (props: SearchModalProps) => {
const { open = true, hidden, toggleModal, children } = props;
const {
open = true,
hidden,
toggleModal,
children,
resultItemComponents,
} = props;
const classes = useStyles();
@@ -199,8 +223,15 @@ export const SearchModal = (props: SearchModalProps) => {
>
{open && (
<SearchContextProvider inheritParentContextIfAvailable>
{(children && children({ toggleModal })) ?? (
<Modal toggleModal={toggleModal} />
{(children &&
children({
toggleModal,
resultItemComponents: resultItemComponents || [],
})) ?? (
<Modal
toggleModal={toggleModal}
resultItemComponents={resultItemComponents}
/>
)}
</SearchContextProvider>
)}
@@ -19,8 +19,9 @@ import { useSearch } from '@backstage/plugin-search-react';
import Tab from '@material-ui/core/Tab';
import Tabs from '@material-ui/core/Tabs';
import { makeStyles } from '@material-ui/core/styles';
import { Theme } from '@material-ui/core/styles';
const useStyles = makeStyles(theme => ({
const useStyles = makeStyles((theme: Theme) => ({
tabs: {
borderBottom: `1px solid ${theme.palette.textVerySubtle}`,
},
@@ -19,7 +19,7 @@ import { SidebarItem } from '@backstage/core-components';
import { IconComponent } from '@backstage/core-plugin-api';
import {
SearchModal,
SearchModalChildrenProps,
SearchModalProps,
SearchModalProvider,
useSearchModal,
} from '../SearchModal';
@@ -29,9 +29,11 @@ import {
*
* @public
*/
export type SidebarSearchModalProps = {
export type SidebarSearchModalProps = Pick<
SearchModalProps,
'children' | 'resultItemComponents'
> & {
icon?: IconComponent;
children?: (props: SearchModalChildrenProps) => JSX.Element;
};
const SidebarSearchModalContent = (props: SidebarSearchModalProps) => {
@@ -49,6 +51,7 @@ const SidebarSearchModalContent = (props: SidebarSearchModalProps) => {
<SearchModal
{...state}
toggleModal={toggleModal}
resultItemComponents={props.resultItemComponents}
children={props.children}
/>
</>
+4 -1
View File
@@ -25,6 +25,7 @@ import {
createComponentExtension,
fetchApiRef,
} from '@backstage/core-plugin-api';
import { SidebarSearchModalProps } from './components/SidebarSearchModal';
export const rootRouteRef = createRouteRef({
id: 'search',
@@ -63,7 +64,9 @@ export const SearchPage = searchPlugin.provide(
/**
* @public
*/
export const SidebarSearchModal = searchPlugin.provide(
export const SidebarSearchModal = searchPlugin.provide<
(props: SidebarSearchModalProps) => JSX.Element | null
>(
createComponentExtension({
name: 'SidebarSearchModal',
component: {