1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-24 17:51:14 +02:00
unleash.unleash/frontend/src/component/common/Table/TableSearch/TableSearchField/TableSearchField.tsx
Tymoteusz Czech 53b12604b8 Search keyboard shortcut (#1048)
* feat: search keyboard shortcut

* fix: search input placeholder snapshot update

* fix: update apple device recognition

Co-authored-by: Nuno Góis <github@nunogois.com>

* refactor: return hotkey from useKeyboardShortcut

* fix: don't close non-empty search field

* Archive table
new sort parameter

* Revert "Archive table"

This reverts commit 171806352c2a01ce439ce7bd77476797d544275c.

* update search field focus

* refactor: clarify hotkey description

* fix: make variant payload text box multiline (#1060)

* fix: make variant payload text box multiline

* refactor: adjust min/max rows

* refactor: use fixed number of rows to avoid MUI render loop bug

* fix: toggle search on escape only in focused

* fix: add hotkey to custom placeholders

Co-authored-by: Nuno Góis <github@nunogois.com>
Co-authored-by: andreas-unleash <andreas@getunleash.ai>
Co-authored-by: olav <mail@olav.io>
2022-06-06 14:23:48 +02:00

104 lines
3.7 KiB
TypeScript

import { useRef, useState } from 'react';
import { IconButton, InputBase, Tooltip } from '@mui/material';
import { Search, Close } from '@mui/icons-material';
import classnames from 'classnames';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { useStyles } from './TableSearchField.styles';
import { TableSearchFieldSuggestions } from './TableSearchFieldSuggestions/TableSearchFieldSuggestions';
import { IGetSearchContextOutput } from 'hooks/useSearch';
import { useKeyboardShortcut } from 'hooks/useKeyboardShortcut';
interface ITableSearchFieldProps {
value: string;
onChange: (value: string) => void;
className?: string;
placeholder?: string;
hasFilters?: boolean;
getSearchContext?: () => IGetSearchContextOutput;
}
export const TableSearchField = ({
value = '',
onChange,
className,
placeholder: customPlaceholder,
hasFilters,
getSearchContext,
}: ITableSearchFieldProps) => {
const ref = useRef<HTMLInputElement>();
const { classes: styles } = useStyles();
const [showSuggestions, setShowSuggestions] = useState(false);
const hotkey = useKeyboardShortcut(
{ modifiers: ['ctrl'], key: 'k', preventDefault: true },
() => {
ref.current?.focus();
setShowSuggestions(true);
}
);
useKeyboardShortcut({ key: 'Escape' }, () => {
if (document.activeElement === ref.current) {
setShowSuggestions(suggestions => !suggestions);
}
});
const placeholder = `${customPlaceholder ?? 'Search'} (${hotkey})`;
return (
<div className={styles.container}>
<div
className={classnames(
styles.search,
className,
'search-container'
)}
>
<Search
className={classnames(styles.searchIcon, 'search-icon')}
/>
<InputBase
inputRef={ref}
placeholder={placeholder}
classes={{
root: classnames(styles.inputRoot, 'input-container'),
}}
inputProps={{ 'aria-label': placeholder }}
value={value}
onChange={e => onChange(e.target.value)}
onFocus={() => setShowSuggestions(true)}
onBlur={() => setShowSuggestions(false)}
/>
<div
className={classnames(
styles.clearContainer,
'clear-container'
)}
>
<ConditionallyRender
condition={Boolean(value)}
show={
<Tooltip title="Clear search query" arrow>
<IconButton
size="small"
onClick={() => {
onChange('');
ref.current?.focus();
}}
>
<Close className={styles.clearIcon} />
</IconButton>
</Tooltip>
}
/>
</div>
</div>
<ConditionallyRender
condition={Boolean(hasFilters) && showSuggestions}
show={
<TableSearchFieldSuggestions
getSearchContext={getSearchContext!}
/>
}
/>
</div>
);
};