Merge pull request #8300 from backstage/feat/search-bar-clear-button
[SearchBar] Add a new optional clear button prop
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-search': patch
|
||||
---
|
||||
|
||||
Add a new optional clearButton property to the SearchBar component. The default value for this new property is true.
|
||||
@@ -4,9 +4,9 @@ title: Search Engines
|
||||
description: Choosing and configuring your search engine for Backstage
|
||||
---
|
||||
|
||||
Backstage supports 2 search engines by default, an in-memory engine called Lunr
|
||||
and ElasticSearch. You can configure your own search engines by implementing the
|
||||
provided interface as mentioned in the
|
||||
Backstage supports 3 search engines by default, an in-memory engine called Lunr,
|
||||
ElasticSearch and Postgres. You can configure your own search engines by
|
||||
implementing the provided interface as mentioned in the
|
||||
[search backend documentation.](./getting-started.md#Backend)
|
||||
|
||||
Provided search engine implementations have their own way of constructing
|
||||
|
||||
@@ -84,6 +84,7 @@ export const SearchBar: ({
|
||||
className,
|
||||
debounceTime,
|
||||
placeholder,
|
||||
clearButton,
|
||||
}: Props) => JSX.Element;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "SearchBarNext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
@@ -94,11 +95,13 @@ export const SearchBarNext: ({
|
||||
className,
|
||||
debounceTime,
|
||||
placeholder,
|
||||
clearButton,
|
||||
}: {
|
||||
autoFocus?: boolean | undefined;
|
||||
className?: string | undefined;
|
||||
debounceTime?: number | undefined;
|
||||
placeholder?: string | undefined;
|
||||
clearButton?: boolean | undefined;
|
||||
}) => JSX.Element;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Paper, Grid } from '@material-ui/core';
|
||||
import { Paper, Grid, makeStyles } from '@material-ui/core';
|
||||
import { SearchBar, SearchContext } from '../index';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
|
||||
@@ -81,3 +81,48 @@ export const Focused = () => {
|
||||
</MemoryRouter>
|
||||
);
|
||||
};
|
||||
|
||||
export const WithoutClearButton = () => {
|
||||
return (
|
||||
<MemoryRouter>
|
||||
{/* @ts-ignore (defaultValue requires more than what is used here) */}
|
||||
<SearchContext.Provider value={defaultValue}>
|
||||
<Grid container direction="row">
|
||||
<Grid item xs={12}>
|
||||
<Paper style={{ padding: '8px 0' }}>
|
||||
<SearchBar clearButton={false} />
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</SearchContext.Provider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
};
|
||||
|
||||
const useStyles = makeStyles({
|
||||
search: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
padding: '8px 0',
|
||||
borderRadius: '50px',
|
||||
margin: 'auto',
|
||||
},
|
||||
});
|
||||
|
||||
export const CustomStyles = () => {
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<MemoryRouter>
|
||||
{/* @ts-ignore (defaultValue requires more than what is used here) */}
|
||||
<SearchContext.Provider value={defaultValue}>
|
||||
<Grid container direction="row">
|
||||
<Grid item xs={12}>
|
||||
<Paper className={classes.search}>
|
||||
<SearchBar />
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</SearchContext.Provider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -149,6 +149,20 @@ describe('SearchBar', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Should not show clear button', async () => {
|
||||
render(
|
||||
<ApiProvider apis={apiRegistry}>
|
||||
<SearchContextProvider initialState={{ ...initialState, term }}>
|
||||
<SearchBar clearButton={false} />
|
||||
</SearchContextProvider>
|
||||
</ApiProvider>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.queryByRole('button', { name: 'Clear' }),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Adheres to provided debounceTime', async () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ type PresenterProps = {
|
||||
className?: string;
|
||||
placeholder?: string;
|
||||
autoFocus?: boolean;
|
||||
clearButton?: boolean;
|
||||
};
|
||||
|
||||
export const SearchBarBase = ({
|
||||
@@ -40,6 +41,7 @@ export const SearchBarBase = ({
|
||||
onSubmit,
|
||||
className,
|
||||
placeholder: overridePlaceholder,
|
||||
clearButton = true,
|
||||
}: PresenterProps) => {
|
||||
const configApi = useApi(configApiRef);
|
||||
|
||||
@@ -79,11 +81,13 @@ export const SearchBarBase = ({
|
||||
</InputAdornment>
|
||||
}
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton aria-label="Clear" onClick={handleClear}>
|
||||
<ClearButton />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
clearButton && (
|
||||
<InputAdornment position="end">
|
||||
<IconButton aria-label="Clear" onClick={handleClear}>
|
||||
<ClearButton />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
)
|
||||
}
|
||||
{...(className && { className })}
|
||||
{...(onSubmit && { onKeyDown })}
|
||||
@@ -96,6 +100,7 @@ type Props = {
|
||||
className?: string;
|
||||
debounceTime?: number;
|
||||
placeholder?: string;
|
||||
clearButton?: boolean;
|
||||
};
|
||||
|
||||
export const SearchBar = ({
|
||||
@@ -103,6 +108,7 @@ export const SearchBar = ({
|
||||
className,
|
||||
debounceTime = 0,
|
||||
placeholder,
|
||||
clearButton = true,
|
||||
}: Props) => {
|
||||
const { term, setTerm } = useSearch();
|
||||
const [value, setValue] = useState<string>(term);
|
||||
@@ -129,6 +135,7 @@ export const SearchBar = ({
|
||||
onChange={handleQuery}
|
||||
onClear={handleClear}
|
||||
placeholder={placeholder}
|
||||
clearButton={clearButton}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user