Change <SearchType> design to follow Figma
Signed-off-by: Oliver Sand <oliver.sand@sda-se.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-search': patch
|
||||
---
|
||||
|
||||
Change `<SearchType>` design to follow Figma and be similar to existing multi
|
||||
selects in Backstage.
|
||||
@@ -14,13 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { screen, render, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { SearchType } from './SearchType';
|
||||
|
||||
import { SearchContextProvider } from '../SearchContext';
|
||||
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 { SearchType } from './SearchType';
|
||||
|
||||
jest.mock('@backstage/core-plugin-api', () => ({
|
||||
...jest.requireActual('@backstage/core-plugin-api'),
|
||||
@@ -101,9 +100,6 @@ describe('SearchType', () => {
|
||||
expect(
|
||||
screen.getByRole('option', { name: values[1] }),
|
||||
).not.toHaveAttribute('aria-selected');
|
||||
expect(screen.getByRole('option', { name: 'All' })).not.toHaveAttribute(
|
||||
'aria-selected',
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders correctly based on type filter defaultValue', async () => {
|
||||
@@ -130,9 +126,6 @@ describe('SearchType', () => {
|
||||
expect(
|
||||
screen.getByRole('option', { name: values[1] }),
|
||||
).not.toHaveAttribute('aria-selected');
|
||||
expect(screen.getByRole('option', { name: 'All' })).not.toHaveAttribute(
|
||||
'aria-selected',
|
||||
);
|
||||
});
|
||||
|
||||
it('Selecting a value sets type filter state', async () => {
|
||||
@@ -169,19 +162,9 @@ describe('SearchType', () => {
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('listbox')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
userEvent.click(screen.getByRole('option', { name: 'All' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(query).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
types: [],
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Selecting a value maintains unrelated filter state, selecting All defaults to default empty state', async () => {
|
||||
it('Selecting none defaults to empty state', async () => {
|
||||
render(
|
||||
<SearchContextProvider
|
||||
initialState={{
|
||||
@@ -221,7 +204,7 @@ describe('SearchType', () => {
|
||||
expect(screen.getByRole('listbox')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
userEvent.click(screen.getByRole('option', { name: 'All' }));
|
||||
userEvent.click(screen.getByRole('option', { name: values[0] }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(query).toHaveBeenLastCalledWith(expect.objectContaining([]));
|
||||
|
||||
@@ -13,30 +13,33 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useSearch } from '../SearchContext';
|
||||
import { useEffectOnce } from 'react-use';
|
||||
import React, { ChangeEvent } from 'react';
|
||||
import {
|
||||
Checkbox,
|
||||
Chip,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
MenuItem,
|
||||
Select,
|
||||
} from '@material-ui/core';
|
||||
import React, { ChangeEvent } from 'react';
|
||||
import { useEffectOnce } from 'react-use';
|
||||
import { useSearch } from '../SearchContext';
|
||||
|
||||
const useStyles = makeStyles({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
label: {
|
||||
textTransform: 'capitalize',
|
||||
},
|
||||
chips: {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
marginTop: theme.spacing(1),
|
||||
},
|
||||
chip: {
|
||||
margin: 2,
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
export type SearchTypeProps = {
|
||||
className?: string;
|
||||
@@ -55,20 +58,18 @@ const SearchType = ({
|
||||
const { types, setTypes } = useSearch();
|
||||
|
||||
useEffectOnce(() => {
|
||||
if (defaultValue && Array.isArray(defaultValue)) {
|
||||
setTypes(defaultValue);
|
||||
} else if (defaultValue) {
|
||||
setTypes([defaultValue]);
|
||||
if (!types.length) {
|
||||
if (defaultValue && Array.isArray(defaultValue)) {
|
||||
setTypes(defaultValue);
|
||||
} else if (defaultValue) {
|
||||
setTypes([defaultValue]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const handleChange = (e: ChangeEvent<{ value: unknown }>) => {
|
||||
const value = e.target.value as string[];
|
||||
if (!value || value.includes('*')) {
|
||||
setTypes([]);
|
||||
} else {
|
||||
setTypes(value.filter(it => it !== 'All'));
|
||||
}
|
||||
setTypes(value as string[]);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -84,22 +85,26 @@ const SearchType = ({
|
||||
<Select
|
||||
multiple
|
||||
variant="outlined"
|
||||
value={types.length ? types : ['All']}
|
||||
value={types}
|
||||
onChange={handleChange}
|
||||
placeholder="All Results"
|
||||
renderValue={selected => (
|
||||
<div className={classes.chips}>
|
||||
{(selected as string[]).map(value => (
|
||||
<Chip key={value} label={value} className={classes.chip} />
|
||||
<Chip
|
||||
key={value}
|
||||
label={value}
|
||||
className={classes.chip}
|
||||
size="small"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<MenuItem value="*">
|
||||
<em>All</em>
|
||||
</MenuItem>
|
||||
{values.map((value: string) => (
|
||||
<MenuItem key={value} value={value}>
|
||||
{value}
|
||||
<Checkbox checked={types.indexOf(value) > -1} />
|
||||
<ListItemText primary={value} />
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
Reference in New Issue
Block a user