feat(search): Improve search dialog's & page's bar UI

Signed-off-by: Carlos Esteban Lopez <lcarlosesteb@vmware.com>
This commit is contained in:
Carlos Esteban Lopez
2023-03-01 16:24:49 -05:00
committed by Carlos Lopez
parent 694003a11c
commit e22f74f421
4 changed files with 98 additions and 79 deletions
@@ -37,20 +37,24 @@ import {
DialogTitle,
Grid,
makeStyles,
Paper,
} from '@material-ui/core';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
import BuildIcon from '@material-ui/icons/Build';
import CloseIcon from '@material-ui/icons/Close';
import LaunchIcon from '@material-ui/icons/Launch';
import React, { KeyboardEvent, useCallback, useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
const useStyles = makeStyles(theme => ({
dialogTitle: {
gap: theme.spacing(1),
display: 'grid',
alignItems: 'center',
gridTemplateColumns: '1fr auto',
'&> button': {
marginTop: theme.spacing(1),
},
},
container: {
borderRadius: 30,
@@ -90,7 +94,7 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
});
const handleSearchBarKeyDown = useCallback(
(e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
(e: KeyboardEvent<HTMLDivElement | HTMLTextAreaElement>) => {
if (e.key === 'Enter') {
toggleModal();
navigate(searchPagePath);
@@ -103,15 +107,13 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
<>
<DialogTitle>
<Box className={classes.dialogTitle}>
<Paper className={classes.container}>
<SearchBar
className={classes.input}
inputProps={{ ref: searchBarRef }}
onKeyDown={handleSearchBarKeyDown}
/>
</Paper>
<SearchBar
className={classes.input}
inputProps={{ ref: searchBarRef }}
onKeyDown={handleSearchBarKeyDown}
/>
<IconButton aria-label="close" onClick={() => toggleModal()}>
<IconButton aria-label="close" onClick={toggleModal}>
<CloseIcon />
</IconButton>
</Box>
@@ -186,15 +188,15 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
alignItems="center"
>
<Grid item>
<Link to={searchPagePath} onClick={toggleModal}>
<Typography
component="span"
className={classes.viewResultsLink}
>
View Full Results
</Typography>
<LaunchIcon color="primary" />
</Link>
<Button
to={searchPagePath}
onClick={toggleModal}
endIcon={<ArrowForwardIcon />}
component={Link}
color="primary"
>
View Full Results
</Button>
</Grid>
</Grid>
</Grid>
@@ -70,9 +70,7 @@ const SearchPage = () => {
<Content>
<Grid container direction="row">
<Grid item xs={12}>
<Paper className={classes.bar}>
<SearchBar debounceTime={100} />
</Paper>
<SearchBar debounceTime={100} />
</Grid>
{!isMobile && (
<Grid item xs={3}>
@@ -13,39 +13,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, {
ChangeEvent,
KeyboardEvent,
useState,
useEffect,
useCallback,
forwardRef,
ComponentType,
ForwardRefExoticComponent,
} from 'react';
import useDebounce from 'react-use/lib/useDebounce';
import {
InputBase,
InputBaseProps,
InputAdornment,
IconButton,
} from '@material-ui/core';
import SearchIcon from '@material-ui/icons/Search';
import ClearButton from '@material-ui/icons/Clear';
import {
AnalyticsContext,
configApiRef,
useApi,
} from '@backstage/core-plugin-api';
import { IconButton, InputAdornment, TextField } from '@material-ui/core';
import { TextFieldProps } from '@material-ui/core/TextField';
import ClearButton from '@material-ui/icons/Clear';
import SearchIcon from '@material-ui/icons/Search';
import React, {
ChangeEvent,
ComponentType,
forwardRef,
ForwardRefExoticComponent,
KeyboardEvent,
useCallback,
useEffect,
useState,
} from 'react';
import useDebounce from 'react-use/lib/useDebounce';
import { SearchContextProvider, useSearch } from '../../context';
import { TrackSearch } from '../SearchTracker';
function withContext<T>(Component: ComponentType<T>) {
return forwardRef<unknown, T>((props, ref) => (
return forwardRef<HTMLDivElement, T>((props, ref) => (
<SearchContextProvider inheritParentContextIfAvailable>
<Component {...props} ref={ref} />
</SearchContextProvider>
@@ -57,12 +50,13 @@ function withContext<T>(Component: ComponentType<T>) {
*
* @public
*/
export type SearchBarBaseProps = Omit<InputBaseProps, 'onChange'> & {
export type SearchBarBaseProps = Omit<TextFieldProps, 'onChange'> & {
debounceTime?: number;
clearButton?: boolean;
onClear?: () => void;
onSubmit?: () => void;
onChange: (value: string) => void;
endAdornment?: React.ReactNode;
};
/**
@@ -109,7 +103,7 @@ export const SearchBarBase: ForwardRefExoticComponent<SearchBarBaseProps> =
);
const handleKeyDown = useCallback(
(e: KeyboardEvent<HTMLInputElement>) => {
(e: KeyboardEvent<HTMLDivElement>) => {
if (onKeyDown) onKeyDown(e);
if (onSubmit && e.key === 'Enter') {
onSubmit();
@@ -147,14 +141,21 @@ export const SearchBarBase: ForwardRefExoticComponent<SearchBarBaseProps> =
return (
<TrackSearch>
<InputBase
<TextField
data-testid="search-bar-next"
ref={ref}
variant="outlined"
margin="normal"
inputRef={ref}
value={value}
placeholder={placeholder}
startAdornment={startAdornment}
endAdornment={clearButton ? endAdornment : defaultEndAdornment}
inputProps={{ 'aria-label': 'Search', ...defaultInputProps }}
label={placeholder}
InputProps={{
startAdornment,
endAdornment: clearButton ? endAdornment : defaultEndAdornment,
}}
inputProps={{
'aria-label': 'Search',
...defaultInputProps,
}}
fullWidth={fullWidth}
onChange={handleChange}
onKeyDown={handleKeyDown}
@@ -13,9 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { KeyboardEvent, useRef, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { Link, useContent } from '@backstage/core-components';
import { useRouteRef } from '@backstage/core-plugin-api';
import {
SearchBar,
SearchContextProvider,
SearchResult,
SearchResultPager,
useSearch,
} from '@backstage/plugin-search-react';
import {
Dialog,
DialogActions,
@@ -23,21 +29,17 @@ import {
DialogTitle,
Divider,
Grid,
Paper,
useTheme,
} from '@material-ui/core';
import Typography from '@material-ui/core/Typography';
import LaunchIcon from '@material-ui/icons/Launch';
import Box from '@material-ui/core/Box';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import { makeStyles } from '@material-ui/core/styles';
import {
SearchContextProvider,
SearchBar,
SearchResult,
SearchResultPager,
useSearch,
} from '@backstage/plugin-search-react';
import { useRouteRef } from '@backstage/core-plugin-api';
import { Link, useContent } from '@backstage/core-components';
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
import CloseIcon from '@material-ui/icons/Close';
import React, { KeyboardEvent, useCallback, useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { rootRouteRef } from '../../plugin';
/**
@@ -78,6 +80,15 @@ export interface SearchModalProps {
}
const useStyles = makeStyles(theme => ({
dialogTitle: {
gap: theme.spacing(1),
display: 'grid',
alignItems: 'center',
gridTemplateColumns: '1fr auto',
'&> button': {
marginTop: theme.spacing(1),
},
},
container: {
borderRadius: 30,
display: 'flex',
@@ -111,7 +122,7 @@ export const Modal = () => {
}, [focusContent, transitions]);
const handleSearchBarKeyDown = useCallback(
(e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
(e: KeyboardEvent<HTMLDivElement | HTMLTextAreaElement>) => {
if (e.key === 'Enter') {
navigate(searchPagePath);
handleSearchResultClick();
@@ -123,13 +134,17 @@ export const Modal = () => {
return (
<>
<DialogTitle>
<Paper className={classes.container}>
<Box className={classes.dialogTitle}>
<SearchBar
className={classes.input}
inputProps={{ ref: searchBarRef }}
onKeyDown={handleSearchBarKeyDown}
/>
</Paper>
<IconButton aria-label="close" onClick={toggleModal}>
<CloseIcon />
</IconButton>
</Box>
</DialogTitle>
<DialogContent>
<Grid
@@ -139,12 +154,15 @@ export const Modal = () => {
alignItems="center"
>
<Grid item>
<Link to={searchPagePath} onClick={handleSearchResultClick}>
<Typography component="span" className={classes.viewResultsLink}>
View Full Results
</Typography>
<LaunchIcon color="primary" />
</Link>
<Button
to={searchPagePath}
onClick={handleSearchResultClick}
endIcon={<ArrowForwardIcon />}
component={Link}
color="primary"
>
View Full Results
</Button>
</Grid>
</Grid>
<Divider />