Merge branch 'master' into rugvip/test-port
This commit is contained in:
@@ -1,5 +1,17 @@
|
||||
# @backstage/plugin-search
|
||||
|
||||
## 0.4.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a125278b81: Refactor out the deprecated path and icon from RouteRefs
|
||||
- 704b267e1c: Smaller UX improvements to search components such as optional autoFocus prop to SearchBar components, decreased debounce value and closing modal on link click of SearchModal, terminology updates of SearchResultPager.
|
||||
- Updated dependencies
|
||||
- @backstage/catalog-model@0.9.7
|
||||
- @backstage/plugin-catalog-react@0.6.4
|
||||
- @backstage/core-components@0.7.4
|
||||
- @backstage/core-plugin-api@0.2.0
|
||||
|
||||
## 0.4.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -80,6 +80,7 @@ export const searchApiRef: ApiRef<SearchApi>;
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const SearchBar: ({
|
||||
autoFocus,
|
||||
className,
|
||||
debounceTime,
|
||||
placeholder,
|
||||
@@ -89,10 +90,12 @@ export const SearchBar: ({
|
||||
//
|
||||
// @public @deprecated (undocumented)
|
||||
export const SearchBarNext: ({
|
||||
autoFocus,
|
||||
className,
|
||||
debounceTime,
|
||||
placeholder,
|
||||
}: {
|
||||
autoFocus?: boolean | undefined;
|
||||
className?: string | undefined;
|
||||
debounceTime?: number | undefined;
|
||||
placeholder?: string | undefined;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/plugin-search",
|
||||
"description": "The Backstage plugin that provides your backstage app with search",
|
||||
"version": "0.4.17",
|
||||
"version": "0.4.18",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -30,12 +30,12 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.9.6",
|
||||
"@backstage/catalog-model": "^0.9.7",
|
||||
"@backstage/config": "^0.1.11",
|
||||
"@backstage/core-components": "^0.7.3",
|
||||
"@backstage/core-plugin-api": "^0.1.13",
|
||||
"@backstage/core-components": "^0.7.4",
|
||||
"@backstage/core-plugin-api": "^0.2.0",
|
||||
"@backstage/errors": "^0.1.4",
|
||||
"@backstage/plugin-catalog-react": "^0.6.3",
|
||||
"@backstage/plugin-catalog-react": "^0.6.4",
|
||||
"@backstage/search-common": "^0.2.1",
|
||||
"@backstage/theme": "^0.2.13",
|
||||
"@backstage/types": "^0.1.1",
|
||||
@@ -51,10 +51,10 @@
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.8.2",
|
||||
"@backstage/core-app-api": "^0.1.20",
|
||||
"@backstage/dev-utils": "^0.2.12",
|
||||
"@backstage/test-utils": "^0.1.21",
|
||||
"@backstage/cli": "^0.9.0",
|
||||
"@backstage/core-app-api": "^0.1.22",
|
||||
"@backstage/dev-utils": "^0.2.13",
|
||||
"@backstage/test-utils": "^0.1.22",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/react-hooks": "^7.0.2",
|
||||
|
||||
@@ -62,3 +62,22 @@ export const CustomPlaceholder = () => {
|
||||
</MemoryRouter>
|
||||
);
|
||||
};
|
||||
|
||||
export const Focused = () => {
|
||||
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' }}>
|
||||
{/* decision up to adopter, read https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md#no-autofocus */}
|
||||
{/* eslint-disable-next-line jsx-a11y/no-autofocus */}
|
||||
<SearchBar autoFocus />
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</SearchContext.Provider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -30,9 +30,11 @@ type PresenterProps = {
|
||||
onSubmit?: () => void;
|
||||
className?: string;
|
||||
placeholder?: string;
|
||||
autoFocus?: boolean;
|
||||
};
|
||||
|
||||
export const SearchBarBase = ({
|
||||
autoFocus,
|
||||
value,
|
||||
onChange,
|
||||
onSubmit,
|
||||
@@ -60,6 +62,9 @@ export const SearchBarBase = ({
|
||||
|
||||
return (
|
||||
<InputBase
|
||||
// decision up to adopter, read https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md#no-autofocus
|
||||
// eslint-disable-next-line jsx-a11y/no-autofocus
|
||||
autoFocus={autoFocus}
|
||||
data-testid="search-bar-next"
|
||||
fullWidth
|
||||
placeholder={placeholder}
|
||||
@@ -87,12 +92,14 @@ export const SearchBarBase = ({
|
||||
};
|
||||
|
||||
type Props = {
|
||||
autoFocus?: boolean;
|
||||
className?: string;
|
||||
debounceTime?: number;
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export const SearchBar = ({
|
||||
autoFocus,
|
||||
className,
|
||||
debounceTime = 0,
|
||||
placeholder,
|
||||
@@ -114,6 +121,9 @@ export const SearchBar = ({
|
||||
|
||||
return (
|
||||
<SearchBarBase
|
||||
// decision up to adopter, read https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md#no-autofocus
|
||||
// eslint-disable-next-line jsx-a11y/no-autofocus
|
||||
autoFocus={autoFocus}
|
||||
className={className}
|
||||
value={value}
|
||||
onChange={handleQuery}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useState, ComponentType } from 'react';
|
||||
import { Button } from '@material-ui/core';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { SearchModal } from '../index';
|
||||
import { searchApiRef } from '../../apis';
|
||||
import { rootRouteRef } from '../../plugin';
|
||||
|
||||
export default {
|
||||
title: 'Plugins/Search/SearchModal',
|
||||
component: SearchModal,
|
||||
decorators: [
|
||||
(Story: ComponentType<{}>) =>
|
||||
wrapInTestApp(
|
||||
<>
|
||||
<Story />
|
||||
</>,
|
||||
{ mountedRoutes: { '/search': rootRouteRef } },
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
const mockSearchApi = {
|
||||
query: () =>
|
||||
Promise.resolve({
|
||||
results: [
|
||||
{
|
||||
type: 'custom-result-item',
|
||||
document: {
|
||||
location: 'search/search-result-1',
|
||||
title: 'Search Result 1',
|
||||
text: 'some text from the search result',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'no-custom-result-item',
|
||||
document: {
|
||||
location: 'search/search-result-2',
|
||||
title: 'Search Result 2',
|
||||
text: 'some text from the search result',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'no-custom-result-item',
|
||||
document: {
|
||||
location: 'search/search-result-3',
|
||||
title: 'Search Result 3',
|
||||
text: 'some text from the search result',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
};
|
||||
|
||||
const apiRegistry = () => ApiRegistry.from([[searchApiRef, mockSearchApi]]);
|
||||
|
||||
export const Default = () => {
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const toggleModal = (): void => setOpen(prevState => !prevState);
|
||||
|
||||
return (
|
||||
<ApiProvider apis={apiRegistry()}>
|
||||
<Button variant="contained" color="primary" onClick={toggleModal}>
|
||||
Toggle Search Modal
|
||||
</Button>
|
||||
<SearchModal open={open} toggleModal={toggleModal} />
|
||||
</ApiProvider>
|
||||
);
|
||||
};
|
||||
@@ -68,7 +68,7 @@ export const Modal = ({ open = true, toggleModal }: SearchModalProps) => {
|
||||
setValue(prevValue => (prevValue !== term ? term : prevValue));
|
||||
}, [term]);
|
||||
|
||||
useDebounce(() => setTerm(value), 1000, [value]);
|
||||
useDebounce(() => setTerm(value), 500, [value]);
|
||||
|
||||
const handleQuery = (newValue: string) => {
|
||||
setValue(newValue);
|
||||
@@ -114,7 +114,10 @@ export const Modal = ({ open = true, toggleModal }: SearchModalProps) => {
|
||||
alignItems="center"
|
||||
>
|
||||
<Grid item>
|
||||
<Link to={`${getSearchLink()}?query=${value}`}>
|
||||
<Link
|
||||
onClick={toggleModal}
|
||||
to={`${getSearchLink()}?query=${value}`}
|
||||
>
|
||||
<span className={classes.viewResultsLink}>View Full Results</span>
|
||||
<Launch color="primary" />
|
||||
</Link>
|
||||
|
||||
@@ -25,7 +25,7 @@ const useStyles = makeStyles(theme => ({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
gap: theme.spacing(2),
|
||||
margin: theme.spacing(4),
|
||||
margin: theme.spacing(2, 0),
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -44,9 +44,8 @@ export const SearchResultPager = () => {
|
||||
disabled={!fetchPreviousPage}
|
||||
onClick={fetchPreviousPage}
|
||||
startIcon={<ArrowBackIosIcon />}
|
||||
size="small"
|
||||
>
|
||||
Back
|
||||
Previous
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
@@ -54,7 +53,6 @@ export const SearchResultPager = () => {
|
||||
disabled={!fetchNextPage}
|
||||
onClick={fetchNextPage}
|
||||
endIcon={<ArrowForwardIosIcon />}
|
||||
size="small"
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
|
||||
@@ -26,13 +26,11 @@ import {
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '/search',
|
||||
title: 'search',
|
||||
id: 'search',
|
||||
});
|
||||
|
||||
export const rootNextRouteRef = createRouteRef({
|
||||
path: '/search-next',
|
||||
title: 'search',
|
||||
id: 'search:next',
|
||||
});
|
||||
|
||||
export const searchPlugin = createPlugin({
|
||||
|
||||
Reference in New Issue
Block a user