Change <SearchType> design to follow Figma

Signed-off-by: Oliver Sand <oliver.sand@sda-se.com>
This commit is contained in:
Oliver Sand
2021-07-26 13:18:36 +02:00
parent 072d8209d6
commit b917365cf9
3 changed files with 38 additions and 44 deletions
+6
View File
@@ -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>