Files
feishin/src/renderer/components/search-input/index.tsx
T
2023-03-28 23:59:51 -07:00

63 lines
1.6 KiB
TypeScript

import { ChangeEvent, KeyboardEvent } from 'react';
import { TextInputProps } from '@mantine/core';
import { useFocusWithin, useHotkeys, useMergedRef } from '@mantine/hooks';
import { RiSearchLine } from 'react-icons/ri';
import { TextInput } from '/@/renderer/components/input';
interface SearchInputProps extends TextInputProps {
initialWidth?: number;
openedWidth?: number;
value?: string;
}
export const SearchInput = ({
initialWidth,
onChange,
openedWidth,
...props
}: SearchInputProps) => {
const { ref, focused } = useFocusWithin();
const mergedRef = useMergedRef<HTMLInputElement>(ref);
const isOpened = focused || ref.current?.value;
const showIcon = !isOpened || (openedWidth || 100) > 100;
useHotkeys([
[
'ctrl+F',
() => {
ref.current.select();
},
],
]);
const handleEscape = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.code === 'Escape') {
onChange?.({ target: { value: '' } } as ChangeEvent<HTMLInputElement>);
ref.current.value = '';
ref.current.blur();
}
};
return (
<TextInput
ref={mergedRef}
{...props}
icon={showIcon && <RiSearchLine />}
size="md"
styles={{
icon: { svg: { fill: 'var(--titlebar-fg)' } },
input: {
backgroundColor: isOpened ? 'inherit' : 'transparent !important',
border: 'none !important',
cursor: isOpened ? 'text' : 'pointer',
padding: isOpened ? '10px' : 0,
},
}}
width={isOpened ? openedWidth || 150 : initialWidth || 35}
onChange={onChange}
onKeyDown={handleEscape}
/>
);
};